@fragno-dev/db 0.2.1 → 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 +206 -140
- package/CHANGELOG.md +67 -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 +38 -28
- 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 +45 -96
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +121 -99
- 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 +172 -9
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +193 -74
- 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 +47 -4
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +106 -39
- 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 +17 -10
- 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 +351 -100
- 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 +440 -267
- 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 +67 -22
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +110 -13
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +8 -5
- 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 +40 -14
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +82 -42
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/generate-id.d.ts +20 -0
- package/dist/schema/generate-id.d.ts.map +1 -0
- package/dist/schema/generate-id.js +28 -0
- package/dist/schema/generate-id.js.map +1 -0
- 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} +49 -35
- package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +48 -32
- 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 +88 -54
- package/src/db-fragment-definition-builder.ts +201 -322
- package/src/db-fragment-instantiator.test.ts +169 -101
- package/src/db-fragment-integration.test.ts +301 -149
- 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 +730 -274
- package/src/fragments/internal-fragment.ts +447 -154
- 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 +411 -259
- package/src/hooks/hooks.ts +265 -66
- 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 +78 -30
- 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 +1512 -1458
- package/src/query/unit-of-work/execute-unit-of-work.ts +1708 -596
- package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +32 -32
- 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 +231 -36
- package/src/query/unit-of-work/unit-of-work.ts +229 -31
- 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 +187 -47
- package/src/schema/generate-id.test.ts +57 -0
- package/src/schema/generate-id.ts +38 -0
- 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/shared/config.ts +0 -10
- package/src/shared/connection-pool.ts +0 -24
- package/src/shared/prisma.ts +0 -45
package/src/hooks/hooks.ts
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ExecuteTxOptions,
|
|
3
|
+
HandlerTxBuilder,
|
|
4
|
+
} from "../query/unit-of-work/execute-unit-of-work";
|
|
1
5
|
import type { RetryPolicy } from "../query/unit-of-work/retry-policy";
|
|
2
6
|
import { ExponentialBackoffRetryPolicy } from "../query/unit-of-work/retry-policy";
|
|
3
7
|
import type { IUnitOfWork } from "../query/unit-of-work/unit-of-work";
|
|
4
8
|
import type { InternalFragmentInstance } from "../fragments/internal-fragment";
|
|
9
|
+
import type { TxResult } from "../query/unit-of-work/execute-unit-of-work";
|
|
10
|
+
import type { FragnoId } from "../schema/create";
|
|
5
11
|
|
|
6
12
|
/**
|
|
7
13
|
* Context available in hook functions via `this`.
|
|
8
|
-
* Contains the
|
|
14
|
+
* Contains the idempotency key for idempotency and database access.
|
|
9
15
|
*/
|
|
10
16
|
export interface HookContext {
|
|
11
17
|
/**
|
|
12
|
-
* Unique
|
|
18
|
+
* Unique idempotency key for this transaction.
|
|
13
19
|
* Use this for idempotency checks in your hook implementation.
|
|
14
20
|
*/
|
|
15
|
-
|
|
21
|
+
idempotencyKey: string;
|
|
22
|
+
/**
|
|
23
|
+
* Create a handler transaction builder to run atomic operations.
|
|
24
|
+
*/
|
|
25
|
+
handlerTx: HookHandlerTx;
|
|
16
26
|
}
|
|
17
27
|
|
|
18
28
|
/**
|
|
@@ -42,6 +52,11 @@ export interface TriggerHookOptions {
|
|
|
42
52
|
* If not provided, uses the default retry policy.
|
|
43
53
|
*/
|
|
44
54
|
retryPolicy?: RetryPolicy;
|
|
55
|
+
/**
|
|
56
|
+
* Absolute time for the first attempt. If in the future, the hook is
|
|
57
|
+
* scheduled for that time; if in the past, it runs immediately.
|
|
58
|
+
*/
|
|
59
|
+
processAt?: Date;
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
/**
|
|
@@ -54,14 +69,88 @@ export interface TriggeredHook {
|
|
|
54
69
|
options?: TriggerHookOptions;
|
|
55
70
|
}
|
|
56
71
|
|
|
72
|
+
export type HookScheduler = {
|
|
73
|
+
schedule: () => Promise<number>;
|
|
74
|
+
drain: () => Promise<void>;
|
|
75
|
+
};
|
|
76
|
+
|
|
57
77
|
/**
|
|
58
78
|
* Configuration for hook processing.
|
|
59
79
|
*/
|
|
60
|
-
export interface HookProcessorConfig {
|
|
61
|
-
hooks:
|
|
80
|
+
export interface HookProcessorConfig<THooks extends HooksMap = HooksMap> {
|
|
81
|
+
hooks: THooks;
|
|
62
82
|
namespace: string;
|
|
63
83
|
internalFragment: InternalFragmentInstance;
|
|
84
|
+
handlerTx: HookHandlerTx;
|
|
85
|
+
/**
|
|
86
|
+
* Internal hook scheduler used to coordinate processing/drain.
|
|
87
|
+
*/
|
|
88
|
+
scheduler?: HookScheduler;
|
|
64
89
|
defaultRetryPolicy?: RetryPolicy;
|
|
90
|
+
/**
|
|
91
|
+
* Re-queue hooks that have been in `processing` for at least this many minutes.
|
|
92
|
+
* Use `false` to disable stuck-processing recovery entirely.
|
|
93
|
+
* Values <= 0 are treated as `false`.
|
|
94
|
+
*
|
|
95
|
+
* Default: 10 minutes.
|
|
96
|
+
*/
|
|
97
|
+
stuckProcessingTimeoutMinutes?: StuckHookProcessingTimeoutMinutes;
|
|
98
|
+
/**
|
|
99
|
+
* Called when stuck processing hooks are detected and re-queued.
|
|
100
|
+
* Invoked after the hooks are moved back to `pending`.
|
|
101
|
+
*/
|
|
102
|
+
onStuckProcessingHooks?: (info: StuckHookProcessingInfo) => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type StuckHookProcessingTimeoutMinutes = number | false;
|
|
106
|
+
|
|
107
|
+
export type StuckHookProcessingEvent = {
|
|
108
|
+
id: FragnoId;
|
|
109
|
+
hookName: string;
|
|
110
|
+
attempts: number;
|
|
111
|
+
maxAttempts: number;
|
|
112
|
+
lastAttemptAt: Date | null;
|
|
113
|
+
nextRetryAt: Date | null;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type StuckHookProcessingInfo = {
|
|
117
|
+
namespace: string;
|
|
118
|
+
timeoutMinutes: number;
|
|
119
|
+
events: StuckHookProcessingEvent[];
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type DurableHooksProcessingOptions = {
|
|
123
|
+
/**
|
|
124
|
+
* Re-queue hooks that have been in `processing` for at least this many minutes.
|
|
125
|
+
* Use `false` to disable stuck-processing recovery entirely.
|
|
126
|
+
* Values <= 0 are treated as `false`.
|
|
127
|
+
*
|
|
128
|
+
* Default: 10 minutes.
|
|
129
|
+
*/
|
|
130
|
+
stuckProcessingTimeoutMinutes?: StuckHookProcessingTimeoutMinutes;
|
|
131
|
+
/**
|
|
132
|
+
* Called when stuck processing hooks are detected and re-queued.
|
|
133
|
+
* Invoked after the hooks are moved back to `pending`.
|
|
134
|
+
*/
|
|
135
|
+
onStuckProcessingHooks?: (info: StuckHookProcessingInfo) => void;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export type HookHandlerTx = (
|
|
139
|
+
execOptions?: Omit<ExecuteTxOptions, "createUnitOfWork">,
|
|
140
|
+
) => HandlerTxBuilder<readonly [], [], [], unknown, unknown, false, false, false, false, HooksMap>;
|
|
141
|
+
|
|
142
|
+
const DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES = 10;
|
|
143
|
+
|
|
144
|
+
function resolveStuckProcessingTimeoutMinutes(
|
|
145
|
+
value: StuckHookProcessingTimeoutMinutes | undefined,
|
|
146
|
+
): number | false {
|
|
147
|
+
if (value === false) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (typeof value === "number") {
|
|
151
|
+
return value > 0 ? value : false;
|
|
152
|
+
}
|
|
153
|
+
return DEFAULT_STUCK_PROCESSING_TIMEOUT_MINUTES;
|
|
65
154
|
}
|
|
66
155
|
|
|
67
156
|
/**
|
|
@@ -69,7 +158,10 @@ export interface HookProcessorConfig {
|
|
|
69
158
|
* This should be called before executeMutations() so hook records are created
|
|
70
159
|
* in the same transaction as the user's mutations.
|
|
71
160
|
*/
|
|
72
|
-
export function prepareHookMutations
|
|
161
|
+
export function prepareHookMutations<THooks extends HooksMap>(
|
|
162
|
+
uow: IUnitOfWork,
|
|
163
|
+
config: HookProcessorConfig<THooks>,
|
|
164
|
+
): void {
|
|
73
165
|
const { namespace, internalFragment, defaultRetryPolicy } = config;
|
|
74
166
|
const retryPolicy = defaultRetryPolicy ?? new ExponentialBackoffRetryPolicy({ maxRetries: 5 });
|
|
75
167
|
|
|
@@ -85,6 +177,8 @@ export function prepareHookMutations(uow: IUnitOfWork, config: HookProcessorConf
|
|
|
85
177
|
for (const hook of triggeredHooks) {
|
|
86
178
|
const hookRetryPolicy = hook.options?.retryPolicy ?? retryPolicy;
|
|
87
179
|
const maxAttempts = hookRetryPolicy.shouldRetry(4) ? 5 : 1;
|
|
180
|
+
const processAt = hook.options?.processAt ? new Date(hook.options.processAt) : null;
|
|
181
|
+
const nextRetryAt = processAt ?? null;
|
|
88
182
|
internalUow.create("fragno_hooks", {
|
|
89
183
|
namespace,
|
|
90
184
|
hookName: hook.hookName,
|
|
@@ -93,9 +187,9 @@ export function prepareHookMutations(uow: IUnitOfWork, config: HookProcessorConf
|
|
|
93
187
|
attempts: 0,
|
|
94
188
|
maxAttempts,
|
|
95
189
|
lastAttemptAt: null,
|
|
96
|
-
nextRetryAt
|
|
190
|
+
nextRetryAt,
|
|
97
191
|
error: null,
|
|
98
|
-
nonce: uow.
|
|
192
|
+
nonce: uow.idempotencyKey,
|
|
99
193
|
});
|
|
100
194
|
}
|
|
101
195
|
}
|
|
@@ -104,76 +198,181 @@ export function prepareHookMutations(uow: IUnitOfWork, config: HookProcessorConf
|
|
|
104
198
|
* Process pending hook events after the transaction has committed.
|
|
105
199
|
* This should be called in the onSuccess callback after executeMutations().
|
|
106
200
|
*/
|
|
107
|
-
export async function processHooks
|
|
201
|
+
export async function processHooks<THooks extends HooksMap>(
|
|
202
|
+
config: HookProcessorConfig<THooks>,
|
|
203
|
+
): Promise<number> {
|
|
108
204
|
const { hooks, namespace, internalFragment, defaultRetryPolicy } = config;
|
|
109
205
|
const retryPolicy = defaultRetryPolicy ?? new ExponentialBackoffRetryPolicy({ maxRetries: 5 });
|
|
206
|
+
const stuckProcessingTimeoutMinutes = resolveStuckProcessingTimeoutMinutes(
|
|
207
|
+
config.stuckProcessingTimeoutMinutes,
|
|
208
|
+
);
|
|
209
|
+
const getDbNow = async () => {
|
|
210
|
+
const services = internalFragment.services as { getDbNow?: () => Promise<Date> };
|
|
211
|
+
if (services.getDbNow) {
|
|
212
|
+
return services.getDbNow();
|
|
213
|
+
}
|
|
214
|
+
return new Date();
|
|
215
|
+
};
|
|
216
|
+
const dbNow = await getDbNow();
|
|
110
217
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
218
|
+
if (stuckProcessingTimeoutMinutes !== false) {
|
|
219
|
+
const staleBefore = new Date(dbNow.getTime() - stuckProcessingTimeoutMinutes * 60_000);
|
|
220
|
+
const stuckEvents = await internalFragment.inContext(async function () {
|
|
221
|
+
return await this.handlerTx()
|
|
222
|
+
.withServiceCalls(
|
|
223
|
+
() =>
|
|
224
|
+
[
|
|
225
|
+
internalFragment.services.hookService.requeueStuckProcessingHooks(
|
|
226
|
+
namespace,
|
|
227
|
+
staleBefore,
|
|
228
|
+
),
|
|
229
|
+
] as const,
|
|
230
|
+
)
|
|
231
|
+
.transform(({ serviceResult: [events] }) => events)
|
|
232
|
+
.execute();
|
|
233
|
+
});
|
|
116
234
|
|
|
117
|
-
|
|
235
|
+
if (stuckEvents.length > 0) {
|
|
236
|
+
try {
|
|
237
|
+
config.onStuckProcessingHooks?.({
|
|
238
|
+
namespace,
|
|
239
|
+
timeoutMinutes: stuckProcessingTimeoutMinutes,
|
|
240
|
+
events: stuckEvents,
|
|
241
|
+
});
|
|
242
|
+
} catch (error) {
|
|
243
|
+
console.error("Error calling onStuckProcessingHooks", error);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
118
247
|
|
|
119
|
-
|
|
120
|
-
|
|
248
|
+
// Claim pending events in the same transaction to avoid double-processing.
|
|
249
|
+
const pendingEvents = await internalFragment.inContext(async function () {
|
|
250
|
+
return await this.handlerTx()
|
|
251
|
+
.withServiceCalls(
|
|
252
|
+
() => [internalFragment.services.hookService.claimPendingHookEvents(namespace)] as const,
|
|
253
|
+
)
|
|
254
|
+
.transform(({ serviceResult: [events] }) => events)
|
|
255
|
+
.execute();
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
if (pendingEvents.length === 0) {
|
|
259
|
+
return 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Process events (async work outside transaction)
|
|
263
|
+
const processedEvents = await Promise.allSettled(
|
|
264
|
+
pendingEvents.map(async (event) => {
|
|
265
|
+
const hookFn = hooks[event.hookName];
|
|
266
|
+
if (!hookFn) {
|
|
267
|
+
return {
|
|
268
|
+
eventId: event.id,
|
|
269
|
+
status: "failed" as const,
|
|
270
|
+
error: `Hook '${event.hookName}' not found in hooks map`,
|
|
271
|
+
attempts: event.attempts,
|
|
272
|
+
maxAttempts: event.maxAttempts,
|
|
273
|
+
};
|
|
121
274
|
}
|
|
122
275
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
276
|
+
try {
|
|
277
|
+
const hookContext: HookContext = {
|
|
278
|
+
idempotencyKey: event.idempotencyKey,
|
|
279
|
+
handlerTx: config.handlerTx,
|
|
280
|
+
};
|
|
281
|
+
await hookFn.call(hookContext, event.payload);
|
|
282
|
+
return {
|
|
283
|
+
eventId: event.id,
|
|
284
|
+
status: "completed" as const,
|
|
285
|
+
};
|
|
286
|
+
} catch (error) {
|
|
287
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
288
|
+
return {
|
|
289
|
+
eventId: event.id,
|
|
290
|
+
status: "failed" as const,
|
|
291
|
+
error: errorMessage,
|
|
292
|
+
attempts: event.attempts,
|
|
293
|
+
maxAttempts: event.maxAttempts,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
}),
|
|
297
|
+
);
|
|
135
298
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
145
|
-
return {
|
|
146
|
-
eventId: event.id,
|
|
147
|
-
status: "failed" as const,
|
|
148
|
-
error: errorMessage,
|
|
149
|
-
attempts: event.attempts,
|
|
150
|
-
maxAttempts: event.maxAttempts,
|
|
151
|
-
};
|
|
299
|
+
// Mark events as completed/failed
|
|
300
|
+
await internalFragment.inContext(async function () {
|
|
301
|
+
await this.handlerTx()
|
|
302
|
+
.withServiceCalls(() => {
|
|
303
|
+
const txResults: TxResult<void>[] = [];
|
|
304
|
+
for (const processedEvent of processedEvents) {
|
|
305
|
+
if (processedEvent.status === "rejected") {
|
|
306
|
+
continue;
|
|
152
307
|
}
|
|
153
|
-
}),
|
|
154
|
-
);
|
|
155
308
|
|
|
156
|
-
|
|
157
|
-
if (processedEvent.status === "rejected") {
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
309
|
+
const { eventId, status } = processedEvent.value;
|
|
160
310
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
311
|
+
if (status === "completed") {
|
|
312
|
+
txResults.push(internalFragment.services.hookService.markHookCompleted(eventId));
|
|
313
|
+
} else if (status === "failed") {
|
|
314
|
+
const { error, attempts } = processedEvent.value;
|
|
315
|
+
txResults.push(
|
|
316
|
+
internalFragment.services.hookService.markHookFailed(
|
|
317
|
+
eventId,
|
|
318
|
+
error,
|
|
319
|
+
attempts,
|
|
320
|
+
retryPolicy,
|
|
321
|
+
dbNow,
|
|
322
|
+
),
|
|
323
|
+
);
|
|
324
|
+
}
|
|
173
325
|
}
|
|
326
|
+
return txResults;
|
|
327
|
+
})
|
|
328
|
+
.execute();
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
const processedCount = processedEvents.reduce(
|
|
332
|
+
(count, result) => count + (result.status === "fulfilled" ? 1 : 0),
|
|
333
|
+
0,
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
return processedCount;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export function createHookScheduler(config: HookProcessorConfig): HookScheduler {
|
|
340
|
+
let processing = false;
|
|
341
|
+
let queued = false;
|
|
342
|
+
let currentPromise: Promise<number> | null = null;
|
|
343
|
+
|
|
344
|
+
const schedule = async () => {
|
|
345
|
+
if (processing) {
|
|
346
|
+
queued = true;
|
|
347
|
+
return currentPromise ?? Promise.resolve(0);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
processing = true;
|
|
351
|
+
currentPromise = (async () => {
|
|
352
|
+
let lastCount = 0;
|
|
353
|
+
try {
|
|
354
|
+
do {
|
|
355
|
+
queued = false;
|
|
356
|
+
lastCount = await processHooks(config);
|
|
357
|
+
} while (queued);
|
|
358
|
+
return lastCount;
|
|
359
|
+
} finally {
|
|
360
|
+
processing = false;
|
|
361
|
+
queued = false;
|
|
174
362
|
}
|
|
363
|
+
})();
|
|
175
364
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
365
|
+
return currentPromise;
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
const drain = async () => {
|
|
369
|
+
while (true) {
|
|
370
|
+
const processed = await schedule();
|
|
371
|
+
if (processed === 0) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
return { schedule, drain };
|
|
179
378
|
}
|
|
@@ -4,7 +4,7 @@ import { generateMigrationFromSchema } from "./auto-from-schema";
|
|
|
4
4
|
|
|
5
5
|
describe("generateMigrationFromSchema", () => {
|
|
6
6
|
it("should generate create-table operation for new tables", () => {
|
|
7
|
-
const mySchema = schema((s) => {
|
|
7
|
+
const mySchema = schema("my", (s) => {
|
|
8
8
|
return s
|
|
9
9
|
.addTable("users", (t) => {
|
|
10
10
|
return t.addColumn("id", idColumn()).addColumn("name", column("string"));
|
|
@@ -35,7 +35,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
it("should generate multiple table operations in sequence", () => {
|
|
38
|
-
const mySchema = schema((s) => {
|
|
38
|
+
const mySchema = schema("my", (s) => {
|
|
39
39
|
return s
|
|
40
40
|
.addTable("users", (t) => {
|
|
41
41
|
return t.addColumn("id", idColumn()).addColumn("name", column("string"));
|
|
@@ -79,7 +79,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
it("should generate add-foreign-key operation for new foreign keys", () => {
|
|
82
|
-
const mySchema = schema((s) => {
|
|
82
|
+
const mySchema = schema("my", (s) => {
|
|
83
83
|
return s
|
|
84
84
|
.addTable("users", (t) => {
|
|
85
85
|
return t.addColumn("id", idColumn());
|
|
@@ -108,7 +108,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
108
108
|
const fkOp = operations[0];
|
|
109
109
|
if (fkOp.type === "add-foreign-key") {
|
|
110
110
|
expect(fkOp.value).toMatchObject({
|
|
111
|
-
name: "
|
|
111
|
+
name: "author",
|
|
112
112
|
referencedTable: "users",
|
|
113
113
|
columns: ["authorId"],
|
|
114
114
|
referencedColumns: ["_internalId"],
|
|
@@ -117,7 +117,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
it("should generate add-index operation for indexes added via alterTable", () => {
|
|
120
|
-
const mySchema = schema((s) => {
|
|
120
|
+
const mySchema = schema("my", (s) => {
|
|
121
121
|
return s
|
|
122
122
|
.addTable("users", (t) => {
|
|
123
123
|
return t.addColumn("id", idColumn()).addColumn("email", column("string"));
|
|
@@ -141,7 +141,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
it("should generate mixed operations for tables and foreign keys", () => {
|
|
144
|
-
const mySchema = schema((s) => {
|
|
144
|
+
const mySchema = schema("my", (s) => {
|
|
145
145
|
return s
|
|
146
146
|
.addTable("users", (t) => {
|
|
147
147
|
return t.addColumn("id", idColumn()).addColumn("name", column("string"));
|
|
@@ -166,7 +166,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
it("should generate mixed operations for tables, indexes, and foreign keys", () => {
|
|
169
|
-
const mySchema = schema((s) => {
|
|
169
|
+
const mySchema = schema("my", (s) => {
|
|
170
170
|
return s
|
|
171
171
|
.addTable("users", (t) => {
|
|
172
172
|
return t.addColumn("id", idColumn()).addColumn("email", column("string"));
|
|
@@ -195,7 +195,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
195
195
|
});
|
|
196
196
|
|
|
197
197
|
it("should generate no operations when version range is empty", () => {
|
|
198
|
-
const mySchema = schema((s) => {
|
|
198
|
+
const mySchema = schema("my", (s) => {
|
|
199
199
|
return s.addTable("users", (t) => {
|
|
200
200
|
return t.addColumn("id", idColumn()).addColumn("name", column("string"));
|
|
201
201
|
});
|
|
@@ -207,7 +207,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
207
207
|
});
|
|
208
208
|
|
|
209
209
|
it("should throw error when fromVersion exceeds schema version", () => {
|
|
210
|
-
const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
210
|
+
const mySchema = schema("my", (s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
211
211
|
|
|
212
212
|
expect(() => {
|
|
213
213
|
generateMigrationFromSchema(mySchema, 999, 1000);
|
|
@@ -215,7 +215,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
215
215
|
});
|
|
216
216
|
|
|
217
217
|
it("should throw error when toVersion exceeds schema version", () => {
|
|
218
|
-
const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
218
|
+
const mySchema = schema("my", (s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
219
219
|
|
|
220
220
|
expect(() => {
|
|
221
221
|
generateMigrationFromSchema(mySchema, 0, 999);
|
|
@@ -223,7 +223,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
223
223
|
});
|
|
224
224
|
|
|
225
225
|
it("should throw error when trying to migrate backwards", () => {
|
|
226
|
-
const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
226
|
+
const mySchema = schema("my", (s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
227
227
|
|
|
228
228
|
expect(() => {
|
|
229
229
|
generateMigrationFromSchema(mySchema, 1, 0);
|
|
@@ -231,7 +231,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
231
231
|
});
|
|
232
232
|
|
|
233
233
|
it("should throw error for negative fromVersion", () => {
|
|
234
|
-
const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
234
|
+
const mySchema = schema("my", (s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
|
|
235
235
|
|
|
236
236
|
expect(() => {
|
|
237
237
|
generateMigrationFromSchema(mySchema, -1, 1);
|
|
@@ -239,7 +239,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
239
239
|
});
|
|
240
240
|
|
|
241
241
|
it("should only create constraints for references, not for referenceColumns", () => {
|
|
242
|
-
const mySchema = schema((s) => {
|
|
242
|
+
const mySchema = schema("my", (s) => {
|
|
243
243
|
return s
|
|
244
244
|
.addTable("posts", (t) => {
|
|
245
245
|
return t
|
|
@@ -276,7 +276,7 @@ describe("generateMigrationFromSchema", () => {
|
|
|
276
276
|
});
|
|
277
277
|
|
|
278
278
|
it("should not create duplicate foreign key constraints", () => {
|
|
279
|
-
const mySchema = schema((s) => {
|
|
279
|
+
const mySchema = schema("my", (s) => {
|
|
280
280
|
return s
|
|
281
281
|
.addTable("users", (t) => t.addColumn("id", idColumn()))
|
|
282
282
|
.addTable("posts", (t) =>
|
|
@@ -16,7 +16,7 @@ import type { MigrationOperation, ColumnInfo } from "./shared";
|
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* ```ts
|
|
19
|
-
* const mySchema = schema(s => s
|
|
19
|
+
* const mySchema = schema("my", s => s
|
|
20
20
|
* .addTable("users", t => t.addColumn("id", idColumn())) // version 1
|
|
21
21
|
* .addTable("posts", t => t.addColumn("id", idColumn())) // version 2
|
|
22
22
|
* );
|
|
@@ -156,11 +156,14 @@ export function generateMigrationFromSchema(
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
} else if (op.type === "add-reference") {
|
|
159
|
+
if (!op.referenceName || op.referenceName.trim().length === 0) {
|
|
160
|
+
throw new Error(`referenceName is required for add-reference on ${op.tableName}`);
|
|
161
|
+
}
|
|
159
162
|
migrationOperations.push({
|
|
160
163
|
type: "add-foreign-key",
|
|
161
164
|
table: op.tableName,
|
|
162
165
|
value: {
|
|
163
|
-
name:
|
|
166
|
+
name: op.referenceName,
|
|
164
167
|
columns: [op.config.from.column],
|
|
165
168
|
referencedTable: op.config.to.table,
|
|
166
169
|
referencedColumns: [op.config.to.column],
|
|
@@ -4,7 +4,7 @@ import { schema, idColumn, column, referenceColumn } from "../schema/create";
|
|
|
4
4
|
import type { MigrationOperation } from "./shared";
|
|
5
5
|
|
|
6
6
|
describe("createMigrator", () => {
|
|
7
|
-
const testSchema = schema((s) => {
|
|
7
|
+
const testSchema = schema("test", (s) => {
|
|
8
8
|
return s
|
|
9
9
|
.addTable("users", (t) => {
|
|
10
10
|
return t.addColumn("id", idColumn()).addColumn("name", column("string"));
|
|
@@ -296,7 +296,7 @@ describe("createMigrator", () => {
|
|
|
296
296
|
|
|
297
297
|
describe("with foreign keys", () => {
|
|
298
298
|
it("should handle schema with foreign keys", async () => {
|
|
299
|
-
const fkSchema = schema((s) => {
|
|
299
|
+
const fkSchema = schema("fk", (s) => {
|
|
300
300
|
return s
|
|
301
301
|
.addTable("users", (t) => {
|
|
302
302
|
return t.addColumn("id", idColumn());
|