@fragno-dev/db 0.2.2 → 0.4.1
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 +404 -175
- package/CHANGELOG.md +109 -0
- package/README.md +54 -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 +24 -9
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.js +60 -22
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +169 -3
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
- package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +25 -6
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +7 -6
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +193 -16
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
- package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
- package/dist/adapters/generic-sql/migration/executor.js +30 -3
- package/dist/adapters/generic-sql/migration/executor.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 +9 -9
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
- package/dist/adapters/generic-sql/migration/sql-generator.js +75 -52
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +7 -6
- 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/db-now-sql.js +27 -0
- package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +32 -21
- 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 +49 -18
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/where-builder.js +43 -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 +6 -2
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
- package/dist/adapters/generic-sql/uow-encoder.js +27 -8
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
- package/dist/adapters/in-memory/condition-evaluator.js +135 -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 +196 -0
- package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-uow.js +871 -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 +30 -0
- package/dist/adapters/in-memory/options.d.ts.map +1 -0
- package/dist/adapters/in-memory/options.js +62 -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 +51 -24
- 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/browser/adapters/adapters.d.ts +61 -0
- package/dist/browser/adapters/adapters.d.ts.map +1 -0
- package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
- package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
- package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
- package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
- package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
- package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
- package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
- package/dist/browser/adapters/in-memory/index.d.ts +2 -0
- package/dist/browser/adapters/in-memory/options.d.ts +1 -0
- package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
- package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
- package/dist/browser/durable-hooks.d.ts +3 -0
- package/dist/browser/fragments/internal-fragment.d.ts +317 -0
- package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
- package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
- package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
- package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
- package/dist/browser/hooks/hooks.d.ts +146 -0
- package/dist/browser/hooks/hooks.d.ts.map +1 -0
- package/dist/browser/id.js +1 -0
- package/dist/browser/internal/adapter-registry.d.ts +4 -0
- package/dist/browser/internal/outbox-state.d.ts +2 -0
- package/dist/browser/mod.d.ts +15 -0
- package/dist/browser/mod.d.ts.map +1 -0
- package/dist/browser/mod.js +17 -0
- package/dist/browser/mod.js.map +1 -0
- package/dist/browser/mod2.d.ts +48 -0
- package/dist/browser/mod2.d.ts.map +1 -0
- package/dist/browser/naming/sql-naming.d.ts +19 -0
- package/dist/browser/naming/sql-naming.d.ts.map +1 -0
- package/dist/browser/outbox/outbox.d.ts +21 -0
- package/dist/browser/outbox/outbox.d.ts.map +1 -0
- package/dist/browser/query/column-defaults.js +1 -0
- package/dist/browser/query/condition-builder.d.ts +44 -0
- package/dist/browser/query/condition-builder.d.ts.map +1 -0
- package/dist/browser/query/condition-builder.js +97 -0
- package/dist/browser/query/condition-builder.js.map +1 -0
- package/dist/browser/query/cursor.d.ts +105 -0
- package/dist/browser/query/cursor.d.ts.map +1 -0
- package/dist/browser/query/cursor.js +150 -0
- package/dist/browser/query/cursor.js.map +1 -0
- package/dist/browser/query/db-now.d.ts +22 -0
- package/dist/browser/query/db-now.d.ts.map +1 -0
- package/dist/browser/query/db-now.js +33 -0
- package/dist/browser/query/db-now.js.map +1 -0
- package/dist/browser/query/orm/orm.d.ts +18 -0
- package/dist/browser/query/orm/orm.d.ts.map +1 -0
- package/dist/browser/query/simple-query-interface.d.ts +108 -0
- package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
- package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
- package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
- package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
- package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
- package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
- package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
- package/dist/browser/query/value-encoding.js +38 -0
- package/dist/browser/query/value-encoding.js.map +1 -0
- package/dist/browser/schema/create.d.ts +326 -0
- package/dist/browser/schema/create.d.ts.map +1 -0
- package/dist/browser/schema/create.js +89 -0
- package/dist/browser/schema/create.js.map +1 -0
- package/dist/browser/schema/generate-id.js +28 -0
- package/dist/browser/schema/generate-id.js.map +1 -0
- package/dist/browser/shared/providers.d.ts +6 -0
- package/dist/browser/shared/providers.d.ts.map +1 -0
- package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
- package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
- package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
- package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
- package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
- package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
- package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
- package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
- package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
- package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
- package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
- package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
- package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
- package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
- package/dist/browser/sync/commands.d.ts +15 -0
- package/dist/browser/sync/commands.d.ts.map +1 -0
- package/dist/browser/sync/commands.js +27 -0
- package/dist/browser/sync/commands.js.map +1 -0
- package/dist/browser/sync/types.d.ts +63 -0
- package/dist/browser/sync/types.d.ts.map +1 -0
- package/dist/browser/util/types.d.ts +8 -0
- package/dist/browser/util/types.d.ts.map +1 -0
- package/dist/browser/with-database.d.ts +29 -0
- package/dist/browser/with-database.d.ts.map +1 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.js +5 -0
- package/dist/db-fragment-definition-builder.d.ts +101 -33
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +450 -60
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
- package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
- package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
- package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
- package/dist/dispatchers/cloudflare-do/index.d.ts +11 -0
- package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
- package/dist/dispatchers/cloudflare-do/index.js +31 -0
- package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
- package/dist/dispatchers/node/dispatcher.d.ts +14 -0
- package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
- package/dist/dispatchers/node/dispatcher.js +80 -0
- package/dist/dispatchers/node/dispatcher.js.map +1 -0
- package/dist/dispatchers/node/index.d.ts +12 -0
- package/dist/dispatchers/node/index.d.ts.map +1 -0
- package/dist/dispatchers/node/index.js +27 -0
- package/dist/dispatchers/node/index.js.map +1 -0
- package/dist/durable-hooks.d.ts +31 -0
- package/dist/durable-hooks.d.ts.map +1 -0
- package/dist/durable-hooks.js +23 -0
- package/dist/durable-hooks.js.map +1 -0
- package/dist/fragments/internal-fragment.d.ts +186 -8
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +203 -38
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/fragments/internal-fragment.routes.js +164 -0
- package/dist/fragments/internal-fragment.routes.js.map +1 -0
- package/dist/fragments/internal-fragment.schema.d.ts +15 -0
- package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
- package/dist/fragments/internal-fragment.schema.js +39 -0
- package/dist/fragments/internal-fragment.schema.js.map +1 -0
- package/dist/hooks/durable-hooks-logger.d.ts +10 -0
- package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
- package/dist/hooks/durable-hooks-logger.js +75 -0
- package/dist/hooks/durable-hooks-logger.js.map +1 -0
- package/dist/hooks/durable-hooks-processor.d.ts +1 -0
- package/dist/hooks/durable-hooks-processor.js +80 -0
- package/dist/hooks/durable-hooks-processor.js.map +1 -0
- package/dist/hooks/durable-hooks-runtime.js +44 -0
- package/dist/hooks/durable-hooks-runtime.js.map +1 -0
- package/dist/hooks/hooks.d.ts +100 -1
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +254 -27
- package/dist/hooks/hooks.js.map +1 -1
- package/dist/id.d.ts +2 -2
- package/dist/id.js +2 -2
- package/dist/internal/adapter-registry.d.ts +11 -0
- package/dist/internal/adapter-registry.d.ts.map +1 -0
- package/dist/internal/adapter-registry.js +135 -0
- package/dist/internal/adapter-registry.js.map +1 -0
- package/dist/internal/outbox-state.d.ts +2 -0
- package/dist/internal/outbox-state.js +26 -0
- package/dist/internal/outbox-state.js.map +1 -0
- package/dist/migration-engine/auto-from-schema.d.ts +33 -0
- package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
- package/dist/migration-engine/auto-from-schema.js +223 -37
- 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 +86 -35
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/migration-engine/shared.d.ts +113 -0
- package/dist/migration-engine/shared.d.ts.map +1 -0
- package/dist/migration-engine/shared.js.map +1 -1
- package/dist/mod.d.ts +20 -12
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +18 -12
- 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/outbox/outbox-builder.js +156 -0
- package/dist/outbox/outbox-builder.js.map +1 -0
- package/dist/outbox/outbox.d.ts +54 -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/query/column-defaults.js +20 -4
- package/dist/query/column-defaults.js.map +1 -1
- package/dist/query/condition-builder.d.ts +7 -1
- package/dist/query/condition-builder.d.ts.map +1 -1
- package/dist/query/condition-builder.js +5 -1
- package/dist/query/condition-builder.js.map +1 -1
- package/dist/query/cursor-client.d.ts +105 -0
- package/dist/query/cursor-client.d.ts.map +1 -0
- package/dist/query/cursor-client.js +165 -0
- package/dist/query/cursor-client.js.map +1 -0
- package/dist/query/cursor.d.ts +3 -1
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +51 -14
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/db-now.d.ts +22 -0
- package/dist/query/db-now.d.ts.map +1 -0
- package/dist/query/db-now.js +35 -0
- package/dist/query/db-now.js.map +1 -0
- package/dist/query/orm/orm.js.map +1 -1
- package/dist/query/serialize/create-sql-serializer.js +5 -4
- 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 +60 -12
- 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 +13 -4
- package/dist/query/simple-query-interface.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
- 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 +50 -24
- 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 +92 -30
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +136 -11
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +16 -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 +103 -35
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +172 -58
- 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 +4 -3
- 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} +88 -60
- 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 +307 -0
- package/dist/schema-output/prisma.js.map +1 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
- package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
- package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
- package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
- package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
- package/dist/sql-driver/sql.js.map +1 -1
- package/dist/sync/commands.d.ts +15 -0
- package/dist/sync/commands.d.ts.map +1 -0
- package/dist/sync/commands.js +27 -0
- package/dist/sync/commands.js.map +1 -0
- package/dist/sync/index.d.ts +4 -0
- package/dist/sync/index.js +4 -0
- package/dist/sync/read-tracking.d.ts +25 -0
- package/dist/sync/read-tracking.d.ts.map +1 -0
- package/dist/sync/read-tracking.js +148 -0
- package/dist/sync/read-tracking.js.map +1 -0
- package/dist/sync/submit.js +213 -0
- package/dist/sync/submit.js.map +1 -0
- package/dist/sync/types.d.ts +63 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/util/default-database-adapter.js +66 -0
- package/dist/util/default-database-adapter.js.map +1 -0
- package/dist/with-database.d.ts +3 -6
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +8 -7
- package/dist/with-database.js.map +1 -1
- package/package.json +62 -55
- package/src/adapters/adapters.ts +33 -26
- package/src/adapters/drizzle/migrate-drizzle.test.ts +99 -41
- package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +601 -0
- package/src/adapters/drizzle/test-utils.ts +13 -8
- package/src/adapters/generic-sql/driver-config.ts +38 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +10 -8
- package/src/adapters/generic-sql/generic-sql-adapter.ts +117 -34
- package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +55 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +297 -3
- package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +120 -0
- package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
- package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +27 -8
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +47 -8
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +28 -9
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +9 -4
- package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +839 -8
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +396 -53
- package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
- package/src/adapters/generic-sql/migration/executor.ts +47 -4
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +238 -46
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +21 -13
- package/src/adapters/generic-sql/migration/sql-generator.ts +145 -66
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +11 -8
- package/src/adapters/generic-sql/query/cursor-utils.test.ts +272 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +42 -7
- package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +171 -35
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +53 -40
- package/src/adapters/generic-sql/query/select-builder.test.ts +16 -11
- package/src/adapters/generic-sql/query/select-builder.ts +7 -3
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +75 -6
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +129 -24
- package/src/adapters/generic-sql/query/where-builder.test.ts +96 -20
- package/src/adapters/generic-sql/query/where-builder.ts +112 -41
- package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +11 -20
- package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +851 -0
- package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +18 -15
- package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +282 -14
- package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +129 -12
- package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +9 -7
- package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +5 -4
- package/src/adapters/generic-sql/uow-decoder.ts +23 -5
- package/src/adapters/generic-sql/uow-encoder.test.ts +36 -3
- package/src/adapters/generic-sql/uow-encoder.ts +48 -13
- package/src/adapters/in-memory/condition-evaluator.test.ts +194 -0
- package/src/adapters/in-memory/condition-evaluator.ts +280 -0
- package/src/adapters/in-memory/errors.ts +20 -0
- package/src/adapters/in-memory/in-memory-adapter.ts +388 -0
- package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +344 -0
- package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +255 -0
- package/src/adapters/in-memory/in-memory-uow.ts +1724 -0
- package/src/adapters/in-memory/index.ts +3 -0
- package/src/adapters/in-memory/options.test.ts +42 -0
- package/src/adapters/in-memory/options.ts +91 -0
- package/src/adapters/in-memory/outbox.test.ts +361 -0
- package/src/adapters/in-memory/reference-resolution.test.ts +51 -0
- package/src/adapters/in-memory/reference-resolution.ts +67 -0
- package/src/adapters/in-memory/sorted-array-index.test.ts +124 -0
- package/src/adapters/in-memory/sorted-array-index.ts +228 -0
- package/src/adapters/in-memory/store.test.ts +69 -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 +58 -0
- package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1207 -0
- package/src/adapters/shared/from-unit-of-work-compiler.ts +159 -47
- package/src/adapters/shared/uow-operation-compiler.ts +28 -18
- package/src/adapters/sql/index.ts +12 -0
- package/src/browser/mod.ts +64 -0
- package/src/client.ts +19 -0
- package/src/db-fragment-definition-builder.test.ts +845 -53
- package/src/db-fragment-definition-builder.ts +911 -95
- package/src/db-fragment-instantiator.test.ts +210 -94
- package/src/db-fragment-integration.test.ts +17 -12
- package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
- package/src/dispatchers/cloudflare-do/index.test.ts +206 -0
- package/src/dispatchers/cloudflare-do/index.ts +63 -0
- package/src/dispatchers/node/dispatcher.ts +112 -0
- package/src/dispatchers/node/index.test.ts +120 -0
- package/src/dispatchers/node/index.ts +50 -0
- package/src/durable-hooks.test.ts +80 -0
- package/src/durable-hooks.ts +67 -0
- package/src/fragments/internal-fragment.routes.test.ts +570 -0
- package/src/fragments/internal-fragment.routes.ts +334 -0
- package/src/fragments/internal-fragment.schema.ts +95 -0
- package/src/fragments/internal-fragment.test.ts +505 -83
- package/src/fragments/internal-fragment.ts +453 -70
- package/src/hooks/durable-hooks-logger.ts +126 -0
- package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
- package/src/hooks/durable-hooks-processor.test.ts +282 -0
- package/src/hooks/durable-hooks-processor.ts +173 -0
- package/src/hooks/durable-hooks-runtime.test.ts +65 -0
- package/src/hooks/durable-hooks-runtime.ts +81 -0
- package/src/hooks/hooks.test.ts +455 -34
- package/src/hooks/hooks.ts +501 -34
- package/src/id.test.ts +34 -0
- package/src/id.ts +1 -3
- package/src/internal/adapter-registry.test.ts +93 -0
- package/src/internal/adapter-registry.ts +239 -0
- package/src/internal/outbox-state.ts +43 -0
- package/src/migration-engine/auto-from-schema.test.ts +107 -14
- package/src/migration-engine/auto-from-schema.ts +365 -44
- package/src/migration-engine/create.test.ts +4 -3
- package/src/migration-engine/create.ts +1 -1
- package/src/migration-engine/generation-engine.test.ts +292 -110
- package/src/migration-engine/generation-engine.ts +117 -66
- package/src/migration-engine/shared.ts +14 -0
- package/src/mod.ts +95 -39
- package/src/naming/sql-naming.ts +181 -0
- package/src/outbox/outbox-builder.ts +241 -0
- package/src/outbox/outbox.test.ts +424 -0
- package/src/outbox/outbox.ts +139 -0
- package/src/query/column-defaults.ts +42 -4
- package/src/query/condition-builder.test.ts +18 -3
- package/src/query/condition-builder.ts +7 -0
- package/src/query/cursor-client.test.ts +70 -0
- package/src/query/cursor-client.ts +263 -0
- package/src/query/cursor.test.ts +119 -20
- package/src/query/cursor.ts +88 -27
- package/src/query/db-now.ts +73 -0
- package/src/query/orm/orm.ts +2 -2
- package/src/query/query-type.test.ts +4 -3
- package/src/query/serialize/create-sql-serializer.ts +10 -5
- package/src/query/serialize/dialect/mysql-serializer.ts +13 -5
- package/src/query/serialize/dialect/postgres-serializer.ts +35 -5
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +90 -3
- package/src/query/serialize/dialect/sqlite-serializer.ts +108 -12
- package/src/query/serialize/sql-serializer.ts +4 -4
- package/src/query/simple-query-interface.ts +15 -4
- package/src/query/unit-of-work/execute-unit-of-work.test.ts +372 -10
- package/src/query/unit-of-work/execute-unit-of-work.ts +87 -27
- package/src/query/unit-of-work/retry-policy.test.ts +1 -0
- package/src/query/unit-of-work/tx-builder.test.ts +73 -1
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +17 -16
- package/src/query/unit-of-work/unit-of-work-types.test.ts +42 -12
- package/src/query/unit-of-work/unit-of-work.test.ts +196 -39
- package/src/query/unit-of-work/unit-of-work.ts +309 -38
- package/src/query/value-decoding.test.ts +63 -4
- package/src/query/value-decoding.ts +32 -6
- package/src/query/value-encoding.test.ts +86 -2
- package/src/query/value-encoding.ts +56 -6
- package/src/schema/create.test.ts +293 -47
- package/src/schema/create.ts +406 -70
- package/src/schema/generate-id.test.ts +3 -2
- package/src/schema/generate-id.ts +2 -2
- package/src/schema/serialize.test.ts +18 -5
- package/src/schema/type-conversion/create-sql-type-mapper.ts +8 -3
- package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
- package/src/schema/type-conversion/type-mapping.test.ts +26 -1
- package/src/schema/validator.test.ts +199 -0
- package/src/schema/validator.ts +232 -0
- package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +232 -129
- package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +155 -99
- package/src/schema-output/prisma.test.ts +694 -0
- package/src/schema-output/prisma.ts +593 -0
- package/src/sql-driver/better-sqlite3.test.ts +5 -3
- package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
- package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
- package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
- package/src/sql-driver/query-executor/query-executor.ts +1 -1
- package/src/sql-driver/sql-driver-adapter.ts +2 -2
- package/src/sql-driver/sql.ts +2 -1
- package/src/sql-driver/sqlocal.test.ts +4 -2
- package/src/sync/commands.test.ts +39 -0
- package/src/sync/commands.ts +51 -0
- package/src/sync/conflict-checker.test.ts +450 -0
- package/src/sync/conflict-checker.ts +248 -0
- package/src/sync/index.ts +14 -0
- package/src/sync/plan.ts +9 -0
- package/src/sync/read-tracking.test.ts +177 -0
- package/src/sync/read-tracking.ts +287 -0
- package/src/sync/submit.test.ts +205 -0
- package/src/sync/submit.ts +328 -0
- package/src/sync/types.ts +80 -0
- package/src/util/default-database-adapter.ts +119 -0
- package/src/with-database.ts +20 -31
- package/tsconfig.json +1 -1
- package/tsdown.config.ts +38 -24
- package/vitest.config.ts +1 -0
- 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 +0 -165
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/packages/fragno/dist/api/bind-services.js +0 -20
- package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
- package/dist/packages/fragno/dist/api/error.js +0 -48
- package/dist/packages/fragno/dist/api/error.js.map +0 -1
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -320
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -525
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
- package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
- package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
- package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
- package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
- package/dist/packages/fragno/dist/api/internal/route.js +0 -10
- package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
- package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
- package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
- package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-input-context.js +0 -118
- package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
- package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
- package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
- package/dist/packages/fragno/dist/api/route.js +0 -17
- package/dist/packages/fragno/dist/api/route.js.map +0 -1
- package/dist/packages/fragno/dist/internal/symbols.js +0 -10
- package/dist/packages/fragno/dist/internal/symbols.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/query/cursor.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { DriverConfig } from "../adapters/generic-sql/driver-config";
|
|
2
|
+
import type { SQLiteStorageMode } from "../adapters/generic-sql/sqlite-storage";
|
|
1
3
|
import type { AnyColumn } from "../schema/create";
|
|
2
4
|
import { createSQLSerializer } from "./serialize/create-sql-serializer";
|
|
3
5
|
import { resolveFragnoIdValue } from "./value-encoding";
|
|
4
|
-
import type { DriverConfig } from "../adapters/generic-sql/driver-config";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Cursor object containing all information needed for pagination
|
|
@@ -56,6 +57,7 @@ export class Cursor {
|
|
|
56
57
|
* Encode cursor to an opaque base64 string (safe to send to client)
|
|
57
58
|
*/
|
|
58
59
|
encode(): string {
|
|
60
|
+
assertSerializableIndexValues(this.#indexValues);
|
|
59
61
|
const data: CursorData = {
|
|
60
62
|
v: 1,
|
|
61
63
|
indexName: this.#indexName,
|
|
@@ -100,7 +102,12 @@ export interface CursorData {
|
|
|
100
102
|
* Encode cursor data to a base64 string (internal)
|
|
101
103
|
*/
|
|
102
104
|
function encodeCursorData(data: CursorData): string {
|
|
103
|
-
|
|
105
|
+
let json: string;
|
|
106
|
+
try {
|
|
107
|
+
json = JSON.stringify(data);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw new Error(`Invalid cursor: ${error instanceof Error ? error.message : "malformed data"}`);
|
|
110
|
+
}
|
|
104
111
|
// Use Buffer in Node.js or btoa in browsers
|
|
105
112
|
if (typeof Buffer !== "undefined") {
|
|
106
113
|
return Buffer.from(json, "utf-8").toString("base64");
|
|
@@ -129,32 +136,38 @@ export function decodeCursor(cursor: string): Cursor {
|
|
|
129
136
|
json = atob(cursor);
|
|
130
137
|
}
|
|
131
138
|
const data = JSON.parse(json);
|
|
139
|
+
const record = data as Record<string, unknown>;
|
|
132
140
|
|
|
133
141
|
// Validate structure
|
|
134
142
|
if (
|
|
135
|
-
!data ||
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
typeof
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
(
|
|
143
|
+
!isPlainObject(data) ||
|
|
144
|
+
!isPlainObject(record["indexValues"]) ||
|
|
145
|
+
typeof record["indexName"] !== "string" ||
|
|
146
|
+
record["indexName"].length === 0 ||
|
|
147
|
+
typeof record["orderDirection"] !== "string" ||
|
|
148
|
+
(record["orderDirection"] !== "asc" && record["orderDirection"] !== "desc") ||
|
|
149
|
+
typeof record["pageSize"] !== "number" ||
|
|
150
|
+
!Number.isFinite(record["pageSize"]) ||
|
|
151
|
+
!Number.isInteger(record["pageSize"]) ||
|
|
152
|
+
record["pageSize"] <= 0
|
|
143
153
|
) {
|
|
144
154
|
throw new Error("Invalid cursor structure");
|
|
145
155
|
}
|
|
146
156
|
|
|
147
157
|
// Only support v1
|
|
148
|
-
|
|
158
|
+
if (typeof record["v"] !== "number") {
|
|
159
|
+
throw new Error("Unsupported cursor version: missing. Only v1 is supported.");
|
|
160
|
+
}
|
|
161
|
+
const version = record["v"];
|
|
149
162
|
if (version !== 1) {
|
|
150
163
|
throw new Error(`Unsupported cursor version: ${version}. Only v1 is supported.`);
|
|
151
164
|
}
|
|
152
165
|
|
|
153
166
|
return new Cursor({
|
|
154
|
-
indexName:
|
|
155
|
-
orderDirection:
|
|
156
|
-
pageSize:
|
|
157
|
-
indexValues:
|
|
167
|
+
indexName: record["indexName"],
|
|
168
|
+
orderDirection: record["orderDirection"],
|
|
169
|
+
pageSize: record["pageSize"],
|
|
170
|
+
indexValues: record["indexValues"],
|
|
158
171
|
});
|
|
159
172
|
} catch (error) {
|
|
160
173
|
throw new Error(`Invalid cursor: ${error instanceof Error ? error.message : "malformed data"}`);
|
|
@@ -194,7 +207,14 @@ export function createCursorFromRecord(
|
|
|
194
207
|
const indexValues: Record<string, unknown> = {};
|
|
195
208
|
|
|
196
209
|
for (const col of indexColumns) {
|
|
197
|
-
|
|
210
|
+
const value = record[col.name];
|
|
211
|
+
if (value === undefined) {
|
|
212
|
+
throw new Error(`Record is missing value for index column "${col.name}".`);
|
|
213
|
+
}
|
|
214
|
+
// Resolve FragnoId/FragnoReference to primitive values for cursor serialization.
|
|
215
|
+
const resolved = resolveFragnoIdValue(value, col);
|
|
216
|
+
// BigInt values are not JSON-serializable, so store them as strings.
|
|
217
|
+
indexValues[col.name] = typeof resolved === "bigint" ? resolved.toString() : resolved;
|
|
198
218
|
}
|
|
199
219
|
|
|
200
220
|
return new Cursor({
|
|
@@ -218,6 +238,7 @@ export function createCursorFromRecord(
|
|
|
218
238
|
* @param cursor - The cursor object
|
|
219
239
|
* @param indexColumns - The columns that make up the index
|
|
220
240
|
* @param driverConfig - The driver configuration
|
|
241
|
+
* @param sqliteStorageMode - Optional SQLite storage mode override
|
|
221
242
|
* @returns Serialized values ready for database queries
|
|
222
243
|
*
|
|
223
244
|
* @example
|
|
@@ -233,23 +254,63 @@ export function serializeCursorValues(
|
|
|
233
254
|
cursor: Cursor,
|
|
234
255
|
indexColumns: AnyColumn[],
|
|
235
256
|
driverConfig: DriverConfig,
|
|
257
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
236
258
|
): Record<string, unknown> {
|
|
237
|
-
const serializer = createSQLSerializer(driverConfig);
|
|
259
|
+
const serializer = createSQLSerializer(driverConfig, sqliteStorageMode);
|
|
238
260
|
const serialized: Record<string, unknown> = {};
|
|
261
|
+
const missingColumns: string[] = [];
|
|
239
262
|
|
|
240
263
|
for (const col of indexColumns) {
|
|
241
|
-
const value = cursor.indexValues[col.
|
|
242
|
-
if (value
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
264
|
+
const value = cursor.indexValues[col.name];
|
|
265
|
+
if (value === undefined) {
|
|
266
|
+
missingColumns.push(col.name);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// If the cursor value is already a FragnoId/FragnoReference, resolve it directly
|
|
271
|
+
// to avoid deserializing non-JSON objects.
|
|
272
|
+
const resolvedDirect = resolveFragnoIdValue(value, col);
|
|
273
|
+
if (resolvedDirect !== value) {
|
|
274
|
+
serialized[col.name] = serializer.serialize(resolvedDirect, col);
|
|
275
|
+
continue;
|
|
251
276
|
}
|
|
277
|
+
|
|
278
|
+
// First deserialize from JSON format to application format
|
|
279
|
+
// (e.g., "2025-11-07T09:36:57.959Z" string → Date object)
|
|
280
|
+
const deserialized = serializer.deserialize(value, col);
|
|
281
|
+
// Resolve FragnoId/FragnoReference to primitive values (if present)
|
|
282
|
+
const resolved = resolveFragnoIdValue(deserialized, col);
|
|
283
|
+
// Then serialize to database format
|
|
284
|
+
// (e.g., Date → database driver format)
|
|
285
|
+
serialized[col.name] = serializer.serialize(resolved, col);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (missingColumns.length > 0) {
|
|
289
|
+
const suffix = cursor.indexName ? ` for index "${cursor.indexName}"` : "";
|
|
290
|
+
const columns = missingColumns.map((name) => `"${name}"`).join(", ");
|
|
291
|
+
const plural = missingColumns.length === 1 ? "" : "s";
|
|
292
|
+
throw new Error(`Cursor is missing values for index column${plural} ${columns}${suffix}.`);
|
|
252
293
|
}
|
|
253
294
|
|
|
254
295
|
return serialized;
|
|
255
296
|
}
|
|
297
|
+
|
|
298
|
+
const isPlainObject = (value: unknown): value is Record<string, unknown> =>
|
|
299
|
+
typeof value === "object" && value !== null && !Array.isArray(value);
|
|
300
|
+
|
|
301
|
+
const assertSerializableIndexValues = (values: Record<string, unknown>): void => {
|
|
302
|
+
for (const [key, value] of Object.entries(values)) {
|
|
303
|
+
if (value === undefined) {
|
|
304
|
+
throw new Error(`Cursor index value "${key}" is undefined.`);
|
|
305
|
+
}
|
|
306
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
307
|
+
throw new Error(`Cursor index value "${key}" must be a finite number.`);
|
|
308
|
+
}
|
|
309
|
+
if (typeof value === "bigint") {
|
|
310
|
+
throw new Error(`Cursor index value "${key}" must not be a BigInt.`);
|
|
311
|
+
}
|
|
312
|
+
if (typeof value === "function" || typeof value === "symbol") {
|
|
313
|
+
throw new Error(`Cursor index value "${key}" is not JSON-serializable.`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export type DbInterval = { tag: "db-interval"; ms: number };
|
|
2
|
+
|
|
3
|
+
export type DbIntervalInput =
|
|
4
|
+
| number
|
|
5
|
+
| {
|
|
6
|
+
ms?: number;
|
|
7
|
+
seconds?: number;
|
|
8
|
+
minutes?: number;
|
|
9
|
+
hours?: number;
|
|
10
|
+
days?: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type DbNow = {
|
|
14
|
+
tag: "db-now";
|
|
15
|
+
offsetMs?: number;
|
|
16
|
+
plus: (interval: DbInterval | DbIntervalInput) => DbNow;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const toIntervalMs = (input: DbInterval | DbIntervalInput): number => {
|
|
20
|
+
if (typeof input === "number") {
|
|
21
|
+
if (!Number.isFinite(input)) {
|
|
22
|
+
throw new Error("DB_INTERVAL_INVALID");
|
|
23
|
+
}
|
|
24
|
+
return input;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (typeof input === "object" && input !== null && "tag" in input) {
|
|
28
|
+
const tagged = input as DbInterval;
|
|
29
|
+
if (tagged.tag === "db-interval") {
|
|
30
|
+
if (!Number.isFinite(tagged.ms)) {
|
|
31
|
+
throw new Error("DB_INTERVAL_INVALID");
|
|
32
|
+
}
|
|
33
|
+
return tagged.ms;
|
|
34
|
+
}
|
|
35
|
+
throw new Error("DB_INTERVAL_INVALID");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const interval = input as Exclude<DbIntervalInput, number>;
|
|
39
|
+
const totalMs =
|
|
40
|
+
(interval.ms ?? 0) +
|
|
41
|
+
(interval.seconds ?? 0) * 1000 +
|
|
42
|
+
(interval.minutes ?? 0) * 60_000 +
|
|
43
|
+
(interval.hours ?? 0) * 3_600_000 +
|
|
44
|
+
(interval.days ?? 0) * 86_400_000;
|
|
45
|
+
|
|
46
|
+
if (!Number.isFinite(totalMs)) {
|
|
47
|
+
throw new Error("DB_INTERVAL_INVALID");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return totalMs;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const createDbNow = (offsetMs = 0): DbNow => ({
|
|
54
|
+
tag: "db-now",
|
|
55
|
+
offsetMs,
|
|
56
|
+
plus: (interval) => createDbNow(offsetMs + toIntervalMs(interval)),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export const dbNow = (): DbNow => createDbNow(0);
|
|
60
|
+
|
|
61
|
+
export const isDbNow = (value: unknown): value is DbNow =>
|
|
62
|
+
typeof value === "object" && value !== null && (value as { tag?: string }).tag === "db-now";
|
|
63
|
+
|
|
64
|
+
export const getDbNowOffsetMs = (value: DbNow): number =>
|
|
65
|
+
typeof value.offsetMs === "number" ? value.offsetMs : 0;
|
|
66
|
+
|
|
67
|
+
export const dbInterval = (input: DbIntervalInput): DbInterval => ({
|
|
68
|
+
tag: "db-interval",
|
|
69
|
+
ms: toIntervalMs(input),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export const isDbInterval = (value: unknown): value is DbInterval =>
|
|
73
|
+
typeof value === "object" && value !== null && (value as { tag?: string }).tag === "db-interval";
|
package/src/query/orm/orm.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { AnyColumn, AnyRelation, AnyTable } from "../../schema/create";
|
|
2
|
+
import { buildCondition, type Condition } from "../condition-builder";
|
|
1
3
|
import type {
|
|
2
4
|
AnySelectClause,
|
|
3
5
|
FindFirstOptions,
|
|
@@ -5,8 +7,6 @@ import type {
|
|
|
5
7
|
JoinBuilder,
|
|
6
8
|
OrderBy,
|
|
7
9
|
} from "../simple-query-interface";
|
|
8
|
-
import { buildCondition, type Condition } from "../condition-builder";
|
|
9
|
-
import type { AnyColumn, AnyRelation, AnyTable } from "../../schema/create";
|
|
10
10
|
|
|
11
11
|
export interface CompiledJoin {
|
|
12
12
|
relation: AnyRelation;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { describe, expectTypeOf, it } from "vitest";
|
|
2
|
+
|
|
2
3
|
import { column, FragnoId, idColumn, referenceColumn, schema } from "../schema/create";
|
|
4
|
+
import type { ConditionBuilder } from "./condition-builder";
|
|
3
5
|
import type {
|
|
4
6
|
SimpleQueryInterface,
|
|
5
7
|
FindFirstOptions,
|
|
@@ -9,11 +11,10 @@ import type {
|
|
|
9
11
|
SelectClause,
|
|
10
12
|
TableToInsertValues,
|
|
11
13
|
} from "./simple-query-interface";
|
|
12
|
-
import type { ConditionBuilder } from "./condition-builder";
|
|
13
14
|
|
|
14
15
|
describe("query type tests", () => {
|
|
15
16
|
// Create test schema
|
|
16
|
-
const _testSchema = schema((s) => {
|
|
17
|
+
const _testSchema = schema("_test", (s) => {
|
|
17
18
|
return s
|
|
18
19
|
.addTable("users", (t) => {
|
|
19
20
|
return t
|
|
@@ -337,7 +338,7 @@ describe("query type tests", () => {
|
|
|
337
338
|
});
|
|
338
339
|
|
|
339
340
|
describe("join", () => {
|
|
340
|
-
const userSchema = schema((s) => {
|
|
341
|
+
const userSchema = schema("user", (s) => {
|
|
341
342
|
return s
|
|
342
343
|
.addTable("users", (t) => {
|
|
343
344
|
return t.addColumn("id", idColumn()).addColumn("name", column("string"));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { DriverConfig } from "../../adapters/generic-sql/driver-config";
|
|
2
|
-
import {
|
|
3
|
-
import { SQLiteSerializer } from "./dialect/sqlite-serializer";
|
|
4
|
-
import { PostgreSQLSerializer } from "./dialect/postgres-serializer";
|
|
2
|
+
import type { SQLiteStorageMode } from "../../adapters/generic-sql/sqlite-storage";
|
|
5
3
|
import { MySQLSerializer } from "./dialect/mysql-serializer";
|
|
4
|
+
import { PostgreSQLSerializer } from "./dialect/postgres-serializer";
|
|
5
|
+
import { SQLiteSerializer } from "./dialect/sqlite-serializer";
|
|
6
|
+
import { SQLSerializer } from "./sql-serializer";
|
|
6
7
|
|
|
7
8
|
// Re-export SQLSerializer for convenience
|
|
8
9
|
export { SQLSerializer } from "./sql-serializer";
|
|
@@ -14,9 +15,13 @@ export { SQLSerializer } from "./sql-serializer";
|
|
|
14
15
|
* (PostgreSQL, MySQL, or SQLite).
|
|
15
16
|
*
|
|
16
17
|
* @param driverConfig - The driver configuration
|
|
18
|
+
* @param sqliteStorageMode - Optional SQLite storage mode override
|
|
17
19
|
* @returns Dialect-specific SQLSerializer instance
|
|
18
20
|
*/
|
|
19
|
-
export function createSQLSerializer(
|
|
21
|
+
export function createSQLSerializer(
|
|
22
|
+
driverConfig: DriverConfig,
|
|
23
|
+
sqliteStorageMode?: SQLiteStorageMode,
|
|
24
|
+
): SQLSerializer {
|
|
20
25
|
// TODO: The serializers are pretty lenient in what they accept (lost of typeof checks), it may
|
|
21
26
|
// be beneficial to implement serializers per DriverConfig, and be less lenient.
|
|
22
27
|
switch (driverConfig.databaseType) {
|
|
@@ -25,7 +30,7 @@ export function createSQLSerializer(driverConfig: DriverConfig): SQLSerializer {
|
|
|
25
30
|
case "mysql":
|
|
26
31
|
return new MySQLSerializer(driverConfig);
|
|
27
32
|
case "sqlite":
|
|
28
|
-
return new SQLiteSerializer(driverConfig);
|
|
33
|
+
return new SQLiteSerializer(driverConfig, sqliteStorageMode);
|
|
29
34
|
default: {
|
|
30
35
|
const exhaustiveCheck: never = driverConfig.databaseType;
|
|
31
36
|
throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
|
|
1
2
|
import type { AnyColumn } from "../../../schema/create";
|
|
2
3
|
import { SQLSerializer } from "../sql-serializer";
|
|
3
|
-
import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* MySQL-specific serializer.
|
|
@@ -19,7 +19,8 @@ export class MySQLSerializer extends SQLSerializer {
|
|
|
19
19
|
super(driverConfig);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
protected serializeDate(value: Date): Date {
|
|
22
|
+
protected serializeDate(value: Date, _col: AnyColumn): Date {
|
|
23
|
+
void _col;
|
|
23
24
|
// MySQL handles Date objects natively
|
|
24
25
|
return value;
|
|
25
26
|
}
|
|
@@ -34,7 +35,8 @@ export class MySQLSerializer extends SQLSerializer {
|
|
|
34
35
|
return value;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
protected deserializeDate(value: unknown): Date {
|
|
38
|
+
protected deserializeDate(value: unknown, _col: AnyColumn): Date {
|
|
39
|
+
void _col;
|
|
38
40
|
if (value instanceof Date) {
|
|
39
41
|
return value;
|
|
40
42
|
}
|
|
@@ -96,12 +98,15 @@ export class MySQLSerializer extends SQLSerializer {
|
|
|
96
98
|
|
|
97
99
|
protected deserializeInteger(value: unknown): number {
|
|
98
100
|
if (typeof value === "number") {
|
|
101
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
|
102
|
+
throw new Error(`Cannot deserialize integer from invalid number: ${value}`);
|
|
103
|
+
}
|
|
99
104
|
return value;
|
|
100
105
|
}
|
|
101
106
|
// MySQL may return integers as strings
|
|
102
107
|
if (typeof value === "string") {
|
|
103
108
|
const num = Number(value);
|
|
104
|
-
if (isNaN(num)) {
|
|
109
|
+
if (Number.isNaN(num) || !Number.isFinite(num)) {
|
|
105
110
|
throw new Error(`Cannot deserialize integer from invalid string: ${value}`);
|
|
106
111
|
}
|
|
107
112
|
return num;
|
|
@@ -121,11 +126,14 @@ export class MySQLSerializer extends SQLSerializer {
|
|
|
121
126
|
protected deserializeDecimal(value: unknown): number {
|
|
122
127
|
// MySQL can return decimals as numbers or strings
|
|
123
128
|
if (typeof value === "number") {
|
|
129
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
|
130
|
+
throw new Error(`Cannot deserialize decimal from invalid number: ${value}`);
|
|
131
|
+
}
|
|
124
132
|
return value;
|
|
125
133
|
}
|
|
126
134
|
if (typeof value === "string") {
|
|
127
135
|
const num = parseFloat(value);
|
|
128
|
-
if (isNaN(num)) {
|
|
136
|
+
if (Number.isNaN(num) || !Number.isFinite(num)) {
|
|
129
137
|
throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
|
|
130
138
|
}
|
|
131
139
|
return num;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
|
|
1
2
|
import type { AnyColumn } from "../../../schema/create";
|
|
2
3
|
import { SQLSerializer } from "../sql-serializer";
|
|
3
|
-
import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* PostgreSQL-specific serializer.
|
|
@@ -18,7 +18,8 @@ export class PostgreSQLSerializer extends SQLSerializer {
|
|
|
18
18
|
super(driverConfig);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
protected serializeDate(value: Date): Date {
|
|
21
|
+
protected serializeDate(value: Date, _col: AnyColumn): Date {
|
|
22
|
+
void _col;
|
|
22
23
|
// PostgreSQL handles Date objects natively
|
|
23
24
|
return value;
|
|
24
25
|
}
|
|
@@ -33,13 +34,18 @@ export class PostgreSQLSerializer extends SQLSerializer {
|
|
|
33
34
|
return value;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
protected deserializeDate(value: unknown): Date {
|
|
37
|
+
protected deserializeDate(value: unknown, _col: AnyColumn): Date {
|
|
38
|
+
void _col;
|
|
37
39
|
if (value instanceof Date) {
|
|
40
|
+
if (this.driverConfig.driverType === "pglite") {
|
|
41
|
+
return new Date(value.getTime() - value.getTimezoneOffset() * 60_000);
|
|
42
|
+
}
|
|
38
43
|
return value;
|
|
39
44
|
}
|
|
40
45
|
// PostgreSQL returns timestamps/dates as strings
|
|
41
46
|
if (typeof value === "string") {
|
|
42
|
-
|
|
47
|
+
// Normalize timezone-less timestamps to UTC to avoid local offset drift.
|
|
48
|
+
return new Date(normalizeTimestampString(value));
|
|
43
49
|
}
|
|
44
50
|
throw new Error(`Cannot deserialize date from value: ${value}`);
|
|
45
51
|
}
|
|
@@ -91,6 +97,9 @@ export class PostgreSQLSerializer extends SQLSerializer {
|
|
|
91
97
|
|
|
92
98
|
protected deserializeInteger(value: unknown): number {
|
|
93
99
|
if (typeof value === "number") {
|
|
100
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
|
101
|
+
throw new Error(`Cannot deserialize integer from invalid number: ${value}`);
|
|
102
|
+
}
|
|
94
103
|
return value;
|
|
95
104
|
}
|
|
96
105
|
// PostgreSQL may return bigint for large integers
|
|
@@ -108,11 +117,14 @@ export class PostgreSQLSerializer extends SQLSerializer {
|
|
|
108
117
|
protected deserializeDecimal(value: unknown): number {
|
|
109
118
|
// PostgreSQL can return decimals as numbers or strings depending on precision
|
|
110
119
|
if (typeof value === "number") {
|
|
120
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
|
121
|
+
throw new Error(`Cannot deserialize decimal from invalid number: ${value}`);
|
|
122
|
+
}
|
|
111
123
|
return value;
|
|
112
124
|
}
|
|
113
125
|
if (typeof value === "string") {
|
|
114
126
|
const num = parseFloat(value);
|
|
115
|
-
if (isNaN(num)) {
|
|
127
|
+
if (Number.isNaN(num) || !Number.isFinite(num)) {
|
|
116
128
|
throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
|
|
117
129
|
}
|
|
118
130
|
return num;
|
|
@@ -127,3 +139,21 @@ export class PostgreSQLSerializer extends SQLSerializer {
|
|
|
127
139
|
throw new Error(`Cannot deserialize string from value: ${typeof value}`);
|
|
128
140
|
}
|
|
129
141
|
}
|
|
142
|
+
|
|
143
|
+
const normalizeTimestampString = (value: string) => {
|
|
144
|
+
if (!hasTimeComponent(value) || !isTimestampWithoutTimezone(value)) {
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
const withTimeSeparator = value.includes(" ") ? value.replace(" ", "T") : value;
|
|
148
|
+
return `${withTimeSeparator}Z`;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const hasTimeComponent = (value: string) => /\d{2}:\d{2}:\d{2}/.test(value);
|
|
152
|
+
|
|
153
|
+
const isTimestampWithoutTimezone = (value: string) => {
|
|
154
|
+
// Detect RFC3339-like timezone indicators: Z or +/-HH(:MM)?
|
|
155
|
+
if (value.endsWith("Z")) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return !/[+-]\d{2}(:?\d{2})?$/.test(value);
|
|
159
|
+
};
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
|
|
3
|
-
import type { AnyColumn } from "../../../schema/create";
|
|
2
|
+
|
|
4
3
|
import { BetterSQLite3DriverConfig } from "../../../adapters/generic-sql/driver-config";
|
|
4
|
+
import { sqliteStoragePrisma } from "../../../adapters/generic-sql/sqlite-storage";
|
|
5
|
+
import type { AnyColumn } from "../../../schema/create";
|
|
6
|
+
import { SQLiteSerializer } from "./sqlite-serializer";
|
|
5
7
|
|
|
6
8
|
describe("SQLiteSerializer", () => {
|
|
7
9
|
const mockDriverConfig = new BetterSQLite3DriverConfig();
|
|
8
10
|
const serializer = new SQLiteSerializer(mockDriverConfig);
|
|
11
|
+
const prismaSerializer = new SQLiteSerializer(mockDriverConfig, sqliteStoragePrisma);
|
|
12
|
+
const timestampColumn: AnyColumn = {
|
|
13
|
+
name: "createdAt",
|
|
14
|
+
type: "timestamp",
|
|
15
|
+
role: "regular",
|
|
16
|
+
isNullable: false,
|
|
17
|
+
} as AnyColumn;
|
|
9
18
|
|
|
10
19
|
describe("serializeBigInt", () => {
|
|
11
20
|
describe("for internal-id and reference columns", () => {
|
|
@@ -110,6 +119,19 @@ describe("SQLiteSerializer", () => {
|
|
|
110
119
|
expect((result as Buffer).length).toBe(8);
|
|
111
120
|
});
|
|
112
121
|
|
|
122
|
+
it("should keep bigint for regular column in prisma storage", () => {
|
|
123
|
+
const col: AnyColumn = {
|
|
124
|
+
name: "largeNumber",
|
|
125
|
+
type: "bigint",
|
|
126
|
+
role: "regular",
|
|
127
|
+
isNullable: false,
|
|
128
|
+
} as AnyColumn;
|
|
129
|
+
|
|
130
|
+
const result = prismaSerializer["serializeBigInt"](BigInt(789), col);
|
|
131
|
+
expect(result).toBe(BigInt(789));
|
|
132
|
+
expect(typeof result).toBe("bigint");
|
|
133
|
+
});
|
|
134
|
+
|
|
113
135
|
it("should handle large values outside safe integer range as Buffer", () => {
|
|
114
136
|
const col: AnyColumn = {
|
|
115
137
|
name: "largeNumber",
|
|
@@ -132,11 +154,18 @@ describe("SQLiteSerializer", () => {
|
|
|
132
154
|
describe("other serialization methods", () => {
|
|
133
155
|
it("should serialize Date to timestamp number", () => {
|
|
134
156
|
const date = new Date("2024-01-01T00:00:00Z");
|
|
135
|
-
const result = serializer["serializeDate"](date);
|
|
157
|
+
const result = serializer["serializeDate"](date, timestampColumn);
|
|
136
158
|
expect(result).toBe(date.getTime());
|
|
137
159
|
expect(typeof result).toBe("number");
|
|
138
160
|
});
|
|
139
161
|
|
|
162
|
+
it("should serialize Date to ISO string for prisma storage", () => {
|
|
163
|
+
const date = new Date("2024-01-01T00:00:00Z");
|
|
164
|
+
const result = prismaSerializer["serializeDate"](date, timestampColumn);
|
|
165
|
+
expect(result).toBe(date.toISOString());
|
|
166
|
+
expect(typeof result).toBe("string");
|
|
167
|
+
});
|
|
168
|
+
|
|
140
169
|
it("should serialize boolean to 0/1", () => {
|
|
141
170
|
expect(serializer["serializeBoolean"](true)).toBe(1);
|
|
142
171
|
expect(serializer["serializeBoolean"](false)).toBe(0);
|
|
@@ -181,6 +210,23 @@ describe("SQLiteSerializer", () => {
|
|
|
181
210
|
});
|
|
182
211
|
});
|
|
183
212
|
|
|
213
|
+
describe("deserializeDate", () => {
|
|
214
|
+
it("should parse CURRENT_TIMESTAMP format as UTC", () => {
|
|
215
|
+
const date = prismaSerializer["deserializeDate"]("2024-03-10 12:34:56", timestampColumn);
|
|
216
|
+
expect(date.toISOString()).toBe("2024-03-10T12:34:56.000Z");
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("should parse CURRENT_TIMESTAMP format with milliseconds as UTC", () => {
|
|
220
|
+
const date = prismaSerializer["deserializeDate"]("2024-03-10 12:34:56.789", timestampColumn);
|
|
221
|
+
expect(date.toISOString()).toBe("2024-03-10T12:34:56.789Z");
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("should parse numeric timestamp strings with decimals", () => {
|
|
225
|
+
const date = serializer["deserializeDate"]("1772709276409.0", timestampColumn);
|
|
226
|
+
expect(date.getTime()).toBe(1772709276409);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
184
230
|
describe("deserializeInteger", () => {
|
|
185
231
|
it("should deserialize number directly", () => {
|
|
186
232
|
expect(serializer["deserializeInteger"](42)).toBe(42);
|
|
@@ -248,4 +294,45 @@ describe("SQLiteSerializer", () => {
|
|
|
248
294
|
);
|
|
249
295
|
});
|
|
250
296
|
});
|
|
297
|
+
|
|
298
|
+
describe("deserializeBigInt", () => {
|
|
299
|
+
it("should throw when prisma storage receives unsafe bigint number", () => {
|
|
300
|
+
const unsafeNumber = Number.MAX_SAFE_INTEGER + 10;
|
|
301
|
+
expect(() => prismaSerializer["deserializeBigInt"](unsafeNumber)).toThrow(RangeError);
|
|
302
|
+
expect(() => prismaSerializer["deserializeBigInt"](unsafeNumber)).toThrow(
|
|
303
|
+
/exceeds Number\.MAX_SAFE_INTEGER/,
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it("should deserialize bigint from ArrayBuffer blob values", () => {
|
|
308
|
+
const expected = BigInt("9007199254740993");
|
|
309
|
+
const buffer = Buffer.alloc(8);
|
|
310
|
+
buffer.writeBigInt64BE(expected);
|
|
311
|
+
const arrayBuffer = buffer.buffer.slice(
|
|
312
|
+
buffer.byteOffset,
|
|
313
|
+
buffer.byteOffset + buffer.byteLength,
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
expect(serializer["deserializeBigInt"](arrayBuffer)).toBe(expected);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("should deserialize bigint from Uint8Array blob values", () => {
|
|
320
|
+
const expected = BigInt("123456789012345678");
|
|
321
|
+
const buffer = Buffer.alloc(8);
|
|
322
|
+
buffer.writeBigInt64BE(expected);
|
|
323
|
+
const value = new Uint8Array(buffer);
|
|
324
|
+
|
|
325
|
+
expect(serializer["deserializeBigInt"](value)).toBe(expected);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it.each([
|
|
329
|
+
["Buffer", Buffer.alloc(9)],
|
|
330
|
+
["ArrayBuffer", new ArrayBuffer(9)],
|
|
331
|
+
["Uint8Array", new Uint8Array(9)],
|
|
332
|
+
])("should reject %s blob values when byte length is not exactly 8", (_, value) => {
|
|
333
|
+
expect(() => serializer["deserializeBigInt"](value)).toThrow(
|
|
334
|
+
/Cannot deserialize bigint from 9 bytes; expected 8\./,
|
|
335
|
+
);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
251
338
|
});
|