@fragno-dev/db 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +202 -140
- package/CHANGELOG.md +35 -0
- package/README.md +30 -9
- package/dist/adapters/adapters.d.ts +23 -21
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
- package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
- package/dist/adapters/generic-sql/driver-config.js +23 -1
- package/dist/adapters/generic-sql/driver-config.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
- package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
- package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
- package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/select-builder.js +5 -3
- package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
- package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/where-builder.js +39 -29
- package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
- package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
- package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
- package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
- package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
- package/dist/adapters/generic-sql/uow-decoder.js +7 -3
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
- package/dist/adapters/generic-sql/uow-encoder.js +28 -8
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
- package/dist/adapters/in-memory/condition-evaluator.js +131 -0
- package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
- package/dist/adapters/in-memory/errors.d.ts +13 -0
- package/dist/adapters/in-memory/errors.d.ts.map +1 -0
- package/dist/adapters/in-memory/errors.js +23 -0
- package/dist/adapters/in-memory/errors.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
- package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
- package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
- package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-uow.js +648 -0
- package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
- package/dist/adapters/in-memory/index.d.ts +4 -0
- package/dist/adapters/in-memory/index.js +4 -0
- package/dist/adapters/in-memory/options.d.ts +28 -0
- package/dist/adapters/in-memory/options.d.ts.map +1 -0
- package/dist/adapters/in-memory/options.js +61 -0
- package/dist/adapters/in-memory/options.js.map +1 -0
- package/dist/adapters/in-memory/reference-resolution.js +26 -0
- package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
- package/dist/adapters/in-memory/sorted-array-index.js +129 -0
- package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
- package/dist/adapters/in-memory/store.js +71 -0
- package/dist/adapters/in-memory/store.js.map +1 -0
- package/dist/adapters/in-memory/value-comparison.js +28 -0
- package/dist/adapters/in-memory/value-comparison.js.map +1 -0
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
- package/dist/adapters/shared/uow-operation-compiler.js +11 -11
- package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
- package/dist/adapters/sql/index.d.ts +5 -0
- package/dist/adapters/sql/index.js +4 -0
- package/dist/db-fragment-definition-builder.d.ts +18 -7
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +116 -54
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
- package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
- package/dist/dispatchers/cloudflare-do/index.js +63 -0
- package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
- package/dist/dispatchers/node/index.d.ts +17 -0
- package/dist/dispatchers/node/index.d.ts.map +1 -0
- package/dist/dispatchers/node/index.js +59 -0
- package/dist/dispatchers/node/index.js.map +1 -0
- package/dist/fragments/internal-fragment.d.ts +79 -2
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +150 -32
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/fragments/internal-fragment.routes.js +29 -0
- package/dist/fragments/internal-fragment.routes.js.map +1 -0
- package/dist/fragments/internal-fragment.schema.d.ts +9 -0
- package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
- package/dist/fragments/internal-fragment.schema.js +22 -0
- package/dist/fragments/internal-fragment.schema.js.map +1 -0
- package/dist/hooks/durable-hooks-processor.d.ts +14 -0
- package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
- package/dist/hooks/durable-hooks-processor.js +32 -0
- package/dist/hooks/durable-hooks-processor.js.map +1 -0
- package/dist/hooks/hooks.d.ts +42 -1
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +72 -6
- package/dist/hooks/hooks.js.map +1 -1
- package/dist/migration-engine/auto-from-schema.js +14 -11
- package/dist/migration-engine/auto-from-schema.js.map +1 -1
- package/dist/migration-engine/generation-engine.d.ts +16 -10
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +72 -33
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/migration-engine/shared.js.map +1 -1
- package/dist/mod.d.ts +15 -8
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +14 -8
- package/dist/mod.js.map +1 -1
- package/dist/naming/sql-naming.d.ts +19 -0
- package/dist/naming/sql-naming.d.ts.map +1 -0
- package/dist/naming/sql-naming.js +116 -0
- package/dist/naming/sql-naming.js.map +1 -0
- package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
- package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/outbox/outbox-builder.js +156 -0
- package/dist/outbox/outbox-builder.js.map +1 -0
- package/dist/outbox/outbox.d.ts +52 -0
- package/dist/outbox/outbox.d.ts.map +1 -0
- package/dist/outbox/outbox.js +37 -0
- package/dist/outbox/outbox.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
- package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
- package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
- package/dist/packages/fragno/dist/api/route.js +14 -1
- package/dist/packages/fragno/dist/api/route.js.map +1 -1
- package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
- package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
- package/dist/query/column-defaults.js +20 -4
- package/dist/query/column-defaults.js.map +1 -1
- package/dist/query/cursor.d.ts +3 -1
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +45 -14
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/db-now.d.ts +8 -0
- package/dist/query/db-now.d.ts.map +1 -0
- package/dist/query/db-now.js +7 -0
- package/dist/query/db-now.js.map +1 -0
- package/dist/query/serialize/create-sql-serializer.js +3 -2
- package/dist/query/serialize/create-sql-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
- package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
- package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
- package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
- package/dist/query/serialize/sql-serializer.js +2 -2
- package/dist/query/serialize/sql-serializer.js.map +1 -1
- package/dist/query/simple-query-interface.d.ts +6 -1
- package/dist/query/simple-query-interface.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +86 -5
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +9 -6
- package/dist/query/value-decoding.js.map +1 -1
- package/dist/query/value-encoding.js +29 -9
- package/dist/query/value-encoding.js.map +1 -1
- package/dist/schema/create.d.ts +38 -14
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +81 -42
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/generate-id.js +2 -2
- package/dist/schema/generate-id.js.map +1 -1
- package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
- package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
- package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
- package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
- package/dist/schema/validator.d.ts +10 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +123 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/schema-output/drizzle.d.ts +30 -0
- package/dist/schema-output/drizzle.d.ts.map +1 -0
- package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
- package/dist/schema-output/drizzle.js.map +1 -0
- package/dist/schema-output/prisma.d.ts +17 -0
- package/dist/schema-output/prisma.d.ts.map +1 -0
- package/dist/schema-output/prisma.js +296 -0
- package/dist/schema-output/prisma.js.map +1 -0
- package/dist/util/default-database-adapter.js +61 -0
- package/dist/util/default-database-adapter.js.map +1 -0
- package/dist/with-database.d.ts +1 -1
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +12 -3
- package/dist/with-database.js.map +1 -1
- package/package.json +43 -28
- package/src/adapters/adapters.ts +30 -24
- package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
- package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
- package/src/adapters/drizzle/test-utils.ts +12 -8
- package/src/adapters/generic-sql/driver-config.ts +38 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
- package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
- package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
- package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
- package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
- package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
- package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
- package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
- package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
- package/src/adapters/generic-sql/query/select-builder.ts +6 -2
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
- package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
- package/src/adapters/generic-sql/query/where-builder.ts +90 -38
- package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
- package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
- package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
- package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
- package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
- package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
- package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
- package/src/adapters/generic-sql/uow-decoder.ts +21 -3
- package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
- package/src/adapters/generic-sql/uow-encoder.ts +50 -11
- package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
- package/src/adapters/in-memory/condition-evaluator.ts +275 -0
- package/src/adapters/in-memory/errors.ts +20 -0
- package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
- package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
- package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
- package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
- package/src/adapters/in-memory/index.ts +3 -0
- package/src/adapters/in-memory/options.test.ts +41 -0
- package/src/adapters/in-memory/options.ts +87 -0
- package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
- package/src/adapters/in-memory/reference-resolution.ts +67 -0
- package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
- package/src/adapters/in-memory/sorted-array-index.ts +228 -0
- package/src/adapters/in-memory/store.test.ts +68 -0
- package/src/adapters/in-memory/store.ts +145 -0
- package/src/adapters/in-memory/value-comparison.ts +53 -0
- package/src/adapters/in-memory/value-normalization.test.ts +57 -0
- package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
- package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
- package/src/adapters/shared/uow-operation-compiler.ts +26 -16
- package/src/adapters/sql/index.ts +12 -0
- package/src/db-fragment-definition-builder.test.ts +30 -12
- package/src/db-fragment-definition-builder.ts +142 -73
- package/src/db-fragment-instantiator.test.ts +105 -13
- package/src/db-fragment-integration.test.ts +9 -7
- package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
- package/src/dispatchers/cloudflare-do/index.ts +104 -0
- package/src/dispatchers/node/index.test.ts +91 -0
- package/src/dispatchers/node/index.ts +87 -0
- package/src/fragments/internal-fragment.routes.ts +42 -0
- package/src/fragments/internal-fragment.schema.ts +51 -0
- package/src/fragments/internal-fragment.test.ts +458 -8
- package/src/fragments/internal-fragment.ts +322 -63
- package/src/hooks/durable-hooks-processor.test.ts +117 -0
- package/src/hooks/durable-hooks-processor.ts +67 -0
- package/src/hooks/hooks.test.ts +165 -5
- package/src/hooks/hooks.ts +197 -9
- package/src/migration-engine/auto-from-schema.test.ts +14 -14
- package/src/migration-engine/auto-from-schema.ts +5 -2
- package/src/migration-engine/create.test.ts +2 -2
- package/src/migration-engine/generation-engine.test.ts +229 -104
- package/src/migration-engine/generation-engine.ts +94 -64
- package/src/migration-engine/shared.ts +1 -0
- package/src/mod.ts +64 -26
- package/src/naming/sql-naming.ts +180 -0
- package/src/outbox/outbox-builder.ts +241 -0
- package/src/outbox/outbox.test.ts +253 -0
- package/src/outbox/outbox.ts +137 -0
- package/src/query/column-defaults.ts +41 -3
- package/src/query/condition-builder.test.ts +3 -3
- package/src/query/cursor.test.ts +116 -18
- package/src/query/cursor.ts +75 -26
- package/src/query/db-now.ts +6 -0
- package/src/query/query-type.test.ts +2 -2
- package/src/query/serialize/create-sql-serializer.ts +7 -2
- package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
- package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
- package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
- package/src/query/serialize/sql-serializer.ts +4 -4
- package/src/query/simple-query-interface.ts +5 -0
- package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
- package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
- package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
- package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
- package/src/query/unit-of-work/unit-of-work.ts +203 -18
- package/src/query/value-decoding.test.ts +13 -2
- package/src/query/value-decoding.ts +17 -4
- package/src/query/value-encoding.test.ts +85 -2
- package/src/query/value-encoding.ts +56 -6
- package/src/schema/create.test.ts +129 -42
- package/src/schema/create.ts +185 -47
- package/src/schema/generate-id.test.ts +2 -2
- package/src/schema/generate-id.ts +2 -2
- package/src/schema/serialize.test.ts +14 -2
- package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
- package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
- package/src/schema/type-conversion/type-mapping.test.ts +25 -1
- package/src/schema/validator.test.ts +197 -0
- package/src/schema/validator.ts +231 -0
- package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
- package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
- package/src/schema-output/prisma.test.ts +536 -0
- package/src/schema-output/prisma.ts +573 -0
- package/src/util/default-database-adapter.ts +106 -0
- package/src/with-database.ts +22 -3
- package/tsdown.config.ts +6 -4
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
- package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
- package/dist/adapters/drizzle/generate.d.ts +0 -30
- package/dist/adapters/drizzle/generate.d.ts.map +0 -1
- package/dist/adapters/drizzle/generate.js.map +0 -1
- package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-adapter.js +0 -17
- package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
- package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
- package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
- package/dist/adapters/shared/table-name-mapper.js +0 -43
- package/dist/adapters/shared/table-name-mapper.js.map +0 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/schema-generator/schema-generator.d.ts +0 -15
- package/dist/schema-generator/schema-generator.d.ts.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
- package/src/adapters/kysely/kysely-adapter.ts +0 -27
- package/src/adapters/shared/table-name-mapper.ts +0 -50
- package/src/schema-generator/schema-generator.ts +0 -12
package/src/schema/create.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
1
2
|
import { createId } from "../id";
|
|
3
|
+
import type { DbNow } from "../query/db-now";
|
|
4
|
+
import type { Prettify } from "../util/types";
|
|
5
|
+
import { createTableStandardSchemaProps, createTableValidator } from "./validator";
|
|
2
6
|
|
|
3
7
|
export { generateId } from "./generate-id";
|
|
8
|
+
export { FragnoDbValidationError } from "./validator";
|
|
4
9
|
|
|
5
10
|
export type AnySchema = Schema<Record<string, AnyTable>>;
|
|
6
11
|
|
|
@@ -95,13 +100,13 @@ export class ExplicitRelationInit<
|
|
|
95
100
|
TTables extends Record<string, AnyTable>,
|
|
96
101
|
TTableName extends keyof TTables,
|
|
97
102
|
> extends RelationInit<TRelationType, TTables, TTableName> {
|
|
98
|
-
init(
|
|
99
|
-
const id = `${this.referencer.
|
|
103
|
+
init(name: string): Relation<TRelationType, TTables[TTableName]> {
|
|
104
|
+
const id = `${this.referencer.name}_${this.referencedTable.name}`;
|
|
100
105
|
|
|
101
106
|
return {
|
|
102
107
|
id,
|
|
103
108
|
on: this.on,
|
|
104
|
-
name
|
|
109
|
+
name,
|
|
105
110
|
referencer: this.referencer,
|
|
106
111
|
table: this.referencedTable,
|
|
107
112
|
type: this.type,
|
|
@@ -123,18 +128,57 @@ export interface Relation<
|
|
|
123
128
|
on: [string, string][];
|
|
124
129
|
}
|
|
125
130
|
|
|
131
|
+
type PickNullable<T> = {
|
|
132
|
+
[P in keyof T as null extends T[P] ? P : never]: T[P];
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type PickNotNullable<T> = {
|
|
136
|
+
[P in keyof T as null extends T[P] ? never : P]: T[P];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
type RawInsertValuesFromColumns<TColumns extends Record<string, AnyColumn>> = {
|
|
140
|
+
[K in keyof TColumns as string extends K ? never : K]: TColumns[K]["$in"];
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
type TableInsertValuesFromColumns<TColumns extends Record<string, AnyColumn>> = Prettify<
|
|
144
|
+
Partial<PickNullable<RawInsertValuesFromColumns<TColumns>>> &
|
|
145
|
+
PickNotNullable<RawInsertValuesFromColumns<TColumns>>
|
|
146
|
+
>;
|
|
147
|
+
|
|
148
|
+
export type TableInsertValues<T extends AnyTable> = TableInsertValuesFromColumns<T["columns"]>;
|
|
149
|
+
|
|
150
|
+
export type TableUnknownKeysMode = "strip" | "strict";
|
|
151
|
+
|
|
152
|
+
export type TableValidationOptions = {
|
|
153
|
+
unknownKeys?: TableUnknownKeysMode;
|
|
154
|
+
};
|
|
155
|
+
|
|
126
156
|
export interface Table<
|
|
127
157
|
TColumns extends Record<string, AnyColumn> = Record<string, AnyColumn>,
|
|
128
158
|
TRelations extends Record<string, AnyRelation> = Record<string, AnyRelation>,
|
|
129
159
|
TIndexes extends Record<string, Index> = Record<string, Index>,
|
|
130
160
|
> {
|
|
161
|
+
/**
|
|
162
|
+
* Standard Schema-compatible validator for insert values.
|
|
163
|
+
*/
|
|
164
|
+
"~standard": StandardSchemaV1.Props<
|
|
165
|
+
TableInsertValuesFromColumns<TColumns>,
|
|
166
|
+
TableInsertValuesFromColumns<TColumns>
|
|
167
|
+
>;
|
|
131
168
|
name: string;
|
|
132
|
-
ormName: string;
|
|
133
169
|
|
|
134
170
|
columns: TColumns;
|
|
135
171
|
relations: TRelations;
|
|
136
172
|
indexes: TIndexes;
|
|
137
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Validate insert values at runtime.
|
|
176
|
+
*/
|
|
177
|
+
validate: (
|
|
178
|
+
value: unknown,
|
|
179
|
+
options?: TableValidationOptions,
|
|
180
|
+
) => TableInsertValuesFromColumns<TColumns>;
|
|
181
|
+
|
|
138
182
|
/**
|
|
139
183
|
* Get column by name
|
|
140
184
|
*/
|
|
@@ -203,7 +247,6 @@ export type TypeMap = {
|
|
|
203
247
|
export class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown> {
|
|
204
248
|
type: TType;
|
|
205
249
|
name: string = "";
|
|
206
|
-
ormName: string = "";
|
|
207
250
|
isNullable: boolean = false;
|
|
208
251
|
role: "external-id" | "internal-id" | "version" | "reference" | "regular" = "regular";
|
|
209
252
|
isHidden: boolean = false;
|
|
@@ -421,9 +464,13 @@ export class VersionColumn<TIn = unknown, TOut = unknown> extends Column<"intege
|
|
|
421
464
|
}
|
|
422
465
|
}
|
|
423
466
|
|
|
467
|
+
type ColumnInput<TType extends keyof TypeMap> =
|
|
468
|
+
| TypeMap[TType]
|
|
469
|
+
| (TType extends "timestamp" | "date" ? DbNow : never);
|
|
470
|
+
|
|
424
471
|
export function column<TType extends keyof TypeMap>(
|
|
425
472
|
type: TType,
|
|
426
|
-
): Column<TType,
|
|
473
|
+
): Column<TType, ColumnInput<TType>, TypeMap[TType]> {
|
|
427
474
|
return new Column(type);
|
|
428
475
|
}
|
|
429
476
|
|
|
@@ -579,6 +626,8 @@ export class FragnoReference {
|
|
|
579
626
|
}
|
|
580
627
|
}
|
|
581
628
|
|
|
629
|
+
const validationClasses = { FragnoId, FragnoReference };
|
|
630
|
+
|
|
582
631
|
type RelationType = "one" | "many";
|
|
583
632
|
|
|
584
633
|
export class TableBuilder<
|
|
@@ -590,7 +639,6 @@ export class TableBuilder<
|
|
|
590
639
|
#columns: TColumns;
|
|
591
640
|
#relations: TRelations;
|
|
592
641
|
#indexes: TIndexes;
|
|
593
|
-
#ormName: string = "";
|
|
594
642
|
#columnOrder: string[] = [];
|
|
595
643
|
|
|
596
644
|
constructor(name: string) {
|
|
@@ -626,7 +674,7 @@ export class TableBuilder<
|
|
|
626
674
|
* Add a column to the table.
|
|
627
675
|
*/
|
|
628
676
|
addColumn<TColumnName extends string, TColumn extends AnyColumn>(
|
|
629
|
-
|
|
677
|
+
name: TColumnName,
|
|
630
678
|
col: TColumn,
|
|
631
679
|
): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes>;
|
|
632
680
|
|
|
@@ -634,28 +682,27 @@ export class TableBuilder<
|
|
|
634
682
|
* Add a column to the table with simplified syntax.
|
|
635
683
|
*/
|
|
636
684
|
addColumn<TColumnName extends string, TType extends keyof TypeMap>(
|
|
637
|
-
|
|
685
|
+
name: TColumnName,
|
|
638
686
|
type: TType,
|
|
639
687
|
): TableBuilder<
|
|
640
|
-
TColumns & Record<TColumnName, Column<TType,
|
|
688
|
+
TColumns & Record<TColumnName, Column<TType, ColumnInput<TType>, TypeMap[TType]>>,
|
|
641
689
|
TRelations,
|
|
642
690
|
TIndexes
|
|
643
691
|
>;
|
|
644
692
|
|
|
645
693
|
addColumn<TColumnName extends string, TColumn extends AnyColumn, TType extends keyof TypeMap>(
|
|
646
|
-
|
|
694
|
+
name: TColumnName,
|
|
647
695
|
colOrType: TColumn | TType,
|
|
648
696
|
): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes> {
|
|
649
697
|
// Create the column if a type string was provided
|
|
650
698
|
const col = typeof colOrType === "string" ? column(colOrType) : colOrType;
|
|
651
699
|
|
|
652
700
|
// Set column metadata
|
|
653
|
-
col.
|
|
654
|
-
col.name = ormName;
|
|
701
|
+
col.name = name;
|
|
655
702
|
|
|
656
703
|
// Add column directly to this builder
|
|
657
|
-
this.#columns[
|
|
658
|
-
this.#columnOrder.push(
|
|
704
|
+
this.#columns[name] = col as unknown as TColumns[TColumnName];
|
|
705
|
+
this.#columnOrder.push(name);
|
|
659
706
|
|
|
660
707
|
return this as unknown as TableBuilder<
|
|
661
708
|
TColumns & Record<TColumnName, TColumn>,
|
|
@@ -716,7 +763,6 @@ export class TableBuilder<
|
|
|
716
763
|
// Auto-add _internalId and _version columns if not already present
|
|
717
764
|
if (!this.#columns["_internalId"]) {
|
|
718
765
|
const col = internalIdColumn();
|
|
719
|
-
col.ormName = "_internalId";
|
|
720
766
|
col.name = "_internalId";
|
|
721
767
|
// Safe: we're adding system columns to the internal columns object
|
|
722
768
|
(this.#columns as Record<string, AnyColumn>)["_internalId"] = col;
|
|
@@ -724,18 +770,13 @@ export class TableBuilder<
|
|
|
724
770
|
|
|
725
771
|
if (!this.#columns["_version"]) {
|
|
726
772
|
const col = versionColumn();
|
|
727
|
-
col.ormName = "_version";
|
|
728
773
|
col.name = "_version";
|
|
729
774
|
// Safe: we're adding system columns to the internal columns object
|
|
730
775
|
(this.#columns as Record<string, AnyColumn>)["_version"] = col;
|
|
731
776
|
}
|
|
732
777
|
|
|
733
|
-
|
|
734
|
-
const ormName = this.#ormName || this.#name;
|
|
735
|
-
|
|
736
|
-
const table: Table<TColumns, TRelations, TIndexes> = {
|
|
778
|
+
const table = {
|
|
737
779
|
name: this.#name,
|
|
738
|
-
ormName,
|
|
739
780
|
columns: this.#columns,
|
|
740
781
|
relations: this.#relations,
|
|
741
782
|
indexes: this.#indexes,
|
|
@@ -751,7 +792,10 @@ export class TableBuilder<
|
|
|
751
792
|
getVersionColumn: () => {
|
|
752
793
|
return versionCol!;
|
|
753
794
|
},
|
|
754
|
-
}
|
|
795
|
+
} as Table<TColumns, TRelations, TIndexes>;
|
|
796
|
+
|
|
797
|
+
table["~standard"] = createTableStandardSchemaProps(table, validationClasses);
|
|
798
|
+
table.validate = createTableValidator(table, validationClasses);
|
|
755
799
|
|
|
756
800
|
// Set table reference and find special columns
|
|
757
801
|
for (const k in this.#columns) {
|
|
@@ -787,6 +831,10 @@ export class TableBuilder<
|
|
|
787
831
|
}
|
|
788
832
|
|
|
789
833
|
export interface Schema<TTables extends Record<string, AnyTable> = Record<string, AnyTable>> {
|
|
834
|
+
/**
|
|
835
|
+
* @description The name of the schema (required).
|
|
836
|
+
*/
|
|
837
|
+
name: string;
|
|
790
838
|
/**
|
|
791
839
|
* @description The version of the schema, automatically incremented on each change.
|
|
792
840
|
*/
|
|
@@ -851,11 +899,15 @@ type ColumnsToTuple<
|
|
|
851
899
|
} & AnyColumn[];
|
|
852
900
|
|
|
853
901
|
export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
902
|
+
#name: string;
|
|
854
903
|
#tables: TTables;
|
|
855
904
|
#version: number = 0;
|
|
856
905
|
#operations: SchemaOperation[] = [];
|
|
906
|
+
#tableNames: Set<string> = new Set();
|
|
907
|
+
#indexNames: Set<string> = new Set();
|
|
857
908
|
|
|
858
|
-
constructor(existingSchema?: Schema<TTables>) {
|
|
909
|
+
constructor(name: string, existingSchema?: Schema<TTables>) {
|
|
910
|
+
this.#name = name;
|
|
859
911
|
if (existingSchema) {
|
|
860
912
|
this.#tables = existingSchema.tables;
|
|
861
913
|
this.#version = existingSchema.version;
|
|
@@ -863,6 +915,29 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
863
915
|
} else {
|
|
864
916
|
this.#tables = {} as TTables;
|
|
865
917
|
}
|
|
918
|
+
|
|
919
|
+
for (const table of Object.values(this.#tables)) {
|
|
920
|
+
this.#registerTableName(table.name);
|
|
921
|
+
for (const index of Object.values(table.indexes)) {
|
|
922
|
+
this.#registerIndexName(index.name, table.name);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
#registerTableName(name: string): void {
|
|
928
|
+
if (this.#tableNames.has(name)) {
|
|
929
|
+
throw new Error(`Duplicate table name "${name}" in schema "${this.#name}".`);
|
|
930
|
+
}
|
|
931
|
+
this.#tableNames.add(name);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
#registerIndexName(name: string, tableName: string): void {
|
|
935
|
+
if (this.#indexNames.has(name)) {
|
|
936
|
+
throw new Error(
|
|
937
|
+
`Duplicate index name "${name}" in schema "${this.#name}". Index names must be unique across tables (conflict on "${tableName}").`,
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
this.#indexNames.add(name);
|
|
866
941
|
}
|
|
867
942
|
|
|
868
943
|
/**
|
|
@@ -871,7 +946,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
871
946
|
*
|
|
872
947
|
* @example
|
|
873
948
|
* ```ts
|
|
874
|
-
* const builder = new SchemaBuilder()
|
|
949
|
+
* const builder = new SchemaBuilder("combined")
|
|
875
950
|
* .add(userSchema)
|
|
876
951
|
* .add(postSchema)
|
|
877
952
|
* .addTable("comments", ...);
|
|
@@ -880,10 +955,32 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
880
955
|
mergeWithExistingSchema<TNewTables extends Record<string, AnyTable>>(
|
|
881
956
|
schema: Schema<TNewTables>,
|
|
882
957
|
): SchemaBuilder<TTables & TNewTables> {
|
|
958
|
+
for (const table of Object.values(schema.tables)) {
|
|
959
|
+
if (this.#tableNames.has(table.name)) {
|
|
960
|
+
throw new Error(
|
|
961
|
+
`Duplicate table name "${table.name}" in schema "${this.#name}" when merging.`,
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
for (const index of Object.values(table.indexes)) {
|
|
965
|
+
if (this.#indexNames.has(index.name)) {
|
|
966
|
+
throw new Error(
|
|
967
|
+
`Duplicate index name "${index.name}" in schema "${this.#name}" when merging (conflict on "${table.name}").`,
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
883
973
|
this.#tables = { ...this.#tables, ...schema.tables } as TTables & TNewTables;
|
|
884
974
|
this.#operations = [...this.#operations, ...schema.operations];
|
|
885
975
|
this.#version += schema.version;
|
|
886
976
|
|
|
977
|
+
for (const table of Object.values(schema.tables)) {
|
|
978
|
+
this.#tableNames.add(table.name);
|
|
979
|
+
for (const index of Object.values(table.indexes)) {
|
|
980
|
+
this.#indexNames.add(index.name);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
887
984
|
return this as unknown as SchemaBuilder<TTables & TNewTables>;
|
|
888
985
|
}
|
|
889
986
|
|
|
@@ -896,7 +993,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
896
993
|
TRelations extends Record<string, AnyRelation>,
|
|
897
994
|
TIndexes extends Record<string, Index> = Record<string, Index>,
|
|
898
995
|
>(
|
|
899
|
-
|
|
996
|
+
name: TTableName,
|
|
900
997
|
callback: (
|
|
901
998
|
builder: TableBuilder<
|
|
902
999
|
Record<string, AnyColumn>,
|
|
@@ -907,10 +1004,22 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
907
1004
|
): SchemaBuilder<TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>> {
|
|
908
1005
|
this.#version++;
|
|
909
1006
|
|
|
910
|
-
|
|
1007
|
+
if (this.#tableNames.has(name)) {
|
|
1008
|
+
throw new Error(`Duplicate table name "${name}" in schema "${this.#name}".`);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
const tableBuilder = new TableBuilder(name);
|
|
911
1012
|
const result = callback(tableBuilder);
|
|
912
1013
|
const builtTable = result.build();
|
|
913
|
-
|
|
1014
|
+
const indexNames = result.getIndexes().map((idx) => idx.name);
|
|
1015
|
+
|
|
1016
|
+
for (const indexName of indexNames) {
|
|
1017
|
+
if (this.#indexNames.has(indexName)) {
|
|
1018
|
+
throw new Error(
|
|
1019
|
+
`Duplicate index name "${indexName}" in schema "${this.#name}". Index names must be unique across tables (conflict on "${name}").`,
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
914
1023
|
|
|
915
1024
|
// Collect sub-operations in order
|
|
916
1025
|
const subOperations: TableSubOperation[] = [];
|
|
@@ -947,7 +1056,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
947
1056
|
subOperations.push({
|
|
948
1057
|
type: "add-index",
|
|
949
1058
|
name: idx.name,
|
|
950
|
-
columns: idx.columns.map((c) => c.
|
|
1059
|
+
columns: idx.columns.map((c) => c.name),
|
|
951
1060
|
unique: idx.unique,
|
|
952
1061
|
});
|
|
953
1062
|
}
|
|
@@ -955,13 +1064,17 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
955
1064
|
// Add the add-table operation
|
|
956
1065
|
this.#operations.push({
|
|
957
1066
|
type: "add-table",
|
|
958
|
-
tableName:
|
|
1067
|
+
tableName: name,
|
|
959
1068
|
operations: subOperations,
|
|
960
1069
|
});
|
|
961
1070
|
|
|
962
1071
|
// Update tables map
|
|
963
|
-
this.#tables = { ...this.#tables, [
|
|
1072
|
+
this.#tables = { ...this.#tables, [name]: builtTable } as TTables &
|
|
964
1073
|
Record<TTableName, Table<TColumns, TRelations, TIndexes>>;
|
|
1074
|
+
this.#tableNames.add(name);
|
|
1075
|
+
for (const indexName of indexNames) {
|
|
1076
|
+
this.#indexNames.add(indexName);
|
|
1077
|
+
}
|
|
965
1078
|
|
|
966
1079
|
return this as unknown as SchemaBuilder<
|
|
967
1080
|
TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>
|
|
@@ -977,7 +1090,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
977
1090
|
* @example
|
|
978
1091
|
* ```ts
|
|
979
1092
|
* // One-to-one or many-to-one: post -> user
|
|
980
|
-
* schema(s => s
|
|
1093
|
+
* schema("blog", s => s
|
|
981
1094
|
* .addTable("users", t => t.addColumn("id", idColumn()))
|
|
982
1095
|
* .addTable("posts", t => t
|
|
983
1096
|
* .addColumn("id", idColumn())
|
|
@@ -1030,6 +1143,10 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1030
1143
|
const table = this.#tables[config.from.table];
|
|
1031
1144
|
const referencedTable = this.#tables[config.to.table];
|
|
1032
1145
|
|
|
1146
|
+
if (!referenceName || referenceName.trim().length === 0) {
|
|
1147
|
+
throw new Error(`referenceName is required for addReference on ${config.from.table}`);
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1033
1150
|
if (!table) {
|
|
1034
1151
|
throw new Error(`Table ${config.from.table} not found in schema`);
|
|
1035
1152
|
}
|
|
@@ -1054,6 +1171,10 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1054
1171
|
throw new Error(`Column ${actualTargetColumnName} not found in table ${config.to.table}`);
|
|
1055
1172
|
}
|
|
1056
1173
|
|
|
1174
|
+
if (table.relations[referenceName]) {
|
|
1175
|
+
throw new Error(`Reference ${referenceName} already exists on table ${config.from.table}`);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1057
1178
|
// Verify that reference columns are bigint (matching internal ID type)
|
|
1058
1179
|
if (column.role === "reference" && column.type !== "bigint") {
|
|
1059
1180
|
throw new Error(
|
|
@@ -1098,7 +1219,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1098
1219
|
* @example
|
|
1099
1220
|
* ```ts
|
|
1100
1221
|
* // Add a new column to an existing table
|
|
1101
|
-
* schema(s => s
|
|
1222
|
+
* schema("blog", s => s
|
|
1102
1223
|
* .addTable("users", t => t
|
|
1103
1224
|
* .addColumn("id", idColumn())
|
|
1104
1225
|
* .addColumn("name", column("string")))
|
|
@@ -1168,10 +1289,15 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1168
1289
|
// Add only new indexes
|
|
1169
1290
|
for (const idx of resultBuilder.getIndexes()) {
|
|
1170
1291
|
if (!existingIndexes.has(idx.name)) {
|
|
1292
|
+
if (this.#indexNames.has(idx.name)) {
|
|
1293
|
+
throw new Error(
|
|
1294
|
+
`Duplicate index name "${idx.name}" in schema "${this.#name}". Index names must be unique across tables (conflict on "${tableName}").`,
|
|
1295
|
+
);
|
|
1296
|
+
}
|
|
1171
1297
|
subOperations.push({
|
|
1172
1298
|
type: "add-index",
|
|
1173
1299
|
name: idx.name,
|
|
1174
|
-
columns: idx.columns.map((c) => c.
|
|
1300
|
+
columns: idx.columns.map((c) => c.name),
|
|
1175
1301
|
unique: idx.unique,
|
|
1176
1302
|
});
|
|
1177
1303
|
}
|
|
@@ -1188,6 +1314,11 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1188
1314
|
|
|
1189
1315
|
// Update table reference in schema
|
|
1190
1316
|
this.#tables[tableName] = newTable as unknown as TTables[TTableName];
|
|
1317
|
+
for (const idx of resultBuilder.getIndexes()) {
|
|
1318
|
+
if (!existingIndexes.has(idx.name)) {
|
|
1319
|
+
this.#indexNames.add(idx.name);
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1191
1322
|
|
|
1192
1323
|
// Set table name for all columns
|
|
1193
1324
|
for (const col of Object.values(newTable.columns)) {
|
|
@@ -1208,6 +1339,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1208
1339
|
const tables = this.#tables;
|
|
1209
1340
|
|
|
1210
1341
|
const schema: Schema<TTables> = {
|
|
1342
|
+
name: this.#name,
|
|
1211
1343
|
version,
|
|
1212
1344
|
tables,
|
|
1213
1345
|
operations,
|
|
@@ -1231,7 +1363,6 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1231
1363
|
}
|
|
1232
1364
|
|
|
1233
1365
|
clonedCol.name = col.name;
|
|
1234
|
-
clonedCol.ormName = col.ormName;
|
|
1235
1366
|
clonedCol.isNullable = col.isNullable;
|
|
1236
1367
|
clonedCol.role = col.role;
|
|
1237
1368
|
clonedCol.isHidden = col.isHidden;
|
|
@@ -1240,20 +1371,28 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1240
1371
|
clonedColumns[colName] = clonedCol;
|
|
1241
1372
|
}
|
|
1242
1373
|
|
|
1243
|
-
|
|
1374
|
+
const clonedTable = {
|
|
1244
1375
|
...v,
|
|
1245
1376
|
columns: clonedColumns,
|
|
1246
|
-
};
|
|
1377
|
+
} as AnyTable;
|
|
1378
|
+
|
|
1379
|
+
clonedTable["~standard"] = createTableStandardSchemaProps(clonedTable, validationClasses);
|
|
1380
|
+
clonedTable.validate = createTableValidator(clonedTable, validationClasses);
|
|
1381
|
+
|
|
1382
|
+
cloneTables[k] = clonedTable;
|
|
1247
1383
|
}
|
|
1248
1384
|
|
|
1249
|
-
|
|
1385
|
+
const clonedSchema: Schema<TTables> = {
|
|
1386
|
+
name: this.#name,
|
|
1250
1387
|
version,
|
|
1251
1388
|
tables: cloneTables as TTables,
|
|
1252
1389
|
operations: [...operations],
|
|
1253
1390
|
clone: () => {
|
|
1254
1391
|
throw new Error("Cannot clone during clone");
|
|
1255
1392
|
},
|
|
1256
|
-
}
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1395
|
+
return new SchemaBuilder<TTables>(this.#name, clonedSchema).build();
|
|
1257
1396
|
},
|
|
1258
1397
|
};
|
|
1259
1398
|
|
|
@@ -1272,19 +1411,18 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
|
|
|
1272
1411
|
* Create a new schema with callback pattern.
|
|
1273
1412
|
*/
|
|
1274
1413
|
export function schema<const TTables extends Record<string, AnyTable> = {}>(
|
|
1414
|
+
name: string,
|
|
1275
1415
|
callback: (builder: SchemaBuilder<{}>) => SchemaBuilder<TTables>,
|
|
1276
1416
|
): Schema<TTables> {
|
|
1277
|
-
return callback(new SchemaBuilder()).build();
|
|
1417
|
+
return callback(new SchemaBuilder(name)).build();
|
|
1278
1418
|
}
|
|
1279
1419
|
|
|
1280
|
-
export function compileForeignKey(key: ForeignKey
|
|
1420
|
+
export function compileForeignKey(key: ForeignKey) {
|
|
1281
1421
|
return {
|
|
1282
1422
|
name: key.name,
|
|
1283
|
-
table:
|
|
1284
|
-
referencedTable:
|
|
1285
|
-
referencedColumns: key.referencedColumns.map((col) =>
|
|
1286
|
-
|
|
1287
|
-
),
|
|
1288
|
-
columns: key.columns.map((col) => (nameType === "sql" ? col.name : col.ormName)),
|
|
1423
|
+
table: key.table.name,
|
|
1424
|
+
referencedTable: key.referencedTable.name,
|
|
1425
|
+
referencedColumns: key.referencedColumns.map((col) => col.name),
|
|
1426
|
+
columns: key.columns.map((col) => col.name),
|
|
1289
1427
|
};
|
|
1290
1428
|
}
|
|
@@ -3,7 +3,7 @@ import { schema, idColumn, FragnoId } from "./create";
|
|
|
3
3
|
import { generateId } from "./generate-id";
|
|
4
4
|
|
|
5
5
|
describe("generateId", () => {
|
|
6
|
-
const testSchema = schema((s) =>
|
|
6
|
+
const testSchema = schema("test", (s) =>
|
|
7
7
|
s.addTable("users", (t) =>
|
|
8
8
|
t.addColumn("id", idColumn()).addColumn("email", "string").addColumn("name", "string"),
|
|
9
9
|
),
|
|
@@ -34,7 +34,7 @@ describe("generateId", () => {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("should work with multiple tables", () => {
|
|
37
|
-
const multiTableSchema = schema((s) =>
|
|
37
|
+
const multiTableSchema = schema("multitable", (s) =>
|
|
38
38
|
s
|
|
39
39
|
.addTable("users", (t) =>
|
|
40
40
|
t.addColumn("id", idColumn()).addColumn("email", "string").addColumn("name", "string"),
|
|
@@ -25,12 +25,12 @@ export function generateId<
|
|
|
25
25
|
const idColumn = tableSchema.getIdColumn();
|
|
26
26
|
const generated = idColumn.generateDefaultValue();
|
|
27
27
|
if (generated === undefined) {
|
|
28
|
-
throw new Error(`ID column ${idColumn.
|
|
28
|
+
throw new Error(`ID column ${idColumn.name} on table ${tableName} has no default generator`);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
if (typeof generated !== "string") {
|
|
32
32
|
throw new Error(
|
|
33
|
-
`ID column ${idColumn.
|
|
33
|
+
`ID column ${idColumn.name} on table ${tableName} has no default generator that generates a string.`,
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -131,7 +131,17 @@ describe("serialize", () => {
|
|
|
131
131
|
it("should convert string timestamps to Date", () => {
|
|
132
132
|
const timestampCol = column("timestamp");
|
|
133
133
|
const time = "2024-01-01 12:30:45.123";
|
|
134
|
-
|
|
134
|
+
const result = deserialize(time, timestampCol, "postgresql");
|
|
135
|
+
assert.instanceOf(result, Date);
|
|
136
|
+
expect(result.toISOString()).toBe("2024-01-01T12:30:45.123Z");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it("should treat timezone-less ISO timestamps as UTC", () => {
|
|
140
|
+
const timestampCol = column("timestamp");
|
|
141
|
+
const time = "2024-01-01T12:30:45.123";
|
|
142
|
+
const result = deserialize(time, timestampCol, "postgresql");
|
|
143
|
+
assert.instanceOf(result, Date);
|
|
144
|
+
expect(result.toISOString()).toBe("2024-01-01T12:30:45.123Z");
|
|
135
145
|
});
|
|
136
146
|
|
|
137
147
|
it("should convert ISO string timestamps to Date", () => {
|
|
@@ -262,7 +272,9 @@ describe("serialize", () => {
|
|
|
262
272
|
it("should convert string timestamps to Date", () => {
|
|
263
273
|
const timestampCol = column("timestamp");
|
|
264
274
|
const time = "2024-01-01 12:30:45.123";
|
|
265
|
-
|
|
275
|
+
const result = deserialize(time, timestampCol, "cockroachdb");
|
|
276
|
+
assert.instanceOf(result, Date);
|
|
277
|
+
expect(result.toISOString()).toBe("2024-01-01T12:30:45.123Z");
|
|
266
278
|
});
|
|
267
279
|
|
|
268
280
|
it("should convert date strings to Date", () => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SupportedDatabase } from "../../adapters/generic-sql/driver-config";
|
|
2
|
+
import type { SQLiteStorageMode } from "../../adapters/generic-sql/sqlite-storage";
|
|
2
3
|
import { PostgreSQLTypeMapper } from "./dialect/postgres";
|
|
3
4
|
import { MySQLTypeMapper } from "./dialect/mysql";
|
|
4
5
|
import { SQLiteTypeMapper } from "./dialect/sqlite";
|
|
@@ -10,16 +11,20 @@ import { SQLiteTypeMapper } from "./dialect/sqlite";
|
|
|
10
11
|
* (PostgreSQL, MySQL, or SQLite).
|
|
11
12
|
*
|
|
12
13
|
* @param database - The database type (sqlite, postgresql, or mysql)
|
|
14
|
+
* @param sqliteStorageMode - Optional SQLite storage mode override
|
|
13
15
|
* @returns Dialect-specific SQLTypeMapper instance
|
|
14
16
|
*/
|
|
15
|
-
export function createSQLTypeMapper(
|
|
17
|
+
export function createSQLTypeMapper(
|
|
18
|
+
database: SupportedDatabase,
|
|
19
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
20
|
+
) {
|
|
16
21
|
switch (database) {
|
|
17
22
|
case "postgresql":
|
|
18
23
|
return new PostgreSQLTypeMapper(database);
|
|
19
24
|
case "mysql":
|
|
20
25
|
return new MySQLTypeMapper(database);
|
|
21
26
|
case "sqlite":
|
|
22
|
-
return new SQLiteTypeMapper(database);
|
|
27
|
+
return new SQLiteTypeMapper(database, sqliteStorageMode);
|
|
23
28
|
default: {
|
|
24
29
|
const exhaustiveCheck: never = database;
|
|
25
30
|
throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AnyColumn } from "../../create";
|
|
2
2
|
import { SQLTypeMapper, type SQLiteDatabaseType } from "../type-mapping";
|
|
3
|
+
import type { SQLiteStorageMode } from "../../../adapters/generic-sql/sqlite-storage";
|
|
4
|
+
import { sqliteStorageDefault } from "../../../adapters/generic-sql/sqlite-storage";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* SQLite-specific type mapper.
|
|
@@ -11,6 +13,13 @@ import { SQLTypeMapper, type SQLiteDatabaseType } from "../type-mapping";
|
|
|
11
13
|
* - REAL for decimals
|
|
12
14
|
*/
|
|
13
15
|
export class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {
|
|
16
|
+
private readonly sqliteStorageMode: SQLiteStorageMode;
|
|
17
|
+
|
|
18
|
+
constructor(database: "sqlite", sqliteStorageMode?: SQLiteStorageMode) {
|
|
19
|
+
super(database);
|
|
20
|
+
this.sqliteStorageMode = sqliteStorageMode ?? sqliteStorageDefault;
|
|
21
|
+
}
|
|
22
|
+
|
|
14
23
|
protected getInternalIdType(): SQLiteDatabaseType {
|
|
15
24
|
// SQLite uses INTEGER for auto-increment (INTEGER PRIMARY KEY)
|
|
16
25
|
return "integer";
|
|
@@ -25,6 +34,9 @@ export class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {
|
|
|
25
34
|
if ("role" in column && column.role === "reference") {
|
|
26
35
|
return "integer";
|
|
27
36
|
}
|
|
37
|
+
if (this.sqliteStorageMode.bigintStorage === "integer") {
|
|
38
|
+
return "integer";
|
|
39
|
+
}
|
|
28
40
|
return "blob";
|
|
29
41
|
}
|
|
30
42
|
|
|
@@ -50,10 +62,16 @@ export class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {
|
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
protected mapTimestamp(): SQLiteDatabaseType {
|
|
65
|
+
if (this.sqliteStorageMode.timestampStorage === "iso-text") {
|
|
66
|
+
return "text";
|
|
67
|
+
}
|
|
53
68
|
return "integer";
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
protected mapDate(): SQLiteDatabaseType {
|
|
72
|
+
if (this.sqliteStorageMode.dateStorage === "iso-text") {
|
|
73
|
+
return "text";
|
|
74
|
+
}
|
|
57
75
|
return "integer";
|
|
58
76
|
}
|
|
59
77
|
|