diff --git a/.gitignore b/.gitignore index fc6ae86..1ec310a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ .vscode logfile .turbo -node_modules \ No newline at end of file +node_modules +# Cursor symlinked files +.cursor/rules/*-local.mdc +.cursor/commands/*-local.* diff --git a/hono/package-lock.json b/hono/package-lock.json index 08b9296..fc1e5c2 100644 --- a/hono/package-lock.json +++ b/hono/package-lock.json @@ -30,7 +30,7 @@ "@typescript-eslint/parser": "^6.21.0", "babel-jest": "^29.7.0", "dotenv": "^16.4.4", - "drizzle-kit": "^0.19.1", + "drizzle-kit": "^0.31.5", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-drizzle": "^0.2.3", @@ -728,11 +728,12 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@drizzle-team/studio": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@drizzle-team/studio/-/studio-0.0.5.tgz", - "integrity": "sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==", - "dev": true + "node_modules/@drizzle-team/brocli": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz", + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/@emnapi/runtime": { "version": "1.4.0", @@ -1189,9 +1190,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", - "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", "cpu": [ "ppc64" ], @@ -1206,9 +1207,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", - "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", "cpu": [ "arm" ], @@ -1223,9 +1224,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", - "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", "cpu": [ "arm64" ], @@ -1240,9 +1241,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", - "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", "cpu": [ "x64" ], @@ -1257,9 +1258,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", - "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", "cpu": [ "arm64" ], @@ -1274,9 +1275,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", - "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", "cpu": [ "x64" ], @@ -1291,9 +1292,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", - "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", "cpu": [ "arm64" ], @@ -1308,9 +1309,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", - "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", "cpu": [ "x64" ], @@ -1325,9 +1326,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", - "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", "cpu": [ "arm" ], @@ -1342,9 +1343,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", - "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", "cpu": [ "arm64" ], @@ -1359,9 +1360,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", - "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", "cpu": [ "ia32" ], @@ -1376,9 +1377,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", - "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", "cpu": [ "loong64" ], @@ -1393,9 +1394,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", - "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", "cpu": [ "mips64el" ], @@ -1410,9 +1411,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", - "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", "cpu": [ "ppc64" ], @@ -1427,9 +1428,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", - "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", "cpu": [ "riscv64" ], @@ -1444,9 +1445,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", - "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", "cpu": [ "s390x" ], @@ -1461,9 +1462,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", - "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", "cpu": [ "x64" ], @@ -1478,9 +1479,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", - "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", "cpu": [ "arm64" ], @@ -1495,9 +1496,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", - "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", "cpu": [ "x64" ], @@ -1512,9 +1513,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", - "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", "cpu": [ "arm64" ], @@ -1529,9 +1530,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", - "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", "cpu": [ "x64" ], @@ -1545,10 +1546,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", - "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", "cpu": [ "x64" ], @@ -1563,9 +1581,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", - "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", "cpu": [ "arm64" ], @@ -1580,9 +1598,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", - "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", "cpu": [ "ia32" ], @@ -1597,9 +1615,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", - "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", "cpu": [ "x64" ], @@ -4010,19 +4028,6 @@ } ] }, - "node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -4053,23 +4058,6 @@ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", "dev": true }, - "node_modules/cli-color": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", - "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", - "dev": true, - "license": "ISC", - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.64", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -4145,16 +4133,6 @@ "simple-swizzle": "^0.2.2" } }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || >=14" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4282,20 +4260,6 @@ "node": ">=0.8" } }, - "node_modules/d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "dev": true, - "license": "ISC", - "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/data-uri-to-buffer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", @@ -4395,566 +4359,93 @@ "node": ">=6" } }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, - "dependencies": { - "heap": ">= 0.2.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dotenv": { - "version": "16.4.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", - "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dreamopt": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.8.0.tgz", - "integrity": "sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==", - "dev": true, - "dependencies": { - "wordwrap": ">=0.0.2" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/drizzle-kit": { - "version": "0.19.13", - "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.19.13.tgz", - "integrity": "sha512-Rba5VW1O2JfJlwVBeZ8Zwt2E2us5oZ08PQBDiVSGlug53TOc8hzXjblZFuF+dnll9/RQEHrkzBmJFgqTvn5Rxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@drizzle-team/studio": "^0.0.5", - "@esbuild-kit/esm-loader": "^2.5.5", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "commander": "^9.4.1", - "esbuild": "^0.18.6", - "esbuild-register": "^3.4.2", - "glob": "^8.1.0", - "hanji": "^0.0.5", - "json-diff": "0.9.0", - "minimatch": "^7.4.3", - "zod": "^3.20.2" - }, - "bin": { - "drizzle-kit": "index.cjs" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/drizzle-kit/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "dev": true, - "license": "MIT", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/drizzle-kit/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "16.4.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz", + "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==", + "dev": true, "engines": { "node": ">=12" }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/drizzle-kit/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "node_modules/drizzle-kit": { + "version": "0.31.5", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.5.tgz", + "integrity": "sha512-+CHgPFzuoTQTt7cOYCV6MOw2w8vqEn/ap1yv4bpZOWL03u7rlVRQhUY0WYT3rHsgVTXwYQDZaSUJSQrMBUKuWg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" + "@drizzle-team/brocli": "^0.10.2", + "@esbuild-kit/esm-loader": "^2.5.5", + "esbuild": "^0.25.4", + "esbuild-register": "^3.5.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "bin": { + "drizzle-kit": "bin.cjs" } }, "node_modules/drizzle-orm": { @@ -5250,66 +4741,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, - "hasInstallScript": true, - "license": "ISC", - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "license": "ISC", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "node_modules/esbuild": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", - "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5320,31 +4755,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.2", - "@esbuild/android-arm": "0.25.2", - "@esbuild/android-arm64": "0.25.2", - "@esbuild/android-x64": "0.25.2", - "@esbuild/darwin-arm64": "0.25.2", - "@esbuild/darwin-x64": "0.25.2", - "@esbuild/freebsd-arm64": "0.25.2", - "@esbuild/freebsd-x64": "0.25.2", - "@esbuild/linux-arm": "0.25.2", - "@esbuild/linux-arm64": "0.25.2", - "@esbuild/linux-ia32": "0.25.2", - "@esbuild/linux-loong64": "0.25.2", - "@esbuild/linux-mips64el": "0.25.2", - "@esbuild/linux-ppc64": "0.25.2", - "@esbuild/linux-riscv64": "0.25.2", - "@esbuild/linux-s390x": "0.25.2", - "@esbuild/linux-x64": "0.25.2", - "@esbuild/netbsd-arm64": "0.25.2", - "@esbuild/netbsd-x64": "0.25.2", - "@esbuild/openbsd-arm64": "0.25.2", - "@esbuild/openbsd-x64": "0.25.2", - "@esbuild/sunos-x64": "0.25.2", - "@esbuild/win32-arm64": "0.25.2", - "@esbuild/win32-ia32": "0.25.2", - "@esbuild/win32-x64": "0.25.2" + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" } }, "node_modules/esbuild-register": { @@ -5865,22 +5301,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, - "license": "ISC", - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -5954,17 +5374,6 @@ "node": ">=0.10.0" } }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -6045,16 +5454,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "license": "ISC", - "dependencies": { - "type": "^2.7.2" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -6357,27 +5756,6 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -6395,19 +5773,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "license": "BSD-2-Clause" }, - "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/global-modules": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", @@ -6511,17 +5876,6 @@ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, - "node_modules/hanji": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/hanji/-/hanji-0.0.5.tgz", - "integrity": "sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==", - "dev": true, - "license": "ISC", - "dependencies": { - "lodash.throttle": "^4.1.1", - "sisteransi": "^1.0.5" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -6588,13 +5942,6 @@ "node": ">= 0.4" } }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true, - "license": "MIT" - }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -6884,13 +6231,6 @@ "node": ">=8" } }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true, - "license": "MIT" - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -8558,24 +7898,6 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, - "node_modules/json-diff": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.9.0.tgz", - "integrity": "sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-color": "^2.0.0", - "difflib": "~0.2.1", - "dreamopt": "~0.8.0" - }, - "bin": { - "json-diff": "bin/json-diff.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -8677,13 +7999,6 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, - "node_modules/lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -8702,16 +8017,6 @@ "yallist": "^3.0.2" } }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es5-ext": "~0.10.2" - } - }, "node_modules/magic-string": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", @@ -8796,26 +8101,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/memoizee": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", - "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", - "dev": true, - "license": "ISC", - "dependencies": { - "d": "^1.0.2", - "es5-ext": "^0.10.64", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -8943,13 +8228,6 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true, - "license": "ISC" - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -10263,20 +9541,6 @@ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, - "node_modules/timers-ext": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", - "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", - "dev": true, - "license": "ISC", - "dependencies": { - "es5-ext": "^0.10.64", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -10438,13 +9702,6 @@ "fsevents": "~2.3.3" } }, - "node_modules/type": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", - "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", - "dev": true, - "license": "ISC" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -10720,13 +9977,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, "node_modules/workerd": { "version": "1.20250310.0", "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250310.0.tgz", diff --git a/hono/package.json b/hono/package.json index 5160a95..55b6425 100644 --- a/hono/package.json +++ b/hono/package.json @@ -39,7 +39,7 @@ "@typescript-eslint/parser": "^6.21.0", "babel-jest": "^29.7.0", "dotenv": "^16.4.4", - "drizzle-kit": "^0.19.1", + "drizzle-kit": "^0.31.5", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-drizzle": "^0.2.3", diff --git a/hono/src/drizzle/0007_concerned_nitro.sql b/hono/src/drizzle/0007_concerned_nitro.sql new file mode 100644 index 0000000..2af1f4d --- /dev/null +++ b/hono/src/drizzle/0007_concerned_nitro.sql @@ -0,0 +1,6 @@ +CREATE TYPE "public"."itemStatus" AS ENUM('available', 'withheld', 'retired');--> statement-breakpoint +ALTER TABLE "items" ADD COLUMN "status" "itemStatus" DEFAULT 'available' NOT NULL;--> statement-breakpoint +UPDATE "items" SET "status" = 'withheld' WHERE "is_archived" = true;--> statement-breakpoint +ALTER TABLE "items" DROP COLUMN "is_archived";--> statement-breakpoint +ALTER TABLE "outfits" ADD COLUMN "location_latitude" DOUBLE PRECISION;--> statement-breakpoint +ALTER TABLE "outfits" ADD COLUMN "location_longitude" DOUBLE PRECISION; \ No newline at end of file diff --git a/hono/src/drizzle/meta/0007_snapshot.json b/hono/src/drizzle/meta/0007_snapshot.json new file mode 100644 index 0000000..503998b --- /dev/null +++ b/hono/src/drizzle/meta/0007_snapshot.json @@ -0,0 +1,386 @@ +{ + "id": "873476ec-4fb7-4d51-917b-8b47d256ac3d", + "prevId": "1620e8fa-2ea6-4e1d-b2c4-b2d0fe3dfbf5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.items": { + "name": "items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "brand": { + "name": "brand", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "photo_url": { + "name": "photo_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "itemType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "rating": { + "name": "rating", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "itemStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'available'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.items_to_outfits": { + "name": "items_to_outfits", + "schema": "", + "columns": { + "item_id": { + "name": "item_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "outfit_id": { + "name": "outfit_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "item_type": { + "name": "item_type", + "type": "itemType", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "items_to_outfits_item_id_items_id_fk": { + "name": "items_to_outfits_item_id_items_id_fk", + "tableFrom": "items_to_outfits", + "tableTo": "items", + "columnsFrom": ["item_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "items_to_outfits_outfit_id_outfits_id_fk": { + "name": "items_to_outfits_outfit_id_outfits_id_fk", + "tableFrom": "items_to_outfits", + "tableTo": "outfits", + "columnsFrom": ["outfit_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "items_to_outfits_item_id_outfit_id_pk": { + "name": "items_to_outfits_item_id_outfit_id_pk", + "columns": ["item_id", "outfit_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.outfits": { + "name": "outfits", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "rating": { + "name": "rating", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "wear_date": { + "name": "wear_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "location_latitude": { + "name": "location_latitude", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "location_longitude": { + "name": "location_longitude", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "rating_check": { + "name": "rating_check", + "value": "\"outfits\".\"rating\" >= 0 AND \"outfits\".\"rating\" <= 2" + } + }, + "isRLSEnabled": false + }, + "public.tags": { + "name": "tags", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hex_color": { + "name": "hex_color", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "min_days_before_item_reuse": { + "name": "min_days_before_item_reuse", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": -1 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "min_days_before_item_reuse": { + "name": "min_days_before_item_reuse", + "value": "\"tags\".\"min_days_before_item_reuse\" >= -1" + } + }, + "isRLSEnabled": false + }, + "public.tags_to_items": { + "name": "tags_to_items", + "schema": "", + "columns": { + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "item_id": { + "name": "item_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "tagStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'suggested'" + } + }, + "indexes": {}, + "foreignKeys": { + "tags_to_items_tag_id_tags_id_fk": { + "name": "tags_to_items_tag_id_tags_id_fk", + "tableFrom": "tags_to_items", + "tableTo": "tags", + "columnsFrom": ["tag_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tags_to_items_item_id_items_id_fk": { + "name": "tags_to_items_item_id_items_id_fk", + "tableFrom": "tags_to_items", + "tableTo": "items", + "columnsFrom": ["item_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "tags_to_items_tag_id_item_id_pk": { + "name": "tags_to_items_tag_id_item_id_pk", + "columns": ["tag_id", "item_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tags_to_outfits": { + "name": "tags_to_outfits", + "schema": "", + "columns": { + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "outfit_id": { + "name": "outfit_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "tagStatus", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'suggested'" + } + }, + "indexes": {}, + "foreignKeys": { + "tags_to_outfits_tag_id_tags_id_fk": { + "name": "tags_to_outfits_tag_id_tags_id_fk", + "tableFrom": "tags_to_outfits", + "tableTo": "tags", + "columnsFrom": ["tag_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tags_to_outfits_outfit_id_outfits_id_fk": { + "name": "tags_to_outfits_outfit_id_outfits_id_fk", + "tableFrom": "tags_to_outfits", + "tableTo": "outfits", + "columnsFrom": ["outfit_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "tags_to_outfits_tag_id_outfit_id_pk": { + "name": "tags_to_outfits_tag_id_outfit_id_pk", + "columns": ["tag_id", "outfit_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.itemStatus": { + "name": "itemStatus", + "schema": "public", + "values": ["available", "withheld", "retired"] + }, + "public.itemType": { + "name": "itemType", + "schema": "public", + "values": ["layer", "top", "bottom", "footwear", "accessory"] + }, + "public.tagStatus": { + "name": "tagStatus", + "schema": "public", + "values": ["manually_assigned", "suggested", "suggestion_accepted", "suggestion_rejected"] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/hono/src/drizzle/meta/_journal.json b/hono/src/drizzle/meta/_journal.json index 8ebfb21..bb8b08b 100644 --- a/hono/src/drizzle/meta/_journal.json +++ b/hono/src/drizzle/meta/_journal.json @@ -50,6 +50,13 @@ "when": 1743730809368, "tag": "0006_exotic_absorbing_man", "breakpoints": true + }, + { + "idx": 7, + "version": "7", + "when": 1761023578962, + "tag": "0007_concerned_nitro", + "breakpoints": true } ] } diff --git a/hono/src/schema.ts b/hono/src/schema.ts index 89bf9c6..095690d 100644 --- a/hono/src/schema.ts +++ b/hono/src/schema.ts @@ -1,9 +1,9 @@ import { createId } from '@paralleldrive/cuid2' import { relations, sql } from 'drizzle-orm' import { - boolean, check, date, + doublePrecision, pgEnum, pgTable, primaryKey, @@ -24,6 +24,12 @@ export const itemTypeEnum: [string, ...string[]] = [ ] export const itemTypeEnumPg = pgEnum('itemType', itemTypeEnum) +/** + * Item Status Enumeration + */ +export const itemStatusEnum: [string, ...string[]] = ['available', 'withheld', 'retired'] +export const itemStatusEnumPg = pgEnum('itemStatus', itemStatusEnum) + /** * Items */ @@ -36,7 +42,7 @@ export const items = pgTable('items', { photoUrl: text('photo_url'), type: itemTypeEnumPg('type').notNull(), rating: smallint('rating').notNull(), - isArchived: boolean('is_archived').notNull().default(false), + status: itemStatusEnumPg('status').notNull().default('available'), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), userId: text('user_id').notNull(), }) @@ -57,6 +63,8 @@ export const outfits = pgTable( .primaryKey(), rating: smallint('rating').notNull(), wearDate: date('wear_date', { mode: 'date' }), + locationLatitude: doublePrecision('location_latitude'), + locationLongitude: doublePrecision('location_longitude'), userId: text('user_id').notNull(), }, (table) => ({ diff --git a/hono/src/services/items.ts b/hono/src/services/items.ts index 8045c11..6554afc 100644 --- a/hono/src/services/items.ts +++ b/hono/src/services/items.ts @@ -6,7 +6,7 @@ import { createInsertSchema, createSelectSchema } from 'drizzle-zod' import { Hono } from 'hono' import { z } from 'zod' -import { itemTypeEnum, items } from '../schema' +import { itemStatusEnum, itemTypeEnum, items } from '../schema' import { requireAuth } from '../utils/auth' import type { AuthVariables } from '../utils/auth' import type { DBVariables } from '../utils/inject-db' @@ -18,6 +18,7 @@ const insertItemSchema = createInsertSchema(items, { photoUrl: z.string().url(), type: z.enum(itemTypeEnum), rating: z.number().min(0).max(4).default(2), + status: z.enum(itemStatusEnum).default('available'), }).omit({ id: true, createdAt: true, userId: true }) const selectItemSchema = createSelectSchema(items, { @@ -71,7 +72,7 @@ const getItemQuery = (db: DBVariables['db'], whereClause: SQL | undefin photoUrl: item.photoUrl, type: item.type, rating: item.rating, - isArchived: item.isArchived, + status: item.status, createdAt: item.createdAt, userId: item.userId, lastWornAt: item.itemsToOutfits.length @@ -111,12 +112,14 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() : eq(items.userId, userId) const itemsData = await getItemQuery(c.get('db'), whereClause).then((items) => { - // Sort by isArchived (non-archived first), then lastWornAt (nulls first), then name + // Sort by status (available first, then withheld, then retired), then lastWornAt (nulls first), then name const sortedItems = items.sort((a, b) => { - // First sort by archive status - if (a.isArchived !== b.isArchived) return a.isArchived ? 1 : -1 + // First sort by status + const statusOrder: Record = { available: 0, withheld: 1, retired: 2 } + const statusCompare = statusOrder[a.status] - statusOrder[b.status] + if (statusCompare !== 0) return statusCompare - // Then use the existing sort logic for items with the same archive status + // Then use the existing sort logic for items with the same status if (!a.lastWornAt && !b.lastWornAt) return a.name.localeCompare(b.name) if (!a.lastWornAt) return -1 if (!b.lastWornAt) return 1 @@ -201,7 +204,7 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() .put( '/:id', zValidator('param', selectItemSchema.pick({ id: true })), - zValidator('json', insertItemSchema), + zValidator('json', insertItemSchema.partial()), requireAuth, injectDB, async (c) => { @@ -219,38 +222,12 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() ...body, userId, }) - .where(eq(items.id, params.id)) + .where(and(eq(items.id, params.id), eq(items.userId, userId))) .returning() )[0] ) } ) - .patch( - '/archive/:id', - zValidator('param', selectItemSchema.pick({ id: true })), - zValidator('json', z.object({ isArchived: z.boolean() })), - requireAuth, - injectDB, - async (c) => { - const auth = c.get('auth') - const userId = auth?.userId || '' - const { id } = c.req.valid('param') - const { isArchived } = c.req.valid('json') - - const updatedItem = await c - .get('db') - .update(items) - .set({ isArchived }) - .where(and(eq(items.id, id), eq(items.userId, userId))) - .returning() - - if (!updatedItem.length) { - return c.json({ message: 'Item not found' }, 404) - } - - return c.json(updatedItem[0]) - } - ) .delete( '/:id', zValidator('param', selectItemSchema.pick({ id: true })), diff --git a/hono/src/services/outfits.ts b/hono/src/services/outfits.ts index ff93ab4..d1de835 100644 --- a/hono/src/services/outfits.ts +++ b/hono/src/services/outfits.ts @@ -15,6 +15,8 @@ import { VIRTUAL_TAGS, getApplicableVirtualTags, isVirtualTag } from './tags' const insertOutfitSchema = createInsertSchema(outfits, { rating: z.number().min(0).max(2).default(1), wearDate: z.coerce.date().optional(), + locationLatitude: z.number().min(-90).max(90).optional(), + locationLongitude: z.number().min(-180).max(180).optional(), }) .extend({ itemIdsTypes: z @@ -116,11 +118,11 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() const itemIds = body.itemIdsTypes.map((e) => e.id) if (itemIds.length > 0) { - // Find which of these items (if any) are currently archived - const archivedItems = await tx.query.items.findMany({ + // Find which of these items (if any) are currently withheld or retired + const unavailableItems = await tx.query.items.findMany({ where: and( inArray(items.id, itemIds), - eq(items.isArchived, true), + sql`items.status != 'available'`, eq(items.userId, userId) ), columns: { @@ -128,15 +130,15 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() }, }) - // If any archived items were found, unarchive them - if (archivedItems.length > 0) { - const archivedItemIds = archivedItems.map((item) => item.id) + // If any unavailable items were found, make them available + if (unavailableItems.length > 0) { + const unavailableItemIds = unavailableItems.map((item) => item.id) - // Unarchive the items + // Make the items available await tx .update(items) - .set({ isArchived: false }) - .where(inArray(items.id, archivedItemIds)) + .set({ status: 'available' }) + .where(inArray(items.id, unavailableItemIds)) } } @@ -212,11 +214,11 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() const virtualTag = isVirtualTagFilter ? VIRTUAL_TAGS[tagId!] : undefined const regularTagId = isVirtualTagFilter ? undefined : tagId - // STEP 1: Get all non-archived items with last worn dates in a single query + // STEP 1: Get all available items with last worn dates in a single query const allItems = await c.get('db').query.items.findMany({ where: and( eq(sql`items.user_id`, userId), - eq(items.isArchived, false) // Exclude archived items from suggestions + eq(items.status, 'available') // Exclude non-available items from suggestions ), columns: { id: true, @@ -225,16 +227,16 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() }, }) - // Get a list of archived item IDs for checking if outfits contain archived items - const archivedItems = await c.get('db').query.items.findMany({ - where: and(eq(sql`items.user_id`, userId), eq(items.isArchived, true)), + // Get a list of non-available item IDs for checking if outfits contain unavailable items + const unavailableItems = await c.get('db').query.items.findMany({ + where: and(eq(sql`items.user_id`, userId), sql`items.status != 'available'`), columns: { id: true, }, }) - // Create a Set of archived item IDs for efficient lookup - const archivedItemIds = new Set(archivedItems.map((item) => item.id)) + // Create a Set of unavailable item IDs for efficient lookup + const unavailableItemIds = new Set(unavailableItems.map((item) => item.id)) // Calculate recency threshold (min count of items per category) const wardrobeCounts = { @@ -371,14 +373,14 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() orderBy: (outfits, { desc }) => [desc(outfits.wearDate)], }) - // Filter out outfits that contain any archived items - const nonArchivedOutfits = eligibleOutfits.filter((outfit) => { - // Return true only if no items in the outfit are archived - return !outfit.itemsToOutfits.some((io) => archivedItemIds.has(io.itemId)) + // Filter out outfits that contain any unavailable items + const availableOutfits = eligibleOutfits.filter((outfit) => { + // Return true only if no items in the outfit are unavailable + return !outfit.itemsToOutfits.some((io) => unavailableItemIds.has(io.itemId)) }) - // If no eligible outfits after filtering archived items, return empty result - if (nonArchivedOutfits.length === 0) { + // If no eligible outfits after filtering unavailable items, return empty result + if (availableOutfits.length === 0) { return c.json({ suggestions: [], generated_at: today, @@ -387,14 +389,14 @@ const app = new Hono<{ Variables: AuthVariables & DBVariables }>() recency_threshold: recencyThresholds, last_page: true, algorithm_version: 'v2', - filter_applied: 'no_eligible_outfits_or_all_contain_archived_items', + filter_applied: 'no_eligible_outfits_or_all_contain_unavailable_items', }, }) } // Filter outfits to only include those with at least one layer/top, one bottom, and one footwear // And apply tag filter if provided - const completeOutfits = nonArchivedOutfits.filter((outfit) => { + const completeOutfits = availableOutfits.filter((outfit) => { const hasTopOrLayer = outfit.itemsToOutfits.some( (io) => io.itemType === 'top' || io.itemType === 'layer' ) diff --git a/hono/test/utils/factory/items.ts b/hono/test/utils/factory/items.ts index f9a45ff..07e8c0f 100644 --- a/hono/test/utils/factory/items.ts +++ b/hono/test/utils/factory/items.ts @@ -1,5 +1,6 @@ import { faker } from '@faker-js/faker' +import type { itemStatusEnum } from '../../../src/schema' import { itemTypeEnum, items } from '../../../src/schema' import { instance } from '../db' @@ -12,6 +13,7 @@ export interface Item { photoUrl: string type: ItemType rating: number + status: (typeof itemStatusEnum)[number] createdAt: Date userId: string lastWornAt: string | null @@ -24,6 +26,7 @@ export interface ItemAPI { photoUrl: string type: ItemType rating: number + status: (typeof itemStatusEnum)[number] createdAt: string userId: string lastWornAt?: string | null @@ -46,6 +49,9 @@ export class ItemFactory implements Item { this.rating = options?.rating ? (options.rating as number) : faker.number.int({ min: 0, max: 4 }) + this.status = options?.status + ? (options.status as (typeof itemStatusEnum)[number]) + : 'available' this.createdAt = options?.createdAt ? new Date(options.createdAt as Date) : new Date(faker.date.past().toISOString().split('T')[0]) @@ -80,6 +86,7 @@ export class ItemFactory implements Item { photoUrl: string type: ItemType rating: number + status: (typeof itemStatusEnum)[number] createdAt: Date userId: string lastWornAt: string | null diff --git a/next/package-lock.json b/next/package-lock.json index 4e19b18..7865fe5 100644 --- a/next/package-lock.json +++ b/next/package-lock.json @@ -4949,9 +4949,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001695", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz", - "integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==", + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "funding": [ { "type": "opencollective", diff --git a/next/src/app/(authenticated)/items/page.tsx b/next/src/app/(authenticated)/items/page.tsx index b0f9874..f340206 100644 --- a/next/src/app/(authenticated)/items/page.tsx +++ b/next/src/app/(authenticated)/items/page.tsx @@ -5,10 +5,11 @@ import { useState } from 'react' import { useItems } from '@/lib/client' import { useItemSearch } from '@/lib/hooks/useItemSearch' import { Card, CardContent } from '@/components/ui/card' -import { ItemListLoading } from '@/components/ItemListLoading' import { Item, itemTypeIcons } from '@/components/Item' import { Button } from '@/components/ui/button' -import { Archive, ArchiveRestore } from 'lucide-react' +import { Archive, ArchiveRestore, Ban } from 'lucide-react' +import type { ItemStatus } from '@/lib/types' +import { ITEM_STATUS } from '@/lib/types' import { ContextMenu, ContextMenuContent, @@ -20,7 +21,7 @@ import ItemsLoading from './loading' // Separate component for Items content to use with Suspense function ItemsContent() { - const { items, isLoading, archiveItem, mutate } = useItems() + const { items, isLoading, updateItemStatus, mutate } = useItems() const [selectedType, setSelectedType] = useState(null) const { @@ -33,20 +34,18 @@ function ItemsContent() { handleNewItem: baseHandleNewItem, } = useItemSearch({ items, - typeFilter: selectedType, - // No longer filtering by archive status in the hook - archiveFilter: null + typeFilter: selectedType }) - // Sort items to show archived items at the end + // Sort items to show available items first, then withheld, then retired const filteredItems = [...baseFilteredItems].sort((a, b) => { - // First sort by archive status (non-archived first) - if (a.isArchived !== b.isArchived) { - return a.isArchived ? 1 : -1; - } + // First sort by status (available first, then withheld, then retired) + const statusOrder = { [ITEM_STATUS.AVAILABLE]: 0, [ITEM_STATUS.WITHHELD]: 1, [ITEM_STATUS.RETIRED]: 2 } as const + const statusCompare = statusOrder[a.status as keyof typeof statusOrder] - statusOrder[b.status as keyof typeof statusOrder] + if (statusCompare !== 0) return statusCompare - // For non-archived items, sort by lastWornAt (oldest first) - if (!a.isArchived && !b.isArchived) { + // For items with the same status, sort by lastWornAt (oldest first) + if (a.status === ITEM_STATUS.AVAILABLE && b.status === ITEM_STATUS.AVAILABLE) { // Items without lastWornAt should be first (never worn) if (!a.lastWornAt && b.lastWornAt) return -1; if (a.lastWornAt && !b.lastWornAt) return 1; @@ -57,13 +56,13 @@ function ItemsContent() { } } - // If archive status is the same and other criteria don't apply, preserve original order + // If status is the same and other criteria don't apply, preserve original order return 0; }); // Function to determine which date category an item belongs to const getDateCategory = (item: typeof filteredItems[0]) => { - if (item.isArchived) return 'archived'; + if (item.status !== ITEM_STATUS.AVAILABLE) return item.status; if (!item.lastWornAt) return 'never'; const lastWorn = new Date(item.lastWornAt); @@ -96,7 +95,8 @@ function ItemsContent() { // Function to get a human-readable title for a category const getCategoryTitle = (category: string) => { - if (category === 'archived') return 'Archived Items'; + if (category === ITEM_STATUS.WITHHELD) return 'Withheld Items'; + if (category === ITEM_STATUS.RETIRED) return 'Retired Items'; if (category === 'never') return 'Never Worn'; if (category === 'last-week') return 'Worn in the Last Week'; if (category === 'this-month') { @@ -110,9 +110,10 @@ function ItemsContent() { // Sort categories in the desired order const getCategoryOrder = (category: string) => { - if (category === 'archived') return 1000; // Always at the end + if (category === ITEM_STATUS.RETIRED) return 1000; // Always at the end + if (category === ITEM_STATUS.WITHHELD) return 950; // Second to last - // Now order from oldest to newest for non-archived items + // Now order from oldest to newest for available items if (category === 'never') return 100; // First // For month-year categories, sort by date (oldest first) @@ -167,8 +168,8 @@ function ItemsContent() { } } - const handleArchiveToggle = async (itemId: string, currentStatus: boolean) => { - await archiveItem(itemId, !currentStatus) + const handleStatusChange = async (itemId: string, newStatus: ItemStatus) => { + await updateItemStatus(itemId, newStatus) } const handleNewItem = (itemId: string, itemType: string) => { @@ -244,7 +245,7 @@ function ItemsContent() {
  • @@ -257,21 +258,54 @@ function ItemsContent() { - handleArchiveToggle(item.id, item.isArchived)} - > - {item.isArchived ? ( - <> + {item.status === ITEM_STATUS.AVAILABLE && ( + <> + handleStatusChange(item.id, ITEM_STATUS.WITHHELD)} + > + + Withhold Item + + handleStatusChange(item.id, ITEM_STATUS.RETIRED)} + > + + Retire Item + + + )} + {item.status === ITEM_STATUS.WITHHELD && ( + <> + handleStatusChange(item.id, ITEM_STATUS.AVAILABLE)} + > - Unarchive Item - - ) : ( - <> + Make Available + + handleStatusChange(item.id, ITEM_STATUS.RETIRED)} + > - Archive Item - - )} - + Retire Item + + + )} + {item.status === ITEM_STATUS.RETIRED && ( + <> + handleStatusChange(item.id, ITEM_STATUS.AVAILABLE)} + > + + Make Available + + handleStatusChange(item.id, ITEM_STATUS.WITHHELD)} + > + + Withhold Item + + + )}
  • diff --git a/next/src/components/AddOutfitModal.tsx b/next/src/components/AddOutfitModal.tsx index b8c6bd2..02f8bc0 100644 --- a/next/src/components/AddOutfitModal.tsx +++ b/next/src/components/AddOutfitModal.tsx @@ -1,28 +1,25 @@ 'use client' import { useState, useEffect, useRef } from 'react' -import { Dialog, DialogContent, DialogClose, DialogTrigger, DialogTitle, DialogDescription } from "@/components/ui/dialog" +import { Dialog, DialogContent, DialogTrigger, DialogTitle, DialogDescription } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { PlusCircle, X, CalendarIcon, Loader2, SearchIcon, Lightbulb } from 'lucide-react' +import { PlusCircle, X, Loader2 } from 'lucide-react' import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { cn } from "@/lib/utils" import { format } from "date-fns" import { Calendar } from "@/components/ui/calendar" import { ScrollArea } from "@/components/ui/scroll-area" -import React from 'react' import { Item, itemTypeIcons } from '@/components/Item' import Rating from './ui/rating' import { Tag } from "@/components/ui/tag" import { client, useItems, useTags, useOutfits } from '@/lib/client' import { useAuth } from '@clerk/nextjs' import { ItemInlineSearch } from './ItemInlineSearch' -import { ItemsResponse } from '@/lib/client' +import { useLocation } from '@/lib/hooks/useLocation' interface AddOutfitModalProps { open?: boolean onOpenChange?: (open: boolean) => void - initialItems?: Array showTrigger?: boolean onSuccess?: () => void } @@ -40,6 +37,7 @@ export function AddOutfitModal({ } const { getToken } = useAuth() + const { data: locationData, status: locationStatus, requestLocation, clearLocation } = useLocation() const [open, setOpen] = useState(false) const [datePickerOpen, setDatePickerOpen] = useState(false) @@ -50,10 +48,10 @@ export function AddOutfitModal({ const [showDropdown, setShowDropdown] = useState(false) const searchInputRef = useRef(null) - const { items: allItems, isLoading: isItemsLoading, isError: isItemsError } = useItems() + const { items: allItems, isLoading: isItemsLoading } = useItems() const [selectedItems, setSelectedItems] = useState>([]) - const { tags, isLoading: isTagsLoading, isError: isTagsError } = useTags() + const { tags } = useTags() const [selectedTags, setSelectedTags] = useState([]) // Add state for highlighted index @@ -76,6 +74,11 @@ export function AddOutfitModal({ setSearchTerm('') setShowDropdown(false) + // Request location when modal opens + if (newOpen) { + requestLocation() + } + // Focus the search input when modal opens setTimeout(() => { searchInputRef.current?.focus() @@ -100,7 +103,11 @@ export function AddOutfitModal({ wearDate: date, rating: rating, itemIdsTypes: selectedItems.map(item => ({ id: item.id, itemType: item.type })), - tagIds: selectedTags + tagIds: selectedTags, + ...(locationData && { + locationLatitude: locationData.latitude, + locationLongitude: locationData.longitude, + }) } try { @@ -124,9 +131,11 @@ export function AddOutfitModal({ handleOpenChange(false) onSuccess?.() + } else { + console.error('Failed to create outfit via API:', res.status, await res.text()) } } catch (error) { - console.log(error) + console.error('Request Error:', error) } finally { setIsSubmitting(false) setSubmittingRating(null) @@ -410,6 +419,27 @@ export function AddOutfitModal({ )} + {/* Location indicator */} + {locationStatus !== 'denied' && ( + + )} {tags?.map((tag) => (
    @@ -41,7 +42,11 @@ export function Item({ item, itemType, isCoreItem = false, showLastWornAt = fals {isCoreItem && }

    - {item.isArchived ? Archived : item.brand || Unbranded} + {item.status !== ITEM_STATUS.AVAILABLE ? ( + {ITEM_STATUS_LABELS[item.status as keyof typeof ITEM_STATUS_LABELS]} + ) : ( + item.brand || Unbranded + )} {showLastWornAt && ( diff --git a/next/src/components/OutfitList.tsx b/next/src/components/OutfitList.tsx index 133dc31..e8b9e1e 100644 --- a/next/src/components/OutfitList.tsx +++ b/next/src/components/OutfitList.tsx @@ -2,7 +2,7 @@ import { useCallback, useRef } from 'react' import { Card, CardContent } from '@/components/ui/card' -import { Calendar, Star, Trash2 } from 'lucide-react' +import { Calendar, MapPin, Trash2 } from 'lucide-react' import { ItemList } from '@/components/ItemList' import OutfitListLoading from './OutfitListLoading' import Rating from '@/components/ui/rating' @@ -80,9 +80,12 @@ export default function OutfitList() {

    - + {outfit.wearDate ? formatDate(outfit.wearDate) : 'Never'} -
    + {outfit.locationLatitude && outfit.locationLongitude && ( + + )} +
    {outfit.tagsToOutfits.map((tagToOutfit) => { const tag = tags?.find(t => t.id === tagToOutfit.tagId) if (!tag) return null diff --git a/next/src/lib/client.ts b/next/src/lib/client.ts index 39f8038..ff06bf2 100644 --- a/next/src/lib/client.ts +++ b/next/src/lib/client.ts @@ -4,6 +4,7 @@ import type { InferRequestType, InferResponseType } from 'hono/client' import useSWR from 'swr' import useSWRInfinite from 'swr/infinite' import { useAuth } from '@clerk/nextjs' +import type { ItemStatus } from './types' export const client = hc(process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8787/') @@ -155,7 +156,7 @@ export function useSuggestedOutfits(tagId?: string) { export function useItems() { const { getToken } = useAuth() const $get = client.api.items.$get - const $patch = client.api.items.archive[':id'].$patch + const $put = client.api.items[':id'].$put const fetcher = (arg: InferRequestType) => async () => { const res = await $get(arg, { @@ -172,9 +173,9 @@ export function useItems() { fetcher({}) ) - const archiveItem = async (itemId: string, archive: boolean) => { + const updateItemStatus = async (itemId: string, status: ItemStatus) => { try { - const res = await $patch({ param: { id: itemId }, json: { isArchived: archive } }, { + const res = await $put({ param: { id: itemId }, json: { status } }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${await getToken()}` @@ -186,7 +187,7 @@ export function useItems() { } return res.ok } catch (error) { - console.error('Error updating item archive status:', error) + console.error('Error updating item status:', error) return false } } @@ -196,7 +197,7 @@ export function useItems() { isLoading, isError: error, mutate, - archiveItem + updateItemStatus } } diff --git a/next/src/lib/hooks/useItemSearch.ts b/next/src/lib/hooks/useItemSearch.ts index fae11e7..aadc5b9 100644 --- a/next/src/lib/hooks/useItemSearch.ts +++ b/next/src/lib/hooks/useItemSearch.ts @@ -1,11 +1,10 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useMemo } from 'react' import { ItemsResponse } from '@/lib/client' import { itemTypeIcons } from '@/components/Item' interface UseItemSearchProps { items: ItemsResponse['items'] typeFilter?: keyof typeof itemTypeIcons | null - archiveFilter?: boolean | null } interface UseItemSearchResult { @@ -23,65 +22,48 @@ interface UseItemSearchResult { export function useItemSearch({ items, - typeFilter = null, - archiveFilter = null + typeFilter = null }: UseItemSearchProps): UseItemSearchResult { const [searchTerm, setSearchTerm] = useState('') const [highlightedIndex, setHighlightedIndex] = useState(-1) const [addMode, setAddMode] = useState(false) - // Filter items based on search term, type filter, and archive filter - const filteredItems = items.filter(item => { - const typeMatch = typeFilter ? item.type === typeFilter : true - - // Archive match - only filter by archive status if archiveFilter is not null - const archiveMatch = archiveFilter === null ? true : (archiveFilter ? item.isArchived : !item.isArchived) - - // Search match - check if search term is in name, brand, or type - let searchMatch = true - if (searchTerm && !addMode) { - const searchTerms = searchTerm.toLowerCase().split(/\s+/) - const itemName = item.name.toLowerCase() - const itemBrand = (item.brand || '').toLowerCase() - const itemType = item.type.toLowerCase() + // Filter items based on search term and type filter + const filteredItems = useMemo(() => { + return items.filter(item => { + const typeMatch = typeFilter ? item.type === typeFilter : true - searchMatch = searchTerms.every(term => - itemName.includes(term) || - itemBrand.includes(term) || - itemType.includes(term) - ) - } - - return typeMatch && archiveMatch && searchMatch - }) - - // Automatically switch to add mode when no search results are found - useEffect(() => { - if (searchTerm && !addMode) { - const hasSearchResults = items.some(item => { - const typeMatch = typeFilter ? item.type === typeFilter : true - const archiveMatch = archiveFilter === null ? true : (archiveFilter ? item.isArchived : !item.isArchived) - + // Search match - check if search term is in name, brand, or type + let searchMatch = true + if (searchTerm && !addMode) { const searchTerms = searchTerm.toLowerCase().split(/\s+/) const itemName = item.name.toLowerCase() const itemBrand = (item.brand || '').toLowerCase() const itemType = item.type.toLowerCase() - const searchMatch = searchTerms.every(term => + searchMatch = searchTerms.every(term => itemName.includes(term) || itemBrand.includes(term) || itemType.includes(term) ) - - return typeMatch && archiveMatch && searchMatch - }) + } + + return typeMatch && searchMatch + }) + }, [items, typeFilter, searchTerm, addMode]) + + // Automatically switch to add mode when no search results are found + useEffect(() => { + if (searchTerm && !addMode) { + // Use the already computed filteredItems to check for results + const hasSearchResults = filteredItems.length > 0 // If we have a search term and no results, switch to add mode if (!hasSearchResults && searchTerm.trim().length >= 2) { setAddMode(true) } } - }, [searchTerm, items, typeFilter, archiveFilter, addMode]) + }, [searchTerm, addMode, filteredItems.length]) const handleSearchChange = (e: React.ChangeEvent) => { setSearchTerm(e.target.value) diff --git a/next/src/lib/hooks/useLocation.ts b/next/src/lib/hooks/useLocation.ts new file mode 100644 index 0000000..b8f4b0f --- /dev/null +++ b/next/src/lib/hooks/useLocation.ts @@ -0,0 +1,92 @@ +import { useState, useEffect, useCallback } from 'react' + +export interface LocationData { + latitude: number + longitude: number + accuracy?: number +} + +export type LocationStatus = 'idle' | 'loading' | 'success' | 'error' | 'denied' + +export interface LocationState { + data: LocationData | null + status: LocationStatus + error: string | null +} + +export function useLocation() { + const [state, setState] = useState({ + data: null, + status: 'idle', + error: null, + }) + + const requestLocation = useCallback(() => { + if (!navigator.geolocation) { + setState(prev => ({ + ...prev, + status: 'error', + error: 'Geolocation is not supported by this browser', + })) + return + } + + setState(prev => ({ ...prev, status: 'loading', error: null })) + + navigator.geolocation.getCurrentPosition( + (position) => { + setState({ + data: { + latitude: position.coords.latitude, + longitude: position.coords.longitude, + accuracy: position.coords.accuracy, + }, + status: 'success', + error: null, + }) + }, + (error) => { + let errorMessage = 'Unknown error occurred' + let status: LocationStatus = 'error' + + switch (error.code) { + case error.PERMISSION_DENIED: + errorMessage = 'Location access denied by user' + status = 'denied' + break + case error.POSITION_UNAVAILABLE: + errorMessage = 'Location information is unavailable' + break + case error.TIMEOUT: + errorMessage = 'Location request timed out' + break + } + + setState({ + data: null, + status, + error: errorMessage, + }) + }, + { + enableHighAccuracy: true, + timeout: 10000, + maximumAge: 300000, // 5 minutes + } + ) + }, []) + + const clearLocation = useCallback(() => { + setState({ + data: null, + status: 'idle', + error: null, + }) + }, []) + + return { + ...state, + requestLocation, + clearLocation, + } +} diff --git a/next/src/lib/types.ts b/next/src/lib/types.ts new file mode 100644 index 0000000..aefaa19 --- /dev/null +++ b/next/src/lib/types.ts @@ -0,0 +1,13 @@ +export type ItemStatus = 'available' | 'withheld' | 'retired' + +export const ITEM_STATUS = { + AVAILABLE: 'available' as const, + WITHHELD: 'withheld' as const, + RETIRED: 'retired' as const, +} as const + +export const ITEM_STATUS_LABELS = { + [ITEM_STATUS.AVAILABLE]: 'Available', + [ITEM_STATUS.WITHHELD]: 'Withheld', + [ITEM_STATUS.RETIRED]: 'Retired', +} as const