diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 0da372cf..fbb2f900 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,16 +1,19 @@ -FROM node:16 AS node_base +FROM node:lts AS node FROM hadolint/hadolint:latest-alpine AS hadolint -FROM ocaml/opam:debian-ocaml-4.12 +FROM ocaml/opam:debian-10-ocaml-4.14 -# copy node from node_base container and link commands USER root -COPY --from=node_base /usr/local/lib/node_modules /usr/local/lib/node_modules -COPY --from=node_base /usr/local/bin/node /usr/local/bin/node -COPY --from=node_base /opt /opt + +# copy node from node container and link commands +COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules +COPY --from=node /usr/local/bin/node /usr/local/bin/node +COPY --from=node /opt /opt RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ + && ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ && ln -s /opt/yarn-v*/bin/yarn /usr/local/bin/yarn \ && ln -s /opt/yarn-v*/bin/yarnpkg /usr/local/bin/yarnpkg + # copy hadolint COPY --from=hadolint /bin/hadolint /bin/hadolint @@ -18,50 +21,46 @@ COPY --from=hadolint /bin/hadolint /bin/hadolint ENV DEBIAN_FRONTEND noninteractive ENV SIHL_ENV development -RUN apt-get update -q \ - && apt-get install -yqq --no-install-recommends \ - default-jre \ - # emacs-nox for emacs, but sihl cannot be installed without - emacs-nox \ - git \ +# install packages +# hadolint ignore=DL3008 +RUN apt-get update -q && apt-get install -yqq --no-install-recommends \ + # development dependencies inotify-tools \ + zsh \ + m4 \ + wget \ + # + # build dependencies (would also be installed by opam depext) + gcc \ libev-dev \ - libffi-dev \ - libfontconfig \ libgmp-dev \ libmariadb-dev \ libpq-dev \ - libqt5gui5 \ libssl-dev \ - lsof \ - m4 \ - pdftk-java \ - perl \ pkg-config \ - utop \ - wget \ - wkhtmltopdf \ - xvfb \ - zip \ - zlib1g-dev \ - zsh \ # # cleanup installations && apt-get autoremove -y \ && apt-get clean all \ - # - # add timezone - && ln -fs /usr/share/zoneinfo/Europe/Zurich /etc/localtime + && rm -rf /var/lib/apt/lists/* + +# add timezone +RUN ln -fs /usr/share/zoneinfo/Europe/Zurich /etc/localtime # WTF: https://github.com/mirage/ocaml-cohttp/issues/675 RUN bash -c 'echo "http 80/tcp www # WorldWideWeb HTTP" >> /etc/services' \ && bash -c 'echo "https 443/tcp www # WorldWideWeb HTTPS" >> /etc/services' -# Switch back to dialog for any ad-hoc use of apt-get -ENV DEBIAN_FRONTEND=dialog USER opam # install oh-my-zsh +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -q -O - | zsh \ && cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc \ - && sed -i "/^plugins=/c\plugins=(git dotenv)" ~/.zshrc + && sed -i "/^plugins=/c\plugins=(git dotenv)" ~/.zshrc \ + # + # link make to devcontainer makefile + && echo 'alias make="make -f /workspace/.devcontainer/Makefile"' >> ~/.zshrc + +# Switch back to dialog for any ad-hoc use of apt-get +ENV DEBIAN_FRONTEND=dialog diff --git a/.devcontainer/Makefile b/.devcontainer/Makefile new file mode 100644 index 00000000..741a9ef0 --- /dev/null +++ b/.devcontainer/Makefile @@ -0,0 +1,3 @@ +include ./Makefile + +SHELL = bash diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 03533291..d1e9521e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,31 +15,34 @@ "postCreateCommand": "bash .devcontainer/postCreate.sh", // Use 'settings' to set *default* container specific settings.json values on container create. // You can edit these settings after create using File > Preferences > Settings > Remote. - "settings": { - "terminal.integrated.profiles.linux": { - "zsh": { - "path": "/bin/zsh" - } - }, - "terminal.integrated.defaultProfile.linux": "zsh", - "editor.formatOnSave": true, - "files.associations": { - "*.ml": "ocaml", - "*.mli": "ocaml" - }, - "ocaml.sandbox": { - "kind": "global", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/bin/zsh" + } + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "editor.formatOnSave": true, + "files.associations": { + "*.ml": "ocaml", + "*.mli": "ocaml" + }, + "ocaml.sandbox": { + "kind": "global" + } + }, + // Add the IDs of extensions you want installed when the container is created in the array below. + "extensions": [ + "donjayamanne.githistory", + "eamodio.gitlens", + "exiasr.hadolint", + "irongeek.vscode-env", + "ocamllabs.ocaml-platform", + "DavidAnson.vscode-markdownlint", + "ms-vscode.makefile-tools" + ] } - }, - // Add the IDs of extensions you want installed when the container is created in the array below. - "extensions": [ - // general useful extensions - "donjayamanne.githistory", - "eamodio.gitlens", - "editorconfig.editorconfig", - "exiasr.hadolint", - "ms-azuretools.vscode-docker", - // project extensions - "ocamllabs.ocaml-platform" - ] + } } diff --git a/.devcontainer/postCreate.sh b/.devcontainer/postCreate.sh index e8c85969..b0adc292 100644 --- a/.devcontainer/postCreate.sh +++ b/.devcontainer/postCreate.sh @@ -1,21 +1,25 @@ -# ocaml/opam post create script +#!/bin/sh + +# immediately when a command fails and print each command +set -ex sudo chown -R opam: _build sudo chown -R opam: node_modules -# initialize project and update environmemnt opam init -a --shell=zsh -eval $(opam env) # get newest opam packages opam remote remove --all default opam remote add default https://opam.ocaml.org -# ensure all system dependencies are installed opam pin add . --yes --no-action opam depext sihl sihl-user sihl-storage sihl-email sihl-queue sihl-cache sihl-token --yes --with-doc --with-test +eval $(opam env) + # install opam packages used for vscode ocaml platform package # e.g. when developing with emax, add also: utop merlin ocamlformat make deps -opam install -y ocaml-lsp-server + +# install yarn packages +yarn diff --git a/Makefile b/Makefile index 4b42e957..95af6848 100644 --- a/Makefile +++ b/Makefile @@ -11,13 +11,13 @@ all: .PHONY: deps deps: opam install -y dune-release merlin ocamlformat utop - opam install -y alcotest-lwt mariadb.1.1.4 caqti-driver-postgresql.1.8.0 caqti-driver-mariadb.1.8.0 + opam install -y alcotest-lwt mariadb.1.1.6 caqti-driver-postgresql.2.0.1 caqti-driver-mariadb.2.0.1 opam install . -y --deps-only --locked eval $(opam env) .PHONY: create_switch create_switch: - opam switch create . 4.12.0 --no-install --locked + opam switch create . 4.14.1 --no-install --locked eval $(opam env) .PHONY: switch diff --git a/dune b/dune index 08c32742..a895656e 100644 --- a/dune +++ b/dune @@ -1 +1,6 @@ +(env + (dev + (flags + (:standard -w -70 -warn-error -70)))) + (data_only_dirs node_modules .devcontainer .git) diff --git a/dune-project b/dune-project index 590bd9e0..24315097 100644 --- a/dune-project +++ b/dune-project @@ -31,7 +31,7 @@ (ocaml (>= 4.12.0)) (conformist - (>= 0.6.0)) + (>= 0.8.1)) (dune-build-info (>= 2.8.4)) (tsort @@ -54,16 +54,14 @@ (>= 0.11.1)) (ssl (>= 0.5.9)) - (uuidm - (>= 0.9.7)) (lwt_ssl (>= 1.1.3)) (lwt_ppx (>= 2.0.1)) (caqti - (>= 1.8.0)) + (>= 2.0.1)) (caqti-lwt - (>= 1.3.0)) + (>= 2.0.1)) (safepass (>= 3.0)) (jwto @@ -88,13 +86,15 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) (package @@ -116,13 +116,15 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) (package @@ -139,13 +141,15 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) (package @@ -163,13 +167,15 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) (package @@ -187,13 +193,15 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) (package @@ -214,13 +222,15 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) (package @@ -240,11 +250,13 @@ (and (>= 1.4.0) :with-test)) + (mariadb + (>= 1.1.6)) (caqti-driver-postgresql (and - (>= 1.8.0) + (>= 2.0.1) :with-test)) (caqti-driver-mariadb (and - (>= 1.8.0) + (>= 2.0.1) :with-test)))) diff --git a/sihl-cache.opam b/sihl-cache.opam index 37f864d3..0ffb41db 100644 --- a/sihl-cache.opam +++ b/sihl-cache.opam @@ -14,8 +14,9 @@ depends: [ "ocaml" {>= "4.08.0"} "sihl" {= version} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl-cache.opam.locked b/sihl-cache.opam.locked index 90bb678c..e5bb2c90 100644 --- a/sihl-cache.opam.locked +++ b/sihl-cache.opam.locked @@ -9,12 +9,10 @@ homepage: "https://github.com/oxidizing/sihl" doc: "https://oxidizing.github.io/sihl/" bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ - "base-bigarray" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "dune" {= "3.0.3"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "dune" {= "3.11.1"} + "ocaml" {= "4.14.1"} ] build: [ ["dune" "subst"] {dev} @@ -32,7 +30,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl-cache" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl-cache/src/repo_sql.ml b/sihl-cache/src/repo_sql.ml index ad26da2c..2e73856c 100644 --- a/sihl-cache/src/repo_sql.ml +++ b/sihl-cache/src/repo_sql.ml @@ -34,7 +34,7 @@ let insert_request = ? ) |sql} - |> Caqti_type.(tup2 string string ->. unit) + |> Caqti_type.(t2 string string ->. unit) ;; let insert ?ctx key_value = Sihl.Database.exec ?ctx insert_request key_value @@ -46,7 +46,7 @@ let update_request = cache_value = $2 WHERE cache_key = $1 |sql} - |> Caqti_type.(tup2 string string ->. unit) + |> Caqti_type.(t2 string string ->. unit) ;; let update ?ctx key_value = Sihl.Database.exec ?ctx update_request key_value diff --git a/sihl-cache/src/sihl_cache.ml b/sihl-cache/src/sihl_cache.ml index 324d9189..e042f2ab 100644 --- a/sihl-cache/src/sihl_cache.ml +++ b/sihl-cache/src/sihl_cache.ml @@ -1,7 +1,5 @@ let log_src = Logs.Src.create ("sihl.service." ^ Sihl.Contract.Cache.name) -module Logs = (val Logs.src_log log_src : Logs.LOG) - module MakeSql (Repo : Repo_sql.Sig) : Sihl.Contract.Cache.Sig = struct let find = Repo.find diff --git a/sihl-email.opam b/sihl-email.opam index 5f9bdd45..e0666244 100644 --- a/sihl-email.opam +++ b/sihl-email.opam @@ -16,8 +16,9 @@ depends: [ "sihl" {= version} "cohttp-lwt-unix" {>= "2.5.4"} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl-email.opam.locked b/sihl-email.opam.locked index 832383a5..c42e897d 100644 --- a/sihl-email.opam.locked +++ b/sihl-email.opam.locked @@ -9,108 +9,100 @@ homepage: "https://github.com/oxidizing/sihl" doc: "https://oxidizing.github.io/sihl/" bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ - "afl-persistent" {= "1.3"} "angstrom" {= "0.15.0"} "asn1-combinators" {= "0.2.6"} "astring" {= "0.8.5"} - "base" {= "v0.14.3"} - "base-bigarray" {= "base"} + "base" {= "v0.16.3"} "base-bytes" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "base64" {= "3.5.0"} + "base64" {= "3.5.1"} "bigarray-compat" {= "1.1.0"} - "bigarray-overlap" {= "0.2.0"} - "bigstringaf" {= "0.8.0"} + "bigarray-overlap" {= "0.2.1"} + "bigstringaf" {= "0.9.1"} "bos" {= "0.2.1"} - "ca-certs" {= "0.2.2"} - "cmdliner" {= "1.0.4"} - "cohttp" {= "5.0.0"} - "cohttp-lwt" {= "5.0.0"} - "cohttp-lwt-unix" {= "5.0.0"} + "ca-certs" {= "0.2.3"} + "cmdliner" {= "1.2.0"} + "cohttp" {= "5.3.0"} + "cohttp-lwt" {= "5.3.0"} + "cohttp-lwt-unix" {= "5.3.0"} "coin" {= "0.1.4"} - "colombe" {= "0.6.0"} - "conduit" {= "5.1.0"} - "conduit-lwt" {= "5.1.0"} - "conduit-lwt-unix" {= "5.1.0"} + "colombe" {= "0.8.0"} + "conduit" {= "6.2.0"} + "conduit-lwt" {= "6.2.0"} + "conduit-lwt-unix" {= "6.2.0"} "conf-gmp" {= "4"} "conf-gmp-powm-sec" {= "3"} "conf-libev" {= "4-12"} - "conf-libssl" {= "3"} - "conf-pkg-config" {= "2"} - "cppo" {= "1.6.8"} - "csexp" {= "1.5.1"} + "conf-libssl" {= "4"} + "conf-pkg-config" {= "3"} + "cppo" {= "1.6.9"} + "csexp" {= "1.5.2"} "cstruct" {= "6.0.1"} - "cstruct-sexp" {= "6.0.1"} "domain-name" {= "0.4.0"} - "dune" {= "3.0.3"} - "dune-configurator" {= "3.0.3"} - "duration" {= "0.2.0"} + "dune" {= "3.11.1"} + "dune-configurator" {= "3.11.1"} + "duration" {= "0.2.1"} "emile" {= "1.1"} - "eqaf" {= "0.8"} + "eqaf" {= "0.9"} "fmt" {= "0.9.0"} "fpath" {= "0.7.3"} "gmap" {= "0.3.0"} "hkdf" {= "1.0.4"} - "hxd" {= "0.3.1"} - "ipaddr" {= "5.3.0"} - "ipaddr-sexp" {= "5.3.0"} - "jsonm" {= "1.0.1"} - "ke" {= "0.5"} - "letters" {= "0.3.0"} + "ipaddr" {= "5.5.0"} + "ipaddr-sexp" {= "5.5.0"} + "jsonm" {= "1.0.2"} + "ke" {= "0.6"} + "letters" {= "0.3.3"} "logs" {= "0.7.0"} - "lwt" {= "5.5.0"} - "lwt_ssl" {= "1.1.3"} - "macaddr" {= "5.3.0"} - "magic-mime" {= "1.2.0"} - "mirage-crypto" {= "0.10.6"} - "mirage-crypto-ec" {= "0.10.6"} - "mirage-crypto-pk" {= "0.10.6"} - "mirage-crypto-rng" {= "0.10.6"} - "mirage-no-solo5" {= "1"} - "mirage-no-xen" {= "1"} - "mmap" {= "1.2.0"} - "mrmime" {= "0.5.0"} - "mtime" {= "1.4.0"} + "lwt" {= "5.7.0"} + "lwt_ssl" {= "1.2.0"} + "macaddr" {= "5.5.0"} + "magic-mime" {= "1.3.1"} + "mirage-crypto" {= "0.11.2"} + "mirage-crypto-ec" {= "0.11.2"} + "mirage-crypto-pk" {= "0.11.2"} + "mirage-crypto-rng" {= "0.11.2"} + "mirage-crypto-rng-lwt" {= "0.11.2"} + "mrmime" {= "0.6.0"} + "mtime" {= "2.0.0"} "num" {= "1.4"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "ocaml" {= "4.14.1"} "ocaml-compiler-libs" {= "v0.12.4"} "ocaml-syntax-shims" {= "1.0.0"} - "ocamlbuild" {= "0.14.1"} - "ocamlfind" {= "1.9.3"} + "ocamlbuild" {= "0.14.2"} + "ocamlfind" {= "1.9.6"} "ocplib-endian" {= "1.2"} - "parsexp" {= "v0.14.2"} + "parsexp" {= "v0.16.0"} "pbkdf" {= "1.2.0"} "pecu" {= "0.6"} - "ppx_cstruct" {= "6.0.1"} "ppx_derivers" {= "1.2.1"} - "ppx_sexp_conv" {= "v0.14.3"} - "ppxlib" {= "0.25.0"} - "prettym" {= "0.0.2"} - "ptime" {= "1.0.0"} - "re" {= "1.10.3"} + "ppx_sexp_conv" {= "v0.16.0"} + "ppxlib" {= "0.31.0"} + "prettym" {= "0.0.3"} + "ptime" {= "1.1.0"} + "re" {= "1.11.0"} "result" {= "1.5"} "rosetta" {= "0.3.0"} "rresult" {= "0.7.0"} - "sendmail" {= "0.6.0"} + "sendmail" {= "0.8.0"} "seq" {= "base"} - "sexplib" {= "v0.14.0"} - "sexplib0" {= "v0.14.0"} - "ssl" {= "0.5.10"} + "sexplib" {= "v0.16.0"} + "sexplib0" {= "v0.16.0"} + "ssl" {= "0.7.0"} "stdlib-shims" {= "0.3.0"} "stringext" {= "1.6.0"} - "tls" {= "0.15.3"} - "topkg" {= "1.0.5"} - "uchar" {= "0.0.2"} + "tls" {= "0.17.1"} + "tls-lwt" {= "0.17.1"} + "topkg" {= "1.0.7"} "unstrctrd" {= "0.3"} - "uri" {= "4.2.0"} - "uri-sexp" {= "4.2.0"} + "uri" {= "4.4.0"} + "uri-sexp" {= "4.4.0"} "uutf" {= "1.0.3"} "uuuu" {= "0.3.0"} - "x509" {= "0.16.0"} + "x509" {= "0.16.5"} "yuscii" {= "0.3.0"} - "zarith" {= "1.12"} + "zarith" {= "1.13"} ] build: [ ["dune" "subst"] {dev} @@ -128,7 +120,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl-email" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl-email/src/sihl_email.ml b/sihl-email/src/sihl_email.ml index 50c311a8..e2ec9236 100644 --- a/sihl-email/src/sihl_email.ml +++ b/sihl-email/src/sihl_email.ml @@ -68,6 +68,7 @@ type smtp_config = { sender : string ; username : string option ; password : string option + ; mechanism : string option ; hostname : string ; port : int option ; start_tls : bool @@ -80,6 +81,7 @@ let smtp_config sender username password + mechanism hostname port start_tls @@ -90,6 +92,7 @@ let smtp_config { sender ; username ; password + ; mechanism ; hostname ; port ; start_tls @@ -107,6 +110,7 @@ let smtp_schema = https://github.com/oxidizing/conformist/issues/11, once exists *) ; optional (string "SMTP_USERNAME") ; optional (string "SMTP_PASSWORD") + ; optional (string "SMTP_MECHANISM") ; string "SMTP_HOST" ; optional (int ~default:587 "SMTP_PORT") ; bool "SMTP_START_TLS" @@ -146,8 +150,24 @@ module MakeSmtp (Config : SmtpConfig) : Sihl.Contract.Email.Sig = struct let with_starttls = config.start_tls in let ca_path = config.ca_path in let ca_cert = config.ca_cert in + let mechanism = + CCOption.bind + config.mechanism + CCFun.( + CCString.lowercase_ascii + %> function + | "login" -> Some Sendmail.LOGIN + | "plain" -> Some Sendmail.PLAIN + | _ -> None) + in let config = - Letters.Config.make ~username ~password ~hostname ~with_starttls + Letters.Config.create + ?mechanism + ~username + ~password + ~hostname + ~with_starttls + () |> Letters.Config.set_port port |> fun conf -> match ca_cert, ca_path with @@ -155,11 +175,12 @@ module MakeSmtp (Config : SmtpConfig) : Sihl.Contract.Email.Sig = struct | None, Some path -> Letters.Config.set_ca_path path conf | None, None -> conf in - Letters.build_email + Letters.create_email ~from:email.sender ~recipients ~subject:email.subject ~body + () |> function | Ok message -> Letters.send ~config ~sender ~recipients ~message | Error msg -> raise (Sihl.Contract.Email.Exception msg) @@ -259,7 +280,7 @@ module MakeSendGrid (Config : SendGridConfig) : Sihl.Contract.Email.Sig = struct "https://api.sendgrid.com/v3/mail/send" |> Uri.of_string ;; - let send' email = + let send' (email : Sihl.Contract.Email.t) = let open Sihl.Contract.Email in let%lwt config = Config.fetch () in let token = config.api_key in @@ -339,8 +360,8 @@ module SendGrid = MakeSendGrid (EnvSendGridConfig) (* This is useful if you need to answer a request quickly while sending the email in the background *) module Queued - (QueueService : Sihl.Contract.Queue.Sig) - (Email : Sihl.Contract.Email.Sig) : Sihl.Contract.Email.Sig = struct + (QueueService : Sihl.Contract.Queue.Sig) + (Email : Sihl.Contract.Email.Sig) : Sihl.Contract.Email.Sig = struct include DevInbox module Job = struct @@ -397,7 +418,7 @@ module Queued ~start ~stop ~dependencies:(fun () -> - [ Email.lifecycle; Sihl.Database.lifecycle; QueueService.lifecycle ]) + [ Email.lifecycle; Sihl.Database.lifecycle; QueueService.lifecycle ]) ;; let register () = Sihl.Container.Service.create lifecycle diff --git a/sihl-email/src/template_repo_sql.ml b/sihl-email/src/template_repo_sql.ml index 7abbf9aa..7e2dc688 100644 --- a/sihl-email/src/template_repo_sql.ml +++ b/sihl-email/src/template_repo_sql.ml @@ -41,13 +41,13 @@ let template = custom ~encode ~decode - (tup2 + (t2 string - (tup2 + (t2 string - (tup2 + (t2 (option string) - (tup2 string (tup2 (option string) (tup2 ptime ptime))))))) + (t2 string (t2 (option string) (t2 ptime ptime))))))) ;; module MakeMariaDb (MigrationService : Sihl.Contract.Migration.Sig) : Sig = @@ -55,8 +55,6 @@ struct let lifecycles = [ Sihl.Database.lifecycle; MigrationService.lifecycle ] module Sql = struct - module Model = Sihl.Contract.Email_template - let get_request = let open Caqti_request.Infix in {sql| @@ -123,7 +121,7 @@ struct ?ctx (get_by_label_request ~with_language:true - Caqti_type.(tup2 string string)) + Caqti_type.(t2 string string)) (label, language) ;; @@ -289,8 +287,6 @@ struct let lifecycles = [ Sihl.Database.lifecycle; MigrationService.lifecycle ] module Sql = struct - module Model = Sihl.Contract.Email_template - let get_request = let open Caqti_request.Infix in {sql| @@ -345,7 +341,7 @@ struct ?ctx (get_by_label_request ~with_language:true - Caqti_type.(tup2 string string)) + Caqti_type.(t2 string string)) (label, language) ;; diff --git a/sihl-email/test/email.ml b/sihl-email/test/email.ml index 8bc103d8..805caf8e 100644 --- a/sihl-email/test/email.ml +++ b/sihl-email/test/email.ml @@ -7,8 +7,8 @@ let template_testable = ;; module Make - (EmailService : Sihl.Contract.Email.Sig) - (EmailTemplateService : Sihl.Contract.Email_template.Sig) = + (EmailService : Sihl.Contract.Email.Sig) + (EmailTemplateService : Sihl.Contract.Email_template.Sig) = struct let create_template _ () = let%lwt () = Sihl.Cleaner.clean_all () in diff --git a/sihl-queue.opam b/sihl-queue.opam index 2837bef6..73f4de08 100644 --- a/sihl-queue.opam +++ b/sihl-queue.opam @@ -16,8 +16,9 @@ depends: [ "sihl" {= version} "tyxml-ppx" {>= "4.4.0"} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl-queue.opam.locked b/sihl-queue.opam.locked index 0986a4bf..c5989088 100644 --- a/sihl-queue.opam.locked +++ b/sihl-queue.opam.locked @@ -10,27 +10,25 @@ homepage: "https://github.com/oxidizing/sihl" doc: "https://oxidizing.github.io/sihl/" bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ - "base-bigarray" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "cmdliner" {= "1.0.4"} - "dune" {= "3.0.3"} + "cmdliner" {= "1.2.0"} + "dune" {= "3.11.1"} "markup" {= "1.0.3"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "ocaml" {= "4.14.1"} "ocaml-compiler-libs" {= "v0.12.4"} - "ocamlbuild" {= "0.14.1"} - "ocamlfind" {= "1.9.3"} + "ocamlbuild" {= "0.14.2"} + "ocamlfind" {= "1.9.6"} "ppx_derivers" {= "1.2.1"} - "ppxlib" {= "0.25.0"} - "re" {= "1.10.3"} + "ppxlib" {= "0.31.0"} + "re" {= "1.11.0"} "seq" {= "base"} - "sexplib0" {= "v0.14.0"} + "sexplib0" {= "v0.16.0"} "stdlib-shims" {= "0.3.0"} - "topkg" {= "1.0.5"} - "tyxml" {= "4.5.0"} - "tyxml-ppx" {= "4.5.0"} - "tyxml-syntax" {= "4.5.0"} + "topkg" {= "1.0.7"} + "tyxml" {= "4.6.0"} + "tyxml-ppx" {= "4.6.0"} + "tyxml-syntax" {= "4.6.0"} "uchar" {= "0.0.2"} "uutf" {= "1.0.3"} ] @@ -50,7 +48,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl-queue" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl-queue/src/repo_inmemory.ml b/sihl-queue/src/repo_inmemory.ml index 64f8808e..dff65f25 100644 --- a/sihl-queue/src/repo_inmemory.ml +++ b/sihl-queue/src/repo_inmemory.ml @@ -78,9 +78,9 @@ let search ?ctx:_ (sort : [ `Desc | `Asc ]) filter ~limit ~offset = |> CCList.take limit |> CCList.sort (fun - (j1 : Sihl.Contract.Queue.instance) - (j2 : Sihl.Contract.Queue.instance) - -> Option.compare String.compare j1.tag j2.tag) + (j1 : Sihl.Contract.Queue.instance) + (j2 : Sihl.Contract.Queue.instance) + -> Option.compare String.compare j1.tag j2.tag) |> fun l -> if sort == `Desc then l else List.rev l in Lwt.return @@ (filtered, List.length filtered) diff --git a/sihl-queue/src/repo_sql.ml b/sihl-queue/src/repo_sql.ml index 2200a9f7..7963452a 100644 --- a/sihl-queue/src/repo_sql.ml +++ b/sihl-queue/src/repo_sql.ml @@ -75,25 +75,25 @@ let job = custom ~encode ~decode - (tup2 + (t2 string - (tup2 + (t2 string - (tup2 + (t2 string - (tup2 + (t2 int - (tup2 + (t2 ptime - (tup2 + (t2 int - (tup2 + (t2 status - (tup2 + (t2 (option string) - (tup2 + (t2 (option ptime) - (tup2 (option string) (option ctx)))))))))))) + (t2 (option string) (option ctx)))))))))))) ;; module MakeMariaDb (MigrationService : Sihl.Contract.Migration.Sig) = struct @@ -140,13 +140,13 @@ module MakeMariaDb (MigrationService : Sihl.Contract.Migration.Sig) = struct let populatable job_instances = job_instances |> List.map (fun j -> - Sihl.Contract.Queue. - { j with - id = - (match j.id |> Uuidm.of_string with - | Some uuid -> Uuidm.to_bytes uuid - | None -> failwith "Invalid uuid provided") - }) + Sihl.Contract.Queue. + { j with + id = + (match j.id |> Uuidm.of_string with + | Some uuid -> Uuidm.to_bytes uuid + | None -> failwith "Invalid uuid provided") + }) ;; let enqueue_all ?ctx job_instances = @@ -419,7 +419,7 @@ module MakeMariaDb (MigrationService : Sihl.Contract.Migration.Sig) = struct Sihl.Database.Migration.create_step ~label:"add ctx column" {sql| - ALTER TABLE queue_jobs + ALTER TABLE queue_jobs ADD COLUMN ctx TEXT NULL |sql} ;; @@ -732,7 +732,7 @@ module MakePostgreSql (MigrationService : Sihl.Contract.Migration.Sig) = struct Sihl.Database.Migration.create_step ~label:"add ctx column" {sql| - ALTER TABLE queue_jobs + ALTER TABLE queue_jobs ADD COLUMN ctx TEXT NULL |sql} ;; diff --git a/sihl-queue/src/sihl_queue.ml b/sihl-queue/src/sihl_queue.ml index 08f926fa..324645b6 100644 --- a/sihl-queue/src/sihl_queue.ml +++ b/sihl-queue/src/sihl_queue.ml @@ -206,7 +206,7 @@ module Make (Repo : Repo.Sig) : Sihl.Contract.Queue.Sig = struct | (job_instance : instance) :: job_instances -> let job = List.find_opt - (fun job -> job.name |> String.equal job_instance.name) + (fun (job : job') -> job.name |> String.equal job_instance.name) jobs in (match job with @@ -233,7 +233,7 @@ module Make (Repo : Repo.Sig) : Sihl.Contract.Queue.Sig = struct if List.length jobs > 0 then ( let job_strings = - jobs |> List.map (fun job -> job.name) |> String.concat ", " + jobs |> List.map (fun (job : job') -> job.name) |> String.concat ", " in Logs.debug (fun m -> m "Run job queue with registered jobs: %s" job_strings); @@ -259,9 +259,9 @@ module Make (Repo : Repo.Sig) : Sihl.Contract.Queue.Sig = struct else Lwt.return @@ Logs.info (fun m -> - m - "QUEUE_PROCESS is false, jobs can be dispatched but they won't be \ - handled within this queue process") + m + "QUEUE_PROCESS is false, jobs can be dispatched but they won't be \ + handled within this queue process") ;; let stop () = diff --git a/sihl-storage.opam b/sihl-storage.opam index 8b5c01a6..a775be66 100644 --- a/sihl-storage.opam +++ b/sihl-storage.opam @@ -15,8 +15,9 @@ depends: [ "ocaml" {>= "4.08.0"} "sihl" {= version} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl-storage.opam.locked b/sihl-storage.opam.locked index cdeab8ac..aadae0b1 100644 --- a/sihl-storage.opam.locked +++ b/sihl-storage.opam.locked @@ -10,12 +10,10 @@ homepage: "https://github.com/oxidizing/sihl" doc: "https://oxidizing.github.io/sihl/" bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ - "base-bigarray" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "dune" {= "3.0.3"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "dune" {= "3.11.1"} + "ocaml" {= "4.14.1"} ] build: [ ["dune" "subst"] {dev} @@ -33,7 +31,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl-storage" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl-storage/src/repo.ml b/sihl-storage/src/repo.ml index 918e7726..39a85890 100644 --- a/sihl-storage/src/repo.ml +++ b/sihl-storage/src/repo.ml @@ -53,7 +53,7 @@ struct custom ~encode ~decode - Caqti_type.(tup2 string (tup2 string (tup2 int (tup2 string string))))) + Caqti_type.(t2 string (t2 string (t2 int (t2 string string))))) ;; let insert_request = @@ -158,7 +158,7 @@ struct ? ) |sql} - |> Caqti_type.(tup2 string string ->. unit) + |> Caqti_type.(t2 string string ->. unit) ;; let insert_blob ?ctx ~id blob = @@ -173,7 +173,7 @@ struct WHERE storage_blobs.uuid = UNHEX(REPLACE($1, '-', '')) |sql} - |> Caqti_type.(tup2 string string ->. unit) + |> Caqti_type.(t2 string string ->. unit) ;; let update_blob ?ctx ~id blob = diff --git a/sihl-token.opam b/sihl-token.opam index c74ad98d..c0badaea 100644 --- a/sihl-token.opam +++ b/sihl-token.opam @@ -15,8 +15,9 @@ depends: [ "ocaml" {>= "4.08.0"} "sihl" {= version} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl-token.opam.locked b/sihl-token.opam.locked index 43644d50..1734dfa0 100644 --- a/sihl-token.opam.locked +++ b/sihl-token.opam.locked @@ -10,12 +10,10 @@ homepage: "https://github.com/oxidizing/sihl" doc: "https://oxidizing.github.io/sihl/" bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ - "base-bigarray" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "dune" {= "3.0.3"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "dune" {= "3.11.1"} + "ocaml" {= "4.14.1"} ] build: [ ["dune" "subst"] {dev} @@ -33,7 +31,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl-token" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl-token/src/blacklist_repo.ml b/sihl-token/src/blacklist_repo.ml index 6754897c..3c826251 100644 --- a/sihl-token/src/blacklist_repo.ml +++ b/sihl-token/src/blacklist_repo.ml @@ -43,7 +43,7 @@ module MariaDb : Sig = struct $2 ) |sql} - |> Caqti_type.(tup2 string ptime ->. unit) + |> Caqti_type.(t2 string ptime ->. unit) ;; let insert ?ctx token = @@ -60,7 +60,7 @@ module MariaDb : Sig = struct FROM token_blacklist WHERE token_blacklist.token_value = ? |sql} - |> Caqti_type.(string ->? tup2 string ptime) + |> Caqti_type.(string ->? t2 string ptime) ;; let find_opt ?ctx token = Sihl.Database.find_opt ?ctx find_request_opt token @@ -134,7 +134,7 @@ module PostgreSql : Sig = struct $2 AT TIME ZONE 'UTC' ) |sql} - |> Caqti_type.(tup2 string ptime ->. unit) + |> Caqti_type.(t2 string ptime ->. unit) ;; let insert ?ctx token = @@ -151,7 +151,7 @@ module PostgreSql : Sig = struct FROM token_blacklist WHERE token_blacklist.token_value = ? |sql} - |> Caqti_type.(string ->? tup2 string ptime) + |> Caqti_type.(string ->? t2 string ptime) ;; let find_opt ?ctx token = Sihl.Database.find_opt ?ctx find_request_opt token diff --git a/sihl-token/src/repo.ml b/sihl-token/src/repo.ml index 31a95734..d05c5e95 100644 --- a/sihl-token/src/repo.ml +++ b/sihl-token/src/repo.ml @@ -53,9 +53,7 @@ module Model = struct custom ~encode ~decode - (tup2 - string - (tup2 string (tup2 string (tup2 string (tup2 ptime ptime)))))) + (t2 string (t2 string (t2 string (t2 string (t2 ptime ptime)))))) ;; end diff --git a/sihl-user.opam b/sihl-user.opam index fce5b42f..5fa60141 100644 --- a/sihl-user.opam +++ b/sihl-user.opam @@ -16,8 +16,9 @@ depends: [ "sihl" {= version} "sihl-token" {= version & with-test} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl-user.opam.locked b/sihl-user.opam.locked index a101f955..07c12e54 100644 --- a/sihl-user.opam.locked +++ b/sihl-user.opam.locked @@ -10,12 +10,10 @@ homepage: "https://github.com/oxidizing/sihl" doc: "https://oxidizing.github.io/sihl/" bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ - "base-bigarray" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "dune" {= "3.0.3"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "dune" {= "3.11.1"} + "ocaml" {= "4.14.1"} ] build: [ ["dune" "subst"] {dev} @@ -33,7 +31,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl-user" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl-user/src/password_reset.ml b/sihl-user/src/password_reset.ml index 4933696b..47688ff2 100644 --- a/sihl-user/src/password_reset.ml +++ b/sihl-user/src/password_reset.ml @@ -5,8 +5,8 @@ let log_src = module Logs = (val Logs.src_log log_src : Logs.LOG) module Make - (UserService : Sihl.Contract.User.Sig) - (TokenService : Sihl.Contract.Token.Sig) = + (UserService : Sihl.Contract.User.Sig) + (TokenService : Sihl.Contract.Token.Sig) = struct let create_reset_token ?ctx email = let%lwt user = UserService.find_by_email_opt ?ctx email in @@ -44,7 +44,7 @@ struct ~start ~stop ~dependencies:(fun () -> - [ TokenService.lifecycle; UserService.lifecycle ]) + [ TokenService.lifecycle; UserService.lifecycle ]) ;; let register () = Sihl.Container.Service.create lifecycle diff --git a/sihl-user/src/sihl_user.ml b/sihl-user/src/sihl_user.ml index 2b2675c8..6183377d 100644 --- a/sihl-user/src/sihl_user.ml +++ b/sihl-user/src/sihl_user.ml @@ -232,11 +232,11 @@ module Make (Repo : User_repo.Sig) : Sihl.Contract.User.Sig = struct ~help:" " ~description:"Creates a user with admin privileges." (fun args -> - match args with - | [ email; password ] -> - let%lwt () = start () in - create_admin ~password email |> Lwt.map ignore |> Lwt.map Option.some - | _ -> Lwt.return None) + match args with + | [ email; password ] -> + let%lwt () = start () in + create_admin ~password email |> Lwt.map ignore |> Lwt.map Option.some + | _ -> Lwt.return None) ;; let lifecycle = diff --git a/sihl-user/src/user_repo.ml b/sihl-user/src/user_repo.ml index 1a42b3b2..c9cd2879 100644 --- a/sihl-user/src/user_repo.ml +++ b/sihl-user/src/user_repo.ml @@ -75,19 +75,19 @@ let user = custom ~encode ~decode - (tup2 + (t2 string - (tup2 + (t2 string - (tup2 + (t2 (option string) - (tup2 + (t2 (option string) - (tup2 + (t2 (option string) - (tup2 + (t2 string - (tup2 status (tup2 bool (tup2 bool (tup2 ptime ptime))))))))))) + (t2 status (t2 bool (t2 bool (t2 ptime ptime))))))))))) ;; module MakeMariaDb (MigrationService : Sihl.Contract.Migration.Sig) : Sig = diff --git a/sihl-user/test/password_reset.ml b/sihl-user/test/password_reset.ml index 53f61608..cfeb78fc 100644 --- a/sihl-user/test/password_reset.ml +++ b/sihl-user/test/password_reset.ml @@ -1,8 +1,8 @@ open Alcotest_lwt module Make - (UserService : Sihl.Contract.User.Sig) - (PasswordResetService : Sihl.Contract.Password_reset.Sig) = + (UserService : Sihl.Contract.User.Sig) + (PasswordResetService : Sihl.Contract.Password_reset.Sig) = struct let reset_password_suceeds _ () = let%lwt () = Sihl.Cleaner.clean_all () in diff --git a/sihl.opam b/sihl.opam index 2d9717ab..9839f174 100644 --- a/sihl.opam +++ b/sihl.opam @@ -15,7 +15,7 @@ bug-reports: "https://github.com/oxidizing/sihl/issues" depends: [ "dune" {>= "2.7"} "ocaml" {>= "4.12.0"} - "conformist" {>= "0.6.0"} + "conformist" {>= "0.8.1"} "dune-build-info" {>= "2.8.4"} "tsort" {>= "2.0.0"} "containers" {>= "3.6.1"} @@ -27,11 +27,10 @@ depends: [ "ppx_deriving_yojson" {>= "3.5.2"} "tls" {>= "0.11.1"} "ssl" {>= "0.5.9"} - "uuidm" {>= "0.9.7"} "lwt_ssl" {>= "1.1.3"} "lwt_ppx" {>= "2.0.1"} - "caqti" {>= "1.8.0"} - "caqti-lwt" {>= "1.3.0"} + "caqti" {>= "2.0.1"} + "caqti-lwt" {>= "2.0.1"} "safepass" {>= "3.0"} "jwto" {>= "0.3.0"} "uuidm" {>= "0.9.7"} @@ -42,8 +41,9 @@ depends: [ "opium" {>= "0.20.0"} "cohttp-lwt-unix" {>= "2.5.4" & with-test} "alcotest-lwt" {>= "1.4.0" & with-test} - "caqti-driver-postgresql" {>= "1.8.0" & with-test} - "caqti-driver-mariadb" {>= "1.8.0" & with-test} + "mariadb" {>= "1.1.6"} + "caqti-driver-postgresql" {>= "2.0.1" & with-test} + "caqti-driver-mariadb" {>= "2.0.1" & with-test} "odoc" {with-doc} ] build: [ diff --git a/sihl.opam.locked b/sihl.opam.locked index 94118fa5..bcf8fe6c 100644 --- a/sihl.opam.locked +++ b/sihl.opam.locked @@ -15,45 +15,41 @@ depends: [ "angstrom" {= "0.15.0"} "asn1-combinators" {= "0.2.6"} "astring" {= "0.8.5"} - "base" {= "v0.14.3"} - "base-bigarray" {= "base"} + "base" {= "v0.16.3"} "base-bytes" {= "base"} "base-threads" {= "base"} "base-unix" {= "base"} - "base64" {= "3.5.0"} + "base64" {= "3.5.1"} "bigarray-compat" {= "1.1.0"} - "bigstringaf" {= "0.8.0"} - "biniou" {= "1.2.1"} + "bigstringaf" {= "0.9.1"} "bos" {= "0.2.1"} - "caqti" {= "1.8.0"} - "caqti-lwt" {= "1.8.0"} - "cmdliner" {= "1.0.4"} + "caqti" {= "2.0.1"} + "caqti-lwt" {= "2.0.1"} + "cmdliner" {= "1.2.0"} "conf-gmp" {= "4"} "conf-gmp-powm-sec" {= "3"} "conf-libev" {= "4-12"} - "conf-libssl" {= "3"} - "conf-pkg-config" {= "2"} - "conformist" {= "0.8.0"} - "containers" {= "3.7"} - "cppo" {= "1.6.8"} + "conf-libssl" {= "4"} + "conf-pkg-config" {= "3"} + "conformist" {= "0.8.1"} + "containers" {= "3.12"} + "cppo" {= "1.6.9"} "cpuid" {= "0.1.2"} - "csexp" {= "1.5.1"} + "csexp" {= "1.5.2"} "cstruct" {= "6.0.1"} "cstruct-lwt" {= "6.0.1"} - "cstruct-sexp" {= "6.0.1"} - "digestif" {= "1.1.1"} + "digestif" {= "1.1.4"} "domain-name" {= "0.4.0"} - "dune" {= "3.0.3"} - "dune-build-info" {= "3.0.3"} - "dune-configurator" {= "3.0.3"} - "duration" {= "0.2.0"} - "easy-format" {= "1.3.2"} + "dune" {= "3.11.1"} + "dune-build-info" {= "3.11.1"} + "dune-configurator" {= "3.11.1"} + "duration" {= "0.2.1"} "either" {= "1.0.0"} - "eqaf" {= "0.8"} - "faraday" {= "0.8.1"} - "faraday-lwt" {= "0.8.1"} - "faraday-lwt-unix" {= "0.8.1"} - "fieldslib" {= "v0.14.0"} + "eqaf" {= "0.9"} + "faraday" {= "0.8.2"} + "faraday-lwt" {= "0.8.2"} + "faraday-lwt-unix" {= "0.8.2"} + "fieldslib" {= "v0.16.0"} "fmt" {= "0.9.0"} "fpath" {= "0.7.3"} "gmap" {= "0.3.0"} @@ -61,66 +57,63 @@ depends: [ "hmap" {= "0.8.1"} "httpaf" {= "0.7.1"} "httpaf-lwt-unix" {= "0.7.1"} - "ipaddr" {= "5.3.0"} - "ipaddr-sexp" {= "5.3.0"} + "ipaddr" {= "5.5.0"} "jwto" {= "0.4.0"} "logs" {= "0.7.0"} - "lwt" {= "5.5.0"} - "lwt_ppx" {= "2.0.3"} - "lwt_ssl" {= "1.1.3"} - "macaddr" {= "5.3.0"} - "magic-mime" {= "1.2.0"} - "mirage-crypto" {= "0.10.6"} - "mirage-crypto-ec" {= "0.10.6"} - "mirage-crypto-pk" {= "0.10.6"} - "mirage-crypto-rng" {= "0.10.6"} + "lwt" {= "5.7.0"} + "lwt-dllist" {= "1.0.1"} + "lwt_ppx" {= "2.1.0"} + "lwt_ssl" {= "1.2.0"} + "macaddr" {= "5.5.0"} + "magic-mime" {= "1.3.1"} + "mirage-crypto" {= "0.11.2"} + "mirage-crypto-ec" {= "0.11.2"} + "mirage-crypto-pk" {= "0.11.2"} + "mirage-crypto-rng" {= "0.11.2"} "mirage-no-solo5" {= "1"} "mirage-no-xen" {= "1"} - "mmap" {= "1.2.0"} - "mtime" {= "1.4.0"} + "mtime" {= "2.0.0"} "multipart-form-data" {= "0.3.0"} "nocrypto" {= "0.5.4-2"} "num" {= "1.4"} - "ocaml" {= "4.12.1"} - "ocaml-base-compiler" {= "4.12.1"} + "ocaml" {= "4.14.1"} "ocaml-compiler-libs" {= "v0.12.4"} "ocaml-syntax-shims" {= "1.0.0"} - "ocamlbuild" {= "0.14.1"} - "ocamlfind" {= "1.9.3"} + "ocamlbuild" {= "0.14.2"} + "ocamlfind" {= "1.9.6"} "ocb-stubblr" {= "0.1.1-1"} "ocplib-endian" {= "1.2"} "opium" {= "0.20.0"} - "parsexp" {= "v0.14.2"} + "parsexp" {= "v0.16.0"} "pbkdf" {= "1.2.0"} - "ppx_cstruct" {= "6.0.1"} "ppx_derivers" {= "1.2.1"} "ppx_deriving" {= "5.2.1"} - "ppx_deriving_yojson" {= "3.6.1"} - "ppx_fields_conv" {= "v0.14.2"} - "ppx_sexp_conv" {= "v0.14.3"} - "ppxlib" {= "0.25.0"} - "ptime" {= "1.0.0"} - "re" {= "1.10.3"} + "ppx_deriving_yojson" {= "3.7.0"} + "ppx_fields_conv" {= "v0.16.0"} + "ppx_sexp_conv" {= "v0.16.0"} + "ppxlib" {= "0.31.0"} + "ptime" {= "1.1.0"} + "re" {= "1.11.0"} "result" {= "1.5"} "rock" {= "0.20.0"} "rresult" {= "0.7.0"} "safepass" {= "3.1"} "seq" {= "base"} - "sexplib" {= "v0.14.0"} - "sexplib0" {= "v0.14.0"} - "ssl" {= "0.5.10"} + "sexplib" {= "v0.16.0"} + "sexplib0" {= "v0.16.0"} + "ssl" {= "0.7.0"} "stdlib-shims" {= "0.3.0"} "stringext" {= "1.6.0"} - "tls" {= "0.15.3"} - "topkg" {= "1.0.5"} + "tls" {= "0.17.1"} + "topkg" {= "1.0.7"} "tsort" {= "2.1.0"} - "tyxml" {= "4.5.0"} - "uri" {= "4.2.0"} - "uuidm" {= "0.9.7"} + "tyxml" {= "4.6.0"} + "uri" {= "4.4.0"} + "uuidm" {= "0.9.8"} "uutf" {= "1.0.3"} - "x509" {= "0.16.0"} - "yojson" {= "1.7.0"} - "zarith" {= "1.12"} + "x509" {= "0.16.5"} + "yojson" {= "2.1.1"} + "zarith" {= "1.13"} ] build: [ ["dune" "subst"] {dev} @@ -138,7 +131,3 @@ build: [ ] dev-repo: "git+https://github.com/oxidizing/sihl.git" name: "sihl" -pin-depends: [ - "ocaml-base-compiler.4.12.1" - "https://github.com/ocaml/ocaml/archive/4.12.1.tar.gz" -] diff --git a/sihl/src/contract_database.ml b/sihl/src/contract_database.ml index f0fc68e8..b70b7d36 100644 --- a/sihl/src/contract_database.ml +++ b/sihl/src/contract_database.ml @@ -13,8 +13,8 @@ module type Sig = sig type 'a prepared_search_request val prepare_requests : string -> string -> string -> string - (* Deprecated in 0.6.0 *) - [@@deprecated "Use prepare_search_request instead"] + (* Deprecated in 0.6.0 *) + [@@deprecated "Use prepare_search_request instead"] (** [prepare_search_request ~search_query ~count_query ~filter_fragment ?sort_by_field type] @@ -59,8 +59,8 @@ module type Sig = sig -> 'c option -> 'a -> ('b list * int) Lwt.t - (* Deprecated in 0.6.0 *) - [@@deprecated "Use run_search_request instead"] + (* Deprecated in 0.6.0 *) + [@@deprecated "Use run_search_request instead"] (** [run_search_request ?ctx prepared_request sort filter ~limit ~offset] runs the [prepared_request] and returns a partial result of the whole stored @@ -107,7 +107,7 @@ module type Sig = sig val fetch_pool : ?ctx:(string * string) list -> unit - -> (Caqti_lwt.connection, Caqti_error.t) Caqti_lwt.Pool.t + -> (Caqti_lwt.connection, Caqti_error.t) Caqti_lwt_unix.Pool.t (** [add_pool ~pool_size name database_url] creates a connection pool with a unique [name]. Creation fails if a pool with the same name was already diff --git a/sihl/src/contract_queue.ml b/sihl/src/contract_queue.ml index 269a0178..ae169c49 100644 --- a/sihl/src/contract_queue.ml +++ b/sihl/src/contract_queue.ml @@ -81,13 +81,13 @@ let default_error_handler ?(ctx = []) msg (instance : instance) = in Lwt.return @@ Logs.err (fun m -> - m - "%s Job with id '%s' and name '%s' failed for input '%s': %s" - ctx - instance.id - instance.name - instance.input - msg) + m + "%s Job with id '%s' and name '%s' failed for input '%s': %s" + ctx + instance.id + instance.name + instance.input + msg) ;; let create_job diff --git a/sihl/src/contract_user.ml b/sihl/src/contract_user.ml index 14f8eac3..83f8d8a8 100644 --- a/sihl/src/contract_user.ml +++ b/sihl/src/contract_user.ml @@ -203,7 +203,7 @@ module type Sig = sig -> email:string -> username:string option -> t Lwt.t - [@@deprecated "Use update() instead"] + [@@deprecated "Use update() instead"] (** [set_password ?ctx ?policy user ~password ~password_confirmation] overrides the current password of a [user] and returns that user. @@ -267,9 +267,9 @@ module type Sig = sig -> password:string -> password_confirmation:string -> ( t - , [ `Already_registered | `Invalid_password_provided of string ] ) - Result.t - Lwt.t + , [ `Already_registered | `Invalid_password_provided of string ] ) + Result.t + Lwt.t (** [login ?ctx email ~password] returns the user associated with [email] if [password] matches the current password. *) diff --git a/sihl/src/core_app.ml b/sihl/src/core_app.ml index e1c15240..7d98e797 100644 --- a/sihl/src/core_app.ml +++ b/sihl/src/core_app.ml @@ -40,32 +40,35 @@ let start_cmd services = "Starts the Sihl app including all registered services and the HTTP \ server." (fun _ -> - let normal_services = - List.filter - (fun service -> not (Core_container.Service.server service)) - services - in - let server_services = List.filter Core_container.Service.server services in - match server_services with - | [ server ] -> - let%lwt _ = Core_container.start_services normal_services in - let%lwt () = Core_container.Service.start server in - run_forever () - | [] -> - Logger.err (fun m -> - m - "No 'server' service registered. Make sure that you have one server \ - service registered in your 'run.ml' such as a HTTP service"); - raise (Exception "No server service registered") - | servers -> - let names = List.map Core_container.Service.name servers in - let names = String.concat ", " names in - Logger.err (fun m -> - m - "Multiple server services registered: '%s', you can only have one \ - service registered that is a 'server' service." - names); - raise (Exception "Multiple server services registered")) + let normal_services = + List.filter + (fun service -> not (Core_container.Service.server service)) + services + in + let server_services = + List.filter Core_container.Service.server services + in + match server_services with + | [ server ] -> + let%lwt _ = Core_container.start_services normal_services in + let%lwt () = Core_container.Service.start server in + run_forever () + | [] -> + Logger.err (fun m -> + m + "No 'server' service registered. Make sure that you have one \ + server service registered in your 'run.ml' such as a HTTP \ + service"); + raise (Exception "No server service registered") + | servers -> + let names = List.map Core_container.Service.name servers in + let names = String.concat ", " names in + Logger.err (fun m -> + m + "Multiple server services registered: '%s', you can only have one \ + service registered that is a 'server' service." + names); + raise (Exception "Multiple server services registered")) ;; let run' ?(commands = []) ?(log_reporter = Core_log.default_reporter) ?args app = diff --git a/sihl/src/core_configuration.ml b/sihl/src/core_configuration.ml index ebf510c0..e7c3794d 100644 --- a/sihl/src/core_configuration.ml +++ b/sihl/src/core_configuration.ml @@ -65,10 +65,10 @@ let envs_to_kv envs = envs |> List.map (String.split_on_char '=') |> List.map (function - | [] -> "", "" - | [ key ] -> key, "" - | [ key; value ] -> key, value - | key :: values -> key, String.concat "" values) + | [] -> "", "" + | [ key ] -> key, "" + | [ key; value ] -> key, value + | key :: values -> key, String.concat "" values) ;; (* .env file handling *) @@ -242,21 +242,21 @@ let require schema = read schema |> ignore let configuration_to_string (configurations : t) : string = configurations |> List.map (fun { name; description; type_; default } -> - match default with - | Some default -> - Format.sprintf - {| + match default with + | Some default -> + Format.sprintf + {| %s %s Type: %s Default: %s |} - name - description - type_ - default - | None -> - Format.sprintf {| + name + description + type_ + default + | None -> + Format.sprintf {| %s %s Type: %s @@ -270,20 +270,20 @@ let print_cmd (configurations : t list) : Core_command.t = ~name:"config" ~description:"Prints a list of configurations that are known to Sihl." (fun _ -> - configurations - |> List.filter (fun configuration -> List.length configuration > 0) - |> List.concat - |> List.sort (fun c1 c2 -> + configurations + |> List.filter (fun configuration -> List.length configuration > 0) + |> List.concat + |> List.sort (fun c1 c2 -> (* We want to show required configurations first. *) match c1.default, c2.default with | Some _, Some _ -> 0 | Some _, None -> 1 | None, Some _ -> -1 | None, None -> 0) - |> configuration_to_string - |> print_endline - |> Option.some - |> Lwt.return) + |> configuration_to_string + |> print_endline + |> Option.some + |> Lwt.return) ;; let commands configurations = [ print_cmd configurations ] diff --git a/sihl/src/core_lifecycle.ml b/sihl/src/core_lifecycle.ml index dee4ea6d..620eab51 100644 --- a/sihl/src/core_lifecycle.ml +++ b/sihl/src/core_lifecycle.ml @@ -69,10 +69,10 @@ let top_sort_lifecycles lifecycles = |> Map.to_seq |> List.of_seq |> List.map (fun (id, lifecycle) -> - let dependencies = - lifecycle.dependencies () |> List.map (fun dep -> dep.id) - in - id, dependencies) + let dependencies = + lifecycle.dependencies () |> List.map (fun dep -> dep.id) + in + id, dependencies) in Logs.debug (fun m -> m @@ -84,21 +84,21 @@ let top_sort_lifecycles lifecycles = m "Pre sorted lifecycle graph: %s" ([%show: int list] sorted)); sorted |> List.map (fun id -> - match Map.find_opt id lifecycles with - | Some l -> l - | None -> - Logs.err (fun m -> - m - "Failed to sort lifecycles. Lifecycce id %d not found in \ - registered lifecycles: %a" - id - pp_map - lifecycles); - Logs.info (fun m -> - m - "It looks like a service or command is depending on a service \ - that has not lifecycle registered."); - raise Exception) + match Map.find_opt id lifecycles with + | Some l -> l + | None -> + Logs.err (fun m -> + m + "Failed to sort lifecycles. Lifecycce id %d not found in \ + registered lifecycles: %a" + id + pp_map + lifecycles); + Logs.info (fun m -> + m + "It looks like a service or command is depending on a service that \ + has not lifecycle registered."); + raise Exception) | Tsort.ErrorCycle remaining_ids -> let remaining_names = List.map diff --git a/sihl/src/core_random.ml b/sihl/src/core_random.ml index 23a897f6..c54ef194 100644 --- a/sihl/src/core_random.ml +++ b/sihl/src/core_random.ml @@ -1,8 +1,8 @@ -let () = Caml.Random.self_init () +let () = Stdlib.Random.self_init () let rec chars result n = if n > 0 - then chars (List.cons (Char.chr (Caml.Random.int 255)) result) (n - 1) + then chars (List.cons (Char.chr (Stdlib.Random.int 255)) result) (n - 1) else result |> List.to_seq |> String.of_seq ;; diff --git a/sihl/src/core_time.mli b/sihl/src/core_time.mli index 60695ef1..06427a1d 100644 --- a/sihl/src/core_time.mli +++ b/sihl/src/core_time.mli @@ -11,47 +11,47 @@ type duration = "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val duration_to_yojson : duration -> Yojson.Safe.t - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val duration_of_yojson : Yojson.Safe.t -> duration Ppx_deriving_yojson_runtime.error_or - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val pp_duration : Format.formatter -> duration -> unit - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val show_duration : duration -> string - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val equal_duration : duration -> duration -> bool - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val duration_to_span : duration -> Ptime.span - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val date_from_now : Ptime.t -> duration -> Ptime.t - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val ptime_to_yojson : Ptime.t -> [> `String of string ] - [@@ocaml.deprecation - "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] +[@@ocaml.deprecation + "Sihl.Time.duration is deprecated, use [Sihl.Time.Span] instead"] val ptime_of_yojson : Yojson.Safe.t -> (Ptime.t, string) result - [@@ocaml.deprecation "Sihl.Time.ptime* are deprecated"] +[@@ocaml.deprecation "Sihl.Time.ptime* are deprecated"] val ptime_of_date_string : string -> (Ptime.t, string) result - [@@ocaml.deprecation "Sihl.Time.ptime* are deprecated"] +[@@ocaml.deprecation "Sihl.Time.ptime* are deprecated"] val ptime_to_date_string : Ptime.t -> string - [@@ocaml.deprecation "Sihl.Time.ptime* are deprecated"] +[@@ocaml.deprecation "Sihl.Time.ptime* are deprecated"] module Span : sig val seconds : int -> Ptime.span diff --git a/sihl/src/database.ml b/sihl/src/database.ml index 451b5352..1a1abecd 100644 --- a/sihl/src/database.ml +++ b/sihl/src/database.ml @@ -5,13 +5,15 @@ let log_src = Logs.Src.create "sihl.service.database" module Logs = (val Logs.src_log log_src : Logs.LOG) let main_pool_ref - : (Caqti_lwt.connection, Caqti_error.t) Caqti_lwt.Pool.t option ref + : (Caqti_lwt.connection, Caqti_error.t) Caqti_lwt_unix.Pool.t option ref = ref None ;; let pools - : (string, (Caqti_lwt.connection, Caqti_error.t) Caqti_lwt.Pool.t) Hashtbl.t + : ( string + , (Caqti_lwt.connection, Caqti_error.t) Caqti_lwt_unix.Pool.t ) + Hashtbl.t = Hashtbl.create 100 ;; @@ -40,9 +42,9 @@ let prepare_search_request : 'a prepared_search_request = let open Caqti_request.Infix in - let output_type = Caqti_type.(tup2 int output_type) in + let output_type = Caqti_type.(t2 int output_type) in let asc_request = - let input_type = Caqti_type.(tup2 int int) in + let input_type = Caqti_type.(t2 int int) in let query = Printf.sprintf "%s ORDER BY %s ASC %s" @@ -53,7 +55,7 @@ let prepare_search_request query |> input_type ->* output_type in let desc_request = - let input_type = Caqti_type.(tup2 int int) in + let input_type = Caqti_type.(t2 int int) in let query = Printf.sprintf "%s ORDER BY %s DESC %s" @@ -64,7 +66,7 @@ let prepare_search_request query |> input_type ->* output_type in let filter_asc_request = - let input_type = Caqti_type.(tup3 string int int) in + let input_type = Caqti_type.(t3 string int int) in let query = Printf.sprintf "%s %s ORDER BY %s ASC %s" @@ -76,7 +78,7 @@ let prepare_search_request query |> input_type ->* output_type in let filter_desc_request = - let input_type = Caqti_type.(tup3 string int int) in + let input_type = Caqti_type.(t3 string int int) in let query = Printf.sprintf "%s %s ORDER BY %s DESC %s" @@ -142,7 +144,7 @@ let schema = ;; let print_pool_usage pool = - let n_connections = Caqti_lwt.Pool.size pool in + let n_connections = Caqti_lwt_unix.Pool.size pool in let max_connections = Option.value (Core_configuration.read schema).pool_size ~default:10 in @@ -179,21 +181,23 @@ let fetch_pool ?(ctx = []) () = Logs.info (fun m -> m "Create pool with size %i" pool_size); (Core_configuration.read schema).url |> Uri.of_string - |> Caqti_lwt.connect_pool ~max_size:pool_size + |> Caqti_lwt_unix.connect_pool + ~pool_config:(Caqti_pool_config.create ~max_size:pool_size ()) |> (function - | Ok pool -> - main_pool_ref := Some pool; - pool - | Error err -> - let msg = "Failed to connect to DB pool" in - Logs.err (fun m -> m "%s %s" msg (Caqti_error.show err)); - raise (Contract_database.Exception ("Failed to create pool: " ^ msg))) + | Ok pool -> + main_pool_ref := Some pool; + pool + | Error err -> + let msg = "Failed to connect to DB pool" in + Logs.err (fun m -> m "%s %s" msg (Caqti_error.show err)); + raise (Contract_database.Exception ("Failed to create pool: " ^ msg))) ;; let add_pool ?(pool_size = 10) name database_url = database_url |> Uri.of_string - |> Caqti_lwt.connect_pool ~max_size:pool_size + |> Caqti_lwt_unix.connect_pool + ~pool_config:(Caqti_pool_config.create ~max_size:pool_size ()) |> function | Ok pool -> if Option.is_some (Hashtbl.find_opt pools name) @@ -216,7 +220,7 @@ let drop_pool name = Logs.warn (fun m -> m "Connection pool with name '%s' doesn't exist" name); Lwt.return_unit | Some connection -> - let%lwt () = Caqti_lwt.Pool.drain connection in + let%lwt () = Caqti_lwt_unix.Pool.drain connection in let () = Hashtbl.remove pools name in Lwt.return_unit ;; @@ -231,7 +235,7 @@ let transaction ?ctx f = let pool = fetch_pool ?ctx () in print_pool_usage pool; let%lwt result = - Caqti_lwt.Pool.use + Caqti_lwt_unix.Pool.use (fun connection -> Logs.debug (fun m -> m "Fetched connection from pool"); let (module Connection : Caqti_lwt.CONNECTION) = connection in @@ -318,10 +322,8 @@ let query ?ctx f = let pool = fetch_pool ?ctx () in print_pool_usage pool; let%lwt result = - Caqti_lwt.Pool.use - (fun connection -> - let module Connection = (val connection : Caqti_lwt.CONNECTION) in - f connection |> Lwt.map Result.ok) + Caqti_lwt_unix.Pool.use + (fun connection -> f connection |> Lwt.map Result.ok) pool in match result with diff --git a/sihl/src/database_migration.ml b/sihl/src/database_migration.ml index ff2109ee..4d1ab988 100644 --- a/sihl/src/database_migration.ml +++ b/sihl/src/database_migration.ml @@ -81,7 +81,7 @@ struct m "Found duplicate migration '%s', ignoring it" label) | None -> registered_migrations - := Map.add label (snd migration) !registered_migrations + := Map.add label (snd migration) !registered_migrations ;; let register_migrations migrations = List.iter register_migration migrations @@ -223,7 +223,7 @@ struct let migration_states_namespaces = migrations_states |> List.map (fun migration_state -> - migration_state.Database_migration_repo.Migration.namespace) + migration_state.Database_migration_repo.Migration.namespace) in let registered_migrations_namespaces = Map.to_seq migrations_to_check |> List.of_seq |> List.map fst @@ -334,9 +334,9 @@ struct ~name:"migrate" ~description:"Runs all pending migrations." (fun _ -> - let%lwt () = Database.start () in - let%lwt () = start () in - run_all () |> Lwt.map Option.some) + let%lwt () = Database.start () in + let%lwt () = start () in + run_all () |> Lwt.map Option.some) ;; let lifecycle = diff --git a/sihl/src/database_migration_repo.ml b/sihl/src/database_migration_repo.ml index 89d005b5..3e335c5b 100644 --- a/sihl/src/database_migration_repo.ml +++ b/sihl/src/database_migration_repo.ml @@ -56,7 +56,7 @@ let get_request table = WHERE namespace = ? |sql} table - |> Caqti_type.(string ->? tup3 string int bool) + |> Caqti_type.(string ->? t3 string int bool) ;; let get ?ctx table ~namespace = @@ -75,7 +75,7 @@ let get_all_request table = FROM %s |sql} table - |> Caqti_type.(unit ->* tup3 string int bool) + |> Caqti_type.(unit ->* t3 string int bool) ;; let get_all ?ctx table = @@ -125,7 +125,7 @@ module MariaDb : Sig = struct dirty = VALUES(dirty) |sql} table - |> Caqti_type.(tup3 string int bool ->. unit) + |> Caqti_type.(t3 string int bool ->. unit) ;; let upsert ?ctx table state = @@ -174,7 +174,7 @@ module PostgreSql : Sig = struct dirty = EXCLUDED.dirty |sql} table - |> Caqti_type.(tup3 string int bool ->. unit) + |> Caqti_type.(t3 string int bool ->. unit) ;; let upsert ?ctx table state = diff --git a/sihl/src/dune b/sihl/src/dune index 39d4f53c..2eeee8e0 100644 --- a/sihl/src/dune +++ b/sihl/src/dune @@ -3,8 +3,8 @@ (public_name sihl) (libraries sexplib fmt fmt.tty logs logs.fmt lwt lwt.unix tsort conformist base64 yojson ppx_deriving_yojson.runtime safepass ptime ptime.clock.os - jwto uuidm opium caqti-lwt str dune-build-info bos containers nocrypto - nocrypto.unix cstruct) + jwto uuidm opium caqti-lwt caqti-lwt.unix str dune-build-info bos + containers nocrypto nocrypto.unix cstruct) (preprocess (pps ppx_fields_conv ppx_deriving_yojson ppx_deriving.eq ppx_deriving.show ppx_deriving.make ppx_sexp_conv lwt_ppx))) diff --git a/sihl/src/gen_core.ml b/sihl/src/gen_core.ml index 9dec2e7c..9f9dd762 100644 --- a/sihl/src/gen_core.ml +++ b/sihl/src/gen_core.ml @@ -53,11 +53,10 @@ let schema_of_string (s : string list) : (schema, string) result = s |> List.map (String.split_on_char ':') |> List.map (fun s -> - match s with - | [ name; type_ ] -> Ok (name, type_) - | _ -> - Error - (Format.sprintf "Invalid input provided '%s'" (String.concat ":" s))) + match s with + | [ name; type_ ] -> Ok (name, type_) + | _ -> + Error (Format.sprintf "Invalid input provided '%s'" (String.concat ":" s))) |> List.fold_left (fun schema next -> match schema, next with diff --git a/sihl/src/gen_entity.ml b/sihl/src/gen_entity.ml index bfcbaeb6..6b611640 100644 --- a/sihl/src/gen_entity.ml +++ b/sihl/src/gen_entity.ml @@ -30,7 +30,7 @@ let[@warning "-45"] schema let entity_type (schema : Gen_core.schema) = schema |> List.map (fun (name, type_) -> - Format.sprintf "%s: %s" name (Gen_core.ocaml_type_of_gen_type type_)) + Format.sprintf "%s: %s" name (Gen_core.ocaml_type_of_gen_type type_)) |> String.concat ";" |> Format.sprintf ";%s" ;; @@ -53,10 +53,7 @@ let created_value (schema : Gen_core.schema) = let conformist_fields (schema : Gen_core.schema) = schema |> List.map (fun (name, type_) -> - Format.sprintf - {|%s "%s"|} - (Gen_core.conformist_type_of_gen_type type_) - name) + Format.sprintf {|%s "%s"|} (Gen_core.conformist_type_of_gen_type type_) name) |> String.concat "; " ;; diff --git a/sihl/src/gen_migration.ml b/sihl/src/gen_migration.ml index 281ce98d..a070d77a 100644 --- a/sihl/src/gen_migration.ml +++ b/sihl/src/gen_migration.ml @@ -73,14 +73,14 @@ let type_of_gen_type_mariadb (t : Gen_core.gen_type) : string = let migration_schema_postgresql (schema : Gen_core.schema) = schema |> List.map (fun (name, type_) -> - Format.sprintf "%s %s" name (type_of_gen_type_postgresql type_)) + Format.sprintf "%s %s" name (type_of_gen_type_postgresql type_)) |> String.concat ",\n " ;; let migration_schema_mariadb (schema : Gen_core.schema) = schema |> List.map (fun (name, type_) -> - Format.sprintf "%s %s" name (type_of_gen_type_mariadb type_)) + Format.sprintf "%s %s" name (type_of_gen_type_mariadb type_)) |> String.concat ",\n " ;; diff --git a/sihl/src/gen_repo.ml b/sihl/src/gen_repo.ml index cd4d4909..bd5bc67d 100644 --- a/sihl/src/gen_repo.ml +++ b/sihl/src/gen_repo.ml @@ -220,10 +220,10 @@ let caqti_type (schema : Gen_core.schema) = | [ el1; el2 ] -> let el1 = Gen_core.caqti_type_of_gen_type el1 in let el2 = Gen_core.caqti_type_of_gen_type el2 in - Format.sprintf "(tup2 %s %s)" el1 el2 + Format.sprintf "(t2 %s %s)" el1 el2 | el1 :: rest -> let el1 = Gen_core.caqti_type_of_gen_type el1 in - Format.sprintf "(tup2 %s %s)" el1 (loop rest) + Format.sprintf "(t2 %s %s)" el1 (loop rest) | [] -> failwith "Empty schema provided" in let types = @@ -238,10 +238,10 @@ let caqti_type_update (schema : Gen_core.schema) = | [ el1; el2 ] -> let el1 = Gen_core.caqti_type_of_gen_type el1 in let el2 = Gen_core.caqti_type_of_gen_type el2 in - Format.sprintf "(tup2 %s %s)" el1 el2 + Format.sprintf "(t2 %s %s)" el1 el2 | el1 :: rest -> let el1 = Gen_core.caqti_type_of_gen_type el1 in - Format.sprintf "(tup2 %s %s)" el1 (loop rest) + Format.sprintf "(t2 %s %s)" el1 (loop rest) | [] -> failwith "Empty schema provided" in let types = List.cons Gen_core.String (List.map snd schema) in diff --git a/sihl/src/gen_view.ml b/sihl/src/gen_view.ml index d10cb210..5657463b 100644 --- a/sihl/src/gen_view.ml +++ b/sihl/src/gen_view.ml @@ -355,7 +355,7 @@ let stringify name module_name (field_name, type_) = let table_rows name module_name (schema : Gen_core.schema) = schema |> List.map (fun field -> - Format.sprintf "\"\"%s\"\"" (stringify name module_name field)) + Format.sprintf "\"\"%s\"\"" (stringify name module_name field)) |> String.concat "\n" ;; @@ -363,11 +363,11 @@ let form_values schema = schema |> List.map fst |> List.map (fun name -> - Format.sprintf - "let old_%s, %s_error = Sihl.Web.Rest.find_form \"%s\" form in" - name - name - name) + Format.sprintf + "let old_%s, %s_error = Sihl.Web.Rest.find_form \"%s\" form in" + name + name + name) |> String.concat "\n" ;; @@ -411,8 +411,8 @@ let checkbox field_name field_type = let default_values name module_name schema = schema |> List.map (fun (field_name, field_type) -> - Format.sprintf - {| + Format.sprintf + {| let current_%s = %s |> Option.map (fun (%s : %s.t) -> %s.%s.%s) @@ -420,15 +420,15 @@ let default_values name module_name schema = in %s |} - field_name - name - name - module_name - name - module_name - field_name - (default_value field_type) - (checkbox field_name field_type)) + field_name + name + name + module_name + name + module_name + field_name + (default_value field_type) + (checkbox field_name field_type)) |> String.concat "\n" ;; @@ -490,17 +490,17 @@ let alert (field_name, _) = let form_elements schema = schema |> List.map (fun field -> - Format.sprintf - {| + Format.sprintf + {|
%s
%s |} - (String.capitalize_ascii (fst field)) - (form_input field) - (alert field)) + (String.capitalize_ascii (fst field)) + (form_input field) + (alert field)) |> String.concat "\n" |> unescape_template ;; @@ -508,10 +508,10 @@ let form_elements schema = let show name module_name (schema : Gen_core.schema) = schema |> List.map (fun field -> - Format.sprintf - {|"
%s: " %s "
"|} - (fst field) - (stringify name module_name field)) + Format.sprintf + {|"
%s: " %s "
"|} + (fst field) + (stringify name module_name field)) |> String.concat "\n" |> fun fields -> Format.sprintf @@ -526,8 +526,8 @@ let has_datetime schema = schema |> List.map snd |> List.find_opt (function - | Datetime -> true - | Int | Float | String | Bool -> false) + | Datetime -> true + | Int | Float | String | Bool -> false) |> Option.map (fun _ -> true) |> Option.value ~default:false ;; diff --git a/sihl/src/web_csrf.ml b/sihl/src/web_csrf.ml index dd9b7648..4c93d0a2 100644 --- a/sihl/src/web_csrf.ml +++ b/sihl/src/web_csrf.ml @@ -212,8 +212,8 @@ let middleware multipart >>= List.assoc_opt input_name |> (function - | None -> Opium.Request.urlencoded input_name req - | tkn -> Lwt.return tkn) + | None -> Opium.Request.urlencoded input_name req + | tkn -> Lwt.return tkn) |> Lwt.map (CCOption.flat_map Encrypted_token.of_uri_safe_string) in let stored_encrypted_token = diff --git a/sihl/src/web_http.ml b/sihl/src/web_http.ml index 5b66ff6d..22dfb7e4 100644 --- a/sihl/src/web_http.ml +++ b/sihl/src/web_http.ml @@ -17,12 +17,12 @@ let routers_to_opium_builders routers = let open Web in routers |> List.map (fun router -> - let routes = routes_of_router router in - routes - |> List.map (fun (meth, route, handler) -> - meth, Web.externalize_path route, handler) - |> List.map to_opium_builder - |> List.rev) + let routes = routes_of_router router in + routes + |> List.map (fun (meth, route, handler) -> + meth, Web.externalize_path route, handler) + |> List.map to_opium_builder + |> List.rev) |> List.concat ;; @@ -87,13 +87,13 @@ let routes_cmd = ~name:"routes" ~description:"Prints all HTTP routes" (fun _ -> - !registered_router - |> Option.map Web.routes_of_router - |> Option.map - @@ List.map (fun (meth, route, handler) -> + !registered_router + |> Option.map Web.routes_of_router + |> Option.map + @@ List.map (fun (meth, route, handler) -> meth, Web.externalize_path route, handler) - |> Option.value ~default:[] - |> List.map (fun (meth, path, _) -> + |> Option.value ~default:[] + |> List.map (fun (meth, path, _) -> let meth = Web.( match meth with @@ -107,10 +107,10 @@ let routes_cmd = | Any -> "ANY") in Format.sprintf "%s %s" meth path) - |> String.concat "\n" - |> print_endline - |> Option.some - |> Lwt.return) + |> String.concat "\n" + |> print_endline + |> Option.some + |> Lwt.return) ;; (* Lifecycle *) diff --git a/sihl/src/web_rest.ml b/sihl/src/web_rest.ml index 86c10c39..85491c80 100644 --- a/sihl/src/web_rest.ml +++ b/sihl/src/web_rest.ml @@ -20,7 +20,7 @@ module Form = struct errors |> List.find_opt (fun (field, _, _) -> String.equal field k) |> Option.map (fun (field, input, value) -> - field, CCList.head_opt input, Some value) + field, CCList.head_opt input, Some value) |> Option.value ~default:(k, CCList.head_opt v, None)) urlencoded in diff --git a/sihl/test/core_container.ml b/sihl/test/core_container.ml index 77793061..9ad56616 100644 --- a/sihl/test/core_container.ml +++ b/sihl/test/core_container.ml @@ -124,7 +124,7 @@ let order_multi_type_name_dependencies () = expected_impl_name (actual |> List.map (fun lifecycle -> - lifecycle.Sihl.Container.implementation_name))) + lifecycle.Sihl.Container.implementation_name))) ;; let suite = diff --git a/sihl/test/database.ml b/sihl/test/database.ml index 1fdf5e58..9bc935c1 100644 --- a/sihl/test/database.ml +++ b/sihl/test/database.ml @@ -141,7 +141,7 @@ let transaction_does_not_exhaust_pool _ () = let choose_database_pool _ () = let default_pool = Sihl.Database.fetch_pool () in (* make sure there is no default database pool *) - let%lwt () = Caqti_lwt.Pool.drain default_pool in + let%lwt () = Caqti_lwt_unix.Pool.drain default_pool in let database_url = Option.value ~default:"not found" @@ -164,7 +164,7 @@ let choose_database_pool _ () = let drop_database_pool _ () = let open Sihl.Database in - let%lwt () = fetch_pool () |> Caqti_lwt.Pool.drain in + let%lwt () = fetch_pool () |> Caqti_lwt_unix.Pool.drain in let database_url = Option.value ~default:"not found" diff --git a/sihl/test/web_session.ml b/sihl/test/web_session.ml index 54cda24c..c6939deb 100644 --- a/sihl/test/web_session.ml +++ b/sihl/test/web_session.ml @@ -177,14 +177,14 @@ let update_value _ () = |> Session.update_or_set_value ~key:(fst target1) (function - | None -> Alcotest.fail "value should be found" - | Some v -> Some (con ^ v)) + | None -> Alcotest.fail "value should be found" + | Some v -> Some (con ^ v)) req |> Session.update_or_set_value ~key:(fst target2) (function - | None -> Some (snd target2) - | Some _ -> Alcotest.fail "value should not be found") + | None -> Some (snd target2) + | Some _ -> Alcotest.fail "value should not be found") req |> Lwt.return in @@ -213,14 +213,14 @@ let delete_value _ () = |> Session.update_or_set_value ~key:(fst target1) (function - | None -> Alcotest.fail "value should be found" - | Some _ -> None) + | None -> Alcotest.fail "value should be found" + | Some _ -> None) req |> Session.update_or_set_value ~key:(fst target2) (function - | None -> None - | Some _ -> Alcotest.fail "value should not be found") + | None -> None + | Some _ -> Alcotest.fail "value should not be found") req |> Lwt.return in diff --git a/template/.devcontainer/Dockerfile b/template/.devcontainer/Dockerfile index 1e4fbe16..fbb2f900 100644 --- a/template/.devcontainer/Dockerfile +++ b/template/.devcontainer/Dockerfile @@ -1,16 +1,19 @@ -FROM node:14 AS node_base +FROM node:lts AS node FROM hadolint/hadolint:latest-alpine AS hadolint -FROM ocaml/opam:debian-ocaml-4.12 +FROM ocaml/opam:debian-10-ocaml-4.14 -# copy node from node_base container and link commands USER root -COPY --from=node_base /usr/local/lib/node_modules /usr/local/lib/node_modules -COPY --from=node_base /usr/local/bin/node /usr/local/bin/node -COPY --from=node_base /opt /opt + +# copy node from node container and link commands +COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules +COPY --from=node /usr/local/bin/node /usr/local/bin/node +COPY --from=node /opt /opt RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ + && ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \ && ln -s /usr/local/bin/node /usr/local/bin/nodejs \ && ln -s /opt/yarn-v*/bin/yarn /usr/local/bin/yarn \ && ln -s /opt/yarn-v*/bin/yarnpkg /usr/local/bin/yarnpkg + # copy hadolint COPY --from=hadolint /bin/hadolint /bin/hadolint @@ -18,51 +21,46 @@ COPY --from=hadolint /bin/hadolint /bin/hadolint ENV DEBIAN_FRONTEND noninteractive ENV SIHL_ENV development -RUN apt-get update -q && apt-get install -yqq \ - default-jre \ - # emacs-nox for emacs, but sihl cannot be installed without - emacs-nox \ - git \ +# install packages +# hadolint ignore=DL3008 +RUN apt-get update -q && apt-get install -yqq --no-install-recommends \ + # development dependencies inotify-tools \ + zsh \ + m4 \ + wget \ + # + # build dependencies (would also be installed by opam depext) + gcc \ libev-dev \ - libffi-dev \ - libfontconfig \ libgmp-dev \ libmariadb-dev \ libpq-dev \ - libqt5gui5 \ libssl-dev \ - lsof \ - m4 \ - pdftk-java \ - perl \ pkg-config \ - utop \ - wget \ - wkhtmltopdf \ - xvfb \ - zip \ - zlib1g-dev \ - zsh \ # # cleanup installations && apt-get autoremove -y \ && apt-get clean all \ - # - # add timezone - && ln -fs /usr/share/zoneinfo/Europe/Zurich /etc/localtime + && rm -rf /var/lib/apt/lists/* + +# add timezone +RUN ln -fs /usr/share/zoneinfo/Europe/Zurich /etc/localtime # WTF: https://github.com/mirage/ocaml-cohttp/issues/675 RUN bash -c 'echo "http 80/tcp www # WorldWideWeb HTTP" >> /etc/services' \ - bash -c 'echo "https 443/tcp www # WorldWideWeb HTTPS" >> /etc/services' + && bash -c 'echo "https 443/tcp www # WorldWideWeb HTTPS" >> /etc/services' -# Switch back to dialog for any ad-hoc use of apt-get -ENV DEBIAN_FRONTEND=dialog USER opam # install oh-my-zsh +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN wget https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -q -O - | zsh \ && cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc \ + && sed -i "/^plugins=/c\plugins=(git dotenv)" ~/.zshrc \ # # link make to devcontainer makefile && echo 'alias make="make -f /workspace/.devcontainer/Makefile"' >> ~/.zshrc + +# Switch back to dialog for any ad-hoc use of apt-get +ENV DEBIAN_FRONTEND=dialog diff --git a/template/app/command/command.mli b/template/app/command/command.mli new file mode 100644 index 00000000..fe703cee --- /dev/null +++ b/template/app/command/command.mli @@ -0,0 +1 @@ +val multiply : Sihl.Command.t diff --git a/template/app/schedule/schedule.mli b/template/app/schedule/schedule.mli new file mode 100644 index 00000000..e31965f7 --- /dev/null +++ b/template/app/schedule/schedule.mli @@ -0,0 +1 @@ +val hello : Sihl.Schedule.t diff --git a/template/dune b/template/dune index cb66dfe8..972375b5 100644 --- a/template/dune +++ b/template/dune @@ -1,4 +1,4 @@ (env (dev (flags - (:standard -open StdLabels -w +A-48-42-44 -warn-error +A-3)))) + (:standard -open StdLabels -w +A-48-42-44-70 -warn-error +A-3)))) diff --git a/template/routes/routes.mli b/template/routes/routes.mli new file mode 100644 index 00000000..ea521477 --- /dev/null +++ b/template/routes/routes.mli @@ -0,0 +1,13 @@ +val global_middlewares : Rock.Middleware.t list + +module Site : sig + val hello : Sihl.Web.router + val middlewares : Rock.Middleware.t list +end + +module Api : sig + val hello : Sihl.Web.router + val middlewares : Rock.Middleware.t list +end + +val router : Sihl.Web.router diff --git a/template/run/run.mli b/template/run/run.mli new file mode 100644 index 00000000..c7f21dba --- /dev/null +++ b/template/run/run.mli @@ -0,0 +1 @@ +val services : Sihl.Container.Service.t list diff --git a/template/service/service.mli b/template/service/service.mli new file mode 100644 index 00000000..b3a062ce --- /dev/null +++ b/template/service/service.mli @@ -0,0 +1 @@ +module Migration : Sihl.Contract.Migration.Sig diff --git a/template/test/test.mli b/template/test/test.mli new file mode 100644 index 00000000..6b66239b --- /dev/null +++ b/template/test/test.mli @@ -0,0 +1,2 @@ +val sanity_check : unit -> unit +val suite : (string * unit Alcotest.test_case list) list diff --git a/template/web/handler/api.mli b/template/web/handler/api.mli new file mode 100644 index 00000000..dedf2856 --- /dev/null +++ b/template/web/handler/api.mli @@ -0,0 +1 @@ +val hello : 'a -> Rock.Response.t Lwt.t diff --git a/template/web/handler/page.mli b/template/web/handler/page.mli new file mode 100644 index 00000000..dedf2856 --- /dev/null +++ b/template/web/handler/page.mli @@ -0,0 +1 @@ +val hello : 'a -> Rock.Response.t Lwt.t diff --git a/template/web/middleware/middeware.mli b/template/web/middleware/middeware.mli new file mode 100644 index 00000000..e69de29b diff --git a/template/web/view/hello.mli b/template/web/view/hello.mli new file mode 100644 index 00000000..995711d1 --- /dev/null +++ b/template/web/view/hello.mli @@ -0,0 +1 @@ +val page : [> Html_types.html ] Tyxml_html.elt