diff --git a/.direnv/bin/nix-direnv-reload b/.direnv/bin/nix-direnv-reload
new file mode 100755
index 0000000..575a929
--- /dev/null
+++ b/.direnv/bin/nix-direnv-reload
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+set -e
+if [[ ! -d "/home/ryan/Documents/Code/lifetracker" ]]; then
+ echo "Cannot find source directory; Did you move it?"
+ echo "(Looking for "/home/ryan/Documents/Code/lifetracker")"
+ echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
+ exit 1
+fi
+
+# rebuild the cache forcefully
+_nix_direnv_force_reload=1 direnv exec "/home/ryan/Documents/Code/lifetracker" true
+
+# Update the mtime for .envrc.
+# This will cause direnv to reload again - but without re-building.
+touch "/home/ryan/Documents/Code/lifetracker/.envrc"
+
+# Also update the timestamp of whatever profile_rc we have.
+# This makes sure that we know we are up to date.
+touch -r "/home/ryan/Documents/Code/lifetracker/.envrc" "/home/ryan/Documents/Code/lifetracker/.direnv"/*.rc
diff --git a/.direnv/flake-inputs/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source b/.direnv/flake-inputs/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source
new file mode 120000
index 0000000..3083fc4
--- /dev/null
+++ b/.direnv/flake-inputs/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source
@@ -0,0 +1 @@
+/nix/store/r3pr5wyvfdi4h1b3wja7jcdwqjrfk9px-source
\ No newline at end of file
diff --git a/.direnv/flake-inputs/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source b/.direnv/flake-inputs/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source
new file mode 120000
index 0000000..083370b
--- /dev/null
+++ b/.direnv/flake-inputs/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source
@@ -0,0 +1 @@
+/nix/store/xpkysrb9pn0yqrm1bkll4dr2gqahj43x-source
\ No newline at end of file
diff --git a/.direnv/flake-inputs/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source b/.direnv/flake-inputs/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source
new file mode 120000
index 0000000..f17959f
--- /dev/null
+++ b/.direnv/flake-inputs/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source
@@ -0,0 +1 @@
+/nix/store/yj1wxm9hh8610iyzqnz75kvs6xl8j3my-source
\ No newline at end of file
diff --git a/.direnv/flake-inputs/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source b/.direnv/flake-inputs/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source
new file mode 120000
index 0000000..3b8fd00
--- /dev/null
+++ b/.direnv/flake-inputs/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source
@@ -0,0 +1 @@
+/nix/store/yp0xr7fzkk7rjgp564pn28r7f2mpdcj1-source
\ No newline at end of file
diff --git a/.direnv/flake-profile b/.direnv/flake-profile
deleted file mode 120000
index c7ae5b7..0000000
--- a/.direnv/flake-profile
+++ /dev/null
@@ -1 +0,0 @@
-flake-profile-2-link
\ No newline at end of file
diff --git a/.direnv/flake-profile-2-link b/.direnv/flake-profile-2-link
deleted file mode 120000
index d6e9d0a..0000000
--- a/.direnv/flake-profile-2-link
+++ /dev/null
@@ -1 +0,0 @@
-/nix/store/w46qqqb484a76v5k0lzv524yp9s89vly-nix-shell-env
\ No newline at end of file
diff --git a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
new file mode 120000
index 0000000..5cb5b42
--- /dev/null
+++ b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
@@ -0,0 +1 @@
+/nix/store/11hqs52hdjhxhcb8idddn312grl1hr5i-nix-shell-env
\ No newline at end of file
diff --git a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc
new file mode 100644
index 0000000..f105665
--- /dev/null
+++ b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc
@@ -0,0 +1,2008 @@
+unset shellHook
+PATH=${PATH:-}
+nix_saved_PATH="$PATH"
+XDG_DATA_DIRS=${XDG_DATA_DIRS:-}
+nix_saved_XDG_DATA_DIRS="$XDG_DATA_DIRS"
+AR='ar'
+export AR
+AS='as'
+export AS
+BASH='/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin/bash'
+CC='gcc'
+export CC
+CONFIG_SHELL='/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin/bash'
+export CONFIG_SHELL
+CXX='g++'
+export CXX
+HOSTTYPE='x86_64'
+HOST_PATH='/nix/store/qqz0gj9iaidabp7g34r2fb9mds6ahk8i-bash-interactive-5.2p32/bin:/nix/store/0l63mqr7qx1asjxfz86j4zbs4758gn98-git-2.46.0/bin:/nix/store/2gcih2fhiam3bpkpfbnb2d088brwpcnm-emacs-nox-29.4/bin:/nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0/bin:/nix/store/8zlqhgw5hbakbk2850wvky9x2vqbsqyw-pnpm-9.10.0/bin:/nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev/bin:/nix/store/1gax5xs6h1b70gk7z274kx4qh04hsn96-postgresql-16.4/bin:/nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0/bin:/nix/store/0kg70swgpg45ipcz3pr2siidq9fn6d77-coreutils-9.5/bin:/nix/store/fnq94lw19pnwdl9p8zhfrad4jmlgxlbr-findutils-4.10.0/bin:/nix/store/7jk4jrd99ngnm9iczcf63mfxqba0ak2y-diffutils-3.10/bin:/nix/store/gjlh1zvckhz0qv795lnzgw2zciklbzj2-gnused-4.9/bin:/nix/store/vsyc8jhsr4d9lm2r8yqq9n3j4i66inlj-gnugrep-3.11/bin:/nix/store/9hifsxkcrkvvb712ghnr3gy5g1aiym2d-gawk-5.2.2/bin:/nix/store/l2l5xr2zczq19gqpqz4j8vxxia1j41s1-gnutar-1.35/bin:/nix/store/164s7a7yscnicprzrr78bvk45d77a3yg-gzip-1.13/bin:/nix/store/f8p74dj4r4my8sw5prmm3y4ddkz7591j-bzip2-1.0.8-bin/bin:/nix/store/axrdky652lsmif6m5i8b55q91v4ly4gy-gnumake-4.4.1/bin:/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin:/nix/store/7wg4bz2sika3wd7541rndbnwcq6k9h8v-patch-2.7.6/bin:/nix/store/02mf752h7f5fn7989awzca4ygy94k7w7-xz-5.6.2-bin/bin:/nix/store/fv56zpi80jpakbfmv16r60xvyqwzff6r-file-5.45/bin'
+export HOST_PATH
+IFS='
+'
+IN_NIX_SHELL='impure'
+export IN_NIX_SHELL
+LD='ld'
+export LD
+LINENO='76'
+LOCALE_ARCHIVE='/nix/store/rhjqirbv6p5r6qaiill2k30bqdx84c62-glibc-locales-2.39-52/lib/locale/locale-archive'
+export LOCALE_ARCHIVE
+MACHTYPE='x86_64-pc-linux-gnu'
+NIX_BINTOOLS='/nix/store/b74nxf0yn2dzha02mgdxyklaqjaijzqp-binutils-wrapper-2.42'
+export NIX_BINTOOLS
+NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1'
+export NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu
+NIX_BUILD_CORES='16'
+export NIX_BUILD_CORES
+NIX_CC='/nix/store/zznja5f8v3jafffyah1rk46vpfcn38dv-gcc-wrapper-13.3.0'
+export NIX_CC
+NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1'
+export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu
+NIX_CFLAGS_COMPILE=' -frandom-seed=11hqs52hdj -isystem /nix/store/vh3vhwg8s5v1n019svwi6xzrn4jds047-bash-interactive-5.2p32-dev/include -isystem /nix/store/2gcih2fhiam3bpkpfbnb2d088brwpcnm-emacs-nox-29.4/include -isystem /nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0/include -isystem /nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev/include -isystem /nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0/include -isystem /nix/store/vh3vhwg8s5v1n019svwi6xzrn4jds047-bash-interactive-5.2p32-dev/include -isystem /nix/store/2gcih2fhiam3bpkpfbnb2d088brwpcnm-emacs-nox-29.4/include -isystem /nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0/include -isystem /nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev/include -isystem /nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0/include'
+export NIX_CFLAGS_COMPILE
+NIX_ENFORCE_NO_NATIVE='1'
+export NIX_ENFORCE_NO_NATIVE
+NIX_HARDENING_ENABLE='bindnow format fortify fortify3 pic relro stackprotector strictoverflow zerocallusedregs'
+export NIX_HARDENING_ENABLE
+NIX_LDFLAGS='-rpath /home/ryan/Documents/Code/lifetracker/outputs/out/lib -L/nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev/lib -L/nix/store/l54jqbzqhghvy3g9kqhmcha9z3vzzrxr-postgresql-16.4-lib/lib -L/nix/store/1gax5xs6h1b70gk7z274kx4qh04hsn96-postgresql-16.4/lib -L/nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0/lib -L/nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev/lib -L/nix/store/l54jqbzqhghvy3g9kqhmcha9z3vzzrxr-postgresql-16.4-lib/lib -L/nix/store/1gax5xs6h1b70gk7z274kx4qh04hsn96-postgresql-16.4/lib -L/nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0/lib'
+export NIX_LDFLAGS
+NIX_NO_SELF_RPATH='1'
+NIX_STORE='/nix/store'
+export NIX_STORE
+NM='nm'
+export NM
+NODE_PATH='/nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0/lib/node_modules'
+export NODE_PATH
+OBJCOPY='objcopy'
+export OBJCOPY
+OBJDUMP='objdump'
+export OBJDUMP
+OLDPWD=''
+export OLDPWD
+OPTERR='1'
+OSTYPE='linux-gnu'
+PATH='/nix/store/k97fic16vmpf9z6vjx5dgd6rxcvv5wwh-patchelf-0.15.0/bin:/nix/store/zznja5f8v3jafffyah1rk46vpfcn38dv-gcc-wrapper-13.3.0/bin:/nix/store/x8rg4vhgd20i8vzykm1196f9qdb8klhh-gcc-13.3.0/bin:/nix/store/k4jv8fr725amxalmplzhnlyik93wvk3z-glibc-2.39-52-bin/bin:/nix/store/0kg70swgpg45ipcz3pr2siidq9fn6d77-coreutils-9.5/bin:/nix/store/b74nxf0yn2dzha02mgdxyklaqjaijzqp-binutils-wrapper-2.42/bin:/nix/store/81xsp348yfgmaan9r5055mcdjfw7a8wc-binutils-2.42/bin:/nix/store/qqz0gj9iaidabp7g34r2fb9mds6ahk8i-bash-interactive-5.2p32/bin:/nix/store/0l63mqr7qx1asjxfz86j4zbs4758gn98-git-2.46.0/bin:/nix/store/2gcih2fhiam3bpkpfbnb2d088brwpcnm-emacs-nox-29.4/bin:/nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0/bin:/nix/store/8zlqhgw5hbakbk2850wvky9x2vqbsqyw-pnpm-9.10.0/bin:/nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev/bin:/nix/store/1gax5xs6h1b70gk7z274kx4qh04hsn96-postgresql-16.4/bin:/nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0/bin:/nix/store/0kg70swgpg45ipcz3pr2siidq9fn6d77-coreutils-9.5/bin:/nix/store/fnq94lw19pnwdl9p8zhfrad4jmlgxlbr-findutils-4.10.0/bin:/nix/store/7jk4jrd99ngnm9iczcf63mfxqba0ak2y-diffutils-3.10/bin:/nix/store/gjlh1zvckhz0qv795lnzgw2zciklbzj2-gnused-4.9/bin:/nix/store/vsyc8jhsr4d9lm2r8yqq9n3j4i66inlj-gnugrep-3.11/bin:/nix/store/9hifsxkcrkvvb712ghnr3gy5g1aiym2d-gawk-5.2.2/bin:/nix/store/l2l5xr2zczq19gqpqz4j8vxxia1j41s1-gnutar-1.35/bin:/nix/store/164s7a7yscnicprzrr78bvk45d77a3yg-gzip-1.13/bin:/nix/store/f8p74dj4r4my8sw5prmm3y4ddkz7591j-bzip2-1.0.8-bin/bin:/nix/store/axrdky652lsmif6m5i8b55q91v4ly4gy-gnumake-4.4.1/bin:/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin:/nix/store/7wg4bz2sika3wd7541rndbnwcq6k9h8v-patch-2.7.6/bin:/nix/store/02mf752h7f5fn7989awzca4ygy94k7w7-xz-5.6.2-bin/bin:/nix/store/fv56zpi80jpakbfmv16r60xvyqwzff6r-file-5.45/bin'
+export PATH
+PS4='+ '
+RANLIB='ranlib'
+export RANLIB
+READELF='readelf'
+export READELF
+SHELL='/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin/bash'
+export SHELL
+SIZE='size'
+export SIZE
+SOURCE_DATE_EPOCH='315532800'
+export SOURCE_DATE_EPOCH
+STRINGS='strings'
+export STRINGS
+STRIP='strip'
+export STRIP
+XDG_DATA_DIRS='/nix/store/k97fic16vmpf9z6vjx5dgd6rxcvv5wwh-patchelf-0.15.0/share'
+export XDG_DATA_DIRS
+__structuredAttrs=''
+export __structuredAttrs
+_substituteStream_has_warned_replace_deprecation='false'
+buildInputs='/nix/store/vh3vhwg8s5v1n019svwi6xzrn4jds047-bash-interactive-5.2p32-dev /nix/store/rhjqirbv6p5r6qaiill2k30bqdx84c62-glibc-locales-2.39-52 /nix/store/0l63mqr7qx1asjxfz86j4zbs4758gn98-git-2.46.0 /nix/store/2gcih2fhiam3bpkpfbnb2d088brwpcnm-emacs-nox-29.4 /nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0 /nix/store/8zlqhgw5hbakbk2850wvky9x2vqbsqyw-pnpm-9.10.0 /nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev /nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0'
+export buildInputs
+buildPhase='{ echo "------------------------------------------------------------";
+ echo " WARNING: the existence of this path is not guaranteed.";
+ echo " It is an internal implementation detail for pkgs.mkShell.";
+ echo "------------------------------------------------------------";
+ echo;
+ # Record all build inputs as runtime dependencies
+ export;
+} >> "$out"
+'
+export buildPhase
+builder='/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin/bash'
+export builder
+cmakeFlags=''
+export cmakeFlags
+configureFlags=''
+export configureFlags
+defaultBuildInputs=''
+defaultNativeBuildInputs='/nix/store/k97fic16vmpf9z6vjx5dgd6rxcvv5wwh-patchelf-0.15.0 /nix/store/9l3havpzc3w1xggd19l5c395az4yh449-update-autotools-gnu-config-scripts-hook /nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh /nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh /nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh /nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh /nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh /nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh /nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh /nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh /nix/store/12lvf0c7xric9cny7slvf9cmhypl1p67-patch-shebangs.sh /nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh /nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh /nix/store/aazf105snicrlvyzzbdj85sx4179rpfp-set-source-date-epoch-to-latest.sh /nix/store/gps9qrh99j7g02840wv5x78ykmz30byp-strip.sh /nix/store/zznja5f8v3jafffyah1rk46vpfcn38dv-gcc-wrapper-13.3.0'
+depsBuildBuild=''
+export depsBuildBuild
+depsBuildBuildPropagated=''
+export depsBuildBuildPropagated
+depsBuildTarget=''
+export depsBuildTarget
+depsBuildTargetPropagated=''
+export depsBuildTargetPropagated
+depsHostHost=''
+export depsHostHost
+depsHostHostPropagated=''
+export depsHostHostPropagated
+depsTargetTarget=''
+export depsTargetTarget
+depsTargetTargetPropagated=''
+export depsTargetTargetPropagated
+doCheck=''
+export doCheck
+doInstallCheck=''
+export doInstallCheck
+dontAddDisableDepTrack='1'
+export dontAddDisableDepTrack
+declare -a envBuildBuildHooks=()
+declare -a envBuildHostHooks=()
+declare -a envBuildTargetHooks=()
+declare -a envHostHostHooks=('ccWrapper_addCVars' 'bintoolsWrapper_addLDVars' 'addNodePath' )
+declare -a envHostTargetHooks=('ccWrapper_addCVars' 'bintoolsWrapper_addLDVars' 'addNodePath' )
+declare -a envTargetTargetHooks=()
+declare -a fixupOutputHooks=('if [ -z "${dontPatchELF-}" ]; then patchELF "$prefix"; fi' 'if [[ -z "${noAuditTmpdir-}" && -e "$prefix" ]]; then auditTmpdir "$prefix"; fi' 'if [ -z "${dontGzipMan-}" ]; then compressManPages "$prefix"; fi' '_moveLib64' '_moveSbin' '_moveSystemdUserUnits' 'patchShebangsAuto' '_pruneLibtoolFiles' '_doStrip' )
+guess='16'
+initialPath='/nix/store/0kg70swgpg45ipcz3pr2siidq9fn6d77-coreutils-9.5 /nix/store/fnq94lw19pnwdl9p8zhfrad4jmlgxlbr-findutils-4.10.0 /nix/store/7jk4jrd99ngnm9iczcf63mfxqba0ak2y-diffutils-3.10 /nix/store/gjlh1zvckhz0qv795lnzgw2zciklbzj2-gnused-4.9 /nix/store/vsyc8jhsr4d9lm2r8yqq9n3j4i66inlj-gnugrep-3.11 /nix/store/9hifsxkcrkvvb712ghnr3gy5g1aiym2d-gawk-5.2.2 /nix/store/l2l5xr2zczq19gqpqz4j8vxxia1j41s1-gnutar-1.35 /nix/store/164s7a7yscnicprzrr78bvk45d77a3yg-gzip-1.13 /nix/store/f8p74dj4r4my8sw5prmm3y4ddkz7591j-bzip2-1.0.8-bin /nix/store/axrdky652lsmif6m5i8b55q91v4ly4gy-gnumake-4.4.1 /nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32 /nix/store/7wg4bz2sika3wd7541rndbnwcq6k9h8v-patch-2.7.6 /nix/store/02mf752h7f5fn7989awzca4ygy94k7w7-xz-5.6.2-bin /nix/store/fv56zpi80jpakbfmv16r60xvyqwzff6r-file-5.45'
+mesonFlags=''
+export mesonFlags
+name='nix-shell-env'
+export name
+nativeBuildInputs=''
+export nativeBuildInputs
+out='/home/ryan/Documents/Code/lifetracker/outputs/out'
+export out
+outputBin='out'
+outputDev='out'
+outputDevdoc='REMOVE'
+outputDevman='out'
+outputDoc='out'
+outputInclude='out'
+outputInfo='out'
+outputLib='out'
+outputMan='out'
+outputs='out'
+export outputs
+patches=''
+export patches
+phases='buildPhase'
+export phases
+pkg='/nix/store/zznja5f8v3jafffyah1rk46vpfcn38dv-gcc-wrapper-13.3.0'
+declare -a pkgsBuildBuild=()
+declare -a pkgsBuildHost=('/nix/store/k97fic16vmpf9z6vjx5dgd6rxcvv5wwh-patchelf-0.15.0' '/nix/store/9l3havpzc3w1xggd19l5c395az4yh449-update-autotools-gnu-config-scripts-hook' '/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh' '/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh' '/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh' '/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh' '/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh' '/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh' '/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh' '/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh' '/nix/store/12lvf0c7xric9cny7slvf9cmhypl1p67-patch-shebangs.sh' '/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh' '/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh' '/nix/store/aazf105snicrlvyzzbdj85sx4179rpfp-set-source-date-epoch-to-latest.sh' '/nix/store/gps9qrh99j7g02840wv5x78ykmz30byp-strip.sh' '/nix/store/zznja5f8v3jafffyah1rk46vpfcn38dv-gcc-wrapper-13.3.0' '/nix/store/b74nxf0yn2dzha02mgdxyklaqjaijzqp-binutils-wrapper-2.42' )
+declare -a pkgsBuildTarget=()
+declare -a pkgsHostHost=()
+declare -a pkgsHostTarget=('/nix/store/vh3vhwg8s5v1n019svwi6xzrn4jds047-bash-interactive-5.2p32-dev' '/nix/store/qqz0gj9iaidabp7g34r2fb9mds6ahk8i-bash-interactive-5.2p32' '/nix/store/rhjqirbv6p5r6qaiill2k30bqdx84c62-glibc-locales-2.39-52' '/nix/store/0l63mqr7qx1asjxfz86j4zbs4758gn98-git-2.46.0' '/nix/store/2gcih2fhiam3bpkpfbnb2d088brwpcnm-emacs-nox-29.4' '/nix/store/w78sh036dyn14f29w8za9ni9syrmwm3q-nodejs-20.17.0' '/nix/store/8zlqhgw5hbakbk2850wvky9x2vqbsqyw-pnpm-9.10.0' '/nix/store/45if5nl708nhayxnaqh7h2scz9pn4mn8-postgresql-16.4-dev' '/nix/store/l54jqbzqhghvy3g9kqhmcha9z3vzzrxr-postgresql-16.4-lib' '/nix/store/1gax5xs6h1b70gk7z274kx4qh04hsn96-postgresql-16.4' '/nix/store/c7lxmwsnnh3865advh3vj2z3qdcrkcv1-inotify-tools-4.23.9.0' )
+declare -a pkgsTargetTarget=()
+declare -a postFixupHooks=('_makeSymlinksRelativeInAllOutputs' '_multioutPropagateDev' )
+declare -a postUnpackHooks=('_updateSourceDateEpochFromSourceRoot' )
+declare -a preConfigureHooks=('_multioutConfig' )
+preConfigurePhases=' updateAutotoolsGnuConfigScriptsPhase'
+declare -a preFixupHooks=('_moveToShare' '_multioutDocs' '_multioutDevs' )
+preferLocalBuild='1'
+export preferLocalBuild
+prefix='/home/ryan/Documents/Code/lifetracker/outputs/out'
+declare -a propagatedBuildDepFiles=('propagated-build-build-deps' 'propagated-native-build-inputs' 'propagated-build-target-deps' )
+propagatedBuildInputs=''
+export propagatedBuildInputs
+declare -a propagatedHostDepFiles=('propagated-host-host-deps' 'propagated-build-inputs' )
+propagatedNativeBuildInputs=''
+export propagatedNativeBuildInputs
+declare -a propagatedTargetDepFiles=('propagated-target-target-deps' )
+shell='/nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash-5.2p32/bin/bash'
+export shell
+shellHook=''
+export shellHook
+stdenv='/nix/store/91d27rjqlhkzx7mhzxrir1jcr40nyc7p-stdenv-linux'
+export stdenv
+strictDeps=''
+export strictDeps
+system='x86_64-linux'
+export system
+declare -a unpackCmdHooks=('_defaultUnpack' )
+_activatePkgs ()
+{
+
+ local hostOffset targetOffset;
+ local pkg;
+ for hostOffset in "${allPlatOffsets[@]}";
+ do
+ local pkgsVar="${pkgAccumVarVars[hostOffset + 1]}";
+ for targetOffset in "${allPlatOffsets[@]}";
+ do
+ (( hostOffset <= targetOffset )) || continue;
+ local pkgsRef="${pkgsVar}[$targetOffset - $hostOffset]";
+ local pkgsSlice="${!pkgsRef}[@]";
+ for pkg in ${!pkgsSlice+"${!pkgsSlice}"};
+ do
+ activatePackage "$pkg" "$hostOffset" "$targetOffset";
+ done;
+ done;
+ done
+}
+_addRpathPrefix ()
+{
+
+ if [ "${NIX_NO_SELF_RPATH:-0}" != 1 ]; then
+ export NIX_LDFLAGS="-rpath $1/lib ${NIX_LDFLAGS-}";
+ fi
+}
+_addToEnv ()
+{
+
+ local depHostOffset depTargetOffset;
+ local pkg;
+ for depHostOffset in "${allPlatOffsets[@]}";
+ do
+ local hookVar="${pkgHookVarVars[depHostOffset + 1]}";
+ local pkgsVar="${pkgAccumVarVars[depHostOffset + 1]}";
+ for depTargetOffset in "${allPlatOffsets[@]}";
+ do
+ (( depHostOffset <= depTargetOffset )) || continue;
+ local hookRef="${hookVar}[$depTargetOffset - $depHostOffset]";
+ if [[ -z "${strictDeps-}" ]]; then
+ local visitedPkgs="";
+ for pkg in "${pkgsBuildBuild[@]}" "${pkgsBuildHost[@]}" "${pkgsBuildTarget[@]}" "${pkgsHostHost[@]}" "${pkgsHostTarget[@]}" "${pkgsTargetTarget[@]}";
+ do
+ if [[ "$visitedPkgs" = *"$pkg"* ]]; then
+ continue;
+ fi;
+ runHook "${!hookRef}" "$pkg";
+ visitedPkgs+=" $pkg";
+ done;
+ else
+ local pkgsRef="${pkgsVar}[$depTargetOffset - $depHostOffset]";
+ local pkgsSlice="${!pkgsRef}[@]";
+ for pkg in ${!pkgsSlice+"${!pkgsSlice}"};
+ do
+ runHook "${!hookRef}" "$pkg";
+ done;
+ fi;
+ done;
+ done
+}
+_allFlags ()
+{
+
+ export system pname name version;
+ while IFS='' read -r varName; do
+ nixTalkativeLog "@${varName}@ -> ${!varName}";
+ args+=("--subst-var" "$varName");
+ done < <(awk 'BEGIN { for (v in ENVIRON) if (v ~ /^[a-z][a-zA-Z0-9_]*$/) print v }')
+}
+_assignFirst ()
+{
+
+ local varName="$1";
+ local _var;
+ local REMOVE=REMOVE;
+ shift;
+ for _var in "$@";
+ do
+ if [ -n "${!_var-}" ]; then
+ eval "${varName}"="${_var}";
+ return;
+ fi;
+ done;
+ echo;
+ echo "error: _assignFirst: could not find a non-empty variable whose name to assign to ${varName}.";
+ echo " The following variables were all unset or empty:";
+ echo " $*";
+ if [ -z "${out:-}" ]; then
+ echo ' If you do not want an "out" output in your derivation, make sure to define';
+ echo ' the other specific required outputs. This can be achieved by picking one';
+ echo " of the above as an output.";
+ echo ' You do not have to remove "out" if you want to have a different default';
+ echo ' output, because the first output is taken as a default.';
+ echo;
+ fi;
+ return 1
+}
+_callImplicitHook ()
+{
+
+ local def="$1";
+ local hookName="$2";
+ if declare -F "$hookName" > /dev/null; then
+ nixTalkativeLog "calling implicit '$hookName' function hook";
+ "$hookName";
+ else
+ if type -p "$hookName" > /dev/null; then
+ nixTalkativeLog "sourcing implicit '$hookName' script hook";
+ source "$hookName";
+ else
+ if [ -n "${!hookName:-}" ]; then
+ nixTalkativeLog "evaling implicit '$hookName' string hook";
+ eval "${!hookName}";
+ else
+ return "$def";
+ fi;
+ fi;
+ fi
+}
+_defaultUnpack ()
+{
+
+ local fn="$1";
+ local destination;
+ if [ -d "$fn" ]; then
+ destination="$(stripHash "$fn")";
+ if [ -e "$destination" ]; then
+ echo "Cannot copy $fn to $destination: destination already exists!";
+ echo "Did you specify two \"srcs\" with the same \"name\"?";
+ return 1;
+ fi;
+ cp -pr --reflink=auto -- "$fn" "$destination";
+ else
+ case "$fn" in
+ *.tar.xz | *.tar.lzma | *.txz)
+ ( XZ_OPT="--threads=$NIX_BUILD_CORES" xz -d < "$fn";
+ true ) | tar xf - --mode=+w --warning=no-timestamp
+ ;;
+ *.tar | *.tar.* | *.tgz | *.tbz2 | *.tbz)
+ tar xf "$fn" --mode=+w --warning=no-timestamp
+ ;;
+ *)
+ return 1
+ ;;
+ esac;
+ fi
+}
+_doStrip ()
+{
+
+ local -ra flags=(dontStripHost dontStripTarget);
+ local -ra debugDirs=(stripDebugList stripDebugListTarget);
+ local -ra allDirs=(stripAllList stripAllListTarget);
+ local -ra stripCmds=(STRIP STRIP_FOR_TARGET);
+ local -ra ranlibCmds=(RANLIB RANLIB_FOR_TARGET);
+ stripDebugList=${stripDebugList[*]:-lib lib32 lib64 libexec bin sbin};
+ stripDebugListTarget=${stripDebugListTarget[*]:-};
+ stripAllList=${stripAllList[*]:-};
+ stripAllListTarget=${stripAllListTarget[*]:-};
+ local i;
+ for i in ${!stripCmds[@]};
+ do
+ local -n flag="${flags[$i]}";
+ local -n debugDirList="${debugDirs[$i]}";
+ local -n allDirList="${allDirs[$i]}";
+ local -n stripCmd="${stripCmds[$i]}";
+ local -n ranlibCmd="${ranlibCmds[$i]}";
+ if [[ -n "${dontStrip-}" || -n "${flag-}" ]] || ! type -f "${stripCmd-}" 2> /dev/null 1>&2; then
+ continue;
+ fi;
+ stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags[*]:--S -p}";
+ stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags[*]:--s -p}";
+ done
+}
+_eval ()
+{
+
+ if declare -F "$1" > /dev/null 2>&1; then
+ "$@";
+ else
+ eval "$1";
+ fi
+}
+_logHook ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]]; then
+ return;
+ fi;
+ local hookKind="$1";
+ local hookExpr="$2";
+ shift 2;
+ if declare -F "$hookExpr" > /dev/null 2>&1; then
+ nixTalkativeLog "calling '$hookKind' function hook '$hookExpr'" "$@";
+ else
+ if type -p "$hookExpr" > /dev/null; then
+ nixTalkativeLog "sourcing '$hookKind' script hook '$hookExpr'";
+ else
+ if [[ "$hookExpr" != "_callImplicitHook"* ]]; then
+ local exprToOutput;
+ if [[ ${NIX_DEBUG:-0} -ge 5 ]]; then
+ exprToOutput="$hookExpr";
+ else
+ local hookExprLine;
+ while IFS= read -r hookExprLine; do
+ hookExprLine="${hookExprLine#"${hookExprLine%%[![:space:]]*}"}";
+ if [[ -n "$hookExprLine" ]]; then
+ exprToOutput+="$hookExprLine\\n ";
+ fi;
+ done <<< "$hookExpr";
+ exprToOutput="${exprToOutput%%\\n }";
+ fi;
+ nixTalkativeLog "evaling '$hookKind' string hook '$exprToOutput'";
+ fi;
+ fi;
+ fi
+}
+_makeSymlinksRelative ()
+{
+
+ local symlinkTarget;
+ if [ "${dontRewriteSymlinks-}" ] || [ ! -e "$prefix" ]; then
+ return;
+ fi;
+ while IFS= read -r -d '' f; do
+ symlinkTarget=$(readlink "$f");
+ if [[ "$symlinkTarget"/ != "$prefix"/* ]]; then
+ continue;
+ fi;
+ if [ ! -e "$symlinkTarget" ]; then
+ echo "the symlink $f is broken, it points to $symlinkTarget (which is missing)";
+ fi;
+ echo "rewriting symlink $f to be relative to $prefix";
+ ln -snrf "$symlinkTarget" "$f";
+ done < <(find $prefix -type l -print0)
+}
+_makeSymlinksRelativeInAllOutputs ()
+{
+
+ local output;
+ for output in $(getAllOutputNames);
+ do
+ prefix="${!output}" _makeSymlinksRelative;
+ done
+}
+_moveLib64 ()
+{
+
+ if [ "${dontMoveLib64-}" = 1 ]; then
+ return;
+ fi;
+ if [ ! -e "$prefix/lib64" -o -L "$prefix/lib64" ]; then
+ return;
+ fi;
+ echo "moving $prefix/lib64/* to $prefix/lib";
+ mkdir -p $prefix/lib;
+ shopt -s dotglob;
+ for i in $prefix/lib64/*;
+ do
+ mv --no-clobber "$i" $prefix/lib;
+ done;
+ shopt -u dotglob;
+ rmdir $prefix/lib64;
+ ln -s lib $prefix/lib64
+}
+_moveSbin ()
+{
+
+ if [ "${dontMoveSbin-}" = 1 ]; then
+ return;
+ fi;
+ if [ ! -e "$prefix/sbin" -o -L "$prefix/sbin" ]; then
+ return;
+ fi;
+ echo "moving $prefix/sbin/* to $prefix/bin";
+ mkdir -p $prefix/bin;
+ shopt -s dotglob;
+ for i in $prefix/sbin/*;
+ do
+ mv "$i" $prefix/bin;
+ done;
+ shopt -u dotglob;
+ rmdir $prefix/sbin;
+ ln -s bin $prefix/sbin
+}
+_moveSystemdUserUnits ()
+{
+
+ if [ "${dontMoveSystemdUserUnits:-0}" = 1 ]; then
+ return;
+ fi;
+ if [ ! -e "${prefix:?}/lib/systemd/user" ]; then
+ return;
+ fi;
+ local source="$prefix/lib/systemd/user";
+ local target="$prefix/share/systemd/user";
+ echo "moving $source/* to $target";
+ mkdir -p "$target";
+ ( shopt -s dotglob;
+ for i in "$source"/*;
+ do
+ mv "$i" "$target";
+ done );
+ rmdir "$source";
+ ln -s "$target" "$source"
+}
+_moveToShare ()
+{
+
+ if [ -n "$__structuredAttrs" ]; then
+ if [ -z "${forceShare-}" ]; then
+ forceShare=(man doc info);
+ fi;
+ else
+ forceShare=(${forceShare:-man doc info});
+ fi;
+ if [[ -z "$out" ]]; then
+ return;
+ fi;
+ for d in "${forceShare[@]}";
+ do
+ if [ -d "$out/$d" ]; then
+ if [ -d "$out/share/$d" ]; then
+ echo "both $d/ and share/$d/ exist!";
+ else
+ echo "moving $out/$d to $out/share/$d";
+ mkdir -p $out/share;
+ mv $out/$d $out/share/;
+ fi;
+ fi;
+ done
+}
+_multioutConfig ()
+{
+
+ if [ "$(getAllOutputNames)" = "out" ] || [ -z "${setOutputFlags-1}" ]; then
+ return;
+ fi;
+ if [ -z "${shareDocName:-}" ]; then
+ local confScript="${configureScript:-}";
+ if [ -z "$confScript" ] && [ -x ./configure ]; then
+ confScript=./configure;
+ fi;
+ if [ -f "$confScript" ]; then
+ local shareDocName="$(sed -n "s/^PACKAGE_TARNAME='\(.*\)'$/\1/p" < "$confScript")";
+ fi;
+ if [ -z "$shareDocName" ] || echo "$shareDocName" | grep -q '[^a-zA-Z0-9_-]'; then
+ shareDocName="$(echo "$name" | sed 's/-[^a-zA-Z].*//')";
+ fi;
+ fi;
+ prependToVar configureFlags --bindir="${!outputBin}"/bin --sbindir="${!outputBin}"/sbin --includedir="${!outputInclude}"/include --oldincludedir="${!outputInclude}"/include --mandir="${!outputMan}"/share/man --infodir="${!outputInfo}"/share/info --docdir="${!outputDoc}"/share/doc/"${shareDocName}" --libdir="${!outputLib}"/lib --libexecdir="${!outputLib}"/libexec --localedir="${!outputLib}"/share/locale;
+ prependToVar installFlags pkgconfigdir="${!outputDev}"/lib/pkgconfig m4datadir="${!outputDev}"/share/aclocal aclocaldir="${!outputDev}"/share/aclocal
+}
+_multioutDevs ()
+{
+
+ if [ "$(getAllOutputNames)" = "out" ] || [ -z "${moveToDev-1}" ]; then
+ return;
+ fi;
+ moveToOutput include "${!outputInclude}";
+ moveToOutput lib/pkgconfig "${!outputDev}";
+ moveToOutput share/pkgconfig "${!outputDev}";
+ moveToOutput lib/cmake "${!outputDev}";
+ moveToOutput share/aclocal "${!outputDev}";
+ for f in "${!outputDev}"/{lib,share}/pkgconfig/*.pc;
+ do
+ echo "Patching '$f' includedir to output ${!outputInclude}";
+ sed -i "/^includedir=/s,=\${prefix},=${!outputInclude}," "$f";
+ done
+}
+_multioutDocs ()
+{
+
+ local REMOVE=REMOVE;
+ moveToOutput share/info "${!outputInfo}";
+ moveToOutput share/doc "${!outputDoc}";
+ moveToOutput share/gtk-doc "${!outputDevdoc}";
+ moveToOutput share/devhelp/books "${!outputDevdoc}";
+ moveToOutput share/man "${!outputMan}";
+ moveToOutput share/man/man3 "${!outputDevman}"
+}
+_multioutPropagateDev ()
+{
+
+ if [ "$(getAllOutputNames)" = "out" ]; then
+ return;
+ fi;
+ local outputFirst;
+ for outputFirst in $(getAllOutputNames);
+ do
+ break;
+ done;
+ local propagaterOutput="$outputDev";
+ if [ -z "$propagaterOutput" ]; then
+ propagaterOutput="$outputFirst";
+ fi;
+ if [ -z "${propagatedBuildOutputs+1}" ]; then
+ local po_dirty="$outputBin $outputInclude $outputLib";
+ set +o pipefail;
+ propagatedBuildOutputs=`echo "$po_dirty" | tr -s ' ' '\n' | grep -v -F "$propagaterOutput" | sort -u | tr '\n' ' ' `;
+ set -o pipefail;
+ fi;
+ if [ -z "$propagatedBuildOutputs" ]; then
+ return;
+ fi;
+ mkdir -p "${!propagaterOutput}"/nix-support;
+ for output in $propagatedBuildOutputs;
+ do
+ echo -n " ${!output}" >> "${!propagaterOutput}"/nix-support/propagated-build-inputs;
+ done
+}
+_overrideFirst ()
+{
+
+ if [ -z "${!1-}" ]; then
+ _assignFirst "$@";
+ fi
+}
+_pruneLibtoolFiles ()
+{
+
+ if [ "${dontPruneLibtoolFiles-}" ] || [ ! -e "$prefix" ]; then
+ return;
+ fi;
+ find "$prefix" -type f -name '*.la' -exec grep -q '^# Generated by .*libtool' {} \; -exec grep -q "^old_library=''" {} \; -exec sed -i {} -e "/^dependency_libs='[^']/ c dependency_libs='' #pruned" \;
+}
+_updateSourceDateEpochFromSourceRoot ()
+{
+
+ if [ -n "$sourceRoot" ]; then
+ updateSourceDateEpoch "$sourceRoot";
+ fi
+}
+activatePackage ()
+{
+
+ local pkg="$1";
+ local -r hostOffset="$2";
+ local -r targetOffset="$3";
+ (( hostOffset <= targetOffset )) || exit 1;
+ if [ -f "$pkg" ]; then
+ nixTalkativeLog "sourcing setup hook '$pkg'";
+ source "$pkg";
+ fi;
+ if [[ -z "${strictDeps-}" || "$hostOffset" -le -1 ]]; then
+ addToSearchPath _PATH "$pkg/bin";
+ fi;
+ if (( hostOffset <= -1 )); then
+ addToSearchPath _XDG_DATA_DIRS "$pkg/share";
+ fi;
+ if [[ "$hostOffset" -eq 0 && -d "$pkg/bin" ]]; then
+ addToSearchPath _HOST_PATH "$pkg/bin";
+ fi;
+ if [[ -f "$pkg/nix-support/setup-hook" ]]; then
+ nixTalkativeLog "sourcing setup hook '$pkg/nix-support/setup-hook'";
+ source "$pkg/nix-support/setup-hook";
+ fi
+}
+addEnvHooks ()
+{
+
+ local depHostOffset="$1";
+ shift;
+ local pkgHookVarsSlice="${pkgHookVarVars[$depHostOffset + 1]}[@]";
+ local pkgHookVar;
+ for pkgHookVar in "${!pkgHookVarsSlice}";
+ do
+ eval "${pkgHookVar}s"'+=("$@")';
+ done
+}
+addNodePath ()
+{
+
+ addToSearchPath NODE_PATH "$1/lib/node_modules"
+}
+addToSearchPath ()
+{
+
+ addToSearchPathWithCustomDelimiter ":" "$@"
+}
+addToSearchPathWithCustomDelimiter ()
+{
+
+ local delimiter="$1";
+ local varName="$2";
+ local dir="$3";
+ if [[ -d "$dir" && "${!varName:+${delimiter}${!varName}${delimiter}}" != *"${delimiter}${dir}${delimiter}"* ]]; then
+ export "${varName}=${!varName:+${!varName}${delimiter}}${dir}";
+ fi
+}
+appendToVar ()
+{
+
+ local -n nameref="$1";
+ local useArray type;
+ if [ -n "$__structuredAttrs" ]; then
+ useArray=true;
+ else
+ useArray=false;
+ fi;
+ if type=$(declare -p "$1" 2> /dev/null); then
+ case "${type#* }" in
+ -A*)
+ echo "appendToVar(): ERROR: trying to use appendToVar on an associative array, use variable+=([\"X\"]=\"Y\") instead." 1>&2;
+ return 1
+ ;;
+ -a*)
+ useArray=true
+ ;;
+ *)
+ useArray=false
+ ;;
+ esac;
+ fi;
+ shift;
+ if $useArray; then
+ nameref=(${nameref+"${nameref[@]}"} "$@");
+ else
+ nameref="${nameref-} $*";
+ fi
+}
+auditTmpdir ()
+{
+
+ local dir="$1";
+ [ -e "$dir" ] || return 0;
+ echo "checking for references to $TMPDIR/ in $dir...";
+ local i;
+ find "$dir" -type f -print0 | while IFS= read -r -d '' i; do
+ if [[ "$i" =~ .build-id ]]; then
+ continue;
+ fi;
+ if isELF "$i"; then
+ if {
+ printf :;
+ patchelf --print-rpath "$i"
+ } | grep -q -F ":$TMPDIR/"; then
+ echo "RPATH of binary $i contains a forbidden reference to $TMPDIR/";
+ exit 1;
+ fi;
+ fi;
+ if isScript "$i"; then
+ if [ -e "$(dirname "$i")/.$(basename "$i")-wrapped" ]; then
+ if grep -q -F "$TMPDIR/" "$i"; then
+ echo "wrapper script $i contains a forbidden reference to $TMPDIR/";
+ exit 1;
+ fi;
+ fi;
+ fi;
+ done
+}
+bintoolsWrapper_addLDVars ()
+{
+
+ local role_post;
+ getHostRoleEnvHook;
+ if [[ -d "$1/lib64" && ! -L "$1/lib64" ]]; then
+ export NIX_LDFLAGS${role_post}+=" -L$1/lib64";
+ fi;
+ if [[ -d "$1/lib" ]]; then
+ local -a glob=($1/lib/lib*);
+ if [ "${#glob[*]}" -gt 0 ]; then
+ export NIX_LDFLAGS${role_post}+=" -L$1/lib";
+ fi;
+ fi
+}
+buildPhase ()
+{
+
+ runHook preBuild;
+ if [[ -z "${makeFlags-}" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then
+ echo "no Makefile or custom buildPhase, doing nothing";
+ else
+ foundMakefile=1;
+ local flagsArray=(${enableParallelBuilding:+-j${NIX_BUILD_CORES}} SHELL="$SHELL");
+ concatTo flagsArray makeFlags makeFlagsArray buildFlags buildFlagsArray;
+ echoCmd 'build flags' "${flagsArray[@]}";
+ make ${makefile:+-f $makefile} "${flagsArray[@]}";
+ unset flagsArray;
+ fi;
+ runHook postBuild
+}
+ccWrapper_addCVars ()
+{
+
+ local role_post;
+ getHostRoleEnvHook;
+ if [ -d "$1/include" ]; then
+ export NIX_CFLAGS_COMPILE${role_post}+=" -isystem $1/include";
+ fi;
+ if [ -d "$1/Library/Frameworks" ]; then
+ export NIX_CFLAGS_COMPILE${role_post}+=" -iframework $1/Library/Frameworks";
+ fi
+}
+checkPhase ()
+{
+
+ runHook preCheck;
+ if [[ -z "${foundMakefile:-}" ]]; then
+ echo "no Makefile or custom checkPhase, doing nothing";
+ runHook postCheck;
+ return;
+ fi;
+ if [[ -z "${checkTarget:-}" ]]; then
+ if make -n ${makefile:+-f $makefile} check > /dev/null 2>&1; then
+ checkTarget="check";
+ else
+ if make -n ${makefile:+-f $makefile} test > /dev/null 2>&1; then
+ checkTarget="test";
+ fi;
+ fi;
+ fi;
+ if [[ -z "${checkTarget:-}" ]]; then
+ echo "no check/test target in ${makefile:-Makefile}, doing nothing";
+ else
+ local flagsArray=(${enableParallelChecking:+-j${NIX_BUILD_CORES}} SHELL="$SHELL");
+ concatTo flagsArray makeFlags makeFlagsArray checkFlags=VERBOSE=y checkFlagsArray checkTarget;
+ echoCmd 'check flags' "${flagsArray[@]}";
+ make ${makefile:+-f $makefile} "${flagsArray[@]}";
+ unset flagsArray;
+ fi;
+ runHook postCheck
+}
+compressManPages ()
+{
+
+ local dir="$1";
+ if [ -L "$dir"/share ] || [ -L "$dir"/share/man ] || [ ! -d "$dir/share/man" ]; then
+ return;
+ fi;
+ echo "gzipping man pages under $dir/share/man/";
+ find "$dir"/share/man/ -type f -a '!' -regex '.*\.\(bz2\|gz\|xz\)$' -print0 | while IFS= read -r -d '' f; do
+ if gzip -c -n "$f" > "$f".gz; then
+ rm "$f";
+ else
+ rm "$f".gz;
+ fi;
+ done;
+ find "$dir"/share/man/ -type l -a '!' -regex '.*\.\(bz2\|gz\|xz\)$' -print0 | sort -z | while IFS= read -r -d '' f; do
+ local target;
+ target="$(readlink -f "$f")";
+ if [ -f "$target".gz ]; then
+ ln -sf "$target".gz "$f".gz && rm "$f";
+ fi;
+ done
+}
+concatStringsSep ()
+{
+
+ local sep="$1";
+ local name="$2";
+ local type oldifs;
+ if type=$(declare -p "$name" 2> /dev/null); then
+ local -n nameref="$name";
+ case "${type#* }" in
+ -A*)
+ echo "concatStringsSep(): ERROR: trying to use concatStringsSep on an associative array." 1>&2;
+ return 1
+ ;;
+ -a*)
+ local IFS="$sep";
+ echo -n "${nameref[*]}"
+ ;;
+ *)
+ echo -n "${nameref// /"${sep}"}"
+ ;;
+ esac;
+ fi
+}
+concatTo ()
+{
+
+ local -n targetref="$1";
+ shift;
+ local arg default name type;
+ for arg in "$@";
+ do
+ IFS="=" read -r name default <<< "$arg";
+ local -n nameref="$name";
+ if [[ ! -n "${nameref[@]}" && -n "$default" ]]; then
+ targetref+=("$default");
+ else
+ if type=$(declare -p "$name" 2> /dev/null); then
+ case "${type#* }" in
+ -A*)
+ echo "concatTo(): ERROR: trying to use concatTo on an associative array." 1>&2;
+ return 1
+ ;;
+ -a*)
+ targetref+=("${nameref[@]}")
+ ;;
+ *)
+ if [[ "$name" = *"Array" ]]; then
+ nixErrorLog "concatTo(): $name is not declared as array, treating as a singleton. This will become an error in future";
+ targetref+=(${nameref+"${nameref[@]}"});
+ else
+ targetref+=(${nameref-});
+ fi
+ ;;
+ esac;
+ fi;
+ fi;
+ done
+}
+configurePhase ()
+{
+
+ runHook preConfigure;
+ : "${configureScript=}";
+ if [[ -z "$configureScript" && -x ./configure ]]; then
+ configureScript=./configure;
+ fi;
+ if [ -z "${dontFixLibtool:-}" ]; then
+ export lt_cv_deplibs_check_method="${lt_cv_deplibs_check_method-pass_all}";
+ local i;
+ find . -iname "ltmain.sh" -print0 | while IFS='' read -r -d '' i; do
+ echo "fixing libtool script $i";
+ fixLibtool "$i";
+ done;
+ CONFIGURE_MTIME_REFERENCE=$(mktemp configure.mtime.reference.XXXXXX);
+ find . -executable -type f -name configure -exec grep -l 'GNU Libtool is free software; you can redistribute it and/or modify' {} \; -exec touch -r {} "$CONFIGURE_MTIME_REFERENCE" \; -exec sed -i s_/usr/bin/file_file_g {} \; -exec touch -r "$CONFIGURE_MTIME_REFERENCE" {} \;;
+ rm -f "$CONFIGURE_MTIME_REFERENCE";
+ fi;
+ if [[ -z "${dontAddPrefix:-}" && -n "$prefix" ]]; then
+ prependToVar configureFlags "${prefixKey:---prefix=}$prefix";
+ fi;
+ if [[ -f "$configureScript" ]]; then
+ if [ -z "${dontAddDisableDepTrack:-}" ]; then
+ if grep -q dependency-tracking "$configureScript"; then
+ prependToVar configureFlags --disable-dependency-tracking;
+ fi;
+ fi;
+ if [ -z "${dontDisableStatic:-}" ]; then
+ if grep -q enable-static "$configureScript"; then
+ prependToVar configureFlags --disable-static;
+ fi;
+ fi;
+ if [ -z "${dontPatchShebangsInConfigure:-}" ]; then
+ patchShebangs --build "$configureScript";
+ fi;
+ fi;
+ if [ -n "$configureScript" ]; then
+ local -a flagsArray;
+ concatTo flagsArray configureFlags configureFlagsArray;
+ echoCmd 'configure flags' "${flagsArray[@]}";
+ $configureScript "${flagsArray[@]}";
+ unset flagsArray;
+ else
+ echo "no configure script, doing nothing";
+ fi;
+ runHook postConfigure
+}
+consumeEntire ()
+{
+
+ if IFS='' read -r -d '' "$1"; then
+ echo "consumeEntire(): ERROR: Input null bytes, won't process" 1>&2;
+ return 1;
+ fi
+}
+distPhase ()
+{
+
+ runHook preDist;
+ local flagsArray=();
+ concatTo flagsArray distFlags distFlagsArray distTarget=dist;
+ echo 'dist flags: %q' "${flagsArray[@]}";
+ make ${makefile:+-f $makefile} "${flagsArray[@]}";
+ if [ "${dontCopyDist:-0}" != 1 ]; then
+ mkdir -p "$out/tarballs";
+ cp -pvd ${tarballs[*]:-*.tar.gz} "$out/tarballs";
+ fi;
+ runHook postDist
+}
+dumpVars ()
+{
+
+ if [ "${noDumpEnvVars:-0}" != 1 ]; then
+ {
+ install -m 0600 /dev/null "$NIX_BUILD_TOP/env-vars" && export 2> /dev/null >| "$NIX_BUILD_TOP/env-vars"
+ } || true;
+ fi
+}
+echoCmd ()
+{
+
+ printf "%s:" "$1";
+ shift;
+ printf ' %q' "$@";
+ echo
+}
+exitHandler ()
+{
+
+ exitCode="$?";
+ set +e;
+ if [ -n "${showBuildStats:-}" ]; then
+ read -r -d '' -a buildTimes < <(times);
+ echo "build times:";
+ echo "user time for the shell ${buildTimes[0]}";
+ echo "system time for the shell ${buildTimes[1]}";
+ echo "user time for all child processes ${buildTimes[2]}";
+ echo "system time for all child processes ${buildTimes[3]}";
+ fi;
+ if (( "$exitCode" != 0 )); then
+ runHook failureHook;
+ if [ -n "${succeedOnFailure:-}" ]; then
+ echo "build failed with exit code $exitCode (ignored)";
+ mkdir -p "$out/nix-support";
+ printf "%s" "$exitCode" > "$out/nix-support/failed";
+ exit 0;
+ fi;
+ else
+ runHook exitHook;
+ fi;
+ return "$exitCode"
+}
+findInputs ()
+{
+
+ local -r pkg="$1";
+ local -r hostOffset="$2";
+ local -r targetOffset="$3";
+ (( hostOffset <= targetOffset )) || exit 1;
+ local varVar="${pkgAccumVarVars[hostOffset + 1]}";
+ local varRef="$varVar[$((targetOffset - hostOffset))]";
+ local var="${!varRef}";
+ unset -v varVar varRef;
+ local varSlice="$var[*]";
+ case "${!varSlice-}" in
+ *" $pkg "*)
+ return 0
+ ;;
+ esac;
+ unset -v varSlice;
+ eval "$var"'+=("$pkg")';
+ if ! [ -e "$pkg" ]; then
+ echo "build input $pkg does not exist" 1>&2;
+ exit 1;
+ fi;
+ function mapOffset ()
+ {
+ local -r inputOffset="$1";
+ local -n outputOffset="$2";
+ if (( inputOffset <= 0 )); then
+ outputOffset=$((inputOffset + hostOffset));
+ else
+ outputOffset=$((inputOffset - 1 + targetOffset));
+ fi
+ };
+ local relHostOffset;
+ for relHostOffset in "${allPlatOffsets[@]}";
+ do
+ local files="${propagatedDepFilesVars[relHostOffset + 1]}";
+ local hostOffsetNext;
+ mapOffset "$relHostOffset" hostOffsetNext;
+ (( -1 <= hostOffsetNext && hostOffsetNext <= 1 )) || continue;
+ local relTargetOffset;
+ for relTargetOffset in "${allPlatOffsets[@]}";
+ do
+ (( "$relHostOffset" <= "$relTargetOffset" )) || continue;
+ local fileRef="${files}[$relTargetOffset - $relHostOffset]";
+ local file="${!fileRef}";
+ unset -v fileRef;
+ local targetOffsetNext;
+ mapOffset "$relTargetOffset" targetOffsetNext;
+ (( -1 <= hostOffsetNext && hostOffsetNext <= 1 )) || continue;
+ [[ -f "$pkg/nix-support/$file" ]] || continue;
+ local pkgNext;
+ read -r -d '' pkgNext < "$pkg/nix-support/$file" || true;
+ for pkgNext in $pkgNext;
+ do
+ findInputs "$pkgNext" "$hostOffsetNext" "$targetOffsetNext";
+ done;
+ done;
+ done
+}
+fixLibtool ()
+{
+
+ local search_path;
+ for flag in $NIX_LDFLAGS;
+ do
+ case $flag in
+ -L*)
+ search_path+=" ${flag#-L}"
+ ;;
+ esac;
+ done;
+ sed -i "$1" -e "s^eval \(sys_lib_search_path=\).*^\1'${search_path:-}'^" -e 's^eval sys_lib_.+search_path=.*^^'
+}
+fixupPhase ()
+{
+
+ local output;
+ for output in $(getAllOutputNames);
+ do
+ if [ -e "${!output}" ]; then
+ chmod -R u+w,u-s,g-s "${!output}";
+ fi;
+ done;
+ runHook preFixup;
+ local output;
+ for output in $(getAllOutputNames);
+ do
+ prefix="${!output}" runHook fixupOutput;
+ done;
+ recordPropagatedDependencies;
+ if [ -n "${setupHook:-}" ]; then
+ mkdir -p "${!outputDev}/nix-support";
+ substituteAll "$setupHook" "${!outputDev}/nix-support/setup-hook";
+ fi;
+ if [ -n "${setupHooks:-}" ]; then
+ mkdir -p "${!outputDev}/nix-support";
+ local hook;
+ for hook in ${setupHooks[@]};
+ do
+ local content;
+ consumeEntire content < "$hook";
+ substituteAllStream content "file '$hook'" >> "${!outputDev}/nix-support/setup-hook";
+ unset -v content;
+ done;
+ unset -v hook;
+ fi;
+ if [ -n "${propagatedUserEnvPkgs:-}" ]; then
+ mkdir -p "${!outputBin}/nix-support";
+ printWords $propagatedUserEnvPkgs > "${!outputBin}/nix-support/propagated-user-env-packages";
+ fi;
+ runHook postFixup
+}
+genericBuild ()
+{
+
+ export GZIP_NO_TIMESTAMPS=1;
+ if [ -f "${buildCommandPath:-}" ]; then
+ source "$buildCommandPath";
+ return;
+ fi;
+ if [ -n "${buildCommand:-}" ]; then
+ eval "$buildCommand";
+ return;
+ fi;
+ if [ -z "${phases[*]:-}" ]; then
+ phases="${prePhases[*]:-} unpackPhase patchPhase ${preConfigurePhases[*]:-} configurePhase ${preBuildPhases[*]:-} buildPhase checkPhase ${preInstallPhases[*]:-} installPhase ${preFixupPhases[*]:-} fixupPhase installCheckPhase ${preDistPhases[*]:-} distPhase ${postPhases[*]:-}";
+ fi;
+ for curPhase in ${phases[*]};
+ do
+ runPhase "$curPhase";
+ done
+}
+getAllOutputNames ()
+{
+
+ if [ -n "$__structuredAttrs" ]; then
+ echo "${!outputs[*]}";
+ else
+ echo "$outputs";
+ fi
+}
+getHostRole ()
+{
+
+ getRole "$hostOffset"
+}
+getHostRoleEnvHook ()
+{
+
+ getRole "$depHostOffset"
+}
+getRole ()
+{
+
+ case $1 in
+ -1)
+ role_post='_FOR_BUILD'
+ ;;
+ 0)
+ role_post=''
+ ;;
+ 1)
+ role_post='_FOR_TARGET'
+ ;;
+ *)
+ echo "binutils-wrapper-2.42: used as improper sort of dependency" 1>&2;
+ return 1
+ ;;
+ esac
+}
+getTargetRole ()
+{
+
+ getRole "$targetOffset"
+}
+getTargetRoleEnvHook ()
+{
+
+ getRole "$depTargetOffset"
+}
+getTargetRoleWrapper ()
+{
+
+ case $targetOffset in
+ -1)
+ export NIX_BINTOOLS_WRAPPER_TARGET_BUILD_x86_64_unknown_linux_gnu=1
+ ;;
+ 0)
+ export NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1
+ ;;
+ 1)
+ export NIX_BINTOOLS_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu=1
+ ;;
+ *)
+ echo "binutils-wrapper-2.42: used as improper sort of dependency" 1>&2;
+ return 1
+ ;;
+ esac
+}
+installCheckPhase ()
+{
+
+ runHook preInstallCheck;
+ if [[ -z "${foundMakefile:-}" ]]; then
+ echo "no Makefile or custom installCheckPhase, doing nothing";
+ else
+ if [[ -z "${installCheckTarget:-}" ]] && ! make -n ${makefile:+-f $makefile} "${installCheckTarget:-installcheck}" > /dev/null 2>&1; then
+ echo "no installcheck target in ${makefile:-Makefile}, doing nothing";
+ else
+ local flagsArray=(${enableParallelChecking:+-j${NIX_BUILD_CORES}} SHELL="$SHELL");
+ concatTo flagsArray makeFlags makeFlagsArray installCheckFlags installCheckFlagsArray installCheckTarget=installcheck;
+ echoCmd 'installcheck flags' "${flagsArray[@]}";
+ make ${makefile:+-f $makefile} "${flagsArray[@]}";
+ unset flagsArray;
+ fi;
+ fi;
+ runHook postInstallCheck
+}
+installPhase ()
+{
+
+ runHook preInstall;
+ if [[ -z "${makeFlags-}" && -z "${makefile:-}" && ! ( -e Makefile || -e makefile || -e GNUmakefile ) ]]; then
+ echo "no Makefile or custom installPhase, doing nothing";
+ runHook postInstall;
+ return;
+ else
+ foundMakefile=1;
+ fi;
+ if [ -n "$prefix" ]; then
+ mkdir -p "$prefix";
+ fi;
+ local flagsArray=(${enableParallelInstalling:+-j${NIX_BUILD_CORES}} SHELL="$SHELL");
+ concatTo flagsArray makeFlags makeFlagsArray installFlags installFlagsArray installTargets=install;
+ echoCmd 'install flags' "${flagsArray[@]}";
+ make ${makefile:+-f $makefile} "${flagsArray[@]}";
+ unset flagsArray;
+ runHook postInstall
+}
+isELF ()
+{
+
+ local fn="$1";
+ local fd;
+ local magic;
+ exec {fd}< "$fn";
+ read -r -n 4 -u "$fd" magic;
+ exec {fd}>&-;
+ if [ "$magic" = 'ELF' ]; then
+ return 0;
+ else
+ return 1;
+ fi
+}
+isMachO ()
+{
+
+ local fn="$1";
+ local fd;
+ local magic;
+ exec {fd}< "$fn";
+ read -r -n 4 -u "$fd" magic;
+ exec {fd}>&-;
+ if [[ "$magic" = $(echo -ne "\xfe\xed\xfa\xcf") || "$magic" = $(echo -ne "\xcf\xfa\xed\xfe") ]]; then
+ return 0;
+ else
+ if [[ "$magic" = $(echo -ne "\xfe\xed\xfa\xce") || "$magic" = $(echo -ne "\xce\xfa\xed\xfe") ]]; then
+ return 0;
+ else
+ if [[ "$magic" = $(echo -ne "\xca\xfe\xba\xbe") || "$magic" = $(echo -ne "\xbe\xba\xfe\xca") ]]; then
+ return 0;
+ else
+ return 1;
+ fi;
+ fi;
+ fi
+}
+isScript ()
+{
+
+ local fn="$1";
+ local fd;
+ local magic;
+ exec {fd}< "$fn";
+ read -r -n 2 -u "$fd" magic;
+ exec {fd}>&-;
+ if [[ "$magic" =~ \#! ]]; then
+ return 0;
+ else
+ return 1;
+ fi
+}
+mapOffset ()
+{
+
+ local -r inputOffset="$1";
+ local -n outputOffset="$2";
+ if (( inputOffset <= 0 )); then
+ outputOffset=$((inputOffset + hostOffset));
+ else
+ outputOffset=$((inputOffset - 1 + targetOffset));
+ fi
+}
+moveToOutput ()
+{
+
+ local patt="$1";
+ local dstOut="$2";
+ local output;
+ for output in $(getAllOutputNames);
+ do
+ if [ "${!output}" = "$dstOut" ]; then
+ continue;
+ fi;
+ local srcPath;
+ for srcPath in "${!output}"/$patt;
+ do
+ if [ ! -e "$srcPath" ] && [ ! -L "$srcPath" ]; then
+ continue;
+ fi;
+ if [ "$dstOut" = REMOVE ]; then
+ echo "Removing $srcPath";
+ rm -r "$srcPath";
+ else
+ local dstPath="$dstOut${srcPath#${!output}}";
+ echo "Moving $srcPath to $dstPath";
+ if [ -d "$dstPath" ] && [ -d "$srcPath" ]; then
+ rmdir "$srcPath" --ignore-fail-on-non-empty;
+ if [ -d "$srcPath" ]; then
+ mv -t "$dstPath" "$srcPath"/*;
+ rmdir "$srcPath";
+ fi;
+ else
+ mkdir -p "$(readlink -m "$dstPath/..")";
+ mv "$srcPath" "$dstPath";
+ fi;
+ fi;
+ local srcParent="$(readlink -m "$srcPath/..")";
+ if [ -n "$(find "$srcParent" -maxdepth 0 -type d -empty 2> /dev/null)" ]; then
+ echo "Removing empty $srcParent/ and (possibly) its parents";
+ rmdir -p --ignore-fail-on-non-empty "$srcParent" 2> /dev/null || true;
+ fi;
+ done;
+ done
+}
+nixChattyLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 5 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixDebugLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 6 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixErrorLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 0 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixInfoLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 3 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixNoticeLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 2 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixTalkativeLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 4 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixVomitLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 7 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+nixWarnLog ()
+{
+
+ if [[ -z ${NIX_LOG_FD-} ]] || [[ ${NIX_DEBUG:-0} -lt 1 ]]; then
+ return;
+ fi;
+ printf "%s\n" "$*" >&"$NIX_LOG_FD"
+}
+patchELF ()
+{
+
+ local dir="$1";
+ [ -e "$dir" ] || return 0;
+ echo "shrinking RPATHs of ELF executables and libraries in $dir";
+ local i;
+ while IFS= read -r -d '' i; do
+ if [[ "$i" =~ .build-id ]]; then
+ continue;
+ fi;
+ if ! isELF "$i"; then
+ continue;
+ fi;
+ echo "shrinking $i";
+ patchelf --shrink-rpath "$i" || true;
+ done < <(find "$dir" -type f -print0)
+}
+patchPhase ()
+{
+
+ runHook prePatch;
+ local -a patchesArray;
+ concatTo patchesArray patches;
+ for i in "${patchesArray[@]}";
+ do
+ echo "applying patch $i";
+ local uncompress=cat;
+ case "$i" in
+ *.gz)
+ uncompress="gzip -d"
+ ;;
+ *.bz2)
+ uncompress="bzip2 -d"
+ ;;
+ *.xz)
+ uncompress="xz -d"
+ ;;
+ *.lzma)
+ uncompress="lzma -d"
+ ;;
+ esac;
+ local -a flagsArray;
+ concatTo flagsArray patchFlags=-p1;
+ $uncompress < "$i" 2>&1 | patch "${flagsArray[@]}";
+ done;
+ runHook postPatch
+}
+patchShebangs ()
+{
+
+ local pathName;
+ local update;
+ while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --host)
+ pathName=HOST_PATH;
+ shift
+ ;;
+ --build)
+ pathName=PATH;
+ shift
+ ;;
+ --update)
+ update=true;
+ shift
+ ;;
+ --)
+ shift;
+ break
+ ;;
+ -* | --*)
+ echo "Unknown option $1 supplied to patchShebangs" 1>&2;
+ return 1
+ ;;
+ *)
+ break
+ ;;
+ esac;
+ done;
+ echo "patching script interpreter paths in $@";
+ local f;
+ local oldPath;
+ local newPath;
+ local arg0;
+ local args;
+ local oldInterpreterLine;
+ local newInterpreterLine;
+ if [[ $# -eq 0 ]]; then
+ echo "No arguments supplied to patchShebangs" 1>&2;
+ return 0;
+ fi;
+ local f;
+ while IFS= read -r -d '' f; do
+ isScript "$f" || continue;
+ read -r oldInterpreterLine < "$f" || [ "$oldInterpreterLine" ];
+ read -r oldPath arg0 args <<< "${oldInterpreterLine:2}";
+ if [[ -z "${pathName:-}" ]]; then
+ if [[ -n $strictDeps && $f == "$NIX_STORE"* ]]; then
+ pathName=HOST_PATH;
+ else
+ pathName=PATH;
+ fi;
+ fi;
+ if [[ "$oldPath" == *"/bin/env" ]]; then
+ if [[ $arg0 == "-S" ]]; then
+ arg0=${args%% *};
+ args=${args#* };
+ newPath="$(PATH="${!pathName}" type -P "env" || true)";
+ args="-S $(PATH="${!pathName}" type -P "$arg0" || true) $args";
+ else
+ if [[ $arg0 == "-"* || $arg0 == *"="* ]]; then
+ echo "$f: unsupported interpreter directive \"$oldInterpreterLine\" (set dontPatchShebangs=1 and handle shebang patching yourself)" 1>&2;
+ exit 1;
+ else
+ newPath="$(PATH="${!pathName}" type -P "$arg0" || true)";
+ fi;
+ fi;
+ else
+ if [[ -z $oldPath ]]; then
+ oldPath="/bin/sh";
+ fi;
+ newPath="$(PATH="${!pathName}" type -P "$(basename "$oldPath")" || true)";
+ args="$arg0 $args";
+ fi;
+ newInterpreterLine="$newPath $args";
+ newInterpreterLine=${newInterpreterLine%${newInterpreterLine##*[![:space:]]}};
+ if [[ -n "$oldPath" && ( "$update" == true || "${oldPath:0:${#NIX_STORE}}" != "$NIX_STORE" ) ]]; then
+ if [[ -n "$newPath" && "$newPath" != "$oldPath" ]]; then
+ echo "$f: interpreter directive changed from \"$oldInterpreterLine\" to \"$newInterpreterLine\"";
+ escapedInterpreterLine=${newInterpreterLine//\\/\\\\};
+ timestamp=$(stat --printf "%y" "$f");
+ sed -i -e "1 s|.*|#\!$escapedInterpreterLine|" "$f";
+ touch --date "$timestamp" "$f";
+ fi;
+ fi;
+ done < <(find "$@" -type f -perm -0100 -print0)
+}
+patchShebangsAuto ()
+{
+
+ if [[ -z "${dontPatchShebangs-}" && -e "$prefix" ]]; then
+ if [[ "$output" != out && "$output" = "$outputDev" ]]; then
+ patchShebangs --build "$prefix";
+ else
+ patchShebangs --host "$prefix";
+ fi;
+ fi
+}
+prependToVar ()
+{
+
+ local -n nameref="$1";
+ local useArray type;
+ if [ -n "$__structuredAttrs" ]; then
+ useArray=true;
+ else
+ useArray=false;
+ fi;
+ if type=$(declare -p "$1" 2> /dev/null); then
+ case "${type#* }" in
+ -A*)
+ echo "prependToVar(): ERROR: trying to use prependToVar on an associative array." 1>&2;
+ return 1
+ ;;
+ -a*)
+ useArray=true
+ ;;
+ *)
+ useArray=false
+ ;;
+ esac;
+ fi;
+ shift;
+ if $useArray; then
+ nameref=("$@" ${nameref+"${nameref[@]}"});
+ else
+ nameref="$* ${nameref-}";
+ fi
+}
+printLines ()
+{
+
+ (( "$#" > 0 )) || return 0;
+ printf '%s\n' "$@"
+}
+printWords ()
+{
+
+ (( "$#" > 0 )) || return 0;
+ printf '%s ' "$@"
+}
+recordPropagatedDependencies ()
+{
+
+ declare -ra flatVars=(depsBuildBuildPropagated propagatedNativeBuildInputs depsBuildTargetPropagated depsHostHostPropagated propagatedBuildInputs depsTargetTargetPropagated);
+ declare -ra flatFiles=("${propagatedBuildDepFiles[@]}" "${propagatedHostDepFiles[@]}" "${propagatedTargetDepFiles[@]}");
+ local propagatedInputsIndex;
+ for propagatedInputsIndex in "${!flatVars[@]}";
+ do
+ local propagatedInputsSlice="${flatVars[$propagatedInputsIndex]}[@]";
+ local propagatedInputsFile="${flatFiles[$propagatedInputsIndex]}";
+ [[ -n "${!propagatedInputsSlice}" ]] || continue;
+ mkdir -p "${!outputDev}/nix-support";
+ printWords ${!propagatedInputsSlice} > "${!outputDev}/nix-support/$propagatedInputsFile";
+ done
+}
+runHook ()
+{
+
+ local hookName="$1";
+ shift;
+ local hooksSlice="${hookName%Hook}Hooks[@]";
+ local hook;
+ for hook in "_callImplicitHook 0 $hookName" ${!hooksSlice+"${!hooksSlice}"};
+ do
+ _logHook "$hookName" "$hook" "$@";
+ _eval "$hook" "$@";
+ done;
+ return 0
+}
+runOneHook ()
+{
+
+ local hookName="$1";
+ shift;
+ local hooksSlice="${hookName%Hook}Hooks[@]";
+ local hook ret=1;
+ for hook in "_callImplicitHook 1 $hookName" ${!hooksSlice+"${!hooksSlice}"};
+ do
+ _logHook "$hookName" "$hook" "$@";
+ if _eval "$hook" "$@"; then
+ ret=0;
+ break;
+ fi;
+ done;
+ return "$ret"
+}
+runPhase ()
+{
+
+ local curPhase="$*";
+ if [[ "$curPhase" = unpackPhase && -n "${dontUnpack:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = patchPhase && -n "${dontPatch:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = configurePhase && -n "${dontConfigure:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = buildPhase && -n "${dontBuild:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = checkPhase && -z "${doCheck:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = installPhase && -n "${dontInstall:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = fixupPhase && -n "${dontFixup:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = installCheckPhase && -z "${doInstallCheck:-}" ]]; then
+ return;
+ fi;
+ if [[ "$curPhase" = distPhase && -z "${doDist:-}" ]]; then
+ return;
+ fi;
+ showPhaseHeader "$curPhase";
+ dumpVars;
+ local startTime endTime;
+ startTime=$(date +"%s");
+ eval "${!curPhase:-$curPhase}";
+ endTime=$(date +"%s");
+ showPhaseFooter "$curPhase" "$startTime" "$endTime";
+ if [ "$curPhase" = unpackPhase ]; then
+ [ -n "${sourceRoot:-}" ] && chmod +x -- "${sourceRoot}";
+ cd -- "${sourceRoot:-.}";
+ fi
+}
+showPhaseFooter ()
+{
+
+ local phase="$1";
+ local startTime="$2";
+ local endTime="$3";
+ local delta=$(( endTime - startTime ));
+ (( delta < 30 )) && return;
+ local H=$((delta/3600));
+ local M=$((delta%3600/60));
+ local S=$((delta%60));
+ echo -n "$phase completed in ";
+ (( H > 0 )) && echo -n "$H hours ";
+ (( M > 0 )) && echo -n "$M minutes ";
+ echo "$S seconds"
+}
+showPhaseHeader ()
+{
+
+ local phase="$1";
+ echo "Running phase: $phase";
+ if [[ -z ${NIX_LOG_FD-} ]]; then
+ return;
+ fi;
+ printf "@nix { \"action\": \"setPhase\", \"phase\": \"%s\" }\n" "$phase" >&"$NIX_LOG_FD"
+}
+stripDirs ()
+{
+
+ local cmd="$1";
+ local ranlibCmd="$2";
+ local paths="$3";
+ local stripFlags="$4";
+ local excludeFlags=();
+ local pathsNew=;
+ [ -z "$cmd" ] && echo "stripDirs: Strip command is empty" 1>&2 && exit 1;
+ [ -z "$ranlibCmd" ] && echo "stripDirs: Ranlib command is empty" 1>&2 && exit 1;
+ local pattern;
+ if [ -n "${stripExclude:-}" ]; then
+ for pattern in "${stripExclude[@]}";
+ do
+ excludeFlags+=(-a '!' '(' -name "$pattern" -o -wholename "$prefix/$pattern" ')');
+ done;
+ fi;
+ local p;
+ for p in ${paths};
+ do
+ if [ -e "$prefix/$p" ]; then
+ pathsNew="${pathsNew} $prefix/$p";
+ fi;
+ done;
+ paths=${pathsNew};
+ if [ -n "${paths}" ]; then
+ echo "stripping (with command $cmd and flags $stripFlags) in $paths";
+ local striperr;
+ striperr="$(mktemp --tmpdir="$TMPDIR" 'striperr.XXXXXX')";
+ find $paths -type f "${excludeFlags[@]}" -a '!' -path "$prefix/lib/debug/*" -printf '%D-%i,%p\0' | sort -t, -k1,1 -u -z | cut -d, -f2- -z | xargs -r -0 -n1 -P "$NIX_BUILD_CORES" -- $cmd $stripFlags 2> "$striperr" || exit_code=$?;
+ [[ "$exit_code" = 123 || -z "$exit_code" ]] || ( cat "$striperr" 1>&2 && exit 1 );
+ rm "$striperr";
+ find $paths -name '*.a' -type f -exec $ranlibCmd '{}' \; 2> /dev/null;
+ fi
+}
+stripHash ()
+{
+
+ local strippedName casematchOpt=0;
+ strippedName="$(basename -- "$1")";
+ shopt -q nocasematch && casematchOpt=1;
+ shopt -u nocasematch;
+ if [[ "$strippedName" =~ ^[a-z0-9]{32}- ]]; then
+ echo "${strippedName:33}";
+ else
+ echo "$strippedName";
+ fi;
+ if (( casematchOpt )); then
+ shopt -s nocasematch;
+ fi
+}
+substitute ()
+{
+
+ local input="$1";
+ local output="$2";
+ shift 2;
+ if [ ! -f "$input" ]; then
+ echo "substitute(): ERROR: file '$input' does not exist" 1>&2;
+ return 1;
+ fi;
+ local content;
+ consumeEntire content < "$input";
+ if [ -e "$output" ]; then
+ chmod +w "$output";
+ fi;
+ substituteStream content "file '$input'" "$@" > "$output"
+}
+substituteAll ()
+{
+
+ local input="$1";
+ local output="$2";
+ local -a args=();
+ _allFlags;
+ substitute "$input" "$output" "${args[@]}"
+}
+substituteAllInPlace ()
+{
+
+ local fileName="$1";
+ shift;
+ substituteAll "$fileName" "$fileName" "$@"
+}
+substituteAllStream ()
+{
+
+ local -a args=();
+ _allFlags;
+ substituteStream "$1" "$2" "${args[@]}"
+}
+substituteInPlace ()
+{
+
+ local -a fileNames=();
+ for arg in "$@";
+ do
+ if [[ "$arg" = "--"* ]]; then
+ break;
+ fi;
+ fileNames+=("$arg");
+ shift;
+ done;
+ for file in "${fileNames[@]}";
+ do
+ substitute "$file" "$file" "$@";
+ done
+}
+substituteStream ()
+{
+
+ local var=$1;
+ local description=$2;
+ shift 2;
+ while (( "$#" )); do
+ local replace_mode="$1";
+ case "$1" in
+ --replace)
+ if ! "$_substituteStream_has_warned_replace_deprecation"; then
+ echo "substituteStream() in derivation $name: WARNING: '--replace' is deprecated, use --replace-{fail,warn,quiet}. ($description)" 1>&2;
+ _substituteStream_has_warned_replace_deprecation=true;
+ fi;
+ replace_mode='--replace-warn'
+ ;&
+ --replace-quiet | --replace-warn | --replace-fail)
+ pattern="$2";
+ replacement="$3";
+ shift 3;
+ local savedvar;
+ savedvar="${!var}";
+ eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}';
+ if [ "$pattern" != "$replacement" ]; then
+ if [ "${!var}" == "$savedvar" ]; then
+ if [ "$replace_mode" == --replace-warn ]; then
+ printf "substituteStream() in derivation $name: WARNING: pattern %q doesn't match anything in %s\n" "$pattern" "$description" 1>&2;
+ else
+ if [ "$replace_mode" == --replace-fail ]; then
+ printf "substituteStream() in derivation $name: ERROR: pattern %q doesn't match anything in %s\n" "$pattern" "$description" 1>&2;
+ return 1;
+ fi;
+ fi;
+ fi;
+ fi
+ ;;
+ --subst-var)
+ local varName="$2";
+ shift 2;
+ if ! [[ "$varName" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
+ echo "substituteStream() in derivation $name: ERROR: substitution variables must be valid Bash names, \"$varName\" isn't." 1>&2;
+ return 1;
+ fi;
+ if [ -z ${!varName+x} ]; then
+ echo "substituteStream() in derivation $name: ERROR: variable \$$varName is unset" 1>&2;
+ return 1;
+ fi;
+ pattern="@$varName@";
+ replacement="${!varName}";
+ eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}'
+ ;;
+ --subst-var-by)
+ pattern="@$2@";
+ replacement="$3";
+ eval "$var"'=${'"$var"'//"$pattern"/"$replacement"}';
+ shift 3
+ ;;
+ *)
+ echo "substituteStream() in derivation $name: ERROR: Invalid command line argument: $1" 1>&2;
+ return 1
+ ;;
+ esac;
+ done;
+ printf "%s" "${!var}"
+}
+unpackFile ()
+{
+
+ curSrc="$1";
+ echo "unpacking source archive $curSrc";
+ if ! runOneHook unpackCmd "$curSrc"; then
+ echo "do not know how to unpack source archive $curSrc";
+ exit 1;
+ fi
+}
+unpackPhase ()
+{
+
+ runHook preUnpack;
+ if [ -z "${srcs:-}" ]; then
+ if [ -z "${src:-}" ]; then
+ echo 'variable $src or $srcs should point to the source';
+ exit 1;
+ fi;
+ srcs="$src";
+ fi;
+ local -a srcsArray;
+ concatTo srcsArray srcs;
+ local dirsBefore="";
+ for i in *;
+ do
+ if [ -d "$i" ]; then
+ dirsBefore="$dirsBefore $i ";
+ fi;
+ done;
+ for i in "${srcsArray[@]}";
+ do
+ unpackFile "$i";
+ done;
+ : "${sourceRoot=}";
+ if [ -n "${setSourceRoot:-}" ]; then
+ runOneHook setSourceRoot;
+ else
+ if [ -z "$sourceRoot" ]; then
+ for i in *;
+ do
+ if [ -d "$i" ]; then
+ case $dirsBefore in
+ *\ $i\ *)
+
+ ;;
+ *)
+ if [ -n "$sourceRoot" ]; then
+ echo "unpacker produced multiple directories";
+ exit 1;
+ fi;
+ sourceRoot="$i"
+ ;;
+ esac;
+ fi;
+ done;
+ fi;
+ fi;
+ if [ -z "$sourceRoot" ]; then
+ echo "unpacker appears to have produced no directories";
+ exit 1;
+ fi;
+ echo "source root is $sourceRoot";
+ if [ "${dontMakeSourcesWritable:-0}" != 1 ]; then
+ chmod -R u+w -- "$sourceRoot";
+ fi;
+ runHook postUnpack
+}
+updateAutotoolsGnuConfigScriptsPhase ()
+{
+
+ if [ -n "${dontUpdateAutotoolsGnuConfigScripts-}" ]; then
+ return;
+ fi;
+ for script in config.sub config.guess;
+ do
+ for f in $(find . -type f -name "$script");
+ do
+ echo "Updating Autotools / GNU config script to a newer upstream version: $f";
+ cp -f "/nix/store/q6x5ag0rns4swggcyvcgd1x5i488ws6c-gnu-config-2024-01-01/$script" "$f";
+ done;
+ done
+}
+updateSourceDateEpoch ()
+{
+
+ local path="$1";
+ [[ $path == -* ]] && path="./$path";
+ local -a res=($(find "$path" -type f -not -newer "$NIX_BUILD_TOP/.." -printf '%T@ %p\0' | sort -n --zero-terminated | tail -n1 --zero-terminated | head -c -1));
+ local time="${res[0]//\.[0-9]*/}";
+ local newestFile="${res[1]}";
+ if [ "${time:-0}" -gt "$SOURCE_DATE_EPOCH" ]; then
+ echo "setting SOURCE_DATE_EPOCH to timestamp $time of file $newestFile";
+ export SOURCE_DATE_EPOCH="$time";
+ local now="$(date +%s)";
+ if [ "$time" -gt $((now - 60)) ]; then
+ echo "warning: file $newestFile may be generated; SOURCE_DATE_EPOCH may be non-deterministic";
+ fi;
+ fi
+}
+PATH="$PATH${nix_saved_PATH:+:$nix_saved_PATH}"
+XDG_DATA_DIRS="$XDG_DATA_DIRS${nix_saved_XDG_DATA_DIRS:+:$nix_saved_XDG_DATA_DIRS}"
+export NIX_BUILD_TOP="$(mktemp -d -t nix-shell.XXXXXX)"
+export TMP="$NIX_BUILD_TOP"
+export TMPDIR="$NIX_BUILD_TOP"
+export TEMP="$NIX_BUILD_TOP"
+export TEMPDIR="$NIX_BUILD_TOP"
+eval "${shellHook:-}"
diff --git a/Dockerfile b/Dockerfile
index fd70d24..c0298c2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -35,6 +35,7 @@ RUN pnpm turbo run build
FROM base AS runner
WORKDIR /app
+RUN corepack enable
# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
@@ -47,5 +48,12 @@ COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/.next/static ./apps/web/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/web/public ./apps/web/public
+# Handle db migrations
+COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json
+COPY --from=builder --chown=nextjs:nodejs /app/packages/db ./packages/db
+
+RUN ["pnpm", "db:generate"]
+RUN ["pnpm", "db:migrate"]
+
EXPOSE 3000
CMD node apps/web/server.js
diff --git a/apps/cli/bin/index.js b/apps/cli/bin/index.js
index e35ca2f..958e404 100644
--- a/apps/cli/bin/index.js
+++ b/apps/cli/bin/index.js
@@ -12188,7 +12188,7 @@ const timezones$1 = {
"America/Los_Angeles": "Pacific Time",
// "Atlantic/Azores": "Azores",
// "Atlantic/Cape_Verde": "Cape Verde Islands",
- // GMT: "UTC",
+ "Etc/UTC": "UTC",
"Europe/London": "The UK",
"Europe/Dublin": "Ireland",
// "Europe/Lisbon": "Lisbon",
diff --git a/apps/web/app/api/db/download/route.ts b/apps/web/app/api/db/download/route.ts
index 68186b9..4192b05 100644
--- a/apps/web/app/api/db/download/route.ts
+++ b/apps/web/app/api/db/download/route.ts
@@ -2,17 +2,24 @@ import { NextRequest, NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import serverConfig from '@lifetracker/shared/config';
+import { getConnectionDetails } from '@lifetracker/db/drizzle';
+import { pgDump } from 'pg-dump-restore';
-const DB_PATH = path.join(serverConfig.dataDir, 'lifetracker.db');
+
+const dbPath = path.join(serverConfig.dataDir, `lifetracker-${new Date().getTime()}.sql`);
+
+const returnVal = (await pgDump(getConnectionDetails(), {
+ filePath: dbPath,
+}));
export async function GET(req: NextRequest) {
try {
// Read the production database file
- const dbFile = fs.readFileSync(DB_PATH);
+ const dbFile = fs.readFileSync(dbPath);
return new NextResponse(dbFile, {
headers: {
'Content-Type': 'application/octet-stream',
- 'Content-Disposition': 'attachment; filename="lifetracker.db"'
+ 'Content-Disposition': `attachment; filename="lifetracker-${new Date().getTime()}.sql"`
}
});
diff --git a/apps/web/app/api/db/upload/route.ts b/apps/web/app/api/db/upload/route.ts
index e8a28dd..4944a5b 100644
--- a/apps/web/app/api/db/upload/route.ts
+++ b/apps/web/app/api/db/upload/route.ts
@@ -2,10 +2,13 @@ import { NextRequest, NextResponse } from 'next/server';
import fs from 'fs';
import path from 'path';
import serverConfig from '@lifetracker/shared/config';
+import { pgDump, pgRestore } from 'pg-dump-restore';
+import { db, getConnectionDetails } from '@lifetracker/db/drizzle';
+import { sql } from 'drizzle-orm';
// Define paths for uploaded files and the production DB
const UPLOAD_DIR = path.join(process.cwd(), 'uploads');
-const DB_PATH = path.join(serverConfig.dataDir, 'lifetracker.db');
+const DB_PATH = path.join(serverConfig.dataDir, `lifetracker-${new Date().getTime()}.sql`);
// Ensure upload directory exists
if (!fs.existsSync(UPLOAD_DIR)) {
@@ -35,25 +38,31 @@ export async function POST(req: NextRequest) {
const fileContent = bodyBuffer.slice(start, end);
// Save the uploaded file to the upload directory
- const uploadedFilePath = path.join(UPLOAD_DIR, 'uploaded.db');
+ const uploadedFilePath = path.join(UPLOAD_DIR, 'uploaded.sql');
fs.writeFileSync(uploadedFilePath, fileContent);
- // Validate the uploaded file extension
- if (!uploadedFilePath.endsWith('.db')) {
- return NextResponse.json({ message: 'Invalid file type. Please upload a .db file.' }, { status: 400 });
- }
+ // Back up the existing production database
+ const backupPath = `${serverConfig.dataDir}/pg-backup-${new Date().getTime()}.sql`;
+ const { stdout, stderr } = await pgDump(getConnectionDetails(), {
+ filePath: `${backupPath}`,
+ });
- // Backup the current production database
- const backupPath = path.join(
- serverConfig.dataDir,
- `backup_${Date.now()}.db`
- );
- if (fs.existsSync(DB_PATH)) {
- fs.copyFileSync(DB_PATH, backupPath);
- }
+ console.log("Backed up existing data to ", backupPath);
+ console.log(stdout);
- // Replace the production database with the uploaded file
- fs.renameSync(uploadedFilePath, DB_PATH);
+ // If it's a SQL file, restore the production database from the uploaded file
+ if (uploadedFilePath.endsWith('.sql')) {
+ const { stdout: restoreStdout, stderr: restoreStderr } = await pgRestore(getConnectionDetails(), {
+ clean: true,
+ filePath: uploadedFilePath,
+ });
+ }
+ // If it ends in .db, assume it's a sqlite
+ else if (uploadedFilePath.endsWith('.db')) {
+ // TODO, if ever
+ return NextResponse.json({ message: 'Invalid file type. Please upload a .sql file.' }, { status: 400 });
+ }
+ else { return NextResponse.json({ message: 'Invalid file type. Please upload a .sql file.' }, { status: 400 }); }
return NextResponse.json({ message: 'Database uploaded and replaced successfully!' }, { status: 200 });
} catch (error) {
diff --git a/apps/web/app/dashboard/admin/page.tsx b/apps/web/app/dashboard/admin/page.tsx
index 5f40c64..e0f5aaa 100644
--- a/apps/web/app/dashboard/admin/page.tsx
+++ b/apps/web/app/dashboard/admin/page.tsx
@@ -14,7 +14,7 @@ export default async function AdminPage() {
return (
<>
-
+ {/*
*/}
{/*
*/}
diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx
index 1d92260..64fd5ef 100644
--- a/apps/web/app/layout.tsx
+++ b/apps/web/app/layout.tsx
@@ -19,7 +19,7 @@ import {
import { getServerAuthSession } from "@/server/auth";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
-import { clientConfig } from "@lifetracker/shared/config";
+import serverConfig, { clientConfig } from "@lifetracker/shared/config";
import { useTimezone } from "@lifetracker/shared-react/hooks/timezones";
import { getUserLocalSettings } from "@/lib/userLocalSettings/userLocalSettings";
diff --git a/apps/web/components/dashboard/admin/DatabaseSettings.tsx b/apps/web/components/dashboard/admin/DatabaseSettings.tsx
index 9eb7253..84d7caa 100644
--- a/apps/web/components/dashboard/admin/DatabaseSettings.tsx
+++ b/apps/web/components/dashboard/admin/DatabaseSettings.tsx
@@ -47,7 +47,7 @@ export default function DatabaseSettings() {
const dbData = await download.blob();
const formData = new FormData();
- formData.append('sqliteFile', dbData, 'remoteDB-file.db');
+ formData.append('sqlFile', dbData, 'remoteDB-file.sql');
uploadDB(formData, setRemoteCopyStatus);
// try {
@@ -71,12 +71,12 @@ export default function DatabaseSettings() {
return (
<>
- Upload SQLite Database
+ Upload Postgres SQL
{uploadStatus &&
{uploadStatus}
}
@@ -85,7 +85,7 @@ export default function DatabaseSettings() {
- Download SQLite Database
+ Download Postgres SQL
diff --git a/apps/web/components/dashboard/analytics/AnalyticsView.tsx b/apps/web/components/dashboard/analytics/AnalyticsView.tsx
index b8e71b8..ded9ce8 100644
--- a/apps/web/components/dashboard/analytics/AnalyticsView.tsx
+++ b/apps/web/components/dashboard/analytics/AnalyticsView.tsx
@@ -48,8 +48,8 @@ export default function AnalyticsView() {
}
return [
// spacetime.now().subtract(1, "week").toNativeDate(),
- spacetime.now(useTimezone()).toNativeDate(),
- spacetime.now(useTimezone()).toNativeDate()
+ parseISO(spacetime.now(useTimezone()).format("iso-short")),
+ parseISO(spacetime.now(useTimezone()).format("iso-short")),
];
})();
@@ -75,6 +75,12 @@ export default function AnalyticsView() {
timezone: useTimezone(),
}).data ?? [];
+ const weightData = api.measurements.getTimeseries.useQuery({
+ dateRange,
+ timezone: useTimezone(),
+ metricName: "weight"
+ }).data ?? [];
+
return (
@@ -176,7 +182,27 @@ export default function AnalyticsView() {
}
-
+
+
Weight
+
+ {
+ !weightData ?
:
+
+ {weightData.map((measurement) => (
+ -
+ {measurement.value} {measurement.unit}
+ ,
+ {
+ spacetime(measurement.datetime)
+ .goto(useTimezone())
+ .format("{iso-short} at {hour} {ampm}")
+ }
+
+ ))}
+
+ }
+
+
Drugs
@@ -192,6 +218,6 @@ export default function AnalyticsView() {
}
-
+
);
}
\ No newline at end of file
diff --git a/apps/web/components/dashboard/categories/CategoriesView.tsx b/apps/web/components/dashboard/categories/CategoriesView.tsx
index 7dc831d..b8dbe3e 100644
--- a/apps/web/components/dashboard/categories/CategoriesView.tsx
+++ b/apps/web/components/dashboard/categories/CategoriesView.tsx
@@ -22,7 +22,7 @@ import Link from "next/link";
export default function CategoriesView() {
const { data: session } = useSession();
const { data: categories } = api.categories.list.useQuery();
- const { data: categoryStats } = api.categories.categoryStats.useQuery();
+ // const { data: categoryStats } = api.categories.categoryStats.useQuery();
const invalidateCategoryList = api.useUtils().categories.list.invalidate;
const { mutate: deleteCategory, isPending: isDeletionPending } =
@@ -57,7 +57,7 @@ export default function CategoriesView() {
{c.name}
{c.description}
- {categoryStats[c.id].numEntries}
+ categoryStats[c.id].numEntries
{
- return spacetime(h.date).add(h.time + tzOffset, "hour").format('{hour} {ampm}');
+ return spacetime(h.datetime).format('{hour} {ampm}');
}
- hour.datetime = localDateTime(hour);
-
-
useEffect(() => {
// console.log(hour.categoryDesc);
@@ -133,12 +130,12 @@ export default function EditableHour({
{hourGroup.length > 1
? (
- {hour.datetime}
+ {format(hour.datetime, "hh")}
|
{localDateTime(hourGroup[hourGroup.length - 1])}
)
- : {hour.datetime}
+ : {spacetime(hour.datetime).format('{hour} {ampm}')}
}
diff --git a/apps/web/components/dashboard/hours/HourMeasurementsDialog.tsx b/apps/web/components/dashboard/hours/HourMeasurementsDialog.tsx
index 679d331..3d5722a 100644
--- a/apps/web/components/dashboard/hours/HourMeasurementsDialog.tsx
+++ b/apps/web/components/dashboard/hours/HourMeasurementsDialog.tsx
@@ -6,7 +6,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { TRPCClientError } from "@trpc/client";
import { useForm } from "react-hook-form";
import { z } from "zod";
-import { zMeasurementSchema, ZMetric } from "@lifetracker/shared/types/metrics";
+import { ZMeasurement, zMeasurementSchema, ZMetric } from "@lifetracker/shared/types/metrics";
import { ZHour } from "@lifetracker/shared/types/days";
import { Icon } from "@/components/ui/icon";
@@ -37,7 +37,7 @@ export default function HourMeasurementsDialog({
}) {
const [hour, setHour] = useState(initialHour);
const [isOpen, onOpenChange] = useState(false);
- const [pendingMeasurement, setPendingMeasurement] = useState(false);
+ const [pendingMeasurement, setPendingMeasurement] = useState
(false);
const pendingRef = useRef(null);
useEffect(() => {
diff --git a/apps/web/package.json b/apps/web/package.json
index 8a96700..6597518 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -78,6 +78,7 @@
"next-auth": "^4.24.5",
"next-pwa": "^5.6.0",
"next-themes": "^0.3.0",
+ "pg-dump-restore": "^1.0.12",
"prettier": "^3.2.5",
"react": "^18.2.0",
"react-colorful": "^5.6.1",
diff --git a/apps/web/public/sw.js b/apps/web/public/sw.js
index 79db2c4..dacc388 100644
--- a/apps/web/public/sw.js
+++ b/apps/web/public/sw.js
@@ -1 +1 @@
-if(!self.define){let e,n={};const s=(s,i)=>(s=new URL(s+".js",i).href,n[s]||new Promise((n=>{if("document"in self){const e=document.createElement("script");e.src=s,e.onload=n,document.head.appendChild(e)}else e=s,importScripts(s),n()})).then((()=>{let e=n[s];if(!e)throw new Error(`Module ${s} didn’t register its module`);return e})));self.define=(i,a)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(n[t])return;let u={};const c=e=>s(e,t),r={module:{uri:t},exports:u,require:c};n[t]=Promise.all(i.map((e=>r[e]||c(e)))).then((e=>(a(...e),u)))}}define(["./workbox-01fd22c6"],(function(e){"use strict";importScripts(),self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"/_next/app-build-manifest.json",revision:"c896ae2ce4746ae29a6b3d44a1adceb4"},{url:"/_next/static/84EuupUp4qnK5mnuiJSM9/_buildManifest.js",revision:"bc3a3ea1418035231ef7dcc4ae31f2c4"},{url:"/_next/static/84EuupUp4qnK5mnuiJSM9/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/112-3896b4c5da37081c.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/334-4ca845535978c25d.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/355-b0484ef7ed7587c8.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/420-cb296f2c2540d988.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/48a55697-54a0f084edc64f80.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/539-63eddf60729cee5e.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/565-56de9415c62a0cfe.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/583-309b90b740372f43.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/690-952c36bbd581db34.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/720-9e109c5fe4289e60.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/736-61fc5fbdd2a567cc.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/765-b914e2ac5bdcd4cd.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/809-397aae2b09bda43a.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/83-1a7a82417443604f.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/842-0af3c92c1a39e786.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/862-9b0948f6a492b473.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/874-7df68caed845efb2.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/897-5c5363d71f2f382f.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/927-fb97569bd0507f8d.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/928-5f3808421ddaae7e.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/967-41c22e48b2661482.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/_not-found/page-2d78ffdb77fb1ad6.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/api/auth/%5B...nextauth%5D/route-b3664948804b7054.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/api/health/route-d14806ae7c285863.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/api/trpc/%5Btrpc%5D/route-fd871f1925786e6f.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/admin/page-2ce806163f6d83a5.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/categories/page-ce27fc06f9abf43f.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/day/%5BdateQuery%5D/page-f3488ed64f807575.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/day/page-5613ccd12b77f645.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/error-77f90c1e2feed4cc.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/layout-90288bfcb970a981.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/metrics/page-378015bb5d09efbe.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/not-found-755c9a89a09dbd60.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/dashboard/timeline/page-2b248bb40496aae5.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/layout-78145d633f9c99a9.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/page-fdcd3a32be380da8.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/settings/api-keys/page-c73d1d47d662570c.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/settings/app/page-9ff790b0a73293f2.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/settings/colors/page-34ac6cedde57ddef.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/settings/info/page-dc8c7ea0dbc6deb1.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/settings/layout-3f0bd1d48f01c925.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/settings/page-3e2b10bce2f21f3b.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/app/signin/page-62d6c882c309f850.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/framework-9adb083686e94c4e.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/main-58b7665c8e4fd83f.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/main-app-7e2bff1688ff4191.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/pages/_app-7486b486666c0829.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/pages/_error-dd760f50b13086bf.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-ae2a795241142997.js",revision:"84EuupUp4qnK5mnuiJSM9"},{url:"/_next/static/css/c5ccd7e138025fa2.css",revision:"c5ccd7e138025fa2"},{url:"/_next/static/media/26a46d62cd723877-s.woff2",revision:"befd9c0fdfa3d8a645d5f95717ed6420"},{url:"/_next/static/media/55c55f0601d81cf3-s.woff2",revision:"43828e14271c77b87e3ed582dbff9f74"},{url:"/_next/static/media/581909926a08bbc8-s.woff2",revision:"f0b86e7c24f455280b8df606b89af891"},{url:"/_next/static/media/6d93bde91c0c2823-s.woff2",revision:"621a07228c8ccbfd647918f1021b4868"},{url:"/_next/static/media/97e0cb1ae144a2a9-s.woff2",revision:"e360c61c5bd8d90639fd4503c829c2dc"},{url:"/_next/static/media/a34f9d1faa5f3315-s.p.woff2",revision:"d4fe31e6a2aebc06b8d6e558c9141119"},{url:"/_next/static/media/df0a9ae256c0569c-s.woff2",revision:"d54db44de5ccb18886ece2fda72bdfe0"},{url:"/blur.avif",revision:"39fa4c532f5f840a29197d53a4e72fe1"},{url:"/icons/logo-128.png",revision:"547f30628d92a5cafdc1d8713cf995bc"},{url:"/icons/logo-16.png",revision:"bb2bd28d2a3e8df4abc71818d0185a5e"},{url:"/icons/logo-48.png",revision:"7a2e7ee8e48d2b20fa9974530d4cac5d"},{url:"/icons/logo-full.svg",revision:"a9d0c720d0ca4aa295a1c3e28b61f224"},{url:"/icons/logo-icon.svg",revision:"ca869c6318fde3ff221aa33b283221eb"},{url:"/icons/logo-text.svg",revision:"4a3938661457c886f109541646e6ac58"},{url:"/manifest.json",revision:"8063bef3057655e31117b32add245dbd"}],{ignoreURLParametersMatching:[]}),e.cleanupOutdatedCaches(),e.registerRoute("/",new e.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:e,response:n,event:s,state:i})=>n&&"opaqueredirect"===n.type?new Response(n.body,{status:200,statusText:"OK",headers:n.headers}):n}]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new e.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),e.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new e.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new e.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new e.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),e.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new e.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/image\?url=.+$/i,new e.StaleWhileRevalidate({cacheName:"next-image",plugins:[new e.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp3|wav|ogg)$/i,new e.CacheFirst({cacheName:"static-audio-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:mp4)$/i,new e.CacheFirst({cacheName:"static-video-assets",plugins:[new e.RangeRequestsPlugin,new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:js)$/i,new e.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:css|less)$/i,new e.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new e.StaleWhileRevalidate({cacheName:"next-data",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute(/\.(?:json|xml|csv)$/i,new e.NetworkFirst({cacheName:"static-data-assets",plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>{if(!(self.origin===e.origin))return!1;const n=e.pathname;return!n.startsWith("/api/auth/")&&!!n.startsWith("/api/")}),new e.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>{if(!(self.origin===e.origin))return!1;return!e.pathname.startsWith("/api/")}),new e.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),e.registerRoute((({url:e})=>!(self.origin===e.origin)),new e.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new e.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")}));
+if(!self.define){let s,a={};const e=(e,t)=>(e=new URL(e+".js",t).href,a[e]||new Promise((a=>{if("document"in self){const s=document.createElement("script");s.src=e,s.onload=a,document.head.appendChild(s)}else s=e,importScripts(e),a()})).then((()=>{let s=a[e];if(!s)throw new Error(`Module ${e} didn’t register its module`);return s})));self.define=(t,i)=>{const n=s||("document"in self?document.currentScript.src:"")||location.href;if(a[n])return;let c={};const u=s=>e(s,n),r={module:{uri:n},exports:c,require:u};a[n]=Promise.all(t.map((s=>r[s]||u(s)))).then((s=>(i(...s),c)))}}define(["./workbox-01fd22c6"],(function(s){"use strict";importScripts(),self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"/_next/app-build-manifest.json",revision:"a829dca93041ba607c9ca225032f21c5"},{url:"/_next/static/aZspmizttnNwl5cZuaWiZ/_buildManifest.js",revision:"6c9d06caf97bc7ed715b14499a83d4d9"},{url:"/_next/static/aZspmizttnNwl5cZuaWiZ/_ssgManifest.js",revision:"b6652df95db52feb4daf4eca35380933"},{url:"/_next/static/chunks/1190-1bbf80b720c09149.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/1355-caafc66cd35f56f7.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/1991-d1948e41ec3beb5c.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/3011-151dd930d5615c9b.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/3279-1bd1f80699d904d7.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/3298-762412cdf8b3a513.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/3375-0fdefb9796668119.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/3629-091dc2b9dd55e918.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/3794-5af08ac694450608.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/4339-f72529885018b1de.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/4341-a9d26bdc24b03dac.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/482-5b7c27ab5df8fec2.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/5230-7936532057530905.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/5317-436dbc29e4dc416d.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/5763-5f686dc321d8bf96.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/6302-48fae2ba772b65aa.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7265-be4aa29e569cc593.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7390-d2af2ac2d1a66bc7.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7624-41b2892939ade7ea.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7711-7bb2b959ec1460a4.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7880-83d61aea9fdb0fa3.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7885-286ab3fce6a22366.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/7899-027304c8aa10c198.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/8125-b3a12115d1ada735.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/886-560153677f93a235.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/_not-found/page-108098b20c5fa08e.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/api/auth/%5B...nextauth%5D/route-ae0196542250d075.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/api/db/download/route-5a66aee5baae826f.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/api/db/upload/route-3bb12abfa0474d04.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/api/health/route-48e3ac6831890179.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/api/trpc/%5Btrpc%5D/route-40a314ba841140bc.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/api/v1/measurements/route-e6649fd0776c5135.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/admin/page-5ba63683dc2e5e7d.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/analytics/page-444cde84c3284dd5.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/categories/page-11bfe706eb836285.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/day/%5BdateQuery%5D/page-426be5ccee634baa.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/day/page-189dbd8bc491353c.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/error-369e6f2be944201b.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/layout-a035798b25d45194.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/metrics/page-b53e2421a3c9459e.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/not-found-8b9fdc3e948cdeee.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/dashboard/timeline/page-411dc8b7092ab359.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/layout-f42bc52e8bdaf9e8.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/page-b52f350efd4c8f7d.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/api-keys/page-2f551282255780dd.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/app/page-6593c64d092733fb.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/colors/page-96f5b163826c5074.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/database/page-5590887ca6ae83af.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/info/page-d1d174de41d98d66.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/layout-dea6a01443d7fb2c.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/settings/page-1675bc05c1272ccd.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/app/signin/page-717255d78e099fe1.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/d27283b4-dff70ffe001e7ed3.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/f8cb9cba-6629a11a2c2de967.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/framework-0387496e70e49165.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/main-95aa079cdd30e4a9.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/main-app-5219bb1ee0fccb90.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/pages/_app-9f228b47d94b5d9d.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/pages/_error-a41bff6b46fb8309.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/chunks/polyfills-42372ed130431b0a.js",revision:"846118c33b2c0e922d7b3a7676f81f6f"},{url:"/_next/static/chunks/webpack-b2b69ca3f3a6ca63.js",revision:"aZspmizttnNwl5cZuaWiZ"},{url:"/_next/static/css/0f1843278811ea82.css",revision:"0f1843278811ea82"},{url:"/_next/static/css/3ed81ce3668ecb5d.css",revision:"3ed81ce3668ecb5d"},{url:"/_next/static/css/a3160e048330d9cb.css",revision:"a3160e048330d9cb"},{url:"/_next/static/media/26a46d62cd723877-s.woff2",revision:"befd9c0fdfa3d8a645d5f95717ed6420"},{url:"/_next/static/media/55c55f0601d81cf3-s.woff2",revision:"43828e14271c77b87e3ed582dbff9f74"},{url:"/_next/static/media/581909926a08bbc8-s.woff2",revision:"f0b86e7c24f455280b8df606b89af891"},{url:"/_next/static/media/6d93bde91c0c2823-s.woff2",revision:"621a07228c8ccbfd647918f1021b4868"},{url:"/_next/static/media/97e0cb1ae144a2a9-s.woff2",revision:"e360c61c5bd8d90639fd4503c829c2dc"},{url:"/_next/static/media/a34f9d1faa5f3315-s.p.woff2",revision:"d4fe31e6a2aebc06b8d6e558c9141119"},{url:"/_next/static/media/df0a9ae256c0569c-s.woff2",revision:"d54db44de5ccb18886ece2fda72bdfe0"},{url:"/blur.avif",revision:"39fa4c532f5f840a29197d53a4e72fe1"},{url:"/icons/logo-128.png",revision:"547f30628d92a5cafdc1d8713cf995bc"},{url:"/icons/logo-16.png",revision:"bb2bd28d2a3e8df4abc71818d0185a5e"},{url:"/icons/logo-48.png",revision:"7a2e7ee8e48d2b20fa9974530d4cac5d"},{url:"/icons/logo-full.svg",revision:"a9d0c720d0ca4aa295a1c3e28b61f224"},{url:"/icons/logo-icon.svg",revision:"ca869c6318fde3ff221aa33b283221eb"},{url:"/icons/logo-text.svg",revision:"4a3938661457c886f109541646e6ac58"},{url:"/manifest.json",revision:"8063bef3057655e31117b32add245dbd"}],{ignoreURLParametersMatching:[]}),s.cleanupOutdatedCaches(),s.registerRoute("/",new s.NetworkFirst({cacheName:"start-url",plugins:[{cacheWillUpdate:async({request:s,response:a,event:e,state:t})=>a&&"opaqueredirect"===a.type?new Response(a.body,{status:200,statusText:"OK",headers:a.headers}):a}]}),"GET"),s.registerRoute(/^https:\/\/fonts\.(?:gstatic)\.com\/.*/i,new s.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new s.ExpirationPlugin({maxEntries:4,maxAgeSeconds:31536e3})]}),"GET"),s.registerRoute(/^https:\/\/fonts\.(?:googleapis)\.com\/.*/i,new s.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[new s.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),s.registerRoute(/\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,new s.StaleWhileRevalidate({cacheName:"static-font-assets",plugins:[new s.ExpirationPlugin({maxEntries:4,maxAgeSeconds:604800})]}),"GET"),s.registerRoute(/\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i,new s.StaleWhileRevalidate({cacheName:"static-image-assets",plugins:[new s.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\/_next\/image\?url=.+$/i,new s.StaleWhileRevalidate({cacheName:"next-image",plugins:[new s.ExpirationPlugin({maxEntries:64,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\.(?:mp3|wav|ogg)$/i,new s.CacheFirst({cacheName:"static-audio-assets",plugins:[new s.RangeRequestsPlugin,new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\.(?:mp4)$/i,new s.CacheFirst({cacheName:"static-video-assets",plugins:[new s.RangeRequestsPlugin,new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\.(?:js)$/i,new s.StaleWhileRevalidate({cacheName:"static-js-assets",plugins:[new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\.(?:css|less)$/i,new s.StaleWhileRevalidate({cacheName:"static-style-assets",plugins:[new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\/_next\/data\/.+\/.+\.json$/i,new s.StaleWhileRevalidate({cacheName:"next-data",plugins:[new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute(/\.(?:json|xml|csv)$/i,new s.NetworkFirst({cacheName:"static-data-assets",plugins:[new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute((({url:s})=>{if(!(self.origin===s.origin))return!1;const a=s.pathname;return!a.startsWith("/api/auth/")&&!!a.startsWith("/api/")}),new s.NetworkFirst({cacheName:"apis",networkTimeoutSeconds:10,plugins:[new s.ExpirationPlugin({maxEntries:16,maxAgeSeconds:86400})]}),"GET"),s.registerRoute((({url:s})=>{if(!(self.origin===s.origin))return!1;return!s.pathname.startsWith("/api/")}),new s.NetworkFirst({cacheName:"others",networkTimeoutSeconds:10,plugins:[new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:86400})]}),"GET"),s.registerRoute((({url:s})=>!(self.origin===s.origin)),new s.NetworkFirst({cacheName:"cross-origin",networkTimeoutSeconds:10,plugins:[new s.ExpirationPlugin({maxEntries:32,maxAgeSeconds:3600})]}),"GET")}));
diff --git a/apps/web/uploads/uploaded.sql b/apps/web/uploads/uploaded.sql
new file mode 100644
index 0000000..bc29b7e
Binary files /dev/null and b/apps/web/uploads/uploaded.sql differ
diff --git a/flake.nix b/flake.nix
index de616f8..1ed224b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -22,8 +22,7 @@
emacs-nox
nodejs
pnpm
- sqlite
-
+ postgresql
] ++ optional stdenv.isLinux inotify-tools
++ optional stdenv.isDarwin terminal-notifier
++ optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
diff --git a/package.json b/package.json
index 842f9fa..0c7db00 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
},
"devDependencies": {
"prettier": "^3.3.3",
+ "tsx": "^4.19.2",
"turbo": "^2.2.3",
"typescript": "^5.6.3"
},
diff --git a/packages/db/drizzle-sqlite.ts b/packages/db/drizzle-sqlite.ts
new file mode 100644
index 0000000..b163a69
--- /dev/null
+++ b/packages/db/drizzle-sqlite.ts
@@ -0,0 +1,16 @@
+import "dotenv/config";
+import { drizzle } from "drizzle-orm/better-sqlite3";
+import Database from "better-sqlite3";
+import * as schema from "./schema";
+import serverConfig from "@lifetracker/shared/config";
+
+export const databaseUrl = serverConfig.dataDir
+ ? `${serverConfig.dataDir}/lifetracker.db`
+ : "./lifetracker.db";
+
+
+const sqlite = new Database(databaseUrl);
+export const db = drizzle(sqlite, {
+ schema,
+ logger: false,
+});
\ No newline at end of file
diff --git a/packages/db/drizzle.config.ts b/packages/db/drizzle.config.ts
index e2f24d3..bf187ba 100644
--- a/packages/db/drizzle.config.ts
+++ b/packages/db/drizzle.config.ts
@@ -1,17 +1,17 @@
-import dotenv from "dotenv";
import type { Config } from "drizzle-kit";
import serverConfig from "@lifetracker/shared/config";
-const databaseURL = serverConfig.dataDir
- ? `${serverConfig.dataDir}/lifetracker.db`
- : "./lifetracker.db";
-
-
-export default {
- dialect: "sqlite",
+const dbInfo = {
schema: "./schema.ts",
out: "./migrations",
+ dialect: "postgresql",
dbCredentials: {
- url: databaseURL,
- },
-} satisfies Config;
\ No newline at end of file
+ url: process.env.NODE_ENV === "test"
+ ? serverConfig.testDatabaseUrl
+ : serverConfig.databaseUrl,
+
+ }
+} satisfies Config;
+
+export default dbInfo;
+
diff --git a/packages/db/drizzle.ts b/packages/db/drizzle.ts
index f552037..4eb4b48 100644
--- a/packages/db/drizzle.ts
+++ b/packages/db/drizzle.ts
@@ -1,23 +1,34 @@
import "dotenv/config";
-import { drizzle } from "drizzle-orm/better-sqlite3";
-import Database from "better-sqlite3";
+import { drizzle } from "drizzle-orm/node-postgres";
+import { Pool } from "pg";
import * as schema from "./schema";
-import { migrate } from "drizzle-orm/better-sqlite3/migrator";
-import path from "path";
+import serverConfig from "@lifetracker/shared/config";
-import dbConfig from "./drizzle.config";
+const pool = new Pool({
+ connectionString: serverConfig.databaseUrl,
+});
-const sqlite = new Database(dbConfig.dbCredentials.url);
-export const db = drizzle(sqlite, {
+export const db = drizzle(pool, {
schema,
logger: false,
});
-export function getInMemoryDB(runMigrations: boolean) {
- const mem = new Database(":memory:");
- const db = drizzle(mem, { schema, logger: true });
- if (runMigrations) {
- migrate(db, { migrationsFolder: path.resolve(__dirname, "./migrations") });
+
+export function getConnectionDetails() {
+ const sourceDb = serverConfig.databaseUrl
+ const sourceDbUrl = new URL(sourceDb)
+ return {
+ port: parseInt(sourceDbUrl.port),
+ host: sourceDbUrl.hostname,
+ database: sourceDbUrl.pathname.slice(1),
+ username: sourceDbUrl.username,
+ password: sourceDbUrl.password
}
- return db;
+}
+// Testing utility
+export async function getTestDB() {
+ const testPool = new Pool({
+ connectionString: serverConfig.testDatabaseUrl,
+ });
+ return drizzle(testPool, { schema });
}
\ No newline at end of file
diff --git a/packages/db/index.ts b/packages/db/index.ts
index d54067f..cba8c1c 100644
--- a/packages/db/index.ts
+++ b/packages/db/index.ts
@@ -1,17 +1,24 @@
-import Database from "better-sqlite3";
+import { Pool, QueryResult } from "pg";
import { ExtractTablesWithRelations } from "drizzle-orm";
-import { SQLiteTransaction } from "drizzle-orm/sqlite-core";
-
+import { PgTransaction } from "drizzle-orm/pg-core";
import * as schema from "./schema";
+// Export the db instance from your drizzle setup (make sure your drizzle file is updated for Postgres)
export { db } from "./drizzle";
export * as schema from "./schema";
-export { SqliteError } from "better-sqlite3";
-// This is exported here to avoid leaking better-sqlite types outside of this package.
-export type LifetrackerDBTransaction = SQLiteTransaction<
- "sync",
- Database.RunResult,
- typeof schema,
- ExtractTablesWithRelations
->;
+// If you need to export Postgres errors, you can export them from the pg package.
+// (Optional – remove if not needed)
+export { DatabaseError } from "pg";
+export const ErrorCodes = {
+ UNIQUE_VIOLATION: "23505",
+};
+
+/**
+ * This type alias is provided to avoid leaking pg types outside of this package.
+ *
+ * Note:
+ * - The first generic parameter is set to "async" because most PostgreSQL drivers (like pg) are asynchronous.
+ * - The second generic parameter uses pg's QueryResult type.
+ */
+export type LifetrackerDBTransaction = PgTransaction>;
diff --git a/packages/db/lifetracker.db b/packages/db/lifetracker.db
deleted file mode 100644
index fb3e856..0000000
Binary files a/packages/db/lifetracker.db and /dev/null differ
diff --git a/packages/db/migrate-to-postgres.ts b/packages/db/migrate-to-postgres.ts
new file mode 100644
index 0000000..12f1c7f
--- /dev/null
+++ b/packages/db/migrate-to-postgres.ts
@@ -0,0 +1,63 @@
+// migrate-to-postgres.ts
+import { sql } from "drizzle-orm";
+import { db as pgDb, getConnectionDetails } from "./drizzle";
+import { db as sqliteDb, databaseUrl } from "./drizzle-sqlite";
+import * as schema from "./schema";
+import { pgDump, pgRestore } from "pg-dump-restore";
+import serverConfig from "@lifetracker/shared/config";
+
+
+
+export async function migrateData() {
+ // First back up existing pg data
+ const filename = `${serverConfig.dataDir}/pg-backup-${new Date().getTime()}.sql`;
+ const { stdout, stderr } = await pgDump(getConnectionDetails(), {
+ filePath: `${filename}`,
+ });
+
+ console.log("Backed up existing data to ", filename);
+ console.log(stdout);
+
+ console.log(`Using sqlite db: ${databaseUrl}`);
+
+ const tables = {
+ "users": schema.users,
+ // "apiKeys": schema.apiKeys,
+ // "colors": schema.colors,
+ // "categories": schema.categories,
+ // "days": schema.days,
+ // "hours": schema.hours,
+ // "metrics": schema.metrics,
+ // "measurements": schema.measurements,
+ };
+
+ // console.log(await sqliteDb.select().from(schema.apiKeys));
+
+ // For each table in your schema, transfer the data
+ for (const tableName of Object.keys(tables)) {
+ const oldData = await sqliteDb.query[tableName].findMany();
+ console.log(`Table: ${tableName}`);
+ var skippedRecords = 0;
+ var migratedRecords = 0;
+ for (const record of oldData) {
+ if ((await pgDb.select().from(tables[tableName]).where(sql`${tables[tableName].id} = ${record.id}`)).length == 0) {
+
+ await pgDb.insert(tables[tableName]).values({
+ ...record,
+ createdAt: new Date(),
+ });
+
+ migratedRecords++;
+ }
+ else {
+ skippedRecords++;
+ }
+ }
+
+ console.log(`Migrated ${migratedRecords} records (skipped ${skippedRecords}) from ${tableName}\n`);
+ }
+
+ console.log("Migration complete!");
+}
+
+migrateData().catch(console.error);
diff --git a/packages/db/migrate.ts b/packages/db/migrate.ts
index caf5a5c..0842000 100644
--- a/packages/db/migrate.ts
+++ b/packages/db/migrate.ts
@@ -1,4 +1,17 @@
import { db } from "./drizzle";
-import { migrate } from "drizzle-orm/better-sqlite3/migrator";
+import { migrate } from "drizzle-orm/node-postgres/migrator";
-migrate(db, { migrationsFolder: "./migrations" });
+async function runMigrations() {
+ try {
+ console.log('Starting database migrations...');
+ await migrate(db, { migrationsFolder: "./migrations" });
+ console.log('Migrations completed successfully');
+ } catch (error) {
+ console.error('Error during migration:', error);
+ process.exit(1);
+ } finally {
+ process.exit(0);
+ }
+}
+
+runMigrations();
diff --git a/packages/db/migrations/0000_moaning_thor.sql b/packages/db/migrations/0000_moaning_thor.sql
deleted file mode 100644
index 0509cc9..0000000
--- a/packages/db/migrations/0000_moaning_thor.sql
+++ /dev/null
@@ -1,137 +0,0 @@
-CREATE TABLE `account` (
- `userId` text NOT NULL,
- `type` text NOT NULL,
- `provider` text NOT NULL,
- `providerAccountId` text NOT NULL,
- `refresh_token` text,
- `access_token` text,
- `expires_at` integer,
- `token_type` text,
- `scope` text,
- `id_token` text,
- `session_state` text,
- PRIMARY KEY(`provider`, `providerAccountId`),
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `apiKey` (
- `id` text PRIMARY KEY NOT NULL,
- `name` text NOT NULL,
- `createdAt` integer NOT NULL,
- `keyId` text NOT NULL,
- `keyHash` text NOT NULL,
- `userId` text NOT NULL,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `category` (
- `id` text PRIMARY KEY NOT NULL,
- `createdAt` integer NOT NULL,
- `name` text NOT NULL,
- `code` real NOT NULL,
- `description` text,
- `colorId` text NOT NULL,
- `parentId` text,
- `userId` text NOT NULL,
- FOREIGN KEY (`colorId`) REFERENCES `color`(`id`) ON UPDATE no action ON DELETE no action,
- FOREIGN KEY (`parentId`) REFERENCES `category`(`id`) ON UPDATE no action ON DELETE no action,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `color` (
- `id` text PRIMARY KEY NOT NULL,
- `createdAt` integer NOT NULL,
- `name` text NOT NULL,
- `hexcode` text NOT NULL,
- `inverse` text,
- `userId` text NOT NULL,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `config` (
- `key` text PRIMARY KEY NOT NULL,
- `value` text NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE `day` (
- `id` text PRIMARY KEY NOT NULL,
- `date` text NOT NULL,
- `mood` integer,
- `comment` text,
- `userId` text NOT NULL,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `hour` (
- `id` text PRIMARY KEY NOT NULL,
- `createdAt` integer NOT NULL,
- `userId` text NOT NULL,
- `comment` text,
- `time` integer NOT NULL,
- `dayId` text NOT NULL,
- `categoryId` text,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade,
- FOREIGN KEY (`dayId`) REFERENCES `day`(`id`) ON UPDATE no action ON DELETE cascade,
- FOREIGN KEY (`categoryId`) REFERENCES `category`(`id`) ON UPDATE no action ON DELETE no action
-);
---> statement-breakpoint
-CREATE TABLE `measurement` (
- `id` text PRIMARY KEY NOT NULL,
- `hourId` text,
- `dayId` text NOT NULL,
- `metricId` text NOT NULL,
- `createdAt` integer NOT NULL,
- `userId` text NOT NULL,
- `value` text NOT NULL,
- FOREIGN KEY (`hourId`) REFERENCES `hour`(`id`) ON UPDATE no action ON DELETE no action,
- FOREIGN KEY (`dayId`) REFERENCES `day`(`id`) ON UPDATE no action ON DELETE cascade,
- FOREIGN KEY (`metricId`) REFERENCES `metric`(`id`) ON UPDATE no action ON DELETE cascade,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `metric` (
- `id` text PRIMARY KEY NOT NULL,
- `name` text NOT NULL,
- `description` text,
- `userId` text NOT NULL,
- `type` text NOT NULL,
- `unit` text,
- `goal` real,
- `icon` text NOT NULL,
- `createdAt` integer NOT NULL,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `session` (
- `sessionToken` text PRIMARY KEY NOT NULL,
- `userId` text NOT NULL,
- `expires` integer NOT NULL,
- FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade
-);
---> statement-breakpoint
-CREATE TABLE `user` (
- `id` text PRIMARY KEY NOT NULL,
- `name` text NOT NULL,
- `email` text NOT NULL,
- `emailVerified` integer,
- `image` text,
- `password` text,
- `role` text DEFAULT 'user',
- `timezone` text DEFAULT 'America/Los_Angeles' NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE `verificationToken` (
- `identifier` text NOT NULL,
- `token` text NOT NULL,
- `expires` integer NOT NULL,
- PRIMARY KEY(`identifier`, `token`)
-);
---> statement-breakpoint
-CREATE UNIQUE INDEX `apiKey_keyId_unique` ON `apiKey` (`keyId`);--> statement-breakpoint
-CREATE UNIQUE INDEX `apiKey_name_userId_unique` ON `apiKey` (`name`,`userId`);--> statement-breakpoint
-CREATE UNIQUE INDEX `category_userId_code_unique` ON `category` (`userId`,`code`);--> statement-breakpoint
-CREATE UNIQUE INDEX `color_userId_name_unique` ON `color` (`userId`,`name`);--> statement-breakpoint
-CREATE UNIQUE INDEX `day_date_unique` ON `day` (`date`);--> statement-breakpoint
-CREATE UNIQUE INDEX `hour_dayId_time_unique` ON `hour` (`dayId`,`time`);--> statement-breakpoint
-CREATE UNIQUE INDEX `metric_userId_name_unique` ON `metric` (`userId`,`name`);--> statement-breakpoint
-CREATE UNIQUE INDEX `user_email_unique` ON `user` (`email`);
\ No newline at end of file
diff --git a/packages/db/migrations/0000_redundant_glorian.sql b/packages/db/migrations/0000_redundant_glorian.sql
new file mode 100644
index 0000000..4b7a30e
--- /dev/null
+++ b/packages/db/migrations/0000_redundant_glorian.sql
@@ -0,0 +1,215 @@
+CREATE TABLE IF NOT EXISTS "account" (
+ "userId" text NOT NULL,
+ "type" text NOT NULL,
+ "provider" text NOT NULL,
+ "providerAccountId" text NOT NULL,
+ "refresh_token" text,
+ "access_token" text,
+ "expires_at" integer,
+ "token_type" text,
+ "scope" text,
+ "id_token" text,
+ "session_state" text,
+ CONSTRAINT "account_provider_providerAccountId_pk" PRIMARY KEY("provider","providerAccountId")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "apiKey" (
+ "id" text PRIMARY KEY NOT NULL,
+ "name" text NOT NULL,
+ "createdAt" timestamp DEFAULT now() NOT NULL,
+ "keyId" text NOT NULL,
+ "keyHash" text NOT NULL,
+ "userId" text NOT NULL,
+ CONSTRAINT "apiKey_keyId_unique" UNIQUE("keyId"),
+ CONSTRAINT "apiKey_name_userId_unique" UNIQUE("name","userId")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "category" (
+ "id" text PRIMARY KEY NOT NULL,
+ "createdAt" timestamp DEFAULT now() NOT NULL,
+ "name" text NOT NULL,
+ "code" real NOT NULL,
+ "description" text,
+ "colorId" text NOT NULL,
+ "parentId" text,
+ "userId" text NOT NULL,
+ CONSTRAINT "category_userId_code_unique" UNIQUE("userId","code")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "color" (
+ "id" text PRIMARY KEY NOT NULL,
+ "createdAt" timestamp DEFAULT now() NOT NULL,
+ "name" text NOT NULL,
+ "hexcode" text NOT NULL,
+ "inverse" text,
+ "userId" text NOT NULL,
+ CONSTRAINT "color_userId_name_unique" UNIQUE("userId","name")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "config" (
+ "key" text PRIMARY KEY NOT NULL,
+ "value" text NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "day" (
+ "id" text PRIMARY KEY NOT NULL,
+ "date" text NOT NULL,
+ "mood" integer,
+ "comment" text,
+ "userId" text NOT NULL,
+ CONSTRAINT "day_date_unique" UNIQUE("date")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "hour" (
+ "id" text PRIMARY KEY NOT NULL,
+ "createdAt" timestamp DEFAULT now() NOT NULL,
+ "userId" text NOT NULL,
+ "comment" text,
+ "time" integer NOT NULL,
+ "dayId" text NOT NULL,
+ "categoryId" text
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "measurement" (
+ "id" text PRIMARY KEY NOT NULL,
+ "hourId" text,
+ "dayId" text NOT NULL,
+ "metricId" text NOT NULL,
+ "createdAt" timestamp DEFAULT now() NOT NULL,
+ "userId" text NOT NULL,
+ "value" text NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "metric" (
+ "id" text PRIMARY KEY NOT NULL,
+ "name" text NOT NULL,
+ "description" text,
+ "userId" text NOT NULL,
+ "type" text NOT NULL,
+ "unit" text,
+ "goal" real,
+ "icon" text NOT NULL,
+ "createdAt" timestamp DEFAULT now() NOT NULL,
+ CONSTRAINT "metric_userId_name_unique" UNIQUE("userId","name")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "session" (
+ "sessionToken" text PRIMARY KEY NOT NULL,
+ "userId" text NOT NULL,
+ "expires" timestamp NOT NULL
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "user" (
+ "id" text PRIMARY KEY NOT NULL,
+ "name" text NOT NULL,
+ "email" text NOT NULL,
+ "emailVerified" integer,
+ "image" text,
+ "password" text,
+ "role" text DEFAULT 'user',
+ "timezone" text DEFAULT 'America/Los_Angeles' NOT NULL,
+ CONSTRAINT "user_email_unique" UNIQUE("email")
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "verificationToken" (
+ "identifier" text NOT NULL,
+ "token" text NOT NULL,
+ "expires" timestamp NOT NULL,
+ CONSTRAINT "verificationToken_identifier_token_pk" PRIMARY KEY("identifier","token")
+);
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "account" ADD CONSTRAINT "account_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "apiKey" ADD CONSTRAINT "apiKey_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "category" ADD CONSTRAINT "category_colorId_color_id_fk" FOREIGN KEY ("colorId") REFERENCES "public"."color"("id") ON DELETE no action ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "category" ADD CONSTRAINT "category_parentId_category_id_fk" FOREIGN KEY ("parentId") REFERENCES "public"."category"("id") ON DELETE no action ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "category" ADD CONSTRAINT "category_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "color" ADD CONSTRAINT "color_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "day" ADD CONSTRAINT "day_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "hour" ADD CONSTRAINT "hour_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "hour" ADD CONSTRAINT "hour_dayId_day_id_fk" FOREIGN KEY ("dayId") REFERENCES "public"."day"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "hour" ADD CONSTRAINT "hour_categoryId_category_id_fk" FOREIGN KEY ("categoryId") REFERENCES "public"."category"("id") ON DELETE no action ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "measurement" ADD CONSTRAINT "measurement_hourId_hour_id_fk" FOREIGN KEY ("hourId") REFERENCES "public"."hour"("id") ON DELETE no action ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "measurement" ADD CONSTRAINT "measurement_dayId_day_id_fk" FOREIGN KEY ("dayId") REFERENCES "public"."day"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "measurement" ADD CONSTRAINT "measurement_metricId_metric_id_fk" FOREIGN KEY ("metricId") REFERENCES "public"."metric"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "measurement" ADD CONSTRAINT "measurement_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "metric" ADD CONSTRAINT "metric_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "session" ADD CONSTRAINT "session_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
diff --git a/packages/db/migrations/0001_modify_hour_datetime.sql b/packages/db/migrations/0001_modify_hour_datetime.sql
new file mode 100644
index 0000000..abc94e4
--- /dev/null
+++ b/packages/db/migrations/0001_modify_hour_datetime.sql
@@ -0,0 +1,18 @@
+-- Custom SQL migration file, put you code below! --
+ -- Step 1: Add the new 'datetime' column
+ ALTER TABLE "hour"
+ ADD COLUMN "datetime" TIMESTAMPTZ;
+
+ -- Step 2: Update 'datetime' by combining 'Day.date' and 'Hour.time'
+ UPDATE "hour"
+ SET "datetime" = ("day"."date"::timestamp + ("hour"."time" * INTERVAL '1 hour')) AT TIME ZONE 'UTC'
+ FROM "day"
+ WHERE "hour"."dayId" = "day"."id";
+
+ -- Step 3: Add a unique constraint to 'datetime'
+ ALTER TABLE "hour"
+ ADD CONSTRAINT "hour_datetime_unique" UNIQUE("datetime");
+
+ -- Step 3: Drop the old 'time' column
+ ALTER TABLE "hour"
+ DROP COLUMN "time";
diff --git a/packages/db/migrations/0002_seed_ryan_user.sql b/packages/db/migrations/0002_seed_ryan_user.sql
new file mode 100644
index 0000000..ea5d72d
--- /dev/null
+++ b/packages/db/migrations/0002_seed_ryan_user.sql
@@ -0,0 +1,54 @@
+INSERT INTO "user" (
+ "id",
+ "name",
+ "email",
+ "emailVerified",
+ "image",
+ "password",
+ "role",
+ "timezone"
+)
+VALUES (
+ 'n7yns1s5b122y5e8v0p6uyt8',
+ 'Ryan Pandya',
+ 'ryan@ryanpandya.com',
+ null,
+ null,
+ '$2a$10$ngv9752uxDT11hSPfdZmAe2D8VXLB9mcXkN7TRPI5GZQCuriIu1gC',
+ 'admin',
+ 'America/Los_Angeles'
+);
+
+INSERT INTO "apiKey" (
+ "id",
+ "name",
+ "createdAt",
+ "keyId",
+ "keyHash",
+ "userId"
+)
+VALUES (
+ 'wxl62dg2n721tgzlz3spnjbu',
+ 'CLI App',
+ to_timestamp('1731634820') AT TIME ZONE 'UTC',
+ 'b9b17eb909ce0ecdbf33',
+ '$2a$10$NhOG42FjMbDycWHcJI4LH.Jp.aCV.op7llIP0zw/CBUmB3lO0HHQu',
+ 'n7yns1s5b122y5e8v0p6uyt8'
+);
+
+INSERT INTO "apiKey" (
+ "id",
+ "name",
+ "createdAt",
+ "keyId",
+ "keyHash",
+ "userId"
+)
+VALUES (
+ 'i703hxfm1xoov08jc214jnoz',
+ 'Node-Red',
+ to_timestamp('1737068601') AT TIME ZONE 'UTC',
+ '820b8395dee76268b559',
+ '$2a$10$eUs4vYj2jr47LY6Rou4peudddpB/pyHRo2.cbomoUqNbAJf9RtZDS',
+ 'n7yns1s5b122y5e8v0p6uyt8'
+);
\ No newline at end of file
diff --git a/packages/db/migrations/0003_silky_mongu.sql b/packages/db/migrations/0003_silky_mongu.sql
new file mode 100644
index 0000000..25d5a40
--- /dev/null
+++ b/packages/db/migrations/0003_silky_mongu.sql
@@ -0,0 +1,6 @@
+ALTER TABLE "apiKey" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "category" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "color" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "hour" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "measurement" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;--> statement-breakpoint
+ALTER TABLE "metric" ALTER COLUMN "createdAt" SET DATA TYPE timestamp with time zone;
\ No newline at end of file
diff --git a/packages/db/migrations/0004_tan_justin_hammer.sql b/packages/db/migrations/0004_tan_justin_hammer.sql
new file mode 100644
index 0000000..5e967cd
--- /dev/null
+++ b/packages/db/migrations/0004_tan_justin_hammer.sql
@@ -0,0 +1 @@
+ALTER TABLE "hour" DROP COLUMN IF EXISTS "time";
\ No newline at end of file
diff --git a/packages/db/migrations/meta/0000_snapshot.json b/packages/db/migrations/meta/0000_snapshot.json
index f2bf3a2..63ab378 100644
--- a/packages/db/migrations/meta/0000_snapshot.json
+++ b/packages/db/migrations/meta/0000_snapshot.json
@@ -1,88 +1,78 @@
{
- "version": "6",
- "dialect": "sqlite",
- "id": "9a832735-dcfa-42cc-ad15-6be5b898a160",
+ "id": "8809abd6-6301-4dba-9f67-13071abd3086",
"prevId": "00000000-0000-0000-0000-000000000000",
+ "version": "7",
+ "dialect": "postgresql",
"tables": {
- "account": {
+ "public.account": {
"name": "account",
+ "schema": "",
"columns": {
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"type": {
"name": "type",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"provider": {
"name": "provider",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"providerAccountId": {
"name": "providerAccountId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "integer",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"token_type": {
"name": "token_type",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"scope": {
"name": "scope",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"id_token": {
"name": "id_token",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"session_state": {
"name": "session_state",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
}
},
"indexes": {},
@@ -103,78 +93,58 @@
},
"compositePrimaryKeys": {
"account_provider_providerAccountId_pk": {
+ "name": "account_provider_providerAccountId_pk",
"columns": [
"provider",
"providerAccountId"
- ],
- "name": "account_provider_providerAccountId_pk"
+ ]
}
},
"uniqueConstraints": {}
},
- "apiKey": {
+ "public.apiKey": {
"name": "apiKey",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"createdAt": {
"name": "createdAt",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
"notNull": true,
- "autoincrement": false
+ "default": "now()"
},
"keyId": {
"name": "keyId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"keyHash": {
"name": "keyHash",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
- }
- },
- "indexes": {
- "apiKey_keyId_unique": {
- "name": "apiKey_keyId_unique",
- "columns": [
- "keyId"
- ],
- "isUnique": true
- },
- "apiKey_name_userId_unique": {
- "name": "apiKey_name_userId_unique",
- "columns": [
- "name",
- "userId"
- ],
- "isUnique": true
+ "notNull": true
}
},
+ "indexes": {},
"foreignKeys": {
"apiKey_userId_user_id_fk": {
"name": "apiKey_userId_user_id_fk",
@@ -191,78 +161,79 @@
}
},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "apiKey_keyId_unique": {
+ "name": "apiKey_keyId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "keyId"
+ ]
+ },
+ "apiKey_name_userId_unique": {
+ "name": "apiKey_name_userId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "name",
+ "userId"
+ ]
+ }
+ }
},
- "category": {
+ "public.category": {
"name": "category",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"createdAt": {
"name": "createdAt",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
"notNull": true,
- "autoincrement": false
+ "default": "now()"
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"code": {
"name": "code",
"type": "real",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"colorId": {
"name": "colorId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"parentId": {
"name": "parentId",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
- }
- },
- "indexes": {
- "category_userId_code_unique": {
- "name": "category_userId_code_unique",
- "columns": [
- "userId",
- "code"
- ],
- "isUnique": true
+ "notNull": true
}
},
+ "indexes": {},
"foreignKeys": {
"category_colorId_color_id_fk": {
"name": "category_colorId_color_id_fk",
@@ -305,64 +276,60 @@
}
},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "category_userId_code_unique": {
+ "name": "category_userId_code_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "code"
+ ]
+ }
+ }
},
- "color": {
+ "public.color": {
"name": "color",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"createdAt": {
"name": "createdAt",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
"notNull": true,
- "autoincrement": false
+ "default": "now()"
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"hexcode": {
"name": "hexcode",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"inverse": {
"name": "inverse",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
- }
- },
- "indexes": {
- "color_userId_name_unique": {
- "name": "color_userId_name_unique",
- "columns": [
- "userId",
- "name"
- ],
- "isUnique": true
+ "notNull": true
}
},
+ "indexes": {},
"foreignKeys": {
"color_userId_user_id_fk": {
"name": "color_userId_user_id_fk",
@@ -379,24 +346,32 @@
}
},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "color_userId_name_unique": {
+ "name": "color_userId_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "name"
+ ]
+ }
+ }
},
- "config": {
+ "public.config": {
"name": "config",
+ "schema": "",
"columns": {
"key": {
"name": "key",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
}
},
"indexes": {},
@@ -404,54 +379,42 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
- "day": {
+ "public.day": {
"name": "day",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"date": {
"name": "date",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"mood": {
"name": "mood",
"type": "integer",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"comment": {
"name": "comment",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
- }
- },
- "indexes": {
- "day_date_unique": {
- "name": "day_date_unique",
- "columns": [
- "date"
- ],
- "isUnique": true
+ "notNull": true
}
},
+ "indexes": {},
"foreignKeys": {
"day_userId_user_id_fk": {
"name": "day_userId_user_id_fk",
@@ -468,71 +431,71 @@
}
},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "day_date_unique": {
+ "name": "day_date_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "date"
+ ]
+ }
+ }
},
- "hour": {
+ "public.hour": {
"name": "hour",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"createdAt": {
"name": "createdAt",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
"notNull": true,
- "autoincrement": false
+ "default": "now()"
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"comment": {
"name": "comment",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"time": {
"name": "time",
"type": "integer",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
+ },
+ "datetime": {
+ "name": "datetime",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
},
"dayId": {
"name": "dayId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"categoryId": {
"name": "categoryId",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
- }
- },
- "indexes": {
- "hour_dayId_time_unique": {
- "name": "hour_dayId_time_unique",
- "columns": [
- "dayId",
- "time"
- ],
- "isUnique": true
+ "notNull": false
}
},
+ "indexes": {},
"foreignKeys": {
"hour_userId_user_id_fk": {
"name": "hour_userId_user_id_fk",
@@ -575,59 +538,63 @@
}
},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "hour_dayId_datetime_unique": {
+ "name": "hour_dayId_datetime_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "dayId",
+ "datetime"
+ ]
+ }
+ }
},
- "measurement": {
+ "public.measurement": {
"name": "measurement",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"hourId": {
"name": "hourId",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"dayId": {
"name": "dayId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"metricId": {
"name": "metricId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"createdAt": {
"name": "createdAt",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
"notNull": true,
- "autoincrement": false
+ "default": "now()"
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
}
},
"indexes": {},
@@ -688,83 +655,67 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
- "metric": {
+ "public.metric": {
"name": "metric",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"type": {
"name": "type",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"unit": {
"name": "unit",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"goal": {
"name": "goal",
"type": "real",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"icon": {
"name": "icon",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"createdAt": {
"name": "createdAt",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
"notNull": true,
- "autoincrement": false
- }
- },
- "indexes": {
- "metric_userId_name_unique": {
- "name": "metric_userId_name_unique",
- "columns": [
- "userId",
- "name"
- ],
- "isUnique": true
+ "default": "now()"
}
},
+ "indexes": {},
"foreignKeys": {
"metric_userId_user_id_fk": {
"name": "metric_userId_user_id_fk",
@@ -781,31 +732,38 @@
}
},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "metric_userId_name_unique": {
+ "name": "metric_userId_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "name"
+ ]
+ }
+ }
},
- "session": {
+ "public.session": {
"name": "session",
+ "schema": "",
"columns": {
"sessionToken": {
"name": "sessionToken",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"userId": {
"name": "userId",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"expires": {
"name": "expires",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
}
},
"indexes": {},
@@ -827,57 +785,51 @@
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
- "user": {
+ "public.user": {
"name": "user",
+ "schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"emailVerified": {
"name": "emailVerified",
"type": "integer",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"image": {
"name": "image",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
- "notNull": false,
- "autoincrement": false
+ "notNull": false
},
"role": {
"name": "role",
"type": "text",
"primaryKey": false,
"notNull": false,
- "autoincrement": false,
"default": "'user'"
},
"timezone": {
@@ -885,69 +837,65 @@
"type": "text",
"primaryKey": false,
"notNull": true,
- "autoincrement": false,
"default": "'America/Los_Angeles'"
}
},
- "indexes": {
- "user_email_unique": {
- "name": "user_email_unique",
- "columns": [
- "email"
- ],
- "isUnique": true
- }
- },
+ "indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
- "uniqueConstraints": {}
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "email"
+ ]
+ }
+ }
},
- "verificationToken": {
+ "public.verificationToken": {
"name": "verificationToken",
+ "schema": "",
"columns": {
"identifier": {
"name": "identifier",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"token": {
"name": "token",
"type": "text",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
},
"expires": {
"name": "expires",
- "type": "integer",
+ "type": "timestamp",
"primaryKey": false,
- "notNull": true,
- "autoincrement": false
+ "notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"verificationToken_identifier_token_pk": {
+ "name": "verificationToken_identifier_token_pk",
"columns": [
"identifier",
"token"
- ],
- "name": "verificationToken_identifier_token_pk"
+ ]
}
},
"uniqueConstraints": {}
}
},
"enums": {},
+ "schemas": {},
+ "sequences": {},
"_meta": {
+ "columns": {},
"schemas": {},
- "tables": {},
- "columns": {}
- },
- "internal": {
- "indexes": {}
+ "tables": {}
}
}
\ No newline at end of file
diff --git a/packages/db/migrations/meta/0001_snapshot.json b/packages/db/migrations/meta/0001_snapshot.json
new file mode 100644
index 0000000..cc63263
--- /dev/null
+++ b/packages/db/migrations/meta/0001_snapshot.json
@@ -0,0 +1,901 @@
+{
+ "id": "d1116059-9901-4852-9826-5a4458564eb5",
+ "prevId": "8809abd6-6301-4dba-9f67-13071abd3086",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "providerAccountId": {
+ "name": "providerAccountId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_type": {
+ "name": "token_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_state": {
+ "name": "session_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_userId_user_id_fk": {
+ "name": "account_userId_user_id_fk",
+ "tableFrom": "account",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {
+ "account_provider_providerAccountId_pk": {
+ "name": "account_provider_providerAccountId_pk",
+ "columns": [
+ "provider",
+ "providerAccountId"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ },
+ "public.apiKey": {
+ "name": "apiKey",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "keyId": {
+ "name": "keyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keyHash": {
+ "name": "keyHash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "apiKey_userId_user_id_fk": {
+ "name": "apiKey_userId_user_id_fk",
+ "tableFrom": "apiKey",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "apiKey_keyId_unique": {
+ "name": "apiKey_keyId_unique",
+ "columns": [
+ "keyId"
+ ],
+ "nullsNotDistinct": false
+ },
+ "apiKey_name_userId_unique": {
+ "name": "apiKey_name_userId_unique",
+ "columns": [
+ "name",
+ "userId"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.category": {
+ "name": "category",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "colorId": {
+ "name": "colorId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parentId": {
+ "name": "parentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "category_colorId_color_id_fk": {
+ "name": "category_colorId_color_id_fk",
+ "tableFrom": "category",
+ "columnsFrom": [
+ "colorId"
+ ],
+ "tableTo": "color",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "category_parentId_category_id_fk": {
+ "name": "category_parentId_category_id_fk",
+ "tableFrom": "category",
+ "columnsFrom": [
+ "parentId"
+ ],
+ "tableTo": "category",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "category_userId_user_id_fk": {
+ "name": "category_userId_user_id_fk",
+ "tableFrom": "category",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "category_userId_code_unique": {
+ "name": "category_userId_code_unique",
+ "columns": [
+ "userId",
+ "code"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.color": {
+ "name": "color",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hexcode": {
+ "name": "hexcode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inverse": {
+ "name": "inverse",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "color_userId_user_id_fk": {
+ "name": "color_userId_user_id_fk",
+ "tableFrom": "color",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "color_userId_name_unique": {
+ "name": "color_userId_name_unique",
+ "columns": [
+ "userId",
+ "name"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.config": {
+ "name": "config",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.day": {
+ "name": "day",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mood": {
+ "name": "mood",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "day_userId_user_id_fk": {
+ "name": "day_userId_user_id_fk",
+ "tableFrom": "day",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "day_date_unique": {
+ "name": "day_date_unique",
+ "columns": [
+ "date"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.hour": {
+ "name": "hour",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "datetime": {
+ "name": "datetime",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "categoryId": {
+ "name": "categoryId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "hour_userId_user_id_fk": {
+ "name": "hour_userId_user_id_fk",
+ "tableFrom": "hour",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "hour_dayId_day_id_fk": {
+ "name": "hour_dayId_day_id_fk",
+ "tableFrom": "hour",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "tableTo": "day",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "hour_categoryId_category_id_fk": {
+ "name": "hour_categoryId_category_id_fk",
+ "tableFrom": "hour",
+ "columnsFrom": [
+ "categoryId"
+ ],
+ "tableTo": "category",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "hour_dayId_datetime_unique": {
+ "name": "hour_dayId_datetime_unique",
+ "columns": [
+ "dayId",
+ "datetime"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.measurement": {
+ "name": "measurement",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "hourId": {
+ "name": "hourId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metricId": {
+ "name": "metricId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "measurement_hourId_hour_id_fk": {
+ "name": "measurement_hourId_hour_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "hourId"
+ ],
+ "tableTo": "hour",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "measurement_dayId_day_id_fk": {
+ "name": "measurement_dayId_day_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "tableTo": "day",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "measurement_metricId_metric_id_fk": {
+ "name": "measurement_metricId_metric_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "metricId"
+ ],
+ "tableTo": "metric",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "measurement_userId_user_id_fk": {
+ "name": "measurement_userId_user_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.metric": {
+ "name": "metric",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal": {
+ "name": "goal",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "metric_userId_user_id_fk": {
+ "name": "metric_userId_user_id_fk",
+ "tableFrom": "metric",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "metric_userId_name_unique": {
+ "name": "metric_userId_name_unique",
+ "columns": [
+ "userId",
+ "name"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "sessionToken": {
+ "name": "sessionToken",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_userId_user_id_fk": {
+ "name": "session_userId_user_id_fk",
+ "tableFrom": "session",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "emailVerified": {
+ "name": "emailVerified",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'America/Los_Angeles'"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.verificationToken": {
+ "name": "verificationToken",
+ "schema": "",
+ "columns": {
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "verificationToken_identifier_token_pk": {
+ "name": "verificationToken_identifier_token_pk",
+ "columns": [
+ "identifier",
+ "token"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/packages/db/migrations/meta/0002_snapshot.json b/packages/db/migrations/meta/0002_snapshot.json
new file mode 100644
index 0000000..dd2d442
--- /dev/null
+++ b/packages/db/migrations/meta/0002_snapshot.json
@@ -0,0 +1,901 @@
+{
+ "id": "708d11dd-ccaa-48dd-b152-f012b2412704",
+ "prevId": "d1116059-9901-4852-9826-5a4458564eb5",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "providerAccountId": {
+ "name": "providerAccountId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_type": {
+ "name": "token_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_state": {
+ "name": "session_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_userId_user_id_fk": {
+ "name": "account_userId_user_id_fk",
+ "tableFrom": "account",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {
+ "account_provider_providerAccountId_pk": {
+ "name": "account_provider_providerAccountId_pk",
+ "columns": [
+ "provider",
+ "providerAccountId"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ },
+ "public.apiKey": {
+ "name": "apiKey",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "keyId": {
+ "name": "keyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keyHash": {
+ "name": "keyHash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "apiKey_userId_user_id_fk": {
+ "name": "apiKey_userId_user_id_fk",
+ "tableFrom": "apiKey",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "apiKey_keyId_unique": {
+ "name": "apiKey_keyId_unique",
+ "columns": [
+ "keyId"
+ ],
+ "nullsNotDistinct": false
+ },
+ "apiKey_name_userId_unique": {
+ "name": "apiKey_name_userId_unique",
+ "columns": [
+ "name",
+ "userId"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.category": {
+ "name": "category",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "colorId": {
+ "name": "colorId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parentId": {
+ "name": "parentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "category_colorId_color_id_fk": {
+ "name": "category_colorId_color_id_fk",
+ "tableFrom": "category",
+ "columnsFrom": [
+ "colorId"
+ ],
+ "tableTo": "color",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "category_parentId_category_id_fk": {
+ "name": "category_parentId_category_id_fk",
+ "tableFrom": "category",
+ "columnsFrom": [
+ "parentId"
+ ],
+ "tableTo": "category",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "category_userId_user_id_fk": {
+ "name": "category_userId_user_id_fk",
+ "tableFrom": "category",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "category_userId_code_unique": {
+ "name": "category_userId_code_unique",
+ "columns": [
+ "userId",
+ "code"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.color": {
+ "name": "color",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hexcode": {
+ "name": "hexcode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inverse": {
+ "name": "inverse",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "color_userId_user_id_fk": {
+ "name": "color_userId_user_id_fk",
+ "tableFrom": "color",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "color_userId_name_unique": {
+ "name": "color_userId_name_unique",
+ "columns": [
+ "userId",
+ "name"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.config": {
+ "name": "config",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.day": {
+ "name": "day",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mood": {
+ "name": "mood",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "day_userId_user_id_fk": {
+ "name": "day_userId_user_id_fk",
+ "tableFrom": "day",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "day_date_unique": {
+ "name": "day_date_unique",
+ "columns": [
+ "date"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.hour": {
+ "name": "hour",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "datetime": {
+ "name": "datetime",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "categoryId": {
+ "name": "categoryId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "hour_userId_user_id_fk": {
+ "name": "hour_userId_user_id_fk",
+ "tableFrom": "hour",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "hour_dayId_day_id_fk": {
+ "name": "hour_dayId_day_id_fk",
+ "tableFrom": "hour",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "tableTo": "day",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "hour_categoryId_category_id_fk": {
+ "name": "hour_categoryId_category_id_fk",
+ "tableFrom": "hour",
+ "columnsFrom": [
+ "categoryId"
+ ],
+ "tableTo": "category",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "hour_dayId_datetime_unique": {
+ "name": "hour_dayId_datetime_unique",
+ "columns": [
+ "dayId",
+ "datetime"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.measurement": {
+ "name": "measurement",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "hourId": {
+ "name": "hourId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metricId": {
+ "name": "metricId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "measurement_hourId_hour_id_fk": {
+ "name": "measurement_hourId_hour_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "hourId"
+ ],
+ "tableTo": "hour",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ },
+ "measurement_dayId_day_id_fk": {
+ "name": "measurement_dayId_day_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "tableTo": "day",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "measurement_metricId_metric_id_fk": {
+ "name": "measurement_metricId_metric_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "metricId"
+ ],
+ "tableTo": "metric",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ },
+ "measurement_userId_user_id_fk": {
+ "name": "measurement_userId_user_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.metric": {
+ "name": "metric",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal": {
+ "name": "goal",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "metric_userId_user_id_fk": {
+ "name": "metric_userId_user_id_fk",
+ "tableFrom": "metric",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "metric_userId_name_unique": {
+ "name": "metric_userId_name_unique",
+ "columns": [
+ "userId",
+ "name"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "sessionToken": {
+ "name": "sessionToken",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_userId_user_id_fk": {
+ "name": "session_userId_user_id_fk",
+ "tableFrom": "session",
+ "columnsFrom": [
+ "userId"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "emailVerified": {
+ "name": "emailVerified",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'America/Los_Angeles'"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false
+ }
+ }
+ },
+ "public.verificationToken": {
+ "name": "verificationToken",
+ "schema": "",
+ "columns": {
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "verificationToken_identifier_token_pk": {
+ "name": "verificationToken_identifier_token_pk",
+ "columns": [
+ "identifier",
+ "token"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/packages/db/migrations/meta/0003_snapshot.json b/packages/db/migrations/meta/0003_snapshot.json
new file mode 100644
index 0000000..1908e00
--- /dev/null
+++ b/packages/db/migrations/meta/0003_snapshot.json
@@ -0,0 +1,901 @@
+{
+ "id": "2e969918-73b6-4418-bb7b-76acda909a8a",
+ "prevId": "708d11dd-ccaa-48dd-b152-f012b2412704",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "providerAccountId": {
+ "name": "providerAccountId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_type": {
+ "name": "token_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_state": {
+ "name": "session_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_userId_user_id_fk": {
+ "name": "account_userId_user_id_fk",
+ "tableFrom": "account",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "account_provider_providerAccountId_pk": {
+ "name": "account_provider_providerAccountId_pk",
+ "columns": [
+ "provider",
+ "providerAccountId"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ },
+ "public.apiKey": {
+ "name": "apiKey",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "keyId": {
+ "name": "keyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keyHash": {
+ "name": "keyHash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "apiKey_userId_user_id_fk": {
+ "name": "apiKey_userId_user_id_fk",
+ "tableFrom": "apiKey",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "apiKey_keyId_unique": {
+ "name": "apiKey_keyId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "keyId"
+ ]
+ },
+ "apiKey_name_userId_unique": {
+ "name": "apiKey_name_userId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "name",
+ "userId"
+ ]
+ }
+ }
+ },
+ "public.category": {
+ "name": "category",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "colorId": {
+ "name": "colorId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parentId": {
+ "name": "parentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "category_colorId_color_id_fk": {
+ "name": "category_colorId_color_id_fk",
+ "tableFrom": "category",
+ "tableTo": "color",
+ "columnsFrom": [
+ "colorId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "category_parentId_category_id_fk": {
+ "name": "category_parentId_category_id_fk",
+ "tableFrom": "category",
+ "tableTo": "category",
+ "columnsFrom": [
+ "parentId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "category_userId_user_id_fk": {
+ "name": "category_userId_user_id_fk",
+ "tableFrom": "category",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "category_userId_code_unique": {
+ "name": "category_userId_code_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "code"
+ ]
+ }
+ }
+ },
+ "public.color": {
+ "name": "color",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hexcode": {
+ "name": "hexcode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inverse": {
+ "name": "inverse",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "color_userId_user_id_fk": {
+ "name": "color_userId_user_id_fk",
+ "tableFrom": "color",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "color_userId_name_unique": {
+ "name": "color_userId_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "name"
+ ]
+ }
+ }
+ },
+ "public.config": {
+ "name": "config",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.day": {
+ "name": "day",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mood": {
+ "name": "mood",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "day_userId_user_id_fk": {
+ "name": "day_userId_user_id_fk",
+ "tableFrom": "day",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "day_date_unique": {
+ "name": "day_date_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "date"
+ ]
+ }
+ }
+ },
+ "public.hour": {
+ "name": "hour",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "datetime": {
+ "name": "datetime",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "categoryId": {
+ "name": "categoryId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "hour_userId_user_id_fk": {
+ "name": "hour_userId_user_id_fk",
+ "tableFrom": "hour",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "hour_dayId_day_id_fk": {
+ "name": "hour_dayId_day_id_fk",
+ "tableFrom": "hour",
+ "tableTo": "day",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "hour_categoryId_category_id_fk": {
+ "name": "hour_categoryId_category_id_fk",
+ "tableFrom": "hour",
+ "tableTo": "category",
+ "columnsFrom": [
+ "categoryId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "hour_dayId_datetime_unique": {
+ "name": "hour_dayId_datetime_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "dayId",
+ "datetime"
+ ]
+ }
+ }
+ },
+ "public.measurement": {
+ "name": "measurement",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "hourId": {
+ "name": "hourId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metricId": {
+ "name": "metricId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "measurement_hourId_hour_id_fk": {
+ "name": "measurement_hourId_hour_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "hour",
+ "columnsFrom": [
+ "hourId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "measurement_dayId_day_id_fk": {
+ "name": "measurement_dayId_day_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "day",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "measurement_metricId_metric_id_fk": {
+ "name": "measurement_metricId_metric_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "metric",
+ "columnsFrom": [
+ "metricId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "measurement_userId_user_id_fk": {
+ "name": "measurement_userId_user_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.metric": {
+ "name": "metric",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal": {
+ "name": "goal",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "metric_userId_user_id_fk": {
+ "name": "metric_userId_user_id_fk",
+ "tableFrom": "metric",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "metric_userId_name_unique": {
+ "name": "metric_userId_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "name"
+ ]
+ }
+ }
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "sessionToken": {
+ "name": "sessionToken",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_userId_user_id_fk": {
+ "name": "session_userId_user_id_fk",
+ "tableFrom": "session",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "emailVerified": {
+ "name": "emailVerified",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'America/Los_Angeles'"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "email"
+ ]
+ }
+ }
+ },
+ "public.verificationToken": {
+ "name": "verificationToken",
+ "schema": "",
+ "columns": {
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "verificationToken_identifier_token_pk": {
+ "name": "verificationToken_identifier_token_pk",
+ "columns": [
+ "identifier",
+ "token"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/packages/db/migrations/meta/0004_snapshot.json b/packages/db/migrations/meta/0004_snapshot.json
new file mode 100644
index 0000000..0d5ab12
--- /dev/null
+++ b/packages/db/migrations/meta/0004_snapshot.json
@@ -0,0 +1,895 @@
+{
+ "id": "37a5291a-eed6-4576-a240-2825abdff575",
+ "prevId": "2e969918-73b6-4418-bb7b-76acda909a8a",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "providerAccountId": {
+ "name": "providerAccountId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_type": {
+ "name": "token_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_state": {
+ "name": "session_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_userId_user_id_fk": {
+ "name": "account_userId_user_id_fk",
+ "tableFrom": "account",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "account_provider_providerAccountId_pk": {
+ "name": "account_provider_providerAccountId_pk",
+ "columns": [
+ "provider",
+ "providerAccountId"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ },
+ "public.apiKey": {
+ "name": "apiKey",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "keyId": {
+ "name": "keyId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "keyHash": {
+ "name": "keyHash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "apiKey_userId_user_id_fk": {
+ "name": "apiKey_userId_user_id_fk",
+ "tableFrom": "apiKey",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "apiKey_keyId_unique": {
+ "name": "apiKey_keyId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "keyId"
+ ]
+ },
+ "apiKey_name_userId_unique": {
+ "name": "apiKey_name_userId_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "name",
+ "userId"
+ ]
+ }
+ }
+ },
+ "public.category": {
+ "name": "category",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "code": {
+ "name": "code",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "colorId": {
+ "name": "colorId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "parentId": {
+ "name": "parentId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "category_colorId_color_id_fk": {
+ "name": "category_colorId_color_id_fk",
+ "tableFrom": "category",
+ "tableTo": "color",
+ "columnsFrom": [
+ "colorId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "category_parentId_category_id_fk": {
+ "name": "category_parentId_category_id_fk",
+ "tableFrom": "category",
+ "tableTo": "category",
+ "columnsFrom": [
+ "parentId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "category_userId_user_id_fk": {
+ "name": "category_userId_user_id_fk",
+ "tableFrom": "category",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "category_userId_code_unique": {
+ "name": "category_userId_code_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "code"
+ ]
+ }
+ }
+ },
+ "public.color": {
+ "name": "color",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hexcode": {
+ "name": "hexcode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inverse": {
+ "name": "inverse",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "color_userId_user_id_fk": {
+ "name": "color_userId_user_id_fk",
+ "tableFrom": "color",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "color_userId_name_unique": {
+ "name": "color_userId_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "name"
+ ]
+ }
+ }
+ },
+ "public.config": {
+ "name": "config",
+ "schema": "",
+ "columns": {
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.day": {
+ "name": "day",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "date": {
+ "name": "date",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mood": {
+ "name": "mood",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "day_userId_user_id_fk": {
+ "name": "day_userId_user_id_fk",
+ "tableFrom": "day",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "day_date_unique": {
+ "name": "day_date_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "date"
+ ]
+ }
+ }
+ },
+ "public.hour": {
+ "name": "hour",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "comment": {
+ "name": "comment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "datetime": {
+ "name": "datetime",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "categoryId": {
+ "name": "categoryId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "hour_userId_user_id_fk": {
+ "name": "hour_userId_user_id_fk",
+ "tableFrom": "hour",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "hour_dayId_day_id_fk": {
+ "name": "hour_dayId_day_id_fk",
+ "tableFrom": "hour",
+ "tableTo": "day",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "hour_categoryId_category_id_fk": {
+ "name": "hour_categoryId_category_id_fk",
+ "tableFrom": "hour",
+ "tableTo": "category",
+ "columnsFrom": [
+ "categoryId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "hour_dayId_datetime_unique": {
+ "name": "hour_dayId_datetime_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "dayId",
+ "datetime"
+ ]
+ }
+ }
+ },
+ "public.measurement": {
+ "name": "measurement",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "hourId": {
+ "name": "hourId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "dayId": {
+ "name": "dayId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "metricId": {
+ "name": "metricId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "measurement_hourId_hour_id_fk": {
+ "name": "measurement_hourId_hour_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "hour",
+ "columnsFrom": [
+ "hourId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "measurement_dayId_day_id_fk": {
+ "name": "measurement_dayId_day_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "day",
+ "columnsFrom": [
+ "dayId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "measurement_metricId_metric_id_fk": {
+ "name": "measurement_metricId_metric_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "metric",
+ "columnsFrom": [
+ "metricId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "measurement_userId_user_id_fk": {
+ "name": "measurement_userId_user_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.metric": {
+ "name": "metric",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goal": {
+ "name": "goal",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "createdAt": {
+ "name": "createdAt",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "metric_userId_user_id_fk": {
+ "name": "metric_userId_user_id_fk",
+ "tableFrom": "metric",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "metric_userId_name_unique": {
+ "name": "metric_userId_name_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "userId",
+ "name"
+ ]
+ }
+ }
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "sessionToken": {
+ "name": "sessionToken",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_userId_user_id_fk": {
+ "name": "session_userId_user_id_fk",
+ "tableFrom": "session",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "emailVerified": {
+ "name": "emailVerified",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "timezone": {
+ "name": "timezone",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'America/Los_Angeles'"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "email"
+ ]
+ }
+ }
+ },
+ "public.verificationToken": {
+ "name": "verificationToken",
+ "schema": "",
+ "columns": {
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "verificationToken_identifier_token_pk": {
+ "name": "verificationToken_identifier_token_pk",
+ "columns": [
+ "identifier",
+ "token"
+ ]
+ }
+ },
+ "uniqueConstraints": {}
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "sequences": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json
index a772e87..cb03dca 100644
--- a/packages/db/migrations/meta/_journal.json
+++ b/packages/db/migrations/meta/_journal.json
@@ -1,12 +1,40 @@
{
"version": "7",
- "dialect": "sqlite",
+ "dialect": "postgresql",
"entries": [
{
"idx": 0,
- "version": "6",
- "when": 1733614471710,
- "tag": "0000_moaning_thor",
+ "version": "7",
+ "when": 1738348952600,
+ "tag": "0000_redundant_glorian",
+ "breakpoints": true
+ },
+ {
+ "idx": 1,
+ "version": "7",
+ "when": 1738348955500,
+ "tag": "0001_modify_hour_datetime",
+ "breakpoints": true
+ },
+ {
+ "idx": 2,
+ "version": "7",
+ "when": 1738368573808,
+ "tag": "0002_seed_ryan_user",
+ "breakpoints": true
+ },
+ {
+ "idx": 3,
+ "version": "7",
+ "when": 1738369747329,
+ "tag": "0003_silky_mongu",
+ "breakpoints": true
+ },
+ {
+ "idx": 4,
+ "version": "7",
+ "when": 1738371187519,
+ "tag": "0004_tan_justin_hammer",
"breakpoints": true
}
]
diff --git a/packages/db/package.json b/packages/db/package.json
index aa0d016..93820ea 100644
--- a/packages/db/package.json
+++ b/packages/db/package.json
@@ -9,24 +9,26 @@
"generate": "drizzle-kit generate",
"reset": "tsx reset.ts",
"typecheck": "tsc --noEmit",
- "migrate": "tsx migrate.ts",
- "studio": "drizzle-kit studio"
+ "migrate": "drizzle-kit migrate",
+ "studio": "drizzle-kit studio",
+ "drizzle-kit": "drizzle-kit"
},
"dependencies": {
"@auth/core": "^0.37.3",
"@paralleldrive/cuid2": "^2.2.2",
- "better-sqlite3": "^11.3.0",
"dotenv": "^16.4.1",
"drizzle-orm": "^0.33.0",
- "expo-sqlite": "^14.0.6",
+ "pg": "^8.11.3",
"tsx": "^4.7.1"
},
"devDependencies": {
+ "better-sqlite3": "^11.3.0",
"@lifetracker/eslint-config": "workspace:*",
"@lifetracker/typescript-config": "workspace:*",
"@tsconfig/node21": "^21.0.1",
- "@types/better-sqlite3": "^7.6.9",
+ "@types/pg": "^8.11.0",
"drizzle-kit": "^0.24.2",
+ "pg-dump-restore": "^1.0.12",
"sqlite3": "^5.1.7"
},
"eslintConfig": {
diff --git a/packages/db/schema.ts b/packages/db/schema.ts
index e1ad64c..b6a7f5b 100644
--- a/packages/db/schema.ts
+++ b/packages/db/schema.ts
@@ -1,23 +1,19 @@
import type { AdapterAccount } from "@auth/core/adapters";
import { createId } from "@paralleldrive/cuid2";
import { relations, SQL, sql } from "drizzle-orm";
-import { date } from "drizzle-orm/mysql-core";
+import { time, timestamp } from "drizzle-orm/pg-core";
import {
- AnySQLiteColumn,
- index,
+ pgTable,
integer,
real,
primaryKey,
- sqliteTable,
text,
unique,
-} from "drizzle-orm/sqlite-core";
+} from "drizzle-orm/pg-core";
function createdAtField() {
- return integer("createdAt", { mode: "timestamp" })
- .notNull()
- .$defaultFn(() => new Date());
+ return timestamp("createdAt", { withTimezone: true }).notNull().defaultNow();
}
export function calcInverseColor(hexcode: string): string {
@@ -35,12 +31,12 @@ export function calcInverseColor(hexcode: string): string {
-export const config = sqliteTable("config", {
+export const config = pgTable("config", {
key: text("key").notNull().primaryKey(),
value: text("value").notNull(),
});
-export const apiKeys = sqliteTable(
+export const apiKeys = pgTable(
"apiKey",
{
id: text("id")
@@ -61,21 +57,21 @@ export const apiKeys = sqliteTable(
);
-export const users = sqliteTable("user", {
+export const users = pgTable("user", {
id: text("id")
.notNull()
.primaryKey()
.$defaultFn(() => createId()),
name: text("name").notNull(),
email: text("email").notNull().unique(),
- emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
+ emailVerified: integer("emailVerified"),
image: text("image"),
password: text("password"),
role: text("role", { enum: ["admin", "user"] }).default("user"),
timezone: text("timezone").notNull().default("America/Los_Angeles"),
});
-export const accounts = sqliteTable(
+export const accounts = pgTable(
"account",
{
userId: text("userId")
@@ -99,7 +95,7 @@ export const accounts = sqliteTable(
}),
);
-export const sessions = sqliteTable("session", {
+export const sessions = pgTable("session", {
sessionToken: text("sessionToken")
.notNull()
.primaryKey()
@@ -107,22 +103,22 @@ export const sessions = sqliteTable("session", {
userId: text("userId")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
- expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
+ expires: timestamp("expires").notNull(),
});
-export const verificationTokens = sqliteTable(
+export const verificationTokens = pgTable(
"verificationToken",
{
identifier: text("identifier").notNull(),
token: text("token").notNull(),
- expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
+ expires: timestamp("expires").notNull(),
},
(vt) => ({
compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
}),
);
-export const metrics = sqliteTable("metric", {
+export const metrics = pgTable("metric", {
id: text("id")
.notNull()
.primaryKey()
@@ -143,7 +139,7 @@ export const metrics = sqliteTable("metric", {
}),
);
-export const measurements = sqliteTable("measurement", {
+export const measurements = pgTable("measurement", {
id: text("id")
.notNull()
.primaryKey()
@@ -162,7 +158,7 @@ export const measurements = sqliteTable("measurement", {
}),
);
-export const days = sqliteTable("day", {
+export const days = pgTable("day", {
id: text("id")
.notNull()
.primaryKey()
@@ -175,7 +171,7 @@ export const days = sqliteTable("day", {
.references(() => users.id, { onDelete: "cascade" }),
});
-export const hours = sqliteTable(
+export const hours = pgTable(
"hour",
{
id: text("id")
@@ -187,17 +183,17 @@ export const hours = sqliteTable(
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
comment: text("comment"),
- time: integer("time").notNull(),
+ datetime: timestamp("datetime").notNull(),
dayId: text("dayId").notNull().references(() => days.id, { onDelete: "cascade" }),
categoryId: text("categoryId").references(() => categories.id),
},
(e) => ({
- uniq: unique().on(e.dayId, e.time)
+ uniq: unique().on(e.dayId, e.datetime)
}),
)
-export const colors = sqliteTable(
+export const colors = pgTable(
"color",
{
id: text("id")
@@ -220,7 +216,7 @@ export const colors = sqliteTable(
// and fuck if the in built documentation makes any sense
}),
);
-export const categories = sqliteTable(
+export const categories = pgTable(
"category",
{
id: text("id")
@@ -254,7 +250,11 @@ export const apiKeyRelations = relations(apiKeys, ({ one }) => ({
references: [users.id],
}),
}));
-export const userRelations = relations(users, ({ many }) => ({
+export const userRelations = relations(users, ({ many, one }) => ({
+ apiKeys: one(apiKeys, {
+ fields: [users.id],
+ references: [apiKeys.userId],
+ }),
categories: many(categories),
colors: many(colors),
days: many(days),
@@ -348,9 +348,9 @@ export const measurementsRelations = relations(
fields: [measurements.dayId],
references: [days.id],
}),
- hour: measurements.hourId ? one(hours, {
+ hour: one(hours, {
fields: [measurements.hourId],
references: [hours.id],
- }) : undefined,
+ }),
}),
);
diff --git a/packages/shared/config.ts b/packages/shared/config.ts
index e3c8117..73f7cb0 100644
--- a/packages/shared/config.ts
+++ b/packages/shared/config.ts
@@ -1,7 +1,7 @@
import { z } from "zod";
import dotenv from "dotenv";
dotenv.config({
- path: ".env.local",
+ path: "../../.env.local",
});
const stringBool = (defaultValue: string) =>
z
@@ -55,6 +55,8 @@ const allEnv = z.object({
DEMO_MODE_EMAIL: z.string().optional(),
DEMO_MODE_PASSWORD: z.string().optional(),
DATA_DIR: z.string().default(""),
+ DATABASE_URL: z.string().default("postgres://lifetracker:pleasework@postgresql.home:5432/lifetracker"),
+ TEST_DATABASE_URL: z.string().default("postgres://lifetracker:pleasework@postgresql.home:5432/lifetracker_test"),
MAX_ASSET_SIZE_MB: z.coerce.number().default(4),
INFERENCE_LANG: z.string().default("english"),
// Build only flag
@@ -127,6 +129,8 @@ const serverConfigSchema = allEnv.transform((val) => {
}
: undefined,
dataDir: val.DATA_DIR,
+ databaseUrl: val.DATABASE_URL,
+ testDatabaseUrl: val.TEST_DATABASE_URL,
maxAssetSizeMb: val.MAX_ASSET_SIZE_MB,
serverVersion: val.SERVER_VERSION,
disableNewReleaseCheck: val.DISABLE_NEW_RELEASE_CHECK,
diff --git a/packages/shared/types/days.ts b/packages/shared/types/days.ts
index 4b41552..b29211a 100644
--- a/packages/shared/types/days.ts
+++ b/packages/shared/types/days.ts
@@ -6,8 +6,7 @@ export const zHourSchema = z.object({
id: z.string().optional(),
dayId: z.string(),
date: z.string().optional(),
- time: z.number(),
- datetime: z.string().optional(),
+ datetime: z.date(),
categoryCode: z.coerce.number().nullish(),
categoryId: z.string().nullish(),
categoryName: z.string().nullish(),
diff --git a/packages/trpc/routers/_app.ts b/packages/trpc/routers/_app.ts
index 3492fd0..e2b03e6 100644
--- a/packages/trpc/routers/_app.ts
+++ b/packages/trpc/routers/_app.ts
@@ -1,4 +1,3 @@
-import { apiKeys } from "@lifetracker/db/schema";
import { router } from "../index";
import { usersAppRouter } from "./users";
import { apiKeysAppRouter } from "./apiKeys";
diff --git a/packages/trpc/routers/categories.ts b/packages/trpc/routers/categories.ts
index 4f276cc..8f68ee6 100644
--- a/packages/trpc/routers/categories.ts
+++ b/packages/trpc/routers/categories.ts
@@ -2,7 +2,7 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
import { z } from "zod";
-import { SqliteError } from "@lifetracker/db";
+import { DatabaseError } from "@lifetracker/db";
import { categories, colors } from "@lifetracker/db/schema";
import {
ZCategories,
@@ -54,8 +54,8 @@ async function createCategory(
};
} catch (e) {
- if (e instanceof SqliteError) {
- if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
+ if (e instanceof DatabaseError) {
+ if (e.code == "23505") {
throw new TRPCError({
code: "BAD_REQUEST",
message: "There's already a category with this code",
diff --git a/packages/trpc/routers/colors.ts b/packages/trpc/routers/colors.ts
index ac6f5d7..11b1359 100644
--- a/packages/trpc/routers/colors.ts
+++ b/packages/trpc/routers/colors.ts
@@ -2,7 +2,7 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
import { z } from "zod";
-import { SqliteError } from "@lifetracker/db";
+import { DatabaseError, ErrorCodes } from "@lifetracker/db";
import { colors, calcInverseColor } from "@lifetracker/db/schema";
import {
zColorSchema, ZColor
@@ -37,8 +37,8 @@ async function createColor(
});
return result[0];
} catch (e) {
- if (e instanceof SqliteError) {
- if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
+ if (e instanceof DatabaseError) {
+ if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "This color already exists",
diff --git a/packages/trpc/routers/days.ts b/packages/trpc/routers/days.ts
index 103be92..5bfbee6 100644
--- a/packages/trpc/routers/days.ts
+++ b/packages/trpc/routers/days.ts
@@ -2,7 +2,7 @@ import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
import { z } from "zod";
-import { db, SqliteError } from "@lifetracker/db";
+import { db, DatabaseError, ErrorCodes } from "@lifetracker/db";
import { categories, days, hours, users } from "@lifetracker/db/schema";
import {
zDaySchema, ZDay,
@@ -11,7 +11,7 @@ import {
import type { Context } from "../index";
import { authedProcedure, router } from "../index";
import { dateFromInput, hoursListInUTC } from "@lifetracker/shared/utils/days";
-import { closestIndexTo, format } from "date-fns";
+import { addDays, closestIndexTo, format, parseISO } from "date-fns";
import { TZDate } from "@date-fns/tz";
import { hoursAppRouter, hourColors, hourJoinsQuery, getHours, createHour } from "./hours";
import spacetime from "spacetime";
@@ -36,8 +36,8 @@ export async function createDay(date: string, ctx: Context) {
return dayRes[0];
} catch (e) {
- if (e instanceof SqliteError) {
- if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
+ if (e instanceof DatabaseError) {
+ if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "This day already exists",
@@ -75,6 +75,27 @@ export async function getDay(ctx: Context, input: { dateQuery: string, timezone:
}
}
+export function listOfDates(dateRange: [Date, Date]) {
+ const [start, end] = dateRange.map((date) => dateFromInput({
+ dateQuery: spacetime(date, "UTC").goto("UTC").format("iso-short"),
+ timezone: "Etc/UTC"
+ }));
+ const dates = [];
+ let currentDate = parseISO(start);
+ while (currentDate <= parseISO(end)) {
+ dates.push(format(currentDate, "yyyy-MM-dd"));
+ currentDate = addDays(currentDate, 1);
+ }
+ return dates.length === 0 ? [format(parseISO(start), "yyyy-MM-dd")] : dates;
+}
+export function listOfDayIds(dateRange: [Date, Date]) {
+ return listOfDates(dateRange).map((date) =>
+ db.select({ id: days.id })
+ .from(days)
+ .where(eq(days.date, date))
+ );
+}
+
export const daysAppRouter = router({
get: authedProcedure
.input(z.object({
diff --git a/packages/trpc/routers/hours.ts b/packages/trpc/routers/hours.ts
index fe07f6d..992a9d2 100644
--- a/packages/trpc/routers/hours.ts
+++ b/packages/trpc/routers/hours.ts
@@ -1,27 +1,23 @@
-import { experimental_trpcMiddleware, TRPCError } from "@trpc/server";
+import { TRPCError } from "@trpc/server";
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
-import { date, z } from "zod";
+import { z } from "zod";
-import { SqliteError } from "@lifetracker/db";
+import { DatabaseError } from "@lifetracker/db";
import { categories, days, hours, colors, measurements, metrics } from "@lifetracker/db/schema";
import {
- zDaySchema, ZDay, ZHour, zHourSchema
+ ZDay, ZHour, zHourSchema
} from "@lifetracker/shared/types/days";
import type { Context } from "../index";
import { authedProcedure, router } from "../index";
-import { addDays, format, parseISO } from "date-fns";
-import { TZDate } from "@date-fns/tz";
-import { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
-import { zCategorySchema } from "@lifetracker/shared/types/categories";
import spacetime from "spacetime";
-import { dateFromInput, hoursListInUTC } from "@lifetracker/shared/utils/days";
-import { createDay, getDay } from "./days";
+import { hoursListInUTC } from "@lifetracker/shared/utils/days";
+import { createDay, listOfDates } from "./days";
-export async function createHour(day: ZDay | { id: string }, time: number, ctx: Context,) {
+export async function createHour(day: { id: string }, datetime: Date, ctx: Context,) {
const newHour = (await ctx.db.insert(hours).values({
- dayId: day.id!,
- time: time,
+ dayId: day.id,
+ datetime: datetime,
userId: ctx.user!.id,
}).returning());
return newHour[0];
@@ -52,7 +48,7 @@ export async function hourColors(hour: ZHour, ctx: Context) {
export async function hourJoinsQuery(
ctx: Context,
- time: number,
+ datetime: Date,
dayId?: string,
day?: ZDay,
) {
@@ -67,7 +63,7 @@ export async function hourJoinsQuery(
const res = await ctx.db.select({
id: hours.id,
dayId: hours.dayId,
- time: hours.time,
+ datetime: hours.datetime,
categoryId: hours.categoryId,
categoryCode: categories.code,
categoryName: categories.name,
@@ -78,11 +74,11 @@ export async function hourJoinsQuery(
.leftJoin(categories, eq(categories.id, hours.categoryId))
.leftJoin(days, eq(days.id, hours.dayId))
.where(and(
- eq(hours.time, time),
+ eq(hours.datetime, datetime),
eq(hours.dayId, id)
));
- const hourMatch = res[0] ?? createHour({ id: id }, time, ctx);
+ const hourMatch = res[0] ?? createHour({ id }, datetime, ctx);
const hourMeasurements = await ctx.db.select({
@@ -131,33 +127,16 @@ export async function getHours(ctx: Context, input: { dateQuery: string | [Date,
// Finally, use the two unique day IDs and the 24 hours to get the actual Hour objects for each day
const dayHours = await Promise.all(uniqueHours.map(async function (map: { date: string, time: number }, i) {
const dayId = uniqueDayIds.find((dayIds: { id: string, date: string }) => map.date == dayIds.date)!.id;
-
- return hourJoinsQuery(ctx, map.time, dayId);
+ const datetime = spacetime(map.date, "Etc/UTC").hour(map.time).toNativeDate();
+ return hourJoinsQuery(ctx, datetime, dayId);
}));
return dayHours;
}
-
-function listOfDates(dateRange: [Date, Date]) {
- const [start, end] = dateRange.map((date) => dateFromInput({
- dateQuery: spacetime(date, "UTC").goto("UTC").format("iso-short"),
- timezone: "Etc/UTC"
- }));
- const dates = [];
- let currentDate = parseISO(start);
- while (currentDate <= parseISO(end)) {
- dates.push(format(currentDate, "yyyy-MM-dd"));
- currentDate = addDays(currentDate, 1);
- }
- return dates.length === 0 ? [format(parseISO(start), "yyyy-MM-dd")] : dates;
-}
-
-
export const hoursAppRouter = router({
get: authedProcedure
.input(z.object({
dateQuery: z.string(),
- time: z.number()
}))
.output(zHourSchema)
.query(async ({ input, ctx }) => {
@@ -165,8 +144,7 @@ export const hoursAppRouter = router({
.leftJoin(days, eq(days.id, hours.dayId))
.where(
and(
- eq(hours.time, input.time),
- eq(days.date, input.dateQuery),
+ eq(hours.datetime, spacetime(input.dateQuery, "Etc/UTC").toNativeDate()),
eq(hours.userId, ctx.user!.id)
)
);
@@ -255,10 +233,20 @@ export const hoursAppRouter = router({
}
)))
.query(async ({ input, ctx }) => {
+
+ // console.log(input.dateRange, input.timezone);
const hoursList = await getHours(ctx, {
dateQuery: input.dateRange,
timezone: input.timezone
});
+ // console.log(hoursList.map(h => {
+ // return {
+ // datetime: spacetime(h.datetime).goto("America/Los_Angeles").format("{iso-short} {hour-24}:{minute}"),
+ // id: h.id,
+ // date: h.date,
+ // };
+ // }));
+
// Count total hours in the filtered range
const totalHours = hoursList.length;
diff --git a/packages/trpc/routers/measurements.ts b/packages/trpc/routers/measurements.ts
index fd2f531..42a025e 100644
--- a/packages/trpc/routers/measurements.ts
+++ b/packages/trpc/routers/measurements.ts
@@ -1,14 +1,17 @@
import { TRPCError } from "@trpc/server";
-import { and, desc, eq, inArray, notExists } from "drizzle-orm";
+import { and, desc, eq, inArray, notExists, sql } from "drizzle-orm";
import { z, ZodNull } from "zod";
-import { SqliteError } from "@lifetracker/db";
-import { colors, metrics, measurements, hours } from "@lifetracker/db/schema";
+import { DatabaseError } from "@lifetracker/db";
+import { colors, metrics, measurements, hours, days } from "@lifetracker/db/schema";
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
import type { Context } from "../index";
import { authedProcedure, router } from "../index";
import { zColorSchema } from "@lifetracker/shared/types/colors";
import { titleCase } from "title-case";
+import { listOfDates, listOfDayIds } from "./days";
+import { getHours } from "./hours";
+import { datetime } from "drizzle-orm/mysql-core";
const getMetricFromInput = async (ctx: Context, input:
{ metricId?: string | null | undefined; metricName?: string | null | undefined; }) => {
@@ -181,4 +184,44 @@ export const measurementsAppRouter = router({
return 0;
}
}),
+ getTimeseries: authedProcedure
+ .input(z.object({
+ dateRange: z.tuple([z.date(), z.date()]),
+ timezone: z.string(),
+ metricName: z.string()
+ }))
+ .output(z.array(z.object({
+ id: z.string(),
+ value: z.string(),
+ unit: z.string(),
+ datetime: z.date(),
+ })
+ ))
+ .query(async ({ input, ctx }) => {
+ const hoursList = await getHours(ctx, {
+ dateQuery: input.dateRange,
+ timezone: input.timezone,
+ });
+ const hourIds = hoursList.map((hour) => hour.id);
+ const metric = await ctx.db.select().from(metrics).where(eq(metrics.name, titleCase(input.metricName)));
+ if (!metric[0]) {
+ throw new TRPCError({
+ code: "NOT_FOUND",
+ message: "Metric not found",
+ });
+ }
+ const measurementsList = await ctx.db.select({
+ id: measurements.id,
+ value: measurements.value,
+ unit: metrics.unit,
+ datetime: hours.datetime,
+ }).from(measurements)
+ .leftJoin(metrics, eq(measurements.metricId, metrics.id))
+ .leftJoin(hours, eq(measurements.hourId, hours.id))
+ .where(and(
+ eq(measurements.metricId, metric[0].id),
+ inArray(measurements.hourId, hourIds),
+ ));
+ return measurementsList;
+ }),
});
\ No newline at end of file
diff --git a/packages/trpc/routers/metrics.ts b/packages/trpc/routers/metrics.ts
index 7fa7894..0e9162d 100644
--- a/packages/trpc/routers/metrics.ts
+++ b/packages/trpc/routers/metrics.ts
@@ -2,7 +2,7 @@ import { TRPCError } from "@trpc/server";
import { and, desc, eq, inArray, notExists } from "drizzle-orm";
import { z } from "zod";
-import { SqliteError } from "@lifetracker/db";
+import { DatabaseError, ErrorCodes } from "@lifetracker/db";
import { colors, metrics } from "@lifetracker/db/schema";
import { zMetricSchema, zMeasurementSchema } from "@lifetracker/shared/types/metrics";
import type { Context } from "../index";
@@ -40,8 +40,8 @@ export const metricsAppRouter = router({
.returning();
return result[0];
} catch (e) {
- if (e instanceof SqliteError) {
- if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
+ if (e instanceof DatabaseError) {
+ if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "This metric already exists",
diff --git a/packages/trpc/routers/users.ts b/packages/trpc/routers/users.ts
index 1a963cd..27222d9 100644
--- a/packages/trpc/routers/users.ts
+++ b/packages/trpc/routers/users.ts
@@ -3,7 +3,7 @@ import { and, count, eq } from "drizzle-orm";
import invariant from "tiny-invariant";
import { z } from "zod";
-import { SqliteError } from "@lifetracker/db";
+import { DatabaseError, ErrorCodes } from "@lifetracker/db";
import { users } from "@lifetracker/db/schema";
import serverConfig from "@lifetracker/shared/config";
import { zSignUpSchema } from "@lifetracker/shared/types/users";
@@ -49,8 +49,8 @@ export async function createUser(
});
return result[0];
} catch (e) {
- if (e instanceof SqliteError) {
- if (e.code == "SQLITE_CONSTRAINT_UNIQUE") {
+ if (e instanceof DatabaseError) {
+ if (e.code == ErrorCodes.UNIQUE_VIOLATION) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Email is already taken",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b7601b9..26ae817 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
prettier:
specifier: ^3.3.3
version: 3.3.3
+ tsx:
+ specifier: ^4.19.2
+ version: 4.19.2
turbo:
specifier: ^2.2.3
version: 2.2.3
@@ -318,7 +321,7 @@ importers:
version: 1.11.13
drizzle-orm:
specifier: ^0.33.0
- version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(react@18.3.1)(sqlite3@5.1.7)
+ version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/pg@8.11.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(pg@8.13.1)(react@18.3.1)(sqlite3@5.1.7)
fastest-levenshtein:
specifier: ^1.0.16
version: 1.0.16
@@ -327,19 +330,22 @@ importers:
version: 3.5.2
lucide-react:
specifier: latest
- version: 0.473.0(react@18.3.1)
+ version: 0.474.0(react@18.3.1)
next:
specifier: latest
- version: 15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ version: 15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-auth:
specifier: ^4.24.5
- version: 4.24.10(next@15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ version: 4.24.10(next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-pwa:
specifier: ^5.6.0
- version: 5.6.0(@babel/core@7.26.0)(@types/babel__core@7.20.5)(next@15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(webpack@5.95.0)
+ version: 5.6.0(@babel/core@7.26.0)(@types/babel__core@7.20.5)(next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(webpack@5.95.0)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ pg-dump-restore:
+ specifier: ^1.0.12
+ version: 1.0.12
prettier:
specifier: ^3.2.5
version: 3.3.3
@@ -467,18 +473,15 @@ importers:
'@paralleldrive/cuid2':
specifier: ^2.2.2
version: 2.2.2
- better-sqlite3:
- specifier: ^11.3.0
- version: 11.5.0
dotenv:
specifier: ^16.4.1
version: 16.4.5
drizzle-orm:
specifier: ^0.33.0
- version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(react@18.3.1)(sqlite3@5.1.7)
- expo-sqlite:
- specifier: ^14.0.6
- version: 14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13))
+ version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/pg@8.11.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(pg@8.13.1)(react@18.3.1)(sqlite3@5.1.7)
+ pg:
+ specifier: ^8.11.3
+ version: 8.13.1
tsx:
specifier: ^4.7.1
version: 4.19.1
@@ -492,12 +495,18 @@ importers:
'@tsconfig/node21':
specifier: ^21.0.1
version: 21.0.3
- '@types/better-sqlite3':
- specifier: ^7.6.9
- version: 7.6.11
+ '@types/pg':
+ specifier: ^8.11.0
+ version: 8.11.11
+ better-sqlite3:
+ specifier: ^11.3.0
+ version: 11.5.0
drizzle-kit:
specifier: ^0.24.2
version: 0.24.2
+ pg-dump-restore:
+ specifier: ^1.0.12
+ version: 1.0.12
sqlite3:
specifier: ^5.1.7
version: 5.1.7
@@ -675,7 +684,7 @@ importers:
version: 4.1.0
drizzle-orm:
specifier: ^0.33.0
- version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(react@18.3.1)(sqlite3@5.1.7)
+ version: 0.33.0(@types/better-sqlite3@7.6.11)(@types/pg@8.11.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(pg@8.13.1)(react@18.3.1)(sqlite3@5.1.7)
spacetime:
specifier: ^7.6.2
version: 7.6.2
@@ -3195,56 +3204,56 @@ packages:
'@microsoft/tsdoc@0.14.2':
resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==}
- '@next/env@15.1.5':
- resolution: {integrity: sha512-jg8ygVq99W3/XXb9Y6UQsritwhjc+qeiO7QrGZRYOfviyr/HcdnhdBQu4gbp2rBIh2ZyBYTBMWbPw3JSCb0GHw==}
+ '@next/env@15.1.6':
+ resolution: {integrity: sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==}
'@next/eslint-plugin-next@14.2.6':
resolution: {integrity: sha512-d3+p4AjIYmhqzYHhhmkRYYN6ZU35TwZAKX08xKRfnHkz72KhWL2kxMFsDptpZs5e8bBGdepn7vn1+9DaF8iX+A==}
- '@next/swc-darwin-arm64@15.1.5':
- resolution: {integrity: sha512-5ttHGE75Nw9/l5S8zR2xEwR8OHEqcpPym3idIMAZ2yo+Edk0W/Vf46jGqPOZDk+m/SJ+vYZDSuztzhVha8rcdA==}
+ '@next/swc-darwin-arm64@15.1.6':
+ resolution: {integrity: sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
- '@next/swc-darwin-x64@15.1.5':
- resolution: {integrity: sha512-8YnZn7vDURUUTInfOcU5l0UWplZGBqUlzvqKKUFceM11SzfNEz7E28E1Arn4/FsOf90b1Nopboy7i7ufc4jXag==}
+ '@next/swc-darwin-x64@15.1.6':
+ resolution: {integrity: sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
- '@next/swc-linux-arm64-gnu@15.1.5':
- resolution: {integrity: sha512-rDJC4ctlYbK27tCyFUhgIv8o7miHNlpCjb2XXfTLQszwAUOSbcMN9q2y3urSrrRCyGVOd9ZR9a4S45dRh6JF3A==}
+ '@next/swc-linux-arm64-gnu@15.1.6':
+ resolution: {integrity: sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-arm64-musl@15.1.5':
- resolution: {integrity: sha512-FG5RApf4Gu+J+pHUQxXPM81oORZrKBYKUaBTylEIQ6Lz17hKVDsLbSXInfXM0giclvXbyiLXjTv42sQMATmZ0A==}
+ '@next/swc-linux-arm64-musl@15.1.6':
+ resolution: {integrity: sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-x64-gnu@15.1.5':
- resolution: {integrity: sha512-NX2Ar3BCquAOYpnoYNcKz14eH03XuF7SmSlPzTSSU4PJe7+gelAjxo3Y7F2m8+hLT8ZkkqElawBp7SWBdzwqQw==}
+ '@next/swc-linux-x64-gnu@15.1.6':
+ resolution: {integrity: sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-linux-x64-musl@15.1.5':
- resolution: {integrity: sha512-EQgqMiNu3mrV5eQHOIgeuh6GB5UU57tu17iFnLfBEhYfiOfyK+vleYKh2dkRVkV6ayx3eSqbIYgE7J7na4hhcA==}
+ '@next/swc-linux-x64-musl@15.1.6':
+ resolution: {integrity: sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-win32-arm64-msvc@15.1.5':
- resolution: {integrity: sha512-HPULzqR/VqryQZbZME8HJE3jNFmTGcp+uRMHabFbQl63TtDPm+oCXAz3q8XyGv2AoihwNApVlur9Up7rXWRcjg==}
+ '@next/swc-win32-arm64-msvc@15.1.6':
+ resolution: {integrity: sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
- '@next/swc-win32-x64-msvc@15.1.5':
- resolution: {integrity: sha512-n74fUb/Ka1dZSVYfjwQ+nSJ+ifUff7jGurFcTuJNKZmI62FFOxQXUYit/uZXPTj2cirm1rvGWHG2GhbSol5Ikw==}
+ '@next/swc-win32-x64-msvc@15.1.6':
+ resolution: {integrity: sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -4401,6 +4410,9 @@ packages:
'@types/parse-json@4.0.2':
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
+ '@types/pg@8.11.11':
+ resolution: {integrity: sha512-kGT1qKM8wJQ5qlawUrEkXgvMSXoV213KfMGXcwfDwUIfUHXqXYXOfS1nE1LINRJVVVx5wCm70XnFlMHaIcQAfw==}
+
'@types/prismjs@1.26.4':
resolution: {integrity: sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==}
@@ -7324,9 +7336,6 @@ packages:
resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
engines: {node: '>= 0.4'}
- get-tsconfig@4.7.2:
- resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==}
-
get-tsconfig@4.8.1:
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
@@ -8570,6 +8579,7 @@ packages:
lodash.get@4.4.2:
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
+ deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
@@ -8654,8 +8664,8 @@ packages:
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
engines: {node: '>=12'}
- lucide-react@0.473.0:
- resolution: {integrity: sha512-KW6u5AKeIjkvrxXZ6WuCu9zHE/gEYSXCay+Gre2ZoInD0Je/e3RBtP4OHpJVJ40nDklSvjVKjgH7VU8/e2dzRw==}
+ lucide-react@0.474.0:
+ resolution: {integrity: sha512-CmghgHkh0OJNmxGKWc0qfPJCYHASPMVSyGY8fj3xgk4v84ItqDg64JNKFZn5hC6E0vHi6gxnbCgwhyVB09wQtA==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -9207,8 +9217,8 @@ packages:
react: ^16.8 || ^17 || ^18
react-dom: ^16.8 || ^17 || ^18
- next@15.1.5:
- resolution: {integrity: sha512-Cf/TEegnt01hn3Hoywh6N8fvkhbOuChO4wFje24+a86wKOubgVaWkDqxGVgoWlz2Hp9luMJ9zw3epftujdnUOg==}
+ next@15.1.6:
+ resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
@@ -9680,6 +9690,51 @@ packages:
periscopic@3.1.0:
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
+ pg-cloudflare@1.1.1:
+ resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
+
+ pg-connection-string@2.7.0:
+ resolution: {integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==}
+
+ pg-dump-restore@1.0.12:
+ resolution: {integrity: sha512-4ubF4amu0B/LjdVvq7M32PFb8labXZ61PnG1PMZaZuwGXGHl1CRoVWSNIjpA1UF2FwBovUJvJElwMIV9bxgk3Q==}
+
+ pg-int8@1.0.1:
+ resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
+ engines: {node: '>=4.0.0'}
+
+ pg-numeric@1.0.2:
+ resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==}
+ engines: {node: '>=4'}
+
+ pg-pool@3.7.0:
+ resolution: {integrity: sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==}
+ peerDependencies:
+ pg: '>=8.0'
+
+ pg-protocol@1.7.0:
+ resolution: {integrity: sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==}
+
+ pg-types@2.2.0:
+ resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
+ engines: {node: '>=4'}
+
+ pg-types@4.0.2:
+ resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==}
+ engines: {node: '>=10'}
+
+ pg@8.13.1:
+ resolution: {integrity: sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==}
+ engines: {node: '>= 8.0.0'}
+ peerDependencies:
+ pg-native: '>=3.0.1'
+ peerDependenciesMeta:
+ pg-native:
+ optional: true
+
+ pgpass@1.0.5:
+ resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
+
picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
@@ -10021,6 +10076,41 @@ packages:
resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
engines: {node: ^10 || ^12 || >=14}
+ postgres-array@2.0.0:
+ resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
+ engines: {node: '>=4'}
+
+ postgres-array@3.0.2:
+ resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==}
+ engines: {node: '>=12'}
+
+ postgres-bytea@1.0.0:
+ resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-bytea@3.0.0:
+ resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==}
+ engines: {node: '>= 6'}
+
+ postgres-date@1.0.7:
+ resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-date@2.1.0:
+ resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
+ engines: {node: '>=12'}
+
+ postgres-interval@1.2.0:
+ resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
+ engines: {node: '>=0.10.0'}
+
+ postgres-interval@3.0.0:
+ resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==}
+ engines: {node: '>=12'}
+
+ postgres-range@1.1.4:
+ resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
+
pouchdb-collections@1.0.1:
resolution: {integrity: sha512-31db6JRg4+4D5Yzc2nqsRqsA2oOkZS8DpFav3jf/qVNBxusKa2ClkEIZ2bJNpaDbMfWtnuSq59p6Bn+CipPMdg==}
@@ -11189,6 +11279,10 @@ packages:
resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==}
engines: {node: '>=6.0.0'}
+ split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+
split@1.0.1:
resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==}
@@ -11707,6 +11801,11 @@ packages:
engines: {node: '>=18.0.0'}
hasBin: true
+ tsx@4.19.2:
+ resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
@@ -12754,6 +12853,7 @@ snapshots:
'@babel/code-frame@7.10.4':
dependencies:
'@babel/highlight': 7.25.9
+ optional: true
'@babel/code-frame@7.22.13':
dependencies:
@@ -12827,6 +12927,7 @@ snapshots:
lodash: 4.17.21
source-map: 0.5.7
trim-right: 1.0.1
+ optional: true
'@babel/generator@7.23.3':
dependencies:
@@ -12969,6 +13070,7 @@ snapshots:
'@babel/helper-environment-visitor@7.24.7':
dependencies:
'@babel/types': 7.26.0
+ optional: true
'@babel/helper-function-name@7.23.0':
dependencies:
@@ -13210,6 +13312,7 @@ snapshots:
chalk: 2.4.2
js-tokens: 4.0.0
picocolors: 1.1.1
+ optional: true
'@babel/parser@7.23.3':
dependencies:
@@ -13298,6 +13401,7 @@ snapshots:
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.0)
transitivePeerDependencies:
- supports-color
+ optional: true
'@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.26.0)':
dependencies:
@@ -13315,6 +13419,7 @@ snapshots:
'@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.0)
transitivePeerDependencies:
- supports-color
+ optional: true
'@babel/plugin-proposal-export-default-from@7.25.9(@babel/core@7.26.0)':
dependencies:
@@ -13326,6 +13431,7 @@ snapshots:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.0)
+ optional: true
'@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.26.0)':
dependencies:
@@ -13338,6 +13444,7 @@ snapshots:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.0)
+ optional: true
'@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.26.0)':
dependencies:
@@ -13347,12 +13454,14 @@ snapshots:
'@babel/helper-plugin-utils': 7.25.9
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.0)
'@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0)
+ optional: true
'@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.26.0)':
dependencies:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.0)
+ optional: true
'@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.26.0)':
dependencies:
@@ -13410,6 +13519,7 @@ snapshots:
dependencies:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
+ optional: true
'@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.3)':
dependencies:
@@ -13861,6 +13971,7 @@ snapshots:
dependencies:
'@babel/core': 7.26.0
'@babel/helper-plugin-utils': 7.25.9
+ optional: true
'@babel/plugin-transform-flow-strip-types@7.25.9(@babel/core@7.26.0)':
dependencies:
@@ -15633,7 +15744,7 @@ snapshots:
'@esbuild-kit/esm-loader@2.6.5':
dependencies:
'@esbuild-kit/core-utils': 3.3.2
- get-tsconfig: 4.7.2
+ get-tsconfig: 4.8.1
'@esbuild/aix-ppc64@0.19.12':
optional: true
@@ -15937,6 +16048,7 @@ snapshots:
'@expo/bunyan@4.0.1':
dependencies:
uuid: 8.3.2
+ optional: true
'@expo/cli@0.18.30(encoding@0.1.13)(expo-modules-autolinking@1.11.3)':
dependencies:
@@ -16023,11 +16135,13 @@ snapshots:
- expo-modules-autolinking
- supports-color
- utf-8-validate
+ optional: true
'@expo/code-signing-certificates@0.0.5':
dependencies:
node-forge: 1.3.1
nullthrows: 1.1.1
+ optional: true
'@expo/config-plugins@8.0.10':
dependencies:
@@ -16048,8 +16162,10 @@ snapshots:
xml2js: 0.6.0
transitivePeerDependencies:
- supports-color
+ optional: true
- '@expo/config-types@51.0.3': {}
+ '@expo/config-types@51.0.3':
+ optional: true
'@expo/config@9.0.4':
dependencies:
@@ -16066,6 +16182,7 @@ snapshots:
sucrase: 3.34.0
transitivePeerDependencies:
- supports-color
+ optional: true
'@expo/devcert@1.1.4':
dependencies:
@@ -16083,6 +16200,7 @@ snapshots:
tslib: 2.8.1
transitivePeerDependencies:
- supports-color
+ optional: true
'@expo/env@0.3.0':
dependencies:
@@ -16093,6 +16211,7 @@ snapshots:
getenv: 1.0.0
transitivePeerDependencies:
- supports-color
+ optional: true
'@expo/image-utils@0.5.1(encoding@0.1.13)':
dependencies:
@@ -16108,12 +16227,14 @@ snapshots:
tempy: 0.3.0
transitivePeerDependencies:
- encoding
+ optional: true
'@expo/json-file@8.3.3':
dependencies:
'@babel/code-frame': 7.10.4
json5: 2.2.3
write-file-atomic: 2.4.3
+ optional: true
'@expo/metro-config@0.18.11':
dependencies:
@@ -16137,11 +16258,13 @@ snapshots:
resolve-from: 5.0.0
transitivePeerDependencies:
- supports-color
+ optional: true
'@expo/osascript@2.1.3':
dependencies:
'@expo/spawn-async': 1.7.2
exec-async: 2.2.0
+ optional: true
'@expo/package-manager@1.5.2':
dependencies:
@@ -16157,12 +16280,14 @@ snapshots:
ora: 3.4.0
split: 1.0.1
sudo-prompt: 9.1.1
+ optional: true
'@expo/plist@0.1.3':
dependencies:
'@xmldom/xmldom': 0.7.13
base64-js: 1.5.1
xmlbuilder: 14.0.0
+ optional: true
'@expo/prebuild-config@7.0.9(encoding@0.1.13)(expo-modules-autolinking@1.11.3)':
dependencies:
@@ -16181,6 +16306,7 @@ snapshots:
transitivePeerDependencies:
- encoding
- supports-color
+ optional: true
'@expo/rudder-sdk-node@1.1.1(encoding@0.1.13)':
dependencies:
@@ -16193,16 +16319,20 @@ snapshots:
uuid: 8.3.2
transitivePeerDependencies:
- encoding
+ optional: true
- '@expo/sdk-runtime-versions@1.0.0': {}
+ '@expo/sdk-runtime-versions@1.0.0':
+ optional: true
'@expo/spawn-async@1.7.2':
dependencies:
cross-spawn: 7.0.5
+ optional: true
'@expo/vector-icons@14.0.4':
dependencies:
prop-types: 15.8.1
+ optional: true
'@expo/websql@1.0.1':
dependencies:
@@ -16211,6 +16341,7 @@ snapshots:
noop-fn: 1.0.0
pouchdb-collections: 1.0.1
tiny-queue: 0.2.1
+ optional: true
'@expo/xcpretty@4.3.1':
dependencies:
@@ -16218,6 +16349,7 @@ snapshots:
chalk: 4.1.2
find-up: 5.0.0
js-yaml: 4.1.0
+ optional: true
'@floating-ui/core@1.6.8':
dependencies:
@@ -16250,6 +16382,7 @@ snapshots:
'@graphql-typed-document-node/core@3.2.0(graphql@15.8.0)':
dependencies:
graphql: 15.8.0
+ optional: true
'@hapi/hoek@9.3.0': {}
@@ -16429,6 +16562,7 @@ snapshots:
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 1.1.2
'@types/yargs': 13.0.12
+ optional: true
'@jest/types@29.6.3':
dependencies:
@@ -16555,34 +16689,34 @@ snapshots:
'@microsoft/tsdoc@0.14.2': {}
- '@next/env@15.1.5': {}
+ '@next/env@15.1.6': {}
'@next/eslint-plugin-next@14.2.6':
dependencies:
glob: 10.3.10
- '@next/swc-darwin-arm64@15.1.5':
+ '@next/swc-darwin-arm64@15.1.6':
optional: true
- '@next/swc-darwin-x64@15.1.5':
+ '@next/swc-darwin-x64@15.1.6':
optional: true
- '@next/swc-linux-arm64-gnu@15.1.5':
+ '@next/swc-linux-arm64-gnu@15.1.6':
optional: true
- '@next/swc-linux-arm64-musl@15.1.5':
+ '@next/swc-linux-arm64-musl@15.1.6':
optional: true
- '@next/swc-linux-x64-gnu@15.1.5':
+ '@next/swc-linux-x64-gnu@15.1.6':
optional: true
- '@next/swc-linux-x64-musl@15.1.5':
+ '@next/swc-linux-x64-musl@15.1.6':
optional: true
- '@next/swc-win32-arm64-msvc@15.1.5':
+ '@next/swc-win32-arm64-msvc@15.1.6':
optional: true
- '@next/swc-win32-x64-msvc@15.1.5':
+ '@next/swc-win32-x64-msvc@15.1.6':
optional: true
'@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1':
@@ -16612,6 +16746,7 @@ snapshots:
'@npmcli/fs@3.1.1':
dependencies:
semver: 7.6.3
+ optional: true
'@npmcli/move-file@1.1.2':
dependencies:
@@ -16630,7 +16765,7 @@ snapshots:
'@pkgr/utils@2.4.2':
dependencies:
- cross-spawn: 7.0.3
+ cross-spawn: 7.0.5
fast-glob: 3.3.2
is-glob: 4.0.3
open: 9.1.0
@@ -17116,6 +17251,7 @@ snapshots:
transitivePeerDependencies:
- '@babel/preset-env'
- supports-color
+ optional: true
'@react-native/babel-plugin-codegen@0.76.2(@babel/preset-env@7.25.7(@babel/core@7.26.0))':
dependencies:
@@ -17172,6 +17308,7 @@ snapshots:
transitivePeerDependencies:
- '@babel/preset-env'
- supports-color
+ optional: true
'@react-native/babel-preset@0.76.2(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))':
dependencies:
@@ -17236,6 +17373,7 @@ snapshots:
nullthrows: 1.1.1
transitivePeerDependencies:
- supports-color
+ optional: true
'@react-native/codegen@0.76.2(@babel/preset-env@7.25.7(@babel/core@7.26.0))':
dependencies:
@@ -17272,7 +17410,8 @@ snapshots:
- supports-color
- utf-8-validate
- '@react-native/debugger-frontend@0.74.85': {}
+ '@react-native/debugger-frontend@0.74.85':
+ optional: true
'@react-native/debugger-frontend@0.76.2': {}
@@ -17296,6 +17435,7 @@ snapshots:
- encoding
- supports-color
- utf-8-validate
+ optional: true
'@react-native/dev-middleware@0.76.2':
dependencies:
@@ -17384,6 +17524,7 @@ snapshots:
rimraf: 3.0.2
transitivePeerDependencies:
- supports-color
+ optional: true
'@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@types/babel__core@7.20.5)(rollup@2.79.2)':
dependencies:
@@ -17488,6 +17629,7 @@ snapshots:
dependencies:
component-type: 1.2.2
join-component: 1.1.0
+ optional: true
'@sideway/address@4.1.5':
dependencies:
@@ -17790,6 +17932,7 @@ snapshots:
'@types/better-sqlite3@7.6.11':
dependencies:
'@types/node': 20.11.24
+ optional: true
'@types/body-parser@1.19.5':
dependencies:
@@ -17941,6 +18084,7 @@ snapshots:
dependencies:
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-lib-report': 3.0.3
+ optional: true
'@types/istanbul-reports@3.0.4':
dependencies:
@@ -17973,6 +18117,7 @@ snapshots:
'@types/node@18.19.64':
dependencies:
undici-types: 5.26.5
+ optional: true
'@types/node@20.11.24':
dependencies:
@@ -17982,6 +18127,12 @@ snapshots:
'@types/parse-json@4.0.2': {}
+ '@types/pg@8.11.11':
+ dependencies:
+ '@types/node': 20.11.24
+ pg-protocol: 1.7.0
+ pg-types: 4.0.2
+
'@types/prismjs@1.26.4': {}
'@types/prop-types@15.7.5': {}
@@ -18091,6 +18242,7 @@ snapshots:
'@types/yargs@13.0.12':
dependencies:
'@types/yargs-parser': 21.0.3
+ optional: true
'@types/yargs@17.0.33':
dependencies:
@@ -18316,12 +18468,14 @@ snapshots:
'@graphql-typed-document-node/core': 3.2.0(graphql@15.8.0)
graphql: 15.8.0
wonka: 4.0.15
+ optional: true
'@urql/exchange-retry@0.3.0(graphql@15.8.0)':
dependencies:
'@urql/core': 2.3.6(graphql@15.8.0)
graphql: 15.8.0
wonka: 4.0.15
+ optional: true
'@vercel/style-guide@5.2.0(@next/eslint-plugin-next@14.2.6)(eslint@8.57.0)(prettier@3.3.3)(typescript@5.3.3)':
dependencies:
@@ -18641,9 +18795,11 @@ snapshots:
'@webassemblyjs/ast': 1.12.1
'@xtuc/long': 4.2.2
- '@xmldom/xmldom@0.7.13': {}
+ '@xmldom/xmldom@0.7.13':
+ optional: true
- '@xmldom/xmldom@0.8.10': {}
+ '@xmldom/xmldom@0.8.10':
+ optional: true
'@xtuc/ieee754@1.2.0': {}
@@ -18686,6 +18842,7 @@ snapshots:
debug: 4.3.7
transitivePeerDependencies:
- supports-color
+ optional: true
agent-base@7.1.0:
dependencies:
@@ -18765,7 +18922,8 @@ snapshots:
ansi-html-community@0.0.8: {}
- ansi-regex@4.1.1: {}
+ ansi-regex@4.1.1:
+ optional: true
ansi-regex@5.0.1: {}
@@ -18790,7 +18948,8 @@ snapshots:
normalize-path: 3.0.0
picomatch: 2.3.1
- application-config-path@0.1.1: {}
+ application-config-path@0.1.1:
+ optional: true
aproba@2.0.0:
optional: true
@@ -18811,7 +18970,8 @@ snapshots:
argparse@2.0.1: {}
- argsarray@0.0.1: {}
+ argsarray@0.0.1:
+ optional: true
aria-hidden@1.2.4:
dependencies:
@@ -18830,6 +18990,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
is-array-buffer: 3.0.4
+ optional: true
array-flatten@1.1.1: {}
@@ -18901,6 +19062,7 @@ snapshots:
get-intrinsic: 1.2.4
is-array-buffer: 3.0.4
is-shared-array-buffer: 1.0.3
+ optional: true
asap@2.0.6: {}
@@ -18930,7 +19092,8 @@ snapshots:
dependencies:
has-symbols: 1.0.3
- asynckit@0.4.0: {}
+ asynckit@0.4.0:
+ optional: true
at-least-node@1.0.0: {}
@@ -18961,6 +19124,7 @@ snapshots:
available-typed-arrays@1.0.7:
dependencies:
possible-typed-array-names: 1.0.0
+ optional: true
axe-core@4.7.0: {}
@@ -19085,8 +19249,10 @@ snapshots:
pretty-format: 24.9.0
zod: 3.23.8
zod-validation-error: 2.1.0(zod@3.23.8)
+ optional: true
- babel-plugin-react-native-web@0.19.13: {}
+ babel-plugin-react-native-web@0.19.13:
+ optional: true
babel-plugin-syntax-hermes-parser@0.23.1:
dependencies:
@@ -19137,6 +19303,7 @@ snapshots:
- '@babel/core'
- '@babel/preset-env'
- supports-color
+ optional: true
babel-preset-jest@29.6.3(@babel/core@7.26.0):
dependencies:
@@ -19161,6 +19328,7 @@ snapshots:
better-opn@3.0.2:
dependencies:
open: 8.4.2
+ optional: true
better-sqlite3@11.5.0:
dependencies:
@@ -19169,7 +19337,8 @@ snapshots:
big-integer@1.6.51: {}
- big-integer@1.6.52: {}
+ big-integer@1.6.52:
+ optional: true
big.js@5.2.2: {}
@@ -19234,10 +19403,12 @@ snapshots:
bplist-creator@0.0.7:
dependencies:
stream-buffers: 2.2.0
+ optional: true
bplist-creator@0.1.0:
dependencies:
stream-buffers: 2.2.0
+ optional: true
bplist-parser@0.2.0:
dependencies:
@@ -19246,10 +19417,12 @@ snapshots:
bplist-parser@0.3.1:
dependencies:
big-integer: 1.6.52
+ optional: true
bplist-parser@0.3.2:
dependencies:
big-integer: 1.6.52
+ optional: true
brace-expansion@1.1.11:
dependencies:
@@ -19293,14 +19466,17 @@ snapshots:
dependencies:
node-int64: 0.4.0
- buffer-alloc-unsafe@1.1.0: {}
+ buffer-alloc-unsafe@1.1.0:
+ optional: true
buffer-alloc@1.2.0:
dependencies:
buffer-alloc-unsafe: 1.1.0
buffer-fill: 1.0.0
+ optional: true
- buffer-fill@1.0.0: {}
+ buffer-fill@1.0.0:
+ optional: true
buffer-from@1.1.2: {}
@@ -19311,7 +19487,8 @@ snapshots:
builtin-modules@3.3.0: {}
- builtins@1.0.3: {}
+ builtins@1.0.3:
+ optional: true
builtins@5.0.1:
dependencies:
@@ -19369,6 +19546,7 @@ snapshots:
ssri: 10.0.6
tar: 6.2.1
unique-filename: 3.0.0
+ optional: true
cacheable-lookup@7.0.0: {}
@@ -19516,7 +19694,8 @@ snapshots:
chardet@0.7.0: {}
- charenc@0.0.2: {}
+ charenc@0.0.2:
+ optional: true
check-error@1.0.3:
dependencies:
@@ -19625,6 +19804,7 @@ snapshots:
cli-cursor@2.1.0:
dependencies:
restore-cursor: 2.0.0
+ optional: true
cli-cursor@3.1.0:
dependencies:
@@ -19632,7 +19812,8 @@ snapshots:
cli-spinners@2.9.0: {}
- cli-spinners@2.9.2: {}
+ cli-spinners@2.9.2:
+ optional: true
cli-table3@0.6.5:
dependencies:
@@ -19658,7 +19839,8 @@ snapshots:
clone@1.0.4: {}
- clone@2.1.2: {}
+ clone@2.1.2:
+ optional: true
clsx@1.2.1: {}
@@ -19714,12 +19896,14 @@ snapshots:
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
+ optional: true
comma-separated-tokens@1.0.8: {}
comma-separated-tokens@2.0.3: {}
- command-exists@1.2.9: {}
+ command-exists@1.2.9:
+ optional: true
commander@10.0.1: {}
@@ -19749,7 +19933,8 @@ snapshots:
commondir@1.0.1: {}
- component-type@1.2.2: {}
+ component-type@1.2.2:
+ optional: true
compressible@2.0.18:
dependencies:
@@ -19907,6 +20092,7 @@ snapshots:
semver: 5.7.2
shebang-command: 1.2.0
which: 1.3.1
+ optional: true
cross-spawn@7.0.3:
dependencies:
@@ -19920,9 +20106,11 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
- crypt@0.0.2: {}
+ crypt@0.0.2:
+ optional: true
- crypto-random-string@1.0.0: {}
+ crypto-random-string@1.0.0:
+ optional: true
crypto-random-string@2.0.0: {}
@@ -20148,7 +20336,8 @@ snapshots:
dependencies:
d3-array: 3.2.1
- dag-map@1.0.2: {}
+ dag-map@1.0.2:
+ optional: true
damerau-levenshtein@1.0.8: {}
@@ -20159,18 +20348,21 @@ snapshots:
call-bind: 1.0.7
es-errors: 1.3.0
is-data-view: 1.0.1
+ optional: true
data-view-byte-length@1.0.1:
dependencies:
call-bind: 1.0.7
es-errors: 1.3.0
is-data-view: 1.0.1
+ optional: true
data-view-byte-offset@1.0.0:
dependencies:
call-bind: 1.0.7
es-errors: 1.3.0
is-data-view: 1.0.1
+ optional: true
date-fns@2.30.0:
dependencies:
@@ -20234,6 +20426,7 @@ snapshots:
dependencies:
execa: 1.0.0
ip-regex: 2.1.0
+ optional: true
default-gateway@6.0.3:
dependencies:
@@ -20309,7 +20502,8 @@ snapshots:
dependencies:
robust-predicates: 3.0.2
- delayed-stream@1.0.0: {}
+ delayed-stream@1.0.0:
+ optional: true
delegates@1.0.0:
optional: true
@@ -20446,6 +20640,7 @@ snapshots:
dotenv-expand@11.0.6:
dependencies:
dotenv: 16.4.5
+ optional: true
dotenv@16.0.3: {}
@@ -20460,12 +20655,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- drizzle-orm@0.33.0(@types/better-sqlite3@7.6.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(react@18.3.1)(sqlite3@5.1.7):
+ drizzle-orm@0.33.0(@types/better-sqlite3@7.6.11)(@types/pg@8.11.11)(@types/react@18.2.61)(better-sqlite3@11.5.0)(expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)))(pg@8.13.1)(react@18.3.1)(sqlite3@5.1.7):
optionalDependencies:
'@types/better-sqlite3': 7.6.11
+ '@types/pg': 8.11.11
'@types/react': 18.2.61
better-sqlite3: 11.5.0
expo-sqlite: 14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13))
+ pg: 8.13.1
react: 18.3.1
sqlite3: 5.1.7
@@ -20531,12 +20728,14 @@ snapshots:
entities@4.5.0: {}
- env-editor@0.4.2: {}
+ env-editor@0.4.2:
+ optional: true
env-paths@2.2.1:
optional: true
- eol@0.9.1: {}
+ eol@0.9.1:
+ optional: true
err-code@2.0.3:
optional: true
@@ -20639,6 +20838,7 @@ snapshots:
typed-array-length: 1.0.6
unbox-primitive: 1.0.2
which-typed-array: 1.1.15
+ optional: true
es-define-property@1.0.0:
dependencies:
@@ -20668,6 +20868,7 @@ snapshots:
es-object-atoms@1.0.0:
dependencies:
es-errors: 1.3.0
+ optional: true
es-set-tostringtag@2.0.2:
dependencies:
@@ -20680,6 +20881,7 @@ snapshots:
get-intrinsic: 1.2.4
has-tostringtag: 1.0.2
hasown: 2.0.2
+ optional: true
es-shim-unscopables@1.0.2:
dependencies:
@@ -20834,7 +21036,7 @@ snapshots:
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(eslint@8.57.0))(eslint@8.57.0)
- eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
eslint-plugin-react: 7.33.2(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0)
@@ -20873,7 +21075,7 @@ snapshots:
eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.0)(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)
fast-glob: 3.3.1
- get-tsconfig: 4.7.2
+ get-tsconfig: 4.8.1
is-core-module: 2.13.1
is-glob: 4.0.3
transitivePeerDependencies:
@@ -20888,9 +21090,9 @@ snapshots:
enhanced-resolve: 5.15.0
eslint: 8.57.0
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
- eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
fast-glob: 3.3.1
- get-tsconfig: 4.7.2
+ get-tsconfig: 4.8.1
is-core-module: 2.13.1
is-glob: 4.0.3
transitivePeerDependencies:
@@ -20927,7 +21129,7 @@ snapshots:
eslint: 8.57.0
ignore: 5.3.1
- eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
+ eslint-plugin-import@2.29.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
dependencies:
array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3
@@ -21208,7 +21410,8 @@ snapshots:
events@3.3.0: {}
- exec-async@2.2.0: {}
+ exec-async@2.2.0:
+ optional: true
execa@1.0.0:
dependencies:
@@ -21219,10 +21422,11 @@ snapshots:
p-finally: 1.0.0
signal-exit: 3.0.7
strip-eof: 1.0.0
+ optional: true
execa@5.1.1:
dependencies:
- cross-spawn: 7.0.3
+ cross-spawn: 7.0.5
get-stream: 6.0.1
human-signals: 2.1.0
is-stream: 2.0.1
@@ -21268,6 +21472,7 @@ snapshots:
md5-file: 3.2.3
transitivePeerDependencies:
- supports-color
+ optional: true
expo-constants@16.0.2(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)):
dependencies:
@@ -21276,19 +21481,23 @@ snapshots:
expo: 51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)
transitivePeerDependencies:
- supports-color
+ optional: true
expo-file-system@17.0.1(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)):
dependencies:
expo: 51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)
+ optional: true
expo-font@12.0.10(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)):
dependencies:
expo: 51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)
fontfaceobserver: 2.3.0
+ optional: true
expo-keep-awake@13.0.2(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)):
dependencies:
expo: 51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)
+ optional: true
expo-modules-autolinking@1.11.3:
dependencies:
@@ -21299,15 +21508,18 @@ snapshots:
fs-extra: 9.1.0
require-from-string: 2.0.2
resolve-from: 5.0.0
+ optional: true
expo-modules-core@1.12.25:
dependencies:
invariant: 2.2.4
+ optional: true
expo-sqlite@14.0.6(expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)):
dependencies:
'@expo/websql': 1.0.1
expo: 51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13)
+ optional: true
expo@51.0.36(@babel/core@7.26.0)(@babel/preset-env@7.25.7(@babel/core@7.26.0))(encoding@0.1.13):
dependencies:
@@ -21333,6 +21545,7 @@ snapshots:
- encoding
- supports-color
- utf-8-validate
+ optional: true
exponential-backoff@3.1.1: {}
@@ -21441,6 +21654,7 @@ snapshots:
fbjs: 3.0.5(encoding@0.1.13)
transitivePeerDependencies:
- encoding
+ optional: true
fbjs-css-vars@1.0.2: {}
@@ -21462,7 +21676,8 @@ snapshots:
dependencies:
xml-js: 1.6.11
- fetch-retry@4.1.1: {}
+ fetch-retry@4.1.1:
+ optional: true
figures@3.2.0:
dependencies:
@@ -21563,6 +21778,7 @@ snapshots:
find-yarn-workspace-root@2.0.0:
dependencies:
micromatch: 4.0.8
+ optional: true
flat-cache@3.0.4:
dependencies:
@@ -21581,7 +21797,8 @@ snapshots:
follow-redirects@1.15.9: {}
- fontfaceobserver@2.3.0: {}
+ fontfaceobserver@2.3.0:
+ optional: true
for-each@0.3.3:
dependencies:
@@ -21589,7 +21806,7 @@ snapshots:
foreground-child@3.1.1:
dependencies:
- cross-spawn: 7.0.3
+ cross-spawn: 7.0.5
signal-exit: 4.1.0
foreground-child@3.3.0:
@@ -21624,6 +21841,7 @@ snapshots:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
+ optional: true
format@0.2.2: {}
@@ -21637,7 +21855,8 @@ snapshots:
fraction.js@4.3.7: {}
- freeport-async@2.0.0: {}
+ freeport-async@2.0.0:
+ optional: true
fresh@0.5.2: {}
@@ -21667,6 +21886,7 @@ snapshots:
graceful-fs: 4.2.11
jsonfile: 6.1.0
universalify: 1.0.0
+ optional: true
fs-extra@9.1.0:
dependencies:
@@ -21682,6 +21902,7 @@ snapshots:
fs-minipass@3.0.3:
dependencies:
minipass: 7.1.2
+ optional: true
fs-monkey@1.0.6: {}
@@ -21740,13 +21961,15 @@ snapshots:
get-package-type@0.1.0: {}
- get-port@3.2.0: {}
+ get-port@3.2.0:
+ optional: true
get-stdin@9.0.0: {}
get-stream@4.1.0:
dependencies:
pump: 3.0.2
+ optional: true
get-stream@6.0.1: {}
@@ -21762,10 +21985,7 @@ snapshots:
call-bind: 1.0.7
es-errors: 1.3.0
get-intrinsic: 1.2.4
-
- get-tsconfig@4.7.2:
- dependencies:
- resolve-pkg-maps: 1.0.0
+ optional: true
get-tsconfig@4.8.1:
dependencies:
@@ -21784,7 +22004,8 @@ snapshots:
dependencies:
isobject: 3.0.1
- getenv@1.0.0: {}
+ getenv@1.0.0:
+ optional: true
git-hooks-list@3.1.0: {}
@@ -21827,6 +22048,7 @@ snapshots:
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
+ optional: true
glob@7.2.3:
dependencies:
@@ -21865,6 +22087,7 @@ snapshots:
dependencies:
define-properties: 1.2.1
gopd: 1.0.1
+ optional: true
globby@10.0.2:
dependencies:
@@ -21937,8 +22160,10 @@ snapshots:
dependencies:
graphql: 15.8.0
tslib: 2.8.1
+ optional: true
- graphql@15.8.0: {}
+ graphql@15.8.0:
+ optional: true
gray-matter@4.0.3:
dependencies:
@@ -21980,7 +22205,8 @@ snapshots:
has-proto@1.0.1: {}
- has-proto@1.0.3: {}
+ has-proto@1.0.3:
+ optional: true
has-symbols@1.0.3: {}
@@ -21991,6 +22217,7 @@ snapshots:
has-tostringtag@1.0.2:
dependencies:
has-symbols: 1.0.3
+ optional: true
has-unicode@2.0.1:
optional: true
@@ -22004,6 +22231,7 @@ snapshots:
hasown@2.0.2:
dependencies:
function-bind: 1.1.2
+ optional: true
hast-util-from-parse5@8.0.1:
dependencies:
@@ -22116,7 +22344,8 @@ snapshots:
no-case: 2.3.2
upper-case: 1.1.3
- hermes-estree@0.19.1: {}
+ hermes-estree@0.19.1:
+ optional: true
hermes-estree@0.23.1: {}
@@ -22127,6 +22356,7 @@ snapshots:
hermes-parser@0.19.1:
dependencies:
hermes-estree: 0.19.1
+ optional: true
hermes-parser@0.23.1:
dependencies:
@@ -22164,6 +22394,7 @@ snapshots:
hosted-git-info@3.0.8:
dependencies:
lru-cache: 6.0.0
+ optional: true
hpack.js@2.1.6:
dependencies:
@@ -22301,6 +22532,7 @@ snapshots:
debug: 4.3.7
transitivePeerDependencies:
- supports-color
+ optional: true
https-proxy-agent@7.0.1:
dependencies:
@@ -22344,7 +22576,8 @@ snapshots:
dependencies:
queue: 6.0.2
- immediate@3.3.0: {}
+ immediate@3.3.0:
+ optional: true
immer@9.0.21: {}
@@ -22429,6 +22662,7 @@ snapshots:
dependencies:
default-gateway: 4.2.0
ipaddr.js: 1.9.1
+ optional: true
internal-slot@1.0.6:
dependencies:
@@ -22441,6 +22675,7 @@ snapshots:
es-errors: 1.3.0
hasown: 2.0.2
side-channel: 1.0.6
+ optional: true
internmap@2.0.3: {}
@@ -22450,7 +22685,8 @@ snapshots:
dependencies:
loose-envify: 1.4.0
- ip-regex@2.1.0: {}
+ ip-regex@2.1.0:
+ optional: true
ip@1.1.8: {}
@@ -22484,6 +22720,7 @@ snapshots:
dependencies:
call-bind: 1.0.7
get-intrinsic: 1.2.4
+ optional: true
is-arrayish@0.2.1: {}
@@ -22506,7 +22743,8 @@ snapshots:
call-bind: 1.0.5
has-tostringtag: 1.0.0
- is-buffer@1.1.6: {}
+ is-buffer@1.1.6:
+ optional: true
is-builtin-module@3.2.1:
dependencies:
@@ -22525,6 +22763,7 @@ snapshots:
is-data-view@1.0.1:
dependencies:
is-typed-array: 1.1.13
+ optional: true
is-date-object@1.0.5:
dependencies:
@@ -22542,7 +22781,8 @@ snapshots:
is-extendable@0.1.1: {}
- is-extglob@1.0.0: {}
+ is-extglob@1.0.0:
+ optional: true
is-extglob@2.1.1: {}
@@ -22559,6 +22799,7 @@ snapshots:
is-glob@2.0.1:
dependencies:
is-extglob: 1.0.0
+ optional: true
is-glob@4.0.3:
dependencies:
@@ -22582,6 +22823,7 @@ snapshots:
is-invalid-path@0.1.0:
dependencies:
is-glob: 2.0.1
+ optional: true
is-lambda@1.0.1:
optional: true
@@ -22596,7 +22838,8 @@ snapshots:
is-negative-zero@2.0.2: {}
- is-negative-zero@2.0.3: {}
+ is-negative-zero@2.0.3:
+ optional: true
is-npm@6.0.0: {}
@@ -22654,8 +22897,10 @@ snapshots:
is-shared-array-buffer@1.0.3:
dependencies:
call-bind: 1.0.7
+ optional: true
- is-stream@1.1.0: {}
+ is-stream@1.1.0:
+ optional: true
is-stream@2.0.1: {}
@@ -22676,6 +22921,7 @@ snapshots:
is-typed-array@1.1.13:
dependencies:
which-typed-array: 1.1.15
+ optional: true
is-typedarray@1.0.0: {}
@@ -22688,6 +22934,7 @@ snapshots:
is-valid-path@0.1.1:
dependencies:
is-invalid-path: 0.1.0
+ optional: true
is-weakmap@2.0.1: {}
@@ -22843,7 +23090,8 @@ snapshots:
merge-stream: 2.0.0
supports-color: 8.1.1
- jimp-compact@0.16.1: {}
+ jimp-compact@0.16.1:
+ optional: true
jiti@1.21.6: {}
@@ -22857,7 +23105,8 @@ snapshots:
'@sideway/formula': 3.0.1
'@sideway/pinpoint': 2.0.0
- join-component@1.1.0: {}
+ join-component@1.1.0:
+ optional: true
jose@4.15.9: {}
@@ -22927,6 +23176,7 @@ snapshots:
memory-cache: 0.2.0
traverse: 0.6.10
valid-url: 1.0.9
+ optional: true
json-schema-traverse@0.4.1: {}
@@ -23066,6 +23316,7 @@ snapshots:
lightningcss-linux-x64-gnu: 1.19.0
lightningcss-linux-x64-musl: 1.19.0
lightningcss-win32-x64-msvc: 1.19.0
+ optional: true
lightningcss@1.28.1:
dependencies:
@@ -23145,6 +23396,7 @@ snapshots:
log-symbols@2.2.0:
dependencies:
chalk: 2.4.2
+ optional: true
log-symbols@3.0.0:
dependencies:
@@ -23205,7 +23457,7 @@ snapshots:
lru-cache@7.18.3: {}
- lucide-react@0.473.0(react@18.3.1):
+ lucide-react@0.474.0(react@18.3.1):
dependencies:
react: 18.3.1
@@ -23266,20 +23518,24 @@ snapshots:
md5-file@3.2.3:
dependencies:
buffer-alloc: 1.2.0
+ optional: true
md5@2.2.1:
dependencies:
charenc: 0.0.2
crypt: 0.0.2
is-buffer: 1.1.6
+ optional: true
md5@2.3.0:
dependencies:
charenc: 0.0.2
crypt: 0.0.2
is-buffer: 1.1.6
+ optional: true
- md5hex@1.0.0: {}
+ md5hex@1.0.0:
+ optional: true
mdast-util-directive@3.0.0:
dependencies:
@@ -23486,7 +23742,8 @@ snapshots:
memoize-one@6.0.0: {}
- memory-cache@0.2.0: {}
+ memory-cache@0.2.0:
+ optional: true
merge-descriptors@1.0.3: {}
@@ -23998,7 +24255,8 @@ snapshots:
mime@1.6.0: {}
- mimic-fn@1.2.0: {}
+ mimic-fn@1.2.0:
+ optional: true
mimic-fn@2.1.0: {}
@@ -24044,6 +24302,7 @@ snapshots:
minipass-collect@2.0.1:
dependencies:
minipass: 7.1.2
+ optional: true
minipass-fetch@1.4.1:
dependencies:
@@ -24057,10 +24316,12 @@ snapshots:
minipass-flush@1.0.5:
dependencies:
minipass: 3.3.6
+ optional: true
minipass-pipeline@1.2.4:
dependencies:
minipass: 3.3.6
+ optional: true
minipass-sized@1.0.3:
dependencies:
@@ -24142,17 +24403,18 @@ snapshots:
neo-async@2.6.2: {}
- nested-error-stacks@2.0.1: {}
+ nested-error-stacks@2.0.1:
+ optional: true
netmask@2.0.2: {}
- next-auth@4.24.10(next@15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ next-auth@4.24.10(next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
'@babel/runtime': 7.26.0
'@panva/hkdf': 1.2.1
cookie: 0.7.2
jose: 4.15.9
- next: 15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ next: 15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
oauth: 0.9.15
openid-client: 5.7.0
preact: 10.24.3
@@ -24161,12 +24423,12 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
uuid: 8.3.2
- next-pwa@5.6.0(@babel/core@7.26.0)(@types/babel__core@7.20.5)(next@15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(webpack@5.95.0):
+ next-pwa@5.6.0(@babel/core@7.26.0)(@types/babel__core@7.20.5)(next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(webpack@5.95.0):
dependencies:
babel-loader: 8.4.1(@babel/core@7.26.0)(webpack@5.95.0)
clean-webpack-plugin: 4.0.0(webpack@5.95.0)
globby: 11.1.0
- next: 15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ next: 15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
terser-webpack-plugin: 5.3.10(webpack@5.95.0)
workbox-webpack-plugin: 6.6.0(@types/babel__core@7.20.5)(webpack@5.95.0)
workbox-window: 6.6.0
@@ -24184,9 +24446,9 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- next@15.1.5(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ next@15.1.6(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
- '@next/env': 15.1.5
+ '@next/env': 15.1.6
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.15
busboy: 1.6.0
@@ -24196,20 +24458,21 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
styled-jsx: 5.1.6(@babel/core@7.26.0)(react@18.3.1)
optionalDependencies:
- '@next/swc-darwin-arm64': 15.1.5
- '@next/swc-darwin-x64': 15.1.5
- '@next/swc-linux-arm64-gnu': 15.1.5
- '@next/swc-linux-arm64-musl': 15.1.5
- '@next/swc-linux-x64-gnu': 15.1.5
- '@next/swc-linux-x64-musl': 15.1.5
- '@next/swc-win32-arm64-msvc': 15.1.5
- '@next/swc-win32-x64-msvc': 15.1.5
+ '@next/swc-darwin-arm64': 15.1.6
+ '@next/swc-darwin-x64': 15.1.6
+ '@next/swc-linux-arm64-gnu': 15.1.6
+ '@next/swc-linux-arm64-musl': 15.1.6
+ '@next/swc-linux-x64-gnu': 15.1.6
+ '@next/swc-linux-x64-musl': 15.1.6
+ '@next/swc-win32-arm64-msvc': 15.1.6
+ '@next/swc-win32-x64-msvc': 15.1.6
sharp: 0.33.5
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
- nice-try@1.0.5: {}
+ nice-try@1.0.5:
+ optional: true
no-case@2.3.2:
dependencies:
@@ -24284,7 +24547,8 @@ snapshots:
node-releases@2.0.18: {}
- noop-fn@1.0.0: {}
+ noop-fn@1.0.0:
+ optional: true
nopt@5.0.0:
dependencies:
@@ -24310,10 +24574,12 @@ snapshots:
osenv: 0.1.5
semver: 5.7.2
validate-npm-package-name: 3.0.0
+ optional: true
npm-run-path@2.0.2:
dependencies:
path-key: 2.0.1
+ optional: true
npm-run-path@4.0.1:
dependencies:
@@ -24355,7 +24621,8 @@ snapshots:
object-inspect@1.13.1: {}
- object-inspect@1.13.2: {}
+ object-inspect@1.13.2:
+ optional: true
object-keys@1.1.1: {}
@@ -24372,6 +24639,7 @@ snapshots:
define-properties: 1.2.1
has-symbols: 1.0.3
object-keys: 1.1.1
+ optional: true
object.entries@1.1.7:
dependencies:
@@ -24428,6 +24696,7 @@ snapshots:
onetime@2.0.1:
dependencies:
mimic-fn: 1.2.0
+ optional: true
onetime@5.1.2:
dependencies:
@@ -24481,6 +24750,7 @@ snapshots:
log-symbols: 2.2.0
strip-ansi: 5.2.0
wcwidth: 1.0.1
+ optional: true
ora@4.1.1:
dependencies:
@@ -24505,7 +24775,8 @@ snapshots:
strip-ansi: 6.0.1
wcwidth: 1.0.1
- os-homedir@1.0.2: {}
+ os-homedir@1.0.2:
+ optional: true
os-tmpdir@1.0.2: {}
@@ -24513,10 +24784,12 @@ snapshots:
dependencies:
os-homedir: 1.0.2
os-tmpdir: 1.0.2
+ optional: true
p-cancelable@3.0.0: {}
- p-finally@1.0.0: {}
+ p-finally@1.0.0:
+ optional: true
p-limit@2.3.0:
dependencies:
@@ -24645,6 +24918,7 @@ snapshots:
parse-png@2.1.0:
dependencies:
pngjs: 3.4.0
+ optional: true
parse5-htmlparser2-tree-adapter@7.0.0:
dependencies:
@@ -24675,6 +24949,7 @@ snapshots:
dependencies:
ansi-escapes: 4.3.2
cross-spawn: 7.0.5
+ optional: true
path-case@2.1.1:
dependencies:
@@ -24690,7 +24965,8 @@ snapshots:
path-is-inside@1.0.2: {}
- path-key@2.0.1: {}
+ path-key@2.0.1:
+ optional: true
path-key@3.1.1: {}
@@ -24730,13 +25006,65 @@ snapshots:
estree-walker: 3.0.3
is-reference: 3.0.2
+ pg-cloudflare@1.1.1:
+ optional: true
+
+ pg-connection-string@2.7.0: {}
+
+ pg-dump-restore@1.0.12:
+ dependencies:
+ execa: 5.1.1
+
+ pg-int8@1.0.1: {}
+
+ pg-numeric@1.0.2: {}
+
+ pg-pool@3.7.0(pg@8.13.1):
+ dependencies:
+ pg: 8.13.1
+
+ pg-protocol@1.7.0: {}
+
+ pg-types@2.2.0:
+ dependencies:
+ pg-int8: 1.0.1
+ postgres-array: 2.0.0
+ postgres-bytea: 1.0.0
+ postgres-date: 1.0.7
+ postgres-interval: 1.2.0
+
+ pg-types@4.0.2:
+ dependencies:
+ pg-int8: 1.0.1
+ pg-numeric: 1.0.2
+ postgres-array: 3.0.2
+ postgres-bytea: 3.0.0
+ postgres-date: 2.1.0
+ postgres-interval: 3.0.0
+ postgres-range: 1.1.4
+
+ pg@8.13.1:
+ dependencies:
+ pg-connection-string: 2.7.0
+ pg-pool: 3.7.0(pg@8.13.1)
+ pg-protocol: 1.7.0
+ pg-types: 2.2.0
+ pgpass: 1.0.5
+ optionalDependencies:
+ pg-cloudflare: 1.1.1
+
+ pgpass@1.0.5:
+ dependencies:
+ split2: 4.2.0
+
picocolors@1.0.0: {}
picocolors@1.1.1: {}
picomatch@2.3.1: {}
- picomatch@3.0.1: {}
+ picomatch@3.0.1:
+ optional: true
pify@2.3.0: {}
@@ -24777,12 +25105,15 @@ snapshots:
'@xmldom/xmldom': 0.8.10
base64-js: 1.5.1
xmlbuilder: 15.1.1
+ optional: true
pluralize@8.0.0: {}
- pngjs@3.4.0: {}
+ pngjs@3.4.0:
+ optional: true
- possible-typed-array-names@1.0.0: {}
+ possible-typed-array-names@1.0.0:
+ optional: true
postcss-calc@9.0.1(postcss@8.4.31):
dependencies:
@@ -25183,7 +25514,30 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
- pouchdb-collections@1.0.1: {}
+ postgres-array@2.0.0: {}
+
+ postgres-array@3.0.2: {}
+
+ postgres-bytea@1.0.0: {}
+
+ postgres-bytea@3.0.0:
+ dependencies:
+ obuf: 1.1.2
+
+ postgres-date@1.0.7: {}
+
+ postgres-date@2.1.0: {}
+
+ postgres-interval@1.2.0:
+ dependencies:
+ xtend: 4.0.2
+
+ postgres-interval@3.0.0: {}
+
+ postgres-range@1.1.4: {}
+
+ pouchdb-collections@1.0.1:
+ optional: true
preact-render-to-string@5.2.6(preact@10.24.3):
dependencies:
@@ -25241,6 +25595,7 @@ snapshots:
ansi-regex: 4.1.1
ansi-styles: 3.2.1
react-is: 16.13.1
+ optional: true
pretty-format@29.7.0:
dependencies:
@@ -25264,7 +25619,8 @@ snapshots:
process-nextick-args@2.0.1: {}
- progress@2.0.3: {}
+ progress@2.0.3:
+ optional: true
promise-inflight@1.0.1:
optional: true
@@ -25337,7 +25693,8 @@ snapshots:
dependencies:
escape-goat: 4.0.0
- qrcode-terminal@0.11.0: {}
+ qrcode-terminal@0.11.0:
+ optional: true
qs@6.13.0:
dependencies:
@@ -25890,6 +26247,7 @@ snapshots:
define-properties: 1.2.1
es-errors: 1.3.0
set-function-name: 2.0.2
+ optional: true
regexpu-core@6.1.1:
dependencies:
@@ -26008,7 +26366,8 @@ snapshots:
mdast-util-to-markdown: 2.1.0
unified: 11.0.5
- remove-trailing-slash@0.1.1: {}
+ remove-trailing-slash@0.1.1:
+ optional: true
renderkid@3.0.0:
dependencies:
@@ -26033,6 +26392,7 @@ snapshots:
nested-error-stacks: 2.0.1
rc: 1.2.8
resolve: 1.7.1
+ optional: true
requires-port@1.0.0: {}
@@ -26048,7 +26408,8 @@ snapshots:
resolve-pkg-maps@1.0.0: {}
- resolve.exports@2.0.2: {}
+ resolve.exports@2.0.2:
+ optional: true
resolve@1.19.0:
dependencies:
@@ -26064,6 +26425,7 @@ snapshots:
resolve@1.7.1:
dependencies:
path-parse: 1.0.7
+ optional: true
resolve@2.0.0-next.5:
dependencies:
@@ -26079,6 +26441,7 @@ snapshots:
dependencies:
onetime: 2.0.1
signal-exit: 3.0.7
+ optional: true
restore-cursor@3.1.0:
dependencies:
@@ -26211,6 +26574,7 @@ snapshots:
get-intrinsic: 1.2.4
has-symbols: 1.0.3
isarray: 2.0.5
+ optional: true
safe-buffer@5.1.2: {}
@@ -26227,6 +26591,7 @@ snapshots:
call-bind: 1.0.7
es-errors: 1.3.0
is-regex: 1.1.4
+ optional: true
safe-stable-stringify@2.5.0: {}
@@ -26311,6 +26676,7 @@ snapshots:
statuses: 2.0.1
transitivePeerDependencies:
- supports-color
+ optional: true
send@0.19.0:
dependencies:
@@ -26408,6 +26774,7 @@ snapshots:
es-errors: 1.3.0
functions-have-names: 1.2.3
has-property-descriptors: 1.0.2
+ optional: true
set-value@4.1.0:
dependencies:
@@ -26455,12 +26822,14 @@ snapshots:
shebang-command@1.2.0:
dependencies:
shebang-regex: 1.0.0
+ optional: true
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
- shebang-regex@1.0.0: {}
+ shebang-regex@1.0.0:
+ optional: true
shebang-regex@3.0.0: {}
@@ -26504,6 +26873,7 @@ snapshots:
bplist-creator: 0.1.0
bplist-parser: 0.3.1
plist: 3.1.0
+ optional: true
simple-swizzle@0.2.2:
dependencies:
@@ -26538,7 +26908,8 @@ snapshots:
astral-regex: 2.0.0
is-fullwidth-code-point: 3.0.0
- slugify@1.6.6: {}
+ slugify@1.6.6:
+ optional: true
smart-buffer@4.2.0: {}
@@ -26655,9 +27026,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ split2@4.2.0: {}
+
split@1.0.1:
dependencies:
through: 2.3.8
+ optional: true
sprintf-js@1.0.3: {}
@@ -26678,6 +27052,7 @@ snapshots:
ssri@10.0.6:
dependencies:
minipass: 7.1.2
+ optional: true
ssri@8.0.1:
dependencies:
@@ -26704,7 +27079,8 @@ snapshots:
std-env@3.7.0: {}
- stream-buffers@2.2.0: {}
+ stream-buffers@2.2.0:
+ optional: true
streamsearch@1.1.0: {}
@@ -26744,6 +27120,7 @@ snapshots:
define-properties: 1.2.1
es-abstract: 1.23.3
es-object-atoms: 1.0.0
+ optional: true
string.prototype.trimend@1.0.7:
dependencies:
@@ -26756,6 +27133,7 @@ snapshots:
call-bind: 1.0.7
define-properties: 1.2.1
es-object-atoms: 1.0.0
+ optional: true
string.prototype.trimstart@1.0.7:
dependencies:
@@ -26768,6 +27146,7 @@ snapshots:
call-bind: 1.0.7
define-properties: 1.2.1
es-object-atoms: 1.0.0
+ optional: true
string_decoder@1.1.1:
dependencies:
@@ -26791,6 +27170,7 @@ snapshots:
strip-ansi@5.2.0:
dependencies:
ansi-regex: 4.1.1
+ optional: true
strip-ansi@6.0.1:
dependencies:
@@ -26806,7 +27186,8 @@ snapshots:
strip-comments@2.0.1: {}
- strip-eof@1.0.0: {}
+ strip-eof@1.0.0:
+ optional: true
strip-final-newline@2.0.0: {}
@@ -26824,7 +27205,8 @@ snapshots:
dependencies:
js-tokens: 9.0.0
- structured-headers@0.4.1: {}
+ structured-headers@0.4.1:
+ optional: true
style-to-object@0.4.4:
dependencies:
@@ -26866,6 +27248,7 @@ snapshots:
mz: 2.7.0
pirates: 4.0.6
ts-interface-checker: 0.1.13
+ optional: true
sucrase@3.35.0:
dependencies:
@@ -26877,9 +27260,11 @@ snapshots:
pirates: 4.0.6
ts-interface-checker: 0.1.13
- sudo-prompt@8.2.5: {}
+ sudo-prompt@8.2.5:
+ optional: true
- sudo-prompt@9.1.1: {}
+ sudo-prompt@9.1.1:
+ optional: true
superjson@2.2.1:
dependencies:
@@ -26901,6 +27286,7 @@ snapshots:
dependencies:
has-flag: 4.0.0
supports-color: 7.2.0
+ optional: true
supports-preserve-symlinks-flag@1.0.0: {}
@@ -26997,7 +27383,8 @@ snapshots:
mkdirp: 1.0.4
yallist: 4.0.0
- temp-dir@1.0.0: {}
+ temp-dir@1.0.0:
+ optional: true
temp-dir@2.0.0: {}
@@ -27010,6 +27397,7 @@ snapshots:
temp-dir: 1.0.0
type-fest: 0.3.1
unique-string: 1.0.0
+ optional: true
tempy@0.6.0:
dependencies:
@@ -27025,11 +27413,13 @@ snapshots:
temp-dir: 2.0.0
type-fest: 0.16.0
unique-string: 2.0.0
+ optional: true
terminal-link@2.1.1:
dependencies:
ansi-escapes: 4.3.2
supports-hyperlinks: 2.3.0
+ optional: true
terser-webpack-plugin@5.3.10(webpack@5.95.0):
dependencies:
@@ -27080,7 +27470,8 @@ snapshots:
tiny-invariant@1.3.3: {}
- tiny-queue@0.2.1: {}
+ tiny-queue@0.2.1:
+ optional: true
tiny-warning@1.0.3: {}
@@ -27141,10 +27532,12 @@ snapshots:
gopd: 1.0.1
typedarray.prototype.slice: 1.0.3
which-typed-array: 1.1.15
+ optional: true
trim-lines@3.0.1: {}
- trim-right@1.0.1: {}
+ trim-right@1.0.1:
+ optional: true
triple-beam@1.4.1: {}
@@ -27222,6 +27615,13 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ tsx@4.19.2:
+ dependencies:
+ esbuild: 0.23.1
+ get-tsconfig: 4.8.1
+ optionalDependencies:
+ fsevents: 2.3.3
+
tunnel-agent@0.6.0:
dependencies:
safe-buffer: 5.2.1
@@ -27267,7 +27667,8 @@ snapshots:
type-fest@0.21.3: {}
- type-fest@0.3.1: {}
+ type-fest@0.3.1:
+ optional: true
type-fest@0.6.0: {}
@@ -27297,6 +27698,7 @@ snapshots:
call-bind: 1.0.7
es-errors: 1.3.0
is-typed-array: 1.1.13
+ optional: true
typed-array-byte-length@1.0.0:
dependencies:
@@ -27312,6 +27714,7 @@ snapshots:
gopd: 1.0.1
has-proto: 1.0.3
is-typed-array: 1.1.13
+ optional: true
typed-array-byte-offset@1.0.0:
dependencies:
@@ -27329,6 +27732,7 @@ snapshots:
gopd: 1.0.1
has-proto: 1.0.3
is-typed-array: 1.1.13
+ optional: true
typed-array-length@1.0.4:
dependencies:
@@ -27344,6 +27748,7 @@ snapshots:
has-proto: 1.0.3
is-typed-array: 1.1.13
possible-typed-array-names: 1.0.0
+ optional: true
typedarray-to-buffer@3.1.5:
dependencies:
@@ -27357,6 +27762,7 @@ snapshots:
es-errors: 1.3.0
typed-array-buffer: 1.0.2
typed-array-byte-offset: 1.0.2
+ optional: true
typescript@5.3.3: {}
@@ -27411,6 +27817,7 @@ snapshots:
unique-filename@3.0.0:
dependencies:
unique-slug: 4.0.0
+ optional: true
unique-slug@2.0.2:
dependencies:
@@ -27420,10 +27827,12 @@ snapshots:
unique-slug@4.0.0:
dependencies:
imurmurhash: 0.1.4
+ optional: true
unique-string@1.0.0:
dependencies:
crypto-random-string: 1.0.0
+ optional: true
unique-string@2.0.0:
dependencies:
@@ -27462,7 +27871,8 @@ snapshots:
universalify@0.1.2: {}
- universalify@1.0.0: {}
+ universalify@1.0.0:
+ optional: true
universalify@2.0.0: {}
@@ -27522,7 +27932,8 @@ snapshots:
dependencies:
punycode: 2.3.0
- url-join@4.0.0: {}
+ url-join@4.0.0:
+ optional: true
url-loader@4.1.1(file-loader@6.2.0(webpack@5.95.0))(webpack@5.95.0):
dependencies:
@@ -27586,13 +27997,15 @@ snapshots:
utils-merge@1.0.1: {}
- uuid@7.0.3: {}
+ uuid@7.0.3:
+ optional: true
uuid@8.3.2: {}
v8-compile-cache-lib@3.0.1: {}
- valid-url@1.0.9: {}
+ valid-url@1.0.9:
+ optional: true
validate-npm-package-license@3.0.4:
dependencies:
@@ -27602,6 +28015,7 @@ snapshots:
validate-npm-package-name@3.0.0:
dependencies:
builtins: 1.0.3
+ optional: true
validate-npm-package-name@5.0.0:
dependencies:
@@ -27788,7 +28202,8 @@ snapshots:
webidl-conversions@4.0.2: {}
- webidl-conversions@5.0.0: {}
+ webidl-conversions@5.0.0:
+ optional: true
webpack-bundle-analyzer@4.10.2:
dependencies:
@@ -27929,6 +28344,7 @@ snapshots:
buffer: 5.7.1
punycode: 2.3.1
webidl-conversions: 5.0.0
+ optional: true
whatwg-url@5.0.0:
dependencies:
@@ -27986,6 +28402,7 @@ snapshots:
for-each: 0.3.3
gopd: 1.0.1
has-tostringtag: 1.0.2
+ optional: true
which@1.3.1:
dependencies:
@@ -28031,7 +28448,8 @@ snapshots:
triple-beam: 1.4.1
winston-transport: 4.9.0
- wonka@4.0.15: {}
+ wonka@4.0.15:
+ optional: true
wordwrap@1.0.0: {}
@@ -28210,6 +28628,7 @@ snapshots:
dependencies:
simple-plist: 1.3.1
uuid: 7.0.3
+ optional: true
xdg-basedir@5.1.0: {}
@@ -28221,12 +28640,16 @@ snapshots:
dependencies:
sax: 1.4.1
xmlbuilder: 11.0.1
+ optional: true
- xmlbuilder@11.0.1: {}
+ xmlbuilder@11.0.1:
+ optional: true
- xmlbuilder@14.0.0: {}
+ xmlbuilder@14.0.0:
+ optional: true
- xmlbuilder@15.1.1: {}
+ xmlbuilder@15.1.1:
+ optional: true
xtend@4.0.2: {}
@@ -28261,6 +28684,7 @@ snapshots:
zod-validation-error@2.1.0(zod@3.23.8):
dependencies:
zod: 3.23.8
+ optional: true
zod@3.23.8: {}