diff --git a/.env b/.env new file mode 100644 index 0000000..719d057 --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ +# This is just an example file, +# replace it in production environments. + +DATABASE_PATH=./data/sqlite.db \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adbb97d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +data/ \ No newline at end of file diff --git a/README.md b/README.md index 5564048..02f382f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # anyhealth -Anyhealth是一款私人健康管理系统。 \ No newline at end of file +Anyhealth是一款私人健康管理系统。 diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..48323bc --- /dev/null +++ b/deno.json @@ -0,0 +1,19 @@ +{ + "tasks": { + "dev": "deno run -A src/main.ts", + "drizzle:push": "mkdir -p data && deno run -A npm:drizzle-kit push", + "drizzle:generate": "mkdir -p data && deno run -A npm:drizzle-kit generate", + "drizzle:migrate": "mkdir -p data && deno run -A npm:drizzle-kit migrate" + }, + "imports": { + "@hono/hono": "jsr:@hono/hono@^4.12.23", + "jose": "npm:jose@^6.2.2", + "@libsql/client": "npm:@libsql/client@^0.17.3", + "dotenv": "npm:dotenv@^17.4.2", + "drizzle-kit": "npm:drizzle-kit@^0.31.10", + "drizzle-orm": "npm:drizzle-orm@^0.45.2" + }, + "fmt": { + "indentWidth": 4 + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..04c7963 --- /dev/null +++ b/deno.lock @@ -0,0 +1,819 @@ +{ + "version": "5", + "specifiers": { + "jsr:@hono/hono@^4.12.23": "4.12.23", + "npm:@libsql/client@~0.17.3": "0.17.3", + "npm:create-hono@latest": "0.19.4", + "npm:dotenv@^17.4.2": "17.4.2", + "npm:drizzle-kit@*": "0.31.10", + "npm:drizzle-kit@~0.31.10": "0.31.10", + "npm:drizzle-orm@~0.45.2": "0.45.2_@libsql+client@0.17.3", + "npm:jose@^6.2.2": "6.2.3" + }, + "jsr": { + "@hono/hono@4.12.23": { + "integrity": "9d9f3da498f69c311b5f92d973eb3b8ebc973b5fd2b4972781b556e07818a745" + } + }, + "npm": { + "@drizzle-team/brocli@0.10.2": { + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==", + "tarball": "https://registry.npmmirror.com/@drizzle-team/brocli/-/brocli-0.10.2.tgz" + }, + "@esbuild-kit/core-utils@3.3.2": { + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "dependencies": [ + "esbuild@0.18.20", + "source-map-support" + ], + "deprecated": true, + "tarball": "https://registry.npmmirror.com/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz" + }, + "@esbuild-kit/esm-loader@2.6.5": { + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "dependencies": [ + "@esbuild-kit/core-utils", + "get-tsconfig" + ], + "deprecated": true, + "tarball": "https://registry.npmmirror.com/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz" + }, + "@esbuild/aix-ppc64@0.25.12": { + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "os": ["aix"], + "cpu": ["ppc64"], + "tarball": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz" + }, + "@esbuild/aix-ppc64@0.28.0": { + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "os": ["aix"], + "cpu": ["ppc64"], + "tarball": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz" + }, + "@esbuild/android-arm64@0.18.20": { + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "os": ["android"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz" + }, + "@esbuild/android-arm64@0.25.12": { + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "os": ["android"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz" + }, + "@esbuild/android-arm64@0.28.0": { + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "os": ["android"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz" + }, + "@esbuild/android-arm@0.18.20": { + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "os": ["android"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz" + }, + "@esbuild/android-arm@0.25.12": { + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "os": ["android"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz" + }, + "@esbuild/android-arm@0.28.0": { + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "os": ["android"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.28.0.tgz" + }, + "@esbuild/android-x64@0.18.20": { + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "os": ["android"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz" + }, + "@esbuild/android-x64@0.25.12": { + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "os": ["android"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz" + }, + "@esbuild/android-x64@0.28.0": { + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "os": ["android"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.28.0.tgz" + }, + "@esbuild/darwin-arm64@0.18.20": { + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "os": ["darwin"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz" + }, + "@esbuild/darwin-arm64@0.25.12": { + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "os": ["darwin"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz" + }, + "@esbuild/darwin-arm64@0.28.0": { + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "os": ["darwin"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz" + }, + "@esbuild/darwin-x64@0.18.20": { + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "os": ["darwin"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz" + }, + "@esbuild/darwin-x64@0.25.12": { + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "os": ["darwin"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz" + }, + "@esbuild/darwin-x64@0.28.0": { + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "os": ["darwin"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz" + }, + "@esbuild/freebsd-arm64@0.18.20": { + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "os": ["freebsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz" + }, + "@esbuild/freebsd-arm64@0.25.12": { + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "os": ["freebsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz" + }, + "@esbuild/freebsd-arm64@0.28.0": { + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "os": ["freebsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz" + }, + "@esbuild/freebsd-x64@0.18.20": { + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "os": ["freebsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz" + }, + "@esbuild/freebsd-x64@0.25.12": { + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "os": ["freebsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz" + }, + "@esbuild/freebsd-x64@0.28.0": { + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "os": ["freebsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz" + }, + "@esbuild/linux-arm64@0.18.20": { + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "os": ["linux"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz" + }, + "@esbuild/linux-arm64@0.25.12": { + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "os": ["linux"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz" + }, + "@esbuild/linux-arm64@0.28.0": { + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "os": ["linux"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz" + }, + "@esbuild/linux-arm@0.18.20": { + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "os": ["linux"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz" + }, + "@esbuild/linux-arm@0.25.12": { + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "os": ["linux"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz" + }, + "@esbuild/linux-arm@0.28.0": { + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "os": ["linux"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz" + }, + "@esbuild/linux-ia32@0.18.20": { + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "os": ["linux"], + "cpu": ["ia32"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz" + }, + "@esbuild/linux-ia32@0.25.12": { + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "os": ["linux"], + "cpu": ["ia32"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz" + }, + "@esbuild/linux-ia32@0.28.0": { + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "os": ["linux"], + "cpu": ["ia32"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz" + }, + "@esbuild/linux-loong64@0.18.20": { + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "os": ["linux"], + "cpu": ["loong64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz" + }, + "@esbuild/linux-loong64@0.25.12": { + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "os": ["linux"], + "cpu": ["loong64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz" + }, + "@esbuild/linux-loong64@0.28.0": { + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "os": ["linux"], + "cpu": ["loong64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz" + }, + "@esbuild/linux-mips64el@0.18.20": { + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "os": ["linux"], + "cpu": ["mips64el"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz" + }, + "@esbuild/linux-mips64el@0.25.12": { + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "os": ["linux"], + "cpu": ["mips64el"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz" + }, + "@esbuild/linux-mips64el@0.28.0": { + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "os": ["linux"], + "cpu": ["mips64el"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz" + }, + "@esbuild/linux-ppc64@0.18.20": { + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "os": ["linux"], + "cpu": ["ppc64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz" + }, + "@esbuild/linux-ppc64@0.25.12": { + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "os": ["linux"], + "cpu": ["ppc64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz" + }, + "@esbuild/linux-ppc64@0.28.0": { + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "os": ["linux"], + "cpu": ["ppc64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz" + }, + "@esbuild/linux-riscv64@0.18.20": { + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "os": ["linux"], + "cpu": ["riscv64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz" + }, + "@esbuild/linux-riscv64@0.25.12": { + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "os": ["linux"], + "cpu": ["riscv64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz" + }, + "@esbuild/linux-riscv64@0.28.0": { + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "os": ["linux"], + "cpu": ["riscv64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz" + }, + "@esbuild/linux-s390x@0.18.20": { + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "os": ["linux"], + "cpu": ["s390x"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz" + }, + "@esbuild/linux-s390x@0.25.12": { + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "os": ["linux"], + "cpu": ["s390x"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz" + }, + "@esbuild/linux-s390x@0.28.0": { + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "os": ["linux"], + "cpu": ["s390x"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz" + }, + "@esbuild/linux-x64@0.18.20": { + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "os": ["linux"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz" + }, + "@esbuild/linux-x64@0.25.12": { + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "os": ["linux"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz" + }, + "@esbuild/linux-x64@0.28.0": { + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "os": ["linux"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz" + }, + "@esbuild/netbsd-arm64@0.25.12": { + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "os": ["netbsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz" + }, + "@esbuild/netbsd-arm64@0.28.0": { + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "os": ["netbsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz" + }, + "@esbuild/netbsd-x64@0.18.20": { + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "os": ["netbsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz" + }, + "@esbuild/netbsd-x64@0.25.12": { + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "os": ["netbsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz" + }, + "@esbuild/netbsd-x64@0.28.0": { + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "os": ["netbsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz" + }, + "@esbuild/openbsd-arm64@0.25.12": { + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "os": ["openbsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz" + }, + "@esbuild/openbsd-arm64@0.28.0": { + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "os": ["openbsd"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz" + }, + "@esbuild/openbsd-x64@0.18.20": { + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "os": ["openbsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz" + }, + "@esbuild/openbsd-x64@0.25.12": { + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "os": ["openbsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz" + }, + "@esbuild/openbsd-x64@0.28.0": { + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "os": ["openbsd"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz" + }, + "@esbuild/openharmony-arm64@0.25.12": { + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "os": ["openharmony"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz" + }, + "@esbuild/openharmony-arm64@0.28.0": { + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "os": ["openharmony"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz" + }, + "@esbuild/sunos-x64@0.18.20": { + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "os": ["sunos"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz" + }, + "@esbuild/sunos-x64@0.25.12": { + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "os": ["sunos"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz" + }, + "@esbuild/sunos-x64@0.28.0": { + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "os": ["sunos"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz" + }, + "@esbuild/win32-arm64@0.18.20": { + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "os": ["win32"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz" + }, + "@esbuild/win32-arm64@0.25.12": { + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "os": ["win32"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz" + }, + "@esbuild/win32-arm64@0.28.0": { + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "os": ["win32"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz" + }, + "@esbuild/win32-ia32@0.18.20": { + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "os": ["win32"], + "cpu": ["ia32"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz" + }, + "@esbuild/win32-ia32@0.25.12": { + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "os": ["win32"], + "cpu": ["ia32"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz" + }, + "@esbuild/win32-ia32@0.28.0": { + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "os": ["win32"], + "cpu": ["ia32"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz" + }, + "@esbuild/win32-x64@0.18.20": { + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "os": ["win32"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz" + }, + "@esbuild/win32-x64@0.25.12": { + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "os": ["win32"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz" + }, + "@esbuild/win32-x64@0.28.0": { + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "os": ["win32"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz" + }, + "@libsql/client@0.17.3": { + "integrity": "sha512-HXk9wiAoJbKFbyBH4O+aEhN6ir5ERXuXvwE5OD2eR4/5RUa3Pw/8L9zrnVdU+iNJitRvisPWaIwmhkO3bH7giA==", + "dependencies": [ + "@libsql/core", + "@libsql/hrana-client", + "js-base64", + "libsql", + "promise-limit" + ], + "tarball": "https://registry.npmmirror.com/@libsql/client/-/client-0.17.3.tgz" + }, + "@libsql/core@0.17.3": { + "integrity": "sha512-2UjK1i7JBkMduJo4WdvvBxMMvVJ31pArBZNONyz/GCJJAH+1UHat2X6vn10S/WpY5fKzIT98WqYFl2vzWRLOfg==", + "dependencies": [ + "js-base64" + ], + "tarball": "https://registry.npmmirror.com/@libsql/core/-/core-0.17.3.tgz" + }, + "@libsql/darwin-arm64@0.5.29": { + "integrity": "sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==", + "os": ["darwin"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@libsql/darwin-arm64/-/darwin-arm64-0.5.29.tgz" + }, + "@libsql/darwin-x64@0.5.29": { + "integrity": "sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==", + "os": ["darwin"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@libsql/darwin-x64/-/darwin-x64-0.5.29.tgz" + }, + "@libsql/hrana-client@0.10.0": { + "integrity": "sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==", + "dependencies": [ + "@libsql/isomorphic-ws", + "js-base64" + ], + "tarball": "https://registry.npmmirror.com/@libsql/hrana-client/-/hrana-client-0.10.0.tgz" + }, + "@libsql/isomorphic-ws@0.1.5": { + "integrity": "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==", + "dependencies": [ + "@types/ws", + "ws" + ], + "tarball": "https://registry.npmmirror.com/@libsql/isomorphic-ws/-/isomorphic-ws-0.1.5.tgz" + }, + "@libsql/linux-arm-gnueabihf@0.5.29": { + "integrity": "sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==", + "os": ["linux"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@libsql/linux-arm-gnueabihf/-/linux-arm-gnueabihf-0.5.29.tgz" + }, + "@libsql/linux-arm-musleabihf@0.5.29": { + "integrity": "sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==", + "os": ["linux"], + "cpu": ["arm"], + "tarball": "https://registry.npmmirror.com/@libsql/linux-arm-musleabihf/-/linux-arm-musleabihf-0.5.29.tgz" + }, + "@libsql/linux-arm64-gnu@0.5.29": { + "integrity": "sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==", + "os": ["linux"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@libsql/linux-arm64-gnu/-/linux-arm64-gnu-0.5.29.tgz" + }, + "@libsql/linux-arm64-musl@0.5.29": { + "integrity": "sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==", + "os": ["linux"], + "cpu": ["arm64"], + "tarball": "https://registry.npmmirror.com/@libsql/linux-arm64-musl/-/linux-arm64-musl-0.5.29.tgz" + }, + "@libsql/linux-x64-gnu@0.5.29": { + "integrity": "sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==", + "os": ["linux"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@libsql/linux-x64-gnu/-/linux-x64-gnu-0.5.29.tgz" + }, + "@libsql/linux-x64-musl@0.5.29": { + "integrity": "sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==", + "os": ["linux"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@libsql/linux-x64-musl/-/linux-x64-musl-0.5.29.tgz" + }, + "@libsql/win32-x64-msvc@0.5.29": { + "integrity": "sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==", + "os": ["win32"], + "cpu": ["x64"], + "tarball": "https://registry.npmmirror.com/@libsql/win32-x64-msvc/-/win32-x64-msvc-0.5.29.tgz" + }, + "@neon-rs/load@0.0.4": { + "integrity": "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==", + "tarball": "https://registry.npmmirror.com/@neon-rs/load/-/load-0.0.4.tgz" + }, + "@types/node@25.9.2": { + "integrity": "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==", + "dependencies": [ + "undici-types" + ], + "tarball": "https://registry.npmmirror.com/@types/node/-/node-25.9.2.tgz" + }, + "@types/ws@8.18.1": { + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dependencies": [ + "@types/node" + ], + "tarball": "https://registry.npmmirror.com/@types/ws/-/ws-8.18.1.tgz" + }, + "buffer-from@1.1.2": { + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "tarball": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz" + }, + "create-hono@0.19.4": { + "integrity": "sha512-0Kes3aNRqez5hv8YOqL2GQS6qdlpe7f9JuxTdj4xU4FBCo7isqoQJBCgI6pzjatvlLZB0ftT61GzvSVZF2VIBg==", + "bin": true, + "tarball": "https://registry.npmmirror.com/create-hono/-/create-hono-0.19.4.tgz" + }, + "detect-libc@2.0.2": { + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "tarball": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.2.tgz" + }, + "dotenv@17.4.2": { + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "tarball": "https://registry.npmmirror.com/dotenv/-/dotenv-17.4.2.tgz" + }, + "drizzle-kit@0.31.10": { + "integrity": "sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==", + "dependencies": [ + "@drizzle-team/brocli", + "@esbuild-kit/esm-loader", + "esbuild@0.25.12", + "tsx" + ], + "bin": true, + "tarball": "https://registry.npmmirror.com/drizzle-kit/-/drizzle-kit-0.31.10.tgz" + }, + "drizzle-orm@0.45.2_@libsql+client@0.17.3": { + "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", + "dependencies": [ + "@libsql/client" + ], + "optionalPeers": [ + "@libsql/client" + ], + "tarball": "https://registry.npmmirror.com/drizzle-orm/-/drizzle-orm-0.45.2.tgz" + }, + "esbuild@0.18.20": { + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "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" + ], + "scripts": true, + "bin": true, + "tarball": "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz" + }, + "esbuild@0.25.12": { + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "optionalDependencies": [ + "@esbuild/aix-ppc64@0.25.12", + "@esbuild/android-arm@0.25.12", + "@esbuild/android-arm64@0.25.12", + "@esbuild/android-x64@0.25.12", + "@esbuild/darwin-arm64@0.25.12", + "@esbuild/darwin-x64@0.25.12", + "@esbuild/freebsd-arm64@0.25.12", + "@esbuild/freebsd-x64@0.25.12", + "@esbuild/linux-arm@0.25.12", + "@esbuild/linux-arm64@0.25.12", + "@esbuild/linux-ia32@0.25.12", + "@esbuild/linux-loong64@0.25.12", + "@esbuild/linux-mips64el@0.25.12", + "@esbuild/linux-ppc64@0.25.12", + "@esbuild/linux-riscv64@0.25.12", + "@esbuild/linux-s390x@0.25.12", + "@esbuild/linux-x64@0.25.12", + "@esbuild/netbsd-arm64@0.25.12", + "@esbuild/netbsd-x64@0.25.12", + "@esbuild/openbsd-arm64@0.25.12", + "@esbuild/openbsd-x64@0.25.12", + "@esbuild/openharmony-arm64@0.25.12", + "@esbuild/sunos-x64@0.25.12", + "@esbuild/win32-arm64@0.25.12", + "@esbuild/win32-ia32@0.25.12", + "@esbuild/win32-x64@0.25.12" + ], + "scripts": true, + "bin": true, + "tarball": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.12.tgz" + }, + "esbuild@0.28.0": { + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "optionalDependencies": [ + "@esbuild/aix-ppc64@0.28.0", + "@esbuild/android-arm@0.28.0", + "@esbuild/android-arm64@0.28.0", + "@esbuild/android-x64@0.28.0", + "@esbuild/darwin-arm64@0.28.0", + "@esbuild/darwin-x64@0.28.0", + "@esbuild/freebsd-arm64@0.28.0", + "@esbuild/freebsd-x64@0.28.0", + "@esbuild/linux-arm@0.28.0", + "@esbuild/linux-arm64@0.28.0", + "@esbuild/linux-ia32@0.28.0", + "@esbuild/linux-loong64@0.28.0", + "@esbuild/linux-mips64el@0.28.0", + "@esbuild/linux-ppc64@0.28.0", + "@esbuild/linux-riscv64@0.28.0", + "@esbuild/linux-s390x@0.28.0", + "@esbuild/linux-x64@0.28.0", + "@esbuild/netbsd-arm64@0.28.0", + "@esbuild/netbsd-x64@0.28.0", + "@esbuild/openbsd-arm64@0.28.0", + "@esbuild/openbsd-x64@0.28.0", + "@esbuild/openharmony-arm64@0.28.0", + "@esbuild/sunos-x64@0.28.0", + "@esbuild/win32-arm64@0.28.0", + "@esbuild/win32-ia32@0.28.0", + "@esbuild/win32-x64@0.28.0" + ], + "scripts": true, + "bin": true, + "tarball": "https://registry.npmmirror.com/esbuild/-/esbuild-0.28.0.tgz" + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "os": ["darwin"], + "scripts": true, + "tarball": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz" + }, + "get-tsconfig@4.14.0": { + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dependencies": [ + "resolve-pkg-maps" + ], + "tarball": "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.14.0.tgz" + }, + "jose@6.2.3": { + "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "tarball": "https://registry.npmmirror.com/jose/-/jose-6.2.3.tgz" + }, + "js-base64@3.7.8": { + "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", + "tarball": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.8.tgz" + }, + "libsql@0.5.29": { + "integrity": "sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==", + "dependencies": [ + "@neon-rs/load", + "detect-libc" + ], + "optionalDependencies": [ + "@libsql/darwin-arm64", + "@libsql/darwin-x64", + "@libsql/linux-arm-gnueabihf", + "@libsql/linux-arm-musleabihf", + "@libsql/linux-arm64-gnu", + "@libsql/linux-arm64-musl", + "@libsql/linux-x64-gnu", + "@libsql/linux-x64-musl", + "@libsql/win32-x64-msvc" + ], + "os": ["darwin", "linux", "win32"], + "cpu": ["x64", "arm64", "wasm32", "arm"], + "tarball": "https://registry.npmmirror.com/libsql/-/libsql-0.5.29.tgz" + }, + "promise-limit@2.7.0": { + "integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==", + "tarball": "https://registry.npmmirror.com/promise-limit/-/promise-limit-2.7.0.tgz" + }, + "resolve-pkg-maps@1.0.0": { + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "tarball": "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" + }, + "source-map-support@0.5.21": { + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": [ + "buffer-from", + "source-map" + ], + "tarball": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz" + }, + "source-map@0.6.1": { + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "tarball": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz" + }, + "tsx@4.22.4": { + "integrity": "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==", + "dependencies": [ + "esbuild@0.28.0" + ], + "optionalDependencies": [ + "fsevents" + ], + "bin": true, + "tarball": "https://registry.npmmirror.com/tsx/-/tsx-4.22.4.tgz" + }, + "undici-types@7.24.6": { + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "tarball": "https://registry.npmmirror.com/undici-types/-/undici-types-7.24.6.tgz" + }, + "ws@8.21.0": { + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "tarball": "https://registry.npmmirror.com/ws/-/ws-8.21.0.tgz" + } + }, + "workspace": { + "dependencies": [ + "jsr:@hono/hono@^4.12.23", + "npm:@libsql/client@~0.17.3", + "npm:dotenv@^17.4.2", + "npm:drizzle-kit@~0.31.10", + "npm:drizzle-orm@~0.45.2", + "npm:jose@^6.2.2" + ] + } +} diff --git a/drizzle.config.ts b/drizzle.config.ts new file mode 100644 index 0000000..3b955bb --- /dev/null +++ b/drizzle.config.ts @@ -0,0 +1,11 @@ +import "dotenv/config"; +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + out: "./drizzle", + schema: "./src/db/schema.ts", + dialect: "sqlite", + dbCredentials: { + url: `file:${process.env.DATABASE_PATH!}`, + }, +}); diff --git a/drizzle/0000_talented_young_avengers.sql b/drizzle/0000_talented_young_avengers.sql new file mode 100644 index 0000000..5b4a9d4 --- /dev/null +++ b/drizzle/0000_talented_young_avengers.sql @@ -0,0 +1,4 @@ +CREATE TABLE `metas` ( + `key` text PRIMARY KEY NOT NULL, + `value` text +); diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json new file mode 100644 index 0000000..7b5a7ce --- /dev/null +++ b/drizzle/meta/0000_snapshot.json @@ -0,0 +1,42 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "345f884f-f61d-47b9-89cd-8aa53c2ed828", + "prevId": "00000000-0000-0000-0000-000000000000", + "tables": { + "metas": { + "name": "metas", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json new file mode 100644 index 0000000..323baf0 --- /dev/null +++ b/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "sqlite", + "entries": [ + { + "idx": 0, + "version": "6", + "when": 1780835325557, + "tag": "0000_talented_young_avengers", + "breakpoints": true + } + ] +} diff --git a/src/db/schema.ts b/src/db/schema.ts new file mode 100644 index 0000000..c5ba4f1 --- /dev/null +++ b/src/db/schema.ts @@ -0,0 +1,6 @@ +import { sqliteTable, text } from "drizzle-orm/sqlite-core"; + +export const metasTable = sqliteTable("metas", { + key: text().primaryKey(), + value: text(), +}); diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..96c2bc3 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,112 @@ +import "dotenv/config"; +import { drizzle } from "drizzle-orm/libsql"; +import { eq } from "drizzle-orm"; +import { createClient } from "@libsql/client"; +import { SignJWT } from "jose"; + +import { Hono } from "@hono/hono"; +import { commonResponse } from "./utils/response.ts"; +import { hashPassword, verifyPassword } from "./utils/crypto.ts"; +import { metasTable } from "./db/schema.ts"; + +const client = createClient({ + url: `file:${process.env.DATABASE_PATH!}`, +}); +const db = drizzle(client); + +const JWT_SECRET = crypto.getRandomValues(new Uint8Array(32)); + +async function initDefaultUser() { + const row = await db + .select() + .from(metasTable) + .where(eq(metasTable.key, "userinfo_username")) + .get(); + if (row) return; + + const usernameHash = await hashPassword("ah"); + const passwordHash = await hashPassword("123456"); + + await db + .insert(metasTable) + .values([ + { key: "userinfo_username", value: usernameHash }, + { key: "userinfo_password", value: passwordHash }, + ]) + .run(); + console.log("Default user created (username: ah, password: 123456)"); +} + +await initDefaultUser(); + +const app = new Hono(); + +app.get("/", (c) => { + return commonResponse(c, true, 200, { "hint": "Hello! But nothing here." }); +}); +app.get("/ping", (c) => { + return commonResponse(c, true, 200, {}); +}); + +app.post("/authenticate", async (c) => { + const body = await c.req.json<{ username?: string; password?: string }>(); + if (!body.username || !body.password) { + return commonResponse( + c, + false, + 400, + {}, + "Missing username or password", + ); + } + + const storedUsername = await db + .select() + .from(metasTable) + .where(eq(metasTable.key, "userinfo_username")) + .get(); + const storedPassword = await db + .select() + .from(metasTable) + .where(eq(metasTable.key, "userinfo_password")) + .get(); + + if (!storedUsername?.value || !storedPassword?.value) { + return commonResponse(c, false, 500, {}, "User not configured"); + } + + const usernameValid = await verifyPassword( + body.username, + storedUsername.value, + ); + if (!usernameValid) { + return commonResponse(c, false, 401, {}, "Invalid credentials"); + } + + const passwordValid = await verifyPassword( + body.password, + storedPassword.value, + ); + if (!passwordValid) { + return commonResponse(c, false, 401, {}, "Invalid credentials"); + } + + const jwt = await new SignJWT({ username: body.username }) + .setProtectedHeader({ alg: "HS256" }) + .setIssuedAt() + .setExpirationTime("24h") + .sign(JWT_SECRET); + + return commonResponse(c, true, 200, { token: jwt }); +}); + +Deno.serve(app.fetch); + +const handleExit = () => { + console.log("Closing database connection..."); + db.$client.close(); + console.log("Disconnected."); + process.exit(0); +}; +process.on("SIGINT", handleExit); +process.on("SIGTERM", handleExit); diff --git a/src/utils/crypto.ts b/src/utils/crypto.ts new file mode 100644 index 0000000..3730dc7 --- /dev/null +++ b/src/utils/crypto.ts @@ -0,0 +1,60 @@ +const ITERATIONS = 2000; +const SALT_LENGTH = 16; +const HASH_LENGTH = 64; + +function toHex(buffer: ArrayBuffer): string { + return Array.from(new Uint8Array(buffer)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); +} + +function fromHex(hex: string): Uint8Array { + const bytes = new Uint8Array(hex.length / 2); + for (let i = 0; i < hex.length; i += 2) { + bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); + } + return bytes; +} + +async function deriveKey( + password: string, + salt: Uint8Array, +): Promise { + const encoder = new TextEncoder(); + const keyMaterial = await crypto.subtle.importKey( + "raw", + encoder.encode(password), + { name: "PBKDF2" }, + false, + ["deriveBits"], + ); + return crypto.subtle.deriveBits( + { + name: "PBKDF2", + hash: "SHA-256", + salt, + iterations: ITERATIONS, + }, + keyMaterial, + HASH_LENGTH * 8, + ); +} + +export async function hashPassword(password: string): Promise { + const salt = crypto.getRandomValues( + new Uint8Array(SALT_LENGTH) as Uint8Array, + ); + const hash = await deriveKey(password, salt); + return `${toHex(salt.buffer)}:${toHex(hash)}`; +} + +export async function verifyPassword( + password: string, + stored: string, +): Promise { + const [saltHex, hashHex] = stored.split(":"); + if (!saltHex || !hashHex) return false; + const salt = fromHex(saltHex); + const derived = await deriveKey(password, salt); + return toHex(derived) === hashHex; +} diff --git a/src/utils/response.ts b/src/utils/response.ts new file mode 100644 index 0000000..96853a3 --- /dev/null +++ b/src/utils/response.ts @@ -0,0 +1,16 @@ +import { Context } from "@hono/hono"; +import { ContentfulStatusCode } from "@hono/hono/utils/http-status"; + +export function commonResponse( + c: Context, + ok: boolean, + status: ContentfulStatusCode, + data: object, + message: string | null = null, +) { + return c.json({ + ok, + data, + message, + }, status); +}