@fragno-dev/db 0.1.15 → 0.2.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 +242 -179
- package/CHANGELOG.md +23 -0
- package/README.md +123 -8
- package/dist/adapters/adapters.d.ts +5 -5
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -21
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +7 -54
- package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
- package/dist/adapters/drizzle/generate.d.ts +3 -0
- package/dist/adapters/drizzle/generate.d.ts.map +1 -1
- package/dist/adapters/drizzle/generate.js +36 -28
- package/dist/adapters/drizzle/generate.js.map +1 -1
- package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
- package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
- package/dist/adapters/generic-sql/driver-config.js +94 -0
- package/dist/adapters/generic-sql/driver-config.js.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
- package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
- package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
- package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
- package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
- package/dist/adapters/generic-sql/migration/executor.js +18 -0
- package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
- package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
- package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
- package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
- package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
- package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/select-builder.js +69 -0
- package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
- package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/where-builder.js +129 -0
- package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
- package/dist/adapters/generic-sql/result-interpreter.js +74 -0
- package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
- package/dist/adapters/generic-sql/uow-decoder.js +105 -0
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
- package/dist/adapters/generic-sql/uow-encoder.js +93 -0
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
- package/dist/adapters/kysely/kysely-adapter.d.ts +5 -18
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
- package/dist/adapters/kysely/kysely-adapter.js +6 -165
- package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
- package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +47 -61
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
- package/dist/adapters/{drizzle/shared.d.ts → shared/table-name-mapper.d.ts} +2 -4
- package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
- package/dist/adapters/shared/table-name-mapper.js +43 -0
- package/dist/adapters/shared/table-name-mapper.js.map +1 -0
- package/dist/adapters/shared/uow-operation-compiler.js +105 -0
- package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
- package/dist/db-fragment-definition-builder.d.ts +53 -19
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +89 -19
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/fragments/internal-fragment.d.ts +39 -5
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +82 -10
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/hooks/hooks.d.ts +51 -0
- package/dist/hooks/hooks.d.ts.map +1 -0
- package/dist/hooks/hooks.js +88 -0
- package/dist/hooks/hooks.js.map +1 -0
- package/dist/migration-engine/generation-engine.d.ts +0 -2
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +23 -61
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/mod.d.ts +34 -10
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +47 -16
- package/dist/mod.js.map +1 -1
- package/dist/node_modules/.pnpm/{rou3@0.7.8 → rou3@0.7.10}/node_modules/rou3/dist/index.js +1 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +69 -31
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
- package/dist/query/column-defaults.js +27 -0
- package/dist/query/column-defaults.js.map +1 -0
- package/dist/query/cursor.d.ts +4 -4
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +8 -6
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/orm/orm.d.ts +1 -1
- package/dist/query/orm/orm.js.map +1 -1
- package/dist/query/serialize/create-sql-serializer.js +30 -0
- package/dist/query/serialize/create-sql-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
- package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
- package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
- package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
- package/dist/query/serialize/sql-serializer.js +67 -0
- package/dist/query/serialize/sql-serializer.js.map +1 -0
- package/dist/query/{query.d.ts → simple-query-interface.d.ts} +5 -5
- package/dist/query/simple-query-interface.d.ts.map +1 -0
- package/dist/query/{execute-unit-of-work.d.ts → unit-of-work/execute-unit-of-work.d.ts} +13 -3
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
- package/dist/query/{execute-unit-of-work.js → unit-of-work/execute-unit-of-work.js} +17 -4
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
- package/dist/query/{retry-policy.d.ts → unit-of-work/retry-policy.d.ts} +1 -1
- package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
- package/dist/query/{retry-policy.js → unit-of-work/retry-policy.js} +1 -1
- package/dist/query/unit-of-work/retry-policy.js.map +1 -0
- package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +51 -18
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
- package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +58 -11
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
- package/dist/query/value-decoding.js +71 -0
- package/dist/query/value-decoding.js.map +1 -0
- package/dist/query/value-encoding.js +124 -0
- package/dist/query/value-encoding.js.map +1 -0
- package/dist/schema/create.d.ts +3 -0
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +4 -0
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
- package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
- package/dist/schema/type-conversion/dialect/mysql.js +57 -0
- package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
- package/dist/schema/type-conversion/dialect/postgres.js +56 -0
- package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
- package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
- package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
- package/dist/schema/type-conversion/type-mapping.js +63 -0
- package/dist/schema/type-conversion/type-mapping.js.map +1 -0
- package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
- package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
- package/dist/sql-driver/connection/connection-provider.js +19 -0
- package/dist/sql-driver/connection/connection-provider.js.map +1 -0
- package/dist/sql-driver/connection/single-connection-provider.js +23 -0
- package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
- package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
- package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
- package/dist/sql-driver/dialects/dialects.d.ts +2 -0
- package/dist/sql-driver/dialects/dialects.js +3 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
- package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
- package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
- package/dist/sql-driver/driver/runtime-driver.js +56 -0
- package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
- package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
- package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
- package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
- package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
- package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
- package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
- package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
- package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
- package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver-adapter.js +68 -0
- package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
- package/dist/sql-driver/sql-driver.d.ts +38 -0
- package/dist/sql-driver/sql-driver.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver.js +1 -0
- package/dist/sql-driver/sql.js +50 -0
- package/dist/sql-driver/sql.js.map +1 -0
- package/dist/with-database.d.ts +6 -2
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +1 -1
- package/dist/with-database.js.map +1 -1
- package/package.json +37 -10
- package/src/adapters/adapters.ts +8 -5
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +60 -169
- package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +31 -55
- package/src/adapters/drizzle/drizzle-adapter.ts +15 -107
- package/src/adapters/drizzle/generate.test.ts +2 -2
- package/src/adapters/drizzle/generate.ts +78 -34
- package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
- package/src/adapters/drizzle/shared.ts +0 -34
- package/src/adapters/drizzle/test-utils.ts +3 -3
- package/src/adapters/generic-sql/README.md +14 -0
- package/src/adapters/generic-sql/driver-config.ts +144 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
- package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
- package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
- package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
- package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
- package/src/adapters/generic-sql/migration/executor.ts +33 -0
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
- package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
- package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
- package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
- package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
- package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
- package/src/adapters/generic-sql/query/select-builder.ts +137 -0
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
- package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
- package/src/adapters/generic-sql/query/where-builder.ts +211 -0
- package/src/adapters/generic-sql/result-interpreter.ts +102 -0
- package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
- package/src/adapters/generic-sql/uow-decoder.ts +152 -0
- package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
- package/src/adapters/generic-sql/uow-encoder.ts +131 -0
- package/src/adapters/kysely/kysely-adapter-pglite.test.ts +26 -76
- package/src/adapters/kysely/{kysely-adapter-sqlite.test.ts → kysely-adapter-sqlocal.test.ts} +76 -17
- package/src/adapters/kysely/kysely-adapter.ts +10 -250
- package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +110 -104
- package/src/adapters/shared/table-name-mapper.ts +50 -0
- package/src/adapters/shared/uow-operation-compiler.ts +211 -0
- package/src/db-fragment-definition-builder.test.ts +2 -2
- package/src/db-fragment-definition-builder.ts +281 -50
- package/src/db-fragment-instantiator.test.ts +78 -2
- package/src/db-fragment-integration.test.ts +14 -16
- package/src/fragments/internal-fragment.test.ts +434 -45
- package/src/fragments/internal-fragment.ts +184 -20
- package/src/hooks/hooks.test.ts +575 -0
- package/src/hooks/hooks.ts +179 -0
- package/src/migration-engine/generation-engine.test.ts +44 -54
- package/src/migration-engine/generation-engine.ts +48 -94
- package/src/mod.ts +117 -29
- package/src/query/column-defaults.ts +49 -0
- package/src/query/cursor.test.ts +31 -6
- package/src/query/cursor.ts +11 -7
- package/src/query/orm/orm.ts +1 -1
- package/src/query/query-type.test.ts +9 -9
- package/src/query/serialize/create-sql-serializer.ts +34 -0
- package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
- package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
- package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
- package/src/query/serialize/sql-serializer.ts +143 -0
- package/src/query/{query.ts → simple-query-interface.ts} +2 -2
- package/src/query/{execute-unit-of-work.test.ts → unit-of-work/execute-unit-of-work.test.ts} +16 -16
- package/src/query/{execute-unit-of-work.ts → unit-of-work/execute-unit-of-work.ts} +49 -8
- package/src/query/{unit-of-work-coordinator.test.ts → unit-of-work/unit-of-work-coordinator.test.ts} +41 -43
- package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +5 -3
- package/src/query/{unit-of-work.test.ts → unit-of-work/unit-of-work.test.ts} +100 -9
- package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +135 -32
- package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -427
- package/src/query/value-decoding.ts +113 -0
- package/src/query/value-encoding.test.ts +390 -0
- package/src/query/value-encoding.ts +168 -0
- package/src/schema/create.test.ts +5 -1
- package/src/schema/create.ts +5 -0
- package/src/schema/serialize.test.ts +165 -407
- package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
- package/src/schema/type-conversion/dialect/mysql.ts +64 -0
- package/src/schema/type-conversion/dialect/postgres.ts +62 -0
- package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
- package/src/schema/type-conversion/type-mapping.test.ts +137 -0
- package/src/schema/type-conversion/type-mapping.ts +153 -0
- package/src/shared/connection-pool.ts +5 -5
- package/src/sql-driver/better-sqlite3.test.ts +126 -0
- package/src/sql-driver/connection/connection-provider.ts +27 -0
- package/src/sql-driver/connection/single-connection-provider.ts +42 -0
- package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
- package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
- package/src/sql-driver/dialects/dialects.ts +1 -0
- package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
- package/src/sql-driver/driver/runtime-driver.ts +91 -0
- package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
- package/src/sql-driver/query-executor/plugin.ts +22 -0
- package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
- package/src/sql-driver/query-executor/query-executor.ts +44 -0
- package/src/sql-driver/sql-driver-adapter.ts +96 -0
- package/src/sql-driver/sql-driver.ts +53 -0
- package/src/sql-driver/sql.ts +57 -0
- package/src/sql-driver/sqlocal.test.ts +117 -0
- package/src/with-database.ts +35 -23
- package/tsdown.config.ts +7 -2
- package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
- package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
- package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -334
- package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -123
- package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -160
- package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
- package/dist/adapters/drizzle/join-column-utils.js +0 -28
- package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
- package/dist/adapters/drizzle/shared.d.ts.map +0 -1
- package/dist/adapters/drizzle/shared.js +0 -35
- package/dist/adapters/drizzle/shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
- package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
- package/dist/adapters/kysely/kysely-query-builder.js +0 -321
- package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
- package/dist/adapters/kysely/kysely-query-compiler.js +0 -67
- package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-query.d.ts +0 -23
- package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-query.js +0 -230
- package/dist/adapters/kysely/kysely-query.js.map +0 -1
- package/dist/adapters/kysely/kysely-shared.d.ts +0 -14
- package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-shared.js +0 -33
- package/dist/adapters/kysely/kysely-shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-compiler.js +0 -193
- package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-executor.js +0 -93
- package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-base.js +0 -128
- package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-factory.js +0 -34
- package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
- package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
- package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
- package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
- package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
- package/dist/adapters/kysely/migration/execute.js +0 -34
- package/dist/adapters/kysely/migration/execute.js.map +0 -1
- package/dist/migration-engine/create.d.ts +0 -37
- package/dist/migration-engine/create.d.ts.map +0 -1
- package/dist/migration-engine/create.js +0 -58
- package/dist/migration-engine/create.js.map +0 -1
- package/dist/migration-engine/shared.d.ts +0 -112
- package/dist/migration-engine/shared.d.ts.map +0 -1
- package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/query/execute-unit-of-work.d.ts.map +0 -1
- package/dist/query/execute-unit-of-work.js.map +0 -1
- package/dist/query/query.d.ts.map +0 -1
- package/dist/query/result-transform.js +0 -170
- package/dist/query/result-transform.js.map +0 -1
- package/dist/query/retry-policy.d.ts.map +0 -1
- package/dist/query/retry-policy.js.map +0 -1
- package/dist/query/unit-of-work.d.ts.map +0 -1
- package/dist/query/unit-of-work.js.map +0 -1
- package/dist/schema/serialize.js +0 -111
- package/dist/schema/serialize.js.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -122
- package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
- package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
- package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +0 -1442
- package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +0 -1414
- package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1400
- package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -677
- package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -228
- package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -309
- package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
- package/src/adapters/drizzle/join-column-utils.ts +0 -39
- package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
- package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
- package/src/adapters/kysely/kysely-query-builder.ts +0 -666
- package/src/adapters/kysely/kysely-query-compiler.ts +0 -127
- package/src/adapters/kysely/kysely-query.test.ts +0 -498
- package/src/adapters/kysely/kysely-query.ts +0 -399
- package/src/adapters/kysely/kysely-shared.ts +0 -57
- package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -986
- package/src/adapters/kysely/kysely-uow-compiler.ts +0 -350
- package/src/adapters/kysely/kysely-uow-executor.ts +0 -164
- package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -794
- package/src/adapters/kysely/migration/execute-base.ts +0 -256
- package/src/adapters/kysely/migration/execute-factory.ts +0 -53
- package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
- package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
- package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
- package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
- package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
- package/src/adapters/kysely/migration/execute.ts +0 -50
- package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
- package/src/query/result-transform.ts +0 -274
- package/src/schema/serialize.ts +0 -407
- /package/dist/query/{query.js → simple-query-interface.js} +0 -0
- /package/src/query/{retry-policy.test.ts → unit-of-work/retry-policy.test.ts} +0 -0
- /package/src/query/{retry-policy.ts → unit-of-work/retry-policy.ts} +0 -0
package/src/mod.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from "./adapters/adapters";
|
|
2
2
|
import type { AnySchema } from "./schema/create";
|
|
3
|
-
import type { AbstractQuery } from "./query/query";
|
|
4
3
|
import type { CursorResult } from "./query/cursor";
|
|
5
4
|
import { Cursor } from "./query/cursor";
|
|
5
|
+
import type { FragnoInstantiatedFragment, AnyFragnoInstantiatedFragment } from "@fragno-dev/core";
|
|
6
|
+
import type {
|
|
7
|
+
FragnoPublicConfigWithDatabase,
|
|
8
|
+
ImplicitDatabaseDependencies,
|
|
9
|
+
} from "./db-fragment-definition-builder";
|
|
10
|
+
import {
|
|
11
|
+
getSchemaVersionFromDatabase,
|
|
12
|
+
type InternalFragmentInstance,
|
|
13
|
+
} from "./fragments/internal-fragment";
|
|
6
14
|
|
|
7
15
|
export type { DatabaseAdapter, CursorResult };
|
|
8
16
|
export { Cursor };
|
|
@@ -49,30 +57,6 @@ export class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {
|
|
|
49
57
|
return fragnoDatabaseFakeSymbol;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
async createClient(): Promise<AbstractQuery<T, TUOWConfig>> {
|
|
53
|
-
const dbVersion = await this.#adapter.getSchemaVersion(this.#namespace);
|
|
54
|
-
if (dbVersion !== this.#schema.version.toString()) {
|
|
55
|
-
throw new Error(
|
|
56
|
-
`Database is not at expected version. Did you forget to run migrations?` +
|
|
57
|
-
` Current version: ${dbVersion}, Expected version: ${this.#schema.version}`,
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return this.#adapter.createQueryEngine(this.#schema, this.#namespace);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async runMigrations(): Promise<boolean> {
|
|
65
|
-
if (!this.#adapter.createMigrationEngine) {
|
|
66
|
-
throw new Error("Migration engine not supported for this adapter.");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const migrator = this.#adapter.createMigrationEngine(this.#schema, this.#namespace);
|
|
70
|
-
const preparedMigration = await migrator.prepareMigration();
|
|
71
|
-
await preparedMigration.execute();
|
|
72
|
-
|
|
73
|
-
return preparedMigration.operations.length > 0;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
60
|
get namespace() {
|
|
77
61
|
return this.#namespace;
|
|
78
62
|
}
|
|
@@ -107,22 +91,126 @@ export {
|
|
|
107
91
|
type UOWCompiler,
|
|
108
92
|
type UOWExecutor,
|
|
109
93
|
type UOWDecoder,
|
|
110
|
-
} from "./query/unit-of-work";
|
|
94
|
+
} from "./query/unit-of-work/unit-of-work";
|
|
111
95
|
|
|
112
96
|
export {
|
|
113
97
|
type RetryPolicy,
|
|
114
98
|
NoRetryPolicy,
|
|
115
99
|
ExponentialBackoffRetryPolicy,
|
|
116
100
|
LinearBackoffRetryPolicy,
|
|
117
|
-
} from "./query/retry-policy";
|
|
101
|
+
} from "./query/unit-of-work/retry-policy";
|
|
118
102
|
|
|
119
103
|
export {
|
|
120
104
|
executeUnitOfWork,
|
|
121
105
|
type ExecuteUnitOfWorkResult,
|
|
122
106
|
type ExecuteUnitOfWorkCallbacks,
|
|
123
107
|
type ExecuteUnitOfWorkOptions,
|
|
124
|
-
} from "./query/execute-unit-of-work";
|
|
108
|
+
} from "./query/unit-of-work/execute-unit-of-work";
|
|
125
109
|
|
|
126
|
-
export {
|
|
110
|
+
export type { BoundServices } from "@fragno-dev/core";
|
|
127
111
|
|
|
128
112
|
export { internalFragmentDef } from "./fragments/internal-fragment";
|
|
113
|
+
export type { InternalFragmentInstance } from "./fragments/internal-fragment";
|
|
114
|
+
|
|
115
|
+
export type { HookContext, HooksMap, HookFn, HookPayload, TriggerHookOptions } from "./hooks/hooks";
|
|
116
|
+
|
|
117
|
+
export type AnyFragnoInstantiatedDatabaseFragment = FragnoInstantiatedFragment<
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
+
any,
|
|
120
|
+
ImplicitDatabaseDependencies<AnySchema>,
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
122
|
+
any,
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
|
+
any,
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
126
|
+
any,
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
|
+
any,
|
|
129
|
+
FragnoPublicConfigWithDatabase,
|
|
130
|
+
// Ensure the fragment has the internal fragment linked
|
|
131
|
+
{ _fragno_internal: InternalFragmentInstance } & Record<string, AnyFragnoInstantiatedFragment>
|
|
132
|
+
>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Helper function to run migrations for a database fragment.
|
|
136
|
+
* Extracts the database adapter, schema, and namespace from the fragment and runs migrations.
|
|
137
|
+
* This function:
|
|
138
|
+
* 1. Ensures the internal settings fragment is migrated first
|
|
139
|
+
* 2. Retrieves the current database version from the internal fragment
|
|
140
|
+
* 3. Runs migration from current version to target version
|
|
141
|
+
*
|
|
142
|
+
* @param fragment - The instantiated fragment to run migrations for
|
|
143
|
+
* @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const fragment = instantiate(myFragmentDef)
|
|
148
|
+
* .withConfig({})
|
|
149
|
+
* .withRoutes([])
|
|
150
|
+
* .withOptions({ databaseAdapter: myAdapter })
|
|
151
|
+
* .build();
|
|
152
|
+
*
|
|
153
|
+
* await migrate(fragment);
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
export async function migrate(fragment: AnyFragnoInstantiatedDatabaseFragment): Promise<void> {
|
|
157
|
+
const { options, deps, linkedFragments } = fragment.$internal;
|
|
158
|
+
const adapter = options.databaseAdapter;
|
|
159
|
+
|
|
160
|
+
// Check if adapter supports prepareMigrations
|
|
161
|
+
if (!adapter.prepareMigrations) {
|
|
162
|
+
throw new Error(
|
|
163
|
+
"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.",
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const schema = deps.schema;
|
|
168
|
+
const namespace = deps.namespace;
|
|
169
|
+
|
|
170
|
+
// Step 1: Ensure the internal fragment (settings table) is migrated first
|
|
171
|
+
const internalFragment = linkedFragments._fragno_internal;
|
|
172
|
+
|
|
173
|
+
if (!internalFragment) {
|
|
174
|
+
throw new Error("Internal fragment not found. Please ensure the internal fragment is linked.");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (!(await adapter.isConnectionHealthy())) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
"Database connection is not healthy. Please check your database connection and try again.",
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const internalDeps = internalFragment.$internal.deps;
|
|
184
|
+
const internalSchema = internalDeps.schema;
|
|
185
|
+
const internalNamespace = internalDeps.namespace;
|
|
186
|
+
|
|
187
|
+
const internalCurrentVersion = await getSchemaVersionFromDatabase(
|
|
188
|
+
internalFragment,
|
|
189
|
+
internalNamespace,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
// Migrate internal fragment if needed
|
|
193
|
+
if (internalCurrentVersion < internalSchema.version) {
|
|
194
|
+
const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);
|
|
195
|
+
await internalMigrations.execute(internalCurrentVersion, internalSchema.version);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Step 2: Get current database version for this fragment's namespace
|
|
199
|
+
const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);
|
|
200
|
+
|
|
201
|
+
// Step 3: Run the migration from current version to target version
|
|
202
|
+
const targetVersion = schema.version;
|
|
203
|
+
|
|
204
|
+
if (currentVersion === targetVersion) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (currentVersion > targetVersion) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
`Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const migrations = adapter.prepareMigrations(schema, namespace);
|
|
215
|
+
await migrations.execute(currentVersion, targetVersion);
|
|
216
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AnyColumn } from "../schema/create";
|
|
2
|
+
import { createId } from "../id";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate a runtime default value for a column that has defaultTo$()
|
|
6
|
+
*
|
|
7
|
+
* Only generates values for runtime defaults (defaultTo$), NOT static defaults (defaultTo).
|
|
8
|
+
* Static defaults should be handled by the database via DEFAULT constraints.
|
|
9
|
+
*
|
|
10
|
+
* @param column - The column with a default value configuration
|
|
11
|
+
* @returns The generated default value, or undefined if the column has no runtime default
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export function generateRuntimeDefault(column: AnyColumn): unknown {
|
|
16
|
+
// Check if column has a default value configuration
|
|
17
|
+
if (!column.default) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// If it's a static default value (defaultTo), return undefined
|
|
22
|
+
// as the database should handle this via DEFAULT constraint
|
|
23
|
+
if ("value" in column.default) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// If it's a database-level special function (defaultTo(b => b.now())), return undefined
|
|
28
|
+
// as the database should handle this via DEFAULT NOW() or equivalent
|
|
29
|
+
if ("dbSpecial" in column.default) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Handle runtime defaults (defaultTo$)
|
|
34
|
+
const runtime = column.default.runtime;
|
|
35
|
+
|
|
36
|
+
if (runtime === "cuid") {
|
|
37
|
+
return createId();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (runtime === "now") {
|
|
41
|
+
return new Date();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (typeof runtime === "function") {
|
|
45
|
+
return runtime();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
package/src/query/cursor.test.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import { decodeCursor, createCursorFromRecord, serializeCursorValues, Cursor } from "./cursor";
|
|
3
3
|
import { column, idColumn, schema } from "../schema/create";
|
|
4
|
+
import {
|
|
5
|
+
BetterSQLite3DriverConfig,
|
|
6
|
+
MySQL2DriverConfig,
|
|
7
|
+
NodePostgresDriverConfig,
|
|
8
|
+
} from "../adapters/generic-sql/driver-config";
|
|
4
9
|
|
|
5
10
|
describe("Cursor utilities", () => {
|
|
6
11
|
describe("Cursor class encode and decode", () => {
|
|
@@ -245,7 +250,11 @@ describe("Cursor utilities", () => {
|
|
|
245
250
|
});
|
|
246
251
|
|
|
247
252
|
const indexColumns = [table.columns.id, table.columns.age];
|
|
248
|
-
const serialized = serializeCursorValues(
|
|
253
|
+
const serialized = serializeCursorValues(
|
|
254
|
+
cursor,
|
|
255
|
+
indexColumns,
|
|
256
|
+
new NodePostgresDriverConfig(),
|
|
257
|
+
);
|
|
249
258
|
|
|
250
259
|
expect(serialized).toHaveProperty("id", "user123");
|
|
251
260
|
expect(serialized).toHaveProperty("age", 25);
|
|
@@ -267,7 +276,11 @@ describe("Cursor utilities", () => {
|
|
|
267
276
|
});
|
|
268
277
|
|
|
269
278
|
const indexColumns = [table.columns.id, table.columns.name];
|
|
270
|
-
const serialized = serializeCursorValues(
|
|
279
|
+
const serialized = serializeCursorValues(
|
|
280
|
+
cursor,
|
|
281
|
+
indexColumns,
|
|
282
|
+
new NodePostgresDriverConfig(),
|
|
283
|
+
);
|
|
271
284
|
|
|
272
285
|
expect(serialized).toHaveProperty("id", "user123");
|
|
273
286
|
expect(serialized).not.toHaveProperty("name");
|
|
@@ -307,7 +320,11 @@ describe("Cursor utilities", () => {
|
|
|
307
320
|
const decoded = decodeCursor(cursor.encode());
|
|
308
321
|
|
|
309
322
|
// Serialize the values
|
|
310
|
-
const serialized = serializeCursorValues(
|
|
323
|
+
const serialized = serializeCursorValues(
|
|
324
|
+
decoded,
|
|
325
|
+
indexColumns,
|
|
326
|
+
new NodePostgresDriverConfig(),
|
|
327
|
+
);
|
|
311
328
|
|
|
312
329
|
// Should preserve the values
|
|
313
330
|
expect(serialized["score"]).toBe(42);
|
|
@@ -350,7 +367,11 @@ describe("Cursor utilities", () => {
|
|
|
350
367
|
expect(decoded.indexValues["createdAt"]).toBe("2025-11-07T09:36:57.959Z");
|
|
351
368
|
|
|
352
369
|
// Serialize should convert it back to Date for the database
|
|
353
|
-
const serialized = serializeCursorValues(
|
|
370
|
+
const serialized = serializeCursorValues(
|
|
371
|
+
decoded,
|
|
372
|
+
indexColumns,
|
|
373
|
+
new NodePostgresDriverConfig(),
|
|
374
|
+
);
|
|
354
375
|
|
|
355
376
|
// For PostgreSQL, Date objects should be passed through as-is
|
|
356
377
|
expect(serialized["createdAt"]).toBeInstanceOf(Date);
|
|
@@ -388,7 +409,11 @@ describe("Cursor utilities", () => {
|
|
|
388
409
|
const decoded = decodeCursor(cursor.encode());
|
|
389
410
|
|
|
390
411
|
// Serialize should convert string back to Date, then to timestamp number for SQLite
|
|
391
|
-
const serialized = serializeCursorValues(
|
|
412
|
+
const serialized = serializeCursorValues(
|
|
413
|
+
decoded,
|
|
414
|
+
indexColumns,
|
|
415
|
+
new BetterSQLite3DriverConfig(),
|
|
416
|
+
);
|
|
392
417
|
|
|
393
418
|
// For SQLite, Date should be converted to timestamp number
|
|
394
419
|
expect(typeof serialized["createdAt"]).toBe("number");
|
|
@@ -426,7 +451,7 @@ describe("Cursor utilities", () => {
|
|
|
426
451
|
const decoded = decodeCursor(cursor.encode());
|
|
427
452
|
|
|
428
453
|
// Serialize for MySQL
|
|
429
|
-
const serialized = serializeCursorValues(decoded, indexColumns,
|
|
454
|
+
const serialized = serializeCursorValues(decoded, indexColumns, new MySQL2DriverConfig());
|
|
430
455
|
|
|
431
456
|
// For MySQL, Date objects should be passed through as-is
|
|
432
457
|
expect(serialized["createdAt"]).toBeInstanceOf(Date);
|
package/src/query/cursor.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AnyColumn } from "../schema/create";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { createSQLSerializer } from "./serialize/create-sql-serializer";
|
|
3
|
+
import { resolveFragnoIdValue } from "./value-encoding";
|
|
4
|
+
import type { DriverConfig } from "../adapters/generic-sql/driver-config";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Cursor object containing all information needed for pagination
|
|
@@ -216,7 +217,7 @@ export function createCursorFromRecord(
|
|
|
216
217
|
*
|
|
217
218
|
* @param cursor - The cursor object
|
|
218
219
|
* @param indexColumns - The columns that make up the index
|
|
219
|
-
* @param
|
|
220
|
+
* @param driverConfig - The driver configuration
|
|
220
221
|
* @returns Serialized values ready for database queries
|
|
221
222
|
*
|
|
222
223
|
* @example
|
|
@@ -224,15 +225,16 @@ export function createCursorFromRecord(
|
|
|
224
225
|
* const serialized = serializeCursorValues(
|
|
225
226
|
* cursor,
|
|
226
227
|
* [table.columns.createdAt],
|
|
227
|
-
*
|
|
228
|
+
* driverConfig
|
|
228
229
|
* );
|
|
229
230
|
* ```
|
|
230
231
|
*/
|
|
231
232
|
export function serializeCursorValues(
|
|
232
233
|
cursor: Cursor,
|
|
233
234
|
indexColumns: AnyColumn[],
|
|
234
|
-
|
|
235
|
+
driverConfig: DriverConfig,
|
|
235
236
|
): Record<string, unknown> {
|
|
237
|
+
const serializer = createSQLSerializer(driverConfig);
|
|
236
238
|
const serialized: Record<string, unknown> = {};
|
|
237
239
|
|
|
238
240
|
for (const col of indexColumns) {
|
|
@@ -240,10 +242,12 @@ export function serializeCursorValues(
|
|
|
240
242
|
if (value !== undefined) {
|
|
241
243
|
// First deserialize from JSON format to application format
|
|
242
244
|
// (e.g., "2025-11-07T09:36:57.959Z" string → Date object)
|
|
243
|
-
const deserialized = deserialize(value, col
|
|
245
|
+
const deserialized = serializer.deserialize(value, col);
|
|
246
|
+
// Resolve FragnoId/FragnoReference to primitive values (if present)
|
|
247
|
+
const resolved = resolveFragnoIdValue(deserialized, col);
|
|
244
248
|
// Then serialize to database format
|
|
245
249
|
// (e.g., Date → database driver format)
|
|
246
|
-
serialized[col.ormName] = serialize(
|
|
250
|
+
serialized[col.ormName] = serializer.serialize(resolved, col);
|
|
247
251
|
}
|
|
248
252
|
}
|
|
249
253
|
|
package/src/query/orm/orm.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
FindManyOptions,
|
|
5
5
|
JoinBuilder,
|
|
6
6
|
OrderBy,
|
|
7
|
-
} from "../query";
|
|
7
|
+
} from "../simple-query-interface";
|
|
8
8
|
import { buildCondition, type Condition } from "../condition-builder";
|
|
9
9
|
import type { AnyColumn, AnyRelation, AnyTable } from "../../schema/create";
|
|
10
10
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { describe, expectTypeOf, it } from "vitest";
|
|
2
2
|
import { column, FragnoId, idColumn, referenceColumn, schema } from "../schema/create";
|
|
3
3
|
import type {
|
|
4
|
-
|
|
4
|
+
SimpleQueryInterface,
|
|
5
5
|
FindFirstOptions,
|
|
6
6
|
FindManyOptions,
|
|
7
7
|
JoinBuilder,
|
|
8
8
|
OrderBy,
|
|
9
9
|
SelectClause,
|
|
10
10
|
TableToInsertValues,
|
|
11
|
-
} from "./query";
|
|
11
|
+
} from "./simple-query-interface";
|
|
12
12
|
import type { ConditionBuilder } from "./condition-builder";
|
|
13
13
|
|
|
14
14
|
describe("query type tests", () => {
|
|
@@ -91,8 +91,8 @@ describe("query type tests", () => {
|
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
describe("
|
|
95
|
-
type Query =
|
|
94
|
+
describe("SimpleQueryInterface methods", () => {
|
|
95
|
+
type Query = SimpleQueryInterface<TestSchema>;
|
|
96
96
|
|
|
97
97
|
describe("findFirst", () => {
|
|
98
98
|
it("should return all columns when select is true or undefined", () => {
|
|
@@ -257,7 +257,7 @@ describe("query type tests", () => {
|
|
|
257
257
|
|
|
258
258
|
describe("table name type checking", () => {
|
|
259
259
|
it("should only allow valid table names", () => {
|
|
260
|
-
const _query = {} as
|
|
260
|
+
const _query = {} as SimpleQueryInterface<TestSchema>;
|
|
261
261
|
|
|
262
262
|
// Valid table names
|
|
263
263
|
type UsersParam = Parameters<typeof _query.find<"users">>;
|
|
@@ -272,7 +272,7 @@ describe("query type tests", () => {
|
|
|
272
272
|
|
|
273
273
|
describe("column type inference", () => {
|
|
274
274
|
it("should correctly infer column types for users table", () => {
|
|
275
|
-
const _query = {} as
|
|
275
|
+
const _query = {} as SimpleQueryInterface<TestSchema>;
|
|
276
276
|
type Result = Awaited<ReturnType<typeof _query.findFirst<"users">>>;
|
|
277
277
|
type User = Exclude<Result, null>;
|
|
278
278
|
|
|
@@ -284,7 +284,7 @@ describe("query type tests", () => {
|
|
|
284
284
|
});
|
|
285
285
|
|
|
286
286
|
it("should correctly infer column types for posts table", () => {
|
|
287
|
-
const _query = {} as
|
|
287
|
+
const _query = {} as SimpleQueryInterface<TestSchema>;
|
|
288
288
|
type Result = Awaited<ReturnType<typeof _query.findFirst<"posts">>>;
|
|
289
289
|
type Post = Exclude<Result, null>;
|
|
290
290
|
|
|
@@ -297,7 +297,7 @@ describe("query type tests", () => {
|
|
|
297
297
|
});
|
|
298
298
|
|
|
299
299
|
it("should correctly infer column types for comments table", () => {
|
|
300
|
-
const _query = {} as
|
|
300
|
+
const _query = {} as SimpleQueryInterface<TestSchema>;
|
|
301
301
|
type Result = Awaited<ReturnType<typeof _query.findFirst<"comments">>>;
|
|
302
302
|
type Comment = Exclude<Result, null>;
|
|
303
303
|
|
|
@@ -311,7 +311,7 @@ describe("query type tests", () => {
|
|
|
311
311
|
|
|
312
312
|
describe("complex scenarios", () => {
|
|
313
313
|
it("should handle multiple table operations with correct types", () => {
|
|
314
|
-
const _query = {} as
|
|
314
|
+
const _query = {} as SimpleQueryInterface<TestSchema>;
|
|
315
315
|
|
|
316
316
|
// Create user return type
|
|
317
317
|
type UserResult = Awaited<ReturnType<typeof _query.create<"users">>>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { DriverConfig } from "../../adapters/generic-sql/driver-config";
|
|
2
|
+
import { SQLSerializer } from "./sql-serializer";
|
|
3
|
+
import { SQLiteSerializer } from "./dialect/sqlite-serializer";
|
|
4
|
+
import { PostgreSQLSerializer } from "./dialect/postgres-serializer";
|
|
5
|
+
import { MySQLSerializer } from "./dialect/mysql-serializer";
|
|
6
|
+
|
|
7
|
+
// Re-export SQLSerializer for convenience
|
|
8
|
+
export { SQLSerializer } from "./sql-serializer";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Factory function to create a dialect-specific SQL serializer from a DriverConfig.
|
|
12
|
+
*
|
|
13
|
+
* Based on the database type, returns the appropriate serializer implementation
|
|
14
|
+
* (PostgreSQL, MySQL, or SQLite).
|
|
15
|
+
*
|
|
16
|
+
* @param driverConfig - The driver configuration
|
|
17
|
+
* @returns Dialect-specific SQLSerializer instance
|
|
18
|
+
*/
|
|
19
|
+
export function createSQLSerializer(driverConfig: DriverConfig): SQLSerializer {
|
|
20
|
+
// TODO: The serializers are pretty lenient in what they accept (lost of typeof checks), it may
|
|
21
|
+
// be beneficial to implement serializers per DriverConfig, and be less lenient.
|
|
22
|
+
switch (driverConfig.databaseType) {
|
|
23
|
+
case "postgresql":
|
|
24
|
+
return new PostgreSQLSerializer(driverConfig);
|
|
25
|
+
case "mysql":
|
|
26
|
+
return new MySQLSerializer(driverConfig);
|
|
27
|
+
case "sqlite":
|
|
28
|
+
return new SQLiteSerializer(driverConfig);
|
|
29
|
+
default: {
|
|
30
|
+
const exhaustiveCheck: never = driverConfig.databaseType;
|
|
31
|
+
throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { AnyColumn } from "../../../schema/create";
|
|
2
|
+
import { SQLSerializer } from "../sql-serializer";
|
|
3
|
+
import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* MySQL-specific serializer.
|
|
7
|
+
*
|
|
8
|
+
* MySQL has good native type support:
|
|
9
|
+
* - Native JSON support (MySQL 5.7+)
|
|
10
|
+
* - Native boolean type (TINYINT(1))
|
|
11
|
+
* - Native timestamp/datetime/date types
|
|
12
|
+
* - Native bigint support
|
|
13
|
+
*
|
|
14
|
+
* Similar to PostgreSQL, most values pass through without conversion.
|
|
15
|
+
* Timestamps/dates are returned as strings and need to be parsed.
|
|
16
|
+
*/
|
|
17
|
+
export class MySQLSerializer extends SQLSerializer {
|
|
18
|
+
constructor(driverConfig: DriverConfig) {
|
|
19
|
+
super(driverConfig);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected serializeDate(value: Date): Date {
|
|
23
|
+
// MySQL handles Date objects natively
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected serializeBoolean(value: boolean): boolean {
|
|
28
|
+
// MySQL handles boolean natively (as TINYINT(1))
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected serializeBigInt(value: bigint, _col: AnyColumn): bigint {
|
|
33
|
+
// MySQL handles bigint natively
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected deserializeDate(value: unknown): Date {
|
|
38
|
+
if (value instanceof Date) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
// MySQL returns timestamps/dates as strings
|
|
42
|
+
if (typeof value === "string") {
|
|
43
|
+
return new Date(value);
|
|
44
|
+
}
|
|
45
|
+
throw new Error(`Cannot deserialize date from value: ${value}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected deserializeBoolean(value: unknown): boolean {
|
|
49
|
+
if (typeof value === "boolean") {
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
// MySQL may return booleans as numbers (0/1)
|
|
53
|
+
if (typeof value === "number") {
|
|
54
|
+
return value === 1;
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`Cannot deserialize boolean from value: ${value}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected deserializeBigInt(value: unknown): bigint {
|
|
60
|
+
if (typeof value === "bigint") {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
// MySQL may return bigints as strings
|
|
64
|
+
if (typeof value === "string") {
|
|
65
|
+
return BigInt(value);
|
|
66
|
+
}
|
|
67
|
+
if (typeof value === "number") {
|
|
68
|
+
return BigInt(value);
|
|
69
|
+
}
|
|
70
|
+
throw new Error(`Cannot deserialize bigint from value: ${value}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected serializeJson(value: unknown): unknown {
|
|
74
|
+
// MySQL supports native JSON, pass through as-is
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
protected deserializeJson(value: unknown): unknown {
|
|
79
|
+
// MySQL returns parsed JSON objects, pass through as-is
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
protected deserializeBinary(value: unknown): Uint8Array {
|
|
84
|
+
// MySQL can return Buffer or Uint8Array for BLOB columns
|
|
85
|
+
if (value instanceof Buffer) {
|
|
86
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
87
|
+
}
|
|
88
|
+
if (value instanceof Uint8Array) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
if (value instanceof ArrayBuffer) {
|
|
92
|
+
return new Uint8Array(value);
|
|
93
|
+
}
|
|
94
|
+
throw new Error(`Cannot deserialize binary from value: ${typeof value}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected deserializeInteger(value: unknown): number {
|
|
98
|
+
if (typeof value === "number") {
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
// MySQL may return integers as strings
|
|
102
|
+
if (typeof value === "string") {
|
|
103
|
+
const num = Number(value);
|
|
104
|
+
if (isNaN(num)) {
|
|
105
|
+
throw new Error(`Cannot deserialize integer from invalid string: ${value}`);
|
|
106
|
+
}
|
|
107
|
+
return num;
|
|
108
|
+
}
|
|
109
|
+
// MySQL may return bigint for large integers
|
|
110
|
+
if (typeof value === "bigint") {
|
|
111
|
+
if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
|
|
112
|
+
throw new RangeError(
|
|
113
|
+
`Cannot deserialize integer value ${value}: exceeds safe integer range`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
return Number(value);
|
|
117
|
+
}
|
|
118
|
+
throw new Error(`Cannot deserialize integer from value: ${typeof value}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
protected deserializeDecimal(value: unknown): number {
|
|
122
|
+
// MySQL can return decimals as numbers or strings
|
|
123
|
+
if (typeof value === "number") {
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
if (typeof value === "string") {
|
|
127
|
+
const num = parseFloat(value);
|
|
128
|
+
if (isNaN(num)) {
|
|
129
|
+
throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
|
|
130
|
+
}
|
|
131
|
+
return num;
|
|
132
|
+
}
|
|
133
|
+
throw new Error(`Cannot deserialize decimal from value: ${typeof value}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected deserializeString(value: unknown): string {
|
|
137
|
+
if (typeof value === "string") {
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
throw new Error(`Cannot deserialize string from value: ${typeof value}`);
|
|
141
|
+
}
|
|
142
|
+
}
|