diff --git a/.prettierignore b/.prettierignore index fb54f00..0415cce 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,4 +7,4 @@ out .serverless # Serverless folder (has its own config) -serverless/ +#serverless/ diff --git a/serverless/README.md b/serverless/README.md index e73cbc1..6cf0e40 100644 --- a/serverless/README.md +++ b/serverless/README.md @@ -53,6 +53,97 @@ sls deploy --stage dev sls deploy --stage prod ``` +## RDS + Drizzle (Postgres) + +This project provisions a **private** Postgres RDS instance and the networking needed for Lambdas to reach it. + +### What gets created + +Defined in `serverless.yml`: + +- A dedicated VPC with 2 public subnets + 2 private subnets +- A NAT Gateway for private-subnet egress +- Security groups: + - Lambda SG (egress all) + - RDS SG (allows inbound `5432` only from the Lambda SG) +- An RDS Postgres instance: + - `DeletionProtection: true` + - `DeletionPolicy: Snapshot` / `UpdateReplacePolicy: Snapshot` + - `AutoMinorVersionUpgrade: true` (minor updates) + - Not publicly accessible +- An RDS Proxy in the same VPC (Lambdas connect to the proxy, proxy connects to RDS) +- A Secrets Manager secret for the RDS master user (generated password) + +Note: RDS + NAT Gateway incur AWS costs. + +### Drizzle files + +- Schema: `src/db/schema/**/*.ts` +- Drizzle config: `drizzle.config.ts` +- Generated migrations (SQL): `drizzle/` (packaged for Lambda) + +### Install deps + +```bash +cd serverless +npm install +``` + +### Generate a migration (no DB connection required) + +Drizzle can generate SQL migrations by diffing your schema files. + +```bash +cd serverless +npm run db:generate +``` + +This writes SQL into `serverless/drizzle/`. + +### Deploy the database + +```bash +cd serverless +sls deploy --stage dev +``` + +RDS creation can take several minutes. + +### Apply migrations (recommended: run inside AWS) + +Because the RDS instance is in private subnets, it is not directly reachable from your laptop by default. +The repo includes an internal migration Lambda (`dbMigrate`) that runs in the same VPC as the database. + +```bash +cd serverless +sls invoke -f dbMigrate --stage dev +``` + +### Sanity check connectivity + +```bash +cd serverless +sls invoke -f dbPing --stage dev +``` + +### Local migrations (optional) + +If you set up network access to the private RDS instance (e.g., via Client VPN or an SSM tunnel through a bastion host), you can run Drizzle migrations locally: + +```bash +export DATABASE_URL='postgres://USER:PASSWORD@HOST:5432/esdp' +npm run db:migrate +``` + +### Deletion protection behavior + +- `sls remove` will **not** be able to delete the DB instance while deletion protection is enabled. +- To intentionally remove it later, you must first disable deletion protection in `serverless.yml` and redeploy, then remove the stack. + +### Stage-specific DB name + +The Postgres database name comes from the stage param `db_name` in `serverless.yml` (e.g. `esdpdev`, `esdpalpha`, `esdpbeta`, `esdpprod`). + ## Local Development ```bash diff --git a/serverless/drizzle.config.ts b/serverless/drizzle.config.ts new file mode 100644 index 0000000..317fae5 --- /dev/null +++ b/serverless/drizzle.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'drizzle-kit'; + +export default defineConfig({ + schema: './src/db/schema/**/*.ts', + out: './drizzle', + dialect: 'postgresql', + dbCredentials: { + url: process.env.DATABASE_URL ?? '', + }, +}); diff --git a/serverless/package-lock.json b/serverless/package-lock.json index 3560bf1..8e47d32 100644 --- a/serverless/package-lock.json +++ b/serverless/package-lock.json @@ -10,8 +10,10 @@ "license": "ISC", "dependencies": { "@aws-sdk/client-s3": "^3.965.0", + "@aws-sdk/client-secrets-manager": "^3.965.0", "@aws-sdk/s3-request-presigner": "^3.965.0", "axios": "^1.13.2", + "drizzle-orm": "^0.44.5", "form-data": "^4.0.1" }, "devDependencies": { @@ -20,10 +22,12 @@ "@types/node": "^25.0.8", "@typescript-eslint/eslint-plugin": "^8.53.0", "@typescript-eslint/parser": "^8.53.0", + "drizzle-kit": "^0.31.5", "esbuild": "^0.27.2", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.4", + "pg": "^8.16.3", "prettier": "^3.7.4", "serverless-esbuild": "^1.57.0", "ts-node": "^10.9.2", @@ -298,6 +302,512 @@ "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/client-secrets-manager": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.968.0.tgz", + "integrity": "sha512-TfMOTqwhlgFFhhNgWspOlaMpJEggw3C26MkY5ja6574zo4ybirW/UhkC793UtANxke874g1M0qZofPKtKh6aOg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.968.0", + "@aws-sdk/credential-provider-node": "3.968.0", + "@aws-sdk/middleware-host-header": "3.968.0", + "@aws-sdk/middleware-logger": "3.968.0", + "@aws-sdk/middleware-recursion-detection": "3.968.0", + "@aws-sdk/middleware-user-agent": "3.968.0", + "@aws-sdk/region-config-resolver": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@aws-sdk/util-endpoints": "3.968.0", + "@aws-sdk/util-user-agent-browser": "3.968.0", + "@aws-sdk/util-user-agent-node": "3.968.0", + "@smithy/config-resolver": "^4.4.5", + "@smithy/core": "^3.20.3", + "@smithy/fetch-http-handler": "^5.3.8", + "@smithy/hash-node": "^4.2.7", + "@smithy/invalid-dependency": "^4.2.7", + "@smithy/middleware-content-length": "^4.2.7", + "@smithy/middleware-endpoint": "^4.4.4", + "@smithy/middleware-retry": "^4.4.20", + "@smithy/middleware-serde": "^4.2.8", + "@smithy/middleware-stack": "^4.2.7", + "@smithy/node-config-provider": "^4.3.7", + "@smithy/node-http-handler": "^4.4.7", + "@smithy/protocol-http": "^5.3.7", + "@smithy/smithy-client": "^4.10.5", + "@smithy/types": "^4.11.0", + "@smithy/url-parser": "^4.2.7", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.19", + "@smithy/util-defaults-mode-node": "^4.2.22", + "@smithy/util-endpoints": "^3.2.7", + "@smithy/util-middleware": "^4.2.7", + "@smithy/util-retry": "^4.2.7", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/client-sso": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.968.0.tgz", + "integrity": "sha512-y+k23MvMzpn1WpeQ9sdEXg1Bbw7dfi0ZH2uwyBv78F/kz0mZOI+RJ1KJg8DgSD8XvdxB8gX5GQ8rzo0LnDothA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.968.0", + "@aws-sdk/middleware-host-header": "3.968.0", + "@aws-sdk/middleware-logger": "3.968.0", + "@aws-sdk/middleware-recursion-detection": "3.968.0", + "@aws-sdk/middleware-user-agent": "3.968.0", + "@aws-sdk/region-config-resolver": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@aws-sdk/util-endpoints": "3.968.0", + "@aws-sdk/util-user-agent-browser": "3.968.0", + "@aws-sdk/util-user-agent-node": "3.968.0", + "@smithy/config-resolver": "^4.4.5", + "@smithy/core": "^3.20.3", + "@smithy/fetch-http-handler": "^5.3.8", + "@smithy/hash-node": "^4.2.7", + "@smithy/invalid-dependency": "^4.2.7", + "@smithy/middleware-content-length": "^4.2.7", + "@smithy/middleware-endpoint": "^4.4.4", + "@smithy/middleware-retry": "^4.4.20", + "@smithy/middleware-serde": "^4.2.8", + "@smithy/middleware-stack": "^4.2.7", + "@smithy/node-config-provider": "^4.3.7", + "@smithy/node-http-handler": "^4.4.7", + "@smithy/protocol-http": "^5.3.7", + "@smithy/smithy-client": "^4.10.5", + "@smithy/types": "^4.11.0", + "@smithy/url-parser": "^4.2.7", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.19", + "@smithy/util-defaults-mode-node": "^4.2.22", + "@smithy/util-endpoints": "^3.2.7", + "@smithy/util-middleware": "^4.2.7", + "@smithy/util-retry": "^4.2.7", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/core": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.968.0.tgz", + "integrity": "sha512-u4lIpvGqMMHZN523/RxW70xNoVXHBXucIWZsxFKc373E6TWYEb16ddFhXTELioS5TU93qkd/6yDQZzI6AAhbkw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@aws-sdk/xml-builder": "3.968.0", + "@smithy/core": "^3.20.3", + "@smithy/node-config-provider": "^4.3.7", + "@smithy/property-provider": "^4.2.7", + "@smithy/protocol-http": "^5.3.7", + "@smithy/signature-v4": "^5.3.7", + "@smithy/smithy-client": "^4.10.5", + "@smithy/types": "^4.11.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.7", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.968.0.tgz", + "integrity": "sha512-G+zgXEniQxBHFtHo+0yImkYutvJZLvWqvkPUP8/cG+IaYg54OY7L/GPIAZJh0U3m0Uepao98NbL15zjM+uplqQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/property-provider": "^4.2.7", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.968.0.tgz", + "integrity": "sha512-79teHBx/EtsNRR3Bq8fQdmMHtUcYwvohm9EwXXFt2Jd3BEOBH872IjIlfKdAvdkM+jW1QeeWOZBAxXGPir7GcQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/fetch-http-handler": "^5.3.8", + "@smithy/node-http-handler": "^4.4.7", + "@smithy/property-provider": "^4.2.7", + "@smithy/protocol-http": "^5.3.7", + "@smithy/smithy-client": "^4.10.5", + "@smithy/types": "^4.11.0", + "@smithy/util-stream": "^4.5.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.968.0.tgz", + "integrity": "sha512-9J9pcweoEN8yG7Qliux1zl9J3DT8X6OLcDN2RVXdTd5xzWBaYlupnUiJzoP6lvXdMnEmlDZaV7IMtoBdG7MY6g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/credential-provider-env": "3.968.0", + "@aws-sdk/credential-provider-http": "3.968.0", + "@aws-sdk/credential-provider-login": "3.968.0", + "@aws-sdk/credential-provider-process": "3.968.0", + "@aws-sdk/credential-provider-sso": "3.968.0", + "@aws-sdk/credential-provider-web-identity": "3.968.0", + "@aws-sdk/nested-clients": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/credential-provider-imds": "^4.2.7", + "@smithy/property-provider": "^4.2.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-login": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.968.0.tgz", + "integrity": "sha512-YxBaR0IMuHPOVTG+73Ve0QfllweN+EdwBRnHFhUGnahMGAcTmcaRdotqwqWfiws+9ud44IFKjxXR3t8jaGpFnQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/nested-clients": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/property-provider": "^4.2.7", + "@smithy/protocol-http": "^5.3.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.968.0.tgz", + "integrity": "sha512-wei6v0c9vDEam8pM5eWe9bt+5ixg8nL0q+DFPzI6iwdLUqmJsPoAzWPEyMkgp03iE02SS2fMqPWpmRjz/NVyUw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.968.0", + "@aws-sdk/credential-provider-http": "3.968.0", + "@aws-sdk/credential-provider-ini": "3.968.0", + "@aws-sdk/credential-provider-process": "3.968.0", + "@aws-sdk/credential-provider-sso": "3.968.0", + "@aws-sdk/credential-provider-web-identity": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/credential-provider-imds": "^4.2.7", + "@smithy/property-provider": "^4.2.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.968.0.tgz", + "integrity": "sha512-my9M/ijRyEACoyeEWiC2sTVM3+eck5IWPGTPQrlYMKivy4LLlZchohtIopuqTom+JZzLZD508j1s9aDvl7BA0w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/property-provider": "^4.2.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.968.0.tgz", + "integrity": "sha512-XPYPcxfWIt5jBbofoP2xhAHlFYos0dzwbHsoE18Cera/XnaCEbsUpdROo30t0Kjdbv0EWMYLMPDi9G+vPRDnhQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.968.0", + "@aws-sdk/core": "3.968.0", + "@aws-sdk/token-providers": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/property-provider": "^4.2.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.968.0.tgz", + "integrity": "sha512-9HNAP6mx2jsBW4moWnRg5ycyZ0C1EbtMIegIHa93ga13B/8VZF9Y0iDnwW73yQYzCEt9UrDiFeRck/ChZup3rA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/nested-clients": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/property-provider": "^4.2.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.968.0.tgz", + "integrity": "sha512-ujlNT215VtE/2D2jEhFVcTuPPB36HJyLBM0ytnni/WPIjzq89iJrKR1tEhxpk8uct6A5NSQ6w9Y7g2Rw1rkSoQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@smithy/protocol-http": "^5.3.7", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-logger": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.968.0.tgz", + "integrity": "sha512-zvhhEPZgvaRDxzf27m2WmgaXoN7upFt/gvG7ofBN5zCBlkh3JtFamMh5KWYVQwMhc4eQBK3NjH0oIUKZSVztag==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.968.0.tgz", + "integrity": "sha512-KygPiwpSAPGobgodK/oLb7OLiwK29pNJeNtP+GZ9pxpceDRqhN0Ub8Eo84dBbWq+jbzAqBYHzy+B1VsbQ/hLWA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.7", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.968.0.tgz", + "integrity": "sha512-4h5/B8FyxMjLxtXd5jbM2R69aO57qQiHoAJQTtkpuxmM7vhvjSxEQtMM9L1kuMXoMVNE7xM4886h0+gbmmxplg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@aws-sdk/util-endpoints": "3.968.0", + "@smithy/core": "^3.20.3", + "@smithy/protocol-http": "^5.3.7", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/nested-clients": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.968.0.tgz", + "integrity": "sha512-LLppm+8MzD3afD2IA/tYDp5AoVPOybK7MHQz5DVB4HsZ+fHvwYlvau2ZUK8nKwJSk5c1kWcxCZkyuJQjFu37ng==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.968.0", + "@aws-sdk/middleware-host-header": "3.968.0", + "@aws-sdk/middleware-logger": "3.968.0", + "@aws-sdk/middleware-recursion-detection": "3.968.0", + "@aws-sdk/middleware-user-agent": "3.968.0", + "@aws-sdk/region-config-resolver": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@aws-sdk/util-endpoints": "3.968.0", + "@aws-sdk/util-user-agent-browser": "3.968.0", + "@aws-sdk/util-user-agent-node": "3.968.0", + "@smithy/config-resolver": "^4.4.5", + "@smithy/core": "^3.20.3", + "@smithy/fetch-http-handler": "^5.3.8", + "@smithy/hash-node": "^4.2.7", + "@smithy/invalid-dependency": "^4.2.7", + "@smithy/middleware-content-length": "^4.2.7", + "@smithy/middleware-endpoint": "^4.4.4", + "@smithy/middleware-retry": "^4.4.20", + "@smithy/middleware-serde": "^4.2.8", + "@smithy/middleware-stack": "^4.2.7", + "@smithy/node-config-provider": "^4.3.7", + "@smithy/node-http-handler": "^4.4.7", + "@smithy/protocol-http": "^5.3.7", + "@smithy/smithy-client": "^4.10.5", + "@smithy/types": "^4.11.0", + "@smithy/url-parser": "^4.2.7", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.19", + "@smithy/util-defaults-mode-node": "^4.2.22", + "@smithy/util-endpoints": "^3.2.7", + "@smithy/util-middleware": "^4.2.7", + "@smithy/util-retry": "^4.2.7", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/region-config-resolver": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.968.0.tgz", + "integrity": "sha512-BzrCpxEsAHbi+yDGtgXJ+/5AvLPjfhcT6DlL+Fc4g13J5Z0VwiO95Wem+Q4KK7WDZH7/sZ/1WFvfitjLTKZbEw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@smithy/config-resolver": "^4.4.5", + "@smithy/node-config-provider": "^4.3.7", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/token-providers": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.968.0.tgz", + "integrity": "sha512-lXUZqB2qTFmZYNXPnVT0suSHGiuQAPrL2DhmhbjqOdR7+GKDHL5KbeKFvPisy7Y4neliJqT4Q1VPWa0nqYaiZg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.968.0", + "@aws-sdk/nested-clients": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/property-provider": "^4.2.7", + "@smithy/shared-ini-file-loader": "^4.4.2", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/types": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.968.0.tgz", + "integrity": "sha512-Wuumj/1cuiuXTMdHmvH88zbEl+5Pw++fOFQuMCF4yP0R+9k1lwX8rVst+oy99xaxtdluJZXrsccoZoA67ST1Ow==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-endpoints": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.968.0.tgz", + "integrity": "sha512-9IdilgylS0crFSeI59vtr8qhDYMYYOvnvkl1dLp59+EmLH1IdXz7+4cR5oh5PkoqD7DRzc5Uzm2GnZhK6I0oVQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@smithy/types": "^4.11.0", + "@smithy/url-parser": "^4.2.7", + "@smithy/util-endpoints": "^3.2.7", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.968.0.tgz", + "integrity": "sha512-nRxjs8Jpq8ZHFsa/0uiww2f4+40D6Dt6bQmepAJHIE/D+atwPINDKsfamCjFnxrjKU3WBWpGYEf/QDO0XZsFMw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.968.0", + "@smithy/types": "^4.11.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.968.0.tgz", + "integrity": "sha512-oaIkPGraGhZgkDmxVhTIlakaUNWKO9aMN+uB6I+eS26MWi/lpMK66HTZeXEnaTrmt5/kl99YC0N37zScz58Tdg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.968.0", + "@aws-sdk/types": "3.968.0", + "@smithy/node-config-provider": "^4.3.7", + "@smithy/types": "^4.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/xml-builder": { + "version": "3.968.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.968.0.tgz", + "integrity": "sha512-bZQKn41ebPh/uW9uWUE5oLuaBr44Gt78dkw2amu5zcwo1J/d8s6FdzZcRDmz0rHE2NHJWYkdQYeVQo7jhMziqA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.11.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { "version": "3.965.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.965.0.tgz", @@ -975,6 +1485,13 @@ "node": ">=12" } }, + "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/@effect/platform": { "version": "0.65.5", "resolved": "https://registry.npmjs.org/@effect/platform/-/platform-0.65.5.tgz", @@ -1036,6 +1553,442 @@ "effect": "^3.8.3" } }, + "node_modules/@esbuild-kit/core-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "deprecated": "Merged into tsx: https://tsx.is", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.18.20", + "source-map-support": "^0.5.21" + } + }, + "node_modules/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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/@esbuild-kit/core-utils/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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/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, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "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" + } + }, + "node_modules/@esbuild-kit/esm-loader": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "deprecated": "Merged into tsx: https://tsx.is", + "dev": true, + "license": "MIT", + "dependencies": { + "@esbuild-kit/core-utils": "^3.3.2", + "get-tsconfig": "^4.7.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -2108,12 +3061,12 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.7.tgz", - "integrity": "sha512-rzMY6CaKx2qxrbYbqjXWS0plqEy7LOdKHS0bg4ixJ6aoGDPNUcLWk/FRNuCILh7GKLG9TFUXYYeQQldMBBwuyw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", + "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2146,16 +3099,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.5.tgz", - "integrity": "sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", + "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.7", - "@smithy/util-middleware": "^4.2.7", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -2163,18 +3116,18 @@ } }, "node_modules/@smithy/core": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.20.1.tgz", - "integrity": "sha512-wOboSEdQ85dbKAJ0zL+wQ6b0HTSBRhtGa0PYKysQXkRg+vK0tdCRRVruiFM2QMprkOQwSYOnwF4og96PAaEGag==", + "version": "3.20.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.20.5.tgz", + "integrity": "sha512-0Tz77Td8ynHaowXfOdrD0F1IH4tgWGUhwmLwmpFyTbr+U9WHXNNp9u/k2VjBXGnSe7BwjBERRpXsokGTXzNjhA==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.8", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-stream": "^4.5.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-stream": "^4.5.10", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" @@ -2184,15 +3137,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.7.tgz", - "integrity": "sha512-CmduWdCiILCRNbQWFR0OcZlUPVtyE49Sr8yYL0rZQ4D/wKxiNzBNS/YHemvnbkIWj623fplgkexUd/c9CAKdoA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", + "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -2270,14 +3223,14 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.8.tgz", - "integrity": "sha512-h/Fi+o7mti4n8wx1SR6UHWLaakwHRx29sizvp8OOm7iqwKGFneT06GCSFhml6Bha5BT6ot5pj3CYZnCHhGC2Rg==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", + "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.7", - "@smithy/querystring-builder": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" }, @@ -2383,18 +3336,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.2.tgz", - "integrity": "sha512-mqpAdux0BNmZu/SqkFhQEnod4fX23xxTvU2LUpmKp0JpSI+kPYCiHJMmzREr8yxbNxKL2/DU1UZm9i++ayU+2g==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.6.tgz", + "integrity": "sha512-dpq3bHqbEOBqGBjRVHVFP3eUSPpX0BYtg1D5d5Irgk6orGGAuZfY22rC4sErhg+ZfY/Y0kPqm1XpAmDZg7DeuA==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.20.1", - "@smithy/middleware-serde": "^4.2.8", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", - "@smithy/url-parser": "^4.2.7", - "@smithy/util-middleware": "^4.2.7", + "@smithy/core": "^3.20.5", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -2402,18 +3355,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.18", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.18.tgz", - "integrity": "sha512-E5hulijA59nBk/zvcwVMaS7FG7Y4l6hWA9vrW018r+8kiZef4/ETQaPI4oY+3zsy9f6KqDv3c4VKtO4DwwgpCg==", + "version": "4.4.22", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.22.tgz", + "integrity": "sha512-vwWDMaObSMjw6WCC/3Ae9G7uul5Sk95jr07CDk1gkIMpaDic0phPS1MpVAZ6+YkF7PAzRlpsDjxPwRlh/S11FQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/service-error-classification": "^4.2.7", - "@smithy/smithy-client": "^4.10.3", - "@smithy/types": "^4.11.0", - "@smithy/util-middleware": "^4.2.7", - "@smithy/util-retry": "^4.2.7", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" }, @@ -2422,13 +3375,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.8.tgz", - "integrity": "sha512-8rDGYen5m5+NV9eHv9ry0sqm2gI6W7mc1VSFMtn6Igo25S507/HaOX9LTHAS2/J32VXD0xSzrY0H5FJtOMS4/w==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", + "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2436,12 +3389,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.7.tgz", - "integrity": "sha512-bsOT0rJ+HHlZd9crHoS37mt8qRRN/h9jRve1SXUhVbkRzu0QaNYZp1i1jha4n098tsvROjcwfLlfvcFuJSXEsw==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", + "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2449,14 +3402,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.7.tgz", - "integrity": "sha512-7r58wq8sdOcrwWe+klL9y3bc4GW1gnlfnFOuL7CXa7UzfhzhxKuzNdtqgzmTV+53lEp9NXh5hY/S4UgjLOzPfw==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", + "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.7", - "@smithy/shared-ini-file-loader": "^4.4.2", - "@smithy/types": "^4.11.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2464,15 +3417,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.7.tgz", - "integrity": "sha512-NELpdmBOO6EpZtWgQiHjoShs1kmweaiNuETUpuup+cmm/xJYjT4eUjfhrXRP4jCOaAsS3c3yPsP3B+K+/fyPCQ==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.8.tgz", + "integrity": "sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/querystring-builder": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/abort-controller": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2480,12 +3433,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.7.tgz", - "integrity": "sha512-jmNYKe9MGGPoSl/D7JDDs1C8b3dC8f/w78LbaVfoTtWy4xAd5dfjaFG9c9PWPihY4ggMQNQSMtzU77CNgAJwmA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", + "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2493,12 +3446,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.7.tgz", - "integrity": "sha512-1r07pb994I20dD/c2seaZhoCuNYm0rWrvBxhCQ70brNh11M5Ml2ew6qJVo0lclB3jMIXirD4s2XRXRe7QEi0xA==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", + "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2506,12 +3459,12 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.7.tgz", - "integrity": "sha512-eKONSywHZxK4tBxe2lXEysh8wbBdvDWiA+RIuaxZSgCMmA0zMgoDpGLJhnyj+c0leOQprVnXOmcB4m+W9Rw7sg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", + "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" }, @@ -2520,12 +3473,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.7.tgz", - "integrity": "sha512-3X5ZvzUHmlSTHAXFlswrS6EGt8fMSIxX/c3Rm1Pni3+wYWB6cjGocmRIoqcQF9nU5OgGmL0u7l9m44tSUpfj9w==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", + "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2533,24 +3486,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.7.tgz", - "integrity": "sha512-YB7oCbukqEb2Dlh3340/8g8vNGbs/QsNNRms+gv3N2AtZz9/1vSBx6/6tpwQpZMEJFs7Uq8h4mmOn48ZZ72MkA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", + "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0" + "@smithy/types": "^4.12.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.2.tgz", - "integrity": "sha512-M7iUUff/KwfNunmrgtqBfvZSzh3bmFgv/j/t1Y1dQ+8dNo34br1cqVEqy6v0mYEgi0DkGO7Xig0AnuOaEGVlcg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", + "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2577,17 +3530,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.3.tgz", - "integrity": "sha512-EfECiO/0fAfb590LBnUe7rI5ux7XfquQ8LBzTe7gxw0j9QW/q8UT/EHWHlxV/+jhQ3+Ssga9uUYXCQgImGMbNg==", + "version": "4.10.7", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.7.tgz", + "integrity": "sha512-Uznt0I9z3os3Z+8pbXrOSCTXCA6vrjyN7Ub+8l2pRDum44vLv8qw0qGVkJN0/tZBZotaEFHrDPKUoPNueTr5Vg==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.20.1", - "@smithy/middleware-endpoint": "^4.4.2", - "@smithy/middleware-stack": "^4.2.7", - "@smithy/protocol-http": "^5.3.7", - "@smithy/types": "^4.11.0", - "@smithy/util-stream": "^4.5.8", + "@smithy/core": "^3.20.5", + "@smithy/middleware-endpoint": "^4.4.6", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" }, "engines": { @@ -2595,9 +3548,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.11.0.tgz", - "integrity": "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", + "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2607,13 +3560,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.7.tgz", - "integrity": "sha512-/RLtVsRV4uY3qPWhBDsjwahAtt3x2IsMGnP5W1b2VZIe+qgCqkLxI1UOHDZp1Q1QSOrdOR32MF3Ph2JfWT1VHg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", + "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/querystring-parser": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2684,14 +3637,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.17", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.17.tgz", - "integrity": "sha512-dwN4GmivYF1QphnP3xJESXKtHvkkvKHSZI8GrSKMVoENVSKW2cFPRYC4ZgstYjUHdR3zwaDkIaTDIp26JuY7Cw==", + "version": "4.3.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.21.tgz", + "integrity": "sha512-DtmVJarzqtjghtGjCw/PFJolcJkP7GkZgy+hWTAN3YLXNH+IC82uMoMhFoC3ZtIz5mOgCm5+hOGi1wfhVYgrxw==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.7", - "@smithy/smithy-client": "^4.10.3", - "@smithy/types": "^4.11.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2699,17 +3652,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.20", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.20.tgz", - "integrity": "sha512-VD/I4AEhF1lpB3B//pmOIMBNLMrtdMXwy9yCOfa2QkJGDr63vH3RqPbSAKzoGMov3iryCxTXCxSsyGmEB8PDpg==", + "version": "4.2.24", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.24.tgz", + "integrity": "sha512-JelBDKPAVswVY666rezBvY6b0nF/v9TXjUbNwDNAyme7qqKYEX687wJv0uze8lBIZVbg30wlWnlYfVSjjpKYFA==", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.4.5", - "@smithy/credential-provider-imds": "^4.2.7", - "@smithy/node-config-provider": "^4.3.7", - "@smithy/property-provider": "^4.2.7", - "@smithy/smithy-client": "^4.10.3", - "@smithy/types": "^4.11.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2717,13 +3670,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.7.tgz", - "integrity": "sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", + "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.7", - "@smithy/types": "^4.11.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2743,12 +3696,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.7.tgz", - "integrity": "sha512-i1IkpbOae6NvIKsEeLLM9/2q4X+M90KV3oCFgWQI4q0Qz+yUZvsr+gZPdAEAtFhWQhAHpTsJO8DRJPuwVyln+w==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", + "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.11.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2756,13 +3709,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.7", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.7.tgz", - "integrity": "sha512-SvDdsQyF5CIASa4EYVT02LukPHVzAgUA4kMAuZ97QJc2BpAqZfA4PINB8/KOoCXEw9tsuv/jQjMeaHFvxdLNGg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", + "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.2.7", - "@smithy/types": "^4.11.0", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2770,14 +3723,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.8.tgz", - "integrity": "sha512-ZnnBhTapjM0YPGUSmOs0Mcg/Gg87k503qG4zU2v/+Js2Gu+daKOJMeqcQns8ajepY8tgzzfYxl6kQyZKml6O2w==", + "version": "4.5.10", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.10.tgz", + "integrity": "sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g==", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.8", - "@smithy/node-http-handler": "^4.4.7", - "@smithy/types": "^4.11.0", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", @@ -3517,6 +4470,13 @@ "node": "*" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -3795,6 +4755,631 @@ "node": ">=8" } }, + "node_modules/drizzle-kit": { + "version": "0.31.8", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.8.tgz", + "integrity": "sha512-O9EC/miwdnRDY10qRxM8P3Pg8hXe3LyU4ZipReKOgTwn4OqANmftj8XJz1UPUAS6NMHf0E2htjsbQujUTkncCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@drizzle-team/brocli": "^0.10.2", + "@esbuild-kit/esm-loader": "^2.5.5", + "esbuild": "^0.25.4", + "esbuild-register": "^3.5.0" + }, + "bin": { + "drizzle-kit": "bin.cjs" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "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" + } + }, + "node_modules/drizzle-orm": { + "version": "0.44.7", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.44.7.tgz", + "integrity": "sha512-quIpnYznjU9lHshEOAYLoZ9s3jweleHlZIAWR/jX9gAWNg/JhQ1wj0KGRf7/Zm+obRrYd9GjPVJg790QY9N5AQ==", + "license": "Apache-2.0", + "peerDependencies": { + "@aws-sdk/client-rds-data": ">=3", + "@cloudflare/workers-types": ">=4", + "@electric-sql/pglite": ">=0.2.0", + "@libsql/client": ">=0.10.0", + "@libsql/client-wasm": ">=0.10.0", + "@neondatabase/serverless": ">=0.10.0", + "@op-engineering/op-sqlite": ">=2", + "@opentelemetry/api": "^1.4.1", + "@planetscale/database": ">=1.13", + "@prisma/client": "*", + "@tidbcloud/serverless": "*", + "@types/better-sqlite3": "*", + "@types/pg": "*", + "@types/sql.js": "*", + "@upstash/redis": ">=1.34.7", + "@vercel/postgres": ">=0.8.0", + "@xata.io/client": "*", + "better-sqlite3": ">=7", + "bun-types": "*", + "expo-sqlite": ">=14.0.0", + "gel": ">=2", + "knex": "*", + "kysely": "*", + "mysql2": ">=2", + "pg": ">=8", + "postgres": ">=3", + "sql.js": ">=1", + "sqlite3": ">=5" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-rds-data": { + "optional": true + }, + "@cloudflare/workers-types": { + "optional": true + }, + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@libsql/client-wasm": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@op-engineering/op-sqlite": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "@tidbcloud/serverless": { + "optional": true + }, + "@types/better-sqlite3": { + "optional": true + }, + "@types/pg": { + "optional": true + }, + "@types/sql.js": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "bun-types": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "gel": { + "optional": true + }, + "knex": { + "optional": true + }, + "kysely": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "postgres": { + "optional": true + }, + "prisma": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3924,6 +5509,19 @@ "@esbuild/win32-x64": "0.27.2" } }, + "node_modules/esbuild-register": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -4579,6 +6177,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5421,6 +7032,103 @@ "node": ">=8" } }, + "node_modules/pg": { + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.7" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", @@ -5434,6 +7142,49 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5629,6 +7380,16 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -5775,6 +7536,37 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -6138,6 +7930,16 @@ } } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/serverless/package.json b/serverless/package.json index cdf6c3c..7a5ea12 100644 --- a/serverless/package.json +++ b/serverless/package.json @@ -10,6 +10,8 @@ "format": "prettier --write 'src/**/*.ts'", "format:check": "prettier --check 'src/**/*.ts'", "type-check": "tsc --noEmit", + "db:generate": "drizzle-kit generate", + "db:migrate": "drizzle-kit migrate", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], @@ -17,9 +19,11 @@ "license": "ISC", "type": "commonjs", "dependencies": { + "@aws-sdk/client-secrets-manager": "^3.965.0", "@aws-sdk/client-s3": "^3.965.0", "@aws-sdk/s3-request-presigner": "^3.965.0", "axios": "^1.13.2", + "drizzle-orm": "^0.44.5", "form-data": "^4.0.1" }, "devDependencies": { @@ -28,6 +32,7 @@ "@types/node": "^25.0.8", "@typescript-eslint/eslint-plugin": "^8.53.0", "@typescript-eslint/parser": "^8.53.0", + "drizzle-kit": "^0.31.5", "esbuild": "^0.27.2", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -35,6 +40,7 @@ "prettier": "^3.7.4", "serverless-esbuild": "^1.57.0", "ts-node": "^10.9.2", + "pg": "^8.16.3", "typescript": "^5.9.3" } } diff --git a/serverless/serverless.yml b/serverless/serverless.yml index 5527b82..ac4331a 100644 --- a/serverless/serverless.yml +++ b/serverless/serverless.yml @@ -1,46 +1,54 @@ service: esdp-api app: esdp-api-app -frameworkVersion: "4" +frameworkVersion: '4' + +package: + patterns: + - drizzle/** stages: - prod: - # Enables observability in the prod stage - observability: true + prod: + # Enables observability in the prod stage + observability: true - # Sepcify parameter values to be used in the prod stage - params: - es_endpoint: https://insurtechtoolkit.com - domain: es.imex.online - es_user: Imex2 - es_password: Patrick - beta: - # Enables observability in the prod stage - observability: false + # Sepcify parameter values to be used in the prod stage + params: + es_endpoint: https://insurtechtoolkit.com + domain: es.imex.online + es_user: Imex2 + es_password: Patrick + db_name: esdpprod + beta: + # Enables observability in the prod stage + observability: false - # Sepcify parameter values to be used in the prod stage - params: - es_endpoint: https://4284-79073.el-alt.com - domain: beta.es.imex.online - es_user: Imex2 - es_password: Patrick - alpha: - # Enables observability in the prod stage - observability: false - # Sepcify parameter values to be used in the prod stage - params: - es_endpoint: https://4284-79287.el-alt.com - domain: alpha.es.imex.online - es_user: Imex2 - es_password: Patrick - dev: - # Enables observability in the prod stage - observability: false - # Sepcify parameter values to be used in the prod stage - params: - es_endpoint: https://4284-79287.el-alt.com - domain: dev.es.imex.online - es_user: Imex2 - es_password: Patrick + # Sepcify parameter values to be used in the prod stage + params: + es_endpoint: https://4284-79073.el-alt.com + domain: beta.es.imex.online + es_user: Imex2 + es_password: Patrick + db_name: esdpbeta + alpha: + # Enables observability in the prod stage + observability: false + # Sepcify parameter values to be used in the prod stage + params: + es_endpoint: https://4284-79287.el-alt.com + domain: alpha.es.imex.online + es_user: Imex2 + es_password: Patrick + db_name: esdpalpha + dev: + # Enables observability in the prod stage + observability: false + # Sepcify parameter values to be used in the prod stage + params: + es_endpoint: https://4284-79287.el-alt.com + domain: dev.es.imex.online + es_user: Imex2 + es_password: Patrick + db_name: esdpdev # params: # dev: @@ -53,70 +61,477 @@ stages: # domain: es.imex.online provider: - name: aws - runtime: nodejs22.x - region: ca-central-1 - domain: ${param:domain} - httpApi: # This creates a cheaper, faster "HTTP API" Gateway - cors: true # Automatically configures CORS + name: aws + runtime: nodejs22.x + region: ca-central-1 + domain: ${param:domain} + httpApi: # This creates a cheaper, faster "HTTP API" Gateway + cors: true # Automatically configures CORS build: - esbuild: - bundle: true - minify: false - sourcemap: true - exclude: - - '@aws-sdk/*' - target: node22 - platform: node + esbuild: + bundle: true + minify: false + sourcemap: true + exclude: + - '@aws-sdk/*' + target: node22 + platform: node functions: - vehicleType: - handler: src/handlers/vehicleType.handler - events: - - httpApi: - path: /vehicleType - method: post - scrub: - handler: src/handlers/scrub.handler - environment: - ES_ENDPOINT: ${param:es_endpoint} - ES_USER: ${param:es_user} - ES_PASSWORD: ${param:es_password} - events: - - httpApi: - path: /scrub - method: post - emsupload: - handler: src/handlers/emsupload.handler - environment: - ES_ENDPOINT: ${param:es_endpoint} - UPLOAD_BUCKET_NAME: ${self:service}-uploads-${sls:stage} - iamRoleStatements: - - Effect: Allow - Action: - - s3:PutObject - - s3:PutObjectAcl - - s3:GetObject - Resource: - - arn:aws:s3:::${self:service}-uploads-${sls:stage}/* - events: - - httpApi: - path: /emsupload - method: post + vehicleType: + handler: src/handlers/vehicleType.handler + events: + - httpApi: + path: /vehicleType + method: post + scrub: + handler: src/handlers/scrub.handler + environment: + ES_ENDPOINT: ${param:es_endpoint} + ES_USER: ${param:es_user} + ES_PASSWORD: ${param:es_password} + events: + - httpApi: + path: /scrub + method: post + emsupload: + handler: src/handlers/emsupload.handler + environment: + ES_ENDPOINT: ${param:es_endpoint} + UPLOAD_BUCKET_NAME: ${self:service}-uploads-${sls:stage} + iamRoleStatements: + - Effect: Allow + Action: + - s3:PutObject + - s3:PutObjectAcl + - s3:GetObject + Resource: + - arn:aws:s3:::${self:service}-uploads-${sls:stage}/* + events: + - httpApi: + path: /emsupload + method: post + + dbMigrate: + handler: src/handlers/dbMigrate.handler + timeout: 30 + memorySize: 512 + vpc: + securityGroupIds: + - Ref: LambdaSecurityGroup + subnetIds: + - Ref: PrivateSubnetA + - Ref: PrivateSubnetB + environment: + DB_HOST: + Fn::GetAtt: + - DbProxy + - Endpoint + DB_PORT: 5432 + DB_NAME: ${param:db_name} + DB_SECRET_ARN: + Ref: DbSecret + iamRoleStatements: + - Effect: Allow + Action: + - secretsmanager:GetSecretValue + Resource: + - Ref: DbSecret + + dbPing: + handler: src/handlers/dbPing.handler + timeout: 15 + memorySize: 256 + vpc: + securityGroupIds: + - Ref: LambdaSecurityGroup + subnetIds: + - Ref: PrivateSubnetA + - Ref: PrivateSubnetB + environment: + DB_HOST: + Fn::GetAtt: + - DbProxy + - Endpoint + DB_PORT: 5432 + DB_NAME: ${param:db_name} + DB_SECRET_ARN: + Ref: DbSecret + iamRoleStatements: + - Effect: Allow + Action: + - secretsmanager:GetSecretValue + Resource: + - Ref: DbSecret resources: - Resources: - UploadBucket: - Type: AWS::S3::Bucket - Properties: - BucketName: ${self:service}-uploads-${sls:stage} - CorsConfiguration: - CorsRules: - - AllowedOrigins: - - "*" - AllowedMethods: - - PUT - - POST - AllowedHeaders: - - "*" + Resources: + EsdpVpc: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.0.0.0/16 + EnableDnsSupport: true + EnableDnsHostnames: true + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-vpc + + InternetGateway: + Type: AWS::EC2::InternetGateway + Properties: + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-igw + + VpcGatewayAttachment: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: + Ref: EsdpVpc + InternetGatewayId: + Ref: InternetGateway + + PublicSubnetA: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: EsdpVpc + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: '' + CidrBlock: 10.0.0.0/24 + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-public-a + + PublicSubnetB: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: EsdpVpc + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: '' + CidrBlock: 10.0.1.0/24 + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-public-b + + PrivateSubnetA: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: EsdpVpc + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: '' + CidrBlock: 10.0.10.0/24 + MapPublicIpOnLaunch: false + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-private-a + + PrivateSubnetB: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: EsdpVpc + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: '' + CidrBlock: 10.0.11.0/24 + MapPublicIpOnLaunch: false + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-private-b + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: EsdpVpc + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-public-rt + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: VpcGatewayAttachment + Properties: + RouteTableId: + Ref: PublicRouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: + Ref: InternetGateway + + PublicSubnetARouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: PublicSubnetA + RouteTableId: + Ref: PublicRouteTable + + PublicSubnetBRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: PublicSubnetB + RouteTableId: + Ref: PublicRouteTable + + NatEip: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + + NatGateway: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: + Fn::GetAtt: + - NatEip + - AllocationId + SubnetId: + Ref: PublicSubnetA + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-nat + + PrivateRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: EsdpVpc + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-private-rt + + PrivateRoute: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Ref: PrivateRouteTable + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: + Ref: NatGateway + + PrivateSubnetARouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: PrivateSubnetA + RouteTableId: + Ref: PrivateRouteTable + + PrivateSubnetBRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: PrivateSubnetB + RouteTableId: + Ref: PrivateRouteTable + + LambdaSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: ${self:service}-${sls:stage} Lambda security group + VpcId: + Ref: EsdpVpc + SecurityGroupEgress: + - IpProtocol: -1 + CidrIp: 0.0.0.0/0 + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-lambda-sg + + ProxySecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: ${self:service}-${sls:stage} RDS proxy security group + VpcId: + Ref: EsdpVpc + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 5432 + ToPort: 5432 + SourceSecurityGroupId: + Ref: LambdaSecurityGroup + - IpProtocol: tcp + FromPort: 5432 + ToPort: 5432 + CidrIp: 70.36.57.88/32 + SecurityGroupEgress: + - IpProtocol: -1 + CidrIp: 0.0.0.0/0 + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-proxy-sg + + RdsSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: ${self:service}-${sls:stage} RDS security group + VpcId: + Ref: EsdpVpc + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 5432 + ToPort: 5432 + SourceSecurityGroupId: + Ref: ProxySecurityGroup + - IpProtocol: tcp + FromPort: 5432 + ToPort: 5432 + CidrIp: 70.36.57.88/32 + Tags: + - Key: Name + Value: ${self:service}-${sls:stage}-rds-sg + + DbSubnetGroup: + Type: AWS::RDS::DBSubnetGroup + Properties: + DBSubnetGroupDescription: ${self:service}-${sls:stage} DB subnet group + SubnetIds: + - Ref: PrivateSubnetA + - Ref: PrivateSubnetB + - Ref: PublicSubnetA + - Ref: PublicSubnetB + + DbSecret: + Type: AWS::SecretsManager::Secret + Properties: + Description: ${self:service}-${sls:stage} RDS master credentials + GenerateSecretString: + SecretStringTemplate: '{"username":"esdp_admin"}' + GenerateStringKey: password + PasswordLength: 32 + ExcludeCharacters: '"@/\\' + + DbProxyRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - rds.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: ${self:service}-${sls:stage}-db-proxy-secrets + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - secretsmanager:GetSecretValue + Resource: + - Ref: DbSecret + + DbProxy: + Type: AWS::RDS::DBProxy + Properties: + DBProxyName: ${self:service}-${sls:stage}-proxy + EngineFamily: POSTGRESQL + IdleClientTimeout: 1800 + RequireTLS: true + RoleArn: + Fn::GetAtt: + - DbProxyRole + - Arn + VpcSubnetIds: + - Ref: PrivateSubnetA + - Ref: PrivateSubnetB + VpcSecurityGroupIds: + - Ref: ProxySecurityGroup + Auth: + - AuthScheme: SECRETS + SecretArn: + Ref: DbSecret + IAMAuth: DISABLED + + DbProxyTargetGroup: + Type: AWS::RDS::DBProxyTargetGroup + Properties: + DBProxyName: + Ref: DbProxy + TargetGroupName: default + DBInstanceIdentifiers: + - Ref: PostgresDb + ConnectionPoolConfigurationInfo: + MaxConnectionsPercent: 75 + MaxIdleConnectionsPercent: 50 + ConnectionBorrowTimeout: 120 + + PostgresDb: + Type: AWS::RDS::DBInstance + DeletionPolicy: Snapshot + UpdateReplacePolicy: Snapshot + Properties: + DBInstanceIdentifier: ${self:service}-${sls:stage}-postgres + Engine: postgres + # EngineVersion intentionally omitted so AWS uses the current default/latest for RDS Postgres. + AutoMinorVersionUpgrade: true + DBInstanceClass: db.t4g.micro + AllocatedStorage: 20 + StorageType: gp3 + StorageEncrypted: true + PubliclyAccessible: true + MultiAZ: false + DBName: ${param:db_name} + BackupRetentionPeriod: 7 + CopyTagsToSnapshot: true + DeletionProtection: true + VPCSecurityGroups: + - Ref: RdsSecurityGroup + DBSubnetGroupName: + Ref: DbSubnetGroup + MasterUsername: + Fn::Sub: '{{resolve:secretsmanager:${DbSecret}::username}}' + MasterUserPassword: + Fn::Sub: '{{resolve:secretsmanager:${DbSecret}::password}}' + + UploadBucket: + Type: AWS::S3::Bucket + Properties: + BucketName: ${self:service}-uploads-${sls:stage} + CorsConfiguration: + CorsRules: + - AllowedOrigins: + - '*' + AllowedMethods: + - PUT + - POST + AllowedHeaders: + - '*' + + Outputs: + DbEndpointAddress: + Value: + Fn::GetAtt: + - PostgresDb + - Endpoint.Address + DbEndpointPort: + Value: + Fn::GetAtt: + - PostgresDb + - Endpoint.Port + DbSecretArn: + Value: + Ref: DbSecret + + DbProxyEndpoint: + Value: + Fn::GetAtt: + - DbProxy + - Endpoint diff --git a/serverless/src/db/schema/index.ts b/serverless/src/db/schema/index.ts new file mode 100644 index 0000000..5bc8021 --- /dev/null +++ b/serverless/src/db/schema/index.ts @@ -0,0 +1,31 @@ +import { AnyPgColumn, boolean, pgTable, text, timestamp, uuid, index } from 'drizzle-orm/pg-core'; + +export const shops = pgTable('shops', { + id: uuid('id').defaultRandom().primaryKey(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + esApiKey: text('es_api_key').notNull().unique(), + active: boolean('active').notNull().default(true), +}); + +export const jobs = pgTable( + 'jobs', + { + id: uuid('id').defaultRandom().primaryKey(), + shopId: uuid('shopId') + .references((): AnyPgColumn => shops.id) + .notNull(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + clm_no: text('clm_no'), + ciecaid: text('ciecaid'), + }, + (table) => [index('clm_no_idx').on(table.clm_no)] +); + +export const joblines = pgTable('joblines', { + id: uuid('id').defaultRandom().primaryKey(), + createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), + jobId: uuid('jobId') + .references((): AnyPgColumn => jobs.id) + .notNull(), + line_desc: text('line_desc'), +}); diff --git a/serverless/src/handlers/dbMigrate.ts b/serverless/src/handlers/dbMigrate.ts new file mode 100644 index 0000000..c58d576 --- /dev/null +++ b/serverless/src/handlers/dbMigrate.ts @@ -0,0 +1,22 @@ +import { APIGatewayProxyResult } from 'aws-lambda'; +import { migrate } from 'drizzle-orm/node-postgres/migrator'; + +import { getDb } from '../lib/db'; + +export const handler = async (): Promise => { + try { + const db = await getDb(); + await migrate(db, { migrationsFolder: 'drizzle' }); + + return { + statusCode: 200, + body: JSON.stringify({ success: true, message: 'Migrations applied.' }), + }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { + statusCode: 500, + body: JSON.stringify({ success: false, error: errorMessage }), + }; + } +}; diff --git a/serverless/src/handlers/dbPing.ts b/serverless/src/handlers/dbPing.ts new file mode 100644 index 0000000..399018e --- /dev/null +++ b/serverless/src/handlers/dbPing.ts @@ -0,0 +1,23 @@ +import { APIGatewayProxyResult } from 'aws-lambda'; + +import { sql } from 'drizzle-orm'; + +import { getDb } from '../lib/db'; + +export const handler = async (): Promise => { + try { + const db = await getDb(); + const result = await db.execute(sql`select 1 as ok`); + + return { + statusCode: 200, + body: JSON.stringify({ success: true, result }), + }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : 'Unknown error'; + return { + statusCode: 500, + body: JSON.stringify({ success: false, error: errorMessage }), + }; + } +}; diff --git a/serverless/src/lib/db.ts b/serverless/src/lib/db.ts index e42fa26..a4f8118 100644 --- a/serverless/src/lib/db.ts +++ b/serverless/src/lib/db.ts @@ -1,2 +1,75 @@ -// Placeholder for database utilities -// Export database connection and helper functions here +import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager'; +import { drizzle, NodePgDatabase } from 'drizzle-orm/node-postgres'; +import { Pool } from 'pg'; + +import * as schema from '../db/schema'; + +type DbSecret = { + username: string; + password: string; +}; + +let cachedSecret: DbSecret | undefined; +let cachedPool: Pool | undefined; +let cachedDb: NodePgDatabase | undefined; + +function requireEnv(name: string): string { + const value = process.env[name]; + if (!value) { + throw new Error(`Missing required env var: ${name}`); + } + return value; +} + +async function getDbSecret(): Promise { + if (cachedSecret) return cachedSecret; + + const secretArn = requireEnv('DB_SECRET_ARN'); + const client = new SecretsManagerClient({}); + const result = await client.send( + new GetSecretValueCommand({ + SecretId: secretArn, + }), + ); + + if (!result.SecretString) { + throw new Error('SecretString was empty for DB_SECRET_ARN'); + } + + const parsed = JSON.parse(result.SecretString) as Partial; + if (!parsed.username || !parsed.password) { + throw new Error('DB secret missing username/password'); + } + + cachedSecret = { username: parsed.username, password: parsed.password }; + return cachedSecret; +} + +export async function getPool(): Promise { + if (cachedPool) return cachedPool; + + const host = requireEnv('DB_HOST'); + const port = Number.parseInt(requireEnv('DB_PORT'), 10); + const database = requireEnv('DB_NAME'); + const { username: user, password } = await getDbSecret(); + + cachedPool = new Pool({ + host, + port, + database, + user, + password, + max: 5, + idleTimeoutMillis: 30_000, + connectionTimeoutMillis: 10_000, + }); + + return cachedPool; +} + +export async function getDb(): Promise> { + if (cachedDb) return cachedDb; + const pool = await getPool(); + cachedDb = drizzle(pool, { schema }); + return cachedDb; +}