From 6c3b431ee2fbfadd1fd80e33655fbf6d5c593090 Mon Sep 17 00:00:00 2001 From: KarimTamani Date: Wed, 10 Jun 2026 18:09:54 +0100 Subject: [PATCH] Add Oracle & MSSQL Support --- package-lock.json | 5100 ++++++++--------- package.json | 7 +- public/sqldeveloper.png | Bin 0 -> 96782 bytes public/ssms.png | Bin 0 -> 67394 bytes src/App.tsx | 4 - .../components/db-controller/sql-preview.tsx | 55 +- .../database/modals/import-database.tsx | 128 +- src/hooks/user-render-sql.tsx | 62 - src/i18/languages/ar.ts | 19 +- src/i18/languages/de.ts | 19 +- src/i18/languages/en.ts | 17 + src/i18/languages/es.ts | 16 + src/i18/languages/fr.ts | 15 + src/i18/languages/hi.ts | 15 + src/i18/languages/pt.ts | 15 + src/i18/languages/ru.ts | 15 + src/i18/languages/zh.ts | 17 +- src/lib/data_types/mssql_data_types.ts | 175 + src/lib/data_types/oracle_data_types.ts | 151 + src/lib/data_types/seed_datatypes.ts | 6 +- src/lib/database.ts | 21 +- src/lib/field.ts | 3 +- src/lib/schemas/data-type-schema.ts | 2 +- .../database-provider/database-provider.tsx | 3 +- src/utils/import/base-sql-importer.ts | 780 +++ src/utils/import/import-utils.ts | 40 + src/utils/import/mariadb-importer.ts | 37 + src/utils/import/mssql-importer.ts | 702 +++ src/utils/import/mysql-importer.ts | 97 + src/utils/import/oracle-importer.ts | 725 +++ src/utils/import/postgresql-importer.ts | 284 + src/utils/import/sqlite-importer.ts | 60 + src/utils/migration.ts | 153 + .../render/database/base-database-renderer.ts | 389 ++ .../render/database/base-sql-renderer.ts | 306 + src/utils/render/database/mariadb-renderer.ts | 10 + .../database/mssql-database-renderer.ts | 203 + src/utils/render/database/mysql-renderer.ts | 91 + src/utils/render/database/oracle-renderer.ts | 196 + .../render/database/postgresql-renderer.ts | 157 + .../database/sqlite-database-renderer.ts | 110 + src/utils/render/parsers/database_to_ast.ts | 395 -- src/utils/render/parsers/sql_to_database.ts | 722 --- src/utils/render/render-uttils.ts | 39 + vite.config.ts | 2 +- 45 files changed, 7351 insertions(+), 4012 deletions(-) create mode 100644 public/sqldeveloper.png create mode 100644 public/ssms.png delete mode 100644 src/hooks/user-render-sql.tsx create mode 100644 src/lib/data_types/mssql_data_types.ts create mode 100644 src/lib/data_types/oracle_data_types.ts create mode 100644 src/utils/import/base-sql-importer.ts create mode 100644 src/utils/import/import-utils.ts create mode 100644 src/utils/import/mariadb-importer.ts create mode 100644 src/utils/import/mssql-importer.ts create mode 100644 src/utils/import/mysql-importer.ts create mode 100644 src/utils/import/oracle-importer.ts create mode 100644 src/utils/import/postgresql-importer.ts create mode 100644 src/utils/import/sqlite-importer.ts create mode 100644 src/utils/migration.ts create mode 100644 src/utils/render/database/base-database-renderer.ts create mode 100644 src/utils/render/database/base-sql-renderer.ts create mode 100644 src/utils/render/database/mariadb-renderer.ts create mode 100644 src/utils/render/database/mssql-database-renderer.ts create mode 100644 src/utils/render/database/mysql-renderer.ts create mode 100644 src/utils/render/database/oracle-renderer.ts create mode 100644 src/utils/render/database/postgresql-renderer.ts create mode 100644 src/utils/render/database/sqlite-database-renderer.ts delete mode 100644 src/utils/render/parsers/database_to_ast.ts delete mode 100644 src/utils/render/parsers/sql_to_database.ts diff --git a/package-lock.json b/package-lock.json index 0b1b923..6406d38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@codemirror/lang-sql": "^6.9.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", + "@guanmingchiu/sqlparser-ts": "^0.61.1", "@internationalized/date": "^3.8.2", "@nextui-org/react": "^2.6.11", "@powersync/drizzle-driver": "^0.4.0", @@ -76,15 +77,16 @@ }, "devDependencies": { "@types/better-sqlite3": "^7.6.13", - "@types/node": "20.5.7", + "@types/node": "20.19.0", "@types/object-hash": "^3.0.6", "@types/pluralize": "^0.0.33", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "@typescript-eslint/eslint-plugin": "8.11.0", "@typescript-eslint/parser": "8.11.0", - "@vitejs/plugin-react": "^4.2.1", + "@vitejs/plugin-react": "^6.0.2", "autoprefixer": "10.4.19", + "esbuild": "^0.28.0", "eslint": "^8.57.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-import": "^2.26.0", @@ -95,6 +97,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-unused-imports": "4.1.4", "prettier": "3.3.3", + "rollup": "^4.61.1", "tw-animate-css": "^1.3.6", "typescript": "5.6.3", "vite": "^8.0.3", @@ -102,321 +105,72 @@ "vite-tsconfig-paths": "^4.3.2" } }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", + "node_modules/@adobe/react-spectrum": { + "version": "3.47.1", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.47.1.tgz", + "integrity": "sha512-mijNyd8XmA6KoBMbqKc4Rp+S2voKdZkPydJFjQbG0SkOjOKcgqVpJdKGsKdLMZBn9Jk5SgEuklyrhc7Uvot2tA==", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", - "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", - "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.4", - "@babel/types": "^7.28.4", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" + "@internationalized/date": "^3.12.2", + "@react-types/shared": "^3.35.0", + "@spectrum-icons/ui": "^3.7.1", + "@spectrum-icons/workflow": "^4.3.1", + "@swc/helpers": "^0.5.0", + "client-only": "^0.0.1", + "clsx": "^2.0.0", + "react-aria": "3.49.0", + "react-aria-components": "1.18.0", + "react-stately": "3.47.0", + "react-transition-group": "^4.4.5", + "use-sync-external-store": "^1.6.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", - "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.4" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, + "node_modules/@adobe/react-spectrum-ui": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-ui/-/react-spectrum-ui-1.2.1.tgz", + "integrity": "sha512-wcrbEE2O/9WnEn6avBnaVRRx88S5PLFsPLr4wffzlbMfXeQsy+RMQwaJd3cbzrn18/j04Isit7f7Emfn0dhrJA==", + "license": "Apache-2.0", "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, + "node_modules/@adobe/react-spectrum-workflow": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-workflow/-/react-spectrum-workflow-2.3.5.tgz", + "integrity": "sha512-b53VIPwPWKb/T5gzE3qs+QlGP5gVrw/LnWV3xMksDU+CRl3rzOKUwxIGiZO8ICyYh1WiyqY4myGlPU/nAynBUg==", + "license": "Apache-2.0", "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@adobe/react-spectrum/node_modules/@react-types/shared": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", - "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", - "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@codemirror/autocomplete": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.19.0.tgz", - "integrity": "sha512-61Hfv3cF07XvUxNeC3E7jhG8XNi1Yom1G0lRC936oLnlF+jrbrv8rc/J98XlYzcsAoTVupfsf5fLej1aI8kyIg==", + "version": "6.20.3", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz", + "integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -426,13 +180,13 @@ } }, "node_modules/@codemirror/commands": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", - "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.3.tgz", + "integrity": "sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.4.0", + "@codemirror/state": "^6.6.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } @@ -452,45 +206,45 @@ } }, "node_modules/@codemirror/language": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.3.tgz", - "integrity": "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==", + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.3.tgz", + "integrity": "sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", - "@lezer/common": "^1.1.0", + "@lezer/common": "^1.5.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0", "style-mod": "^4.0.0" } }, "node_modules/@codemirror/lint": { - "version": "6.8.5", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", - "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz", + "integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.35.0", + "@codemirror/view": "^6.42.0", "crelt": "^1.0.5" } }, "node_modules/@codemirror/search": { - "version": "6.5.11", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz", - "integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.0.tgz", + "integrity": "sha512-ZvGm99wc/s2cITtMT15LFdn8aH/aS+V+DqyGq/N5ZlV5vWtH+nILvC2nw0zX7ByNoHHDZ2IxxdW38O0tc5nVHg==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", + "@codemirror/view": "^6.37.0", "crelt": "^1.0.5" } }, "node_modules/@codemirror/state": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", - "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.6.0.tgz", + "integrity": "sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==", "license": "MIT", "dependencies": { "@marijn/find-cluster-break": "^1.0.0" @@ -509,21 +263,21 @@ } }, "node_modules/@codemirror/view": { - "version": "6.38.3", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.3.tgz", - "integrity": "sha512-x2t87+oqwB1mduiQZ6huIghjMt4uZKFEdj66IcXw7+a5iBEvv9lh7EWDRHI7crnD4BMGpnyq/RzmCGbiEZLcvQ==", + "version": "6.43.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.1.tgz", + "integrity": "sha512-+BIjw/AG3tDQ4pJgTLPYdAW25eDE66YsvM4LKyVPgGzVgZ4a9Wj1SRX8kPVKgBDdPt8oHtZ15F0qx7p0oOHdHw==", "license": "MIT", "dependencies": { - "@codemirror/state": "^6.5.0", + "@codemirror/state": "^6.6.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "node_modules/@date-fns/tz": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.4.1.tgz", - "integrity": "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.5.0.tgz", + "integrity": "sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==", "license": "MIT" }, "node_modules/@dnd-kit/accessibility": { @@ -580,43 +334,482 @@ } }, "node_modules/@emnapi/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", - "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { - "@emnapi/wasi-threads": "1.2.0", + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", - "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", - "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -633,9 +826,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -667,9 +860,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -701,31 +894,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", - "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.10" + "@floating-ui/utils": "^0.2.11" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", - "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.3", - "@floating-ui/utils": "^0.2.10" + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", - "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.4" + "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { "react": ">=16.8.0", @@ -733,19 +926,19 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz", - "integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", "license": "MIT", "dependencies": { "@formatjs/fast-memoize": "2.2.7", - "@formatjs/intl-localematcher": "0.6.1", + "@formatjs/intl-localematcher": "0.6.2", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } @@ -760,35 +953,44 @@ } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz", - "integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.4", - "@formatjs/icu-skeleton-parser": "1.8.14", + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", "tslib": "^2.8.0" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.14", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz", - "integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==", + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/ecma402-abstract": "2.3.6", "tslib": "^2.8.0" } }, "node_modules/@formatjs/intl-localematcher": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz", - "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", "license": "MIT", "dependencies": { "tslib": "^2.8.0" } }, + "node_modules/@guanmingchiu/sqlparser-ts": { + "version": "0.61.1", + "resolved": "https://registry.npmjs.org/@guanmingchiu/sqlparser-ts/-/sqlparser-ts-0.61.1.tgz", + "integrity": "sha512-5RA05UHDkcm4cyhBNz2oJqU+8+fhCZvseSGtAvuVcwM1EEh2FfRaU1qdPygpriGqsQRT3Cn1PK5YShJffQjmXg==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -806,9 +1008,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -852,18 +1054,18 @@ "license": "BSD-3-Clause" }, "node_modules/@internationalized/date": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.9.0.tgz", - "integrity": "sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.2.tgz", + "integrity": "sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/message": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.8.tgz", - "integrity": "sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.10.tgz", + "integrity": "sha512-nc0Or6EdWHqZRcsXb6P9hBIpLsfSl/ILh0rk5h/OVBpzmhdExXtPy2cQtWsq8XKRBpRHwDNnAHt4OpolcB7dog==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", @@ -871,39 +1073,27 @@ } }, "node_modules/@internationalized/number": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz", - "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.7.tgz", + "integrity": "sha512-3ji1fcrT+FPAK86UqEhB/psHixYo6niWPJtt7+qRaYFynt/BaJG8GhAPimtWUpEiVSTq8ZM8L5psMxGquiB/Vg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/string": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.7.tgz", - "integrity": "sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.9.tgz", + "integrity": "sha512-kzP/M/mbQxODlmOt4bIQZ2SBVUWUSqMLXooXixnX7noche8WHaQcA+nwFN1K2KCF/cp+LDUhcJsCicwkvhD1pg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@journeyapps/wa-sqlite": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@journeyapps/wa-sqlite/-/wa-sqlite-1.3.2.tgz", - "integrity": "sha512-zZ0KF01an940DV2jJHHzeTvGlXZ8il/sWnI6a2hH3eV/LHtb5H0c6TB7WursE3c8BvNLifXre3R0mLM5OyNhgw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@journeyapps/wa-sqlite/-/wa-sqlite-1.7.0.tgz", + "integrity": "sha512-xQZ670aKDo4FWxIFpLqY0AGDpURr09aYIO08UkLdWvFw8C018nCiqY0ILJudGRhRdXORhv7K2xD2OXZ2QxU39w==", "hasInstallScript": true, "peer": true }, @@ -953,24 +1143,24 @@ } }, "node_modules/@lezer/common": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", - "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", + "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", "license": "MIT" }, "node_modules/@lezer/highlight": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", - "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz", + "integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==", "license": "MIT", "dependencies": { - "@lezer/common": "^1.0.0" + "@lezer/common": "^1.3.0" } }, "node_modules/@lezer/lr": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", - "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", + "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", "license": "MIT", "dependencies": { "@lezer/common": "^1.0.0" @@ -983,13 +1173,13 @@ "license": "MIT" }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", - "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", + "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", "license": "MIT", "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "@tybys/wasm-util": "^0.10.2" }, "funding": { "type": "github", @@ -2610,9 +2800,9 @@ } }, "node_modules/@nextui-org/theme/node_modules/tailwind-merge": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", - "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz", + "integrity": "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==", "license": "MIT", "funding": { "type": "github", @@ -3038,9 +3228,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.122.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", - "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -3060,11 +3250,12 @@ } }, "node_modules/@powersync/common": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/@powersync/common/-/common-1.38.1.tgz", - "integrity": "sha512-kSPDprIHV3FnNtDrkUOvuSYlH5G0SuOK74WjaXCnxIfxuwf73pFRYdBThczABJUqZ/iYC/csnweV/sUxK+6nog==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/@powersync/common/-/common-1.54.0.tgz", + "integrity": "sha512-/gzitw4iQL4UI7ILf7TUzCy/cfbDJGU3/aiN/ciaLtDd2Uts3wYARVKclSW0OJhPPisKCX0E8Ev/iZGQPbTgDA==", "license": "Apache-2.0", "dependencies": { + "event-iterator": "^2.0.0", "js-logger": "^1.6.1" } }, @@ -3079,62 +3270,60 @@ } }, "node_modules/@powersync/react": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@powersync/react/-/react-1.7.4.tgz", - "integrity": "sha512-I9T4FQbpv2/tCnV6O5Warf4Rkitni+zgVJS1poveSHwTigiLORbhN86JZkv8+2tK3sT/eo9DplbMHoy9fIHltQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@powersync/react/-/react-1.10.0.tgz", + "integrity": "sha512-orM29qocbF8zYTBM27j9nPNztyplpbNVaw8djpqxl8N2wESqHTbHOKpatg+Fa5aofgjzmrkiGwevJvCbiWYYWQ==", "license": "Apache-2.0", "peerDependencies": { - "@powersync/common": "^1.38.1", + "@powersync/common": "^1.51.0", "react": "*" } }, "node_modules/@powersync/web": { - "version": "1.26.2", - "resolved": "https://registry.npmjs.org/@powersync/web/-/web-1.26.2.tgz", - "integrity": "sha512-w1p6b7TwI3zBNT9gh75otAn16vuaTQtMS/1xABFIS8V5/Psn1ifGhYOWszAbrwFyIPo7DJKC7JVqiId+9rADlA==", + "version": "1.38.3", + "resolved": "https://registry.npmjs.org/@powersync/web/-/web-1.38.3.tgz", + "integrity": "sha512-rID0jWVhON68IxqfyomQzAK6kTKG6LH9PCjRovKDD3tuMRNiLrcZCS584JEbh7y6N+UHxIuDUckcUbi3ckeOmA==", "license": "Apache-2.0", "dependencies": { - "@powersync/common": "1.38.1", - "async-mutex": "^0.4.0", - "bson": "^6.6.0", + "@powersync/common": "1.54.0", "comlink": "^4.4.2", "commander": "^12.1.0" }, "bin": { - "powersync-web": "bin/powersync.js" + "powersync-web": "bin/powersync.cjs" }, "peerDependencies": { - "@journeyapps/wa-sqlite": "^1.3.1", - "@powersync/common": "^1.38.1" + "@journeyapps/wa-sqlite": "^1.5.0", + "@powersync/common": "^1.54.0" } }, "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.2.tgz", + "integrity": "sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.4.tgz", + "integrity": "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ==", "license": "MIT" }, "node_modules/@radix-ui/react-accordion": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", - "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.13.tgz", + "integrity": "sha512-xITxBB2p5m5tAe7M0F95kb4uAh7jSIKGlExMEm93HlW+XxZHV2eXFbPWLktd4JhRiwcnXNbO7iekcrbZy6ZCvA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collapsible": "1.1.12", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collapsible": "1.1.13", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -3152,12 +3341,12 @@ } }, "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.9.tgz", + "integrity": "sha512-yqHW5WQ/cTpU/un7dqqIKNy2iRU8BC0JB78PEzTfCCYvZu1U6W9KwObAniMk9nhSfyotKPQTYaUD/HB0f5muig==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", @@ -3175,16 +3364,16 @@ } }, "node_modules/@radix-ui/react-avatar": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", - "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.12.tgz", + "integrity": "sha512-NQCQyWC7QrDPhjMn8hUqFeU0lUrprIgm1AyMgLbzuQJibNnatdc3SSMo3/UGFu/eUkJUU1cEcKCnyhXTQzq6tA==", "license": "MIT", "dependencies": { - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-is-hydrated": "0.1.0", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-is-hydrated": "0.1.1", + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3202,19 +3391,19 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", - "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.13.tgz", + "integrity": "sha512-F0s8+p2XNpfc3k02zBfB0jPWbkHVG162+p7BdUMyJ2308QMqZ+oaclX+FAzKFovgL5OqRU+Rvy6f/vbdlJVaqA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3232,15 +3421,15 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.9.tgz", + "integrity": "sha512-zuSVi7ziP7uQRqc+yGxsKJfNkdyHv3ZKDaHe0gzg4dRgws96TPKWIiz84tVHP4GEcEl8bC0mdt17NkcxaJHmaQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", @@ -3258,9 +3447,9 @@ } }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz", + "integrity": "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3273,9 +3462,9 @@ } }, "node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.4.tgz", + "integrity": "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3288,25 +3477,25 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", - "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.16.tgz", + "integrity": "sha512-l9ok83YBclEZhbjgzt76Hw733e6cvRKPNgO6GJ/IETlufXG9p+fRu2wlvpImQvR6xdJ8h7J8J2DBvsPEiEsKMw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.9", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3324,9 +3513,9 @@ } }, "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz", + "integrity": "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3339,16 +3528,16 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.12.tgz", + "integrity": "sha512-MhoruH6xEzsbvOmo4TNgMfmtvRGyDZw4MDSdf4ybMHfezjqwzv6hyd4lsMzBp8K9Sn6sGzCF62x1I7BYUECXOg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-escape-keydown": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3366,18 +3555,18 @@ } }, "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", - "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.17.tgz", + "integrity": "sha512-S6b3Jm57sY5EdDyOMLkacbB0qMnKhy1RCKZCt795ZkmtUOAvojYIZ5p7dXHIh5Cyr3jCLLI5/g64V3FKLudZmw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.16", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-menu": "2.1.17", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -3395,9 +3584,9 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz", + "integrity": "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3410,14 +3599,14 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.9.tgz", + "integrity": "sha512-9Se8t+Zry+1rEOL7Y6l/4ANYU/TOtAtf8O2fKdwLltcaMcm6kOqYGbzO4tMFQ0bvzO920pRAoHpFZ4W85S3keQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3435,12 +3624,12 @@ } }, "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz", + "integrity": "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3453,12 +3642,12 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", - "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.9.tgz", + "integrity": "sha512-rDoTeMbCwRVcnmo7NGT9IlPo1yXmEI+xc1URP3oeewwZEV4mdTp1dYUhYbQdo4D1q2SjKVvv4N1gNY77QAQtjA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", @@ -3476,29 +3665,29 @@ } }, "node_modules/@radix-ui/react-menu": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", - "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.17.tgz", + "integrity": "sha512-fmbNnFyf+JYCN0DhhWnEdUTDnZD1mXaPQWivdsPIb8oOSbARfD3LIQJbLCG8a8QLCwoMxiJ7GVPIFcC8Dw8v2Q==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.9", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.0", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-roving-focus": "1.1.12", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-callback-ref": "1.1.2", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3516,21 +3705,21 @@ } }, "node_modules/@radix-ui/react-menubar": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", - "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.17.tgz", + "integrity": "sha512-AKtZ4O782yO7qwIyq73WpulYt1IHhQ0htDb6wNcxzxnSDCcSWMVBiU9ycpcA90XzQO4IVIxIErtak6Kg/Vt0rQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.16", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-menu": "2.1.17", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-roving-focus": "1.1.12", + "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -3548,26 +3737,26 @@ } }, "node_modules/@radix-ui/react-popover": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", - "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.16.tgz", + "integrity": "sha512-8brVpAU5Uq7Bh0c8EFc4ZTf2JJTYn0o+1L+CUJB3UYIOkTjKGMgoHvduylrahdmNlr3DfH0rFq2DrbNZXgaspw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.9", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.0", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3585,21 +3774,21 @@ } }, "node_modules/@radix-ui/react-popper": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", - "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.0.tgz", + "integrity": "sha512-9PB589e1aWZbrlFUHdz6WiPCL+xLZHQFX7oibqG/6Q0SwOkxDyQX9W/cyPa+sAPPKuC8cpLCpRczE5a/1DiwVQ==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" + "@radix-ui/react-arrow": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.2", + "@radix-ui/react-use-rect": "1.1.2", + "@radix-ui/react-use-size": "1.1.2", + "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3617,13 +3806,13 @@ } }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.11.tgz", + "integrity": "sha512-UEytdjgEh2tJGgD/gZK4FUx6t1rNIlM3U0DENhSrG7I75FGm1DnaDuVUWF1pWAWUwGmn1sCJ1VGHn8LhN1aTOw==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3641,13 +3830,12 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.6.tgz", + "integrity": "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3665,12 +3853,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.5.tgz", + "integrity": "sha512-zifXeB8Y88qCYx8PLZ5oQb32KwZub+s925mMoZsBBq9KUQqWKkREubTfs6ASjRPPBe7Jt9O8OHH89+95VG+grA==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", @@ -3688,21 +3876,21 @@ } }, "node_modules/@radix-ui/react-radio-group": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", - "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.4.0.tgz", + "integrity": "sha512-eHdV5bLx9sH+tBnbDjkIBdvQEH/c6MEtQYhTbxkaDK9qsIFFLtmJYEQFVdwhnruWotLfQmIuWEL/J+L3utE8rQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-roving-focus": "1.1.12", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-use-previous": "1.1.2", + "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3720,20 +3908,20 @@ } }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.12.tgz", + "integrity": "sha512-FvgPt1bRmg8Xt2QpF7NUZW3dE0ZQHGm41dAdgT2J2GJPoIXz+9Em3NobAxf4fupcxhgHu03E5CRiU2MWvObXyg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -3751,20 +3939,20 @@ } }, "node_modules/@radix-ui/react-scroll-area": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", - "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.11.tgz", + "integrity": "sha512-DS39ziOgea75U/TrXKU2/oKp0be2jrDHnzFLvahg/0iNAT1Zq16e4Uw0WXwyXvsK+mG3BRyMb7A3NRZMDuEXtQ==", "license": "MIT", "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/number": "1.1.2", + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3782,32 +3970,33 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", - "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.3.0.tgz", + "integrity": "sha512-mENc7WpJvJcW8hlMpzfFcHcEhTvYS5JMBmi9HVC1Q00uhBwML086MHYUV8QQdQv6lcu0Wg8dzd1RB8AFADcG/g==", "license": "MIT", "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3", + "@radix-ui/number": "1.1.2", + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.9", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.0", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-use-layout-effect": "1.1.2", + "@radix-ui/react-use-previous": "1.1.2", + "@radix-ui/react-visually-hidden": "1.2.5", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", @@ -3825,12 +4014,12 @@ } }, "node_modules/@radix-ui/react-separator": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", - "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.9.tgz", + "integrity": "sha512-gvgW+JV/Mbjj6darztTetnmElpQEzZrXpJvfj+dOxNAxiyHEAyUvEjjl4zxblvmjmKmi3jfPoy7ZdxzCuUBJSA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", @@ -3848,12 +4037,12 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.5.tgz", + "integrity": "sha512-rCMO3QsIVKv5JTY5CVbo2MvO77SpEqqYc8AvRE7OWqRDOIqAKjsp+DrmnY9uc8NPdxB5E2z47HTYGeE2+NTptg==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" + "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", @@ -3866,18 +4055,18 @@ } }, "node_modules/@radix-ui/react-switch": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", - "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.3.0.tgz", + "integrity": "sha512-GP1EZwhoZO/GGnhM1P5/2Vpm8iN8EnngyU0oezn2l78kN8tj25pyrvjIaT7azBhK615KSt+P2w39y57YV5jVkA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-use-previous": "1.1.2", + "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -3895,14 +4084,14 @@ } }, "node_modules/@radix-ui/react-toggle": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", - "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.11.tgz", + "integrity": "sha512-FikrKJemoBGZQ6uRID0HJqSPBP6D7OppdD2OhLl0ZYLlAyPXI7MezoYGmumwNkrAoRm35xXkb4C8JPfJZZzcaw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -3920,18 +4109,18 @@ } }, "node_modules/@radix-ui/react-toggle-group": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", - "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.12.tgz", + "integrity": "sha512-TEgECgJaWGAHJJZGzNNEYTNBdIXqX7LchANycpyP7DkfjmuiSN7ISt1k/ZRGVJgVJonsgP4vwaiKMn5utrcwWQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-toggle": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-roving-focus": "1.1.12", + "@radix-ui/react-toggle": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -3949,23 +4138,23 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", - "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.9.tgz", + "integrity": "sha512-u6F9MmTtBSLkiXNVDrtB/yPCZarM9smNswC24YYLV/M+bth6J3Gs3vlJezEoFwKZvPvxhCpUYdUnOsNG/0XOlA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-visually-hidden": "1.2.3" + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.0", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", @@ -3983,9 +4172,9 @@ } }, "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz", + "integrity": "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3998,13 +4187,13 @@ } }, "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.3.tgz", + "integrity": "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-effect-event": "0.0.3", + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -4017,12 +4206,12 @@ } }, "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz", + "integrity": "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -4035,12 +4224,12 @@ } }, "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.2.tgz", + "integrity": "sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -4053,13 +4242,10 @@ } }, "node_modules/@radix-ui/react-use-is-hydrated": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", - "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.1.tgz", + "integrity": "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A==", "license": "MIT", - "dependencies": { - "use-sync-external-store": "^1.5.0" - }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -4071,9 +4257,9 @@ } }, "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz", + "integrity": "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -4086,9 +4272,9 @@ } }, "node_modules/@radix-ui/react-use-previous": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.2.tgz", + "integrity": "sha512-IGBQPtRFdhN6MQ8dbegVmBq1LVZluya3F1jWY+puIcQC3MHctRwTDSBWCkL/3ZcnMJLTMJ++Z+ktmvg0F89iCw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -4101,12 +4287,12 @@ } }, "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.2.tgz", + "integrity": "sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==", "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.1" + "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -4119,12 +4305,12 @@ } }, "node_modules/@radix-ui/react-use-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.2.tgz", + "integrity": "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -4137,12 +4323,12 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.5.tgz", + "integrity": "sha512-tPcHNI3FajdDBFpl/Ez1m2WL0ufJqBKyHxMDBvKitopamK36WwBGOMicuMEZKkM5Wce41QxUyv6BsiqfrWBiGg==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", @@ -4160,9 +4346,9 @@ } }, "node_modules/@radix-ui/rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.2.tgz", + "integrity": "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==", "license": "MIT" }, "node_modules/@react-aria/breadcrumbs": { @@ -4245,122 +4431,20 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/checkbox/node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-aria/checkbox/node_modules/@react-aria/toggle": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.12.1.tgz", - "integrity": "sha512-XaFiRs1KEcIT6bTtVY/KTQxw4kinemj/UwXw2iJTu9XS43hhJ/9cvj8KzNGrKGqaxTpOYj62TnSHZbSiFViHDA==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.13.1.tgz", + "integrity": "sha512-1SPMBSrbT94Jsy7Wuv9SH2uPv7szGP7KgO4QGIAcF3e5kHwvGQJdMHY6+xR17slk8ICXfFojBqUKgpJjyY2+KQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/interactions": "^3.25.5", - "@react-aria/utils": "^3.30.1", - "@react-stately/toggle": "^3.9.1", - "@react-types/checkbox": "^3.10.1", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/checkbox/node_modules/@react-aria/toggle/node_modules/@react-aria/interactions": { - "version": "3.25.5", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.5.tgz", - "integrity": "sha512-EweYHOEvMwef/wsiEqV73KurX/OqnmbzKQa2fLxdULbec5+yDj6wVGaRHIzM4NiijIDe+bldEl5DG05CAKOAHA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.30.1", - "@react-stately/flags": "^3.1.2", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/checkbox/node_modules/@react-aria/toggle/node_modules/@react-aria/utils": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz", - "integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/checkbox/node_modules/@react-stately/toggle": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.9.1.tgz", - "integrity": "sha512-L6yUdE8xZfQhw4aEFZduF8u4v0VrpYrwWEA4Tu/4qwGIPukH0wd2W21Zpw+vAiLOaDKnxel1nXX68MWnm4QXpw==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.10.8", - "@react-types/checkbox": "^3.10.1", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/checkbox/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/checkbox/node_modules/@react-types/checkbox": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.10.1.tgz", - "integrity": "sha512-8ZqBoGBxtn6U/znpmyutGtBBaafUzcZnbuvYjwyRSONTrqQ0IhUq6jI/jbnE9r9SslIkbMB8IS1xRh2e63qmEQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/checkbox/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-aria/combobox": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.11.0.tgz", @@ -4469,194 +4553,19 @@ } }, "node_modules/@react-aria/grid": { - "version": "3.14.4", - "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.14.4.tgz", - "integrity": "sha512-l1FLQNKnoHpY4UClUTPUV0AqJ5bfAULEE0ErY86KznWLd+Hqzo7mHLqqDV02CDa/8mIUcdoax/MrYYIbPDlOZA==", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.15.1.tgz", + "integrity": "sha512-u/903msISq7V78lAJ1Nt4bElMTh6Pzp/bS+lFv79POkFeHWv4icb42egRI7D9YYjO1tYWmNHC5iTcxzvcnOWxQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.21.1", - "@react-aria/i18n": "^3.12.12", - "@react-aria/interactions": "^3.25.5", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/selection": "^3.25.1", - "@react-aria/utils": "^3.30.1", - "@react-stately/collections": "^3.12.7", - "@react-stately/grid": "^3.11.5", - "@react-stately/selection": "^3.20.5", - "@react-types/checkbox": "^3.10.1", - "@react-types/grid": "^3.3.5", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-aria/focus": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.21.1.tgz", - "integrity": "sha512-hmH1IhHlcQ2lSIxmki1biWzMbGgnhdxJUM0MFfzc71Rv6YAzhlx4kX3GYn4VNcjCeb6cdPv4RZ5vunV4kgMZYQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/interactions": "^3.25.5", - "@react-aria/utils": "^3.30.1", - "@react-types/shared": "^3.32.0", "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/grid/node_modules/@react-aria/i18n": { - "version": "3.12.12", - "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.12.tgz", - "integrity": "sha512-JN6p+Xc6Pu/qddGRoeYY6ARsrk2Oz7UiQc9nLEPOt3Ch+blJZKWwDjcpo/p6/wVZdD/2BgXS7El6q6+eMg7ibw==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.9.0", - "@internationalized/message": "^3.1.8", - "@internationalized/number": "^3.6.5", - "@internationalized/string": "^3.2.7", - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.30.1", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-aria/interactions": { - "version": "3.25.5", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.5.tgz", - "integrity": "sha512-EweYHOEvMwef/wsiEqV73KurX/OqnmbzKQa2fLxdULbec5+yDj6wVGaRHIzM4NiijIDe+bldEl5DG05CAKOAHA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.30.1", - "@react-stately/flags": "^3.1.2", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-aria/selection": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.25.1.tgz", - "integrity": "sha512-HG+k3rDjuhnXPdVyv9CKiebee2XNkFYeYZBxEGlK3/pFVBzndnc8BXNVrXSgtCHLs2d090JBVKl1k912BPbj0Q==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/focus": "^3.21.1", - "@react-aria/i18n": "^3.12.12", - "@react-aria/interactions": "^3.25.5", - "@react-aria/utils": "^3.30.1", - "@react-stately/selection": "^3.20.5", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-aria/utils": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz", - "integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-stately/collections": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.7.tgz", - "integrity": "sha512-0kQc0mI986GOCQHvRy4L0JQiotIK/KmEhR9Mu/6V0GoSdqg5QeUe4kyoNWj3bl03uQXme80v0L2jLHt+fOHHjA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-types/checkbox": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.10.1.tgz", - "integrity": "sha512-8ZqBoGBxtn6U/znpmyutGtBBaafUzcZnbuvYjwyRSONTrqQ0IhUq6jI/jbnE9r9SslIkbMB8IS1xRh2e63qmEQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-types/grid": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.3.5.tgz", - "integrity": "sha512-hG6J2KDfmOHitkWoCa/9DvY1nTO2wgMIApcFoqLv7AWJr9CzvVqo5tIhZZCXiT1AvU2kafJxu9e7sr5GxAT2YA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/grid/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-aria/i18n": { "version": "3.12.4", "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.4.tgz", @@ -4744,12 +4653,17 @@ } }, "node_modules/@react-aria/live-announcer": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.4.4.tgz", - "integrity": "sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.5.1.tgz", + "integrity": "sha512-kLvwHjM3D7KgdquiAhUpRnMLKFrvl2r8naDXqPUlSWGRG15wsJRLhQOHLxGp0Umyg7KcSA+OD1mhQV5aRv0P1w==", "license": "Apache-2.0", "dependencies": { - "@swc/helpers": "^0.5.0" + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-aria/menu": { @@ -4878,108 +4792,86 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/spinbutton": { - "version": "3.6.18", - "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.18.tgz", - "integrity": "sha512-dnmh7sNsprhYTpqCJhcuc9QJ9C/IG/o9TkgW5a9qcd2vS+dzEgqAiJKIMbJFG9kiJymv2NwIPysF12IWix+J3A==", + "node_modules/@react-aria/slider/node_modules/@react-types/shared": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", "license": "Apache-2.0", - "dependencies": { - "@react-aria/i18n": "^3.12.12", - "@react-aria/live-announcer": "^3.4.4", - "@react-aria/utils": "^3.30.1", - "@react-types/button": "^3.14.0", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/spinbutton/node_modules/@react-aria/i18n": { - "version": "3.12.12", - "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.12.tgz", - "integrity": "sha512-JN6p+Xc6Pu/qddGRoeYY6ARsrk2Oz7UiQc9nLEPOt3Ch+blJZKWwDjcpo/p6/wVZdD/2BgXS7El6q6+eMg7ibw==", - "license": "Apache-2.0", - "dependencies": { - "@internationalized/date": "^3.9.0", - "@internationalized/message": "^3.1.8", - "@internationalized/number": "^3.6.5", - "@internationalized/string": "^3.2.7", - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.30.1", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/spinbutton/node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/spinbutton/node_modules/@react-aria/utils": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz", - "integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==", + "node_modules/@react-aria/slider/node_modules/@react-types/slider": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.9.0.tgz", + "integrity": "sha512-gbQWB8LnucC+jhDi5Imd2ZDPbVuiHt0xzObGHWq6GTZ3slLgTvGQaHNO5h9+h7dZH0iFQOVNb6+TlyTsnjFuAw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", + "@react-aria/slider": "^3.9.0", + "@react-spectrum/slider": "^3.9.0", + "@react-stately/slider": "^3.8.0" + }, + "peerDependencies": { + "@react-spectrum/provider": "^3.0.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/slider/node_modules/@react-types/slider/node_modules/@react-aria/slider": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.9.1.tgz", + "integrity": "sha512-bFWhyM6mP9TzAjCpOKybS7x0RTsFa2+49XKytKN53xS7bdHEnWGbWpsdJ09qZ6z1fnrwFcq/j/hhj/0gVO8kdQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.34.0", "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/spinbutton/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", + "node_modules/@react-aria/slider/node_modules/@react-types/slider/node_modules/@react-spectrum/slider": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.9.1.tgz", + "integrity": "sha512-UMBZaaofQsAfH+2SPh2GyxlJjKmRkjVoY1ixybkz8Jh+pOPOFEMugAt3fuLMW22geOC5PXs6AxHYsNb0BwKVnQ==", "license": "Apache-2.0", "dependencies": { + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/spinbutton/node_modules/@react-types/button": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.14.0.tgz", - "integrity": "sha512-pXt1a+ElxiZyWpX0uznyjy5Z6EHhYxPcaXpccZXyn6coUo9jmCbgg14xR7Odo+JcbfaaISzZTDO7oGLVTcHnpA==", + "node_modules/@react-aria/slider/node_modules/@react-types/slider/node_modules/@react-stately/slider": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.8.1.tgz", + "integrity": "sha512-MSfiRJakgdp2FSPtDeViEgXbYjRBGXXSTvExUvDDZx2xiEmSgefEQ4WWwCWPN4tdWbRISZoCYrmG8mY04Gevpw==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.32.0" + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/spinbutton/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", + "node_modules/@react-aria/spinbutton": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.8.1.tgz", + "integrity": "sha512-mDed6rDI2JE3QCaX+QykRyw9GjiRAHY1+RqxX2DR0yEtW2n9GxTQfCR9KVnXm69eTgCoxDIa7okBCrHhYB8bUw==", "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" + }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-aria/ssr": { @@ -5013,120 +4905,61 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/switch/node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-aria/switch/node_modules/@react-aria/toggle": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.12.1.tgz", - "integrity": "sha512-XaFiRs1KEcIT6bTtVY/KTQxw4kinemj/UwXw2iJTu9XS43hhJ/9cvj8KzNGrKGqaxTpOYj62TnSHZbSiFViHDA==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.13.1.tgz", + "integrity": "sha512-1SPMBSrbT94Jsy7Wuv9SH2uPv7szGP7KgO4QGIAcF3e5kHwvGQJdMHY6+xR17slk8ICXfFojBqUKgpJjyY2+KQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/interactions": "^3.25.5", - "@react-aria/utils": "^3.30.1", - "@react-stately/toggle": "^3.9.1", - "@react-types/checkbox": "^3.10.1", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/switch/node_modules/@react-aria/toggle/node_modules/@react-aria/interactions": { - "version": "3.25.5", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.5.tgz", - "integrity": "sha512-EweYHOEvMwef/wsiEqV73KurX/OqnmbzKQa2fLxdULbec5+yDj6wVGaRHIzM4NiijIDe+bldEl5DG05CAKOAHA==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.30.1", - "@react-stately/flags": "^3.1.2", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", - "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/switch/node_modules/@react-aria/toggle/node_modules/@react-aria/utils": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz", - "integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==", - "license": "Apache-2.0", - "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/switch/node_modules/@react-stately/toggle": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.9.1.tgz", - "integrity": "sha512-L6yUdE8xZfQhw4aEFZduF8u4v0VrpYrwWEA4Tu/4qwGIPukH0wd2W21Zpw+vAiLOaDKnxel1nXX68MWnm4QXpw==", + "node_modules/@react-aria/switch/node_modules/@react-types/switch": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.6.0.tgz", + "integrity": "sha512-6pjDO5a35ovAAw5xsSJoftmUP1BhFzKazB5IuVBNTbeEvJjz/LC1NGkVV3sQX68ZDSZ0UyYLS7ENIVHKU+hjzA==", "license": "Apache-2.0", "dependencies": { - "@react-stately/utils": "^3.10.8", - "@react-types/checkbox": "^3.10.1", - "@react-types/shared": "^3.32.0", + "@react-aria/switch": "^3.8.0", + "@react-spectrum/switch": "^3.7.0" + }, + "peerDependencies": { + "@react-spectrum/provider": "^3.0.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/switch/node_modules/@react-types/switch/node_modules/@react-aria/switch": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.8.1.tgz", + "integrity": "sha512-WzkJG3xJnBdd9rdBxG+0RgWdopAqwI61Ni4ZQtA2rgFuG9UpZIrhsL7qgFO/+R6oEgoeGAMeUlvCf97Ppj2uTg==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/switch/node_modules/@react-types/switch/node_modules/@react-spectrum/switch": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/switch/-/switch-3.7.1.tgz", + "integrity": "sha512-71rSqseVrieCWxQpwCBbqY4F6bBo8IK/jM+r8ounN/WIkoMGhZkVigF8tSwd+/p8ym2tmJq6MoWn0he1taBo0Q==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum": "^3.47.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/switch/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/switch/node_modules/@react-types/checkbox": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.10.1.tgz", - "integrity": "sha512-8ZqBoGBxtn6U/znpmyutGtBBaafUzcZnbuvYjwyRSONTrqQ0IhUq6jI/jbnE9r9SslIkbMB8IS1xRh2e63qmEQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-aria/switch/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-aria/table": { @@ -5263,71 +5096,39 @@ } }, "node_modules/@react-aria/visually-hidden/node_modules/@react-aria/interactions": { - "version": "3.25.5", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.5.tgz", - "integrity": "sha512-EweYHOEvMwef/wsiEqV73KurX/OqnmbzKQa2fLxdULbec5+yDj6wVGaRHIzM4NiijIDe+bldEl5DG05CAKOAHA==", + "version": "3.28.1", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.28.1.tgz", + "integrity": "sha512-Bqb+HrD5I5MHS2SKBhISYqo2SW8Y2dfzgF/Y1lIJq7xqLxheo9vzxPGEHhz+XzkgGfoqEJx8A6a3C7uiqS3HWA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-aria/utils": "^3.30.1", - "@react-stately/flags": "^3.1.2", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/visually-hidden/node_modules/@react-aria/ssr": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", - "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-aria/visually-hidden/node_modules/@react-aria/utils": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.30.1.tgz", - "integrity": "sha512-zETcbDd6Vf9GbLndO6RiWJadIZsBU2MMm23rBACXLmpRztkrIqPEb2RVdlLaq1+GklDx0Ii6PfveVjx+8S5U6A==", + "version": "3.34.1", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.34.1.tgz", + "integrity": "sha512-H6+rGZL+0f58bBNaUMfctEnT+NogqwAk+nHiB8sR3K+YlQ37GTuCijy2U/pPvQtFMS5mURrjZeBH5JNNXsx14A==", "license": "Apache-2.0", "dependencies": { - "@react-aria/ssr": "^3.9.10", - "@react-stately/flags": "^3.1.2", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", "@swc/helpers": "^0.5.0", - "clsx": "^2.0.0" + "react-aria": "^3.48.0", + "react-stately": "^3.46.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-aria/visually-hidden/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-aria/visually-hidden/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", "license": "Apache-2.0", "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" @@ -5354,6 +5155,50 @@ "license": "MIT", "peer": true }, + "node_modules/@react-spectrum/dialog": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/dialog/-/dialog-3.10.1.tgz", + "integrity": "sha512-RMoZkKswUMFiEnAHZljEV1ybpMUjrS5RxkwWb3IFMo+ZtnLIeIT87k4DxoUJKOVrw3bnSsLRSTw1Fvf7jZ/eFw==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum": "^3.47.0", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-spectrum/listbox": { + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/listbox/-/listbox-3.16.1.tgz", + "integrity": "sha512-iQ7eym1zVR3wmOpOnmbKF0A+cbdzUGobZdNC/H9rdiyGkEE0OIrlk3z3APIFHfM/juK/LHXZ+srbF5LU8/sDCg==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum": "^3.47.0", + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-spectrum/provider": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.11.1.tgz", + "integrity": "sha512-TsoNdVdmlQ7L+75ILq5Yb3+wp/I1AtIeat0o+Y+ZBxP+TtWpwT1ZtCB5l3cplFVzHzOpZlzO0VaDrDP9ElGYDw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@adobe/react-spectrum": "^3.47.0", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-stately/calendar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.6.0.tgz", @@ -5419,6 +5264,20 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@react-stately/combobox/node_modules/@react-stately/select": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.10.1.tgz", + "integrity": "sha512-f7rVJO/YAfq33hienemL6fg95uZZQ+vIvcwzQelIr2WDZvyf3p4OPS1CMzcroyl3tNsYvG/Vy26dOuF4tu6vOA==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-stately/datepicker": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.11.0.tgz", @@ -5439,12 +5298,17 @@ } }, "node_modules/@react-stately/flags": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.1.2.tgz", - "integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.2.1.tgz", + "integrity": "sha512-WPw9z4SPYqQMuExCnBNrQyyxCWSi9CDYnVqca19bqxaHZRT/uL5nL+IGCPHHa70Y5rx39E5hYKl8Hf0QJ6XKyA==", "license": "Apache-2.0", "dependencies": { - "@swc/helpers": "^0.5.0" + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-stately/form": { @@ -5460,56 +5324,6 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-stately/grid": { - "version": "3.11.5", - "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.11.5.tgz", - "integrity": "sha512-4cNjGYaNkcVS2wZoNHUrMRICBpkHStYw57EVemP7MjiWEVu53kzPgR1Iwmti2WFCpi1Lwu0qWNeCfzKpXW4BTg==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.7", - "@react-stately/selection": "^3.20.5", - "@react-types/grid": "^3.3.5", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/grid/node_modules/@react-stately/collections": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.7.tgz", - "integrity": "sha512-0kQc0mI986GOCQHvRy4L0JQiotIK/KmEhR9Mu/6V0GoSdqg5QeUe4kyoNWj3bl03uQXme80v0L2jLHt+fOHHjA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/grid/node_modules/@react-types/grid": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.3.5.tgz", - "integrity": "sha512-hG6J2KDfmOHitkWoCa/9DvY1nTO2wgMIApcFoqLv7AWJr9CzvVqo5tIhZZCXiT1AvU2kafJxu9e7sr5GxAT2YA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/grid/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-stately/list": { "version": "3.11.1", "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.11.1.tgz", @@ -5571,171 +5385,18 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-stately/select": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.7.1.tgz", - "integrity": "sha512-vZt4j9yVyOTWWJoP9plXmYaPZH2uMxbjcGMDbiShwsFiK8C2m9b3Cvy44TZehfzCWzpMVR/DYxEYuonEIGA82Q==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/form": "^3.2.1", - "@react-stately/list": "^3.13.0", - "@react-stately/overlays": "^3.6.19", - "@react-types/select": "^3.10.1", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-stately/collections": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.7.tgz", - "integrity": "sha512-0kQc0mI986GOCQHvRy4L0JQiotIK/KmEhR9Mu/6V0GoSdqg5QeUe4kyoNWj3bl03uQXme80v0L2jLHt+fOHHjA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-stately/form": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.2.1.tgz", - "integrity": "sha512-btgOPXkwvd6fdWKoepy5Ue43o2932OSkQxozsR7US1ffFLcQc3SNlADHaRChIXSG8ffPo9t0/Sl4eRzaKu3RgQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-stately/list": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.13.0.tgz", - "integrity": "sha512-Panv8TmaY8lAl3R7CRhyUadhf2yid6VKsRDBCBB1FHQOOeL7lqIraz/oskvpabZincuaIUWqQhqYslC4a6dvuA==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/collections": "^3.12.7", - "@react-stately/selection": "^3.20.5", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-stately/overlays": { - "version": "3.6.19", - "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.19.tgz", - "integrity": "sha512-swZXfDvxTYd7tKEpijEHBFFaEmbbnCvEhGlmrAz4K72cuRR9O5u+lcla8y1veGBbBSzrIdKNdBoIIJ+qQH+1TQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-stately/utils": "^3.10.8", - "@react-types/overlays": "^3.9.1", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-types/overlays": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.9.1.tgz", - "integrity": "sha512-UCG3TOu8FLk4j0Pr1nlhv0opcwMoqbGEOUvsSr6ITN6Qs2y0j+KYSYQ7a4+04m3dN//8+9Wjkkid8k+V1dV2CA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-types/select": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.10.1.tgz", - "integrity": "sha512-teANUr1byOzGsS/r2j7PatV470JrOhKP8En9lscfnqW5CeUghr+0NxkALnPkiEhCObi/Vu8GIcPareD0HNhtFA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/select/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-stately/selection": { - "version": "3.20.5", - "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.20.5.tgz", - "integrity": "sha512-YezWUNEn2pz5mQlbhmngiX9HqQsruLSXlkrAzB1DD6aliGrUvPKufTTGCixOaB8KVeCamdiFAgx1WomNplzdQA==", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.21.1.tgz", + "integrity": "sha512-Tq8UfAOG5SCxnTYivyYQH5NRpiuEJG2k20wmJ/s4Db0FnnjYg1xbKe55vu2A9ni/nUTLKUMj7MFaJytMIXPwxg==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.7", - "@react-stately/utils": "^3.10.8", - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/selection/node_modules/@react-stately/collections": { - "version": "3.12.7", - "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.7.tgz", - "integrity": "sha512-0kQc0mI986GOCQHvRy4L0JQiotIK/KmEhR9Mu/6V0GoSdqg5QeUe4kyoNWj3bl03uQXme80v0L2jLHt+fOHHjA==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0", - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/selection/node_modules/@react-stately/utils": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.8.tgz", - "integrity": "sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-stately/selection/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-stately/slider": { @@ -5753,6 +5414,74 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@react-stately/slider/node_modules/@react-types/shared": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/slider/node_modules/@react-types/slider": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.9.0.tgz", + "integrity": "sha512-gbQWB8LnucC+jhDi5Imd2ZDPbVuiHt0xzObGHWq6GTZ3slLgTvGQaHNO5h9+h7dZH0iFQOVNb6+TlyTsnjFuAw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/slider": "^3.9.0", + "@react-spectrum/slider": "^3.9.0", + "@react-stately/slider": "^3.8.0" + }, + "peerDependencies": { + "@react-spectrum/provider": "^3.0.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/slider/node_modules/@react-types/slider/node_modules/@react-aria/slider": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.9.1.tgz", + "integrity": "sha512-bFWhyM6mP9TzAjCpOKybS7x0RTsFa2+49XKytKN53xS7bdHEnWGbWpsdJ09qZ6z1fnrwFcq/j/hhj/0gVO8kdQ==", + "license": "Apache-2.0", + "dependencies": { + "@react-types/shared": "^3.34.0", + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/slider/node_modules/@react-types/slider/node_modules/@react-spectrum/slider": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.9.1.tgz", + "integrity": "sha512-UMBZaaofQsAfH+2SPh2GyxlJjKmRkjVoY1ixybkz8Jh+pOPOFEMugAt3fuLMW22geOC5PXs6AxHYsNb0BwKVnQ==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum": "^3.47.0", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-stately/slider/node_modules/@react-types/slider/node_modules/@react-stately/slider": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.8.1.tgz", + "integrity": "sha512-MSfiRJakgdp2FSPtDeViEgXbYjRBGXXSTvExUvDDZx2xiEmSgefEQ4WWwCWPN4tdWbRISZoCYrmG8mY04Gevpw==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-stately/table": { "version": "3.13.0", "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.13.0.tgz", @@ -5773,6 +5502,20 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@react-stately/table/node_modules/@react-stately/grid": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.12.1.tgz", + "integrity": "sha512-GvOXlPtzoswhyV3bZK3habHdHBGR7qdzOy2WumYiNG7DAj8J+9WvAObrPmquuI2VrZYMSNzgFb3IoL+sQsMI8A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-stately": "^3.46.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-stately/tabs": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.7.0.tgz", @@ -5949,37 +5692,32 @@ } }, "node_modules/@react-types/dialog": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.21.tgz", - "integrity": "sha512-jF1gN4bvwYamsLjefaFDnaSKxTa3Wtvn5f7WLjNVZ8ICVoiMBMdUJXTlPQHAL4YWqtCj4hK/3uimR1E+Pwd7Xw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.6.0.tgz", + "integrity": "sha512-vvxohmsTRZWE/saaJt6mMy3ONA4xbQTSk1okfMUK6OMSp/VpLBRLCz/2/myiMK3UIBCagUnrwzOwbk9whnFx0g==", "license": "Apache-2.0", "dependencies": { - "@react-types/overlays": "^3.9.1", - "@react-types/shared": "^3.32.0" + "@react-aria/dialog": "^3.6.0", + "@react-spectrum/dialog": "^3.10.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "@react-spectrum/provider": "^3.0.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-types/dialog/node_modules/@react-types/overlays": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.9.1.tgz", - "integrity": "sha512-UCG3TOu8FLk4j0Pr1nlhv0opcwMoqbGEOUvsSr6ITN6Qs2y0j+KYSYQ7a4+04m3dN//8+9Wjkkid8k+V1dV2CA==", + "node_modules/@react-types/dialog/node_modules/@react-aria/dialog": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.6.1.tgz", + "integrity": "sha512-Eo3Kj23TjENuERUYrGkH+VN1PJvK8/zep76pfwBg29erUVDpGdfagYRq82aGcxJ/ohG8iRxZDwp2tTrU1RG1MQ==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.32.0" + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/dialog/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/form": { @@ -6019,24 +5757,32 @@ } }, "node_modules/@react-types/listbox": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.7.3.tgz", - "integrity": "sha512-ONgror9uyGmIer5XxpRRNcc8QFVWiOzINrMKyaS8G4l3aP52ZwYpRfwMAVtra8lkVNvXDmO7hthPZkB6RYdNOA==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.8.0.tgz", + "integrity": "sha512-6l/P1mYQUQ7hGW6x8cH/EB8YvRzhhoB536G/GI7t2F2FbjcGkA1kNXhzDo24tLTXi9elnehevEEySRsRa9p6VA==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.32.0" + "@react-aria/listbox": "^3.16.0", + "@react-spectrum/listbox": "^3.16.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "@react-spectrum/provider": "^3.0.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-types/listbox/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", + "node_modules/@react-types/listbox/node_modules/@react-aria/listbox": { + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.16.1.tgz", + "integrity": "sha512-FbNeUXmo/H2Qp+yKboNod1eVhfmQDv1YexzEIAHsKL5Cx8uA7wZID9Pbq28jPC4plPISgS5KLBodaDikOXqviA==", "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "react-aria": "^3.48.0" + }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/menu": { @@ -6109,48 +5855,6 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, - "node_modules/@react-types/slider": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.8.1.tgz", - "integrity": "sha512-WxiQWj6iQr5Uft0/KcB9XSr361XnyTmL6eREZZacngA9CjPhRWYP3BRDPcCTuP7fj9Yi4QKMrryyjHqMHP8OKQ==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/slider/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/switch": { - "version": "3.5.14", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.14.tgz", - "integrity": "sha512-M8kIv97i+ejCel4Ho+Y7tDbpOehymGwPA4ChxibeyD32+deyxu5B6BXxgKiL3l+oTLQ8ihLo3sRESdPFw8vpQg==", - "license": "Apache-2.0", - "dependencies": { - "@react-types/shared": "^3.32.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, - "node_modules/@react-types/switch/node_modules/@react-types/shared": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.32.0.tgz", - "integrity": "sha512-t+cligIJsZYFMSPFMvsJMjzlzde06tZMOIOFa1OV5Z0BcMowrb2g4mB57j/9nP28iJIRYn10xCniQts+qadrqQ==", - "license": "Apache-2.0", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" - } - }, "node_modules/@react-types/table": { "version": "3.10.3", "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.10.3.tgz", @@ -6220,9 +5924,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", "cpu": [ "arm64" ], @@ -6236,9 +5940,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", "cpu": [ "arm64" ], @@ -6252,9 +5956,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", - "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", "cpu": [ "x64" ], @@ -6268,9 +5972,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", - "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", "cpu": [ "x64" ], @@ -6284,9 +5988,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", - "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", "cpu": [ "arm" ], @@ -6300,9 +6004,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", "cpu": [ "arm64" ], @@ -6316,9 +6020,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", - "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", "cpu": [ "arm64" ], @@ -6332,9 +6036,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", "cpu": [ "ppc64" ], @@ -6348,9 +6052,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", "cpu": [ "s390x" ], @@ -6364,9 +6068,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", - "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", "cpu": [ "x64" ], @@ -6380,9 +6084,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", - "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", "cpu": [ "x64" ], @@ -6396,9 +6100,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", - "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", "cpu": [ "arm64" ], @@ -6412,25 +6116,27 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", - "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", "cpu": [ "wasm32" ], "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">=14.0.0" + "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", - "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", "cpu": [ "arm64" ], @@ -6444,9 +6150,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", - "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", "cpu": [ "x64" ], @@ -6460,10 +6166,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "dev": true, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "license": "MIT" }, "node_modules/@rollup/plugin-virtual": { @@ -6484,15 +6189,14 @@ } } }, -<<<<<<< HEAD -======= "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", - "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", + "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6500,12 +6204,13 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", - "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", + "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6513,12 +6218,13 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", - "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", + "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6526,12 +6232,13 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", - "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", + "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6539,12 +6246,13 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", - "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", + "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6552,12 +6260,13 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", - "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", + "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6565,12 +6274,13 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", - "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", + "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6578,12 +6288,13 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", - "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", + "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6591,12 +6302,13 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", - "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", + "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6604,12 +6316,13 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", - "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", + "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6617,12 +6330,13 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", - "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", + "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6630,12 +6344,13 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", - "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", + "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6643,12 +6358,13 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", - "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", + "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6656,12 +6372,13 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", - "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", + "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6669,12 +6386,13 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", - "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", + "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6682,12 +6400,13 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", - "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", + "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6695,12 +6414,13 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", - "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", + "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6708,12 +6428,13 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", - "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", + "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6721,12 +6442,13 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", - "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", + "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6734,12 +6456,13 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", - "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", + "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6747,12 +6470,13 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", - "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", + "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6760,12 +6484,13 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", - "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", + "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6773,12 +6498,13 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", - "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", + "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6786,12 +6512,13 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", - "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", + "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -6799,19 +6526,19 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", - "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", + "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ "win32" ] }, ->>>>>>> e3d52a7 (Bump rollup from 4.52.2 to 4.60.1) "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -6819,16 +6546,47 @@ "dev": true, "license": "MIT" }, + "node_modules/@spectrum-icons/ui": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.7.1.tgz", + "integrity": "sha512-veQymocUYo5OciXQajSailOdbWe+k6+2ehfF8D4d0V923D4xOUadtT253xXZ5vEQjPat6Kyp2WDKeQNjd7kL1w==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum-ui": "1.2.1", + "@babel/runtime": "^7.24.4", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "@adobe/react-spectrum": "^3.47.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@spectrum-icons/workflow": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.3.1.tgz", + "integrity": "sha512-kDF+/EbFVyLGytotqqdYt4uSij4j/PQmDQO5km/C6DyzKjyuic3FnSBFinR+mA6oFv1OjMcLvrrDBqK3wbqRlA==", + "license": "Apache-2.0", + "dependencies": { + "@adobe/react-spectrum-workflow": "2.3.5", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "@adobe/react-spectrum": "^3.47.0", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@swc/core": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.19.tgz", - "integrity": "sha512-V1r4wFdjaZIUIZZrV2Mb/prEeu03xvSm6oatPxsvnXKF9lNh5Jtk9QvUdiVfD9rrvi7bXrAVhg9Wpbmv/2Fl1g==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.41.tgz", + "integrity": "sha512-03nQq/082QRJJiOvp3FGbgxTGyyxMxohPTjhk/W9bD2J0tk4ukITI7goOhOO2WbaHn/lsPmo/zf8+DIXhwpgYQ==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.25" + "@swc/types": "^0.1.26" }, "engines": { "node": ">=10" @@ -6838,16 +6596,18 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.13.19", - "@swc/core-darwin-x64": "1.13.19", - "@swc/core-linux-arm-gnueabihf": "1.13.19", - "@swc/core-linux-arm64-gnu": "1.13.19", - "@swc/core-linux-arm64-musl": "1.13.19", - "@swc/core-linux-x64-gnu": "1.13.19", - "@swc/core-linux-x64-musl": "1.13.19", - "@swc/core-win32-arm64-msvc": "1.13.19", - "@swc/core-win32-ia32-msvc": "1.13.19", - "@swc/core-win32-x64-msvc": "1.13.19" + "@swc/core-darwin-arm64": "1.15.41", + "@swc/core-darwin-x64": "1.15.41", + "@swc/core-linux-arm-gnueabihf": "1.15.41", + "@swc/core-linux-arm64-gnu": "1.15.41", + "@swc/core-linux-arm64-musl": "1.15.41", + "@swc/core-linux-ppc64-gnu": "1.15.41", + "@swc/core-linux-s390x-gnu": "1.15.41", + "@swc/core-linux-x64-gnu": "1.15.41", + "@swc/core-linux-x64-musl": "1.15.41", + "@swc/core-win32-arm64-msvc": "1.15.41", + "@swc/core-win32-ia32-msvc": "1.15.41", + "@swc/core-win32-x64-msvc": "1.15.41" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" @@ -6859,9 +6619,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.19.tgz", - "integrity": "sha512-NxDyte9tCJSJ8+R62WDtqwg8eI57lubD52sHyGOfezpJBOPr36bUSGGLyO3Vod9zTGlOu2CpkuzA/2iVw92u1g==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.41.tgz", + "integrity": "sha512-kREh6J5paQFvP3i7f/4FbqRNOJREutVFVOkder4GVyCBQ39YmER55cW/y1NNjwrchzFqgYswFn0mMDCqbqKzrw==", "cpu": [ "arm64" ], @@ -6876,9 +6636,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.19.tgz", - "integrity": "sha512-+w5DYrJndSygFFRDcuPYmx5BljD6oYnAohZ15K1L6SfORHp/BTSIbgSFRKPoyhjuIkDiq3W0um8RoMTOBAcQjQ==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.41.tgz", + "integrity": "sha512-N8B56ESFazZAWZyIkecADSPCwlLEinW7QLMEeotCpv4J7VXwfH+OLkmRL8o96UZ+1355fwHxDTS6/wK7yucvkA==", "cpu": [ "x64" ], @@ -6893,9 +6653,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.19.tgz", - "integrity": "sha512-7LlfgpdwwYq2q7himNkAAFo4q6jysMLFNoBH6GRP7WL29NcSsl5mPMJjmYZymK+sYq/9MTVieDTQvChzYDsapw==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.41.tgz", + "integrity": "sha512-6XrId2fyle0mS5xxON8rU84mPd2Cq1kDJRj+4BnQKTd7u+2kSA6Ww+JkOP0iTNqOqt9OXhPOEAjBHAuonWcdCg==", "cpu": [ "arm" ], @@ -6910,9 +6670,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.19.tgz", - "integrity": "sha512-ml3I6Lm2marAQ3UC/TS9t/yILBh/eDSVHAdPpikp652xouWAVW1znUeV6bBSxe1sSZIenv+p55ubKAWq/u84sQ==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.41.tgz", + "integrity": "sha512-ynLIarxlkVnqHn1D0fKOVht6mNU5ks6lrH+MY3kkS+XFaGGgDxFZVjWKJlkYTKm3RCvBTfA8Ng5fLufXheMRKQ==", "cpu": [ "arm64" ], @@ -6927,9 +6687,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.19.tgz", - "integrity": "sha512-M/otFc3/rWWkbF6VgbOXVzUKVoE7MFcphTaStxJp4bwb7oP5slYlxMZN51Dk/OTOfvCDo9pTAFDKNyixbkXMDQ==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.41.tgz", + "integrity": "sha512-dXu/5vd4gh8symyhRF+4G7gOPkjmb4pONhh7sl+6GSiW0LOKZlfu5kXmyFbTz9smOT7jgr002qY9b1nujjXt2A==", "cpu": [ "arm64" ], @@ -6943,10 +6703,44 @@ "node": ">=10" } }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.41.tgz", + "integrity": "sha512-XGO6zVPXoPE0gf/XnI4jBbafNT13AYgoh6ns0JCSdOetI/kqVf0vhpz7NuNgAzZrMVCsmieqjPoTwViDgh4mOQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.41.tgz", + "integrity": "sha512-0WUglRwyZtW+iMi7J3iFdrCxreZZIKf4egTwEQfIYRsqFax69A0OrFj+NIoFSE03xBT/IFRrg+S8K6f9Ky+4hA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.19.tgz", - "integrity": "sha512-NoMUKaOJEdouU4tKF88ggdDHFiRRING+gYLxDqnTfm+sUXaizB5OGBRzvSVDYSXQb1SuUuChnXFPFzwTWbt3ZQ==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.41.tgz", + "integrity": "sha512-VxkuQK59c0tHm6uJZCUrS3cyA2JhGGfdU6e41SZz0x/JS+4Sm7C1mIc97In14vkZJopEt7yXA2TouCqZDSygEA==", "cpu": [ "x64" ], @@ -6961,9 +6755,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.19.tgz", - "integrity": "sha512-r6krlZwyu8SBaw24QuS1lau2I9q8M+eJV6ITz0rpb6P1Bx0elf9ii5Bhh8ddmIqXXH8kOGSjC/dwcdHbZqAhgw==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.41.tgz", + "integrity": "sha512-/0qXIu1ZxggLuovLb22vFfKHq2AA4n6Whw5UwmVCHk4pkw7KWnPIQpMCEqUMPsNkFJig7PPp/TSYFu8ZEb2rtQ==", "cpu": [ "x64" ], @@ -6978,9 +6772,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.19.tgz", - "integrity": "sha512-awcZSIuxyVn0Dw28VjMvgk1qiDJ6CeQwHkZNUjg2UxVlq23zE01NMMp+zkoGFypmLG9gaGmJSzuoqvk/WCQ5tw==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.41.tgz", + "integrity": "sha512-Y481sMNZM6rECh9VO4+y26N1lWEDAyxnBZskUf37fl90uHE946VHfmiVQWT0uMFOhyJJFovGTRuF4W82dwewUg==", "cpu": [ "arm64" ], @@ -6995,9 +6789,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.19.tgz", - "integrity": "sha512-H5d+KO7ISoLNgYvTbOcCQjJZNM3R7yaYlrMAF13lUr6GSiOUX+92xtM31B+HvzAWI7HtvVe74d29aC1b1TpXFA==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.41.tgz", + "integrity": "sha512-BAchBD5qeUzy3hiPSLJtaaoSm4blCLyYffOF1bGE4ETcV+OisqjUAwDQMJj++4bTpvMCDzwC+Bj3PmQyBCtscw==", "cpu": [ "ia32" ], @@ -7012,9 +6806,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.19.tgz", - "integrity": "sha512-qNoyCpXvv2O3JqXKanRIeoMn03Fho/As+N4Fhe7u0FsYh4VYqGQah4DGDzEP/yjl4Gx1IElhqLGDhCCGMwWaDw==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.41.tgz", + "integrity": "sha512-WOkA+fJ/ViVBQDsSV9JC52NACTe5PhlurA6viASDZGb7HR3KS01ZG7RZ+Bg6SVQFIoq3gSbTsskQVe6EbHFAYw==", "cpu": [ "x64" ], @@ -7036,18 +6830,18 @@ "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", - "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" } }, "node_modules/@swc/types": { - "version": "0.1.25", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", - "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz", + "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -7055,16 +6849,25 @@ } }, "node_modules/@swc/wasm": { - "version": "1.13.19", - "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.13.19.tgz", - "integrity": "sha512-CtmxrM/VgT/x6U3O3FcT/RAE1/MtTEIgq3jtHeAE0TpiTOor/nl2lib7iMXkUy4jx9F4HZGyoVzyATYDsNK0jg==", + "version": "1.15.41", + "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.15.41.tgz", + "integrity": "sha512-wFocmIRY5pSvqxzvJbsKiHyP6oNrSPqBbicF1TV3n0E1ZekSQm/hG9cbRYwxd2pVGL4Nmg8JNpIeLSwRS97Gdg==", "dev": true, "license": "Apache-2.0" }, + "node_modules/@tabby_ai/hijri-converter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@tabby_ai/hijri-converter/-/hijri-converter-1.0.5.tgz", + "integrity": "sha512-r5bClKrcIusDoo049dSL8CawnHR6mRdDwhlQuIgZRNty68q0x8k3Lf1BtPAMxRf/GgnHBnIO4ujd3+GQdLWzxQ==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@tabler/icons": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.35.0.tgz", - "integrity": "sha512-yYXe+gJ56xlZFiXwV9zVoe3FWCGuZ/D7/G4ZIlDtGxSx5CGQK110wrnT29gUj52kEZoxqF7oURTk97GQxELOFQ==", + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.44.0.tgz", + "integrity": "sha512-Wn0AOZG9sg0L+bjfMqq4eNhC6pQjIrk94LvvWYNYkY8KH8wC3YILRzQlrnVJc4FUeMxH/AK97QsYCX35H3LndA==", "license": "MIT", "funding": { "type": "github", @@ -7072,12 +6875,12 @@ } }, "node_modules/@tabler/icons-react": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.35.0.tgz", - "integrity": "sha512-XG7t2DYf3DyHT5jxFNp5xyLVbL4hMJYJhiSdHADzAjLRYfL7AnjlRfiHDHeXxkb2N103rEIvTsBRazxXtAUz2g==", + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.44.0.tgz", + "integrity": "sha512-8+rvzBbVm/1Z3sG3x7GUNAaxIKxwgz8xaMhRs23nrCnMTKRFAhEC+82zAIFeAA0seXdrAGX5HFCkaLpGK2rVHg==", "license": "MIT", "dependencies": { - "@tabler/icons": "3.35.0" + "@tabler/icons": "3.44.0" }, "funding": { "type": "github", @@ -7088,52 +6891,47 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.13.tgz", - "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", + "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", "license": "MIT", "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", - "jiti": "^2.5.1", - "lightningcss": "1.30.1", - "magic-string": "^0.30.18", + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.21.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.13" + "tailwindcss": "4.3.0" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.13.tgz", - "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==", - "hasInstallScript": true, + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", + "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, "engines": { - "node": ">= 10" + "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-x64": "4.1.13", - "@tailwindcss/oxide-freebsd-x64": "4.1.13", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.13", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-x64-musl": "4.1.13", - "@tailwindcss/oxide-wasm32-wasi": "4.1.13", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.13" + "@tailwindcss/oxide-android-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-x64": "4.3.0", + "@tailwindcss/oxide-freebsd-x64": "4.3.0", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-x64-musl": "4.3.0", + "@tailwindcss/oxide-wasm32-wasi": "4.3.0", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz", - "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", + "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", "cpu": [ "arm64" ], @@ -7143,13 +6941,13 @@ "android" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz", - "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", + "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", "cpu": [ "arm64" ], @@ -7159,13 +6957,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz", - "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", + "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", "cpu": [ "x64" ], @@ -7175,13 +6973,13 @@ "darwin" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz", - "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", + "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", "cpu": [ "x64" ], @@ -7191,13 +6989,13 @@ "freebsd" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz", - "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", + "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", "cpu": [ "arm" ], @@ -7207,13 +7005,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz", - "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", + "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", "cpu": [ "arm64" ], @@ -7223,13 +7021,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz", - "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", + "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", "cpu": [ "arm64" ], @@ -7239,13 +7037,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz", - "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", + "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", "cpu": [ "x64" ], @@ -7255,13 +7053,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz", - "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", + "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", "cpu": [ "x64" ], @@ -7271,13 +7069,13 @@ "linux" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz", - "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", + "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -7292,75 +7090,21 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.5", - "@emnapi/runtime": "^1.4.5", - "@emnapi/wasi-threads": "^1.0.4", - "@napi-rs/wasm-runtime": "^0.2.12", - "@tybys/wasm-util": "^0.10.0", - "tslib": "^2.8.0" + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.4.5", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.4", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.4.5", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.10.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.0", - "inBundle": true, - "license": "0BSD", - "optional": true - }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz", - "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", + "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", "cpu": [ "arm64" ], @@ -7370,13 +7114,13 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz", - "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", + "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", "cpu": [ "x64" ], @@ -7386,33 +7130,33 @@ "win32" ], "engines": { - "node": ">= 10" + "node": ">= 20" } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", - "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.20.tgz", + "integrity": "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==", "license": "MIT", "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + "tailwindcss": ">=3.0.0 || >=4.0.0 || insiders" } }, "node_modules/@tailwindcss/vite": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.13.tgz", - "integrity": "sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==", "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.1.13", - "@tailwindcss/oxide": "4.1.13", - "tailwindcss": "4.1.13" + "@tailwindcss/node": "4.3.0", + "@tailwindcss/oxide": "4.3.0", + "tailwindcss": "4.3.0" }, "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "node_modules/@tanstack/react-virtual": { @@ -7443,60 +7187,15 @@ } }, "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, "node_modules/@types/better-sqlite3": { "version": "7.6.13", "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.13.tgz", @@ -7556,6 +7255,13 @@ "@types/d3-selection": "*" } }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -7564,9 +7270,9 @@ "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", "license": "MIT" }, "node_modules/@types/lodash-es": { @@ -7588,11 +7294,14 @@ } }, "node_modules/@types/node": { - "version": "20.5.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", - "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", + "version": "20.19.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.0.tgz", + "integrity": "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==", "devOptional": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } }, "node_modules/@types/object-hash": { "version": "3.0.6", @@ -7833,9 +7542,9 @@ } }, "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.25.2", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.25.2.tgz", - "integrity": "sha512-s2fbpdXrSMWEc86moll/d007ZFhu6jzwNu5cWv/2o7egymvLeZO52LWkewgbr+BUCGWGPsoJVWeaejbsb/hLcw==", + "version": "4.25.10", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.25.10.tgz", + "integrity": "sha512-P3vytLlpE62KYSWrMUnwDCv2lvaQDuDZzyj03mHntuHo5bSl34fRZpjTY3kQTPGuXHxkGSYpoPFFj+hMTqaaMQ==", "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.0.0", @@ -7860,16 +7569,16 @@ } }, "node_modules/@uiw/react-codemirror": { - "version": "4.25.2", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.25.2.tgz", - "integrity": "sha512-XP3R1xyE0CP6Q0iR0xf3ed+cJzJnfmbLelgJR6osVVtMStGGZP3pGQjjwDRYptmjGHfEELUyyBLdY25h0BQg7w==", + "version": "4.25.10", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.25.10.tgz", + "integrity": "sha512-DzgSMwM5qzB7v1FIb4gEeriYt67iiay756/HIOM9mAbeOVK0MO7rqefHf0O5c0269pJKMW7AH9FjclExD23V9w==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.18.6", "@codemirror/commands": "^6.1.0", "@codemirror/state": "^6.1.1", "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.25.2", + "@uiw/codemirror-extensions-basic-setup": "4.25.10", "codemirror": "^6.0.0" }, "funding": { @@ -7886,52 +7595,67 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz", + "integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==", "dev": true, "license": "ISC" }, "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz", + "integrity": "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" + "@rolldown/pluginutils": "^1.0.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } } }, "node_modules/@xyflow/react": { - "version": "12.8.6", - "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.8.6.tgz", - "integrity": "sha512-SksAm2m4ySupjChphMmzvm55djtgMDPr+eovPDdTnyGvShf73cvydfoBfWDFllooIQ4IaiUL5yfxHRwU0c37EA==", + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.11.0.tgz", + "integrity": "sha512-na4IO33FSs2OS72hASgZDmTYwFAkef7Z74uBUVrong3ARmQQHfnRUVaCFn1kTt5LbS6pK03TbYjCPGLjLFfziA==", "license": "MIT", "dependencies": { - "@xyflow/system": "0.0.70", + "@xyflow/system": "0.0.77", "classcat": "^5.0.3", "zustand": "^4.4.0" }, "peerDependencies": { + "@types/react": ">=17", + "@types/react-dom": ">=17", "react": ">=17", "react-dom": ">=17" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, "node_modules/@xyflow/system": { - "version": "0.0.70", - "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.70.tgz", - "integrity": "sha512-PpC//u9zxdjj0tfTSmZrg3+sRbTz6kop/Amky44U2Dl51sxzDTIUfXMwETOYpmr2dqICWXBIJwXL2a9QWtX2XA==", + "version": "0.0.77", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.77.tgz", + "integrity": "sha512-qCDCMCQAAgUu8yHnhloHG9F5mwPX5E+Wl8McpYIOPSSXfzFJJoZcwOcsDiAjitVKIg2de1WmJbCHfpcvxprsgg==", "license": "MIT", "dependencies": { "@types/d3-drag": "^3.0.7", @@ -7946,9 +7670,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -7969,9 +7693,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -8216,15 +7940,6 @@ "node": ">= 0.4" } }, - "node_modules/async-mutex": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.1.tgz", - "integrity": "sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/autoprefixer": { "version": "10.4.19", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", @@ -8280,9 +7995,9 @@ } }, "node_modules/axe-core": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz", + "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==", "dev": true, "license": "MPL-2.0", "engines": { @@ -8307,13 +8022,16 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.7.tgz", - "integrity": "sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==", + "version": "2.10.35", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.35.tgz", + "integrity": "sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/big-integer": { @@ -8326,9 +8044,9 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", + "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", "dev": true, "license": "MIT", "dependencies": { @@ -8349,9 +8067,9 @@ } }, "node_modules/browserslist": { - "version": "4.26.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz", - "integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -8369,11 +8087,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.3", - "caniuse-lite": "^1.0.30001741", - "electron-to-chromium": "^1.5.218", - "node-releases": "^2.0.21", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -8382,25 +8100,16 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bson": { - "version": "6.10.4", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz", - "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==", - "license": "Apache-2.0", - "engines": { - "node": ">=16.20.1" - } - }, "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" }, "engines": { @@ -8452,9 +8161,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001745", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001745.tgz", - "integrity": "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==", + "version": "1.0.30001797", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz", + "integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==", "dev": true, "funding": [ { @@ -8489,15 +8198,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", @@ -8522,6 +8222,12 @@ "integrity": "sha512-1inzZmicIFcmUya7PGtUQeXtcF7zZpPnxtQoYOrz0uiOBGlLFa4ik4361seYL2JCcRDIyfdFHiwQolESFlw+Og==", "license": "MIT" }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -8637,13 +8343,6 @@ "dev": true, "license": "MIT" }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", @@ -8678,10 +8377,9 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, "node_modules/d3-color": { @@ -8851,9 +8549,9 @@ } }, "node_modules/date-fns": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", - "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz", + "integrity": "sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==", "license": "MIT", "funding": { "type": "github", @@ -8867,9 +8565,9 @@ "license": "MIT" }, "node_modules/dayjs": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", - "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", + "version": "1.11.21", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz", + "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==", "license": "MIT" }, "node_modules/debug": { @@ -8949,9 +8647,9 @@ } }, "node_modules/detect-libc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.1.tgz", - "integrity": "sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -8994,6 +8692,16 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/drizzle-orm": { "version": "0.43.1", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.43.1.tgz", @@ -9131,9 +8839,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.224", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.224.tgz", - "integrity": "sha512-kWAoUu/bwzvnhpdZSIc6KUyvkI1rbRXMT0Eq8pKReyOyaPZcctMli+EgvcN1PAvwVc7Tdo4Fxi2PsLNDU05mdg==", + "version": "1.5.371", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.371.tgz", + "integrity": "sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w==", "dev": true, "license": "ISC" }, @@ -9151,22 +8859,22 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.23.0.tgz", + "integrity": "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.3" }, "engines": { "node": ">=10.13.0" } }, "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", "dev": true, "license": "MIT", "dependencies": { @@ -9253,37 +8961,37 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", - "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.3.tgz", + "integrity": "sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.6", + "es-abstract": "^1.24.2", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.3", + "es-set-tostringtag": "^2.1.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.6", + "get-intrinsic": "^1.3.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", - "iterator.prototype": "^1.1.4", - "safe-array-concat": "^1.1.3" + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -9340,6 +9048,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -9434,15 +9184,15 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", "dev": true, "license": "MIT", "dependencies": { "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -9456,9 +9206,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", - "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.13.0.tgz", + "integrity": "sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9538,9 +9288,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -9625,9 +9375,9 @@ } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -9670,9 +9420,9 @@ } }, "node_modules/eslint-plugin-node/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -9693,6 +9443,28 @@ "node": "*" } }, + "node_modules/eslint-plugin-node/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/eslint-plugin-node/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -9781,9 +9553,9 @@ } }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -9817,24 +9589,6 @@ "node": "*" } }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/eslint-plugin-react/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -9918,9 +9672,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -9960,9 +9714,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10005,6 +9759,12 @@ "node": ">=0.10.0" } }, + "node_modules/event-iterator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/event-iterator/-/event-iterator-2.0.0.tgz", + "integrity": "sha512-KGft0ldl31BZVV//jj+IAIGCxkvvUkkON+ScH6zfoX+l+omX6001ggyRSpI0Io2Hlro0ThXotswCtfzS8UkIiQ==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -10069,9 +9829,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "license": "ISC", "dependencies": { @@ -10271,14 +10031,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" } }, "node_modules/get-intrinsic": { @@ -10351,7 +10111,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -10383,9 +10143,9 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "dev": true, "license": "MIT", "dependencies": { @@ -10554,9 +10314,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -10586,30 +10346,27 @@ } }, "node_modules/i18next": { - "version": "25.5.2", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.5.2.tgz", - "integrity": "sha512-lW8Zeh37i/o0zVr+NoCHfNnfvVw+M6FQbRp36ZZ/NyHDJ3NJVpp2HhAUyU9WafL5AssymNoOjMRB48mmx2P6Hw==", + "version": "26.3.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.1.tgz", + "integrity": "sha512-txQqd5EULsqEh9OJqRH15aCaOuy/nLJyhw5EHCSKLKJE1aBbb3Zve2+uQIxgWhPm1QqUQoWyQBm2kfmmIrzkcQ==", "funding": [ { "type": "individual", - "url": "https://locize.com" - }, - { - "type": "individual", - "url": "https://locize.com/i18next.html" + "url": "https://www.locize.com/i18next" }, { "type": "individual", "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + }, + { + "type": "individual", + "url": "https://www.locize.com" } ], "license": "MIT", "peer": true, - "dependencies": { - "@babel/runtime": "^7.27.6" - }, "peerDependencies": { - "typescript": "^5" + "typescript": "^5 || ^6" }, "peerDependenciesMeta": { "typescript": { @@ -10618,9 +10375,9 @@ } }, "node_modules/i18next-browser-languagedetector": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.0.tgz", - "integrity": "sha512-P+3zEKLnOF0qmiesW383vsLdtQVyKtCNA9cjSoKCppTKPQVfKd2W8hbVo5ZhNJKDqeM7BOcvNoKJOjpHh4Js9g==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-8.2.1.tgz", + "integrity": "sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.23.2" @@ -10708,14 +10465,14 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.16", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz", - "integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==", + "version": "10.7.18", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", - "@formatjs/icu-messageformat-parser": "2.11.2", + "@formatjs/icu-messageformat-parser": "2.11.4", "tslib": "^2.8.0" } }, @@ -10810,13 +10567,13 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -10887,14 +10644,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -11159,9 +10917,9 @@ } }, "node_modules/jiti": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.0.tgz", - "integrity": "sha512-VXe6RjJkBPj0ohtqaO8vSWP3ZhAKo66fKrFNCll4BTcwljPLz03pCbaNKfzGP5MbrCYcbJ7v0nOYYwUzTEIdXQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -11180,10 +10938,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -11192,19 +10960,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -11227,16 +10982,16 @@ "license": "MIT" }, "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, "bin": { "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" } }, "node_modules/jsx-ast-utils": { @@ -11300,9 +11055,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -11315,16 +11070,17 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { @@ -11348,9 +11104,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -11368,9 +11124,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], @@ -11388,9 +11144,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], @@ -11408,9 +11164,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], @@ -11428,9 +11184,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], @@ -11448,9 +11204,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], @@ -11468,9 +11224,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], @@ -11488,9 +11244,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], @@ -11508,9 +11264,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], @@ -11528,9 +11284,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], @@ -11594,16 +11350,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/lucide-react": { "version": "0.501.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.501.0.tgz", @@ -11614,9 +11360,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.19", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", - "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -11682,31 +11428,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/moo": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", - "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.3.tgz", + "integrity": "sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==", "license": "BSD-3-Clause" }, "node_modules/motion-dom": { @@ -11732,9 +11457,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -11784,17 +11509,49 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, - "node_modules/node-releases": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.21.tgz", - "integrity": "sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==", + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/node-sql-parser": { - "version": "5.3.12", - "resolved": "https://registry.npmjs.org/node-sql-parser/-/node-sql-parser-5.3.12.tgz", - "integrity": "sha512-GQBwA2e44qjbK0MzFwh5bNYefniV6cKT4KfjNDpuh/2EWipUEK1BCMc//moSidp8EF6fHB/EqJwUH9GCh9MAPg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/node-sql-parser/-/node-sql-parser-5.4.0.tgz", + "integrity": "sha512-jVe6Z61gPcPjCElPZ6j8llB3wnqGcuQzefim1ERsqIakxnEy5JlzV7XKdO1KmacRG5TKwPc4vJTgSRQ0LfkbFw==", "license": "Apache-2.0", "dependencies": { "@types/pegjs": "^0.10.0", @@ -11818,7 +11575,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12075,9 +11831,9 @@ "license": "MIT" }, "node_modules/pgsql-ast-parser": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/pgsql-ast-parser/-/pgsql-ast-parser-12.0.1.tgz", - "integrity": "sha512-pe8C6Zh5MsS+o38WlSu18NhrTjAv1UNMeDTs2/Km2ZReZdYBYtwtbWGZKK2BM2izv5CrQpbmP0oI10wvHOwv4A==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/pgsql-ast-parser/-/pgsql-ast-parser-12.0.2.tgz", + "integrity": "sha512-1WWa96Sw6h4uv9GLw98EzH/+xoBTC8j2TwV/AMW3E+Ir/fHOu/jLLbj6kPiz3y2bGISTKNYvKWwHoqvQ5FLuAw==", "license": "MIT", "dependencies": { "moo": "^0.5.1", @@ -12123,9 +11879,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", "funding": [ { "type": "opencollective", @@ -12142,7 +11898,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -12197,9 +11953,9 @@ } }, "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz", + "integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==", "dev": true, "license": "MIT", "dependencies": { @@ -12213,7 +11969,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -12283,15 +12038,73 @@ "node": ">=0.10.0" } }, + "node_modules/react-aria": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.49.0.tgz", + "integrity": "sha512-4+oK9FwJQWYhyA5zLfj/feOGY0zZbkE1muoF4gyxMroHVypjcYaRSTlJwvxph2zIlxt757KX6xIK2wJ5Aw1Kog==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.2", + "@internationalized/number": "^3.6.7", + "@internationalized/string": "^3.2.9", + "@react-types/shared": "^3.35.0", + "@swc/helpers": "^0.5.0", + "aria-hidden": "^1.2.3", + "clsx": "^2.0.0", + "react-stately": "3.47.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-aria-components": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.18.0.tgz", + "integrity": "sha512-FhRQjuDkH4WhgFv+O2sYTzK3JzdZTGpBeaqfRlfTo+DcSZzD8elJEkytHe7SDpcexVKeire8NVd7OruZHfCVoA==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.2", + "@react-types/shared": "^3.35.0", + "@swc/helpers": "^0.5.0", + "client-only": "^0.0.1", + "react-aria": "3.49.0", + "react-stately": "3.47.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-aria-components/node_modules/@react-types/shared": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-aria/node_modules/@react-types/shared": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/react-day-picker": { - "version": "9.11.0", - "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.11.0.tgz", - "integrity": "sha512-L4FYOaPrr3+AEROeP6IG2mCORZZfxJDkJI2df8mv1jyPrNYeccgmFPZDaHyAuPCBCddQFozkxbikj2NhMEYfDQ==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.14.0.tgz", + "integrity": "sha512-tBaoDWjPwe0M5pGrum4H0SR6Lyk+BO9oHnp9JbKpGKW2mlraNPgP9BMfsg5pWpwrssARmeqk7YBl2oXutZTaHA==", "license": "MIT", "dependencies": { "@date-fns/tz": "^1.4.1", + "@tabby_ai/hijri-converter": "1.0.5", "date-fns": "^4.1.0", - "date-fns-jalali": "^4.1.0-0" + "date-fns-jalali": "4.1.0-0" }, "engines": { "node": ">=18" @@ -12390,20 +12203,10 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, - "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-remove-scroll": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", - "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.7", @@ -12489,6 +12292,32 @@ "react-dom": ">=16.8" } }, + "node_modules/react-stately": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.47.0.tgz", + "integrity": "sha512-H3ar+SOWP920EbVg7qWfP3fZjZiwhlEJAEJQqjt+w8oKijCwFgr0+R4941PIHscOXRNRvEOjvWilitImC0DdBg==", + "license": "Apache-2.0", + "dependencies": { + "@internationalized/date": "^3.12.2", + "@internationalized/number": "^3.6.7", + "@internationalized/string": "^3.2.9", + "@react-types/shared": "^3.35.0", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/react-stately/node_modules/@react-types/shared": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.35.0.tgz", + "integrity": "sha512-iNWvuzEwANttpQpdlu8nPBtdHb0mcCMj1ZTH//iRB5E/14IAnyRlR25rxH7pNLyzHINsPGEKnWvpwDMCT6vziQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/react-style-singleton": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", @@ -12549,6 +12378,22 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/redux": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", @@ -12617,13 +12462,16 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -12684,21 +12532,14 @@ "url": "https://github.com/sponsors/isaacs" } }, -<<<<<<< HEAD "node_modules/rolldown": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", - "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", -======= - "node_modules/rollup": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", - "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", ->>>>>>> e3d52a7 (Bump rollup from 4.52.2 to 4.60.1) + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.122.0", - "@rolldown/pluginutils": "1.0.0-rc.12" + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" }, "bin": { "rolldown": "bin/cli.mjs" @@ -12707,57 +12548,67 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { -<<<<<<< HEAD - "@rolldown/binding-android-arm64": "1.0.0-rc.12", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", - "@rolldown/binding-darwin-x64": "1.0.0-rc.12", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" -======= - "@rollup/rollup-android-arm-eabi": "4.60.1", - "@rollup/rollup-android-arm64": "4.60.1", - "@rollup/rollup-darwin-arm64": "4.60.1", - "@rollup/rollup-darwin-x64": "4.60.1", - "@rollup/rollup-freebsd-arm64": "4.60.1", - "@rollup/rollup-freebsd-x64": "4.60.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", - "@rollup/rollup-linux-arm-musleabihf": "4.60.1", - "@rollup/rollup-linux-arm64-gnu": "4.60.1", - "@rollup/rollup-linux-arm64-musl": "4.60.1", - "@rollup/rollup-linux-loong64-gnu": "4.60.1", - "@rollup/rollup-linux-loong64-musl": "4.60.1", - "@rollup/rollup-linux-ppc64-gnu": "4.60.1", - "@rollup/rollup-linux-ppc64-musl": "4.60.1", - "@rollup/rollup-linux-riscv64-gnu": "4.60.1", - "@rollup/rollup-linux-riscv64-musl": "4.60.1", - "@rollup/rollup-linux-s390x-gnu": "4.60.1", - "@rollup/rollup-linux-x64-gnu": "4.60.1", - "@rollup/rollup-linux-x64-musl": "4.60.1", - "@rollup/rollup-openbsd-x64": "4.60.1", - "@rollup/rollup-openharmony-arm64": "4.60.1", - "@rollup/rollup-win32-arm64-msvc": "4.60.1", - "@rollup/rollup-win32-ia32-msvc": "4.60.1", - "@rollup/rollup-win32-x64-gnu": "4.60.1", - "@rollup/rollup-win32-x64-msvc": "4.60.1", - "fsevents": "~2.3.2" ->>>>>>> e3d52a7 (Bump rollup from 4.52.2 to 4.60.1) + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" } }, - "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", - "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", - "license": "MIT" + "node_modules/rollup": { + "version": "4.61.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", + "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.61.1", + "@rollup/rollup-android-arm64": "4.61.1", + "@rollup/rollup-darwin-arm64": "4.61.1", + "@rollup/rollup-darwin-x64": "4.61.1", + "@rollup/rollup-freebsd-arm64": "4.61.1", + "@rollup/rollup-freebsd-x64": "4.61.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", + "@rollup/rollup-linux-arm-musleabihf": "4.61.1", + "@rollup/rollup-linux-arm64-gnu": "4.61.1", + "@rollup/rollup-linux-arm64-musl": "4.61.1", + "@rollup/rollup-linux-loong64-gnu": "4.61.1", + "@rollup/rollup-linux-loong64-musl": "4.61.1", + "@rollup/rollup-linux-ppc64-gnu": "4.61.1", + "@rollup/rollup-linux-ppc64-musl": "4.61.1", + "@rollup/rollup-linux-riscv64-gnu": "4.61.1", + "@rollup/rollup-linux-riscv64-musl": "4.61.1", + "@rollup/rollup-linux-s390x-gnu": "4.61.1", + "@rollup/rollup-linux-x64-gnu": "4.61.1", + "@rollup/rollup-linux-x64-musl": "4.61.1", + "@rollup/rollup-openbsd-x64": "4.61.1", + "@rollup/rollup-openharmony-arm64": "4.61.1", + "@rollup/rollup-win32-arm64-msvc": "4.61.1", + "@rollup/rollup-win32-ia32-msvc": "4.61.1", + "@rollup/rollup-win32-x64-gnu": "4.61.1", + "@rollup/rollup-win32-x64-msvc": "4.61.1", + "fsevents": "~2.3.2" + } }, "node_modules/run-parallel": { "version": "1.2.0", @@ -12784,15 +12635,15 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, @@ -12857,9 +12708,9 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", "dev": true, "license": "ISC", "bin": { @@ -12942,15 +12793,15 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -12962,14 +12813,14 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -13046,9 +12897,9 @@ } }, "node_modules/sql-formatter": { - "version": "15.6.9", - "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.6.9.tgz", - "integrity": "sha512-r9VKnkRfKW7jbhTgytwbM+JqmFclQYN9L58Z3UTktuy9V1f1Y+rGK3t70Truh2wIOJzvZkzobAQ2PwGjjXsr6Q==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.8.1.tgz", + "integrity": "sha512-nT2r90kTEYBuse9fe4r1Rp78v1mOBD35KsGc07Vo9eQSVa1TcTSnCS0zouf6BCmdzvmqBsBW+cYuBoYkHO/OWg==", "license": "MIT", "dependencies": { "argparse": "^2.0.1", @@ -13127,19 +12978,20 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -13149,16 +13001,16 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.2" }, "engines": { "node": ">= 0.4" @@ -13222,9 +13074,9 @@ } }, "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz", + "integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==", "license": "MIT" }, "node_modules/supports-color": { @@ -13271,9 +13123,9 @@ } }, "node_modules/tailwind-merge": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", - "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", "license": "MIT", "funding": { "type": "github", @@ -13297,9 +13149,9 @@ } }, "node_modules/tailwind-variants/node_modules/tailwind-merge": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", - "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz", + "integrity": "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==", "license": "MIT", "funding": { "type": "github", @@ -13307,9 +13159,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", - "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", + "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", "license": "MIT" }, "node_modules/tailwindcss-animate": { @@ -13322,9 +13174,9 @@ } }, "node_modules/tapable": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", - "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "license": "MIT", "engines": { "node": ">=6" @@ -13334,31 +13186,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/tar": { - "version": "7.5.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", - "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -13367,13 +13194,13 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -13471,19 +13298,6 @@ "strip-bom": "^3.0.0" } }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -13584,18 +13398,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" }, "engines": { "node": ">= 0.4" @@ -13637,10 +13451,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -13767,18 +13588,18 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", - "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/use-undo": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/use-undo/-/use-undo-1.1.1.tgz", - "integrity": "sha512-2NNpJv7TDQpyETgRTG5I/CsABX5nhExpx8PEhWiDsnW9C5BA6Xnn8G9u/lPeg3+JsBrBtUx8/5bMbGmpnWz1Cw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-undo/-/use-undo-1.2.0.tgz", + "integrity": "sha512-ZzrdoHH67DCMuWbTQ14MKX2YRhzzCZMd9dtiaSu3mLzxd/iXfvKY6m6qCIAlU/Psmq328o2o4PvM/keGijXCIA==", "license": "MIT", "peerDependencies": { "react": ">=16.8.6", @@ -13792,9 +13613,9 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -13818,16 +13639,16 @@ } }, "node_modules/vite": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", - "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.16.tgz", + "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", - "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.12", - "tinyglobby": "^0.2.15" + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" }, "bin": { "vite": "bin/vite.js" @@ -13843,8 +13664,8 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.1.0", - "esbuild": "^0.27.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", @@ -13914,6 +13735,7 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "dev": true, "funding": [ "https://github.com/sponsors/broofa", @@ -13944,235 +13766,6 @@ } } }, - "node_modules/vite/node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" - } - }, - "node_modules/vite/node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/vite/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -14284,14 +13877,14 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", + "call-bind": "^1.0.9", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", @@ -14322,13 +13915,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 7ff17f6..a29d272 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@codemirror/lang-sql": "^6.9.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", + "@guanmingchiu/sqlparser-ts": "^0.61.1", "@internationalized/date": "^3.8.2", "@nextui-org/react": "^2.6.11", "@powersync/drizzle-driver": "^0.4.0", @@ -78,15 +79,16 @@ }, "devDependencies": { "@types/better-sqlite3": "^7.6.13", - "@types/node": "20.5.7", + "@types/node": "20.19.0", "@types/object-hash": "^3.0.6", "@types/pluralize": "^0.0.33", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", "@typescript-eslint/eslint-plugin": "8.11.0", "@typescript-eslint/parser": "8.11.0", - "@vitejs/plugin-react": "^4.2.1", + "@vitejs/plugin-react": "^6.0.2", "autoprefixer": "10.4.19", + "esbuild": "^0.28.0", "eslint": "^8.57.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-import": "^2.26.0", @@ -97,6 +99,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-unused-imports": "4.1.4", "prettier": "3.3.3", + "rollup": "^4.61.1", "tw-animate-css": "^1.3.6", "typescript": "5.6.3", "vite": "^8.0.3", diff --git a/public/sqldeveloper.png b/public/sqldeveloper.png new file mode 100644 index 0000000000000000000000000000000000000000..0e657a3ae92d04dfd28e292a4fc12eae85482e55 GIT binary patch literal 96782 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 literal 0 HcmV?d00001 diff --git a/src/App.tsx b/src/App.tsx index a43b559..b2c1853 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,6 @@ import "@/styles/globals.css" - import { ReactFlowProvider } from "@xyflow/react"; import useAppRoutes from "./routes/app-route"; import { SyncProvider } from "./providers/sync-provider/sync-provider"; @@ -10,8 +9,6 @@ import DiagramProvider from "./providers/diagram-provider/diagram-provider"; import { ModalProvider } from "./providers/modal-provider/modal-provider"; import DatabaseHotkeysProvider from "./providers/database-hotkeys/database-hotkeys-provider"; - - function App() { const appRoutes = useAppRoutes(); @@ -21,7 +18,6 @@ function App() { - {appRoutes} diff --git a/src/features/database/components/db-controller/sql-preview.tsx b/src/features/database/components/db-controller/sql-preview.tsx index 58544fa..1a199ea 100644 --- a/src/features/database/components/db-controller/sql-preview.tsx +++ b/src/features/database/components/db-controller/sql-preview.tsx @@ -1,11 +1,9 @@ -import { useRenderSql } from "@/hooks/user-render-sql"; -import { useDatabase } from "@/providers/database-provider/database-provider"; -import React, { useEffect, useMemo } from "react"; - + +import { useDatabase, useDatabaseOperations } from "@/providers/database-provider/database-provider"; +import React, { useEffect, useMemo, useState } from "react"; import CodeMirror from '@uiw/react-codemirror'; import { sql } from '@codemirror/lang-sql'; import { oneDark } from '@codemirror/theme-one-dark'; - import { overrideDarkTheme, overrideLightTheme } from "@/lib/colors"; import { DatabaseType } from "@/lib/schemas/database-schema"; import CircularDependencyAlert from "./circular-dependecy-alert"; @@ -13,21 +11,26 @@ import { useTranslation } from "react-i18next"; import Clipboard from "@/components/clipboard"; import { TableType } from "@/lib/schemas/table-schema"; import { RelationshipType } from "@/lib/schemas/relationship-schema"; - import { useTheme } from "@/providers/theme-provider/theme-provider"; import { toast } from "sonner"; +import BaseDatabaseRenderer from "@/utils/render/database/base-database-renderer"; +import { CircularDependencyError, getRenderer } from "@/utils/render/render-uttils"; +import { areArraysEqual } from "@/utils/utils"; interface SqlPreviewProps { tableFilterIds?: string[] } - - - const SqlPreview: React.FC = ({ tableFilterIds }) => { + const { database: currentDatabase } = useDatabase(); + const { data_types } = useDatabaseOperations(); + const [sqlCode, setSqlCode] = useState(""); + + const [circularDependency, setCircularDependency] = useState(undefined); + const database = useMemo(() => { if (!tableFilterIds) return currentDatabase; @@ -40,10 +43,39 @@ const SqlPreview: React.FC = ({ tableFilterIds }) => { } as DatabaseType; }, [currentDatabase, tableFilterIds]) - const { sql: sqlCode, circularDependency } = useRenderSql(database as DatabaseType); const { theme } = useTheme(); const { t } = useTranslation(); + useEffect(() => { + (async () => { + + if (database?.dialect && data_types.length > 0) { + + try { + const renderer: BaseDatabaseRenderer = getRenderer(database.dialect, data_types); + const sql: string = await renderer.renderDDL(database) + + setSqlCode(sql); + setCircularDependency(undefined); + + } catch (error) { + + if ((error as CircularDependencyError)?.cycle) + setCircularDependency((previousError) => { + if (!previousError) + return error as CircularDependencyError; + else if (Array.isArray(previousError.cycle) && Array.isArray((error as CircularDependencyError).cycle) && !(areArraysEqual(previousError.cycle, (error as CircularDependencyError).cycle))) + + return error as CircularDependencyError; + return previousError; + }) + } + } + + })() + }, [database, data_types]); + + useEffect(() => { if (circularDependency) toast(t("db_controller.circular_dependency.title"), { @@ -66,7 +98,6 @@ const SqlPreview: React.FC = ({ tableFilterIds }) => { text={sqlCode} /> - = ({ tableFilterIds }) => { extensions={[sql()]} readOnly theme={theme != "dark" ? overrideLightTheme : [oneDark, overrideDarkTheme]} - /> - ) diff --git a/src/features/database/modals/import-database.tsx b/src/features/database/modals/import-database.tsx index e07d773..46e8fc6 100644 --- a/src/features/database/modals/import-database.tsx +++ b/src/features/database/modals/import-database.tsx @@ -6,13 +6,11 @@ import { overrideDarkTheme, overrideLightTheme } from "@/lib/colors"; import { sql } from '@codemirror/lang-sql'; import { DatabaseDialect, ImportDatabaseMethod, ImportDatabaseOption, ImportMethodType, MARIADB_DUMP_EXAMPLE, MARIADB_DUMP_INSTRUCTIONS, MYSQL_DUMP_EXAMPLE, MYSQL_DUMP_INSTRUCTIONS, PG_DUMP_EXAMPLE, PG_DUMP_INSTRUCTIONS, SQLITE_DUMP_EXAMPLE, SQLITE_DUMP_INSRUCTION } from "@/lib/database"; import { useDatabase, useDatabaseOperations } from "@/providers/database-provider/database-provider"; - import { AlertCircleIcon, Code, HelpCircle } from "lucide-react"; -import { SqlToDatabase } from "@/utils/render/parsers/sql_to_database"; import Clipboard from "@/components/clipboard"; import { Trans } from 'react-i18next'; import { Node, useReactFlow } from "@xyflow/react"; -import { adjustTablesPositions } from "@/utils/tables"; +import { adjustTablesPositions, getTableNextSequence } from "@/utils/tables"; import { TableInsertType } from "@/lib/schemas/table-schema"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Label } from "@/components/ui/label"; @@ -20,6 +18,8 @@ import { useTheme } from "@/providers/theme-provider/theme-provider"; import { cn } from "@/lib/utils"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { buttonVariants } from "@/components/ui/button"; +import { BaseSqlImporter } from "@/utils/import/base-sql-importer"; +import { getImporter } from "@/utils/import/import-utils"; const options: ImportDatabaseOption[] = [{ @@ -107,6 +107,27 @@ const options: ImportDatabaseOption[] = [{ type: ImportMethodType.DB_CLIENT, numberOfInstructions: 5, }] +} + , { + dialect: DatabaseDialect.MSSQL, + docUrl: "https://stackrender.io/docs/import/mssql", + methods: [{ + id: "ssms", + name: "SSMS", + logo: "/ssms.png", + type: ImportMethodType.DB_CLIENT, + numberOfInstructions: 5, + }] +}, { + dialect: DatabaseDialect.ORACLE, + docUrl: "https://stackrender.io/docs/import/oracle", + methods: [{ + id: "sqldeveloper", + name: "SQL Developer", + logo: "/sqldeveloper.png", + type: ImportMethodType.DB_CLIENT, + numberOfInstructions: 6, + }] } ]; @@ -114,7 +135,6 @@ const options: ImportDatabaseOption[] = [{ const ImportDatabaseModal: React.FC = ({ isOpen, onOpenChange }) => { const { t } = useTranslation(); - const { theme: resolvedTheme } = useTheme(); const { database, isLoading, isSwitchingDatabase } = useDatabase(); const { data_types, importDatabase } = useDatabaseOperations(); @@ -123,6 +143,17 @@ const ImportDatabaseModal: React.FC = ({ isOpen, onOpenChange }) => const [error, setError] = useState(false); const { fitView } = useReactFlow(); + const [importer, setImporter] = useState(undefined); + + useEffect(() => { + if (isLoading || data_types.length == 0 || !database?.dialect) + return; + + else if (data_types.length > 0) { + setImporter(getImporter(database.dialect, data_types)) + } + }, [isLoading, data_types]); + let currentOption: ImportDatabaseOption | undefined = useMemo(() => { return options.find((option: ImportDatabaseOption) => option.dialect == database?.dialect) }, [database]); @@ -141,52 +172,63 @@ const ImportDatabaseModal: React.FC = ({ isOpen, onOpenChange }) => return currentOption?.methods.find((method: ImportDatabaseMethod) => method.id == selectedMethodId) as ImportDatabaseMethod; }, [selectedMethodId, currentOption]) + const validateSql = useCallback((code: string) => { - try { - const parsedDatabase = SqlToDatabase(code, data_types, database?.dialect as DatabaseDialect); - - setParsedDatabase(parsedDatabase); - setError(false); - - } catch (error) { - - setError(true); - setParsedDatabase(undefined) - } - setSqlCode(code) - - }, [database?.dialect, data_types]) - - - - const onImport = useCallback(async () => { - return new Promise(async (res, rej) => { + if (importer) try { - const nodes: Node[] = parsedDatabase.tables.map((table: TableInsertType) => ({ - id: table.id, - data: { - table - } - })) - - const adjustedTables = await adjustTablesPositions(nodes, parsedDatabase.relationships); - await importDatabase(adjustedTables, parsedDatabase.relationships, parsedDatabase.indices); - - onOpenChange && onOpenChange(false); - - setTimeout(() => { - fitView({ - duration: 500 - }); - }, 300); + const parsedDatabase = importer.parseSql(code); + setParsedDatabase(parsedDatabase); + setError(false); } catch (error) { setError(true); - rej() + setParsedDatabase(undefined) } - }) - }, [parsedDatabase]); + else { + console.error("Importer not loaded"); + } + setSqlCode(code) + + }, [database?.dialect, data_types, importer]) + + const onImport = useCallback(async () => { + + let nextTableSequence: number = getTableNextSequence(database ? database.tables : []); + if (parsedDatabase) + return new Promise(async (res, rej) => { + try { + const nodes: Node[] = parsedDatabase.tables.map((table: TableInsertType) => ({ + id: table.id, + data: { + table + } + })) + + const adjustedTables = await adjustTablesPositions(nodes, parsedDatabase.relationships); + + for (let index = 0; index < adjustedTables.length; index++) { + adjustedTables[index].sequence = nextTableSequence; + nextTableSequence += 1; + } + + await importDatabase(adjustedTables, parsedDatabase.relationships, parsedDatabase.indexes); + + onOpenChange && onOpenChange(false); + + setTimeout(() => { + fitView({ + duration: 500 + }); + }, 300); + + } catch (error) { + + setError(true); + rej() + } + }) + }, [parsedDatabase, database]); if (isLoading || isSwitchingDatabase) diff --git a/src/hooks/user-render-sql.tsx b/src/hooks/user-render-sql.tsx deleted file mode 100644 index c9100f8..0000000 --- a/src/hooks/user-render-sql.tsx +++ /dev/null @@ -1,62 +0,0 @@ - - -import { useDatabaseOperations } from "@/providers/database-provider/database-provider"; -import { DatabaseToAst } from "@/utils/render/parsers/database_to_ast"; -import { useEffect, useState } from "react"; - -import { Parser } from "node-sql-parser"; -import { DatabaseType } from "@/lib/schemas/database-schema"; -import { format } from 'sql-formatter'; -import { DatabaseDialect, getDatabaseByDialect } from "@/lib/database"; -import { CircularDependencyError, fixCharsetPlacement, fixSQLiteColumnOrder } from "@/utils/render/render-uttils"; -import { areArraysEqual } from "@/utils/utils"; -import { decomposeManyToMany } from "@/utils/relationship"; - -const parser = new Parser(); - - -export const useRenderSql = (database: DatabaseType) => { - const [sql, setSql] = useState(""); - const { data_types } = useDatabaseOperations(); - const [circularDependency, setCircularDependency] = useState(undefined) ; - - useEffect(() => { - try { - - const decomposedDatabase = decomposeManyToMany(database) ; - - const dbAst: any = DatabaseToAst(decomposedDatabase, data_types); - - let sql: string = parser.sqlify(dbAst, { - database: getDatabaseByDialect(database.dialect).name - }); - - if (database.dialect != DatabaseDialect.SQLITE) - sql = fixCharsetPlacement(format(sql, { language: "sql" })); - else - sql = fixSQLiteColumnOrder(format(sql, { language: "sql" })); - - const formattedSqlCode = format(sql, { language: 'sql' }); - - setSql( - (formattedSqlCode) - ); - setCircularDependency(undefined); - } catch (error) { - - if ((error as CircularDependencyError)?.cycle) - setCircularDependency((previousError) => { - if (!previousError) - return error as CircularDependencyError; - else if (Array.isArray(previousError.cycle) && Array.isArray((error as CircularDependencyError).cycle) && !(areArraysEqual(previousError.cycle, (error as CircularDependencyError).cycle))) - - return error as CircularDependencyError; - return previousError; - }) - - } - }, [database , data_types]); - - return { sql, circularDependency }; - -} \ No newline at end of file diff --git a/src/i18/languages/ar.ts b/src/i18/languages/ar.ts index 681190c..b8750a7 100644 --- a/src/i18/languages/ar.ts +++ b/src/i18/languages/ar.ts @@ -6,7 +6,7 @@ export const ar = { tables: "الجداول", relationships: "العلاقات", database: "قاعدة البيانات", - documentation : "الوثائق" + documentation: "الوثائق" }, color_picker: { default_color: "اللون الافتراضي" @@ -196,7 +196,7 @@ export const ar = { import_database: { title: "استيراد قاعدة البيانات", import: "استيراد", - view_docs : "عرض الوثائق" , + view_docs: "عرض الوثائق", import_options: "هل ترغب في الاستيراد باستخدام:", import_error: "خطأ في تحليل SQL", import_error_description: "تعذر استيراد SQL الخاص بك بسبب وجود صيغة غير صحيحة.", @@ -259,6 +259,21 @@ export const ar = { step3: "من القائمة، اختر File > Export > Database to SQL file.", step4: "في النافذة، اختر Export schema only ثم انقر Save.", step5: "أخيرًا، انسخ محتوى ملف .sql إلى محرر الكود أدناه." + }, + ssms: { + "step1": "افتح SQL Server Management Studio (SSMS).", + "step2": "انقر بزر الفأرة الأيمن على قاعدة البيانات، ثم اختر Tasks → Generate Scripts من القائمة.", + "step3": "في خطوة Choose Objects، اختر Choose specific database objects ثم قم بتحديد جميع الجداول.", + "step4": "في خطوة Set Scripting Options، اختر Save to file وحدد مكان حفظ ملف .sql.", + "step5": "أكمل المعالج، ثم افتح ملف .sql الذي تم إنشاؤه وانسخ محتواه إلى محرر الكود أدناه." + }, + sqldeveloper: { + "step1": "افتح Oracle SQL Developer واتصل بقاعدة البيانات الخاصة بك.", + "step2": "من القائمة العلوية، اذهب إلى Tools → Database Export.", + "step3": "في نافذة التصدير، اختر الاتصال الخاص بك وتأكد من تفعيل Pretty Print و Terminator فقط، وإلغاء تحديد Export Data لضمان تصدير المخطط فقط.", + "step4": "اختر مكان حفظ ملف التصدير ثم تابع إلى الخطوة التالية.", + "step5": "تحت Standard Object Types، اختر فقط Tables و Indexes و Constraints و Referential Constraints، واترك باقي الخيارات بدون تحديد.", + "step6": "أكمل المعالج، ثم افتح ملف .sql الناتج وانسخ محتواه إلى محرر الكود أدناه." } } } diff --git a/src/i18/languages/de.ts b/src/i18/languages/de.ts index f7a86ea..ed2211a 100644 --- a/src/i18/languages/de.ts +++ b/src/i18/languages/de.ts @@ -6,7 +6,7 @@ export const de = { tables: "Tabellen", relationships: "Beziehungen", database: "Datenbank", - documentation : "Dokumentation" + documentation: "Dokumentation" }, color_picker: { default_color: "Standardfarbe" @@ -196,7 +196,7 @@ export const de = { import_database: { title: "Datenbank importieren", import: "Importieren", - view_docs : "Dokumentation anzeigen" , + view_docs: "Dokumentation anzeigen", import_options: "Möchtest du importieren mit:", import_error: "SQL-Parsing-Fehler", import_error_description: "Wir konnten dein SQL nicht importieren, da es ungültige Syntax enthält.", @@ -259,6 +259,21 @@ export const de = { step3: "Gehe zu File > Export > Database to SQL file.", step4: "Wähle im Dialog Export schema only und klicke auf Save.", step5: "Kopiere abschließend den Inhalt der .sql-Datei in den Editor." + }, + ssms: { + "step1": "Öffnen Sie SQL Server Management Studio (SSMS).", + "step2": "Klicken Sie mit der rechten Maustaste auf Ihre Datenbank und wählen Sie im Kontextmenü Tasks → Skripte generieren.", + "step3": "Im Schritt Objekte auswählen wählen Sie Bestimmte Datenbankobjekte auswählen und markieren Sie alle Tabellen.", + "step4": "Im Schritt Skripting-Optionen festlegen wählen Sie In Datei speichern und wählen Sie den Speicherort für die .sql-Datei.", + "step5": "Schließen Sie den Assistenten ab, öffnen Sie anschließend die generierte .sql-Datei und kopieren Sie deren Inhalt in den Code-Editor unten." + }, + sqldeveloper: { + "step1": "Öffnen Sie Oracle SQL Developer und verbinden Sie sich mit Ihrer Datenbank.", + "step2": "Gehen Sie im oberen Menü zu Tools → Datenbank-Export.", + "step3": "Im Exportdialog wählen Sie Ihre Verbindung und stellen Sie sicher, dass nur Pretty Print und Terminator aktiviert sind und Export Data deaktiviert ist, um nur das Schema zu exportieren.", + "step4": "Wählen Sie den Speicherort der Exportdatei und fahren Sie mit dem nächsten Schritt fort.", + "step5": "Unter Standard-Objekttypen wählen Sie nur Tabellen, Indizes, Einschränkungen und referenzielle Einschränkungen aus. Lassen Sie alle anderen Optionen deaktiviert.", + "step6": "Schließen Sie den Assistenten ab, öffnen Sie anschließend die generierte .sql-Datei und kopieren Sie deren Inhalt in den Code-Editor unten." } } } diff --git a/src/i18/languages/en.ts b/src/i18/languages/en.ts index 6e1e00f..03ed2b8 100644 --- a/src/i18/languages/en.ts +++ b/src/i18/languages/en.ts @@ -277,6 +277,23 @@ export const en = { step5: "Finally, copy the contents of the .sql file into the code editor below." }, + + ssms: { + "step1": "Open SQL Server Management Studio (SSMS).", + "step2": "Right-click your database, then select Tasks → Generate Scripts from the context menu.", + "step3": "In the Choose Objects step, select Choose specific database objects, then check all tables.", + "step4": "In the Set Scripting Options step, select Save to file and choose where to save the .sql file.", + "step5": "Complete the wizard, then open the generated .sql file and copy its contents into the code editor below." + }, + sqldeveloper: { + "step1": "Open Oracle SQL Developer and connect to your database.", + "step2": "From the top menu, go to Tools → Database Export.", + "step3": "In the export dialog, select your connection, then make sure only Pretty Print and Terminator are checked, and Export Data is unchecked to ensure schema-only export.", + "step4": "Choose where to save the export file, then continue to the next step.", + "step5": "Under Standard Object Types, check only Tables, Indexes, Constraints, and Referential Constraints. Leave all other options unchecked.", + "step6": "Complete the wizard, then open the generated .sql file and copy its contents into the code editor below." + } + } diff --git a/src/i18/languages/es.ts b/src/i18/languages/es.ts index aab2a18..fd99382 100644 --- a/src/i18/languages/es.ts +++ b/src/i18/languages/es.ts @@ -273,6 +273,22 @@ export const es = { step5: "Finalmente, copia el contenido del archivo .sql en el editor de código a continuación." }, + + ssms: { + "step1": "Abra SQL Server Management Studio (SSMS).", + "step2": "Haga clic derecho en su base de datos y luego seleccione Tareas → Generar scripts en el menú contextual.", + "step3": "En el paso Elegir objetos, seleccione Elegir objetos específicos de la base de datos y marque todas las tablas.", + "step4": "En el paso Establecer opciones de script, seleccione Guardar en archivo y elija dónde guardar el archivo .sql.", + "step5": "Complete el asistente, luego abra el archivo .sql generado y copie su contenido en el editor de código a continuación." + }, + sqldeveloper: { + "step1": "Abra Oracle SQL Developer y conéctese a su base de datos.", + "step2": "En el menú superior, vaya a Herramientas → Exportación de base de datos.", + "step3": "En el diálogo de exportación, seleccione su conexión y asegúrese de que solo estén marcadas Pretty Print y Terminator, y que Export Data esté desmarcado para asegurar exportación solo del esquema.", + "step4": "Elija dónde guardar el archivo de exportación y continúe al siguiente paso.", + "step5": "En Tipos de objetos estándar, marque solo Tablas, Índices, Restricciones y Restricciones referenciales. Deje todo lo demás desmarcado.", + "step6": "Complete el asistente, luego abra el archivo .sql generado y copie su contenido en el editor de código a continuación." + } } diff --git a/src/i18/languages/fr.ts b/src/i18/languages/fr.ts index 94831e8..eef45f0 100644 --- a/src/i18/languages/fr.ts +++ b/src/i18/languages/fr.ts @@ -262,6 +262,21 @@ export const fr = { step3: "Allez à Fichier > Exporter > Base de données vers fichier SQL.", step4: "Dans la fenêtre, sélectionnez Exporter uniquement le schéma et cliquez sur Enregistrer.", step5: "Enfin, copiez le contenu du fichier .sql dans l’éditeur de code ci-dessous." + }, + ssms: { + "step1": "Ouvrez SQL Server Management Studio (SSMS).", + "step2": "Faites un clic droit sur votre base de données, puis sélectionnez Tâches → Générer des scripts dans le menu contextuel.", + "step3": "Dans l’étape Choisir les objets, sélectionnez Choisir des objets spécifiques de la base de données, puis cochez toutes les tables.", + "step4": "Dans l’étape Définir les options de script, sélectionnez Enregistrer dans un fichier et choisissez l’emplacement où enregistrer le fichier .sql.", + "step5": "Terminez l’assistant, puis ouvrez le fichier .sql généré et copiez son contenu dans l’éditeur de code ci-dessous." + }, + sqldeveloper: { + "step1": "Ouvrez Oracle SQL Developer et connectez-vous à votre base de données.", + "step2": "Dans le menu supérieur, allez dans Outils → Exportation de base de données.", + "step3": "Dans la boîte de dialogue d’exportation, sélectionnez votre connexion, puis assurez-vous que seules les options Pretty Print et Terminator sont cochées, et que Export Data est décoché pour garantir une exportation du schéma uniquement.", + "step4": "Choisissez l’emplacement du fichier d’exportation, puis passez à l’étape suivante.", + "step5": "Sous Types d’objets standards, cochez uniquement Tables, Index, Contraintes et Contraintes référentielles. Laissez toutes les autres options décochées.", + "step6": "Terminez l’assistant, puis ouvrez le fichier .sql généré et copiez son contenu dans l’éditeur de code ci-dessous." } } } diff --git a/src/i18/languages/hi.ts b/src/i18/languages/hi.ts index 35c0372..4d33136 100644 --- a/src/i18/languages/hi.ts +++ b/src/i18/languages/hi.ts @@ -268,6 +268,21 @@ export const hi = { step3: "शीर्ष मेनू से File > Export > Database to SQL file पर जाएं।", step4: "डायलॉग में Export schema only चुनें और Save पर क्लिक करें।", step5: "अंत में, .sql फ़ाइल की सामग्री को नीचे दिए गए code editor में कॉपी करें।" + } , + ssms: { + "step1": "SQL Server Management Studio (SSMS) खोलें।", + "step2": "अपना डेटाबेस पर राइट-क्लिक करें, फिर संदर्भ मेनू से Tasks → Generate Scripts चुनें।", + "step3": "Choose Objects चरण में, Choose specific database objects चुनें, फिर सभी टेबल्स को चेक करें।", + "step4": "Set Scripting Options चरण में, Save to file चुनें और .sql फ़ाइल को सेव करने का स्थान चुनें।", + "step5": "विज़ार्ड पूरा करें, फिर जनरेट की गई .sql फ़ाइल खोलें और उसकी सामग्री को नीचे दिए गए कोड एडिटर में कॉपी करें।" + }, + sqldeveloper: { + "step1": "Oracle SQL Developer खोलें और अपने डेटाबेस से कनेक्ट करें।", + "step2": "ऊपरी मेनू से Tools → Database Export पर जाएँ।", + "step3": "Export डायलॉग में अपना कनेक्शन चुनें, फिर सुनिश्चित करें कि केवल Pretty Print और Terminator चुने गए हैं, और Export Data अनचेक है ताकि केवल schema export हो।", + "step4": "एक्सपोर्ट फ़ाइल को सेव करने का स्थान चुनें, फिर अगले चरण पर जाएँ।", + "step5": "Standard Object Types के अंतर्गत केवल Tables, Indexes, Constraints, और Referential Constraints चुनें। बाकी सभी विकल्प अनचेक रखें।", + "step6": "विज़ार्ड पूरा करें, फिर जनरेट की गई .sql फ़ाइल खोलें और उसकी सामग्री को नीचे दिए गए कोड एडिटर में कॉपी करें।" } } } diff --git a/src/i18/languages/pt.ts b/src/i18/languages/pt.ts index 385314c..e63cbba 100644 --- a/src/i18/languages/pt.ts +++ b/src/i18/languages/pt.ts @@ -269,6 +269,21 @@ export const pt = { step3: "Vá para Arquivo > Exportar > Banco de Dados para Arquivo SQL.", step4: "Na janela de diálogo, escolha Exportar apenas o esquema e clique em Salvar.", step5: "Finalmente, copie o conteúdo do arquivo .sql para o editor de código abaixo." + } , + ssms: { + "step1": "Abra o SQL Server Management Studio (SSMS).", + "step2": "Clique com o botão direito no seu banco de dados e selecione Tarefas → Gerar Scripts no menu de contexto.", + "step3": "Na etapa Escolher Objetos, selecione Escolher objetos específicos do banco de dados e marque todas as tabelas.", + "step4": "Na etapa Definir opções de script, selecione Salvar em arquivo e escolha onde salvar o arquivo .sql.", + "step5": "Conclua o assistente e depois abra o arquivo .sql gerado e copie seu conteúdo para o editor de código abaixo." + }, + sqldeveloper: { + "step1": "Abra o Oracle SQL Developer e conecte-se ao seu banco de dados.", + "step2": "No menu superior, vá em Ferramentas → Exportação de Banco de Dados.", + "step3": "Na janela de exportação, selecione sua conexão e certifique-se de que apenas Pretty Print e Terminator estejam marcados, e que Export Data esteja desmarcado para garantir exportação apenas do schema.", + "step4": "Escolha onde salvar o arquivo de exportação e continue para a próxima etapa.", + "step5": "Em Tipos de Objetos Padrão, marque apenas Tabelas, Índices, Restrições e Restrições referenciais. Deixe todas as outras opções desmarcadas.", + "step6": "Conclua o assistente e depois abra o arquivo .sql gerado e copie seu conteúdo para o editor de código abaixo." } } } diff --git a/src/i18/languages/ru.ts b/src/i18/languages/ru.ts index 690497d..698eb77 100644 --- a/src/i18/languages/ru.ts +++ b/src/i18/languages/ru.ts @@ -257,6 +257,21 @@ export const ru = { step3: "Выберите Файл > Экспорт > База данных в SQL файл.", step4: "Выберите Экспортировать только схему и нажмите Сохранить.", step5: "Скопируйте содержимое .sql файла в редактор ниже." + }, + ssms: { + "step1": "Откройте SQL Server Management Studio (SSMS).", + "step2": "Щёлкните правой кнопкой мыши по вашей базе данных, затем выберите Tasks → Generate Scripts в контекстном меню.", + "step3": "В шаге Choose Objects выберите Select specific database objects и отметьте все таблицы.", + "step4": "В шаге Set Scripting Options выберите Save to file и укажите, куда сохранить файл .sql.", + "step5": "Завершите мастер, затем откройте созданный файл .sql и скопируйте его содержимое в редактор кода ниже." + }, + sqldeveloper: { + "step1": "Откройте Oracle SQL Developer и подключитесь к базе данных.", + "step2": "В верхнем меню перейдите в Tools → Database Export.", + "step3": "В окне экспорта выберите соединение и убедитесь, что отмечены только Pretty Print и Terminator, а Export Data отключён, чтобы экспортировать только схему.", + "step4": "Выберите место сохранения файла экспорта и перейдите к следующему шагу.", + "step5": "В разделе Standard Object Types отметьте только Tables, Indexes, Constraints и Referential Constraints. Остальные параметры оставьте отключёнными.", + "step6": "Завершите мастер, затем откройте созданный файл .sql и скопируйте его содержимое в редактор кода ниже." } } } diff --git a/src/i18/languages/zh.ts b/src/i18/languages/zh.ts index 902edbd..77437f4 100644 --- a/src/i18/languages/zh.ts +++ b/src/i18/languages/zh.ts @@ -210,7 +210,7 @@ export const zh = { import_database: { title: "导入数据库", import: "导入", - view_docs : "查看文档" , + view_docs: "查看文档", import_options: "请选择导入方式:", import_error: "SQL 解析错误", import_error_description: "我们无法导入您的 SQL,因为它包含无效语法。", @@ -276,6 +276,21 @@ export const zh = { step3: "顶部菜单选择 文件 > 导出 > 导出为 SQL 文件。", step4: "选择 仅导出结构 并点击 保存。", step5: "将 .sql 文件内容复制到下方 代码编辑器 中。" + }, + ssms: { + "step1": "打开 SQL Server Management Studio (SSMS)。", + "step2": "右键单击你的数据库,然后在上下文菜单中选择 任务 → 生成脚本。", + "step3": "在“选择对象”步骤中,选择“选择特定数据库对象”,然后勾选所有表。", + "step4": "在“设置脚本选项”步骤中,选择“保存到文件”,并选择保存 .sql 文件的位置。", + "step5": "完成向导后,打开生成的 .sql 文件,并将其内容复制到下面的代码编辑器中。" + }, + sqldeveloper: { + "step1": "打开 Oracle SQL Developer 并连接到你的数据库。", + "step2": "从顶部菜单进入 工具 → 数据库导出。", + "step3": "在导出对话框中,选择你的连接,并确保只勾选 Pretty Print 和 Terminator,同时取消勾选 Export Data,以确保仅导出结构。", + "step4": "选择导出文件的保存位置,然后进入下一步。", + "step5": "在标准对象类型下,仅勾选 表、索引、约束 和 参照约束。取消所有其他选项。", + "step6": "完成向导后,打开生成的 .sql 文件,并将其内容复制到下面的代码编辑器中。" } } } diff --git a/src/lib/data_types/mssql_data_types.ts b/src/lib/data_types/mssql_data_types.ts new file mode 100644 index 0000000..d9cfb5f --- /dev/null +++ b/src/lib/data_types/mssql_data_types.ts @@ -0,0 +1,175 @@ +import { DataInsertType } from "../schemas/data-type-schema"; + +export const MSSQLDataType: Partial[] = [ + { + id: 'c7a6fd94-ecec-4b79-9ea6-8ca25bae8d9c', + name: 'tinyint', + type: 'integer', + modifiers: ['auto_increment'] + }, + { + id: '48bdd059-9b52-4f93-b5c1-42d9dc2b7d13', + name: 'smallint', + type: 'integer', + + modifiers: ['auto_increment'] + }, + { + id: 'ae5e05da-21e0-4746-b972-6069ab628dc2', + name: 'int', + type: 'integer', + + modifiers: ['auto_increment'] + }, + { + id: '8a719f0c-0b0f-4be2-b660-61502575a5bd', + name: 'bigint', + type: 'integer', + + modifiers: ['auto_increment'] + }, + { + id: '442c88ae-6d53-41d5-bdaf-cb95192ab2e7', + name: 'decimal', + type: 'numeric', + modifiers: ['precision', 'scale'], + synonyms: ['numeric'] + }, + { + id: 'c3102982-a9ee-48c9-b050-bc3e8318efda', + name: 'float', + type: 'numeric', + modifiers: ['precision'] + }, + { + id: '1858ca0e-ba61-45aa-9236-8028ab7d7570', + name: 'real', + type: 'numeric' + }, + { + id: '3842960d-f0a9-411b-99d2-be3cfaf03fe7', + name: 'money', + type: 'numeric' + }, + { + id: '664aacc0-d646-4052-a616-d0b3d5d546df', + name: 'smallmoney', + type: 'numeric' + }, + { + id: 'fbdfd7d5-72d1-4c0b-9cfb-ca843ac444a4', + name: 'char', + type: 'text', + modifiers: ['length'] + }, + { + id: '1a6f261b-1abf-4f13-b803-a9533198f4c9', + name: 'varchar', + type: 'text', + modifiers: ['length'] + }, + { + id: '0a27e11f-1af7-4a62-babd-cfc1ecdd5f1f', + name: 'text', + type: 'text' + }, + { + id: 'c8cd26da-a09e-4a18-8b2f-11a2e4fe049c', + name: 'nchar', + type: 'text', + modifiers: ['length'] + }, + { + id: '53f552a2-b782-4084-a236-6928651b4f43', + name: 'nvarchar', + type: 'text', + modifiers: ['length'] + }, + { + id: 'e0071583-b97a-4f67-80b1-6ff25b8b8c37', + name: 'ntext', + type: 'text' + }, + { + id: '9df5d149-c9f1-4d26-a3ae-832accc08831', + name: 'binary', + type: 'binary', + modifiers: ['length', 'no_default'] + }, + { + id: '3c351e8c-92ba-40aa-843c-df2d8409e95a', + name: 'varbinary', + type: 'binary', + modifiers: ['length', 'no_default'] + }, + { + id: '731051f0-050f-4eb2-a327-5e10dd6bf6ca', + name: 'image', + type: 'binary', + modifiers: ['no_unique', 'no_default'] + }, + { + id: 'b412d41c-255b-413d-b866-4b652f291606', + name: 'date', + type: 'time' + }, + { + id: 'cc0f4f94-772c-4f4e-b1d3-f2fe0a18ee49', + name: 'time', + type: 'time', + modifiers: ['precision'] + }, + { + id: '83a37c4f-9501-485e-bc10-802673ca0594', + name: 'datetime', + type: 'time' + }, + { + id: '85a466ba-b97a-4c47-a204-1a8f0e16d275', + name: 'smalldatetime', + type: 'time' + }, + { + id: '562887bf-8d60-4e9e-b038-e760a6da05a2', + name: 'datetime2', + type: 'time', + modifiers: ['precision'] + }, + { + id: '1165eda1-6b45-4c45-82de-ddc90bb87f86', + name: 'datetimeoffset', + type: 'time', + modifiers: ['precision'] + }, + { + id: '00ea0771-47e0-4067-ba74-a153421c2d69', + name: 'uniqueidentifier', + type: 'uuid', + + }, + { + id: '03db80b0-d2c0-47bc-879b-8d0c17a36a9e', + name: 'bit', + type: 'boolean' + }, + { + id: '060d32ca-4e8a-496f-a29e-36d1947d0469', + name: 'json', + type: 'json' + }, + { + id: '090ad5cd-43b6-4443-93ce-61a6f12c6f4e', + name: 'xml', + type: 'xml' + }, + { + id: '9e9ddfc5-176b-4574-a097-3a1cbf927d9c', + name: 'geometry', + type: 'geometric' + }, + { + id: 'c6cdd823-5b8e-45ed-a489-3b68ce10b698', + name: 'geography', + type: 'geometric' + } +] \ No newline at end of file diff --git a/src/lib/data_types/oracle_data_types.ts b/src/lib/data_types/oracle_data_types.ts new file mode 100644 index 0000000..4711d3e --- /dev/null +++ b/src/lib/data_types/oracle_data_types.ts @@ -0,0 +1,151 @@ +import { DataInsertType } from "../schemas/data-type-schema"; + +export const OracleDataType: Partial[] = [ + { + id: '7b79fc89-38ae-4cf7-bdb8-1a270c2c4f0b', + name: 'number', + type: 'numeric', + modifiers: ['precision', 'scale', "auto_increment"], + synonyms: ['decimal', 'dec', 'numeric'] + }, + { + id: 'fc4ba819-cbf8-4550-9e78-6f7a05883f55', + name: 'integer', + type: 'integer', + modifiers: ["auto_increment"], + synonyms: ['int', 'smallint'] + }, + { + id: 'd4a2a12b-1c72-443a-9c9b-b30a0a4e64d3', + name: 'float', + type: 'numeric', + modifiers: ['precision'] + }, + { + id: 'd2b819bd-028a-4790-8e32-a1e06c6cb82c', + name: 'binary_float', + type: 'numeric' + }, + { + id: '6a04aad8-b97e-4a57-ae1a-b270f3885821', + name: 'binary_double', + type: 'numeric' + }, + { + id: 'a15c03d8-e8f1-4285-8148-134311b403e4', + name: 'varchar2', + type: 'text', + modifiers: ['length'], + synonyms: ['varchar', 'character varying'] + }, + { + id: 'f5932edf-41bc-4d52-ad1d-4501acbe77f1', + name: 'char', + type: 'text', + modifiers: ['length'], + synonyms: ['character'] + }, + { + id: 'ac67bfe8-6c83-4729-b9b2-ac6fbca5699f', + name: 'nchar', + type: 'text', + modifiers: ['length'] + }, + { + id: 'bd515b9f-1355-436a-9ff6-f007d61361f2', + name: 'nvarchar2', + type: 'text', + modifiers: ['length'] + }, + { + id: '16115bbb-a06e-4663-96c5-6169398aba60', + name: 'clob', + type: 'lob', + modifiers: ['no_default' , 'no_unique'] + }, + { + id: 'a0e84fd7-dae8-4f1c-b989-acae67eedbf5', + name: 'nclob', + type: 'lob', + modifiers: ['no_default' , 'no_unique'] + }, + { + id: '18762e8d-8fa7-43cf-9e0a-4205f2b2f3b1', + name: 'blob', + type: 'lob', + modifiers: ['no_default' , 'no_unique'] + }, + { + id: 'c19f392c-6edc-439c-a65b-a52f1d616051', + name: 'bfile', + type: 'lob', + modifiers: ['no_default' , 'no_unique'] + }, + { + id: '699d85c7-080e-4ec9-ae3c-2dafdaf4cd27', + name: 'raw', + type: 'binary', + modifiers: ['length' , 'no_default' ] + }, + { + id: '8521fef1-0105-49ca-a927-cde3cf4224d3', + name: 'date', + type: 'time', + }, + { + id: '5306e486-a2db-4095-9c4d-bc216e2b3b57', + name: 'timestamp', + type: 'time', + modifiers: ['precision'], + synonyms: ['timestamp without time zone'] + }, + { + id: '8604a573-7472-4603-952e-316fe1ef3407', + name: 'timestamp with time zone', + type: 'time', + modifiers: ['precision'] + }, + { + id: '6ec0d6d2-dc41-49b1-9e15-2ded2d75b5ef', + name: 'timestamp with local time zone', + type: 'time', + modifiers: ['precision'] + }, + { + id: '7076c729-ff35-4d5e-8f21-8c02bfc90d5c', + name: 'interval year to month', + type: 'time' , + modifiers: ['precision' , "no_default"] + }, + { + id: '6e2ca449-5062-4feb-a5ce-19fcc751ff2b', + name: 'interval day to second', + type: 'time', + modifiers: ['precision' , "no_default"] + }, + { + id: '3c3cd09e-a970-4c48-9f6e-6636757e3dd7', + name: 'rowid', + type: 'rowid', + modifiers: ['no_default' , 'no_unique'] + }, + { + id: 'f8ca2603-b196-4044-baec-bdc02803f3b8', + name: 'urowid', + type: 'rowid', + modifiers: ['no_default', 'no_unique'] + }, + { + id: 'c9abbfda-e2b3-4746-a536-36f34204b383', + name: 'xmltype', + type: 'xml', + modifiers: ['no_default'] + }, + { + id: '92fb0e59-b573-43a6-a7d3-f357867a3b00', + name: 'json', + type: 'json', + modifiers: ['no_default'] + }, + +] \ No newline at end of file diff --git a/src/lib/data_types/seed_datatypes.ts b/src/lib/data_types/seed_datatypes.ts index c478454..0a5fd39 100644 --- a/src/lib/data_types/seed_datatypes.ts +++ b/src/lib/data_types/seed_datatypes.ts @@ -5,6 +5,8 @@ import { PostgresDataType } from "./postgres_data_types"; import { SqliteDataTypes } from "./sqlite_data_types"; import { MariaDbDataType } from "./mariadb_data_types"; import { DatabaseDialect } from "../database"; +import { OracleDataType } from "./oracle_data_types"; +import { MSSQLDataType } from "./mssql_data_types"; @@ -18,7 +20,9 @@ export const seedDataTypes = async (db: any) => { ...mapToDataType(MysqlDataType , DatabaseDialect.MYSQL) , ...mapToDataType(PostgresDataType , DatabaseDialect.POSTGRES) , ...mapToDataType(SqliteDataTypes , DatabaseDialect.SQLITE) , - ...mapToDataType(MariaDbDataType , DatabaseDialect.MARIADB) + ...mapToDataType(MariaDbDataType , DatabaseDialect.MARIADB) , + ...mapToDataType(OracleDataType , DatabaseDialect.ORACLE) , + ...mapToDataType(MSSQLDataType , DatabaseDialect.MSSQL) , ] as DataInsertType[]) } diff --git a/src/lib/database.ts b/src/lib/database.ts index a2a70ed..517a198 100644 --- a/src/lib/database.ts +++ b/src/lib/database.ts @@ -1,3 +1,5 @@ +import _ from "lodash"; +import { DatabaseType as DatabaseSchemaType } from "./schemas/database-schema"; export interface DatabaseType { @@ -13,7 +15,7 @@ export enum DatabaseDialect { POSTGRES = "postgres", SQLITE = "sqlite", MARIADB = "mariadb", - SQL_SERVER = "sql_server", + MSSQL = "mssql", ORACLE = "oracle" }; @@ -45,10 +47,10 @@ export const DBTypes: DatabaseType[] = [ { name: "SQL Server", - dialect: DatabaseDialect.SQL_SERVER, + dialect: DatabaseDialect.MSSQL, logo: "/sql_server_logo_small.png", small_logo: "/sql_server_logo_small.png" , - comming : true + }, { @@ -56,7 +58,7 @@ export const DBTypes: DatabaseType[] = [ dialect: DatabaseDialect.ORACLE, logo: "/oracle_logo_small.png", small_logo: "/oracle_logo_small.png" , - comming : true + }, ] @@ -115,3 +117,14 @@ export enum CardinalityStyle { SYMBOLIC = "SYMBOLIC" } + + +export const emptyDb = (database: DatabaseSchemaType) : DatabaseSchemaType => { + + let cloneDb : any = _.cloneDeep(database); + cloneDb.tables = []; + cloneDb.relationships = []; + cloneDb.numOfTables = 0; + + return cloneDb as DatabaseSchemaType; +} \ No newline at end of file diff --git a/src/lib/field.ts b/src/lib/field.ts index 9810b8d..911e63c 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -106,4 +106,5 @@ export enum ForeignKeyActions { } -export const MYSQL_MAX_VAR_LENGTH = 255; \ No newline at end of file +export const MYSQL_MAX_VAR_LENGTH = 255; +export const DEFAULT_LENGTH_PARAM = 100; \ No newline at end of file diff --git a/src/lib/schemas/data-type-schema.ts b/src/lib/schemas/data-type-schema.ts index c2f1d94..363e2e6 100644 --- a/src/lib/schemas/data-type-schema.ts +++ b/src/lib/schemas/data-type-schema.ts @@ -9,7 +9,7 @@ export const data_types = sqliteTable('data_types', { name: text('name'), dialect: text("dialect", { - enum: ["postgres", "mysql", "sqlite", "mariadb"], + enum: ["postgres", "mysql", "sqlite", "mariadb" , "mssql" , "oracle"], }).notNull().default("postgres"), type: text('type').notNull(), diff --git a/src/providers/database-provider/database-provider.tsx b/src/providers/database-provider/database-provider.tsx index 4d2e4d7..04e26e1 100644 --- a/src/providers/database-provider/database-provider.tsx +++ b/src/providers/database-provider/database-provider.tsx @@ -17,6 +17,7 @@ import { field_indices, FieldIndexInsertType } from "@/lib/schemas/field_index-s import { v4 } from "uuid"; import { DataType } from "@/lib/schemas/data-type-schema"; import { deleteFieldsWithCascade, deleteIndicesWithCascade, deleteTablesWithCascade } from "@/utils/cascade"; +import { DatabaseDialect } from "@/lib/database"; const TYPE_ORDER = ["integer", "text", "boolean", "numeric", "time", "enum"] as const; @@ -431,7 +432,7 @@ const DatabaseProvider: React.FC = ({ children }) => { }, [db, currentDatabaseId]); const getInteger = useCallback(() => { - return data_types.find((dataType: DataType) => dataType.name == "integer"); + return data_types.find((dataType: DataType) => dataType.name == "integer" || (dataType.name == "int" && dataType.dialect == DatabaseDialect.MSSQL)); }, [data_types]); const importDatabase = useCallback(async (importedTables: TableInsertType[], importedRelationships: RelationshipInsertType[], importedIndices: IndexInsertType[]) => { diff --git a/src/utils/import/base-sql-importer.ts b/src/utils/import/base-sql-importer.ts new file mode 100644 index 0000000..d03a986 --- /dev/null +++ b/src/utils/import/base-sql-importer.ts @@ -0,0 +1,780 @@ + +import { randomColor } from '@/lib/colors'; +import { DatabaseDialect } from '@/lib/database'; +import { DataTypes, ForeignKeyActions, Modifiers, TimeDefaultValues } from '@/lib/field'; +import { DataType } from '@/lib/schemas/data-type-schema'; +import { FieldInsertType } from '@/lib/schemas/field-schema'; +import { IndexInsertType } from '@/lib/schemas/index-schema'; +import { Cardinality, RelationshipInsertType } from '@/lib/schemas/relationship-schema'; +import { TableInsertType } from '@/lib/schemas/table-schema'; +import { init, parse, ReferentialAction } from '@guanmingchiu/sqlparser-ts'; +import { v4 } from 'uuid'; + + +export class BaseSqlImporter { + + + protected data_types: DataType[] = []; + protected dialect: DatabaseDialect | undefined; + + public constructor(data_types: DataType[]) { + this.data_types = data_types; + init(); + } + + public parseSql(sql: string) { + + let errors: Error[] = []; + + const tables: TableInsertType[] = []; + const relationships: RelationshipInsertType[] = []; + const indexes: IndexInsertType[] = []; + const fk_constraints: any[] = []; + + const cleaned = this.cleanSql(sql); + + const { createIndexStatements, alterTableStatements, createTableStatements } = this.extractStatments(cleaned); + + try { + for (const statment of createTableStatements) { + + try { + const astStatment: any = parse(statment, this.dialect as any)?.pop(); + + if (astStatment?.CreateTable) { + const { table, errors: tableErrors, fk_constraints: tableFkConstraints } = this.astToTable(astStatment); + if (table) + tables.push(table); + errors.push(...tableErrors); + + if (tableFkConstraints) + fk_constraints.push(...tableFkConstraints); + + } + } catch (error) { + errors.push(error as Error); + } + + } + for (const statment of alterTableStatements) { + try { + const astStatment: any = parse(statment, this.dialect as any)?.pop(); + + if (astStatment?.AlterTable) { + + for (const operation of astStatment.AlterTable.operations) { + + if (operation.AddConstraint?.constraint?.ForeignKey) { + + const targetTableName: string | undefined = astStatment.AlterTable.name?.at(-1)?.Identifier?.value; + if (!targetTableName) + continue; + + fk_constraints.push({ + ...operation.AddConstraint.constraint.ForeignKey, + target_table: targetTableName + }) + + } + else if (operation.AddConstraint?.constraint?.Unique) { + + const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == astStatment.AlterTable.name?.at(-1)?.Identifier?.value); + + const columns: any[] | undefined = operation.AddConstraint?.constraint?.Unique?.columns; + + if (!table || !columns) { + continue; + } + if (columns && columns.length > 0 && table.fields) { + + for (const { column } of columns) { + const index = table.fields.findIndex((field: FieldInsertType) => field.name == column?.expr?.Identifier?.value); + if (index >= 0) { + table.fields[index].unique = true; + } + } + + } + } else if (operation.AddConstraint?.constraint.PrimaryKey) { + + const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == astStatment.AlterTable.name?.at(-1)?.Identifier?.value); + + const columns: any[] | undefined = operation.AddConstraint?.constraint?.PrimaryKey?.columns; + + if (!table || !columns) { + continue; + } + if (columns && columns.length > 0 && table.fields) { + for (const { column } of columns) { + const index = table.fields.findIndex((field: FieldInsertType) => field.name == column?.expr?.Identifier?.value); + if (index >= 0) { + table.fields[index].isPrimary = true; + } + } + } + } + } + } + } catch (error) { + errors.push(error as Error) + continue; + } + + } + for (const statment of createIndexStatements) { + try { + const astStatment: any = parse(statment, this.dialect as any)?.pop(); + + if (astStatment.CreateIndex) { + const { index, error: indexErrors } = this.astToIndex(astStatment, tables); + + + if (indexErrors) + errors.push(indexErrors); + + if (index) + indexes.push(index) + } + } catch (error) { + errors.push(error as Error); + } + } + for (const constraint of fk_constraints) { + try { + relationships.push(this.astToRelationship(constraint, tables)) + } catch (error) { + errors.push(error as Error); + } + } + + + if (tables.length == 0) + throw Error("Can't parse sql") + return { + tables, + relationships, + indexes, + errors + } + + } catch (error) { + throw error; + } + + + } + + protected astToTable(ast: any): ParsedTable { + const errors: Error[] = [] + const tableName: string | undefined = ast.CreateTable.name?.at(-1)?.Identifier?.value; + const columns: any[] = ast.CreateTable.columns; + const fk_constraints: any[] = []; + + + if (!tableName || !columns) + throw Error("Invalid table defintiion"); + + const fields: FieldInsertType[] = [] + + for (let index = 0; index < columns.length; index++) { + try { + + const { field, fk_constraint } = this.astToField(columns[index], index); + fields.push(field); + + if (fk_constraint) { + fk_constraints.push({ + ...fk_constraint, + columns: [{ + value: field.name + }], + target_table: tableName + }) + } + } catch (error) { + errors.push(error as Error); + continue + } + } + + if (ast.CreateTable.constraints && ast.CreateTable.constraints.length > 0) { + for (const constraint of ast.CreateTable.constraints) { + if (constraint.ForeignKey) { + fk_constraints.push({ + ...constraint.ForeignKey, + target_table: tableName + }); + } + else if (constraint.PrimaryKey) { + for (const { column } of constraint.PrimaryKey.columns) { + + const columnName: string | undefined = column.expr?.Identifier?.value; + if (!columnName) + continue; + const index = fields.findIndex((field: FieldInsertType) => field.name === columnName); + if (index >= 0) { + fields[index].isPrimary = true; + } + } + } else if (constraint.Unique) { + const columns: any[] | undefined = constraint.Unique?.columns; + if (columns && columns.length > 0) { + + for (const { column } of columns) { + const index = fields.findIndex((field: FieldInsertType) => field.name == column?.expr?.Identifier?.value); + if (index >= 0) { + fields[index].unique = true; + } + } + + } + } + } + } + return { + table: { + id: v4(), + name: tableName, + fields: fields, + color: randomColor() + } as TableInsertType, + errors, + fk_constraints + } + } + + protected astToField(ast: any, sequence: number): ParsedField { + + let isPrimary: boolean = false; + let nullable: boolean = true; + let unique: boolean = false; + let autoIncrement: boolean = false; + let maxLength: number | undefined; + let precision: number | undefined; + let scale: number | undefined; + let values: any[] | string | undefined = undefined; + let defaultValue: string | undefined; + let typeName: string | undefined; + let extraParam: number | undefined; + let fk_constraint: any | undefined; + let params: any[] | undefined; + + + // if it's a basic type like (texts , booleans .. ect) we get the name directly + // if it's a type that take params , the data type become an object + if (typeof ast.data_type === "string") { + typeName = ast.data_type.toLowerCase(); + + + } else if (typeof ast.data_type === "object" && !ast.data_type.Custom) { + const attributeName = Object.keys(ast.data_type)[0]; + if (ast.data_type[attributeName]?.IntegerLength) { + + maxLength = ast.data_type[attributeName]?.IntegerLength?.length; + } + if (ast.data_type[attributeName]?.Precision) { + precision = ast.data_type[attributeName]?.Precision; + } + + if (ast.data_type[attributeName]?.PrecisionAndScale && ast.data_type[attributeName]?.PrecisionAndScale?.length == 2) { + precision = ast.data_type[attributeName]?.PrecisionAndScale[0]; + scale = ast.data_type[attributeName]?.PrecisionAndScale[1]; + } + + if (typeof ast.data_type[attributeName] == "number") { + extraParam = ast.data_type[attributeName]; + } + + if (Array.isArray(ast.data_type[attributeName])) { + params = ast.data_type[attributeName]; + } + typeName = attributeName.toLowerCase(); + + + if (typeName == "timestamp" && this.dialect == DatabaseDialect.ORACLE && ast.data_type[attributeName].length >= 2 && ast.data_type[attributeName][1] == "WithTimeZone") { + typeName += "withtimezone" ; + } + } + + else if (ast.data_type.Custom && Array.isArray(ast.data_type.Custom)) { + if (ast.data_type.Custom.length > 1 && ast.data_type.Custom[1]?.[0] && !isNaN(Number(ast.data_type.Custom[1]?.[0]))) + extraParam = Number(ast.data_type.Custom[1]?.[0]); + + typeName = ast.data_type.Custom[0]?.[0]?.Identifier?.value.toLowerCase(); + + } + + const dataType: DataType | undefined = this.processDataType(typeName as string); + + if (!dataType) { + console.log (typeName , this.data_types) + throw Error("Data type not found"); + } + // get data type modifiers + const modifiers: string[] = dataType?.modifiers ? JSON.parse(dataType.modifiers) : []; + // the parser pass an extra param in case if the type is cutsom , that extra param can be either a length or precision + // to know which one we have to test what kind of modifier the data type support + if (extraParam && modifiers.includes(Modifiers.LENGTH)) + maxLength = extraParam; + + if (extraParam && modifiers.includes(Modifiers.PRECISION)) + precision = extraParam; + + if (params && params.length > 0 && Array.isArray(params[0]) && modifiers.includes(Modifiers.VALUES)) { + + const paramValues = params[0].filter((value: any) => value.Name !== undefined).map((value: any) => value.Name); + if (paramValues.every(v => typeof v === "string")) { + values = JSON.stringify(paramValues); + } + } + + if (modifiers.includes(Modifiers.PRECISION) && params && params.length > 0 && !isNaN(params[0]) && !precision) { + precision = params[0]; + } + + // get field defintion options + const options: any | undefined = [] = ast.options; + + try { + for (const option of options) { + if (typeof option.option == "string") { + + if (option.option == "Null") + nullable = true; + + if (option.option == "NotNull") + nullable = false; + + continue; + } + else if (typeof option.option === "object") { + + if (option.option.PrimaryKey) { + isPrimary = true; + continue; + } + if (option.option.Unique) { + unique = true; + continue; + } + if (option.option.Default) { + + defaultValue = this.processDefaultValue(option.option.Default, dataType); + continue; + } + if (option.option.DialectSpecific && option.option.DialectSpecific.length > 0) { + for (const { Word } of option.option.DialectSpecific) { + if (Word?.keyword == "AUTO_INCREMENT") { + autoIncrement = true; + break; + } + } + } + if (option.option.ForeignKey) { + fk_constraint = option.option.ForeignKey; + } + } + } + } catch (error) { + throw Error("Failed to extract column options") + } + + if (isPrimary) { + nullable = false; + } + + return { + field: { + id: v4(), + name: ast.name.value, + typeId: dataType?.id, + nullable, + autoIncrement, + unique, + isPrimary, + maxLength, + precision, + scale, + defaultValue, + sequence, + values + } as FieldInsertType, + fk_constraint + }; + + } + protected astToRelationship(ast: any, tables: TableInsertType[]): RelationshipInsertType { + + + let targetTable: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == ast.target_table); + let sourceTable: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == ast.foreign_table?.at(-1)?.Identifier?.value); + let sourceField: FieldInsertType | undefined = sourceTable?.fields?.find((field: FieldInsertType) => field.name == ast.referred_columns?.[0]?.value); + let targetField: FieldInsertType | undefined = targetTable?.fields?.find((field: FieldInsertType) => field.name == ast.columns?.[0]?.value); + + if (!sourceTable || !sourceField || !targetField || !targetTable) { + throw Error("Inavlid FK Constraint") + + } + + const onDelete: ForeignKeyActions | undefined = ast.on_delete ? this.astToForiegnKeyAction(ast.on_delete) : undefined; + const onUpdate: ForeignKeyActions | undefined = ast.on_update ? this.astToForiegnKeyAction(ast.on_update) : undefined; + const name: string | undefined = ast.name?.value; + + return { + id: v4(), + name, + sourceFieldId: sourceField.id, + targetFieldId: targetField.id, + sourceTableId: sourceTable.id, + targetTableId: targetTable.id, + cardinality: targetField.unique ? Cardinality.one_to_one : Cardinality.one_to_many, + onDelete, + onUpdate + } as RelationshipInsertType + } + protected astToIndex(ast: any, tables: TableInsertType[]): ParsedIndex { + + const tableName: string = ast.CreateIndex.table_name?.at(-1)?.Identifier?.value; + const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == tableName); + + if (!table) + throw Error("index table not found"); + + const columnNames: string[] = ast.CreateIndex.columns.map(({ column }: any) => column.expr?.Identifier?.value) + .filter((column: string | undefined) => column != undefined); + + const fieldIds: string[] = (table.fields?.filter((field: FieldInsertType) => columnNames.includes(field.name)) as FieldInsertType[]) + .map((field: FieldInsertType) => field.id); + + let indexName: string = ast.CreateIndex.name?.[0]?.Identifier?.value; + if (!indexName) { + indexName = `${tableName}_${columnNames.join("_")}_index`; + } + + return { + index: { + id: v4(), + name: indexName, + tableId: table.id, + unique: ast.CreateIndex.unique, + fieldIndices: fieldIds?.map((id: string) => ({ + id: v4(), + fieldId: id + })) + } as IndexInsertType, + error: undefined + } + } + + protected astToForiegnKeyAction(ast: ReferentialAction): ForeignKeyActions { + switch (ast) { + case "Cascade": + return ForeignKeyActions.CASCADE; + case "SetNull": + return ForeignKeyActions.SET_NULL; + case 'Restrict': + return ForeignKeyActions.RESTRICT; + case "SetDefault": + return ForeignKeyActions.SET_DEFAULT; + } + return ForeignKeyActions.NO_ACTION; + } + + protected processDataType(typeName: string): DataType | undefined { + + + // get data type from the supported ones + return this.data_types.find((dataType: DataType) => { + let synonyms: string[] = dataType.synonyms ? JSON.parse(dataType.synonyms) : []; + synonyms = synonyms.map((synonym: string) => synonym.replace(/ /g, '')); + return (dataType.name as string).replace(/ /g, '') == typeName || synonyms.includes(typeName as string) + }); + + } + + protected processDefaultValue(ast: any, dataType: DataType): string | undefined { + + if (ast.Value && ast.Value.value) { + + const value: any = ast.Value.value; + if (value.Number && Array.isArray(value.Number) && value.Number.length > 0 && !isNaN(Number(value.Number[0]))) { + return value.Number[0]; + } + + else if (value.SingleQuotedString || value.DoubleQuotedString) { + const valuesArray = Object.values(value); + if (valuesArray.length > 0) + return valuesArray[0] as string; + } + + else if (value.Boolean) { + return "true"; + } + + else if (value.NationalStringLiteral) { + return value.NationalStringLiteral + } + + } else if (ast.Function) { + if (dataType.type == DataTypes.TIME) { + if (ast.Function.name?.[0]?.Identifier?.value && this.isCurrentTimesTampFunction(ast.Function.name?.[0]?.Identifier?.value)) + return TimeDefaultValues.NOW; + + } + } else if (ast.TypedString) { + + const value = ast.TypedString.value?.value; + + if (value.SingleQuotedString || value.DoubleQuotedString) { + const valuesArray = Object.values(value); + if (valuesArray.length > 0) + return valuesArray[0] as string; + } + } + + return undefined; + } + + protected isCurrentTimesTampFunction(value: string): boolean { + const upper: string = value.toUpperCase(); + + return upper == "CURRENT_TIMESTAMP" || upper == "NOW"; + } + + + protected cleanSql(sql: string): string { + // Clean up SQL: remove comments and normalize + const cleanedSql = sql + .replace(/--.*$/gm, '') // remove single-line comments + .replace(/\/\*[\s\S]*?\*\//g, '') // remove multi-line comments + .replace(/\s+/g, ' ') // normalize whitespace + .replace(/;\s*/g, ';\n'); // separate statements + return cleanedSql; + } + + protected extractStatments(sql: string): ExtractedStatments { + + const createTableStatements: string[] = []; + const alterTableStatements: string[] = []; + const createIndexStatements: string[] = []; + + // Split into individual statements + const statements = sql + .split('\n') + .map(s => s.trim()) + .filter(Boolean); + + + for (const stmt of statements) { + const upper = stmt.toUpperCase(); + + if (upper.startsWith('CREATE TABLE')) { + createTableStatements.push(stmt); + } else if (upper.startsWith('ALTER TABLE')) { + alterTableStatements.push(stmt); + } else if (upper.startsWith('CREATE INDEX') || upper.startsWith('CREATE UNIQUE INDEX')) { + createIndexStatements.push(stmt); + } + } + return { + createTableStatements, + alterTableStatements, + createIndexStatements + } as ExtractedStatments; + } + +} + +export type ParsedDatabaase = { + tables: TableInsertType[], + relationships: RelationshipInsertType[], + indexes: IndexInsertType[], + errors: Error[] +} + +export type ParsedTable = { + table: TableInsertType; + errors: Error[]; + fk_constraints: any[] | undefined, +} + +export type ParsedIndex = { + index: IndexInsertType; + error?: Error; + +} + +export type ParsedField = { + field: FieldInsertType, + fk_constraint: any | undefined +} + +export type ExtractedStatments = { + createTableStatements: string[], + alterTableStatements: string[], + createIndexStatements: string[], + createPostgresTypesStatements?: string[], + alterSequenceStatments?: string[] +} + + + + + +/* + + +START TRANSACTION; + +CREATE TABLE `users` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(255) NOT NULL +); + +CREATE UNIQUE INDEX `users_usernae_index` ON `users` (`username`); + +COMMIT; + + +CREATE TABLE `users` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(255) NOT NULL UNIQUE, + email VARCHAR(255) NOT NULL UNIQUE, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + last_login_at DATETIME NULL, + is_active BOOLEAN NOT NULL DEFAULT TRUE, + updated_at TEXT NULL DEFAULT 'Hello world' UNIQUE +); + +CREATE INDEX `idx_users_created_at_index` ON `users` (`created_at`); + +CREATE INDEX `idx_users_last_login_at` ON `users` (`last_login_at`); + +CREATE TABLE `categories` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL UNIQUE, + description TEXT NULL +); + +CREATE TABLE `tags` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL UNIQUE +); + +CREATE TABLE `projects` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT NULL, + category_id INTEGER NULL, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + user_id INTEGER NULL, + due_date DATETIME NULL, + status ENUM ( + 'planning', + 'in_progress', + 'completed', + 'on_hold', + 'draft' + ) NOT NULL DEFAULT 'draft', + FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`), + FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL +); + +CREATE TABLE `tasks` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + title VARCHAR(255) NOT NULL, + description TEXT NULL, + status ENUM ('todo', 'in_progress', 'done') NOT NULL DEFAULT 'todo', + priority ENUM ('low', 'medium', 'high') NULL DEFAULT 'medium', + due_date DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + project_id INTEGER NULL, + assigned_to_user_id INTEGER NULL, + completed_at DATETIME NULL, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`), + FOREIGN KEY (`assigned_to_user_id`) REFERENCES `users` (`id`) +); + +CREATE TABLE `comments` ( + id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + task_id INTEGER NOT NULL, + comment TEXT NOT NULL, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + user_id INTEGER NOT NULL, + updated_at DATETIME NULL, + FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) +); + +CREATE INDEX `idx_comments_created_at` ON `comments` (`created_at`); + +CREATE INDEX `idx_comments_user_id` ON `comments` (`user_id`); + +CREATE INDEX `idx_comments_task_id` ON `comments` (`task_id`); + +CREATE TABLE `task_tags` ( + task_id INTEGER NOT NULL, + tag_id INTEGER NOT NULL, + FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`), + FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) +) + +CREATE TABLE all_mysql_types ( + -- Numeric types + col_tinyint TINYINT(3), + col_smallint SMALLINT(5), + col_mediumint MEDIUMINT(7), + col_int INT(11), + col_bigint BIGINT(20), + + col_decimal DECIMAL(10, 2), + col_numeric NUMERIC(8, 3), + + col_float FLOAT(7, 4), + col_double DOUBLE(15, 8), + col_real REAL, + + col_boolean BOOLEAN, + + -- Date & time types + col_date DATE, + col_datetime DATETIME(6), + col_timestamp TIMESTAMP(6), + col_time TIME(6), + col_year YEAR, + + -- String types + col_char CHAR(10), + col_varchar VARCHAR(255), + + col_binary BINARY(16), + col_varbinary VARBINARY(255), + + col_tinytext TINYTEXT, + col_text TEXT, + col_mediumtext MEDIUMTEXT, + col_longtext LONGTEXT, + + col_tinyblob TINYBLOB, + col_blob BLOB, + col_mediumblob MEDIUMBLOB, + col_longblob LONGBLOB, + + col_enum ENUM('A', 'B', 'C'), + col_set SET('X', 'Y', 'Z'), + + -- JSON + col_json JSON, + + -- Spatial types + col_geometry GEOMETRY, + col_point POINT, + col_linestring LINESTRING, + col_polygon POLYGON +); + + + + +*/ \ No newline at end of file diff --git a/src/utils/import/import-utils.ts b/src/utils/import/import-utils.ts new file mode 100644 index 0000000..712f59d --- /dev/null +++ b/src/utils/import/import-utils.ts @@ -0,0 +1,40 @@ +import { DatabaseDialect } from "@/lib/database"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import { BaseSqlImporter } from "./base-sql-importer"; +import { MysqlImporter } from "./mysql-importer"; +import { MariaDbImporter } from "./mariadb-importer"; +import { SqliteImporter } from "./sqlite-importer"; +import { PostgreSqlImporter } from "./postgresql-importer"; +import { OracleImporter } from "./oracle-importer"; +import { MSSQLImporter } from "./mssql-importer"; + +export const getImporter = (dialect: DatabaseDialect, data_types: DataType[]) => { + let importer: BaseSqlImporter | undefined = undefined; + + + switch (dialect) { + case DatabaseDialect.MYSQL: + importer = (new MysqlImporter(data_types)); + break; + case DatabaseDialect.MARIADB: + importer = (new MariaDbImporter(data_types)); + break; + case DatabaseDialect.SQLITE: + importer = (new SqliteImporter(data_types)); + break; + case DatabaseDialect.POSTGRES: + importer = (new PostgreSqlImporter(data_types)); + break; + case DatabaseDialect.ORACLE: + importer = (new OracleImporter(data_types)); + break; + case DatabaseDialect.MSSQL: + importer = (new MSSQLImporter(data_types)); + break; + default: + importer = new BaseSqlImporter(data_types); + break; + } + + return importer; +} \ No newline at end of file diff --git a/src/utils/import/mariadb-importer.ts b/src/utils/import/mariadb-importer.ts new file mode 100644 index 0000000..1db9ba8 --- /dev/null +++ b/src/utils/import/mariadb-importer.ts @@ -0,0 +1,37 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { MysqlImporter } from "./mysql-importer"; + +export class MariaDbImporter extends MysqlImporter { + + public constructor(data_types: DataType[]) { + super(data_types); + this.dialect = DatabaseDialect.MYSQL; + } + + + protected processDefaultValue(ast: any, dataType: DataType): string | undefined { + + let defaultValue: string | undefined = super.processDefaultValue(ast, dataType); + + if (!defaultValue) { + if (ast.Nested?.Function) { + if ( ast.Nested.Function.name?.[0]?.Identifier?.value?.toUpperCase() == "UUID" ) { + + return "random" ; + } + } + if (ast.Function) { + if ( ast.Function.name?.[0]?.Identifier?.value.toUpperCase() == "UUID" ) { + + return "random" ; + } + + } + } + + return defaultValue + } + + +} diff --git a/src/utils/import/mssql-importer.ts b/src/utils/import/mssql-importer.ts new file mode 100644 index 0000000..fc6b88a --- /dev/null +++ b/src/utils/import/mssql-importer.ts @@ -0,0 +1,702 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { BaseSqlImporter, ExtractedStatments, ParsedDatabaase, ParsedField } from "./base-sql-importer"; +import { TableInsertType } from "@/lib/schemas/table-schema"; +import { FieldInsertType } from "@/lib/schemas/field-schema"; +import { TimeDefaultValues } from "@/lib/field"; + +export class MSSQLImporter extends BaseSqlImporter { + + + private dfConstraints: string[] = []; + + public constructor(data_types: DataType[]) { + super(data_types); + this.dialect = DatabaseDialect.MSSQL; + } + + public parseSql(sql: string) { + try { + this.dfConstraints = []; + const parsedDatabaase: ParsedDatabaase = super.parseSql(sql); + for (const constraint of this.dfConstraints) { + try { + this.processDefaultValueConstraint(constraint, parsedDatabaase.tables); + } catch (error) { + parsedDatabaase.errors.push(error as Error); + } + } + return parsedDatabaase; + } catch (error) { + throw error; + } + } + + protected astToField(ast: any, sequence: number): ParsedField { + const { field, fk_constraint } = super.astToField(ast, sequence); + // get field defintion options + const options: any | undefined = [] = ast.options; + for (const option of options) { + if (option.option?.Identity) { + field.autoIncrement = true; + } + } + + return { field, fk_constraint }; + } + private processDefaultValueConstraint(constraint: string, tables: TableInsertType[]) { + const regex = + /ALTER\s+TABLE\s+(?:(?:\[(?[^\]]+)\]|(?\w+))\.)?(?:\[(?[^\]]+)\]|(?\w+))\s+ADD\s+CONSTRAINT\s+(?:\[(?[^\]]+)\]|(?\w+))\s+DEFAULT\s*\((?.*?)\)\s+FOR\s+(?:\[(?[^\]]+)\]|(?\w+))/is; + + const match = constraint.match(regex); + + if (match?.groups) { + const schema = + match.groups.schema1 || match.groups.schema2 || null; + + const tableName = + match.groups.table1 || match.groups.table2; + + const constraint = + match.groups.constraint1 || match.groups.constraint2; + + const column = + match.groups.column1 || match.groups.column2; + + const defaultValue = + match.groups.defaultValue?.trim() + // remove only wrapping parentheses around the whole value + .replace(/^\((.*)\)$/s, "$1") + + // repeat once more for cases like ((1)) + .replace(/^\((.*)\)$/s, "$1") + + // remove surrounding quotes + .replace(/^['"](.*)['"]$/s, "$1"); + + + if (tableName && column && defaultValue) { + const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == tableName); + if (!table) + throw Error("Table in DF constraint not found : " + constraint); + + const field: FieldInsertType | undefined = table.fields?.find((field: FieldInsertType) => field.name == column); + if (!field) { + throw Error("field not found in DF constraint : " + constraint); + } + + const isFunctionRegex = + /^[a-zA-Z_][a-zA-Z0-9_]*\s*\([^()]*\)$/; + + if (isFunctionRegex.test(defaultValue)) { + // in case the default value is a function sysdatetimeoffset() , CONVERT([date],getdate()) ... ect + // if it's a function of time current timestamp. + const upperDefaultValue: string = defaultValue.toUpperCase(); + if (upperDefaultValue.includes("GETDATE") || upperDefaultValue.includes("SYSDATETIME") || upperDefaultValue.includes("SYSDATETIMEOFFSET")) { + field.defaultValue = TimeDefaultValues.NOW; + } else if (upperDefaultValue.includes("NEWID")) { + + field.defaultValue = "random"; + } + + } else { + field.defaultValue = defaultValue; + } + + } else + throw Error("Failed to process a MSSQL DF constraint : " + constraint); + } + + } + protected processDefaultValue(ast: any, dataType: DataType): string | undefined { + let defaultValue: string | undefined = super.processDefaultValue(ast, dataType); + if (dataType.name == "bit" && defaultValue) { + return defaultValue == "1" ? "true" : "false"; + } + else if (!defaultValue && dataType.name == "uniqueidentifier") { + if (ast.Function) { + if (ast.Function.name?.[0]?.Identifier?.value && (ast.Function.name?.[0]?.Identifier?.value == "NEWSEQUENTIALID" || ast.Function.name?.[0]?.Identifier?.value == "NEWID")) { + return "random"; + } + } + return defaultValue + } + return defaultValue; + } + protected isCurrentTimesTampFunction(value: string): boolean { + return value == "GETDATE" || value == "SYSDATETIME" || value == "SYSDATETIMEOFFSET"; + } + + protected cleanSql(sql: string): string { + const cleanedSql = sql // remove GO batches + .replace(/([^;\s])\s*\r?\nGO\b/gm, '$1;') + .replace(/^\s*GO\s*$/gm, '') + + + // remove WITH CHECK + .replace(/\bWITH\s+CHECK\b\s*/gi, '') + + // remove CHECK CONSTRAINT enable statements (FK validation step) + .replace( + /ALTER TABLE\s+\[?.*?\]?\.?\[?.*?\]?\s+CHECK\s+CONSTRAINT\s+\[?.*?\]?;\s*/gi, + '' + ) + // remove computed columns + .replace( + /^\s*(?:\[[^\]]+\]|\w+)\s+AS\s+.*?(?:PERSISTED\s*)?,?\s*$/gim, + '' + ) + .replace( + /(\[[^\]]+\]|\w+)\s+([^,]*?)\s+FOREIGN\s+KEY\s+REFERENCES\s+([^\s,()]+)\s*\(\s*([^\s,()]+)\s*\)/gi, + (_match, col, beforeRefs, table, refCol) => { + return `${col} ${beforeRefs.trim()} REFERENCES ${table}(${refCol})`; + } + ) + // remove CLUSTERED / NONCLUSTERED + .replace(/\bCLUSTERED\b/g, '') + .replace(/\bNONCLUSTERED\b/g, '') + + // remove ASC / DESC inside constraints + .replace(/\s+\bASC\b/g, '') + .replace(/\s+\bDESC\b/g, '') + + // remove WITH (...) ON [PRIMARY] + .replace(/\)\s*WITH\s*\([^)]+\)\s*ON\s*\[[^\]]+\]/g, ')') + + // remove trailing table storage clauses + .replace(/\)\s*ON\s*\[[^\]]+\](\s*TEXTIMAGE_ON\s*\[[^\]]+\])?/g, ')') + + // cleanup extra spaces + .replace(/[ \t]+/g, ' ') + .replace(/\n\s+\n/g, '\n\n'); + + + return super.cleanSql(cleanedSql); + } + + protected extractStatments(sql: string): ExtractedStatments { + + const statments: ExtractedStatments = super.extractStatments(sql); + + statments.alterTableStatements = statments.alterTableStatements.filter((statment: string) => { + if (/ALTER\s+TABLE\s+\[[^\]]+\]\.\[[^\]]+\]\s+ADD\s+CONSTRAINT\s+\[[^\]]+\]\s+DEFAULT\s*\(.*?\)\s+FOR\s+\[[^\]]+\]/i.test(statment)) { + + this.dfConstraints.push(statment); + + } + else { + + return statment; + } + }) + return statments + } + +} + + +/* +-- ============================================= +-- Enterprise E-Commerce Platform Database +-- Version: 1.0 (No CHECK Constraints) +-- ============================================= + +-- Drop database if exists (for clean creation) +IF EXISTS (SELECT name FROM sys.databases WHERE name = N'ECommerceDB') +BEGIN + ALTER DATABASE ECommerceDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE; + DROP DATABASE ECommerceDB; +END +GO + +CREATE DATABASE ECommerceDB; +GO + +USE ECommerceDB; +GO + +-- ============================================= +-- 1. Customer Management Schema +-- ============================================= + +CREATE TABLE Customers ( + CustomerID INT IDENTITY(1,1) PRIMARY KEY, + CustomerNumber AS 'CUST-' + RIGHT('000000' + CAST(CustomerID AS VARCHAR(6)), 6) PERSISTED, + Email VARCHAR(255) NOT NULL UNIQUE, + Phone VARCHAR(20) NOT NULL, + FirstName NVARCHAR(50) NOT NULL, + LastName NVARCHAR(50) NOT NULL, + DateOfBirth DATE NULL, + TaxID VARCHAR(50) NULL, + IsActive BIT NOT NULL DEFAULT 1, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + UpdatedAt DATETIME2 NOT NULL DEFAULT GETDATE() +); + +CREATE TABLE CustomerAddresses ( + AddressID INT IDENTITY(1,1) PRIMARY KEY, + CustomerID INT NOT NULL, + AddressType VARCHAR(20) NOT NULL, -- Billing, Shipping, Both + AddressLine1 NVARCHAR(200) NOT NULL, + AddressLine2 NVARCHAR(200) NULL, + City NVARCHAR(100) NOT NULL, + StateProvince NVARCHAR(100) NOT NULL, + PostalCode VARCHAR(20) NOT NULL, + CountryCode CHAR(2) NOT NULL, + IsDefault BIT NOT NULL DEFAULT 0, + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ON DELETE CASCADE +); + +CREATE TABLE CustomerLoyalty ( + LoyaltyID INT IDENTITY(1,1) PRIMARY KEY, + CustomerID INT NOT NULL UNIQUE, + PointsBalance INT NOT NULL DEFAULT 0, + TierLevel VARCHAR(20) NOT NULL DEFAULT 'Bronze', + TotalSpent DECIMAL(18,2) NOT NULL DEFAULT 0, + JoinDate DATE NOT NULL DEFAULT GETDATE(), + PointsExpiryDate DATE NULL, + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ON DELETE CASCADE +); + +CREATE TABLE CustomerPreferences ( + PreferenceID INT IDENTITY(1,1) PRIMARY KEY, + CustomerID INT NOT NULL, + PreferenceKey VARCHAR(50) NOT NULL, + PreferenceValue NVARCHAR(500) NULL, + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ON DELETE CASCADE, + CONSTRAINT UQ_Customer_Preference UNIQUE (CustomerID, PreferenceKey) +); + +-- ============================================= +-- 2. Product Catalog Schema +-- ============================================= + +CREATE TABLE Categories ( + CategoryID INT IDENTITY(1,1) PRIMARY KEY, + ParentCategoryID INT NULL, + CategoryName NVARCHAR(100) NOT NULL, + CategoryCode VARCHAR(50) NOT NULL UNIQUE, + Description NVARCHAR(500) NULL, + IsActive BIT NOT NULL DEFAULT 1, + DisplayOrder INT NOT NULL DEFAULT 0, + FOREIGN KEY (ParentCategoryID) REFERENCES Categories(CategoryID) +); + +CREATE TABLE Brands ( + BrandID INT IDENTITY(1,1) PRIMARY KEY, + BrandName NVARCHAR(100) NOT NULL UNIQUE, + BrandCode VARCHAR(50) NOT NULL UNIQUE, + Website VARCHAR(255) NULL, + IsActive BIT NOT NULL DEFAULT 1 +); + +CREATE TABLE Products ( + ProductID INT IDENTITY(1,1) PRIMARY KEY, + SKU VARCHAR(50) NOT NULL UNIQUE, + ProductName NVARCHAR(200) NOT NULL, + Description NVARCHAR(MAX) NULL, + CategoryID INT NOT NULL, + BrandID INT NULL, + UnitPrice DECIMAL(18,2) NOT NULL, + Weight DECIMAL(10,3) NOT NULL DEFAULT 0, + IsTaxable BIT NOT NULL DEFAULT 1, + IsActive BIT NOT NULL DEFAULT 1, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + ModifiedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + FOREIGN KEY (CategoryID) REFERENCES Categories(CategoryID), + FOREIGN KEY (BrandID) REFERENCES Brands(BrandID) +); + +CREATE TABLE ProductAttributes ( + AttributeID INT IDENTITY(1,1) PRIMARY KEY, + AttributeName NVARCHAR(100) NOT NULL UNIQUE, + DataType VARCHAR(20) NOT NULL -- String, Integer, Decimal, Boolean, Date +); + +CREATE TABLE ProductAttributeValues ( + ProductID INT NOT NULL, + AttributeID INT NOT NULL, + AttributeValue NVARCHAR(500) NOT NULL, + PRIMARY KEY (ProductID, AttributeID), + FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ON DELETE CASCADE, + FOREIGN KEY (AttributeID) REFERENCES ProductAttributes(AttributeID) +); + +CREATE TABLE Inventory ( + InventoryID INT IDENTITY(1,1) PRIMARY KEY, + ProductID INT NOT NULL, + WarehouseCode VARCHAR(20) NOT NULL, + QuantityOnHand INT NOT NULL DEFAULT 0, + QuantityReserved INT NOT NULL DEFAULT 0, + ReorderLevel INT NOT NULL DEFAULT 10, + ReorderQuantity INT NOT NULL DEFAULT 50, + LastRestockedDate DATETIME2 NULL, + FOREIGN KEY (ProductID) REFERENCES Products(ProductID), + CONSTRAINT UQ_Product_Warehouse UNIQUE (ProductID, WarehouseCode) +); + +-- ============================================= +-- 3. Pricing & Promotions Schema +-- ============================================= + +CREATE TABLE PriceTiers ( + TierID INT IDENTITY(1,1) PRIMARY KEY, + TierName VARCHAR(50) NOT NULL UNIQUE, + MinQuantity INT NOT NULL, + DiscountPercentage DECIMAL(5,2) NOT NULL +); + +CREATE TABLE ProductPricing ( + PricingID INT IDENTITY(1,1) PRIMARY KEY, + ProductID INT NOT NULL, + TierID INT NOT NULL, + Price DECIMAL(18,2) NOT NULL, + EffectiveFrom DATE NOT NULL, + EffectiveTo DATE NULL, + FOREIGN KEY (ProductID) REFERENCES Products(ProductID), + FOREIGN KEY (TierID) REFERENCES PriceTiers(TierID) +); + +CREATE TABLE Promotions ( + PromotionID INT IDENTITY(1,1) PRIMARY KEY, + PromotionCode VARCHAR(50) NOT NULL UNIQUE, + PromotionName NVARCHAR(200) NOT NULL, + DiscountType VARCHAR(20) NOT NULL, -- Percentage, FixedAmount, BuyOneGetOne + DiscountValue DECIMAL(18,2) NOT NULL, + StartDate DATETIME2 NOT NULL, + EndDate DATETIME2 NOT NULL, + MinOrderAmount DECIMAL(18,2) NULL, + MaxDiscountAmount DECIMAL(18,2) NULL, + UsageLimit INT NULL, + UsedCount INT NOT NULL DEFAULT 0, + IsActive BIT NOT NULL DEFAULT 1 +); + +CREATE TABLE PromotionApplicability ( + ApplicabilityID INT IDENTITY(1,1) PRIMARY KEY, + PromotionID INT NOT NULL, + ApplicableToType VARCHAR(20) NOT NULL, -- AllProducts, SpecificProduct, SpecificCategory, SpecificBrand + ReferenceID INT NULL, + FOREIGN KEY (PromotionID) REFERENCES Promotions(PromotionID) +); + +-- ============================================= +-- 4. Order Management Schema +-- ============================================= + +CREATE TABLE OrderStatus ( + StatusID INT IDENTITY(1,1) PRIMARY KEY, + StatusName VARCHAR(50) NOT NULL UNIQUE, + StatusDescription NVARCHAR(200) NULL, + IsFinalState BIT NOT NULL DEFAULT 0 +); + +CREATE TABLE Orders ( + OrderID INT IDENTITY(1,1) PRIMARY KEY, + OrderNumber AS 'ORD-' + FORMAT(OrderID, '000000') PERSISTED, + CustomerID INT NOT NULL, + OrderDate DATETIME2 NOT NULL DEFAULT GETDATE(), + StatusID INT NOT NULL, + PaymentStatus VARCHAR(30) NOT NULL DEFAULT 'Pending', -- Pending, Paid, Failed, Refunded + ShippingAddressID INT NOT NULL, + BillingAddressID INT NOT NULL, + Subtotal DECIMAL(18,2) NOT NULL, + TaxAmount DECIMAL(18,2) NOT NULL DEFAULT 0, + ShippingAmount DECIMAL(18,2) NOT NULL DEFAULT 0, + DiscountAmount DECIMAL(18,2) NOT NULL DEFAULT 0, + TotalAmount DECIMAL(18,2) NOT NULL, + PromotionID INT NULL, + Notes NVARCHAR(MAX) NULL, + OrderWeight DECIMAL(10,3) NOT NULL DEFAULT 0, + CompletedDate DATETIME2 NULL, + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID), + FOREIGN KEY (StatusID) REFERENCES OrderStatus(StatusID), + FOREIGN KEY (ShippingAddressID) REFERENCES CustomerAddresses(AddressID), + FOREIGN KEY (BillingAddressID) REFERENCES CustomerAddresses(AddressID), + FOREIGN KEY (PromotionID) REFERENCES Promotions(PromotionID) +); + +CREATE TABLE OrderItems ( + OrderItemID INT IDENTITY(1,1) PRIMARY KEY, + OrderID INT NOT NULL, + ProductID INT NOT NULL, + Quantity INT NOT NULL, + UnitPrice DECIMAL(18,2) NOT NULL, + DiscountApplied DECIMAL(18,2) NOT NULL DEFAULT 0, + TotalPrice DECIMAL(18,2) NOT NULL, + FOREIGN KEY (OrderID) REFERENCES Orders(OrderID) ON DELETE CASCADE, + FOREIGN KEY (ProductID) REFERENCES Products(ProductID) +); + +CREATE TABLE OrderTracking ( + TrackingID INT IDENTITY(1,1) PRIMARY KEY, + OrderID INT NOT NULL, + StatusID INT NOT NULL, + StatusDate DATETIME2 NOT NULL DEFAULT GETDATE(), + Notes NVARCHAR(500) NULL, + FOREIGN KEY (OrderID) REFERENCES Orders(OrderID) ON DELETE CASCADE, + FOREIGN KEY (StatusID) REFERENCES OrderStatus(StatusID) +); + +-- ============================================= +-- 5. Payment & Transaction Schema +-- ============================================= + +CREATE TABLE PaymentMethods ( + PaymentMethodID INT IDENTITY(1,1) PRIMARY KEY, + MethodName VARCHAR(50) NOT NULL UNIQUE, -- CreditCard, PayPal, BankTransfer, Cash + IsActive BIT NOT NULL DEFAULT 1, + ProcessingFee DECIMAL(5,2) NOT NULL DEFAULT 0 +); + +CREATE TABLE Currencies ( + CurrencyID INT IDENTITY(1,1) PRIMARY KEY, + CurrencyCode CHAR(3) NOT NULL UNIQUE, -- USD, EUR, GBP, JPY + CurrencyName NVARCHAR(50) NOT NULL, + ExchangeRateToUSD DECIMAL(18,6) NOT NULL, + IsBaseCurrency BIT NOT NULL DEFAULT 0 +); + +CREATE TABLE Payments ( + PaymentID INT IDENTITY(1,1) PRIMARY KEY, + OrderID INT NOT NULL, + PaymentMethodID INT NOT NULL, + CurrencyID INT NOT NULL, + Amount DECIMAL(18,2) NOT NULL, + PaymentDate DATETIME2 NOT NULL DEFAULT GETDATE(), + TransactionID VARCHAR(100) NULL, + PaymentStatus VARCHAR(30) NOT NULL DEFAULT 'Pending', + GatewayResponse NVARCHAR(MAX) NULL, + FOREIGN KEY (OrderID) REFERENCES Orders(OrderID), + FOREIGN KEY (PaymentMethodID) REFERENCES PaymentMethods(PaymentMethodID), + FOREIGN KEY (CurrencyID) REFERENCES Currencies(CurrencyID) +); + +CREATE TABLE Refunds ( + RefundID INT IDENTITY(1,1) PRIMARY KEY, + PaymentID INT NOT NULL, + RefundAmount DECIMAL(18,2) NOT NULL, + RefundDate DATETIME2 NOT NULL DEFAULT GETDATE(), + Reason NVARCHAR(500) NULL, + ApprovalStatus VARCHAR(30) NOT NULL DEFAULT 'Pending', + ProcessedBy INT NULL, + FOREIGN KEY (PaymentID) REFERENCES Payments(PaymentID) +); + +-- ============================================= +-- 6. Shipping & Logistics Schema +-- ============================================= + +CREATE TABLE ShippingMethods ( + ShippingMethodID INT IDENTITY(1,1) PRIMARY KEY, + MethodName VARCHAR(100) NOT NULL UNIQUE, -- Standard, Express, Overnight + EstimatedDeliveryDays INT NOT NULL, + BaseCost DECIMAL(18,2) NOT NULL, + CostPerKg DECIMAL(18,2) NOT NULL DEFAULT 0, + IsActive BIT NOT NULL DEFAULT 1 +); + +CREATE TABLE Shipments ( + ShipmentID INT IDENTITY(1,1) PRIMARY KEY, + OrderID INT NOT NULL, + ShippingMethodID INT NOT NULL, + TrackingNumber VARCHAR(100) NULL, + CarrierName VARCHAR(100) NOT NULL, + ShippedDate DATETIME2 NULL, + DeliveredDate DATETIME2 NULL, + ShippingCost DECIMAL(18,2) NOT NULL, + FOREIGN KEY (OrderID) REFERENCES Orders(OrderID), + FOREIGN KEY (ShippingMethodID) REFERENCES ShippingMethods(ShippingMethodID) +); + +CREATE TABLE Warehouses ( + WarehouseID INT IDENTITY(1,1) PRIMARY KEY, + WarehouseCode VARCHAR(20) NOT NULL UNIQUE, + WarehouseName NVARCHAR(100) NOT NULL, + LocationAddress NVARCHAR(500) NOT NULL, + City NVARCHAR(100) NOT NULL, + CountryCode CHAR(2) NOT NULL, + IsActive BIT NOT NULL DEFAULT 1 +); + +-- Add WarehouseCode foreign key to Inventory +ALTER TABLE Inventory ADD WarehouseID INT NULL; +ALTER TABLE Inventory ADD FOREIGN KEY (WarehouseID) REFERENCES Warehouses(WarehouseID); +ALTER TABLE Inventory ALTER COLUMN WarehouseCode VARCHAR(20) NULL; + +-- ============================================= +-- 7. Reviews & Ratings Schema +-- ============================================= + +CREATE TABLE ProductReviews ( + ReviewID INT IDENTITY(1,1) PRIMARY KEY, + ProductID INT NOT NULL, + CustomerID INT NOT NULL, + Rating INT NOT NULL, -- 1 to 5 stars + Title NVARCHAR(200) NULL, + ReviewText NVARCHAR(MAX) NULL, + IsVerifiedPurchase BIT NOT NULL DEFAULT 0, + HelpfulCount INT NOT NULL DEFAULT 0, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + IsApproved BIT NOT NULL DEFAULT 0, + FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ON DELETE CASCADE, + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) +); + +CREATE TABLE ReviewHelpfulness ( + HelpfulnessID INT IDENTITY(1,1) PRIMARY KEY, + ReviewID INT NOT NULL, + CustomerID INT NOT NULL, + IsHelpful BIT NOT NULL, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + FOREIGN KEY (ReviewID) REFERENCES ProductReviews(ReviewID) ON DELETE CASCADE, + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID), + CONSTRAINT UQ_Review_Customer UNIQUE (ReviewID, CustomerID) +); + +-- ============================================= +-- 8. Shopping Cart Schema +-- ============================================= + +CREATE TABLE ShoppingCarts ( + CartID INT IDENTITY(1,1) PRIMARY KEY, + CustomerID INT NOT NULL UNIQUE, + CreatedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + LastModified DATETIME2 NOT NULL DEFAULT GETDATE(), + FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ON DELETE CASCADE +); + +CREATE TABLE CartItems ( + CartItemID INT IDENTITY(1,1) PRIMARY KEY, + CartID INT NOT NULL, + ProductID INT NOT NULL, + Quantity INT NOT NULL, + AddedAt DATETIME2 NOT NULL DEFAULT GETDATE(), + FOREIGN KEY (CartID) REFERENCES ShoppingCarts(CartID) ON DELETE CASCADE, + FOREIGN KEY (ProductID) REFERENCES Products(ProductID) +); + +-- ============================================= +-- INDEXES for Performance +-- ============================================= + +-- Customers indexes +CREATE INDEX IX_Customers_Email ON Customers(Email); +CREATE INDEX IX_Customers_LastName ON Customers(LastName); +CREATE INDEX IX_Customers_CreatedAt ON Customers(CreatedAt); + +-- CustomerAddresses indexes +CREATE INDEX IX_CustomerAddresses_CustomerID ON CustomerAddresses(CustomerID); +CREATE INDEX IX_CustomerAddresses_CountryCode ON CustomerAddresses(CountryCode); + +-- Products indexes +CREATE INDEX IX_Products_CategoryID ON Products(CategoryID); +CREATE INDEX IX_Products_BrandID ON Products(BrandID); +CREATE INDEX IX_Products_SKU ON Products(SKU); +CREATE INDEX IX_Products_UnitPrice ON Products(UnitPrice); +CREATE INDEX IX_Products_IsActive ON Products(IsActive); + +-- Inventory indexes +CREATE INDEX IX_Inventory_ProductID ON Inventory(ProductID); +CREATE INDEX IX_Inventory_WarehouseID ON Inventory(WarehouseID); +CREATE INDEX IX_Inventory_QuantityOnHand ON Inventory(QuantityOnHand); + +-- Orders indexes +CREATE INDEX IX_Orders_CustomerID ON Orders(CustomerID); +CREATE INDEX IX_Orders_OrderDate ON Orders(OrderDate); +CREATE INDEX IX_Orders_StatusID ON Orders(StatusID); +CREATE INDEX IX_Orders_PaymentStatus ON Orders(PaymentStatus); +CREATE INDEX IX_Orders_TotalAmount ON Orders(TotalAmount); + +-- OrderItems indexes +CREATE INDEX IX_OrderItems_OrderID ON OrderItems(OrderID); +CREATE INDEX IX_OrderItems_ProductID ON OrderItems(ProductID); + +-- Payments indexes +CREATE INDEX IX_Payments_OrderID ON Payments(OrderID); +CREATE INDEX IX_Payments_PaymentStatus ON Payments(PaymentStatus); +CREATE INDEX IX_Payments_PaymentDate ON Payments(PaymentDate); + +-- Shipments indexes +CREATE INDEX IX_Shipments_OrderID ON Shipments(OrderID); +CREATE INDEX IX_Shipments_TrackingNumber ON Shipments(TrackingNumber); +CREATE INDEX IX_Shipments_ShippedDate ON Shipments(ShippedDate); + +-- ProductReviews indexes +CREATE INDEX IX_ProductReviews_ProductID ON ProductReviews(ProductID); +CREATE INDEX IX_ProductReviews_CustomerID ON ProductReviews(CustomerID); +CREATE INDEX IX_ProductReviews_Rating ON ProductReviews(Rating); +CREATE INDEX IX_ProductReviews_CreatedAt ON ProductReviews(CreatedAt); + +-- Promotions indexes +CREATE INDEX IX_Promotions_PromotionCode ON Promotions(PromotionCode); +CREATE INDEX IX_Promotions_StartDate_EndDate ON Promotions(StartDate, EndDate); + +-- OrderTracking indexes +CREATE INDEX IX_OrderTracking_OrderID ON OrderTracking(OrderID); +CREATE INDEX IX_OrderTracking_StatusID ON OrderTracking(StatusID); +CREATE INDEX IX_OrderTracking_StatusDate ON OrderTracking(StatusDate); + +-- CartItems indexes +CREATE INDEX IX_CartItems_CartID ON CartItems(CartID); +CREATE INDEX IX_CartItems_ProductID ON CartItems(ProductID); + +-- Composite indexes for common query patterns +CREATE INDEX IX_Orders_Customer_Date ON Orders(CustomerID, OrderDate DESC); +CREATE INDEX IX_OrderItems_Product_Price ON OrderItems(ProductID, UnitPrice); +CREATE INDEX IX_Products_Category_Price ON Products(CategoryID, UnitPrice); + +-- ============================================= +-- Insert initial reference data +-- ============================================= + +-- Order Status +INSERT INTO OrderStatus (StatusName, StatusDescription, IsFinalState) VALUES +('Pending', 'Order placed but not processed', 0), +('PaymentReceived', 'Payment has been confirmed', 0), +('Processing', 'Order is being prepared', 0), +('Shipped', 'Order has been shipped', 0), +('Delivered', 'Order delivered to customer', 1), +('Cancelled', 'Order cancelled', 1), +('Refunded', 'Order refunded', 1); + +-- Payment Methods +INSERT INTO PaymentMethods (MethodName, ProcessingFee) VALUES +('CreditCard', 2.9), +('PayPal', 3.5), +('BankTransfer', 0.5), +('CashOnDelivery', 0.0); + +-- Currencies +INSERT INTO Currencies (CurrencyCode, CurrencyName, ExchangeRateToUSD, IsBaseCurrency) VALUES +('USD', 'US Dollar', 1.0, 1), +('EUR', 'Euro', 1.09, 0), +('GBP', 'British Pound', 1.27, 0), +('JPY', 'Japanese Yen', 0.0067, 0); + +-- Shipping Methods +INSERT INTO ShippingMethods (MethodName, EstimatedDeliveryDays, BaseCost, CostPerKg) VALUES +('Standard Shipping', 5, 5.99, 1.5), +('Express Shipping', 2, 12.99, 2.5), +('Overnight', 1, 24.99, 4.0); + +-- Price Tiers +INSERT INTO PriceTiers (TierName, MinQuantity, DiscountPercentage) VALUES +('Regular', 1, 0), +('Wholesale', 10, 10), +('Bulk', 50, 15), +('Enterprise', 100, 20); + +-- Sample Categories +INSERT INTO Categories (CategoryName, CategoryCode, DisplayOrder) VALUES +('Electronics', 'ELEC', 1), +('Clothing', 'CLOTH', 2), +('Books', 'BOOKS', 3), +('Home & Garden', 'HOME', 4); + +-- Sample Brands +INSERT INTO Brands (BrandName, BrandCode) VALUES +('TechPro', 'TP001'), +('FashionHub', 'FH002'), +('ReadWell', 'RW003'); +*/ diff --git a/src/utils/import/mysql-importer.ts b/src/utils/import/mysql-importer.ts new file mode 100644 index 0000000..46af5c7 --- /dev/null +++ b/src/utils/import/mysql-importer.ts @@ -0,0 +1,97 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { BaseSqlImporter, ParsedDatabaase, ParsedField } from "./base-sql-importer"; +import { DatabaseDialect } from "@/lib/database"; +import { Modifiers, MySQLCharset, MySQLCollation } from "@/lib/field"; + +export class MysqlImporter extends BaseSqlImporter { + + public constructor(data_types: DataType[]) { + super(data_types); + this.dialect = DatabaseDialect.MYSQL; + } + + protected astToField(ast: any, sequence: number): ParsedField { + try { + const { field, fk_constraint } = super.astToField(ast, sequence) + // get the data type + const dataType: DataType = this.data_types.find((dataType: DataType) => dataType.id == field.typeId) as DataType; + // if data type is of type set then extract it's values + if (dataType.name == "set") { + if (ast.data_type["Set"] && Array.isArray(ast.data_type["Set"])) { + try { + field.values = JSON.stringify(ast.data_type["Set"]) + } catch (error) { + console.error("faield to parse Mysql Set values") + } + } + + } + // get data type modifiers + const modifiers: string[] = dataType?.modifiers ? JSON.parse(dataType.modifiers) : []; + + const options: any | undefined = [] = ast.options; + + for (const option of options) { + if (typeof option.option === "object") { + if (option.option?.CharacterSet?.[0]?.Identifier?.value && modifiers.includes(Modifiers.CHARSET)) { + const charset: string = option.option.CharacterSet[0].Identifier.value; + + if (Object.values(MySQLCharset).includes(charset as MySQLCharset)) { + + field.charset = charset; + } + } + if (option.option?.Collation?.[0]?.Identifier?.value && modifiers.includes(Modifiers.COLLATE)) { + + const collate: string = option.option.Collation[0].Identifier.value; + + if (Object.values(MySQLCollation).includes(collate as MySQLCollation)) { + + field.collate = collate; + } + + } + + } + } + + return { field, fk_constraint }; + } catch (error) { + throw error; + } + } + + + protected cleanSql(sql: string): string { + let cleaned: string = super.cleanSql(sql); + return cleaned.replace(/\b(?:unsigned|zerofill)\b/gi, ''); + } +} + + + +/* + + +CREATE TABLE employees ( + id INT PRIMARY KEY AUTO_INCREMENT, + first_name VARCHAR(100), + last_name VARCHAR(100), + department_id INT, + + CONSTRAINT uq_employee_name_dept + UNIQUE (first_name, last_name, department_id) +); + +CREATE TABLE products ( + id INT PRIMARY KEY AUTO_INCREMENT, + sku VARCHAR(100), + name VARCHAR(255) +); + +ALTER TABLE products +ADD CONSTRAINT uq_products_sku +UNIQUE (sku); + + +*/ \ No newline at end of file diff --git a/src/utils/import/oracle-importer.ts b/src/utils/import/oracle-importer.ts new file mode 100644 index 0000000..066ce2a --- /dev/null +++ b/src/utils/import/oracle-importer.ts @@ -0,0 +1,725 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { BaseSqlImporter, ExtractedStatments, ParsedDatabaase, ParsedField } from "./base-sql-importer"; + +import { DataTypes, Modifiers, TimeDefaultValues } from "@/lib/field"; +import { TableInsertType } from "@/lib/schemas/table-schema"; +import { FieldInsertType } from "@/lib/schemas/field-schema"; + +export class OracleImporter extends BaseSqlImporter { + + private alterNullabilityStatments: string[] = []; + + public constructor(data_types: DataType[]) { + super(data_types); + this.dialect = DatabaseDialect.ORACLE; + } + + + + public parseSql(sql: string) { + try { + this.alterNullabilityStatments = []; + const parsedDatabaase: ParsedDatabaase = super.parseSql(sql); + for (const statment of this.alterNullabilityStatments) { + try { + + this.processAlterColumnNullabilityStatment(statment, parsedDatabaase.tables); + } catch (error) { + parsedDatabaase.errors.push(error as Error); + } + } + return parsedDatabaase; + } catch (error) { + throw error; + } + } + + + protected astToField(ast: any, sequence: number): ParsedField { + const { field, fk_constraint } = super.astToField(ast, sequence); + + const dataType: DataType = this.data_types.find((dataType: DataType) => dataType.id == field.typeId) as DataType; + // get the modifiers to test if the data type really support auto increment or not + const modifiers: string[] = dataType?.modifiers ? JSON.parse(dataType.modifiers) : []; + + if (ast.data_type.Custom && Array.isArray(ast.data_type.Custom)) { + if (ast.data_type.Custom.length == 2 && ast.data_type.Custom[1]?.length == 2 && !isNaN(Number(ast.data_type.Custom[1]?.[1] && modifiers.includes(Modifiers.SCALE)))) + field.scale = Number(ast.data_type.Custom[1]?.[1]); + } + // get field defintion options + const options: any | undefined = [] = ast.options; + for (const option of options) { + if (option.option?.Generated?.generated_as == "ByDefault") { + if (modifiers.includes(Modifiers.AUTO_INCREMENT)) { + field.autoIncrement = true; + break; + } + } + } + return { field, fk_constraint }; + + } + + + private processAlterColumnNullabilityStatment(statement: string, tables: TableInsertType[]): void { + + + const regex = /ALTER\s+TABLE\s+"(?[^"]+)"\s+MODIFY\s*\(\s*"(?[^"]+)"\s+(?NOT\s+NULL|NULL)(?:\s+ENABLE)?\s*\)/i; + const match = statement.match(regex); + + + + if (match?.groups) { + const { tableName, columnName, nullability } = match.groups; + + + const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name.toUpperCase() == tableName.toUpperCase()); + if (!table) { + throw Error("Altered Table not found in : " + statement); + } + const field : FieldInsertType | undefined = table.fields?.find((field: FieldInsertType) => field.name.toUpperCase() == columnName.toUpperCase()) + if (!field) + throw Error("Altered field not found in : " + statement); + + + field.nullable = !(nullability.toUpperCase() == "NOT NULL") ; + + } + } + + protected processDefaultValue(ast: any, dataType: DataType): string | undefined { + const defaultValue: string | undefined = super.processDefaultValue(ast, dataType); + + if (!defaultValue && ast.Identifier && ast.Identifier.value && dataType.type == DataTypes.TIME) { + + if (this.isCurrentTimesTampFunction(ast.Identifier.value)) + return TimeDefaultValues.NOW; + } + return defaultValue; + } + + + protected isCurrentTimesTampFunction(value: string): boolean { + const upper: string = value.toUpperCase(); + return super.isCurrentTimesTampFunction(value) || upper == "SYSDATE" || upper == "SYSTIMESTAMP"; + } + + protected processDataType(typeName: string): DataType | undefined { + let dataType: DataType | undefined = super.processDataType(typeName); + + if (!dataType) { + if (typeName == "year") { + return this.data_types.find((dataType: DataType) => dataType.name == "interval year to month"); + } + else if (typeName == "day") { + return this.data_types.find((dataType: DataType) => dataType.name == "interval day to second"); + } + } + return dataType; + } + + + protected cleanSql(sql: string): string { + let cleaned: string = super.cleanSql(sql); + cleaned = cleaned.replace(/\bWITH\s+LOCAL\s+TIME\b/gi, 'WITH TIME'); + // remove all ENABLE keywords in add foriegn key constraint + cleaned = cleaned.replace( + /(ALTER\s+TABLE[\s\S]*?FOREIGN\s+KEY[\s\S]*?REFERENCES[\s\S]*?)\s+ENABLE(?=\s*;)/gi, + '$1' + ); + // remove MINVALUE [X] MAXVALUE [Y] INCREMENT BY [N] START WITH [M] CACHE [C] NOORDER NOCYCLE NOKEEP NOSCALE . + cleaned = cleaned.replace( + /(GENERATED\s+(?:ALWAYS|BY\s+DEFAULT(?:\s+ON\s+NULL)?)\s+AS\s+IDENTITY)([\s\S]*?)(?=,|\s+NOT\s+NULL|\s+PRIMARY\s+KEY)/gi, + '$1' + ); + // remove all USING INDEX ENBALE in add Unique or Primary Key constraints . + cleaned = cleaned.replace(/\s+USING\s+INDEX\s+ENABLE(?=\s*;)/gi, ''); + // remove START WITH X INCREMENT BY Y + cleaned = cleaned.replace(/\s+START\s+WITH\s+\d+(?:\s+INCREMENT\s+BY\s+\d+)?/gi, ''); + cleaned = cleaned.replace( + /\bINTERVAL\s+YEAR(\s*\(\s*\d+\s*\))?\s+TO\s+MONTH(?:\s*\(\s*\d+\s*\))?/gi, + 'YEAR$1' + ); + + cleaned = cleaned.replace( + /\bINTERVAL\s+DAY(\s*\(\s*\d+\s*\))?\s+TO\s+SECOND(?:\s*\(\s*\d+\s*\))?/gi, + 'DAY$1' + ); + + + return cleaned; + } + + protected extractStatments(sql: string): ExtractedStatments { + + const statments: ExtractedStatments = super.extractStatments(sql); + + statments.alterTableStatements = statments.alterTableStatements.filter((statment: string) => { + if (/ALTER\s+TABLE\s+.+?\s+MODIFY\s*\(\s*".+?"\s+(?:NULL|NOT\s+NULL)(?:\s+ENABLE)?\s*\)/i.test(statment)) { + + this.alterNullabilityStatments.push(statment); + + } + else { + + return statment; + } + }) + return statments + } +} + + +/* + + + + + + +-- ============================================= +-- Creative Enterprise Platform Database for Oracle +-- Theme: Multi-Tenant Project Management & Resource Planning +-- Version: 3.0 (Oracle Edition) +-- ============================================= + +-- Drop user/schema if needed (optional - run separately) +-- DROP USER creative_enterprise CASCADE; +-- CREATE USER creative_enterprise IDENTIFIED BY password; +-- GRANT CONNECT, RESOURCE, UNLIMITED TABLESPACE TO creative_enterprise; +-- CONNECT creative_enterprise/password; + +-- ============================================= +-- 1. TENANT & ORGANIZATION SCHEMA +-- ============================================= + +-- Inline primary key, inline unique, default as expression +CREATE TABLE Tenants ( + TenantID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 100 INCREMENT BY 1 PRIMARY KEY, + TenantCode VARCHAR2(20) NOT NULL UNIQUE, + TenantName NVARCHAR2(200) NOT NULL, + SubscriptionTier VARCHAR2(30) DEFAULT 'Trial' NOT NULL, + CreatedDate DATE DEFAULT SYSDATE NOT NULL, + IsActive CHAR(1) DEFAULT '1' NOT NULL, + MaxUsers NUMBER(5) DEFAULT 10 NOT NULL, + CONSTRAINT UQ_Tenant_Name UNIQUE (TenantName) +); + +-- Constraints at end of table +CREATE TABLE Departments ( + DepartmentID NUMBER(10) NOT NULL, + TenantID NUMBER(10) NOT NULL, + DeptCode VARCHAR2(20) NOT NULL, + DeptName NVARCHAR2(100) NOT NULL, + Budget NUMBER(18,2) DEFAULT 0 NOT NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, + CONSTRAINT PK_Departments PRIMARY KEY (DepartmentID, TenantID), + CONSTRAINT UQ_DeptCode_Tenant UNIQUE (DeptCode, TenantID) +); + +-- Foreign key added via ALTER after creation +CREATE TABLE Companies ( + CompanyID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 500 INCREMENT BY 5 NOT NULL, + TenantID NUMBER(10) NOT NULL, + CompanyName NVARCHAR2(150) NOT NULL, + LegalName NVARCHAR2(200) NOT NULL, + TaxNumber VARCHAR2(50) NOT NULL, + FoundedYear NUMBER(4) DEFAULT EXTRACT(YEAR FROM SYSDATE) NOT NULL, + IsHeadquarters CHAR(1) DEFAULT '0' NOT NULL +); + +-- Adding constraint via ALTER +ALTER TABLE Companies ADD CONSTRAINT PK_Companies PRIMARY KEY (CompanyID); +ALTER TABLE Companies ADD CONSTRAINT UQ_Company_TaxNumber UNIQUE (TaxNumber); +ALTER TABLE Companies ADD CONSTRAINT UQ_Company_Name_Tenant UNIQUE (CompanyName, TenantID); + +-- ============================================= +-- 2. USER & ROLE MANAGEMENT +-- ============================================= + +-- Mix of inline and named constraints +CREATE TABLE Roles ( + RoleID RAW(16) DEFAULT SYS_GUID() PRIMARY KEY, + RoleName VARCHAR2(50) NOT NULL CONSTRAINT AK_RoleName UNIQUE, + PriorityLevel NUMBER(3) DEFAULT 5 NOT NULL, + IsSystemRole CHAR(1) DEFAULT '0' NOT NULL +); + +-- Primary key inline, foreign keys at end +CREATE TABLE Users ( + UserID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + TenantID NUMBER(10) NOT NULL, + RoleID RAW(16) NOT NULL, + Email VARCHAR2(255) NOT NULL, + Username VARCHAR2(100) NOT NULL, + PasswordHash CHAR(64) NOT NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, + LastLogin TIMESTAMP NULL, + IsLocked CHAR(1) DEFAULT '0' NOT NULL, + LoginAttempts NUMBER(3) DEFAULT 0 NOT NULL, + CONSTRAINT PK_Users PRIMARY KEY (UserID), + CONSTRAINT UQ_User_Email UNIQUE (Email), + CONSTRAINT UQ_User_Username_Tenant UNIQUE (Username, TenantID) +); + +-- Foreign keys added via ALTER +ALTER TABLE Users ADD CONSTRAINT FK_Users_Tenants FOREIGN KEY (TenantID) REFERENCES Tenants(TenantID); +ALTER TABLE Users ADD CONSTRAINT FK_Users_Roles FOREIGN KEY (RoleID) REFERENCES Roles(RoleID); + +-- Foreign key added via ALTER +CREATE TABLE UserProfiles ( + ProfileID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + UserID NUMBER(10) NOT NULL, + FirstName NVARCHAR2(50) NOT NULL, + LastName NVARCHAR2(50) NOT NULL, + PhoneNumber VARCHAR2(20) NULL, + DateOfBirth DATE NULL, + ProfileImageURL VARCHAR2(500) NULL, + LastUpdated TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL +); + +ALTER TABLE UserProfiles ADD CONSTRAINT PK_UserProfiles PRIMARY KEY (ProfileID); +ALTER TABLE UserProfiles ADD CONSTRAINT UQ_UserProfiles_UserID UNIQUE (UserID); +ALTER TABLE UserProfiles ADD CONSTRAINT FK_UserProfiles_Users FOREIGN KEY (UserID) REFERENCES Users(UserID) ON DELETE CASCADE; + +-- ============================================= +-- 3. PROJECT & TASK MANAGEMENT +-- ============================================= + +-- Primary key as named constraint at end +CREATE TABLE Projects ( + ProjectID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1000 INCREMENT BY 1 NOT NULL, + TenantID NUMBER(10) NOT NULL, + DepartmentID NUMBER(10) NOT NULL, + CompanyID NUMBER(10) NULL, + ProjectName NVARCHAR2(200) NOT NULL, + ProjectCode VARCHAR2(30) NOT NULL, + StartDate DATE DEFAULT SYSDATE NOT NULL, + EndDate DATE NULL, + Status VARCHAR2(20) DEFAULT 'Planning' NOT NULL, + Priority VARCHAR2(20) DEFAULT 'Medium' NOT NULL, + CompletionPercent NUMBER(5,2) DEFAULT 0 NOT NULL +); + +ALTER TABLE Projects ADD CONSTRAINT PK_Projects PRIMARY KEY (ProjectID); +ALTER TABLE Projects ADD CONSTRAINT UQ_ProjectCode_Tenant UNIQUE (ProjectCode, TenantID); +ALTER TABLE Projects ADD CONSTRAINT FK_Projects_Tenants FOREIGN KEY (TenantID) REFERENCES Tenants(TenantID); +ALTER TABLE Projects ADD CONSTRAINT FK_Projects_Departments FOREIGN KEY (DepartmentID, TenantID) REFERENCES Departments(DepartmentID, TenantID); +ALTER TABLE Projects ADD CONSTRAINT FK_Projects_Companies FOREIGN KEY (CompanyID) REFERENCES Companies(CompanyID); + +-- All constraints inline +CREATE TABLE Tasks ( + TaskID NUMBER(15) GENERATED BY DEFAULT AS IDENTITY START WITH 50000 INCREMENT BY 1 PRIMARY KEY, + ProjectID NUMBER(10) NOT NULL, + ParentTaskID NUMBER(15) NULL, + TaskTitle NVARCHAR2(200) NOT NULL, + TaskDescription NCLOB NULL, + AssignedToUserID NUMBER(10) NULL, + Status VARCHAR2(20) DEFAULT 'ToDo' NOT NULL, + StoryPoints NUMBER(3) DEFAULT 1 NOT NULL, + DueDate DATE NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, + CONSTRAINT FK_Tasks_Projects FOREIGN KEY (ProjectID) REFERENCES Projects(ProjectID) ON DELETE CASCADE, + CONSTRAINT FK_Tasks_ParentTask FOREIGN KEY (ParentTaskID) REFERENCES Tasks(TaskID), + CONSTRAINT FK_Tasks_AssignedUser FOREIGN KEY (AssignedToUserID) REFERENCES Users(UserID), + CONSTRAINT UQ_Task_Project_Title UNIQUE (ProjectID, TaskTitle) +); + +-- ALTER for composite foreign key +CREATE TABLE TaskDependencies ( + DependencyID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + TaskID NUMBER(15) NOT NULL, + DependsOnTaskID NUMBER(15) NOT NULL, + DependencyType VARCHAR2(20) DEFAULT 'FS' NOT NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL +); + +ALTER TABLE TaskDependencies ADD CONSTRAINT PK_TaskDependencies PRIMARY KEY (DependencyID); +ALTER TABLE TaskDependencies ADD CONSTRAINT UQ_Task_Dependency UNIQUE (TaskID, DependsOnTaskID); +ALTER TABLE TaskDependencies ADD CONSTRAINT FK_TaskDependencies_Task FOREIGN KEY (TaskID) REFERENCES Tasks(TaskID); +ALTER TABLE TaskDependencies ADD CONSTRAINT FK_TaskDependencies_DependsOn FOREIGN KEY (DependsOnTaskID) REFERENCES Tasks(TaskID); + +-- ============================================= +-- 4. RESOURCE & ALLOCATION +-- ============================================= + +CREATE TABLE ResourceTypes ( + ResourceTypeID NUMBER(3) PRIMARY KEY, + TypeName VARCHAR2(50) NOT NULL UNIQUE, + IsBillable CHAR(1) DEFAULT '1' NOT NULL, + HourlyRate NUMBER(10,2) DEFAULT 0 NOT NULL +); + +CREATE TABLE Resources ( + ResourceID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + ResourceTypeID NUMBER(3) NOT NULL, + TenantID NUMBER(10) NOT NULL, + ResourceName NVARCHAR2(100) NOT NULL, + ResourceCode VARCHAR2(30) NOT NULL, + IsAvailable CHAR(1) DEFAULT '1' NOT NULL, + DailyCapacity NUMBER(8,2) DEFAULT 8 NOT NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL +); + +ALTER TABLE Resources ADD CONSTRAINT PK_Resources PRIMARY KEY (ResourceID); +ALTER TABLE Resources ADD CONSTRAINT UQ_ResourceCode_Tenant UNIQUE (ResourceCode, TenantID); +ALTER TABLE Resources ADD CONSTRAINT FK_Resources_ResourceTypes FOREIGN KEY (ResourceTypeID) REFERENCES ResourceTypes(ResourceTypeID); +ALTER TABLE Resources ADD CONSTRAINT FK_Resources_Tenants FOREIGN KEY (TenantID) REFERENCES Tenants(TenantID); + +-- Foreign key added via ALTER (different style) +CREATE TABLE ResourceAllocations ( + AllocationID RAW(16) DEFAULT SYS_GUID() NOT NULL, + ResourceID NUMBER(10) NOT NULL, + TaskID NUMBER(15) NOT NULL, + AllocatedHours NUMBER(8,2) NOT NULL, + AllocationDate DATE DEFAULT SYSDATE NOT NULL, + IsConfirmed CHAR(1) DEFAULT '0' NOT NULL, + Notes NVARCHAR2(500) NULL +); + +ALTER TABLE ResourceAllocations ADD CONSTRAINT PK_ResourceAllocations PRIMARY KEY (AllocationID); +ALTER TABLE ResourceAllocations ADD CONSTRAINT UQ_Resource_Task_Date UNIQUE (ResourceID, TaskID, AllocationDate); +ALTER TABLE ResourceAllocations ADD CONSTRAINT FK_ResourceAllocations_Resources FOREIGN KEY (ResourceID) REFERENCES Resources(ResourceID); +ALTER TABLE ResourceAllocations ADD CONSTRAINT FK_ResourceAllocations_Tasks FOREIGN KEY (TaskID) REFERENCES Tasks(TaskID); + +-- ============================================= +-- 5. TIME TRACKING +-- ============================================= + +CREATE TABLE TimeEntries ( + TimeEntryID NUMBER(15) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + UserID NUMBER(10) NOT NULL, + TaskID NUMBER(15) NOT NULL, + EntryDate DATE DEFAULT SYSDATE NOT NULL, + HoursWorked NUMBER(5,2) NOT NULL, + Description NVARCHAR2(500) NULL, + IsBilled CHAR(1) DEFAULT '0' NOT NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL +); + +ALTER TABLE TimeEntries ADD CONSTRAINT PK_TimeEntries PRIMARY KEY (TimeEntryID); +ALTER TABLE TimeEntries ADD CONSTRAINT FK_TimeEntries_Users FOREIGN KEY (UserID) REFERENCES Users(UserID); +ALTER TABLE TimeEntries ADD CONSTRAINT FK_TimeEntries_Tasks FOREIGN KEY (TaskID) REFERENCES Tasks(TaskID); +ALTER TABLE TimeEntries ADD CONSTRAINT UQ_TimeEntry_User_Task_Date UNIQUE (UserID, TaskID, EntryDate); + +-- ============================================= +-- 6. INVOICING & BILLING +-- ============================================= + +CREATE TABLE BillingRates ( + RateID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + TenantID NUMBER(10) NOT NULL, + ResourceTypeID NUMBER(3) NOT NULL, + HourlyRate NUMBER(10,2) NOT NULL, + EffectiveFrom DATE DEFAULT SYSDATE NOT NULL, + EffectiveTo DATE NULL +); + +ALTER TABLE BillingRates ADD CONSTRAINT PK_BillingRates PRIMARY KEY (RateID); +ALTER TABLE BillingRates ADD CONSTRAINT UQ_Rate_Type_Tenant_Date UNIQUE (TenantID, ResourceTypeID, EffectiveFrom); +ALTER TABLE BillingRates ADD CONSTRAINT FK_BillingRates_Tenants FOREIGN KEY (TenantID) REFERENCES Tenants(TenantID); +ALTER TABLE BillingRates ADD CONSTRAINT FK_BillingRates_ResourceTypes FOREIGN KEY (ResourceTypeID) REFERENCES ResourceTypes(ResourceTypeID); + +CREATE TABLE Invoices ( + InvoiceID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 10000 INCREMENT BY 1 NOT NULL, + TenantID NUMBER(10) NOT NULL, + ProjectID NUMBER(10) NOT NULL, + InvoiceNumber VARCHAR2(50) NOT NULL, + IssueDate DATE DEFAULT SYSDATE NOT NULL, + DueDate DATE NOT NULL, + TotalAmount NUMBER(18,2) NOT NULL, + TaxAmount NUMBER(18,2) DEFAULT 0 NOT NULL, + Status VARCHAR2(20) DEFAULT 'Draft' NOT NULL, + PaidDate DATE NULL +); + +ALTER TABLE Invoices ADD CONSTRAINT PK_Invoices PRIMARY KEY (InvoiceID); +ALTER TABLE Invoices ADD CONSTRAINT UQ_InvoiceNumber_Tenant UNIQUE (InvoiceNumber, TenantID); +ALTER TABLE Invoices ADD CONSTRAINT FK_Invoices_Tenants FOREIGN KEY (TenantID) REFERENCES Tenants(TenantID); +ALTER TABLE Invoices ADD CONSTRAINT FK_Invoices_Projects FOREIGN KEY (ProjectID) REFERENCES Projects(ProjectID); + +-- Foreign key with ON DELETE SET NULL +CREATE TABLE InvoiceLineItems ( + LineItemID NUMBER(15) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + InvoiceID NUMBER(10) NOT NULL, + TimeEntryID NUMBER(15) NULL, + Description NVARCHAR2(255) NOT NULL, + Quantity NUMBER(10,2) DEFAULT 1 NOT NULL, + UnitPrice NUMBER(18,2) NOT NULL, + LineTotal NUMBER(18,2) GENERATED ALWAYS AS (Quantity * UnitPrice) VIRTUAL +); + +ALTER TABLE InvoiceLineItems ADD CONSTRAINT PK_InvoiceLineItems PRIMARY KEY (LineItemID); +ALTER TABLE InvoiceLineItems ADD CONSTRAINT FK_InvoiceLineItems_Invoices FOREIGN KEY (InvoiceID) REFERENCES Invoices(InvoiceID) ON DELETE CASCADE; +ALTER TABLE InvoiceLineItems ADD CONSTRAINT FK_InvoiceLineItems_TimeEntries FOREIGN KEY (TimeEntryID) REFERENCES TimeEntries(TimeEntryID) ON DELETE SET NULL; + +-- ============================================= +-- 7. NOTIFICATIONS & AUDIT +-- ============================================= + +CREATE TABLE NotificationTypes ( + NotificationTypeID NUMBER(5) NOT NULL, + TypeName VARCHAR2(50) NOT NULL, + DefaultTemplate NVARCHAR2(500) NULL +); + +ALTER TABLE NotificationTypes ADD CONSTRAINT PK_NotificationTypes PRIMARY KEY (NotificationTypeID); +ALTER TABLE NotificationTypes ADD CONSTRAINT UQ_NotificationTypeName UNIQUE (TypeName); + +CREATE TABLE Notifications ( + NotificationID RAW(16) DEFAULT SYS_GUID() NOT NULL, + UserID NUMBER(10) NOT NULL, + NotificationTypeID NUMBER(5) NOT NULL, + Title NVARCHAR2(200) NOT NULL, + Message NCLOB NOT NULL, + IsRead CHAR(1) DEFAULT '0' NOT NULL, + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, + ReadAt TIMESTAMP NULL, + MetadataJSON CLOB NULL +); + +ALTER TABLE Notifications ADD CONSTRAINT PK_Notifications PRIMARY KEY (NotificationID); +ALTER TABLE Notifications ADD CONSTRAINT FK_Notifications_Users FOREIGN KEY (UserID) REFERENCES Users(UserID) ON DELETE CASCADE; +ALTER TABLE Notifications ADD CONSTRAINT FK_Notifications_NotificationTypes FOREIGN KEY (NotificationTypeID) REFERENCES NotificationTypes(NotificationTypeID); + +-- Audit log with all constraints via ALTER +CREATE TABLE AuditLog ( + AuditID NUMBER(15) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + TenantID NUMBER(10) NOT NULL, + UserID NUMBER(10) NULL, + TableName VARCHAR2(100) NOT NULL, + RecordID VARCHAR2(100) NOT NULL, + ActionType VARCHAR2(20) NOT NULL, + OldValueXML XMLTYPE NULL, + NewValueXML XMLTYPE NULL, + ChangedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, + IPAddress VARCHAR2(45) NULL +); + +ALTER TABLE AuditLog ADD CONSTRAINT PK_AuditLog PRIMARY KEY (AuditID); +ALTER TABLE AuditLog ADD CONSTRAINT FK_AuditLog_Tenants FOREIGN KEY (TenantID) REFERENCES Tenants(TenantID); +ALTER TABLE AuditLog ADD CONSTRAINT FK_AuditLog_Users FOREIGN KEY (UserID) REFERENCES Users(UserID); +ALTER TABLE AuditLog MODIFY UserID DEFAULT USER; + +-- ============================================= +-- 8. MILESTONES & DELIVERABLES +-- ============================================= + +CREATE TABLE Milestones ( + MilestoneID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + ProjectID NUMBER(10) NOT NULL, + MilestoneName NVARCHAR2(200) NOT NULL, + TargetDate DATE NOT NULL, + ActualCompletionDate DATE NULL, + Status VARCHAR2(20) DEFAULT 'Pending' NOT NULL, + Budget NUMBER(18,2) NULL +); + +ALTER TABLE Milestones ADD CONSTRAINT PK_Milestones PRIMARY KEY (MilestoneID); +ALTER TABLE Milestones ADD CONSTRAINT FK_Milestones_Projects FOREIGN KEY (ProjectID) REFERENCES Projects(ProjectID); +ALTER TABLE Milestones ADD CONSTRAINT UQ_Milestone_Project_Name UNIQUE (ProjectID, MilestoneName); + +CREATE TABLE Deliverables ( + DeliverableID NUMBER(10) GENERATED BY DEFAULT AS IDENTITY START WITH 1 INCREMENT BY 1 NOT NULL, + MilestoneID NUMBER(10) NOT NULL, + DeliverableName NVARCHAR2(200) NOT NULL, + Description NVARCHAR2(500) NULL, + ExpectedOutput NVARCHAR2(500) NOT NULL, + IsCompleted CHAR(1) DEFAULT '0' NOT NULL, + CompletedAt TIMESTAMP NULL +); + +ALTER TABLE Deliverables ADD CONSTRAINT PK_Deliverables PRIMARY KEY (DeliverableID); +ALTER TABLE Deliverables ADD CONSTRAINT FK_Deliverables_Milestones FOREIGN KEY (MilestoneID) REFERENCES Milestones(MilestoneID); +ALTER TABLE Deliverables ADD CONSTRAINT UQ_Deliverable_Milestone_Name UNIQUE (MilestoneID, DeliverableName); + +-- ============================================= +-- INDEXES for Performance Optimization +-- ============================================= + +-- Single column indexes +CREATE INDEX IX_Users_TenantID ON Users(TenantID); +CREATE INDEX IX_Users_RoleID ON Users(RoleID); +CREATE INDEX IX_Users_Email ON Users(Email); +CREATE INDEX IX_Users_Username ON Users(Username); + +CREATE INDEX IX_Projects_TenantID ON Projects(TenantID); +CREATE INDEX IX_Projects_DepartmentID ON Projects(DepartmentID); +CREATE INDEX IX_Projects_Status ON Projects(Status); +CREATE INDEX IX_Projects_StartDate ON Projects(StartDate); + +CREATE INDEX IX_Tasks_ProjectID ON Tasks(ProjectID); +CREATE INDEX IX_Tasks_AssignedToUserID ON Tasks(AssignedToUserID); +CREATE INDEX IX_Tasks_Status ON Tasks(Status); +CREATE INDEX IX_Tasks_DueDate ON Tasks(DueDate); + +CREATE INDEX IX_TimeEntries_UserID ON TimeEntries(UserID); +CREATE INDEX IX_TimeEntries_TaskID ON TimeEntries(TaskID); +CREATE INDEX IX_TimeEntries_EntryDate ON TimeEntries(EntryDate); +CREATE INDEX IX_TimeEntries_IsBilled ON TimeEntries(IsBilled); + +CREATE INDEX IX_ResourceAllocations_ResourceID ON ResourceAllocations(ResourceID); +CREATE INDEX IX_ResourceAllocations_TaskID ON ResourceAllocations(TaskID); +CREATE INDEX IX_ResourceAllocations_AllocationDate ON ResourceAllocations(AllocationDate); + +CREATE INDEX IX_Invoices_TenantID ON Invoices(TenantID); +CREATE INDEX IX_Invoices_ProjectID ON Invoices(ProjectID); +CREATE INDEX IX_Invoices_Status ON Invoices(Status); +CREATE INDEX IX_Invoices_DueDate ON Invoices(DueDate); + +CREATE INDEX IX_InvoiceLineItems_InvoiceID ON InvoiceLineItems(InvoiceID); +CREATE INDEX IX_InvoiceLineItems_TimeEntryID ON InvoiceLineItems(TimeEntryID); + +CREATE INDEX IX_Notifications_UserID ON Notifications(UserID); +CREATE INDEX IX_Notifications_IsRead ON Notifications(IsRead); +CREATE INDEX IX_Notifications_CreatedAt ON Notifications(CreatedAt); + +CREATE INDEX IX_AuditLog_TenantID ON AuditLog(TenantID); +CREATE INDEX IX_AuditLog_TableName ON AuditLog(TableName); +CREATE INDEX IX_AuditLog_ChangedAt ON AuditLog(ChangedAt); +CREATE INDEX IX_AuditLog_ActionType ON AuditLog(ActionType); + +-- Composite indexes for common query patterns (Oracle specific) +CREATE INDEX IX_Tasks_Project_Status ON Tasks(ProjectID, Status); +CREATE INDEX IX_TimeEntries_User_Date ON TimeEntries(UserID, EntryDate); +CREATE INDEX IX_ResourceAllocations_Resource_Date ON ResourceAllocations(ResourceID, AllocationDate); +CREATE INDEX IX_Invoices_Tenant_Status ON Invoices(TenantID, Status); +CREATE INDEX IX_Notifications_User_Read ON Notifications(UserID, IsRead, CreatedAt DESC); + +-- Bitmap indexes for low-cardinality columns (Oracle feature) +CREATE BITMAP INDEX IX_Tasks_Status_BMP ON Tasks(Status); +CREATE BITMAP INDEX IX_Projects_Status_BMP ON Projects(Status); +CREATE BITMAP INDEX IX_Invoices_Status_BMP ON Invoices(Status); +CREATE BITMAP INDEX IX_Users_IsLocked_BMP ON Users(IsLocked); + +-- Function-based index (Oracle specific) +CREATE INDEX IX_Users_Email_Upper ON Users(UPPER(Email)); +CREATE INDEX IX_Projects_Code_Upper ON Projects(UPPER(ProjectCode)); + +-- ============================================= +-- Comments for documentation (Oracle style) +-- ============================================= + +COMMENT ON TABLE Tenants IS 'Multi-tenant organizations using the platform'; +COMMENT ON TABLE Projects IS 'Projects belonging to specific tenants and departments'; +COMMENT ON TABLE Tasks IS 'Work items associated with projects'; +COMMENT ON TABLE TimeEntries IS 'Time logged by users against tasks'; +COMMENT ON TABLE Invoices IS 'Billing documents for projects and time entries'; +COMMENT ON COLUMN Users.PasswordHash IS 'SHA-256 hash of user password'; +COMMENT ON COLUMN Tasks.StoryPoints IS 'Agile estimation points for task complexity'; +COMMENT ON COLUMN ResourceAllocations.AllocationID IS 'Globally unique identifier using SYS_GUID'; + + + + +CREATE TABLE ORACLE_ALL_DATATYPES_TEST ( + -- Identity / numeric types + ID NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + NumberCol NUMBER(18,4) NOT NULL UNIQUE DEFAULT 12345.6789, + IntegerCol INTEGER NULL DEFAULT 100, + IntCol INT NOT NULL DEFAULT 200, + SmallIntCol SMALLINT NULL UNIQUE DEFAULT 50, + FloatCol FLOAT(20) NOT NULL DEFAULT 123.45, + BinaryFloatCol BINARY_FLOAT NULL DEFAULT 10.5, + BinaryDoubleCol BINARY_DOUBLE NOT NULL DEFAULT 99.999, + + -- Character types + CharCol CHAR(10) NOT NULL DEFAULT 'CHARVAL', + NCharCol NCHAR(20) NULL DEFAULT N'NCHARVAL', + VarChar2Col VARCHAR2(255) NOT NULL UNIQUE DEFAULT 'varchar2 text', + NVarChar2Col NVARCHAR2(200) NULL DEFAULT N'nvarchar2 text', + ClobCol CLOB NULL, + NClobCol NCLOB NULL, + + -- RAW / binary + RawCol RAW(100) NOT NULL , + + BlobCol BLOB NULL, + + -- Date & time + DateCol DATE NOT NULL DEFAULT SYSDATE, + TimestampCol TIMESTAMP(6) NULL DEFAULT SYSTIMESTAMP, + TimestampTZCol TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT SYSTIMESTAMP, + TimestampLTZCol TIMESTAMP(6) WITH LOCAL TIME ZONE NULL DEFAULT SYSTIMESTAMP, + IntervalYearMonthCol INTERVAL YEAR(4) TO MONTH DEFAULT INTERVAL '2-6' YEAR TO MONTH, + IntervalDaySecondCol INTERVAL DAY(3) TO SECOND(6) + DEFAULT INTERVAL '5 12:30:45.123456' DAY TO SECOND, + + -- XML + XmlTypeCol XMLTYPE NULL, + + -- Row identifier + RowIdCol ROWID NULL, + URowIdCol UROWID NULL, + + -- JSON (stored as CLOB/VARCHAR2 in many Oracle versions) + JsonCol CLOB NULL, + + + + -- Default expressions + CreatedAt TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL +); + + +CREATE TABLE all_oracle_types ( + id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + + -- Numeric types + col_number_int NUMBER(10) NOT NULL DEFAULT 1, + col_number_decimal NUMBER(10,2) NULL DEFAULT 99.99, + col_numeric NUMERIC(8,3) NOT NULL DEFAULT 123.456, + col_decimal DECIMAL(12,4) NULL DEFAULT 456.7890, + col_float FLOAT(10) NULL DEFAULT 1.23, + col_binary_float BINARY_FLOAT NOT NULL DEFAULT 3.14, + col_binary_double BINARY_DOUBLE NULL DEFAULT 6.28318, + + -- Character types + col_char CHAR(10) NOT NULL DEFAULT 'CHARVAL', + col_nchar NCHAR(10) NULL DEFAULT 'NCHARVAL', + + col_varchar2 VARCHAR2(255) NULL UNIQUE DEFAULT 'varchar2 value', + col_nvarchar2 NVARCHAR2(100) NOT NULL DEFAULT 'nvarchar2 value', + + col_clob CLOB NULL, + col_nclob NCLOB NULL, + + -- Raw / binary + col_raw RAW(16) NULL, + col_blob BLOB NULL, + + -- Date & time types + col_date DATE NOT NULL DEFAULT DATE '2024-01-01', + + col_timestamp TIMESTAMP(6) + NOT NULL DEFAULT CURRENT_TIMESTAMP, + + col_timestamp_tz TIMESTAMP(6) WITH TIME ZONE + NULL DEFAULT CURRENT_TIMESTAMP, + + col_timestamp_ltz TIMESTAMP(6) WITH LOCAL TIME ZONE + NULL, + + col_interval_ym INTERVAL YEAR(2) TO MONTH + NULL DEFAULT INTERVAL '1-2' YEAR TO MONTH, + + col_interval_ds INTERVAL DAY(2) TO SECOND(6) + NULL DEFAULT INTERVAL '3 12:30:45.123456' + DAY TO SECOND, + + -- XML + col_xml XMLTYPE NULL, + + -- JSON (Oracle 21c+ native JSON type) + col_json JSON NULL, + + -- Row identifier + col_urowid UROWID NULL, + + -- Some extra inline UNIQUE columns + col_unique_number NUMBER(5) UNIQUE DEFAULT 500, + col_unique_text VARCHAR2(50) UNIQUE NULL +); + +*/ \ No newline at end of file diff --git a/src/utils/import/postgresql-importer.ts b/src/utils/import/postgresql-importer.ts new file mode 100644 index 0000000..625e84e --- /dev/null +++ b/src/utils/import/postgresql-importer.ts @@ -0,0 +1,284 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { BaseSqlImporter, ExtractedStatments, ParsedDatabaase, ParsedField } from "./base-sql-importer"; +import { init, parse, format, validate, Statement } from '@guanmingchiu/sqlparser-ts'; +import { TableInsertType } from "@/lib/schemas/table-schema"; +import { FieldInsertType } from "@/lib/schemas/field-schema"; + +interface PostgreSQLType { + name: string; + values: string[] +} + +export class PostgreSqlImporter extends BaseSqlImporter { + + private enums: PostgreSQLType[] = []; + + public constructor(data_types: DataType[]) { + super(data_types); + this.dialect = DatabaseDialect.POSTGRES; + } + + public parseSql(sql: string) { + try { + + this.enums = []; + + const cleaned: string = this.cleanSql(sql); + + const { createPostgresTypesStatements, alterSequenceStatments } = this.extractStatments(cleaned); + if (createPostgresTypesStatements) + for (const statment of createPostgresTypesStatements) { + const astStatment: any = parse(statment, this.dialect as any)?.pop(); + if (astStatment?.CreateType) { + this.enums.push(this.astToEnum(astStatment.CreateType)); + } + } + + const parsedDatabaase: ParsedDatabaase = super.parseSql(sql); + + if (alterSequenceStatments) { + for (const statment of alterSequenceStatments) { + try { + this.processAlterSequenceStatements(statment, parsedDatabaase.tables); + } catch (error) { + parsedDatabaase.errors.push(error as Error); + } + } + } + + + return parsedDatabaase; + } catch (error) { + throw error; + } + } + + + protected processAlterSequenceStatements(statment: string, tables: TableInsertType[]) { + + const regex = + /ALTER\s+SEQUENCE\s+[\w"]+\.[\w"]+\s+OWNED\s+BY\s+("?[\w]+"?)\.("?[\w]+"?)\.("?[\w]+"?)/i; + + const match = statment.match(regex); + + if (!match) { + return; + } + + const schema = match[1].replace(/"/g, ''); + const tableName = match[2].replace(/"/g, ''); + const columnName = match[3].replace(/"/g, ''); + + + const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == tableName); + if (!table) { + throw Error(`table ${tableName} not found in : ${statment}`); + } + + const index = table.fields?.findIndex((field: FieldInsertType) => field.name == columnName) ?? -1; + if (index < 0) { + throw Error(`field ${columnName} not found in : ${statment}`); + } + + (table.fields as FieldInsertType[])[index].autoIncrement = true ; + + + + } + + protected astToField(ast: any, sequence: number): ParsedField { + const { field, fk_constraint } = super.astToField(ast, sequence); + + if (typeof ast.data_type === "object" && ast.data_type.Custom) { + const typeName = ast.data_type.Custom[0]?.[0]?.Identifier?.value.toLowerCase(); + // it's a serial type + if (typeName?.toLowerCase().includes("serial")) { + + field.autoIncrement = true; + } + else { + const postgreSqlType: PostgreSQLType | undefined = this.enums.find((postgreSqlType: PostgreSQLType) => postgreSqlType.name == typeName); + if (postgreSqlType && postgreSqlType.values.length > 0) { + try { + field.values = JSON.stringify(postgreSqlType.values); + } catch (error) { + console.error("failed to parse postgresql type values") + } + } + + } + } + + + return { field, fk_constraint }; + } + + protected processDefaultValue(ast: any, dataType: DataType): string | undefined { + + let defaultValue: string | undefined = super.processDefaultValue(ast, dataType); + + if (!defaultValue) { + if (ast.Function) { + if (ast.Function.name?.[0]?.Identifier?.value == "gen_random_uuid") { + return "random"; + } + } + } + + return defaultValue + } + + + protected processDataType(typeName: string): DataType | undefined { + let dataType: DataType | undefined = super.processDataType(typeName); + + if (!dataType) { + if (typeName?.toLowerCase().includes("serial")) { + // if it's a serial type , then get the base integer type (integer , smallint , bigint) + let baseType: string = typeName.toLowerCase() == "serial" ? "integer" : typeName.toLowerCase().replace("serial", "int"); + return super.processDataType(baseType); + } + else { + const isEnum: boolean = Boolean(this.enums.find((postgreSqlType: PostgreSQLType) => postgreSqlType.name == typeName)); + if (isEnum) { + return this.data_types.find((dataType: DataType) => dataType.name == "enum") + } + } + + } + return dataType + } + + private astToEnum(ast: any): PostgreSQLType { + + const values: string[] | undefined = ast.representation?.Enum?.labels?.map((label: any) => label.value); + + return { + name: ast.name?.[0]?.Identifier?.value, + values + } as PostgreSQLType; + } + + protected extractStatments(sql: string): ExtractedStatments { + + const createPostgresTypesStatements: string[] = []; + const alterSequenceStatments: string[] = []; + const { createIndexStatements, createTableStatements, alterTableStatements } = super.extractStatments(sql); + + // Split into individual statements + const statements = sql + .split('\n') + .map(s => s.trim()) + .filter(Boolean); + + for (const stmt of statements) { + const upper = stmt.toUpperCase(); + if (upper.startsWith('CREATE TYPE')) { + createPostgresTypesStatements.push(stmt); + } + if (upper.startsWith("ALTER SEQUENCE")) { + alterSequenceStatments.push(stmt); + } + } + + return { + createIndexStatements, + createTableStatements, + alterTableStatements, + createPostgresTypesStatements, + alterSequenceStatments + }; + } +} + + +/* + + +CREATE TYPE "users_user_type_enum" AS ENUM ( + 'individual', + 'agency', + 'developer', + 'admin', + 'employee' +); + +CREATE TYPE "users_provider_enum" AS ENUM ( + 'google.com', + 'facebook.com', + 'password', + 'anonymous' +); + +CREATE TABLE "users" ( + id INTEGER NOT NULL PRIMARY KEY, + full_name VARCHAR NOT NULL, + email VARCHAR NOT NULL, + picture_url VARCHAR NULL, + phone_number VARCHAR NULL, + password_hash VARCHAR NOT NULL, + user_type users_user_type_enum NOT NULL DEFAULT 'individual', + provider users_provider_enum NOT NULL DEFAULT 'password', + birthday TIMESTAMP(3) NULL, + gender BOOLEAN NULL, + created_at TIMESTAMPTZ (6) NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ (6) NULL, + is_email_verified BOOLEAN NOT NULL DEFAULT FALSE +); + +CREATE TABLE all_postgres_types ( + id BIGSERIAL PRIMARY KEY, + + -- Numeric types + col_smallint SMALLINT NOT NULL DEFAULT 1, + col_integer INTEGER NOT NULL UNIQUE DEFAULT 1000, + col_bigint BIGINT NULL DEFAULT 10000, + + col_decimal DECIMAL(10,2) NOT NULL DEFAULT 99.99, + col_numeric NUMERIC(8,3) NULL DEFAULT 123.456, + + col_real REAL NULL DEFAULT 1.23, + col_double DOUBLE PRECISION NOT NULL DEFAULT 2.3456, + + col_boolean BOOLEAN NOT NULL DEFAULT TRUE, + + -- Date & time types + col_date DATE NOT NULL DEFAULT DATE '2024-01-01', + col_timestamp TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + col_timestamptz TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + col_time TIME(6) NULL DEFAULT TIME '12:34:56.123456', + + -- String types + col_char CHAR(10) NOT NULL DEFAULT 'charval', + col_varchar VARCHAR(255) NULL UNIQUE DEFAULT 'varchar value', + col_text TEXT NULL DEFAULT 'some text', + + -- Binary + col_bytea BYTEA NULL, + + -- Enum (PostgreSQL requires type creation first) + col_enum TEXT NOT NULL DEFAULT 'A', + + -- JSON + col_json JSON NULL, + col_jsonb JSONB NULL, + + -- UUID + col_uuid UUID NOT NULL UNIQUE DEFAULT gen_random_uuid(), + + -- Array + col_text_array TEXT[] NULL DEFAULT ARRAY['a','b','c'], + + -- Range types + col_int_range INT4RANGE NULL, + col_ts_range TSRANGE NULL, + + -- XML + col_xml XML NULL, + + -- Some extra UNIQUE inline + col_unique_text TEXT UNIQUE +); + +*/ \ No newline at end of file diff --git a/src/utils/import/sqlite-importer.ts b/src/utils/import/sqlite-importer.ts new file mode 100644 index 0000000..61308af --- /dev/null +++ b/src/utils/import/sqlite-importer.ts @@ -0,0 +1,60 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { BaseSqlImporter } from "./base-sql-importer"; + +export class SqliteImporter extends BaseSqlImporter { + public constructor(data_types: DataType[]) { + super(data_types); + this.dialect = DatabaseDialect.SQLITE; + } +} + + + + +/* +CREATE TABLE "users" ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + username TEXT NOT NULL UNIQUE, + email TEXT NOT NULL UNIQUE, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE "projects" ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + name TEXT NOT NULL, + description TEXT NULL DEFAULT 'Hello world' +); + +CREATE TABLE "tasks" ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + project_id INTEGER NOT NULL, + title TEXT NOT NULL, + description TEXT NULL, + due_date DATETIME NULL, + priority TEXT NULL, + status TEXT NULL, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY ("project_id") REFERENCES "projects" ("id") ON DELETE CASCADE +); + +CREATE TABLE "comments" ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + task_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + comment_text TEXT NOT NULL, + created_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE, + FOREIGN KEY ("task_id") REFERENCES "tasks" ("id") ON DELETE CASCADE +); + +CREATE TABLE "task_assignments" ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + task_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + assigned_at DATETIME NULL DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY ("task_id") REFERENCES "tasks" ("id") ON DELETE CASCADE, + FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE +) +*/ \ No newline at end of file diff --git a/src/utils/migration.ts b/src/utils/migration.ts new file mode 100644 index 0000000..940034a --- /dev/null +++ b/src/utils/migration.ts @@ -0,0 +1,153 @@ +import { DatabaseType } from "@/lib/schemas/database-schema"; +import { FieldType } from "@/lib/schemas/field-schema"; +import { RelationshipType } from "@/lib/schemas/relationship-schema"; +import { TableType } from "@/lib/schemas/table-schema"; +import { decomposeManyToMany, getDefaultRelationshipName } from "./relationship"; +import _ from "lodash"; +import { DBDiffOperation } from "./database"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import { IndexType } from "@/lib/schemas/index-schema"; +import { FieldIndexType } from "@/lib/schemas/field_index-schema"; +import { DatabaseDialect } from "@/lib/database"; + + +export const prepareForMigration = (db: DatabaseType) => { + + let database = _.cloneDeep(db); + + database.tables = database.tables.map((table: any) => { + delete table.sequence; + table.fields = table.fields.map((field: any) => { + delete field.sequence; + delete field.note; + return field; + }) + return table; + }); + + database.relationships = database.relationships.map((relationship: RelationshipType) => { + + if (relationship.name) + return relationship; + + relationship.sourceTable = database.tables.find((table: TableType) => table.id == relationship.sourceTableId) as TableType; + relationship.targetTable = database.tables.find((table: TableType) => table.id == relationship.targetTableId) as TableType; + + relationship.sourceField = relationship.sourceTable.fields.find((field: FieldType) => field.id == relationship.sourceFieldId) as FieldType; + relationship.targetField = relationship.targetTable.fields.find((field: FieldType) => field.id == relationship.targetFieldId) as FieldType; + + relationship.name = getDefaultRelationshipName(relationship) + return relationship; + }); + + database = decomposeManyToMany(database); + + return database; +} + +// enrich a database operations is : +// - adding the type to the fields . +// - adding sourceField , targetField , sourceTable , targetTable to the relationships +export const optimizeOps = (operations: DBDiffOperation[], currentDatabase: DatabaseType, previousDatabase: DatabaseType, data_types: DataType[]): DBDiffOperation[] => { + let ops: DBDiffOperation[] = []; + + + + const schemaOperations = operations.filter((operation: DBDiffOperation) => (operation.type != "UPDATE_FIELD_INDICES") && !( + operation.type == "UPDATE_FIELD" && operation.changes.isPrimary !== undefined && Object.keys(operation.changes).length == 1 + )); + + + + for (let index = 0; index < schemaOperations.length; index++) { + + const operation: DBDiffOperation = _.cloneDeep(schemaOperations[index]); + + if (operation.type == "UPDATE_NUM_TABLES") + continue; + if (operation.type == "RENAME_DATABASE") + continue; + + + + if (operation.type == "CREATE_TABLE") { + operation.table.fields = Object.values(operation.table.fields).map((field: FieldType) => ({ + ...field, + type: data_types.find((type: DataType) => type.id == field.typeId) + })) as FieldType[]; + + operation.table.indices = Object.values(operation.table.indices).map((indice: IndexType) => ({ + ...indice, + fieldIndices: Object.values(indice.fieldIndices), + + })) + operation.table.indices = operation.table.indices.map((index: IndexType) => ({ + ...index, + fields: index.fieldIndices.map((fieldIndex: FieldIndexType) => operation.table.fields.find((field: FieldType) => field.id == fieldIndex.fieldId)) as FieldType[] + })) + } + + if (operation.type == "CREATE_RELATIONSHIP") { + + // try to get the sourceTable from the previous database + let sourceTable: TableType | undefined = previousDatabase.tables.find((table: TableType) => table.id == operation.relationship.sourceTableId); + if (!sourceTable) { + // if the source table is not found that mean it's a new table created in this migration + // so we need to get it from the currentDatabase + sourceTable = currentDatabase.tables.find((table: TableType) => table.id == operation.relationship.sourceTableId) as TableType; + } + + let sourceField: FieldType | undefined = sourceTable.fields.find((field: FieldType) => field.id == operation.relationship.sourceFieldId); + if (!sourceField) { + // if the source field is not found , then it could be a new field created in this new migration + // so what we need to do it is we need to get it from the current Database , + const currentSourceTable: TableType = currentDatabase.tables.find((table: TableType) => table.id == operation.relationship.sourceTableId) as TableType; + sourceField = currentSourceTable.fields.find((field: FieldType) => field.id == operation.relationship.sourceFieldId); + } + + // now we do the same thing for the target table and field . + let targetTable: TableType | undefined = previousDatabase.tables.find((table: TableType) => table.id == operation.relationship.targetTableId) as TableType; + // if not found , the target table culd be a new table created in this migration + if (!targetTable) { + targetTable = currentDatabase.tables.find((table: TableType) => table.id == operation.relationship.targetTableId) as TableType; + } + let targetField: FieldType | undefined = targetTable.fields.find((field: FieldType) => field.id == operation.relationship.targetFieldId); + if (!targetField) { + // it can be a new field , so we need to get it from the current migration . + const currentTargetTable: TableType = currentDatabase.tables.find((table: TableType) => table.id == operation.relationship.targetTableId) as TableType; + targetField = currentTargetTable.fields.find((field: FieldType) => field.id == operation.relationship.targetFieldId) as FieldType + } + operation.relationship.sourceTable = sourceTable; + operation.relationship.targetTable = targetTable; + + operation.relationship.sourceField = sourceField as FieldType; + operation.relationship.targetField = targetField as FieldType; + } + + ops.push(operation) + } + + ops = orderOperations(ops) + + return ops; +} + + +const orderOperations = (ops: DBDiffOperation[]): DBDiffOperation[] => { + const OPERATION_ORDER = [ + // Create + 'CREATE_TABLE', + 'CREATE_RELATIONSHIP', + ]; + return [...ops].sort( + (a, b) => + OPERATION_ORDER.indexOf(a.type) - OPERATION_ORDER.indexOf(b.type) + ); +} + + + + + + + diff --git a/src/utils/render/database/base-database-renderer.ts b/src/utils/render/database/base-database-renderer.ts new file mode 100644 index 0000000..3dfabd2 --- /dev/null +++ b/src/utils/render/database/base-database-renderer.ts @@ -0,0 +1,389 @@ +import { DatabaseDialect } from "@/lib/database"; +import { DataTypes, ForeignKeyActions, Modifiers, MYSQL_MAX_VAR_LENGTH, TimeDefaultValues } from "@/lib/field"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseType } from "@/lib/schemas/database-schema"; +import { FieldType } from "@/lib/schemas/field-schema"; +import { IndexType } from "@/lib/schemas/index-schema"; +import { Cardinality, RelationshipType } from "@/lib/schemas/relationship-schema"; +import { TableType } from "@/lib/schemas/table-schema"; +import { DBDiffOperation, mapDiffToDBDiffOperation, normalizeDatabase } from "@/utils/database"; +import { optimizeOps, prepareForMigration } from "@/utils/migration"; +import { compare } from "fast-json-patch"; +import { AST } from "node-sql-parser"; +import { Statement } from "pgsql-ast-parser"; +import { getPostgresEnumName } from "../render-uttils"; +import { emptyDb } from "@/lib/database"; + +export default abstract class BaseDatabaseRenderer { + + protected dialect: DatabaseDialect; + protected data_types: DataType[]; + protected schema?: DatabaseType | undefined; + protected parser: any; + protected readyPromise: Promise; + + public constructor(dialect: DatabaseDialect, data_types: DataType[]) { + this.dialect = dialect; + this.data_types = data_types; + + this.readyPromise = import("node-sql-parser").then((sqlParser) => { + this.parser = new sqlParser.Parser(); + }) + + } + + public getDialect(): DatabaseDialect { + return this.dialect; + } + + public async renderDDL(database: DatabaseType): Promise { + + const previousDatabase = emptyDb(database); + + // we prepare both databases by enriching them and removing some UI elements that can interfear with json fast path + const preparedCurrentDatabase = prepareForMigration(database); + const preparedPreviousDatabse = prepareForMigration(previousDatabase); + + // notmalize both just ignore array elements order diff + const normalizedPreviousDatabase = normalizeDatabase(preparedPreviousDatabse); + const normalizedCurrentDatabase = normalizeDatabase(preparedCurrentDatabase); + + // perform a comparison to extract the diff between the previous database and the current one . + const diff_json = compare(normalizedPreviousDatabase, normalizedCurrentDatabase); + // map the diff to DB Diff operations to facilate the rendering + // optimize the operations by enriching each operation + let operations: DBDiffOperation[] = mapDiffToDBDiffOperation(diff_json) + operations = optimizeOps(operations, preparedCurrentDatabase, preparedPreviousDatabse, this.data_types); + + // extract the ast based on the dialect + const ast: ASTStatment[] = this.operationsToAst(operations, database); + // render ast from sql + const sql = await this.astToSQL(ast); + + return sql; + } + + protected operationsToAst(operations: DBDiffOperation[], database?: DatabaseType): ASTStatment[] { + const ast: ASTStatment[] = []; + // we basiclly loop over all operations , and turn them into ast . + // some operation can return multiple statments . + // so for that we need to check our input if its one AST or an object AST + for (const operation of operations) { + const statmentAst = this.operationToAst(operation); + if (!statmentAst) + continue; + else if (Array.isArray(statmentAst)) + ast.push(...statmentAst); + else + ast.push(statmentAst); + } + return ast; + } + + protected operationToAst(operation: DBDiffOperation): ASTStatment | ASTStatment[] | null { + switch (operation.type) { + case "CREATE_TABLE": + return this.createTableAst( + operation.table + ); + + case "CREATE_RELATIONSHIP": + if (operation.relationship.cardinality == Cardinality.many_to_many) + break; + return this.createRelationshipAst( + operation.relationship, + ); + + } + return null; + } + + protected abstract astToSQL(ast: ASTStatment[]): Promise; + + protected createTableAst(table: TableType): ASTStatment[] | ASTStatment { + let indices_ast: ASTStatment[] = []; + // get primary keys and check if we hame more than one + const primaryKeys: FieldType[] = table.fields.filter((field: FieldType) => field.isPrimary); + const multiPrimaryKeys: boolean = primaryKeys.length > 1; + // check if we have multiple primary keys if so we need to create a contraint + const constraints: ASTStatment[] = multiPrimaryKeys ? [this.getPrimaryKeyContraint(primaryKeys)] : []; + // get field dification + const field_definitions = table.fields.map((field: FieldType) => this.getFieldDefinition(field, table, multiPrimaryKeys)) + // the base table ast contain only the field dification and the contraints , then child renderer turn it to ast + // check if the table have indices + if (table.indices && table.indices.length > 0) { + // if so loop over it indices and ignore the index with no columns since that will cause an SQl Syntax error . + // finally get the ast of the index and push it to the indices_ast + for (const index of table.indices) { + if (index.fieldIndices.length == 0) + continue; + indices_ast.push(this.createIndexAst( + table, + index + )) + } + } + + return { + field_definitions, + constraints, + indices_ast + } as any; + } + + + protected updateFieldAst(table: TableType, field: FieldType, changes: FieldType): ASTStatment | ASTStatment[] { + // get the previous type + let type = field.type; + + const ast: any = { + length: null, + scale: null, + dataType: null, + auto_increment: null, + } + // if there is changes in the type , max length , scale or precision or auto incrrement . + // in this case SQL Database treat this as a type changes + if (changes.typeId || changes.maxLength || changes.scale || changes.precision || changes.autoIncrement !== undefined || changes.values) { + // if the type changes , get the new type + if (changes.typeId) + type = changes.type; + + // get the new or the old type name + ast.dataType = (this.dialect == DatabaseDialect.POSTGRES && type.name == "enum") ? getPostgresEnumName(table, field) : type.name?.toLocaleUpperCase(); + // get the new or old type modifiers + const modifiers: string[] = type.modifiers ? JSON.parse(type.modifiers) : []; + // if the type support length as VARCHAR(length) and we either have an old max length , or new max length , then set it in the ast + if (modifiers.includes(Modifiers.LENGTH) && (changes.maxLength || field.maxLength)) { + if (changes.maxLength) + ast.length = changes.maxLength + else + ast.length = field.maxLength; + } + // if the field support precision and we either have a previous precision or the user add new one . + // then set the precision in the AST . + if (modifiers.includes(Modifiers.PRECISION) && (changes.precision || field.precision)) { + if (changes.precision) { + ast.length = changes.precision; + } else { + ast.length = field.precision; + } + if (modifiers.includes(Modifiers.SCALE) && !(changes.scale || field.scale)) { + // if the scale is not set , we have to set it as O + ast.scale = "0"; + } + } + // if the type support scale , and scale is set then add it to the ast + if (modifiers.includes(Modifiers.SCALE) && (changes.scale || field.scale)) { + if (changes.scale) { + ast.scale = changes.scale; + } else { + ast.scale = field.scale; + } + } + // okay if the field is auto increment in postgres we need to switch the type ro serial type . + if (modifiers.includes(Modifiers.AUTO_INCREMENT) && (field.autoIncrement || changes.autoIncrement) && this.dialect == DatabaseDialect.POSTGRES) { + if (changes.autoIncrement !== false) { + if (ast.dataType == "INTEGER") + ast.dataType = "SERIAL"; + else + ast.dataType = ast.dataType.replace("INT", "SERIAL"); + } + } + // if there changes in the values + if (modifiers.includes(Modifiers.VALUES) && changes.values && this.dialect != DatabaseDialect.POSTGRES) { + try { + ast.values = JSON.parse(changes.values); + } catch (error) { + ast.value = []; + } + } + } + return ast as AST; + } + + + + protected createRelationshipAst(relationship: RelationshipType): ASTStatment { + + let primaryKey: FieldType = relationship.sourceField; + let foreignKey: FieldType = relationship.targetField; + + let sourceTable: TableType = relationship.sourceTable; + let targetTable: TableType = relationship.targetTable; + + if (relationship.cardinality == Cardinality.many_to_one) { + primaryKey = relationship.targetField; + foreignKey = relationship.sourceField; + sourceTable = relationship.targetTable; + targetTable = relationship.sourceTable; + } + return { + primaryKey, + foreignKey, + sourceTable, + targetTable + } as any + } + + + + protected abstract createIndexAst(table: TableType, index: IndexType): ASTStatment; + + protected abstract getPrimaryKeyContraint(field: FieldType[], table?: TableType): ASTStatment; + + protected abstract startTransaction(): string; + + protected abstract commit(): string; + + + protected getFieldDefinition(field: FieldType, table: TableType, ignorePkContraint: boolean): ASTStatment { + // get the modifiers based on the field data type + const modifiers: string[] = field?.type?.modifiers ? JSON.parse(field?.type.modifiers) : []; + + const ast: any = { + length: null, + scale: null, + default_value: null, + dataType: null, + values: null, + default_value_type: null, + auto_increment: null, + primary_key: ignorePkContraint ? false : field.isPrimary, + modifiers: null + } + + + + // data types by the defaut the field data type name , except for Postgres types needs to be handled diffrenet + ast.dataType = field.type?.name?.toLocaleUpperCase(); + + // if the field support PRECISION & SCALE modifiers set the length to precision + if (modifiers.includes(Modifiers.PRECISION) && field.precision) { + ast.length = field.precision; + if (modifiers.includes(Modifiers.SCALE) && !field.scale) + ast.scale = "0"; + } + // if the field support sclae and sclae is set then set the scale + if (modifiers.includes(Modifiers.SCALE) && field.scale) + ast.scale = field.scale; + + // the field support dynamic length , set the length ast + // but in case the max length is not set, and the dielect (Mysql , MariaDb ) require a length , then set the default length + if (modifiers.includes(Modifiers.LENGTH) && field.maxLength) + ast.length = field.maxLength; + + else if ( + modifiers.includes(Modifiers.LENGTH) && + (field.type.dialect == DatabaseDialect.MYSQL || field.type.dialect == DatabaseDialect.MARIADB) && + field.type.name?.startsWith('var') && + !field.maxLength + ) + ast.length = MYSQL_MAX_VAR_LENGTH; + + // if the field is an enum type just parse the enum values + if (modifiers.includes(Modifiers.VALUES) && field.values) { + try { + ast.values = JSON.parse(field.values); + } catch (error) { + ast.value = []; + } + } + const default_value_defintition = this.processDefaultValue(field) as any + + if (default_value_defintition) { + const { default_value_type, default_value } = default_value_defintition; + ast.default_value_type = default_value_type; + ast.default_value = default_value; + + } + + // if the field support auto increment and if the field it is , then set aut increment ast to true . + // but if the dialect is Postgres , then we have to change the type from INTEGERS to SERIALS + if (modifiers.includes(Modifiers.AUTO_INCREMENT) && field.autoIncrement && field.type.dialect != DatabaseDialect.POSTGRES) { + ast.auto_increment = true + } else if (modifiers.includes(Modifiers.AUTO_INCREMENT) && field.autoIncrement && field.type.dialect == DatabaseDialect.POSTGRES) { + ast.auto_increment = true; + if (ast.dataType == "INTEGER") + ast.dataType = "SERIAL"; + else + ast.dataType = ast.dataType.replace("INT", "SERIAL"); + } else { + ast.auto_increment = false; + } + + ast.modifiers = modifiers; + return ast; + } + + protected processDefaultValue(field: FieldType): AST | null { + // if the field have a default value then we need to proccess it based on it type + if (field.defaultValue && field.defaultValue.trim().length > 0) { + + const ast: any = { + default_value_type: null, + default_value: null + } + + if ((field.type.type == DataTypes.INTEGER || field.type.type == DataTypes.NUMERIC) && !isNaN(Number(field.defaultValue))) { + ast.default_value_type = "number" + if (field.type.type == DataTypes.NUMERIC) + ast.default_value = parseFloat(field.defaultValue); + else + ast.default_value = parseInt(field.defaultValue); + } + else if (field.type.type == DataTypes.TEXT || field.type.type == DataTypes.ENUM) { + if (field.type.type == DataTypes.ENUM) { + const values = field.values ? JSON.parse(field.values) : []; + + if (field.type.name == "set") { + ast.default_value_type = "single_quote_string"; + ast.default_value = field.defaultValue; + + } + else if (values.includes(field.defaultValue)) { + ast.default_value_type = "single_quote_string"; + ast.default_value = field.defaultValue; + } + } + else { + ast.default_value_type = "single_quote_string"; + ast.default_value = field.defaultValue; + } + + } + // if we have a field of type time and the default value is Now , then the default value is the fucntion CURRENT_TIME or NOW() + else if (field.type.type == DataTypes.TIME && field.defaultValue == TimeDefaultValues.NOW) { + ast.default_value_type = "function"; + ast.default_value = "CURRENT_TIMESTAMP"; + } + + else if ((field.type.name == "uuid" || field.type.name == "uniqueidentifier") && field.defaultValue == "random") { + ast.default_value_type = "function"; + ast.default_value = "random"; + + } + else if (field.type.type == DataTypes.TIME) { + ast.default_value_type = "single_quote_string"; + ast.default_value = field.defaultValue; + } + // the field have a boolean value + else if (field.defaultValue == "true" || field.defaultValue == "false") { + ast.default_value_type = "bool" + ast.default_value = field.defaultValue == "true" ? true : false; + } + return ast; + } + return null; + } +} + +export interface DBRenderOutput { + schema: DatabaseType, + diff_json: any[], + sql: string; + operations: DBDiffOperation[]; +} + + +export type ASTStatment = AST | Statement | string | null \ No newline at end of file diff --git a/src/utils/render/database/base-sql-renderer.ts b/src/utils/render/database/base-sql-renderer.ts new file mode 100644 index 0000000..54c4d84 --- /dev/null +++ b/src/utils/render/database/base-sql-renderer.ts @@ -0,0 +1,306 @@ +import { DatabaseDialect, getDatabaseByDialect } from "@/lib/database"; +import BaseDatabaseRenderer, { ASTStatment } from "./base-database-renderer"; +import { AST } from "node-sql-parser"; +import { format } from "sql-formatter"; +import { TableType } from "@/lib/schemas/table-schema"; +import { FieldType } from "@/lib/schemas/field-schema"; +import { ForeignKeyActions, Modifiers, TimeDefaultValues } from "@/lib/field"; +import { Cardinality, RelationshipType } from "@/lib/schemas/relationship-schema"; +import { IndexType } from "@/lib/schemas/index-schema"; +import { DataType } from "@/lib/schemas/data-type-schema"; + + + +export abstract class BaseSQLRenderer extends BaseDatabaseRenderer { + + protected async astToSQL(ast: ASTStatment[]): Promise { + // in the base SQL Render we use node-sql-parser . + // by simly passing the AST and formating the code . + // other renderers can override this method to handle the parsing based on the dielact + await this.readyPromise ; + + let sql: string = this.parser.sqlify(ast as AST[], { + database: getDatabaseByDialect(this.dialect).name + }); + return format(sql, { language: 'sql' }); + } + + protected createTableAst(table: TableType): ASTStatment[] | ASTStatment { + // get the tale defintion from parent render that contain only the field defintion and primary keys contraints + // this definition is commun amount (Mysql , MariaDB , Sqlite) , for postgres we need to override it and handle enums + const { field_definitions, constraints, indices_ast } = super.createTableAst(table) as any + // wrape those defintion with create table AST + return [{ + keyword: "table", + type: "create", + table: [{ + table: table.name + }], + create_definitions: [...field_definitions, ...constraints] + }, ...indices_ast] as any + } + + + protected getFieldDefinition(field: FieldType, table: TableType, ignorePkContraint: boolean): AST { + // we get the base field definition from the parent renderer + const definition: any = super.getFieldDefinition(field, table, ignorePkContraint) + // Mysql , MariaDB ,Have some additional attributes such as charset collation , the enum values are inline unlike Postgres , Unsigned , and ZERO FILL + // also we need default value expression that it is compatible with node-sql-parser + let valuesExpr: any | null; + // if the definition extracted values os this field is an enum . + // and for that we generate the values expression that's compatible with out parser + if (definition.values && definition.values.length > 0) { + const values = definition.values.map((value: string) => ({ + type: "single_quote_string", + value + })); + + valuesExpr = { + parentheses: true, + type: "expr_list", + value: values + } + } + + const default_val = !definition.modifiers.includes(Modifiers.NO_DEFAULT) ? this.processDefaultValue(field) : undefined; + const unique: string | null = !definition.modifiers.includes(Modifiers.NO_UNIQUE) ? (field.unique ? "unique" : null) : null; + // return an AST statment for a field definition + return { + column: { + type: "column_ref", + column: { + expr: { + type: "default", value: field.name, + } + }, + }, + default_val, + unique, + auto_increment: definition.auto_increment ? "auto_increment" : undefined, + nullable: { + type: field.nullable ? "null" : "not null", + value: field.nullable ? "null" : "not null", + }, + definition: { + dataType: definition.dataType, + length: definition.length, + scale: definition.scale, + expr: valuesExpr + }, + primary_key: definition.primary_key ? "primary key" : null, + resource: "column" + } as any + } + + protected createRelationshipAst(relationship: RelationshipType): ASTStatment { + // get the foriegn key , primary key source table and target table from the parent renderer + const { primaryKey, foreignKey, sourceTable, targetTable } = super.createRelationshipAst(relationship) as any; + let on_action: any[] = []; + // get the foriegn key actions for on delete and on cascade + if (relationship.onDelete) { + const value: string | null = this.foreignKeyActionToAst(relationship.onDelete as ForeignKeyActions); + + if (value) + on_action.push({ + type: "on delete", + value: { + type: "origin", + value + } + }) + } + + if (relationship.onUpdate) { + const value: string | null = this.foreignKeyActionToAst(relationship.onUpdate as ForeignKeyActions); + if (value) + on_action.push({ + type: "on update", + value: { + type: "origin", + value + } + }) + } + // return create foriegn key contraint for Mysql Dialect + return { + type: "alter", + keyword: "table", + table: [ + { + + table: targetTable.name + } + ], + expr: [{ + action: "add", + create_definitions: { + constraint: relationship.name, + definition: [ + { + type: "column_ref", + table: null, + column: { + expr: { + type: "default", + value: foreignKey.name + } + }, + } + ], + constraint_type: "FOREIGN KEY", + keyword: "constraint", + resource: "constraint", + reference_definition: { + definition: [ + { + type: "column_ref", + table: null, + column: { + expr: { + type: "default", + value: primaryKey.name + } + }, + } + ], + table: [ + { + db: null, + table: sourceTable.name + } + ], + keyword: "references", + on_action + } + }, + + resource: "constraint", + type: "alter" + }] + } as any + } + + + + protected foreignKeyActionToAst(action: ForeignKeyActions): string | null { + switch (action) { + case ForeignKeyActions.CASCADE: + return "cascade"; + + case ForeignKeyActions.SET_NULL: + return "set null"; + + case ForeignKeyActions.RESTRICT: + return "restrict"; + + case ForeignKeyActions.SET_DEFAULT: + return "set default"; + } + return null; + } + + protected getPrimaryKeyContraint(primaryKeys: FieldType[]): AST { + // primary key contraint + return { + constraint_type: "primary key", + resource: "constraint", + definition: primaryKeys.map((field: FieldType) => ({ + column: field.name, + type: "column_ref" + })) + } as any + } + + protected createIndexAst(table: TableType, index: IndexType): AST { + // create index AST for Mysql Dielect + return { + index: index.name, + type: "create", + table: { table: table.name }, + keyword: "index", + on_kw: "on", + index_type: index.unique ? "unique" : null, + index_columns: index.fields.map((field: FieldType) => ({ + column: field.name, + type: "column_ref" + })) + } as AST + } + + protected processDefaultValue(field: FieldType): AST | null { + const definition = super.processDefaultValue(field) as any; + // if the field have a default value , then we generate an expression based on the type of the default value + if (definition && definition.default_value !== null) { + let default_val: any | null = null + if (definition.default_value_type == "string") + default_val = { + type: "default", + value: { + type: "single_quote_string", + value: field.defaultValue + } + } + else if (definition.default_value_type == "function" && field.defaultValue == TimeDefaultValues.NOW) + default_val = { + type: "default", + value: { + type: "function", + name: { + name: [ + { + type: "origin", + value: "CURRENT_TIMESTAMP" + } + ] + }, + over: null + } + } + else if (definition.default_value_type == "function" && field.defaultValue == "random") { + default_val = { + type: "default", + value: { + type: "function", + name: { + name: [ + { + type: "default", + value: this.dialect == DatabaseDialect.POSTGRES ? "gen_random_uuid" : "UUID" + } + ] + }, + args: { + type: "expr_list", + value: [] + }, + parentheses: this.dialect == DatabaseDialect.MARIADB + } + } + } + else { + default_val = { + type: "default", + value: { + type: definition.default_value_type, + value: definition.default_value + } + } + } + return default_val; + } + return null; + } + + + protected startTransaction(): string { + return "BEGIN TRANSACTION;" ; + } + + protected commit(): string { + return "COMMIT;" + } + + + + protected abstract getUsingAst(table: TableType, field: FieldType, dataType: DataType): AST | null; +} \ No newline at end of file diff --git a/src/utils/render/database/mariadb-renderer.ts b/src/utils/render/database/mariadb-renderer.ts new file mode 100644 index 0000000..fa2d185 --- /dev/null +++ b/src/utils/render/database/mariadb-renderer.ts @@ -0,0 +1,10 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import MysqlRenderer from "./mysql-renderer"; +import { DatabaseDialect } from "@/lib/database"; + +export default class MariaDbRenderer extends MysqlRenderer { + + public constructor(data_types: DataType[]) { + super( data_types , DatabaseDialect.MARIADB) + } +} \ No newline at end of file diff --git a/src/utils/render/database/mssql-database-renderer.ts b/src/utils/render/database/mssql-database-renderer.ts new file mode 100644 index 0000000..46567e7 --- /dev/null +++ b/src/utils/render/database/mssql-database-renderer.ts @@ -0,0 +1,203 @@ + +import { FieldType } from "@/lib/schemas/field-schema"; +import { TableType } from "@/lib/schemas/table-schema"; +import BaseDatabaseRenderer, { ASTStatment } from "./base-database-renderer"; +import { DEFAULT_LENGTH_PARAM, ForeignKeyActions, Modifiers } from "@/lib/field"; +import { IndexType } from "@/lib/schemas/index-schema"; +import { RelationshipType } from "@/lib/schemas/relationship-schema"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { format } from 'sql-formatter'; +import { AST } from "node-sql-parser"; + +export default class MSSqlRenderer extends BaseDatabaseRenderer { + + + public constructor(data_types: DataType[]) { + super(DatabaseDialect.MSSQL, data_types) + } + + protected async astToSQL(ast: ASTStatment[]): Promise { + let sql = ast.join("\n"); + sql = format(sql, { language: 'sql' }); + if (sql.length > 0) { + sql = `${this.startTransaction()} + +${sql} + +${this.commit()} +` + } + return sql; + } + + protected createTableAst(table: TableType): ASTStatment[] | ASTStatment { + const ast: any = super.createTableAst(table); + + let indexes: string = ast.indices_ast.filter((index: string) => index != null).join("\n") + + // get primary keys and check if we hame more than one + const primaryKeys: FieldType[] = table.fields.filter((field: FieldType) => field.isPrimary); + let constraints: ASTStatment = ""; + if (primaryKeys.length > 0) { + constraints = this.getPrimaryKeyContraint(primaryKeys, table) + } + return ` + CREATE TABLE ${table.name} ( + ${(ast as any).field_definitions.join(",\n")} + ${constraints ? ',\n' + constraints : ""} + ); + ${indexes} + ` ; + } + + + protected getFieldDefinition(field: FieldType, table: TableType, ignorePkContraint: boolean = false, dropDefaultValue: boolean = false): ASTStatment { + + const ast: any = super.getFieldDefinition(field, table, ignorePkContraint); + + let autoIncrement: string = ast.modifiers.includes(Modifiers.AUTO_INCREMENT) ? (ast.auto_increment ? "IDENTITY(1,1)" : "") : "" + + let nullable: string = "" + let unique: string = ""; + + if (!ast.primary_key) + nullable = (field.nullable !== undefined) ? (field.nullable ? "NULL" : "NOT NULL") : ""; + + let options: number[] | string = []; + + if (ast.length) + options.push(ast.length); + + else if (ast.modifiers.includes(Modifiers.LENGTH)) + options.push(DEFAULT_LENGTH_PARAM); + + if (ast.scale && ast.scale != "0") + options.push(ast.scale); + + options = options.length > 0 ? `(${options.join(",")})` : ""; + + let defaultValue: any = ""; + + if (ast.default_value !== undefined && ast.default_value !== null && !dropDefaultValue) { + defaultValue = `CONSTRAINT DF_${table.name}_${field.name} DEFAULT ${ast.default_value}`; + } + if (!ast.primary_key) { + unique = field.unique ? `CONSTRAINT UQ_${table.name}_${field.name} UNIQUE` : ""; + } + + const dataType = field.type.name == "uuid" ? "RAW(16)" : ast.dataType; + + return `${field.name} ${dataType}${options} ${autoIncrement} ${nullable} ${defaultValue} ${unique} `; + } + + protected processDefaultValue(field: FieldType): AST | null { + const ast: any = super.processDefaultValue(field); + + if (ast && ast.default_value_type) { + if (ast.default_value_type == "single_quote_string") { + ast.default_value = `'${ast.default_value}'` + } + else if (ast.default_value_type == "number" || ast.default_value_type == "bool") + ast.default_value = ast.default_value; + + else if (ast.default_value_type == "function") { + + if (ast.default_value == "CURRENT_TIMESTAMP") { + + switch (field.type.name?.toUpperCase()) { + case "DATE": + ast.default_value = "CAST(GETDATE() AS DATE)" + break; + case "DATETIME": + ast.default_value = "GETDATE()" + break; + case "SMALLDATETIME": + ast.default_value = "GETDATE()" + break; + case "DATETIME2": + ast.default_value = "SYSDATETIME()" + break; + case "DATETIMEOFFSET": + ast.default_value = "SYSDATETIMEOFFSET()" + break; + } + } else if (ast.default_value == "random") { + if (field.isPrimary) + ast.default_value = "NEWSEQUENTIALID()" + else + ast.default_value = "NEWID()" + } + + } + if ( ast.default_value_type == "bool") { + if (ast.default_value) { + ast.default_value = 1 ; + }else { + ast.default_value = 0 ; + } + } + + } + + return ast; + } + + protected createRelationshipAst(relationship: RelationshipType): ASTStatment { + const { primaryKey, foreignKey, sourceTable, targetTable } = super.createRelationshipAst(relationship) as any; + + const constraintName: string = relationship.name ? " CONSTRAINT " + relationship.name : ""; + + const onDeleteFKAction: string | null = this.foreignKeyActionToAst(relationship.onDelete as ForeignKeyActions); + const onUpdateFKAction: string | null = this.foreignKeyActionToAst(relationship.onUpdate as ForeignKeyActions); + + const onDeleteAction: string = onDeleteFKAction ? `ON DELETE ${onDeleteFKAction}` : "" + const onUpdateAction: string = onUpdateFKAction ? `ON UPDATE ${onUpdateFKAction}` : "" + + const FKActions: string = [onDeleteAction, onUpdateAction].join(" "); + + return ` + ALTER TABLE ${targetTable.name} + ADD ${constraintName} FOREIGN KEY (${foreignKey.name}) + REFERENCES ${sourceTable.name}(${primaryKey.name}) ${FKActions}; + ` + } + + protected foreignKeyActionToAst(action: ForeignKeyActions): string | null { + switch (action) { + case ForeignKeyActions.CASCADE: + return "CASCADE"; + + case ForeignKeyActions.SET_NULL: + return "SET NULL"; + case ForeignKeyActions.SET_DEFAULT: + return "SET DEFAULT"; + } + return null; + } + + protected createIndexAst(table: TableType, index: IndexType): ASTStatment { + const unique: string = index.unique ? " UNIQUE" : ""; + + let columns: string[] | string = index.fields.map((field: FieldType) => field.name); + if (columns.length == 0) + return null; + columns = `(${columns.join(",")})` + return `CREATE${unique} INDEX ${index.name} ON ${table.name} ${columns} ;` + + } + + protected getPrimaryKeyContraint(fields: FieldType[], table?: TableType): ASTStatment { + const pks: string[] = fields.map((field: FieldType) => field.name); + return `CONSTRAINT PK_${table?.name} PRIMARY KEY (${pks.join(",")})` + } + + protected startTransaction(): string { + return `BEGIN TRANSACTION;` + } + protected commit(): string { + return "COMMIT;" + } + + +} \ No newline at end of file diff --git a/src/utils/render/database/mysql-renderer.ts b/src/utils/render/database/mysql-renderer.ts new file mode 100644 index 0000000..66dab94 --- /dev/null +++ b/src/utils/render/database/mysql-renderer.ts @@ -0,0 +1,91 @@ +import { FieldType } from "@/lib/schemas/field-schema"; +import { AST } from "node-sql-parser"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { fixCharsetPlacement } from "../render-uttils"; +import { format } from 'sql-formatter'; +import { Modifiers } from "@/lib/field"; +import { TableType } from "@/lib/schemas/table-schema"; +import { BaseSQLRenderer } from "./base-sql-renderer"; +import { IndexType } from "@/lib/schemas/index-schema"; + + +export default class MysqlRenderer extends BaseSQLRenderer { + + public constructor(data_types: DataType[], dialect: DatabaseDialect = DatabaseDialect.MYSQL) { + super(dialect, data_types) + } + protected async astToSQL(ast: AST[]): Promise { + // for Mysql , MariaDB , we use node-sql-parser to turn AST to SQL , + // the package have a bug which is CHARSET and COLLATION missplacementts + // so we patch it using fixCharsetPlacement function + // and finally we format the code + try { + let sql: string = await super.astToSQL(ast); + sql = fixCharsetPlacement(format(sql, { language: "sql" })); + sql = format(sql, { language: 'sql' }); + + if (sql.length > 0) { + sql = `${this.startTransaction()} + +${sql}; + +${this.commit()} +` + } + return sql; + } catch (error) { + throw error; + } + + } + + protected getFieldDefinition(field: FieldType, table: TableType, ignorePkContraint: boolean): AST { + // get the modifiers based on the field data type + const modifiers: string[] = field?.type.modifiers ? JSON.parse(field?.type.modifiers) : []; + + // we get the base field definition from the parent renderer + const definition: any = super.getFieldDefinition(field, table, ignorePkContraint) + // Mysql , MariaDB ,Have some additional attributes such as charset collation , the enum values are inline unlike Postgres , Unsigned , and ZERO FILL + // also we need default value expression that it is compatible with node-sql-parser + let suffix: string[] = []; + + // check if the field support ZEROFILL and if it set , and the same thing for unsigned + if (modifiers.includes(Modifiers.ZEROFILL) && field.zeroFill) { + suffix.push(Modifiers.ZEROFILL.toUpperCase()); + } + if (modifiers.includes(Modifiers.UNSIGNED) && field.unsigned) { + suffix.push(Modifiers.UNSIGNED.toUpperCase()); + } + // if it support charset and charset is set , then generate it expression + if (modifiers.includes(Modifiers.CHARSET) && field.charset) + + definition.character_set = { + type: "CHARACTER SET", + value: { + type: "default", + value: field.charset + } + } + // if it support collate and collate is set , then generate it expression + if (modifiers.includes(Modifiers.COLLATE) && field.collate) + + definition.collate = { + keyword: "collate", + type: "collate", + collate: { + name: field.collate, + } + } + + if (suffix.length > 0) { + definition.definition.suffix = suffix + } + return definition; + + } + + protected getUsingAst(table: TableType, field: FieldType, dataType: DataType): AST | null { + return null; + } +} \ No newline at end of file diff --git a/src/utils/render/database/oracle-renderer.ts b/src/utils/render/database/oracle-renderer.ts new file mode 100644 index 0000000..88ac0b4 --- /dev/null +++ b/src/utils/render/database/oracle-renderer.ts @@ -0,0 +1,196 @@ + +import { FieldType } from "@/lib/schemas/field-schema"; +import { TableType } from "@/lib/schemas/table-schema"; +import { AST } from "node-sql-parser"; +import BaseDatabaseRenderer, { ASTStatment } from "./base-database-renderer"; +import { DEFAULT_LENGTH_PARAM, ForeignKeyActions, Modifiers } from "@/lib/field"; +import { IndexType } from "@/lib/schemas/index-schema"; +import { RelationshipType } from "@/lib/schemas/relationship-schema"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { format } from 'sql-formatter'; + +export default class OracleRenderer extends BaseDatabaseRenderer { + + + public constructor(data_types: DataType[]) { + super(DatabaseDialect.ORACLE, data_types) + } + + protected async astToSQL(ast: ASTStatment[]): Promise { + let sql = ast.join("\n"); + sql = format(sql, { language: 'sql' }); + return sql; + } + + + protected createTableAst(table: TableType): ASTStatment[] | ASTStatment { + const ast: any = super.createTableAst(table); + let pk_constraint: string = ast.constraints?.pop(); + if (pk_constraint) + pk_constraint = "," + pk_constraint + else + pk_constraint = ""; + let indexes: string = ast.indices_ast.filter((index: string) => index != null).join("\n") + return ` + CREATE TABLE ${table.name} ( + ${(ast as any).field_definitions.join(",\n")} + ${pk_constraint} + ); + ${indexes} + ` ; + } + + protected getFieldDefinition(field: FieldType, table: TableType, ignorePkContraint: boolean = false, dropDefaultValue: boolean = false): ASTStatment { + + const ast: any = super.getFieldDefinition(field, table, ignorePkContraint); + + let primaryKey: string = ast.primary_key ? "PRIMARY KEY" : ""; + let autoIncrement: string = ast.modifiers.includes(Modifiers.AUTO_INCREMENT) ? (ast.auto_increment ? "GENERATED BY DEFAULT AS IDENTITY" : "") : "" + + let nullable: string = "" + let unique: string = ""; + + if (!ast.primary_key) + nullable = (field.nullable !== undefined) ? (field.nullable ? "NULL" : "NOT NULL") : ""; + + if (!ast.primary_key) + unique = field.unique ? "UNIQUE" : ""; + + let options: number[] | string = []; + + if (ast.length) + options.push(ast.length); + + else if (ast.modifiers.includes(Modifiers.LENGTH)) + options.push(DEFAULT_LENGTH_PARAM); + + if (ast.scale && ast.scale != "0") + options.push(ast.scale); + + options = options.length > 0 ? `(${options.join(",")})` : ""; + + let defaultValue: any = ""; + + if (ast.default_value !== undefined && ast.default_value !== null) { + defaultValue = "DEFAULT " + ast.default_value + } + if (dropDefaultValue) { + defaultValue = "DEFAULT NULL" + } + + let dataType = ast.dataType; + if (dataType === "TIMESTAMP WITH LOCAL TIME ZONE" && options) { + dataType = `TIMESTAMP${options} WITH LOCAL TIME ZONE` + } + else if (dataType === "TIMESTAMP WITH TIME ZONE" && options) { + dataType = `TIMESTAMP${options} WITH TIME ZONE` + } + else if (dataType === "INTERVAL DAY TO SECOND" && options) { + dataType = `INTERVAL DAY${options} TO SECOND` + } + else if (dataType === "INTERVAL YEAR TO MONTH" && options) { + dataType = `INTERVAL YEAR${options} TO MONTH` + + } + + else + dataType = dataType + options + + + //const dataType = field.type.name == "uuid" ? "RAW(16)" : ast.dataType; + + return `${field.name} ${dataType} ${defaultValue} ${nullable} ${unique} ${autoIncrement} ${primaryKey}`; + } + protected processDefaultValue(field: FieldType): AST | null { + + const ast: any = super.processDefaultValue(field); + + if (ast && ast.default_value !== undefined && ast.default_value !== null) { + + + if (ast.default_value_type == "single_quote_string") { + ast.default_value = `'${ast.default_value}'` + } + else if (ast.default_value_type == "number" || ast.default_value_type == "bool") + ast.default_value = ast.default_value; + + else if (ast.default_value_type == "function") { + + if (ast.default_value == "CURRENT_TIMESTAMP") { + + switch (field.type.name?.toUpperCase()) { + case "DATE": + ast.default_value = "SYSDATE" + break; + case "TIMESTAMP": + ast.default_value = "CURRENT_TIMESTAMP" + break; + case "TIMESTAMP WITH TIME ZONE": + ast.default_value = "SYSTIMESTAMP" + break; + case "TIMESTAMP WITH LOCAL TIME ZONE": + ast.default_value = "SYSTIMESTAMP" + break; + } + } else if (ast.default_value == "random") { + ast.default_value = "SYS_GUID()" + } + } + } + return ast; + } + + protected createIndexAst(table: TableType, index: IndexType): ASTStatment { + const unique: string = index.unique ? " UNIQUE" : ""; + + let columns: string[] | string = index.fields.map((field: FieldType) => field.name); + if (columns.length == 0) + return null; + columns = `(${columns.join(",")})` + return `CREATE${unique} INDEX ${index.name} ON ${table.name} ${columns} ;` + + } + + protected createRelationshipAst(relationship: RelationshipType): ASTStatment { + const { primaryKey, foreignKey, sourceTable, targetTable } = super.createRelationshipAst(relationship) as any; + + const constraintName: string = relationship.name ? " CONSTRAINT " + relationship.name : ""; + + const FKAction: string | null = this.foreignKeyActionToAst(relationship.onDelete as ForeignKeyActions); + const onDeleteAction: string = FKAction ? `ON DELETE ${FKAction}` : "" + + return ` + ALTER TABLE ${targetTable.name} + ADD ${constraintName} FOREIGN KEY (${foreignKey.name}) + REFERENCES ${sourceTable.name}(${primaryKey.name}) ${onDeleteAction}; + ` + } + + + protected foreignKeyActionToAst(action: ForeignKeyActions): string | null { + switch (action) { + case ForeignKeyActions.CASCADE: + return "CASCADE"; + + case ForeignKeyActions.SET_NULL: + return "SET NULL"; + + } + return null; + } + + protected getPrimaryKeyContraint(fields: FieldType[]): ASTStatment { + //throw new Error("Method not implemented."); + const pks: string[] = fields.map((field: FieldType) => field.name); + return ` + PRIMARY KEY (${pks.join(",")}) + ` + } + protected startTransaction(): string { + throw new Error("Method not implemented."); + } + protected commit(): string { + throw new Error("Method not implemented."); + } +} \ No newline at end of file diff --git a/src/utils/render/database/postgresql-renderer.ts b/src/utils/render/database/postgresql-renderer.ts new file mode 100644 index 0000000..4e29bff --- /dev/null +++ b/src/utils/render/database/postgresql-renderer.ts @@ -0,0 +1,157 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect, getDatabaseByDialect } from "@/lib/database"; +import { FieldType } from "@/lib/schemas/field-schema"; +import { TableType } from "@/lib/schemas/table-schema"; +import { BaseSQLRenderer } from "./base-sql-renderer"; +import { AST } from "node-sql-parser"; +import { getPostgresEnumName } from "../render-uttils"; +import { Cardinality, RelationshipType } from "@/lib/schemas/relationship-schema"; +import { IndexType } from "@/lib/schemas/index-schema"; +import { Statement, toSql } from "pgsql-ast-parser"; +import { ASTStatment } from "./base-database-renderer"; +import { format } from "sql-formatter"; +import { DBDiffOperation } from "@/utils/database"; +import { DataTypes } from "@/lib/field"; + + +export default class PostgresqlRenderer extends BaseSQLRenderer { + + public constructor(data_types: DataType[]) { + super(DatabaseDialect.POSTGRES, data_types) + } + + protected async astToSQL(ast: ASTStatment[]): Promise { + // postgres renderer is different , we use a different parser pgsql-ast-parser for index , enum renaming . + // those kind of operations return Statment not AST . + // so the we pass AST to the default parser and Statment to Postgres parser + + await this.readyPromise ; + let sql: string[] = []; + + for (const statment of ast) { + if ((statment as Statement)?.type == "alter index" || (statment as Statement)?.type == "alter enum") { + // index renaming + sql.push(toSql.statement(statment as Statement) + ";"); + } + else { + const statment_sql = this.parser.sqlify(statment as AST, { + database: getDatabaseByDialect(this.dialect).name + }); + sql.push(statment_sql + ";"); + } + } + + if (sql.length > 0) { + sql = [this.startTransaction( ) , ...sql , this.commit()] + } + return format(sql.join(""), { language: 'postgresql' }); + } + + + protected createTableAst(table: TableType): AST[] | AST { + // the only difference in create table statment in postgres is we need to get declare all enums before creating the table + const definition: AST[] = super.createTableAst(table) as any + // so we need an enum ast + const enumsAst: AST[] = []; + // get fields to type enum + let postgresEnums: FieldType[] = table.fields.filter((field: FieldType) => field.type?.name == "enum"); + if (postgresEnums.length > 0) { + // loop over them and intiat them one by one + for (const postgresEnum of postgresEnums) { + (postgresEnum as any).table = table; + enumsAst.push(this.createEnumAst(postgresEnum)); + } + } + definition.splice(0, 0, ...enumsAst); + return definition; + } + + + protected getFieldDefinition(field: FieldType, table: TableType, ignorePkContraint: boolean): AST { + // we get the base field definition from the parent renderer + const definition: any = super.getFieldDefinition(field, table, ignorePkContraint); + + // since postrges uses the serial data types , then there is not need for auto incrmenet attribute + definition.auto_increment = undefined; + // postgres handle enums diffrently , we need to create the enum first then reference to it in the column line + if (definition.definition.dataType == "ENUM") { + definition.definition.dataType = getPostgresEnumName(table, field); + definition.definition.expr = undefined; + } + return definition; + } + + + + private createEnumAst(field: FieldType): AST { + // get the enum values , and cast it into an array + const jsonValues = field.values ? JSON.parse(field.values) : []; + // return the ast of creating a table + return { + as: "as", + type: "create", + resource: "enum", + name: { + schema: null, + name: `${(field as any).table.name}_${field.name.toLowerCase()}_enum` + }, + keyword: "type", + create_definitions: { + parentheses: true, + type: "expr_list", + value: jsonValues.map((value: string) => ({ + type: "single_quote_string", + value + })) + } + } as any + } + + protected getUsingAst(table: TableType, field: FieldType, newDataType: DataType): AST | null { + + const oldType: DataTypes = field.type.type as DataTypes; + const newType: DataTypes = newDataType.type as DataTypes; + + if (oldType === newType && oldType != DataTypes.ENUM) return null; + + if ( + (oldType === DataTypes.INTEGER && newType === DataTypes.NUMERIC) || + (oldType === DataTypes.NUMERIC && newType === DataTypes.INTEGER) + ) return null; + + + let dataType = newDataType.name?.toUpperCase(); + + if (newDataType.name == "enum") + dataType = "TEXT::" + getPostgresEnumName(table, field); + else if (newDataType.name != "text") + dataType = "TEXT::" + newDataType.name?.toUpperCase(); + + return { + as: null, + symbol: "::", + target: [ + { + dataType + } + ], + type: "cast", + keyword: "cast", + expr: { + type: "column_ref", + table: null, + column: { + expr: { + type: "default", + value: field.name + } + }, + collate: null + } + } as any; + } + + protected startTransaction(): string { + return "BEGIN;" ; + } +} diff --git a/src/utils/render/database/sqlite-database-renderer.ts b/src/utils/render/database/sqlite-database-renderer.ts new file mode 100644 index 0000000..f9982b3 --- /dev/null +++ b/src/utils/render/database/sqlite-database-renderer.ts @@ -0,0 +1,110 @@ +import { DataType } from "@/lib/schemas/data-type-schema"; +import { DatabaseDialect } from "@/lib/database"; +import { AST } from "node-sql-parser"; +import { fixSQLiteColumnOrder } from "../render-uttils"; +import { format } from 'sql-formatter'; +import { RelationshipType } from "@/lib/schemas/relationship-schema"; +import { ASTStatment } from "./base-database-renderer"; +import { BaseSQLRenderer } from "./base-sql-renderer"; +import { FieldType } from "@/lib/schemas/field-schema"; +import { TableType } from "@/lib/schemas/table-schema"; +import { DBDiffOperation } from "@/utils/database"; +import { RenderableTable, SortableTable, toRenderableTable, toSortableTable } from "@/lib/table"; +import { DatabaseType } from "@/lib/schemas/database-schema"; +import { orderTables } from "@/utils/tables"; + +export default class SqliteRenderer extends BaseSQLRenderer { + + public constructor(data_types: DataType[]) { + super(DatabaseDialect.SQLITE, data_types) + } + + protected async astToSQL(ast: AST[]): Promise { + try { + let sql: string = await super.astToSQL(ast); + + sql = fixSQLiteColumnOrder(format(sql, { language: "sql" })); + sql = format(sql, { language: 'sql' }); + + if (sql.length > 0) { + sql = `${this.startTransaction()} + +${sql}; + +${this.commit()} +` + } + return sql; + } catch (error) { + throw error; + } + } + + protected operationsToAst(operations: DBDiffOperation[], database?: DatabaseType): ASTStatment[] { + + const ast: ASTStatment[] = []; + + let sortedTables: TableType[] | RenderableTable = operations.filter((operation: DBDiffOperation) => operation.type == "CREATE_TABLE").map((operation: DBDiffOperation) => (operation as any).table) + + if (database) { + let renderableTables: RenderableTable[] = sortedTables.map((table: TableType) => toRenderableTable(table, database)); + let sortableTables: SortableTable[] = renderableTables.map((table: RenderableTable) => toSortableTable(table)); + + const sortedTablesIds: string[] = orderTables(sortableTables); + + sortedTables = sortedTablesIds.map((id: string) => + renderableTables.find((table: TableType) => table.id == id) as TableType + ); + } + + const relationshipOperations: DBDiffOperation[] = operations.filter((operation: DBDiffOperation) => operation.type == "CREATE_RELATIONSHIP"); + + // we basiclly loop over all operations , and turn them into ast . + // some operation can return multiple statments . + // so for that we need to check our input if its one AST or an object AST + for (const table of sortedTables) { + const statmentAst = this.createTableAst(table); + + if (!statmentAst) + continue; + + + if ((table as RenderableTable).foreignRelationships?.length > 0) { + const relationshipsAst: ASTStatment[] = (table as RenderableTable).foreignRelationships.map((relationship: RelationshipType) => { + const operation: DBDiffOperation = relationshipOperations.find((operation: DBDiffOperation) => (operation as any).relationship?.id == relationship.id) as DBDiffOperation; + return this.createRelationshipAst((operation as any).relationship) + }) + + if (Array.isArray(statmentAst)) { + + const index = statmentAst.findIndex((statment: any) => statment.type == "create" && statment.keyword == "table"); + + if (index >= 0) { + (statmentAst[index] as any).create_definitions.push(...relationshipsAst) + } + } + } + if (Array.isArray(statmentAst)) + ast.push(...statmentAst); + else + ast.push(statmentAst); + } + return ast; + } + + protected createRelationshipAst(relationship: RelationshipType): ASTStatment { + const relationshipAst: any = super.createRelationshipAst(relationship) as any; + return relationshipAst.expr[0].create_definitions; + } + + protected getUsingAst(table: TableType, field: FieldType, dataType: DataType): AST | null { + throw new Error("Method not implemented."); + } + protected dropPrimaryKeyConstraintExpr(table: TableType): ASTStatment { + throw new Error("Method not implemented."); + } + protected createPrimaryKeyConstraintExpr(table: TableType, fields: FieldType[]): ASTStatment { + throw new Error("Method not implemented."); + } + +} \ No newline at end of file diff --git a/src/utils/render/parsers/database_to_ast.ts b/src/utils/render/parsers/database_to_ast.ts deleted file mode 100644 index 35520d4..0000000 --- a/src/utils/render/parsers/database_to_ast.ts +++ /dev/null @@ -1,395 +0,0 @@ - - -import { DatabaseDialect } from "@/lib/database"; -import { DataTypes, ForeignKeyActions, Modifiers, MYSQL_MAX_VAR_LENGTH, TimeDefaultValues } from "@/lib/field"; -import { DataType } from "@/lib/schemas/data-type-schema"; -import { DatabaseType } from "@/lib/schemas/database-schema"; -import { FieldType } from "@/lib/schemas/field-schema"; -import { FieldIndexType } from "@/lib/schemas/field_index-schema"; -import { IndexType } from "@/lib/schemas/index-schema"; -import { Cardinality, RelationshipType } from "@/lib/schemas/relationship-schema"; -import { TableType } from "@/lib/schemas/table-schema"; -import { RenderableTable, SortableTable, toRenderableTable, toSortableTable } from "@/lib/table"; -import { getForeignRelationships } from "@/utils/relationship"; -import { orderTables } from "@/utils/tables"; -import _ from "lodash" ; - -export const DatabaseToAst = (db: DatabaseType, data_types: DataType[]) => { - let dbAst: any = []; - if (!data_types || data_types.length == 0) - return dbAst; - const database = _.cloneDeep(db) ; - let renderableTables: RenderableTable[] = database.tables.map((table: TableType) => toRenderableTable(table, database)); - let sortableTables: SortableTable[] = renderableTables.map((table: RenderableTable) => toSortableTable(table)); - - try { - const sortedTablesIds: string[] = orderTables(sortableTables); - - const sortedTables: TableType[] = sortedTablesIds.map((id: string) => - renderableTables.find((table: TableType) => table.id == id) as TableType - ); - for (const table of sortedTables) { - let postgresEnums: FieldType[]; - if (database.dialect == DatabaseDialect.POSTGRES) { - postgresEnums = table.fields.filter((field: FieldType) => field.type?.name == "enum"); - if (postgresEnums.length > 0) { - for (const postgresEnum of postgresEnums) { - (postgresEnum as any).table = table; - dbAst.push(PotgresEnumToAst(postgresEnum)); - } - } - } - - dbAst.push(TableToAst(table, data_types, database.dialect == DatabaseDialect.POSTGRES)); - - if (table.indices && table.indices.length > 0) - for (const index of table.indices) - if (index.fieldIndices?.length > 0) - dbAst.push(IndexToAst({ - ...index, - fields: index.fieldIndices.map((fieldIndex: FieldIndexType) => - table.fields.find((field: FieldType) => field.id == fieldIndex.fieldId) - ) as FieldType[], - }, table)); - }; - } catch (error) { - throw error; - } - return dbAst; -} - - -export const TableToAst = (table: TableType, data_types: DataType[], isPostgresDialect: boolean = false) => { - - const primaryKeys: FieldType[] = table.fields.filter((field: FieldType) => field.isPrimary); - const multiPrimaryKeys: boolean = primaryKeys.length > 1; - - const primaryKeysConstraints: any[] | undefined = multiPrimaryKeys ? [{ - constraint_type: "primary key", - resource: "constraint", - definition: primaryKeys.map((field: FieldType) => ({ - column: field.name, - type: "column_ref" - })) - }] : []; - - let foreignRelationships = getForeignRelationships(table); - const foreignKeysConstraints = foreignRelationships.map((relationship: RelationshipType) => relationshipToAst(relationship)); - const constraints: any[] = [ - ...primaryKeysConstraints, - ...foreignKeysConstraints - ]; - - const filed_definitions = table.fields.filter((field: FieldType) => field.type).map((field: FieldType) => { - const isPostgresEnum: boolean = isPostgresDialect && field.type.name == "enum"; - - return FieldToAst({ - ...field, - type: !(isPostgresEnum) ? - data_types.find((dataType: DataType) => dataType.id == field.typeId) as DataType : - { name: `${table.name}_${field.name.toLowerCase()}_enum` } as DataType, - }, multiPrimaryKeys, !isPostgresEnum) - }) - - return { - keyword: "table", - type: "create", - table: [{ - table: table.name - }], - create_definitions: [...filed_definitions, ...constraints] - } -} -export const FieldToAst = (field: FieldType, ignorePrimaryKey: boolean = false, upperCaseType: boolean = true) => { - - const modifiers: string[] = field?.type.modifiers ? JSON.parse(field?.type.modifiers) : []; - let suffix: string[] = []; - - if (modifiers.includes(Modifiers.ZEROFILL) && field.zeroFill) { - suffix.push(Modifiers.ZEROFILL.toUpperCase()); - } - if (modifiers.includes(Modifiers.UNSIGNED) && field.unsigned) { - suffix.push(Modifiers.UNSIGNED.toUpperCase()); - } - - - let length: number | null = null; - let scale: number | string | null = null; - - let character_set: any | null = null; - let collate: any | null = null; - - let values: any[] = []; - let valuesExpr: any | null; - - let default_val: any | null = null; - let dataType: string | undefined = upperCaseType ? field.type?.name?.toLocaleUpperCase() : field.type?.name as string | undefined; - - if (modifiers.includes(Modifiers.PRECISION) && field.precision) { - length = field.precision; - if (modifiers.includes(Modifiers.SCALE) && !field.scale) - scale = "0"; - } - - if (modifiers.includes(Modifiers.SCALE) && field.scale) - scale = field.scale; - - if (modifiers.includes(Modifiers.LENGTH) && field.maxLength) - length = field.maxLength; - - else if (modifiers.includes(Modifiers.LENGTH) && (field.type.dialect == DatabaseDialect.MYSQL || field.type.dialect == DatabaseDialect.MARIADB) && field.type.name?.startsWith('var') && !field.maxLength) - length = MYSQL_MAX_VAR_LENGTH; - - if (modifiers.includes(Modifiers.CHARSET) && field.charset) - character_set = { - type: "CHARACTER SET", - value: { - type: "default", - value: field.charset - } - } - - if (modifiers.includes(Modifiers.COLLATE) && field.collate) - collate = { - keyword: "collate", - type: "collate", - collate: { - name: field.collate, - } - } - - if (modifiers.includes(Modifiers.VALUES) && field.values) { - - const jsonValues = JSON.parse(field.values); - if (jsonValues.length > 0) { - values = jsonValues.map((value: string) => ({ - type: "single_quote_string", - value - })); - - valuesExpr = { - parentheses: true, - type: "expr_list", - value: values - } - } - } - - if (field.defaultValue && field.defaultValue.trim().length > 0) { - default_val = { - type: "default", - value: { - type: "single_quote_string", - value: field.defaultValue - } - } - if (field.type.type == DataTypes.TIME && field.defaultValue == TimeDefaultValues.NOW) - default_val = { - type: "default", - value: { - type: "function", - name: { - name: [ - { - type: "origin", - value: "CURRENT_TIMESTAMP" - } - ] - }, - over: null - } - } - - else if (field.defaultValue == "true" || field.defaultValue == "false") { - default_val.value.type = "bool" - default_val.value.value = field.defaultValue == "true" ? true : false; - } - - // Check if it's a number (but not empty string or just whitespace) - else if (!isNaN(Number(field.defaultValue))) { - default_val.value.type = "number" - default_val.value.value = Number(field.defaultValue); - } - } - - let auto_increment: string | undefined; - if (modifiers.includes(Modifiers.AUTO_INCREMENT) && field.autoIncrement && field.type.dialect != DatabaseDialect.POSTGRES) { - auto_increment = "auto_increment" - } else if (modifiers.includes(Modifiers.AUTO_INCREMENT) && field.autoIncrement && field.type.dialect == DatabaseDialect.POSTGRES) { - if (dataType == "INTEGER") - dataType = "SERIAL"; - else - dataType = dataType?.replace("INT", "SERIAL"); - - } else { - auto_increment = undefined; - } - - - - return { - column: { - type: "column_ref", - column: { - expr: { - type: "default", value: field.name, - } - }, - }, - collate, - character_set, - default_val, - unique: field.unique ? "unique" : null, - auto_increment, - nullable: { - type: field.nullable ? "null" : "not null", - value: field.nullable ? "null" : "not null", - }, - definition: { - dataType, - length, - scale, - suffix, - expr: valuesExpr - }, - primary_key: field.isPrimary && !ignorePrimaryKey ? "primary key" : null, - resource: "column" - } -} - - - -export const IndexToAst = (index: IndexType, table: TableType) => { - - return { - index: index.name, - type: "create", - table: { table: table.name }, - keyword: "index", - on_kw: "on", - index_type: index.unique ? "unique" : null, - index_columns: index.fields.map((field: FieldType) => ({ - column: field.name, - type: "column_ref" - })) - } -} - -export const PotgresEnumToAst = (field: FieldType) => { - - const jsonValues = field.values ? JSON.parse(field.values) : []; - - return { - as: "as", - type: "create", - resource: "enum", - name: { - schema: null, - name: `${(field as any).table.name}_${field.name.toLowerCase()}_enum` - }, - keyword: "type", - create_definitions: { - parentheses: true, - type: "expr_list", - value: jsonValues.map((value: string) => ({ - type: "single_quote_string", - value - })) - } - } -} - - -const foreignKeyActionToAst = (action: ForeignKeyActions): string | null => { - switch (action) { - case ForeignKeyActions.CASCADE: - return "cascade"; - - case ForeignKeyActions.SET_NULL: - return "set null"; - - case ForeignKeyActions.RESTRICT: - return "restrict"; - - case ForeignKeyActions.SET_DEFAULT: - return "set default"; - - } - return null; -} - - - -export const relationshipToAst = (relationship: RelationshipType) => { - - let primaryKey: FieldType = relationship.sourceField; - let foreignKey: FieldType = relationship.targetField; - - let sourceTable: TableType = relationship.sourceTable; - let targetTable: TableType = relationship.targetTable; - - if (relationship.cardinality == Cardinality.many_to_one) { - primaryKey = relationship.targetField; - foreignKey = relationship.sourceField; - sourceTable = relationship.targetTable; - targetTable = relationship.sourceTable; - } - - let on_action: any[] = []; - - if (relationship.onDelete) { - const value: string | null = foreignKeyActionToAst(relationship.onDelete as ForeignKeyActions); - - if (value) - on_action.push({ - type: "on delete", - value: { - type: "origin", - value - } - }) - } - - - if (relationship.onUpdate) { - const value: string | null = foreignKeyActionToAst(relationship.onUpdate as ForeignKeyActions); - if (value) - on_action.push({ - type: "on update", - value: { - type: "origin", - value - } - }) - } - - return { - constraint: null, - definition: [ - { - type: "column_ref", - column: foreignKey.name, - - } - ], - constraint_type: "FOREIGN KEY", - resource: "constraint", - reference_definition: { - definition: [ - { - type: "column_ref", - column: primaryKey.name, - } - ], - table: [ - { - table: sourceTable.name, - } - ], - keyword: "references", - on_action - } - } - - -} \ No newline at end of file diff --git a/src/utils/render/parsers/sql_to_database.ts b/src/utils/render/parsers/sql_to_database.ts deleted file mode 100644 index 2b1a920..0000000 --- a/src/utils/render/parsers/sql_to_database.ts +++ /dev/null @@ -1,722 +0,0 @@ -import { DataTypes, ForeignKeyActions, Modifiers, TimeDefaultValues } from "@/lib/field"; -import { DataType } from "@/lib/schemas/data-type-schema"; -import { FieldInsertType, FieldType } from "@/lib/schemas/field-schema"; -import { TableInsertType } from "@/lib/schemas/table-schema"; -import { Parser } from "node-sql-parser"; -import { v4 } from "uuid"; -import { parse } from 'pgsql-ast-parser'; -import { DatabaseDialect, getDatabaseByDialect } from "@/lib/database"; -import { randomColor } from "@/lib/colors"; -import { Cardinality, RelationshipInsertType } from "@/lib/schemas/relationship-schema"; -import { IndexInsertType } from "@/lib/schemas/index-schema"; - - -export const SqlToDatabase = (sql: string, data_types: DataType[], dialect: DatabaseDialect) => { - const parser = new Parser(); - let errors: Error[] = []; - - const createTableStatements: string[] = []; - const alterTableStatements: string[] = []; - const createIndexStatements: string[] = []; - const createPostgresTypesStatements: string[] = []; - - const tables: TableInsertType[] = []; - let relationships: RelationshipInsertType[] = []; - const indices: IndexInsertType[] = [] - - const postgresTypes: any[] = []; - // Clean up SQL: remove comments and normalize - const cleanedSql = sql - .replace(/--.*$/gm, '') // remove single-line comments - .replace(/\/\*[\s\S]*?\*\//g, '') // remove multi-line comments - .replace(/\s+/g, ' ') // normalize whitespace - .replace(/;\s*/g, ';\n'); // separate statements - - // Split into individual statements - const statements = cleanedSql - .split('\n') - .map(s => s.trim()) - .filter(Boolean); - - for (const stmt of statements) { - const upper = stmt.toUpperCase(); - - if (upper.startsWith('CREATE TABLE')) { - createTableStatements.push(stmt); - } else if (upper.startsWith('ALTER TABLE')) { - alterTableStatements.push(stmt); - } else if (upper.startsWith('CREATE INDEX') || upper.startsWith('CREATE UNIQUE INDEX')) { - createIndexStatements.push(stmt); - } else if (upper.startsWith('CREATE TYPE')) { - createPostgresTypesStatements.push(stmt); - } - } - - - if (dialect == DatabaseDialect.POSTGRES) { - for (const postgresType of createPostgresTypesStatements) { - try { - const instructionAst = parse(postgresType); - - if (Array.isArray(instructionAst) && instructionAst.length > 0) { - postgresTypes.push(instructionAst[0]); - } - } catch (error) { - errors.push(error as Error); - } - } - - - for (const createTable of createTableStatements) { - try { - const instructionAst = parse(createTable); - - if (Array.isArray(instructionAst) && instructionAst.length > 0) { - const table: TableInsertType = postgresAstToTable(instructionAst[0], data_types, postgresTypes); - tables.push(table); - - for (const column of (instructionAst[0] as any).columns) - if (column.constraints?.length > 0) { - let referenceColumn: any | undefined = column.constraints.find((contraint: any) => contraint.type == "reference") - - if (!referenceColumn) - continue - - referenceColumn = { - ...referenceColumn, localColumns: [ - { name: column.name.name } - ] - } - - const relationshipAst: any = foreignKeyConstraintToAlterTableAst([referenceColumn], table); - - try { - const newRelationships = postgresAstToRelationship(relationshipAst, tables); - relationships = relationships.concat(newRelationships); - - } catch (error) { - errors.push(error as Error); - if ((error as any).relationships && (error as any).relationships.length > 0) - relationships = relationships.concat((error as any).relationships); - } - } - - if ((instructionAst[0] as any).constraints && (instructionAst[0] as any).constraints.length > 0) { - - const relationshipAst: any = foreignKeyConstraintToAlterTableAst((instructionAst[0] as any).constraints, table) - try { - const newRelationships = postgresAstToRelationship(relationshipAst, tables); - relationships = relationships.concat(newRelationships); - } catch (error) { - errors.push(error as Error); - if ((error as any).relationships && (error as any).relationships.length > 0) - relationships = relationships.concat((error as any).relationships); - } - } - } - } catch (error) { - - errors.push(error as Error); - - } - } - for (const createIndex of createIndexStatements) { - try { - const instructionAst = parse(createIndex); - if (Array.isArray(instructionAst) && instructionAst.length > 0) { - indices.push(postgresAstToIndex(instructionAst[0], tables)); - } - } catch (error) { - errors.push(error as Error); - } - } - for (const alterTable of alterTableStatements) { - try { - const instructionAst = parse(alterTable); - if (Array.isArray(instructionAst) && instructionAst.length > 0) { - const extractedRelationships: RelationshipInsertType[] = postgresAstToRelationship((instructionAst[0] as any), tables); - relationships = relationships.concat(extractedRelationships); - } - } catch (error) { - - - if ((error as any).relationships && (error as any).relationships.length > 0) - relationships = relationships.concat((error as any).relationships); - } - } - } else { - let foreignKeyConstraints: any[] = []; - let referenceDefinitions: any[] = []; - - for (let createTable of createTableStatements) { - - try { - - if (dialect == DatabaseDialect.SQLITE) - createTable = createTable.replace(/\btext\s*\(\s*\d+\s*\)/gi, 'TEXT'); - - - let instructionAst = parser.astify(createTable, { - database: dialect == DatabaseDialect.MARIADB ? getDatabaseByDialect(DatabaseDialect.MYSQL).name : getDatabaseByDialect(dialect).name - }); - - if (Array.isArray(instructionAst) && instructionAst.length > 0) { - instructionAst = instructionAst[0]; - } - if (instructionAst) { - const table: TableInsertType = astToTable(instructionAst, data_types); - tables.push(table); - - const tableForeignKeyConstraints = (instructionAst as any).create_definitions.filter((definition: any) => definition.constraint_type == "FOREIGN KEY"); - const tableReferenceDefinitions = (instructionAst as any).create_definitions.filter((definition: any) => definition.resource == "column" && definition.reference_definition); - - foreignKeyConstraints = foreignKeyConstraints.concat( - tableForeignKeyConstraints.map((constraint: any) => ({ ...constraint, table: (instructionAst as any).table })) - ) - referenceDefinitions = referenceDefinitions.concat( - tableReferenceDefinitions.map((constraint: any) => ({ ...constraint, table: (instructionAst as any).table })) - ) - } - - - } catch (error) { - - errors.push(error as Error); - continue; - } - } - for (const foreignKeyConstraint of foreignKeyConstraints) { - try { - relationships.push(astToRelationship(tables, foreignKeyConstraint) as RelationshipInsertType); - } catch (error) { - errors.push(error as Error); - continue; - } - } - for (const referenceDefinition of referenceDefinitions) { - try { - relationships.push(astToRelationship(tables, undefined, referenceDefinition) as RelationshipInsertType); - } catch (error) { - errors.push(error as Error); - continue; - } - } - - for (const alterTable of alterTableStatements) { - try { - let instructionAst: any = parser.astify(alterTable, { - database: getDatabaseByDialect(dialect).name - }); - - if (instructionAst) { - const extractedRelationships: RelationshipInsertType[] = astToRelationship(tables, undefined, undefined, { - ...instructionAst[0], - table: instructionAst[0].table?.[0].table - }) as RelationshipInsertType[]; - - relationships = relationships.concat(extractedRelationships) - } - } catch (error) { - - - if ((error as any).relationships && (error as any).relationships.length > 0) - relationships = relationships.concat((error as any).relationships); - - - } - } - - for (const createIndex of createIndexStatements) { - try { - let instructionAst = parser.astify(createIndex, { - database: getDatabaseByDialect(dialect).name - }); - if (Array.isArray(instructionAst) && instructionAst.length > 0) { - instructionAst = instructionAst[0]; - } - indices.push(astToIndex(instructionAst, tables)); - - } catch (error) { - - errors.push(error as Error); - continue; - } - } - } - if (tables.length == 0) - throw Error("Error while Parsing") - - - return { tables, relationships, indices, errors }; - -} - - - -const astToForiegnKeyAction = (ast: string): ForeignKeyActions => { - switch (ast) { - case "cascade": - return ForeignKeyActions.CASCADE; - case "set null": - return ForeignKeyActions.SET_NULL; - case 'restrict': - return ForeignKeyActions.RESTRICT; - case "set default": - return ForeignKeyActions.SET_DEFAULT; - } - return ForeignKeyActions.NO_ACTION -} - -export const astToRelationship = (tables: TableInsertType[], constraintAst?: any, columnAst?: any, alterTableAst?: any): RelationshipInsertType | RelationshipInsertType[] => { - - let targetField: FieldInsertType | undefined; - let sourceTable: TableInsertType | undefined; - let sourceField: FieldInsertType | undefined; - let targetTable: TableInsertType | undefined; - - let relationships: RelationshipInsertType[] = []; - - - let onDelete: ForeignKeyActions | undefined; - let onUpdate: ForeignKeyActions | undefined; - let on_action: any | undefined; - - - - if (constraintAst) { - - targetTable = tables.find((table: TableInsertType) => table.name == constraintAst.table?.[0].table); - targetField = targetTable?.fields?.find((field: FieldInsertType) => field.name == constraintAst.definition?.[0].column); - sourceTable = tables.find((table: TableInsertType) => table.name == constraintAst.reference_definition?.table?.[0].table); - sourceField = sourceTable?.fields?.find((field: FieldInsertType) => field.name == constraintAst.reference_definition?.definition?.[0].column); - on_action = constraintAst.reference_definition.on_action; - - } - - if (columnAst) { - - - targetTable = tables.find((table: TableInsertType) => table.name == columnAst.table?.[0].table); - targetField = targetTable?.fields?.find((field: FieldInsertType) => field.name == columnAst.column?.column); - sourceTable = tables.find((table: TableInsertType) => table.name == columnAst.reference_definition?.table?.[0].table); - sourceField = sourceTable?.fields?.find((field: FieldInsertType) => field.name == columnAst.reference_definition?.definition?.[0].column); - on_action = columnAst.reference_definition.on_action; - } - - - - if (on_action) { - const onDeleteAst: any | undefined = on_action.find((action: any) => action.type == "on delete"); - const onUpdateAst: any | undefined = on_action.find((action: any) => action.type == "on update"); - - if (onDeleteAst) - onDelete = astToForiegnKeyAction(onDeleteAst.value.value); - if (onUpdateAst) - onUpdate = astToForiegnKeyAction(onUpdateAst.value.value); - } - - if (alterTableAst) { - - const expressions = alterTableAst.expr; - const foreignKeyExpressions = expressions.filter((expression: any) => expression.resource == "constraint" && expression.create_definitions?.constraint_type == "FOREIGN KEY") - targetTable = tables.find((table: TableInsertType) => table.name == alterTableAst.table); - - - for (const expression of foreignKeyExpressions) { - - const targetField: FieldInsertType | undefined = targetTable?.fields?.find((field: FieldInsertType) => field.name == expression.create_definitions?.definition?.[0].column); - const sourceTable: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == expression.create_definitions?.reference_definition?.table?.[0].table) - const sourceField: FieldInsertType | undefined = sourceTable?.fields?.find((field: FieldInsertType) => field.name == expression.create_definitions?.reference_definition?.definition?.[0].column); - - const on_action: any | undefined = expression.create_definitions?.reference_definition?.on_action; - - let onDelete: ForeignKeyActions | undefined; - let onUpdate: ForeignKeyActions | undefined; - if (on_action) { - const onDeleteAst: any | undefined = on_action.find((action: any) => action.type == "on delete"); - const onUpdateAst: any | undefined = on_action.find((action: any) => action.type == "on update"); - - if (onDeleteAst) - onDelete = astToForiegnKeyAction(onDeleteAst.value.value); - if (onUpdateAst) - onUpdate = astToForiegnKeyAction(onUpdateAst.value.value); - } - - - if (!targetField || !sourceField || !sourceTable) - continue; - - relationships.push({ - id: v4(), - targetTableId: targetTable?.id, - targetFieldId: targetField.id, - sourceTableId: sourceTable.id, - sourceFieldId: sourceField.id, - cardinality: targetField.unique ? Cardinality.one_to_one : Cardinality.one_to_many, - onDelete, - onUpdate - } as RelationshipInsertType) - } - - if (relationships.length == foreignKeyExpressions.length) - return relationships; - else - throw Error({ - success: false, - message: "Failed to Extract all relationships", - relationships - } as any) - } - - if (!targetField || !sourceField || !sourceTable) - throw Error("Failed to extract relationship"); - - - return { - id: v4(), - targetTableId: targetTable?.id, - targetFieldId: targetField.id, - sourceTableId: sourceTable.id, - sourceFieldId: sourceField.id, - cardinality: targetField.unique ? Cardinality.one_to_one : Cardinality.one_to_many, - onDelete, - onUpdate - } as RelationshipInsertType; - -} - - - -const astToTable = (ast: any, data_types: DataType[]): TableInsertType => { - - return { - id: v4(), - name: ast.table[0]?.table, - fields: ast.create_definitions.filter((column: any) => column.resource == "column") - .map((fieldAst: any, index: number) => astToField(fieldAst, data_types, index)), - color: randomColor() - } as TableInsertType; -} - - -export const astToField = (ast: any, data_types: DataType[], sequence: number): FieldInsertType => { - - - - const dataType: DataType | undefined = data_types.find((dataType: DataType) => { - const synonyms: string[] = dataType.synonyms ? JSON.parse(dataType.synonyms) : []; - return dataType.name == ast.definition.dataType?.toLowerCase() || synonyms.includes(ast.definition.dataType?.toLowerCase()) - }); - - let values: string | undefined = undefined; - - const modifiers: string[] = dataType?.modifiers ? JSON.parse(dataType.modifiers) : []; - - const { length, scale } = ast.definition; - const { character_set, collate: collation } = ast; - - let charset: string | undefined; - let collate: string | undefined; - - let defaultValue: string | undefined = ast.default_val?.value?.value ? ast.default_val?.value?.value : undefined; - - let maxLength: number | null = null; - let precision: number | null = null; - - if (modifiers.includes(Modifiers.LENGTH) && length) - maxLength = length; - - if (modifiers.includes(Modifiers.PRECISION) && length) - precision = length; - - - if (modifiers.includes(Modifiers.CHARSET) && character_set) - charset = character_set.value?.value; - - if (modifiers.includes(Modifiers.COLLATE) && collation) - collate = collation.collate?.name; - - if (modifiers.includes(Modifiers.VALUES)) { - - - const value = ast.definition?.expr?.value.map((value: any) => value.value); - if (value) - values = JSON.stringify(value); - } - - if (dataType?.type == DataTypes.TIME && - ast.default_val?.value?.type == "function" && - ast.default_val?.value?.name?.name?.length > 0 && - ast.default_val?.value?.name?.name[0].value == "CURRENT_TIMESTAMP") - defaultValue = TimeDefaultValues.NOW; - - const isPrimary: boolean = ast.primary_key == "primary key"; - const nullable: boolean = ast.nullable?.value ? ast.nullable?.value != "not null" : !isPrimary; - - return { - id: v4(), - name: ast.column.column, - defaultValue, - typeId: dataType?.id, - nullable, - unique: ast.unique == "unique", - maxLength, - precision, - scale, - sequence, - autoIncrement: ast.auto_increment == "auto_increment", - isPrimary, - values, - charset, - collate, - } as FieldInsertType; - - -} - - -export const postgresAstToTable = (ast: any, data_types: DataType[], postgresTypes: any[]): TableInsertType => { - - return { - id: v4(), - name: ast.name.name, - fields: ast.columns.filter((column: any) => column.kind == "column") - .map((fieldAst: any, index: number) => postgresAstToField(fieldAst, data_types, index, postgresTypes)), - color: randomColor(), - } as TableInsertType; -} - - - -export const postgresAstToField = (ast: any, data_types: DataType[], sequence: number, postgresTypes: any[]): FieldInsertType => { - - let dataType: DataType | undefined = data_types.find((dataType: DataType) => { - const synonyms: string[] = dataType.synonyms ? JSON.parse(dataType.synonyms) : []; - return dataType.name == ast.dataType.name?.toLowerCase() || synonyms.includes(ast.dataType.name?.toLowerCase()) - }); - - let values: string | undefined; - let autoIncrement: boolean = false; - - if (!dataType && postgresTypes && postgresTypes.length > 0) { - const postgresType: any = postgresTypes.find((type: any) => type.name.name == ast.dataType.name); - if (postgresType) { - dataType = data_types.find((dataType: DataType) => dataType.name == "enum") as DataType; - values = JSON.stringify(postgresType.values.map((value: any) => value.value)); - }; - } - - if (ast.dataType.name?.toLowerCase().includes("serial")) { - - let baseType: string = ast.dataType.name?.toLowerCase() == "serial" ? "integer" : ast.dataType.name?.toLowerCase().replace("serial", "int"); - dataType = data_types.find((dataType: DataType) => { - return dataType.name == baseType; - }); - autoIncrement = true; - } - - const modifiers: string[] = dataType?.modifiers ? JSON.parse(dataType.modifiers) : []; - - let length: number | undefined; - let scale: number | undefined; - let unique: boolean = false; - let primaryKey: boolean = false; - - if (ast.dataType.config && ast.dataType.config.length > 0) { - if (ast.dataType.config.length >= 1) - length = ast.dataType.config[0]; - - if (ast.dataType.config.length == 2) - scale = ast.dataType.config[1]; - } - - - let maxLength: number | null = null; - let precision: number | null = null; - - if (modifiers.includes(Modifiers.LENGTH) && length) - maxLength = length; - - if (modifiers.includes(Modifiers.PRECISION) && length) - precision = length; - - let defaultValue: string | undefined; - let nullable: boolean = true; - - const constraints: any[] | undefined = ast.constraints; - if (constraints && constraints.length > 0) { - - const nullableConstraints: any | undefined = constraints.find((c: any) => c.type == "not null"); - const defaultValueConstraints: any | undefined = constraints.find((c: any) => c.type == "default"); - - if (defaultValueConstraints) { - if (defaultValueConstraints.default.type == "keyword" && defaultValueConstraints.default.keyword == "current_timestamp") - defaultValue = TimeDefaultValues.NOW; - - else if (defaultValueConstraints.default.type == "call" && defaultValueConstraints.default.function?.name == "now") - defaultValue = TimeDefaultValues.NOW; - - else if (defaultValueConstraints.default.type == "cast" && defaultValueConstraints.default.operand) - defaultValue = String(defaultValueConstraints.default.operand.value) - else - defaultValue = String(defaultValueConstraints.default.value); - } - const uniqueConstraints: any | undefined = constraints.find((c: any) => c.type == "unique"); - const primryKeyConstraints: any | undefined = constraints.find((c: any) => c.type == "primary key"); - - if (uniqueConstraints) - unique = true; - if (primryKeyConstraints) - primaryKey = true; - - if (nullableConstraints || primaryKey) - nullable = false; - - } - - - - return { - id: v4(), - name: ast.name.name, - defaultValue, - typeId: dataType?.id, - nullable, - unique, - maxLength, - precision, - scale, - isPrimary: primaryKey, - sequence, - values, - autoIncrement - } as FieldInsertType; -} - -export const postgresAstToRelationship = (ast: any, tables: TableInsertType[]): RelationshipInsertType[] => { - - const relationships: RelationshipInsertType[] = []; - const changes = ast.changes; - - const targetTable: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == ast.table.name); - - if (!targetTable) - throw Error("source table not found"); - - const foreignKeyConstraints = changes.filter((change: any) => change.type == 'add constraint' && change.constraint && change.constraint.type == "foreign key").map((change: any) => change.constraint); - - for (const foreignKeyConstraint of foreignKeyConstraints) { - - const sourceTable: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == foreignKeyConstraint.foreignTable.name); - const targetField: FieldInsertType | undefined = targetTable.fields?.find((field: FieldInsertType) => field.name == foreignKeyConstraint.localColumns[0]?.name) - const sourceField: FieldInsertType | undefined = sourceTable?.fields?.find((field: FieldInsertType) => field.name == foreignKeyConstraint.foreignColumns[0]?.name) - - const onDelete = foreignKeyConstraint.onDelete ? astToForiegnKeyAction(foreignKeyConstraint.onDelete) : undefined; - const onUpdate = foreignKeyConstraint.onUpdate ? astToForiegnKeyAction(foreignKeyConstraint.onUpdate) : undefined; - - if (!sourceField || !targetField || !sourceTable) - continue; - - relationships.push({ - id: v4(), - sourceTableId: sourceTable.id, - targetTableId: targetTable.id, - sourceFieldId: sourceField.id, - targetFieldId: targetField.id, - cardinality: targetField.unique ? Cardinality.one_to_one : Cardinality.one_to_many, - onDelete, onUpdate - } as RelationshipInsertType) - } - - if (relationships.length == foreignKeyConstraints.length) - return relationships; - else - throw Error({ - success: false, - message: "Failed to Extract all relationships", - relationships - } as any) -} - - -const foreignKeyConstraintToAlterTableAst = (constraints: any[], table: TableInsertType) => { - - const changes: any[] = constraints.filter((constraint: any) => constraint.type == "foreign key" || constraint.type == "reference").map((constraint: any) => ({ - - type: "add constraint", - constraint: { - type: "foreign key", - localColumns: [ - { - name: constraint.localColumns?.[0].name - } - ], - foreignTable: { - name: constraint.foreignTable.name, - }, - foreignColumns: [ - { - name: constraint.foreignColumns?.[0].name - } - ], - onDelete: constraint.onDelete, - onUpdate: constraint.onUpdate, - } - })) - - return { - type: "alter table", - only: true, - table: { - name: table.name - }, - changes - } -} - -export const astToIndex = (ast: any, tables: TableInsertType[]): IndexInsertType => { - const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == ast.table.table); - - if (!table) - throw Error("table not found"); - - const fieldNames: string[] = ast.index_columns.map((column: any) => column.column); - const fieldIds: string[] | undefined = table.fields?.filter((field: FieldInsertType) => fieldNames.includes(field.name)) - .map((field: FieldInsertType) => field.id); - - return { - id: v4(), - name: ast.index, - tableId: table.id, - unique: ast.index_type == "unique", - fieldIndices: fieldIds?.map((id: string) => ({ - id: v4(), - fieldId: id - })) - } as IndexInsertType -} - -export const postgresAstToIndex = (ast: any, tables: TableInsertType[]): IndexInsertType => { - const table: TableInsertType | undefined = tables.find((table: TableInsertType) => table.name == ast.table.name); - - if (!table) - throw Error("table not found"); - - const fieldNames: string[] = ast.expressions.map((expression: any) => expression.expression.name); - - - const fieldIds: string[] | undefined = table.fields?.filter((field: FieldInsertType) => fieldNames.includes(field.name)) - .map((field: FieldInsertType) => field.id); - - return { - id: v4(), - name: ast.indexName.name, - tableId: table.id, - unique: ast.unique, - fieldIndices: fieldIds?.map((id: string) => ({ - id: v4(), - fieldId: id - })) - } as IndexInsertType -} - diff --git a/src/utils/render/render-uttils.ts b/src/utils/render/render-uttils.ts index 158916f..b8dca3c 100644 --- a/src/utils/render/render-uttils.ts +++ b/src/utils/render/render-uttils.ts @@ -1,3 +1,14 @@ +import { DatabaseDialect } from "@/lib/database"; +import { DataType } from "@/lib/schemas/data-type-schema"; +import MysqlRenderer from "./database/mysql-renderer"; +import PostgresqlRenderer from "./database/postgresql-renderer"; +import MariaDbRenderer from "./database/mariadb-renderer"; +import OracleRenderer from "./database/oracle-renderer"; +import MSSqlRenderer from "./database/mssql-database-renderer"; +import SqliteRenderer from "./database/sqlite-database-renderer"; +import { TableType } from "@/lib/schemas/table-schema"; +import { FieldType } from "@/lib/schemas/field-schema"; + /** * Fixes charset/collation placement in SQL CREATE TABLE statements * @param sql The SQL string to process @@ -151,4 +162,32 @@ export interface CircularDependencyError { cycle: string[]; success: boolean; message: string; +} + +export const getPostgresEnumName = (table: TableType, field: FieldType): string => { + + return `${table.name}_${field.name.toLowerCase()}_enum` +} + +export const getRenderer = (dialect: DatabaseDialect, data_types: DataType[]) => { + + switch (dialect) { + case DatabaseDialect.MYSQL: + return new MysqlRenderer(data_types); + + case DatabaseDialect.POSTGRES: + return new PostgresqlRenderer(data_types); + + case DatabaseDialect.MARIADB: + return new MariaDbRenderer(data_types); + + case DatabaseDialect.ORACLE: + return new OracleRenderer(data_types); + + case DatabaseDialect.MSSQL: + return new MSSqlRenderer(data_types); + + case DatabaseDialect.SQLITE: + return new SqliteRenderer(data_types); + } } \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index 8e02ca4..ab0ad97 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,7 +12,7 @@ export default defineConfig({ optimizeDeps: { // Don't optimize these packages as they contain web workers and WASM files. // https://github.com/vitejs/vite/issues/11672#issuecomment-1415820673 - exclude: ['@journeyapps/wa-sqlite', '@powersync/web'], + exclude: ['@journeyapps/wa-sqlite', '@powersync/web' , '@guanmingchiu/sqlparser-ts'], include: ['@powersync/web > js-logger'] }, worker: {