@fragno-dev/db 0.1.14 → 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.
Files changed (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","names":["defaultBuilder: DefaultBuilder","runtimeDefaultBuilder: RuntimeDefaultBuilder","#externalId","#internalId","#version","#name","#columns","#relations","#indexes","#columnOrder","column","idCol: AnyColumn | undefined","internalIdCol: AnyColumn | undefined","versionCol: AnyColumn | undefined","#ormName","table: Table<TColumns, TRelations, TIndexes>","#tables","#operations","schema","subOperations: TableSubOperation[]","cloneTables: Record<string, AnyTable>","clonedColumns: Record<string, AnyColumn>","clonedCol: AnyColumn"],"sources":["../../src/schema/create.ts"],"sourcesContent":["import { createId } from \"../id\";\n\nexport type AnySchema = Schema<Record<string, AnyTable>>;\n\nexport type AnyRelation = Relation;\n\nexport type AnyTable = Table;\n\nexport type AnyColumn =\n | Column<keyof TypeMap, unknown, unknown>\n | IdColumn<IdColumnType, unknown, unknown>\n | InternalIdColumn<unknown, unknown>\n | VersionColumn<unknown, unknown>;\n/**\n * Sub-operations that can be performed within table operations.\n * These are stored in order within add-table and alter-table operations.\n */\nexport type TableSubOperation =\n | { type: \"add-column\"; columnName: string; column: AnyColumn }\n | { type: \"add-index\"; name: string; columns: string[]; unique: boolean }\n | {\n type: \"add-foreign-key\";\n name: string;\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n };\n\n/**\n * Operations that can be performed on a schema during its definition.\n * These are tracked so we can generate migrations for specific version ranges.\n */\nexport type SchemaOperation =\n | {\n type: \"add-table\";\n tableName: string;\n operations: TableSubOperation[]; // Ordered list of sub-operations\n }\n | {\n type: \"alter-table\";\n tableName: string;\n operations: TableSubOperation[]; // Ordered list of sub-operations\n }\n | {\n type: \"add-reference\";\n tableName: string; // The table that has the foreign key\n referenceName: string;\n config: {\n type: \"one\" | \"many\";\n from: { table: string; column: string };\n to: { table: string; column: string };\n };\n };\n\nexport interface ForeignKey {\n name: string;\n table: AnyTable;\n columns: AnyColumn[];\n\n referencedTable: AnyTable;\n referencedColumns: AnyColumn[];\n}\n\nclass RelationInit<\n TRelationType extends RelationType,\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n> {\n type: TRelationType;\n referencedTable: TTables[TTableName];\n referencer: AnyTable;\n on: [string, string][] = [];\n\n constructor(type: TRelationType, referencedTable: TTables[TTableName], referencer: AnyTable) {\n this.type = type;\n this.referencedTable = referencedTable;\n this.referencer = referencer;\n }\n}\n\nexport interface Index<\n TColumns extends AnyColumn[] = AnyColumn[],\n TColumnNames extends readonly string[] = readonly string[],\n> {\n name: string;\n columns: TColumns;\n columnNames: TColumnNames;\n unique: boolean;\n}\n\nexport class ExplicitRelationInit<\n TRelationType extends RelationType,\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n> extends RelationInit<TRelationType, TTables, TTableName> {\n init(ormName: string): Relation<TRelationType, TTables[TTableName]> {\n const id = `${this.referencer.ormName}_${this.referencedTable.ormName}`;\n\n return {\n id,\n on: this.on,\n name: ormName,\n referencer: this.referencer,\n table: this.referencedTable,\n type: this.type,\n };\n }\n}\n\nexport interface Relation<\n TRelationType extends RelationType = RelationType,\n TTable extends AnyTable = AnyTable,\n> {\n id: string;\n name: string;\n type: TRelationType;\n\n table: TTable;\n referencer: AnyTable;\n\n on: [string, string][];\n}\n\nexport interface Table<\n TColumns extends Record<string, AnyColumn> = Record<string, AnyColumn>,\n TRelations extends Record<string, AnyRelation> = Record<string, AnyRelation>,\n TIndexes extends Record<string, Index> = Record<string, Index>,\n> {\n name: string;\n ormName: string;\n\n columns: TColumns;\n relations: TRelations;\n indexes: TIndexes;\n\n /**\n * Get column by name\n */\n getColumnByName: (name: string) => AnyColumn | undefined;\n /**\n * Get the external ID column (user-facing)\n */\n getIdColumn: () => AnyColumn;\n /**\n * Get the internal ID column (database-native, used for joins)\n */\n getInternalIdColumn: () => AnyColumn;\n /**\n * Get the version column (for optimistic concurrency control)\n */\n getVersionColumn: () => AnyColumn;\n}\n\ntype DBSpecial = { tag: \"special\"; value: \"now\" };\ntype RuntimeSpecial = { tag: \"special\"; value: \"cuid\" | \"now\" };\n\n/**\n * Builder for database-level default values.\n */\nexport interface DefaultBuilder {\n /** Database-generated timestamp (DEFAULT NOW()) */\n now(): DBSpecial;\n}\n\n/**\n * Builder for runtime-generated default values.\n */\nexport interface RuntimeDefaultBuilder {\n /** Generate CUID identifier */\n cuid(): RuntimeSpecial;\n /** Generate current timestamp */\n now(): RuntimeSpecial;\n}\n\nconst defaultBuilder: DefaultBuilder = {\n now: () => ({ tag: \"special\", value: \"now\" }),\n};\n\nconst runtimeDefaultBuilder: RuntimeDefaultBuilder = {\n cuid: () => ({ tag: \"special\", value: \"cuid\" }),\n now: () => ({ tag: \"special\", value: \"now\" }),\n};\n\ntype IdColumnType = `varchar(${number})`;\n\nexport type TypeMap = {\n string: string;\n bigint: bigint;\n integer: number;\n decimal: number;\n bool: boolean;\n json: unknown;\n /**\n * this follows the same specs as Prisma `Bytes` for consistency.\n */\n binary: Uint8Array;\n date: Date;\n timestamp: Date;\n} & Record<`varchar(${number})`, string>;\n\nexport class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown> {\n type: TType;\n name: string = \"\";\n ormName: string = \"\";\n isNullable: boolean = false;\n role: \"external-id\" | \"internal-id\" | \"version\" | \"reference\" | \"regular\" = \"regular\";\n isHidden: boolean = false;\n\n default?:\n | { value: TypeMap[TType] }\n | { dbSpecial: \"now\" }\n | { runtime: \"cuid\" | \"now\" | (() => TypeMap[TType]) };\n\n tableName: string = \"\";\n\n constructor(type: TType) {\n this.type = type;\n }\n\n nullable<TNullable extends boolean = true>(nullable?: TNullable) {\n this.isNullable = nullable ?? true;\n\n return this as Column<\n TType,\n TNullable extends true ? TIn | null : Exclude<TIn, null>,\n TNullable extends true ? TOut | null : Exclude<TOut, null>\n >;\n }\n\n hidden<THidden extends boolean = true>(hidden?: THidden) {\n this.isHidden = hidden ?? true;\n return this as Column<TType, null, null>;\n }\n\n /**\n * Generate default value at runtime in application code (not in the database).\n *\n * Use this when you need values generated in your application code, either because:\n * - Your database doesn't support the operation (e.g., generating CUIDs)\n * - You want consistent behavior across all databases\n * - You need custom generation logic\n *\n * @param value - Either a literal value or builder callback:\n * - Literal: Any static value of the column type\n * - `(b) => b.cuid()` - Generate a CUID identifier\n * - `(b) => b.now()` - Generate current timestamp\n * - `(b) => ...` - Custom function that returns the default value\n *\n * @example\n * ```ts\n * column(\"string\").defaultTo$((b) => b.cuid()) // Generate CUID at runtime\n * column(\"timestamp\").defaultTo$((b) => b.now()) // Generate timestamp at runtime\n * column(\"integer\").defaultTo$(42) // Static literal\n * column(\"integer\").defaultTo$((b) => Math.floor(Math.random() * 100)) // Custom function\n * ```\n */\n defaultTo$(\n value: TypeMap[TType] | ((builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType]),\n ): Column<TType, TIn | null, TOut> {\n if (typeof value === \"function\") {\n const fn = value as (builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType];\n const result = fn(runtimeDefaultBuilder);\n if (\n typeof result === \"object\" &&\n result !== null &&\n \"tag\" in result &&\n result.tag === \"special\"\n ) {\n this.default = { runtime: result.value };\n } else {\n // Custom function - we need to wrap the callback to call it again later\n this.default = { runtime: () => fn(runtimeDefaultBuilder) as TypeMap[TType] };\n }\n } else {\n // Direct literal value - wrap it in a function for runtime generation\n this.default = { runtime: () => value };\n }\n return this;\n }\n\n /**\n * Set a database-level default value (generated by the database, not application code).\n *\n * The database will generate the default value when inserting rows. If the database\n * doesn't support the operation, Fragno will fall back to generating the value in\n * application code.\n *\n * @param value - Either a literal value or builder callback:\n * - Literal: Any static value of the column type\n * - `(b) => b.now()` - Database-generated timestamp\n *\n * @example\n * ```ts\n * // Static defaults\n * column(\"string\").defaultTo(\"active\")\n * column(\"integer\").defaultTo(0)\n * column(\"boolean\").defaultTo(true)\n *\n * // Database-generated timestamp (with fallback)\n * column(\"timestamp\").defaultTo((b) => b.now())\n * ```\n */\n defaultTo(\n value: TypeMap[TType] | ((builder: DefaultBuilder) => DBSpecial | TypeMap[TType]),\n ): Column<TType, TIn | null, TOut> {\n if (typeof value === \"function\") {\n const fn = value as (builder: DefaultBuilder) => DBSpecial | TypeMap[TType];\n const result = fn(defaultBuilder);\n if (\n typeof result === \"object\" &&\n result !== null &&\n \"tag\" in result &&\n result.tag === \"special\"\n ) {\n this.default = { dbSpecial: result.value };\n } else {\n this.default = { value: result as TypeMap[TType] };\n }\n } else {\n this.default = { value };\n }\n return this;\n }\n\n /**\n * Generate default value for the column at runtime.\n * Used for both runtime defaults (defaultTo$) and fallback generation for\n * database defaults (defaultTo) when the database doesn't support them.\n */\n generateDefaultValue(): TypeMap[TType] | undefined {\n if (!this.default) {\n return;\n }\n\n if (\"value\" in this.default) {\n return this.default.value;\n }\n\n if (\"dbSpecial\" in this.default) {\n // Fallback generation for database-level special functions\n if (this.default.dbSpecial === \"now\") {\n return new Date(Date.now()) as TypeMap[TType];\n }\n return;\n }\n\n // Runtime defaults (defaultTo$)\n if (this.default.runtime === \"cuid\") {\n return createId() as TypeMap[TType];\n }\n if (this.default.runtime === \"now\") {\n return new Date(Date.now()) as TypeMap[TType];\n }\n\n // Custom function\n return this.default.runtime();\n }\n\n /**\n * @description This is used for type inference only. Runtime value will be undefined.\n * @internal\n */\n get $in(): TIn {\n return undefined as unknown as TIn;\n }\n\n /**\n * @description This is used for type inference only. Runtime value will be undefined.\n * @internal\n */\n get $out(): TOut {\n return undefined as unknown as TOut;\n }\n}\n\nexport class IdColumn<\n TType extends IdColumnType = IdColumnType,\n TIn = unknown,\n TOut = unknown,\n> extends Column<TType, TIn, TOut> {\n id = true;\n\n override defaultTo$(\n value: TypeMap[TType] | ((builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType]),\n ) {\n return super.defaultTo$(value) as IdColumn<TType, TIn | null, TOut>;\n }\n\n override defaultTo(\n value: TypeMap[TType] | ((builder: DefaultBuilder) => DBSpecial | TypeMap[TType]),\n ) {\n return super.defaultTo(value) as IdColumn<TType, TIn | null, TOut>;\n }\n}\n\n/**\n * Internal ID column - used for database-native joins and foreign keys.\n * Hidden from user API by default.\n */\nexport class InternalIdColumn<TIn = unknown, TOut = unknown> extends Column<\"bigint\", TIn, TOut> {\n override role = \"internal-id\" as const;\n\n constructor() {\n super(\"bigint\");\n this.hidden();\n }\n}\n\n/**\n * Version column - used for optimistic concurrency control.\n * Automatically incremented on each update.\n */\nexport class VersionColumn<TIn = unknown, TOut = unknown> extends Column<\"integer\", TIn, TOut> {\n override role = \"version\" as const;\n\n constructor() {\n super(\"integer\");\n this.defaultTo(0).hidden();\n }\n}\n\nexport function column<TType extends keyof TypeMap>(\n type: TType,\n): Column<TType, TypeMap[TType], TypeMap[TType]> {\n return new Column(type);\n}\n\n/**\n * Create a reference column that points to another table's internal ID.\n * This is used for foreign key relationships.\n * Always uses bigint to match the internal ID type.\n */\nexport function referenceColumn(): Column<\n \"bigint\",\n string | bigint | FragnoId | FragnoReference,\n FragnoReference\n> {\n const col = new Column<\"bigint\", string | bigint | FragnoId | FragnoReference, FragnoReference>(\n \"bigint\",\n );\n col.role = \"reference\";\n return col;\n}\n\n/**\n * Create an external ID column (user-facing).\n * This is a CUID string that can be auto-generated or user-provided.\n * Input accepts string | FragnoId | null, output returns FragnoId.\n */\nexport function idColumn(): IdColumn<\"varchar(30)\", string | FragnoId | null, FragnoId> {\n const col = new IdColumn<\"varchar(30)\", string | FragnoId | null, FragnoId>(\"varchar(30)\");\n col.role = \"external-id\";\n col.defaultTo$((b) => b.cuid());\n return col;\n}\n\n/**\n * Create an internal ID column (database-native, hidden from user API).\n * Used for joins and foreign keys.\n * @internal\n */\nexport function internalIdColumn(): InternalIdColumn<null, bigint> {\n const col = new InternalIdColumn<null, bigint>();\n col.role = \"internal-id\";\n col.hidden();\n return col;\n}\n\n/**\n * Create a version column for optimistic concurrency control.\n * @internal\n */\nexport function versionColumn(): VersionColumn<null, number> {\n const col = new VersionColumn<null, number>();\n col.role = \"version\";\n col.hidden();\n return col;\n}\n\n/**\n * FragnoId represents a unified ID object that can contain external ID, internal ID, or both.\n * @internal\n *\n * For query inputs: externalId is sufficient (internalId is optional)\n * For query results: both externalId and internalId are provided\n */\nexport class FragnoId {\n readonly #externalId: string;\n readonly #internalId?: bigint;\n readonly #version: number;\n\n constructor({\n externalId,\n internalId,\n version,\n }: {\n externalId: string;\n internalId?: bigint;\n version: number;\n }) {\n this.#externalId = externalId;\n this.#internalId = internalId;\n this.#version = version;\n }\n\n /**\n * Create a FragnoId from just an external ID (for inputs)\n */\n static fromExternal(externalId: string, version: number): FragnoId {\n return new FragnoId({ externalId, version });\n }\n\n get version(): number {\n return this.#version;\n }\n\n get externalId(): string {\n return this.#externalId;\n }\n\n get internalId(): bigint | undefined {\n return this.#internalId;\n }\n\n /**\n * Get the appropriate ID for database operations\n * Prefers internal ID if available, falls back to external ID\n */\n get databaseId(): string | bigint {\n return this.#internalId ?? this.#externalId;\n }\n\n /**\n * Convert to a plain object for serialization\n */\n toJSON(): { externalId: string; internalId?: string } {\n return {\n externalId: this.#externalId,\n internalId: this.#internalId?.toString(),\n };\n }\n\n toString(): string {\n return this.#externalId;\n }\n\n valueOf(): string {\n return this.#externalId;\n }\n}\n\n/**\n * FragnoReference represents a foreign key reference to another table's internal ID.\n * Unlike FragnoId, it only contains the internal ID (bigint) of the referenced record.\n * This is used for reference columns in query results.\n * @internal\n */\nexport class FragnoReference {\n readonly #internalId: bigint;\n\n constructor(internalId: bigint) {\n this.#internalId = internalId;\n }\n\n /**\n * Create a FragnoReference from an internal ID\n */\n static fromInternal(internalId: bigint): FragnoReference {\n return new FragnoReference(internalId);\n }\n\n /**\n * Get the internal ID for database operations\n */\n get internalId(): bigint {\n return this.#internalId;\n }\n}\n\ntype RelationType = \"one\" | \"many\";\n\nexport class TableBuilder<\n TColumns extends Record<string, AnyColumn> = Record<string, AnyColumn>,\n TRelations extends Record<string, AnyRelation> = Record<string, AnyRelation>,\n TIndexes extends Record<string, Index> = Record<string, Index>,\n> {\n #name: string;\n #columns: TColumns;\n #relations: TRelations;\n #indexes: TIndexes;\n #ormName: string = \"\";\n #columnOrder: string[] = [];\n\n constructor(name: string) {\n this.#name = name;\n this.#columns = {} as TColumns;\n this.#relations = {} as TRelations;\n this.#indexes = {} as TIndexes;\n }\n\n // For alterTable to set existing state\n setColumns(columns: TColumns): void {\n this.#columns = { ...columns };\n }\n\n setRelations(relations: TRelations): void {\n this.#relations = { ...relations };\n }\n\n setIndexes(indexes: TIndexes): void {\n this.#indexes = { ...indexes };\n }\n\n // For SchemaBuilder to read collected indexes\n getIndexes(): Index[] {\n return Object.values(this.#indexes) as Index[];\n }\n\n getColumnOrder(): string[] {\n return this.#columnOrder;\n }\n\n /**\n * Add a column to the table.\n */\n addColumn<TColumnName extends string, TColumn extends AnyColumn>(\n ormName: TColumnName,\n col: TColumn,\n ): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes>;\n\n /**\n * Add a column to the table with simplified syntax.\n */\n addColumn<TColumnName extends string, TType extends keyof TypeMap>(\n ormName: TColumnName,\n type: TType,\n ): TableBuilder<\n TColumns & Record<TColumnName, Column<TType, TypeMap[TType], TypeMap[TType]>>,\n TRelations,\n TIndexes\n >;\n\n addColumn<TColumnName extends string, TColumn extends AnyColumn, TType extends keyof TypeMap>(\n ormName: TColumnName,\n colOrType: TColumn | TType,\n ): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes> {\n // Create the column if a type string was provided\n const col = typeof colOrType === \"string\" ? column(colOrType) : colOrType;\n\n // Set column metadata\n col.ormName = ormName;\n col.name = ormName;\n\n // Add column directly to this builder\n this.#columns[ormName] = col as unknown as TColumns[TColumnName];\n this.#columnOrder.push(ormName);\n\n return this as unknown as TableBuilder<\n TColumns & Record<TColumnName, TColumn>,\n TRelations,\n TIndexes\n >;\n }\n\n /**\n * Create an index on the specified columns.\n */\n createIndex<\n TIndexName extends string,\n const TColumnNames extends readonly (string & keyof TColumns)[],\n >(\n name: TIndexName,\n columns: TColumnNames,\n options?: { unique?: boolean },\n ): TableBuilder<\n TColumns,\n TRelations,\n TIndexes & Record<TIndexName, Index<ColumnsToTuple<TColumns, TColumnNames>, TColumnNames>>\n > {\n const cols = columns.map((colName) => {\n const column = this.#columns[colName];\n if (!column) {\n throw new Error(`Unknown column name ${colName}`);\n }\n return column;\n });\n\n const unique = options?.unique ?? false;\n // Safe: we're adding the index to the internal indexes object\n this.#indexes[name] = {\n name,\n columns: cols,\n columnNames: columns,\n unique,\n } as unknown as TIndexes[TIndexName];\n\n return this as unknown as TableBuilder<\n TColumns,\n TRelations,\n TIndexes & Record<TIndexName, Index<ColumnsToTuple<TColumns, TColumnNames>, TColumnNames>>\n >;\n }\n\n /**\n * Build the final table. This should be called after all columns are added.\n */\n build(): Table<TColumns, TRelations, TIndexes> {\n let idCol: AnyColumn | undefined;\n let internalIdCol: AnyColumn | undefined;\n let versionCol: AnyColumn | undefined;\n\n // TODO: Throw if user manually added version/internalId columns\n\n // Auto-add _internalId and _version columns if not already present\n if (!this.#columns[\"_internalId\"]) {\n const col = internalIdColumn();\n col.ormName = \"_internalId\";\n col.name = \"_internalId\";\n // Safe: we're adding system columns to the internal columns object\n (this.#columns as Record<string, AnyColumn>)[\"_internalId\"] = col;\n }\n\n if (!this.#columns[\"_version\"]) {\n const col = versionColumn();\n col.ormName = \"_version\";\n col.name = \"_version\";\n // Safe: we're adding system columns to the internal columns object\n (this.#columns as Record<string, AnyColumn>)[\"_version\"] = col;\n }\n\n // Use name as ormName if ormName is not set\n const ormName = this.#ormName || this.#name;\n\n const table: Table<TColumns, TRelations, TIndexes> = {\n name: this.#name,\n ormName,\n columns: this.#columns,\n relations: this.#relations,\n indexes: this.#indexes,\n getColumnByName: (name) => {\n return Object.values(this.#columns).find((c) => c.name === name);\n },\n getIdColumn: () => {\n return idCol!;\n },\n getInternalIdColumn: () => {\n return internalIdCol!;\n },\n getVersionColumn: () => {\n return versionCol!;\n },\n };\n\n // Set table reference and find special columns\n for (const k in this.#columns) {\n const column = this.#columns[k];\n if (!column) {\n continue;\n }\n\n column.tableName = table.name;\n if (column instanceof IdColumn || column.role === \"external-id\") {\n idCol = column;\n }\n if (column instanceof InternalIdColumn || column.role === \"internal-id\") {\n internalIdCol = column;\n }\n if (column instanceof VersionColumn || column.role === \"version\") {\n versionCol = column;\n }\n }\n\n if (idCol === undefined) {\n throw new Error(`there's no id column in your table ${this.#name}`);\n }\n if (internalIdCol === undefined) {\n throw new Error(`there's no internal id column in your table ${this.#name}`);\n }\n if (versionCol === undefined) {\n throw new Error(`there's no version column in your table ${this.#name}`);\n }\n\n return table;\n }\n}\n\nexport interface Schema<TTables extends Record<string, AnyTable> = Record<string, AnyTable>> {\n /**\n * @description The version of the schema, automatically incremented on each change.\n */\n version: number;\n tables: TTables;\n /**\n * @description Operations performed on this schema, in order.\n * Used to generate migrations for specific version ranges.\n */\n operations: SchemaOperation[];\n\n clone: () => Schema<TTables>;\n}\n\n/**\n * Utility type for updating a single table's relations in a schema.\n * Used to properly type the return value of addReference.\n */\ntype UpdateTableRelations<\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n TReferenceName extends string,\n TReferencedTableName extends keyof TTables,\n TRelationType extends RelationType = RelationType,\n> = {\n [K in keyof TTables]: K extends TTableName\n ? Table<\n TTables[TTableName][\"columns\"],\n TTables[TTableName][\"relations\"] &\n Record<TReferenceName, Relation<TRelationType, TTables[TReferencedTableName]>>,\n TTables[TTableName][\"indexes\"]\n >\n : TTables[K];\n};\n\n/**\n * Utility type for updating a single table in a schema.\n * Used to properly type the return value of alterTable.\n */\ntype UpdateTable<\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n TNewColumns extends Record<string, AnyColumn>,\n TNewRelations extends Record<string, AnyRelation>,\n TNewIndexes extends Record<string, Index>,\n> = {\n [K in keyof TTables]: K extends TTableName\n ? Table<TNewColumns, TNewRelations, TNewIndexes>\n : TTables[K];\n};\n\n/**\n * Map an array of column names to a tuple of their actual column types\n */\ntype ColumnsToTuple<\n TColumns extends Record<string, AnyColumn>,\n TColumnNames extends readonly (keyof TColumns)[],\n> = {\n [K in keyof TColumnNames]: TColumnNames[K] extends keyof TColumns\n ? TColumns[TColumnNames[K]]\n : never;\n} & AnyColumn[];\n\nexport class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {\n #tables: TTables;\n #version: number = 0;\n #operations: SchemaOperation[] = [];\n\n constructor(existingSchema?: Schema<TTables>) {\n if (existingSchema) {\n this.#tables = existingSchema.tables;\n this.#version = existingSchema.version;\n this.#operations = [...existingSchema.operations];\n } else {\n this.#tables = {} as TTables;\n }\n }\n\n /**\n * Add an existing schema to this builder.\n * Merges tables and operations from the provided schema.\n *\n * @example\n * ```ts\n * const builder = new SchemaBuilder()\n * .add(userSchema)\n * .add(postSchema)\n * .addTable(\"comments\", ...);\n * ```\n */\n mergeWithExistingSchema<TNewTables extends Record<string, AnyTable>>(\n schema: Schema<TNewTables>,\n ): SchemaBuilder<TTables & TNewTables> {\n this.#tables = { ...this.#tables, ...schema.tables } as TTables & TNewTables;\n this.#operations = [...this.#operations, ...schema.operations];\n this.#version += schema.version;\n\n return this as unknown as SchemaBuilder<TTables & TNewTables>;\n }\n\n /**\n * Add a table to the schema. Increments the version counter.\n */\n addTable<\n TTableName extends string,\n TColumns extends Record<string, AnyColumn>,\n TRelations extends Record<string, AnyRelation>,\n TIndexes extends Record<string, Index> = Record<string, Index>,\n >(\n ormName: TTableName,\n callback: (\n builder: TableBuilder<\n Record<string, AnyColumn>,\n Record<string, AnyRelation>,\n Record<string, Index>\n >,\n ) => TableBuilder<TColumns, TRelations, TIndexes>,\n ): SchemaBuilder<TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>> {\n this.#version++;\n\n const tableBuilder = new TableBuilder(ormName);\n const result = callback(tableBuilder);\n const builtTable = result.build();\n builtTable.ormName = ormName;\n\n // Collect sub-operations in order\n const subOperations: TableSubOperation[] = [];\n\n // Add user-defined columns first\n const columnOrder = result.getColumnOrder();\n for (const colName of columnOrder) {\n const col = builtTable.columns[colName];\n subOperations.push({\n type: \"add-column\",\n columnName: colName,\n column: col,\n });\n }\n\n // Add system columns (_internalId and _version) that were auto-added\n if (builtTable.columns[\"_internalId\"]) {\n subOperations.push({\n type: \"add-column\",\n columnName: \"_internalId\",\n column: builtTable.columns[\"_internalId\"],\n });\n }\n if (builtTable.columns[\"_version\"]) {\n subOperations.push({\n type: \"add-column\",\n columnName: \"_version\",\n column: builtTable.columns[\"_version\"],\n });\n }\n\n // Add indexes from builder\n for (const idx of result.getIndexes()) {\n subOperations.push({\n type: \"add-index\",\n name: idx.name,\n columns: idx.columns.map((c) => c.ormName),\n unique: idx.unique,\n });\n }\n\n // Add the add-table operation\n this.#operations.push({\n type: \"add-table\",\n tableName: ormName,\n operations: subOperations,\n });\n\n // Update tables map\n this.#tables = { ...this.#tables, [ormName]: builtTable } as TTables &\n Record<TTableName, Table<TColumns, TRelations, TIndexes>>;\n\n return this as unknown as SchemaBuilder<\n TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>\n >;\n }\n\n /**\n * Add a relation between two tables.\n *\n * @param referenceName - A name for this relation (e.g., \"author\", \"posts\")\n * @param config - Configuration specifying the relation type and foreign key mapping\n *\n * @example\n * ```ts\n * // One-to-one or many-to-one: post -> user\n * schema(s => s\n * .addTable(\"users\", t => t.addColumn(\"id\", idColumn()))\n * .addTable(\"posts\", t => t\n * .addColumn(\"id\", idColumn())\n * .addColumn(\"userId\", referenceColumn()))\n * .addReference(\"author\", {\n * type: \"one\",\n * from: { table: \"posts\", column: \"userId\" },\n * to: { table: \"users\", column: \"id\" },\n * })\n * )\n *\n * // One-to-many (inverse relation): user -> posts\n * .addReference(\"posts\", {\n * type: \"many\",\n * from: { table: \"users\", column: \"id\" },\n * to: { table: \"posts\", column: \"userId\" },\n * })\n *\n * // Self-referencing foreign key\n * .addReference(\"inviter\", {\n * type: \"one\",\n * from: { table: \"users\", column: \"invitedBy\" },\n * to: { table: \"users\", column: \"id\" },\n * })\n * ```\n */\n addReference<\n TFromTableName extends string & keyof TTables,\n TToTableName extends string & keyof TTables,\n TReferenceName extends string,\n TRelationType extends RelationType,\n >(\n referenceName: TReferenceName,\n config: {\n type: TRelationType;\n from: {\n table: TFromTableName;\n column: keyof TTables[TFromTableName][\"columns\"];\n };\n to: {\n table: TToTableName;\n column: keyof TTables[TToTableName][\"columns\"];\n };\n },\n ): SchemaBuilder<\n UpdateTableRelations<TTables, TFromTableName, TReferenceName, TToTableName, TRelationType>\n > {\n this.#version++;\n\n const table = this.#tables[config.from.table];\n const referencedTable = this.#tables[config.to.table];\n\n if (!table) {\n throw new Error(`Table ${config.from.table} not found in schema`);\n }\n if (!referencedTable) {\n throw new Error(`Referenced table ${config.to.table} not found in schema`);\n }\n\n const columnName = config.from.column as string;\n const targetColumnName = config.to.column as string;\n\n // Foreign keys always reference internal IDs, not external IDs\n // If user specifies \"id\", translate to \"_internalId\" for the actual FK\n const actualTargetColumnName = targetColumnName === \"id\" ? \"_internalId\" : targetColumnName;\n\n const column = table.columns[columnName];\n const referencedColumn = referencedTable.columns[actualTargetColumnName];\n\n if (!column) {\n throw new Error(`Column ${columnName} not found in table ${config.from.table}`);\n }\n if (!referencedColumn) {\n throw new Error(`Column ${actualTargetColumnName} not found in table ${config.to.table}`);\n }\n\n // Verify that reference columns are bigint (matching internal ID type)\n if (column.role === \"reference\" && column.type !== \"bigint\") {\n throw new Error(\n `Reference column ${columnName} must be of type bigint to match internal ID type`,\n );\n }\n\n // Create the relation (use the user-facing column name for the relation)\n const init = new ExplicitRelationInit(config.type, referencedTable, table);\n init.on.push([columnName, targetColumnName]);\n const relation = init.init(referenceName);\n\n // Add relation to the table\n table.relations[referenceName] = relation;\n\n // Record the operation\n this.#operations.push({\n type: \"add-reference\",\n tableName: config.from.table,\n referenceName,\n config: {\n type: config.type,\n from: { table: config.from.table, column: columnName },\n to: { table: config.to.table, column: actualTargetColumnName },\n },\n });\n\n // Return this with updated type\n // Safe: The relation was added to the table in place and now has the updated relations\n return this as unknown as SchemaBuilder<\n UpdateTableRelations<TTables, TFromTableName, TReferenceName, TToTableName, TRelationType>\n >;\n }\n\n /**\n * Alter an existing table by adding columns or indexes.\n * This is used for append-only schema modifications.\n *\n * @param tableName - The name of the table to modify\n * @param callback - A callback that receives a table builder for adding columns/indexes\n *\n * @example\n * ```ts\n * // Add a new column to an existing table\n * schema(s => s\n * .addTable(\"users\", t => t\n * .addColumn(\"id\", idColumn())\n * .addColumn(\"name\", column(\"string\")))\n * .alterTable(\"users\", t => t\n * .addColumn(\"email\", column(\"string\"))\n * .addColumn(\"age\", column(\"integer\").nullable())\n * .createIndex(\"idx_email\", [\"email\"]))\n * )\n * ```\n */\n alterTable<\n TTableName extends string & keyof TTables,\n TNewColumns extends Record<string, AnyColumn>,\n TNewRelations extends Record<string, AnyRelation>,\n TNewIndexes extends Record<string, Index> = Record<string, Index>,\n >(\n tableName: TTableName,\n callback: (\n builder: TableBuilder<\n TTables[TTableName][\"columns\"],\n TTables[TTableName][\"relations\"],\n Record<string, Index>\n >,\n ) => TableBuilder<TNewColumns, TNewRelations, TNewIndexes>,\n ): SchemaBuilder<UpdateTable<TTables, TTableName, TNewColumns, TNewRelations, TNewIndexes>> {\n const table = this.#tables[tableName];\n\n if (!table) {\n throw new Error(`Table ${tableName} not found in schema`);\n }\n\n // Create builder with existing table state\n const tableBuilder = new TableBuilder(tableName);\n tableBuilder.setColumns(table.columns);\n tableBuilder.setRelations(table.relations);\n tableBuilder.setIndexes(table.indexes);\n\n // Track existing columns and indexes\n const existingColumns = new Set(Object.keys(table.columns));\n const existingIndexes = new Set(Object.keys(table.indexes));\n\n // Apply modifications\n const resultBuilder = callback(\n tableBuilder as TableBuilder<\n TTables[TTableName][\"columns\"],\n TTables[TTableName][\"relations\"],\n Record<string, Index>\n >,\n );\n const newTable = resultBuilder.build();\n\n // Collect sub-operations\n const subOperations: TableSubOperation[] = [];\n\n // Find new columns (preserve order from builder)\n const columnOrder = resultBuilder.getColumnOrder();\n for (const colName of columnOrder) {\n if (!existingColumns.has(colName)) {\n subOperations.push({\n type: \"add-column\",\n columnName: colName,\n column: newTable.columns[colName],\n });\n }\n }\n\n // Add only new indexes\n for (const idx of resultBuilder.getIndexes()) {\n if (!existingIndexes.has(idx.name)) {\n subOperations.push({\n type: \"add-index\",\n name: idx.name,\n columns: idx.columns.map((c) => c.ormName),\n unique: idx.unique,\n });\n }\n }\n\n if (subOperations.length > 0) {\n this.#version++;\n this.#operations.push({\n type: \"alter-table\",\n tableName,\n operations: subOperations,\n });\n }\n\n // Update table reference in schema\n this.#tables[tableName] = newTable as unknown as TTables[TTableName];\n\n // Set table name for all columns\n for (const col of Object.values(newTable.columns)) {\n col.tableName = newTable.name;\n }\n\n return this as unknown as SchemaBuilder<\n UpdateTable<TTables, TTableName, TNewColumns, TNewRelations, TNewIndexes>\n >;\n }\n\n /**\n * Build the final schema. This should be called after all tables are added.\n */\n build(): Schema<TTables> {\n const operations = this.#operations;\n const version = this.#version;\n const tables = this.#tables;\n\n const schema: Schema<TTables> = {\n version,\n tables,\n operations,\n clone: () => {\n const cloneTables: Record<string, AnyTable> = {};\n\n for (const [k, v] of Object.entries(tables)) {\n // Create a new table with cloned columns\n const clonedColumns: Record<string, AnyColumn> = {};\n for (const [colName, col] of Object.entries(v.columns)) {\n // Create a new column with the same properties, preserving the column type\n let clonedCol: AnyColumn;\n if (col instanceof InternalIdColumn) {\n clonedCol = new InternalIdColumn();\n } else if (col instanceof VersionColumn) {\n clonedCol = new VersionColumn();\n } else if (col instanceof IdColumn) {\n clonedCol = new IdColumn(col.type);\n } else {\n clonedCol = new Column(col.type);\n }\n\n clonedCol.name = col.name;\n clonedCol.ormName = col.ormName;\n clonedCol.isNullable = col.isNullable;\n clonedCol.role = col.role;\n clonedCol.isHidden = col.isHidden;\n clonedCol.default = col.default;\n clonedCol.tableName = col.tableName;\n clonedColumns[colName] = clonedCol;\n }\n\n cloneTables[k] = {\n ...v,\n columns: clonedColumns,\n };\n }\n\n return new SchemaBuilder<TTables>({\n version,\n tables: cloneTables as TTables,\n operations: [...operations],\n clone: () => {\n throw new Error(\"Cannot clone during clone\");\n },\n }).build();\n },\n };\n\n return schema;\n }\n\n /**\n * Get the current version of the schema builder.\n */\n getVersion(): number {\n return this.#version;\n }\n}\n\n/**\n * Create a new schema with callback pattern.\n */\nexport function schema<const TTables extends Record<string, AnyTable> = {}>(\n callback: (builder: SchemaBuilder<{}>) => SchemaBuilder<TTables>,\n): Schema<TTables> {\n return callback(new SchemaBuilder()).build();\n}\n\nexport function compileForeignKey(key: ForeignKey, nameType: \"sql\" | \"orm\" = \"orm\") {\n return {\n name: key.name,\n table: nameType === \"sql\" ? key.table.name : key.table.ormName,\n referencedTable: nameType === \"sql\" ? key.referencedTable.name : key.referencedTable.ormName,\n referencedColumns: key.referencedColumns.map((col) =>\n nameType === \"sql\" ? col.name : col.ormName,\n ),\n columns: key.columns.map((col) => (nameType === \"sql\" ? col.name : col.ormName)),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"create.js","names":["defaultBuilder: DefaultBuilder","runtimeDefaultBuilder: RuntimeDefaultBuilder","#externalId","#internalId","#version","#name","#columns","#relations","#indexes","#columnOrder","column","idCol: AnyColumn | undefined","internalIdCol: AnyColumn | undefined","versionCol: AnyColumn | undefined","#ormName","table: Table<TColumns, TRelations, TIndexes>","#tables","#operations","schema","subOperations: TableSubOperation[]","cloneTables: Record<string, AnyTable>","clonedColumns: Record<string, AnyColumn>","clonedCol: AnyColumn"],"sources":["../../src/schema/create.ts"],"sourcesContent":["import { createId } from \"../id\";\nimport { inspect } from \"node:util\";\n\nexport type AnySchema = Schema<Record<string, AnyTable>>;\n\nexport type AnyRelation = Relation;\n\nexport type AnyTable = Table;\n\nexport type AnyColumn =\n | Column<keyof TypeMap, unknown, unknown>\n | IdColumn<IdColumnType, unknown, unknown>\n | InternalIdColumn<unknown, unknown>\n | VersionColumn<unknown, unknown>;\n/**\n * Sub-operations that can be performed within table operations.\n * These are stored in order within add-table and alter-table operations.\n */\nexport type TableSubOperation =\n | { type: \"add-column\"; columnName: string; column: AnyColumn }\n | { type: \"add-index\"; name: string; columns: string[]; unique: boolean }\n | {\n type: \"add-foreign-key\";\n name: string;\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n };\n\n/**\n * Operations that can be performed on a schema during its definition.\n * These are tracked so we can generate migrations for specific version ranges.\n */\nexport type SchemaOperation =\n | {\n type: \"add-table\";\n tableName: string;\n operations: TableSubOperation[]; // Ordered list of sub-operations\n }\n | {\n type: \"alter-table\";\n tableName: string;\n operations: TableSubOperation[]; // Ordered list of sub-operations\n }\n | {\n type: \"add-reference\";\n tableName: string; // The table that has the foreign key\n referenceName: string;\n config: {\n type: \"one\" | \"many\";\n from: { table: string; column: string };\n to: { table: string; column: string };\n };\n };\n\nexport interface ForeignKey {\n name: string;\n table: AnyTable;\n columns: AnyColumn[];\n\n referencedTable: AnyTable;\n referencedColumns: AnyColumn[];\n}\n\nclass RelationInit<\n TRelationType extends RelationType,\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n> {\n type: TRelationType;\n referencedTable: TTables[TTableName];\n referencer: AnyTable;\n on: [string, string][] = [];\n\n constructor(type: TRelationType, referencedTable: TTables[TTableName], referencer: AnyTable) {\n this.type = type;\n this.referencedTable = referencedTable;\n this.referencer = referencer;\n }\n}\n\nexport interface Index<\n TColumns extends AnyColumn[] = AnyColumn[],\n TColumnNames extends readonly string[] = readonly string[],\n> {\n name: string;\n columns: TColumns;\n columnNames: TColumnNames;\n unique: boolean;\n}\n\nexport class ExplicitRelationInit<\n TRelationType extends RelationType,\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n> extends RelationInit<TRelationType, TTables, TTableName> {\n init(ormName: string): Relation<TRelationType, TTables[TTableName]> {\n const id = `${this.referencer.ormName}_${this.referencedTable.ormName}`;\n\n return {\n id,\n on: this.on,\n name: ormName,\n referencer: this.referencer,\n table: this.referencedTable,\n type: this.type,\n };\n }\n}\n\nexport interface Relation<\n TRelationType extends RelationType = RelationType,\n TTable extends AnyTable = AnyTable,\n> {\n id: string;\n name: string;\n type: TRelationType;\n\n table: TTable;\n referencer: AnyTable;\n\n on: [string, string][];\n}\n\nexport interface Table<\n TColumns extends Record<string, AnyColumn> = Record<string, AnyColumn>,\n TRelations extends Record<string, AnyRelation> = Record<string, AnyRelation>,\n TIndexes extends Record<string, Index> = Record<string, Index>,\n> {\n name: string;\n ormName: string;\n\n columns: TColumns;\n relations: TRelations;\n indexes: TIndexes;\n\n /**\n * Get column by name\n */\n getColumnByName: (name: string) => AnyColumn | undefined;\n /**\n * Get the external ID column (user-facing)\n */\n getIdColumn: () => AnyColumn;\n /**\n * Get the internal ID column (database-native, used for joins)\n */\n getInternalIdColumn: () => AnyColumn;\n /**\n * Get the version column (for optimistic concurrency control)\n */\n getVersionColumn: () => AnyColumn;\n}\n\ntype DBSpecial = { tag: \"special\"; value: \"now\" };\ntype RuntimeSpecial = { tag: \"special\"; value: \"cuid\" | \"now\" };\n\n/**\n * Builder for database-level default values.\n */\nexport interface DefaultBuilder {\n /** Database-generated timestamp (DEFAULT NOW()) */\n now(): DBSpecial;\n}\n\n/**\n * Builder for runtime-generated default values.\n */\nexport interface RuntimeDefaultBuilder {\n /** Generate CUID identifier */\n cuid(): RuntimeSpecial;\n /** Generate current timestamp */\n now(): RuntimeSpecial;\n}\n\nconst defaultBuilder: DefaultBuilder = {\n now: () => ({ tag: \"special\", value: \"now\" }),\n};\n\nconst runtimeDefaultBuilder: RuntimeDefaultBuilder = {\n cuid: () => ({ tag: \"special\", value: \"cuid\" }),\n now: () => ({ tag: \"special\", value: \"now\" }),\n};\n\ntype IdColumnType = `varchar(${number})`;\n\nexport type TypeMap = {\n string: string;\n bigint: bigint;\n integer: number;\n decimal: number;\n bool: boolean;\n json: unknown;\n /**\n * this follows the same specs as Prisma `Bytes` for consistency.\n */\n binary: Uint8Array;\n date: Date;\n timestamp: Date;\n} & Record<`varchar(${number})`, string>;\n\nexport class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown> {\n type: TType;\n name: string = \"\";\n ormName: string = \"\";\n isNullable: boolean = false;\n role: \"external-id\" | \"internal-id\" | \"version\" | \"reference\" | \"regular\" = \"regular\";\n isHidden: boolean = false;\n\n default?:\n | { value: TypeMap[TType] }\n | { dbSpecial: \"now\" }\n | { runtime: \"cuid\" | \"now\" | (() => TypeMap[TType]) };\n\n tableName: string = \"\";\n\n constructor(type: TType) {\n this.type = type;\n }\n\n nullable<TNullable extends boolean = true>(nullable?: TNullable) {\n this.isNullable = nullable ?? true;\n\n return this as Column<\n TType,\n TNullable extends true ? TIn | null : Exclude<TIn, null>,\n TNullable extends true ? TOut | null : Exclude<TOut, null>\n >;\n }\n\n hidden<THidden extends boolean = true>(hidden?: THidden) {\n this.isHidden = hidden ?? true;\n return this as Column<TType, null, null>;\n }\n\n /**\n * Generate default value at runtime in application code (not in the database).\n *\n * Use this when you need values generated in your application code, either because:\n * - Your database doesn't support the operation (e.g., generating CUIDs)\n * - You want consistent behavior across all databases\n * - You need custom generation logic\n *\n * @param value - Either a literal value or builder callback:\n * - Literal: Any static value of the column type\n * - `(b) => b.cuid()` - Generate a CUID identifier\n * - `(b) => b.now()` - Generate current timestamp\n * - `(b) => ...` - Custom function that returns the default value\n *\n * @example\n * ```ts\n * column(\"string\").defaultTo$((b) => b.cuid()) // Generate CUID at runtime\n * column(\"timestamp\").defaultTo$((b) => b.now()) // Generate timestamp at runtime\n * column(\"integer\").defaultTo$(42) // Static literal\n * column(\"integer\").defaultTo$((b) => Math.floor(Math.random() * 100)) // Custom function\n * ```\n */\n defaultTo$(\n value: TypeMap[TType] | ((builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType]),\n ): Column<TType, TIn | null, TOut> {\n if (typeof value === \"function\") {\n const fn = value as (builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType];\n const result = fn(runtimeDefaultBuilder);\n if (\n typeof result === \"object\" &&\n result !== null &&\n \"tag\" in result &&\n result.tag === \"special\"\n ) {\n this.default = { runtime: result.value };\n } else {\n // Custom function - we need to wrap the callback to call it again later\n this.default = { runtime: () => fn(runtimeDefaultBuilder) as TypeMap[TType] };\n }\n } else {\n // Direct literal value - wrap it in a function for runtime generation\n this.default = { runtime: () => value };\n }\n return this;\n }\n\n /**\n * Set a database-level default value (generated by the database, not application code).\n *\n * The database will generate the default value when inserting rows. If the database\n * doesn't support the operation, Fragno will fall back to generating the value in\n * application code.\n *\n * @param value - Either a literal value or builder callback:\n * - Literal: Any static value of the column type\n * - `(b) => b.now()` - Database-generated timestamp\n *\n * @example\n * ```ts\n * // Static defaults\n * column(\"string\").defaultTo(\"active\")\n * column(\"integer\").defaultTo(0)\n * column(\"boolean\").defaultTo(true)\n *\n * // Database-generated timestamp (with fallback)\n * column(\"timestamp\").defaultTo((b) => b.now())\n * ```\n */\n defaultTo(\n value: TypeMap[TType] | ((builder: DefaultBuilder) => DBSpecial | TypeMap[TType]),\n ): Column<TType, TIn | null, TOut> {\n if (typeof value === \"function\") {\n const fn = value as (builder: DefaultBuilder) => DBSpecial | TypeMap[TType];\n const result = fn(defaultBuilder);\n if (\n typeof result === \"object\" &&\n result !== null &&\n \"tag\" in result &&\n result.tag === \"special\"\n ) {\n this.default = { dbSpecial: result.value };\n } else {\n this.default = { value: result as TypeMap[TType] };\n }\n } else {\n this.default = { value };\n }\n return this;\n }\n\n /**\n * Generate default value for the column at runtime.\n * Used for both runtime defaults (defaultTo$) and fallback generation for\n * database defaults (defaultTo) when the database doesn't support them.\n */\n generateDefaultValue(): TypeMap[TType] | undefined {\n if (!this.default) {\n return;\n }\n\n if (\"value\" in this.default) {\n return this.default.value;\n }\n\n if (\"dbSpecial\" in this.default) {\n // Fallback generation for database-level special functions\n if (this.default.dbSpecial === \"now\") {\n return new Date(Date.now()) as TypeMap[TType];\n }\n return;\n }\n\n // Runtime defaults (defaultTo$)\n if (this.default.runtime === \"cuid\") {\n return createId() as TypeMap[TType];\n }\n if (this.default.runtime === \"now\") {\n return new Date(Date.now()) as TypeMap[TType];\n }\n\n // Custom function\n return this.default.runtime();\n }\n\n /**\n * @description This is used for type inference only. Runtime value will be undefined.\n * @internal\n */\n get $in(): TIn {\n return undefined as unknown as TIn;\n }\n\n /**\n * @description This is used for type inference only. Runtime value will be undefined.\n * @internal\n */\n get $out(): TOut {\n return undefined as unknown as TOut;\n }\n}\n\nexport class IdColumn<\n TType extends IdColumnType = IdColumnType,\n TIn = unknown,\n TOut = unknown,\n> extends Column<TType, TIn, TOut> {\n id = true;\n\n override defaultTo$(\n value: TypeMap[TType] | ((builder: RuntimeDefaultBuilder) => RuntimeSpecial | TypeMap[TType]),\n ) {\n return super.defaultTo$(value) as IdColumn<TType, TIn | null, TOut>;\n }\n\n override defaultTo(\n value: TypeMap[TType] | ((builder: DefaultBuilder) => DBSpecial | TypeMap[TType]),\n ) {\n return super.defaultTo(value) as IdColumn<TType, TIn | null, TOut>;\n }\n}\n\n/**\n * Internal ID column - used for database-native joins and foreign keys.\n * Hidden from user API by default.\n */\nexport class InternalIdColumn<TIn = unknown, TOut = unknown> extends Column<\"bigint\", TIn, TOut> {\n override role = \"internal-id\" as const;\n\n constructor() {\n super(\"bigint\");\n this.hidden();\n }\n}\n\n/**\n * Version column - used for optimistic concurrency control.\n * Automatically incremented on each update.\n */\nexport class VersionColumn<TIn = unknown, TOut = unknown> extends Column<\"integer\", TIn, TOut> {\n override role = \"version\" as const;\n\n constructor() {\n super(\"integer\");\n this.defaultTo(0).hidden();\n }\n}\n\nexport function column<TType extends keyof TypeMap>(\n type: TType,\n): Column<TType, TypeMap[TType], TypeMap[TType]> {\n return new Column(type);\n}\n\n/**\n * Create a reference column that points to another table's internal ID.\n * This is used for foreign key relationships.\n * Always uses bigint to match the internal ID type.\n */\nexport function referenceColumn(): Column<\n \"bigint\",\n string | bigint | FragnoId | FragnoReference,\n FragnoReference\n> {\n const col = new Column<\"bigint\", string | bigint | FragnoId | FragnoReference, FragnoReference>(\n \"bigint\",\n );\n col.role = \"reference\";\n return col;\n}\n\n/**\n * Create an external ID column (user-facing).\n * This is a CUID string that can be auto-generated or user-provided.\n * Input accepts string | FragnoId | null, output returns FragnoId.\n */\nexport function idColumn(): IdColumn<\"varchar(30)\", string | FragnoId | null, FragnoId> {\n const col = new IdColumn<\"varchar(30)\", string | FragnoId | null, FragnoId>(\"varchar(30)\");\n col.role = \"external-id\";\n col.defaultTo$((b) => b.cuid());\n return col;\n}\n\n/**\n * Create an internal ID column (database-native, hidden from user API).\n * Used for joins and foreign keys.\n * @internal\n */\nexport function internalIdColumn(): InternalIdColumn<null, bigint> {\n const col = new InternalIdColumn<null, bigint>();\n col.role = \"internal-id\";\n col.hidden();\n return col;\n}\n\n/**\n * Create a version column for optimistic concurrency control.\n * @internal\n */\nexport function versionColumn(): VersionColumn<null, number> {\n const col = new VersionColumn<null, number>();\n col.role = \"version\";\n col.hidden();\n return col;\n}\n\n/**\n * FragnoId represents a unified ID object that can contain external ID, internal ID, or both.\n * @internal\n *\n * For query inputs: externalId is sufficient (internalId is optional)\n * For query results: both externalId and internalId are provided\n */\nexport class FragnoId {\n readonly #externalId: string;\n readonly #internalId?: bigint;\n readonly #version: number;\n\n constructor({\n externalId,\n internalId,\n version,\n }: {\n externalId: string;\n internalId?: bigint;\n version: number;\n }) {\n this.#externalId = externalId;\n this.#internalId = internalId;\n this.#version = version;\n }\n\n /**\n * Create a FragnoId from just an external ID (for inputs)\n */\n static fromExternal(externalId: string, version: number): FragnoId {\n return new FragnoId({ externalId, version });\n }\n\n get version(): number {\n return this.#version;\n }\n\n get externalId(): string {\n return this.#externalId;\n }\n\n get internalId(): bigint | undefined {\n return this.#internalId;\n }\n\n /**\n * Get the appropriate ID for database operations\n * Prefers internal ID if available, falls back to external ID\n */\n get databaseId(): string | bigint {\n return this.#internalId ?? this.#externalId;\n }\n\n /**\n * Convert to a plain object for serialization\n */\n toJSON(): { externalId: string; internalId?: string } {\n return {\n externalId: this.#externalId,\n internalId: this.#internalId?.toString(),\n };\n }\n\n toString(): string {\n return this.#externalId;\n }\n\n valueOf(): string {\n return this.#externalId;\n }\n\n [inspect.custom](): string {\n return `FragnoId { externalId: ${this.#externalId}, internalId: ${this.#internalId?.toString()} }`;\n }\n}\n\n/**\n * FragnoReference represents a foreign key reference to another table's internal ID.\n * Unlike FragnoId, it only contains the internal ID (bigint) of the referenced record.\n * This is used for reference columns in query results.\n * @internal\n */\nexport class FragnoReference {\n readonly #internalId: bigint;\n\n constructor(internalId: bigint) {\n this.#internalId = internalId;\n }\n\n /**\n * Create a FragnoReference from an internal ID\n */\n static fromInternal(internalId: bigint): FragnoReference {\n return new FragnoReference(internalId);\n }\n\n /**\n * Get the internal ID for database operations\n */\n get internalId(): bigint {\n return this.#internalId;\n }\n}\n\ntype RelationType = \"one\" | \"many\";\n\nexport class TableBuilder<\n TColumns extends Record<string, AnyColumn> = Record<string, AnyColumn>,\n TRelations extends Record<string, AnyRelation> = Record<string, AnyRelation>,\n TIndexes extends Record<string, Index> = Record<string, Index>,\n> {\n #name: string;\n #columns: TColumns;\n #relations: TRelations;\n #indexes: TIndexes;\n #ormName: string = \"\";\n #columnOrder: string[] = [];\n\n constructor(name: string) {\n this.#name = name;\n this.#columns = {} as TColumns;\n this.#relations = {} as TRelations;\n this.#indexes = {} as TIndexes;\n }\n\n // For alterTable to set existing state\n setColumns(columns: TColumns): void {\n this.#columns = { ...columns };\n }\n\n setRelations(relations: TRelations): void {\n this.#relations = { ...relations };\n }\n\n setIndexes(indexes: TIndexes): void {\n this.#indexes = { ...indexes };\n }\n\n // For SchemaBuilder to read collected indexes\n getIndexes(): Index[] {\n return Object.values(this.#indexes) as Index[];\n }\n\n getColumnOrder(): string[] {\n return this.#columnOrder;\n }\n\n /**\n * Add a column to the table.\n */\n addColumn<TColumnName extends string, TColumn extends AnyColumn>(\n ormName: TColumnName,\n col: TColumn,\n ): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes>;\n\n /**\n * Add a column to the table with simplified syntax.\n */\n addColumn<TColumnName extends string, TType extends keyof TypeMap>(\n ormName: TColumnName,\n type: TType,\n ): TableBuilder<\n TColumns & Record<TColumnName, Column<TType, TypeMap[TType], TypeMap[TType]>>,\n TRelations,\n TIndexes\n >;\n\n addColumn<TColumnName extends string, TColumn extends AnyColumn, TType extends keyof TypeMap>(\n ormName: TColumnName,\n colOrType: TColumn | TType,\n ): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes> {\n // Create the column if a type string was provided\n const col = typeof colOrType === \"string\" ? column(colOrType) : colOrType;\n\n // Set column metadata\n col.ormName = ormName;\n col.name = ormName;\n\n // Add column directly to this builder\n this.#columns[ormName] = col as unknown as TColumns[TColumnName];\n this.#columnOrder.push(ormName);\n\n return this as unknown as TableBuilder<\n TColumns & Record<TColumnName, TColumn>,\n TRelations,\n TIndexes\n >;\n }\n\n /**\n * Create an index on the specified columns.\n */\n createIndex<\n TIndexName extends string,\n const TColumnNames extends readonly (string & keyof TColumns)[],\n >(\n name: TIndexName,\n columns: TColumnNames,\n options?: { unique?: boolean },\n ): TableBuilder<\n TColumns,\n TRelations,\n TIndexes & Record<TIndexName, Index<ColumnsToTuple<TColumns, TColumnNames>, TColumnNames>>\n > {\n const cols = columns.map((colName) => {\n const column = this.#columns[colName];\n if (!column) {\n throw new Error(`Unknown column name ${colName}`);\n }\n return column;\n });\n\n const unique = options?.unique ?? false;\n // Safe: we're adding the index to the internal indexes object\n this.#indexes[name] = {\n name,\n columns: cols,\n columnNames: columns,\n unique,\n } as unknown as TIndexes[TIndexName];\n\n return this as unknown as TableBuilder<\n TColumns,\n TRelations,\n TIndexes & Record<TIndexName, Index<ColumnsToTuple<TColumns, TColumnNames>, TColumnNames>>\n >;\n }\n\n /**\n * Build the final table. This should be called after all columns are added.\n */\n build(): Table<TColumns, TRelations, TIndexes> {\n let idCol: AnyColumn | undefined;\n let internalIdCol: AnyColumn | undefined;\n let versionCol: AnyColumn | undefined;\n\n // TODO: Throw if user manually added version/internalId columns\n\n // Auto-add _internalId and _version columns if not already present\n if (!this.#columns[\"_internalId\"]) {\n const col = internalIdColumn();\n col.ormName = \"_internalId\";\n col.name = \"_internalId\";\n // Safe: we're adding system columns to the internal columns object\n (this.#columns as Record<string, AnyColumn>)[\"_internalId\"] = col;\n }\n\n if (!this.#columns[\"_version\"]) {\n const col = versionColumn();\n col.ormName = \"_version\";\n col.name = \"_version\";\n // Safe: we're adding system columns to the internal columns object\n (this.#columns as Record<string, AnyColumn>)[\"_version\"] = col;\n }\n\n // Use name as ormName if ormName is not set\n const ormName = this.#ormName || this.#name;\n\n const table: Table<TColumns, TRelations, TIndexes> = {\n name: this.#name,\n ormName,\n columns: this.#columns,\n relations: this.#relations,\n indexes: this.#indexes,\n getColumnByName: (name) => {\n return Object.values(this.#columns).find((c) => c.name === name);\n },\n getIdColumn: () => {\n return idCol!;\n },\n getInternalIdColumn: () => {\n return internalIdCol!;\n },\n getVersionColumn: () => {\n return versionCol!;\n },\n };\n\n // Set table reference and find special columns\n for (const k in this.#columns) {\n const column = this.#columns[k];\n if (!column) {\n continue;\n }\n\n column.tableName = table.name;\n if (column instanceof IdColumn || column.role === \"external-id\") {\n idCol = column;\n }\n if (column instanceof InternalIdColumn || column.role === \"internal-id\") {\n internalIdCol = column;\n }\n if (column instanceof VersionColumn || column.role === \"version\") {\n versionCol = column;\n }\n }\n\n if (idCol === undefined) {\n throw new Error(`there's no id column in your table ${this.#name}`);\n }\n if (internalIdCol === undefined) {\n throw new Error(`there's no internal id column in your table ${this.#name}`);\n }\n if (versionCol === undefined) {\n throw new Error(`there's no version column in your table ${this.#name}`);\n }\n\n return table;\n }\n}\n\nexport interface Schema<TTables extends Record<string, AnyTable> = Record<string, AnyTable>> {\n /**\n * @description The version of the schema, automatically incremented on each change.\n */\n version: number;\n tables: TTables;\n /**\n * @description Operations performed on this schema, in order.\n * Used to generate migrations for specific version ranges.\n */\n operations: SchemaOperation[];\n\n clone: () => Schema<TTables>;\n}\n\n/**\n * Utility type for updating a single table's relations in a schema.\n * Used to properly type the return value of addReference.\n */\ntype UpdateTableRelations<\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n TReferenceName extends string,\n TReferencedTableName extends keyof TTables,\n TRelationType extends RelationType = RelationType,\n> = {\n [K in keyof TTables]: K extends TTableName\n ? Table<\n TTables[TTableName][\"columns\"],\n TTables[TTableName][\"relations\"] &\n Record<TReferenceName, Relation<TRelationType, TTables[TReferencedTableName]>>,\n TTables[TTableName][\"indexes\"]\n >\n : TTables[K];\n};\n\n/**\n * Utility type for updating a single table in a schema.\n * Used to properly type the return value of alterTable.\n */\ntype UpdateTable<\n TTables extends Record<string, AnyTable>,\n TTableName extends keyof TTables,\n TNewColumns extends Record<string, AnyColumn>,\n TNewRelations extends Record<string, AnyRelation>,\n TNewIndexes extends Record<string, Index>,\n> = {\n [K in keyof TTables]: K extends TTableName\n ? Table<TNewColumns, TNewRelations, TNewIndexes>\n : TTables[K];\n};\n\n/**\n * Map an array of column names to a tuple of their actual column types\n */\ntype ColumnsToTuple<\n TColumns extends Record<string, AnyColumn>,\n TColumnNames extends readonly (keyof TColumns)[],\n> = {\n [K in keyof TColumnNames]: TColumnNames[K] extends keyof TColumns\n ? TColumns[TColumnNames[K]]\n : never;\n} & AnyColumn[];\n\nexport class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {\n #tables: TTables;\n #version: number = 0;\n #operations: SchemaOperation[] = [];\n\n constructor(existingSchema?: Schema<TTables>) {\n if (existingSchema) {\n this.#tables = existingSchema.tables;\n this.#version = existingSchema.version;\n this.#operations = [...existingSchema.operations];\n } else {\n this.#tables = {} as TTables;\n }\n }\n\n /**\n * Add an existing schema to this builder.\n * Merges tables and operations from the provided schema.\n *\n * @example\n * ```ts\n * const builder = new SchemaBuilder()\n * .add(userSchema)\n * .add(postSchema)\n * .addTable(\"comments\", ...);\n * ```\n */\n mergeWithExistingSchema<TNewTables extends Record<string, AnyTable>>(\n schema: Schema<TNewTables>,\n ): SchemaBuilder<TTables & TNewTables> {\n this.#tables = { ...this.#tables, ...schema.tables } as TTables & TNewTables;\n this.#operations = [...this.#operations, ...schema.operations];\n this.#version += schema.version;\n\n return this as unknown as SchemaBuilder<TTables & TNewTables>;\n }\n\n /**\n * Add a table to the schema. Increments the version counter.\n */\n addTable<\n TTableName extends string,\n TColumns extends Record<string, AnyColumn>,\n TRelations extends Record<string, AnyRelation>,\n TIndexes extends Record<string, Index> = Record<string, Index>,\n >(\n ormName: TTableName,\n callback: (\n builder: TableBuilder<\n Record<string, AnyColumn>,\n Record<string, AnyRelation>,\n Record<string, Index>\n >,\n ) => TableBuilder<TColumns, TRelations, TIndexes>,\n ): SchemaBuilder<TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>> {\n this.#version++;\n\n const tableBuilder = new TableBuilder(ormName);\n const result = callback(tableBuilder);\n const builtTable = result.build();\n builtTable.ormName = ormName;\n\n // Collect sub-operations in order\n const subOperations: TableSubOperation[] = [];\n\n // Add user-defined columns first\n const columnOrder = result.getColumnOrder();\n for (const colName of columnOrder) {\n const col = builtTable.columns[colName];\n subOperations.push({\n type: \"add-column\",\n columnName: colName,\n column: col,\n });\n }\n\n // Add system columns (_internalId and _version) that were auto-added\n if (builtTable.columns[\"_internalId\"]) {\n subOperations.push({\n type: \"add-column\",\n columnName: \"_internalId\",\n column: builtTable.columns[\"_internalId\"],\n });\n }\n if (builtTable.columns[\"_version\"]) {\n subOperations.push({\n type: \"add-column\",\n columnName: \"_version\",\n column: builtTable.columns[\"_version\"],\n });\n }\n\n // Add indexes from builder\n for (const idx of result.getIndexes()) {\n subOperations.push({\n type: \"add-index\",\n name: idx.name,\n columns: idx.columns.map((c) => c.ormName),\n unique: idx.unique,\n });\n }\n\n // Add the add-table operation\n this.#operations.push({\n type: \"add-table\",\n tableName: ormName,\n operations: subOperations,\n });\n\n // Update tables map\n this.#tables = { ...this.#tables, [ormName]: builtTable } as TTables &\n Record<TTableName, Table<TColumns, TRelations, TIndexes>>;\n\n return this as unknown as SchemaBuilder<\n TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>\n >;\n }\n\n /**\n * Add a relation between two tables.\n *\n * @param referenceName - A name for this relation (e.g., \"author\", \"posts\")\n * @param config - Configuration specifying the relation type and foreign key mapping\n *\n * @example\n * ```ts\n * // One-to-one or many-to-one: post -> user\n * schema(s => s\n * .addTable(\"users\", t => t.addColumn(\"id\", idColumn()))\n * .addTable(\"posts\", t => t\n * .addColumn(\"id\", idColumn())\n * .addColumn(\"userId\", referenceColumn()))\n * .addReference(\"author\", {\n * type: \"one\",\n * from: { table: \"posts\", column: \"userId\" },\n * to: { table: \"users\", column: \"id\" },\n * })\n * )\n *\n * // One-to-many (inverse relation): user -> posts\n * .addReference(\"posts\", {\n * type: \"many\",\n * from: { table: \"users\", column: \"id\" },\n * to: { table: \"posts\", column: \"userId\" },\n * })\n *\n * // Self-referencing foreign key\n * .addReference(\"inviter\", {\n * type: \"one\",\n * from: { table: \"users\", column: \"invitedBy\" },\n * to: { table: \"users\", column: \"id\" },\n * })\n * ```\n */\n addReference<\n TFromTableName extends string & keyof TTables,\n TToTableName extends string & keyof TTables,\n TReferenceName extends string,\n TRelationType extends RelationType,\n >(\n referenceName: TReferenceName,\n config: {\n type: TRelationType;\n from: {\n table: TFromTableName;\n column: keyof TTables[TFromTableName][\"columns\"];\n };\n to: {\n table: TToTableName;\n column: keyof TTables[TToTableName][\"columns\"];\n };\n },\n ): SchemaBuilder<\n UpdateTableRelations<TTables, TFromTableName, TReferenceName, TToTableName, TRelationType>\n > {\n this.#version++;\n\n const table = this.#tables[config.from.table];\n const referencedTable = this.#tables[config.to.table];\n\n if (!table) {\n throw new Error(`Table ${config.from.table} not found in schema`);\n }\n if (!referencedTable) {\n throw new Error(`Referenced table ${config.to.table} not found in schema`);\n }\n\n const columnName = config.from.column as string;\n const targetColumnName = config.to.column as string;\n\n // Foreign keys always reference internal IDs, not external IDs\n // If user specifies \"id\", translate to \"_internalId\" for the actual FK\n const actualTargetColumnName = targetColumnName === \"id\" ? \"_internalId\" : targetColumnName;\n\n const column = table.columns[columnName];\n const referencedColumn = referencedTable.columns[actualTargetColumnName];\n\n if (!column) {\n throw new Error(`Column ${columnName} not found in table ${config.from.table}`);\n }\n if (!referencedColumn) {\n throw new Error(`Column ${actualTargetColumnName} not found in table ${config.to.table}`);\n }\n\n // Verify that reference columns are bigint (matching internal ID type)\n if (column.role === \"reference\" && column.type !== \"bigint\") {\n throw new Error(\n `Reference column ${columnName} must be of type bigint to match internal ID type`,\n );\n }\n\n // Create the relation (use the user-facing column name for the relation)\n const init = new ExplicitRelationInit(config.type, referencedTable, table);\n init.on.push([columnName, targetColumnName]);\n const relation = init.init(referenceName);\n\n // Add relation to the table\n table.relations[referenceName] = relation;\n\n // Record the operation\n this.#operations.push({\n type: \"add-reference\",\n tableName: config.from.table,\n referenceName,\n config: {\n type: config.type,\n from: { table: config.from.table, column: columnName },\n to: { table: config.to.table, column: actualTargetColumnName },\n },\n });\n\n // Return this with updated type\n // Safe: The relation was added to the table in place and now has the updated relations\n return this as unknown as SchemaBuilder<\n UpdateTableRelations<TTables, TFromTableName, TReferenceName, TToTableName, TRelationType>\n >;\n }\n\n /**\n * Alter an existing table by adding columns or indexes.\n * This is used for append-only schema modifications.\n *\n * @param tableName - The name of the table to modify\n * @param callback - A callback that receives a table builder for adding columns/indexes\n *\n * @example\n * ```ts\n * // Add a new column to an existing table\n * schema(s => s\n * .addTable(\"users\", t => t\n * .addColumn(\"id\", idColumn())\n * .addColumn(\"name\", column(\"string\")))\n * .alterTable(\"users\", t => t\n * .addColumn(\"email\", column(\"string\"))\n * .addColumn(\"age\", column(\"integer\").nullable())\n * .createIndex(\"idx_email\", [\"email\"]))\n * )\n * ```\n */\n alterTable<\n TTableName extends string & keyof TTables,\n TNewColumns extends Record<string, AnyColumn>,\n TNewRelations extends Record<string, AnyRelation>,\n TNewIndexes extends Record<string, Index> = Record<string, Index>,\n >(\n tableName: TTableName,\n callback: (\n builder: TableBuilder<\n TTables[TTableName][\"columns\"],\n TTables[TTableName][\"relations\"],\n Record<string, Index>\n >,\n ) => TableBuilder<TNewColumns, TNewRelations, TNewIndexes>,\n ): SchemaBuilder<UpdateTable<TTables, TTableName, TNewColumns, TNewRelations, TNewIndexes>> {\n const table = this.#tables[tableName];\n\n if (!table) {\n throw new Error(`Table ${tableName} not found in schema`);\n }\n\n // Create builder with existing table state\n const tableBuilder = new TableBuilder(tableName);\n tableBuilder.setColumns(table.columns);\n tableBuilder.setRelations(table.relations);\n tableBuilder.setIndexes(table.indexes);\n\n // Track existing columns and indexes\n const existingColumns = new Set(Object.keys(table.columns));\n const existingIndexes = new Set(Object.keys(table.indexes));\n\n // Apply modifications\n const resultBuilder = callback(\n tableBuilder as TableBuilder<\n TTables[TTableName][\"columns\"],\n TTables[TTableName][\"relations\"],\n Record<string, Index>\n >,\n );\n const newTable = resultBuilder.build();\n\n // Collect sub-operations\n const subOperations: TableSubOperation[] = [];\n\n // Find new columns (preserve order from builder)\n const columnOrder = resultBuilder.getColumnOrder();\n for (const colName of columnOrder) {\n if (!existingColumns.has(colName)) {\n subOperations.push({\n type: \"add-column\",\n columnName: colName,\n column: newTable.columns[colName],\n });\n }\n }\n\n // Add only new indexes\n for (const idx of resultBuilder.getIndexes()) {\n if (!existingIndexes.has(idx.name)) {\n subOperations.push({\n type: \"add-index\",\n name: idx.name,\n columns: idx.columns.map((c) => c.ormName),\n unique: idx.unique,\n });\n }\n }\n\n if (subOperations.length > 0) {\n this.#version++;\n this.#operations.push({\n type: \"alter-table\",\n tableName,\n operations: subOperations,\n });\n }\n\n // Update table reference in schema\n this.#tables[tableName] = newTable as unknown as TTables[TTableName];\n\n // Set table name for all columns\n for (const col of Object.values(newTable.columns)) {\n col.tableName = newTable.name;\n }\n\n return this as unknown as SchemaBuilder<\n UpdateTable<TTables, TTableName, TNewColumns, TNewRelations, TNewIndexes>\n >;\n }\n\n /**\n * Build the final schema. This should be called after all tables are added.\n */\n build(): Schema<TTables> {\n const operations = this.#operations;\n const version = this.#version;\n const tables = this.#tables;\n\n const schema: Schema<TTables> = {\n version,\n tables,\n operations,\n clone: () => {\n const cloneTables: Record<string, AnyTable> = {};\n\n for (const [k, v] of Object.entries(tables)) {\n // Create a new table with cloned columns\n const clonedColumns: Record<string, AnyColumn> = {};\n for (const [colName, col] of Object.entries(v.columns)) {\n // Create a new column with the same properties, preserving the column type\n let clonedCol: AnyColumn;\n if (col instanceof InternalIdColumn) {\n clonedCol = new InternalIdColumn();\n } else if (col instanceof VersionColumn) {\n clonedCol = new VersionColumn();\n } else if (col instanceof IdColumn) {\n clonedCol = new IdColumn(col.type);\n } else {\n clonedCol = new Column(col.type);\n }\n\n clonedCol.name = col.name;\n clonedCol.ormName = col.ormName;\n clonedCol.isNullable = col.isNullable;\n clonedCol.role = col.role;\n clonedCol.isHidden = col.isHidden;\n clonedCol.default = col.default;\n clonedCol.tableName = col.tableName;\n clonedColumns[colName] = clonedCol;\n }\n\n cloneTables[k] = {\n ...v,\n columns: clonedColumns,\n };\n }\n\n return new SchemaBuilder<TTables>({\n version,\n tables: cloneTables as TTables,\n operations: [...operations],\n clone: () => {\n throw new Error(\"Cannot clone during clone\");\n },\n }).build();\n },\n };\n\n return schema;\n }\n\n /**\n * Get the current version of the schema builder.\n */\n getVersion(): number {\n return this.#version;\n }\n}\n\n/**\n * Create a new schema with callback pattern.\n */\nexport function schema<const TTables extends Record<string, AnyTable> = {}>(\n callback: (builder: SchemaBuilder<{}>) => SchemaBuilder<TTables>,\n): Schema<TTables> {\n return callback(new SchemaBuilder()).build();\n}\n\nexport function compileForeignKey(key: ForeignKey, nameType: \"sql\" | \"orm\" = \"orm\") {\n return {\n name: key.name,\n table: nameType === \"sql\" ? key.table.name : key.table.ormName,\n referencedTable: nameType === \"sql\" ? key.referencedTable.name : key.referencedTable.ormName,\n referencedColumns: key.referencedColumns.map((col) =>\n nameType === \"sql\" ? col.name : col.ormName,\n ),\n columns: key.columns.map((col) => (nameType === \"sql\" ? col.name : col.ormName)),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { PostgreSQLTypeMapper } from "./dialect/postgres.js";
2
+ import { MySQLTypeMapper } from "./dialect/mysql.js";
3
+ import { SQLiteTypeMapper } from "./dialect/sqlite.js";
4
+
5
+ //#region src/schema/type-conversion/create-sql-type-mapper.ts
6
+ /**
7
+ * Factory function to create a dialect-specific SQL type mapper.
8
+ *
9
+ * Based on the database type, returns the appropriate mapper implementation
10
+ * (PostgreSQL, MySQL, or SQLite).
11
+ *
12
+ * @param database - The database type (sqlite, postgresql, or mysql)
13
+ * @returns Dialect-specific SQLTypeMapper instance
14
+ */
15
+ function createSQLTypeMapper(database) {
16
+ switch (database) {
17
+ case "postgresql": return new PostgreSQLTypeMapper(database);
18
+ case "mysql": return new MySQLTypeMapper(database);
19
+ case "sqlite": return new SQLiteTypeMapper(database);
20
+ default: {
21
+ const exhaustiveCheck = database;
22
+ throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
23
+ }
24
+ }
25
+ }
26
+
27
+ //#endregion
28
+ export { createSQLTypeMapper };
29
+ //# sourceMappingURL=create-sql-type-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-sql-type-mapper.js","names":["exhaustiveCheck: never"],"sources":["../../../src/schema/type-conversion/create-sql-type-mapper.ts"],"sourcesContent":["import type { SupportedDatabase } from \"../../adapters/generic-sql/driver-config\";\nimport { PostgreSQLTypeMapper } from \"./dialect/postgres\";\nimport { MySQLTypeMapper } from \"./dialect/mysql\";\nimport { SQLiteTypeMapper } from \"./dialect/sqlite\";\n\n/**\n * Factory function to create a dialect-specific SQL type mapper.\n *\n * Based on the database type, returns the appropriate mapper implementation\n * (PostgreSQL, MySQL, or SQLite).\n *\n * @param database - The database type (sqlite, postgresql, or mysql)\n * @returns Dialect-specific SQLTypeMapper instance\n */\nexport function createSQLTypeMapper(database: SupportedDatabase) {\n switch (database) {\n case \"postgresql\":\n return new PostgreSQLTypeMapper(database);\n case \"mysql\":\n return new MySQLTypeMapper(database);\n case \"sqlite\":\n return new SQLiteTypeMapper(database);\n default: {\n const exhaustiveCheck: never = database;\n throw new Error(`Unsupported database type: ${exhaustiveCheck}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,oBAAoB,UAA6B;AAC/D,SAAQ,UAAR;EACE,KAAK,aACH,QAAO,IAAI,qBAAqB,SAAS;EAC3C,KAAK,QACH,QAAO,IAAI,gBAAgB,SAAS;EACtC,KAAK,SACH,QAAO,IAAI,iBAAiB,SAAS;EACvC,SAAS;GACP,MAAMA,kBAAyB;AAC/B,SAAM,IAAI,MAAM,8BAA8B,kBAAkB"}
@@ -0,0 +1,57 @@
1
+ import { SQLTypeMapper } from "../type-mapping.js";
2
+
3
+ //#region src/schema/type-conversion/dialect/mysql.ts
4
+ /**
5
+ * MySQL-specific type mapper.
6
+ *
7
+ * MySQL supports:
8
+ * - BIGINT for large integers (with AUTO_INCREMENT for internal IDs)
9
+ * - INTEGER for integers
10
+ * - BOOLEAN for booleans (alias for TINYINT(1))
11
+ * - JSON for JSON data (native support in MySQL 5.7+)
12
+ * - TEXT for strings
13
+ * - VARCHAR(n) for variable-length strings
14
+ * - LONGBLOB for binary data
15
+ * - DATETIME for timestamps without timezone
16
+ * - DATE for dates
17
+ * - DECIMAL for decimals
18
+ */
19
+ var MySQLTypeMapper = class extends SQLTypeMapper {
20
+ getInternalIdType() {
21
+ return "bigint";
22
+ }
23
+ mapInteger(_column) {
24
+ return "integer";
25
+ }
26
+ mapBigint(_column) {
27
+ return "bigint";
28
+ }
29
+ mapString() {
30
+ return "text";
31
+ }
32
+ mapVarchar(length) {
33
+ return `varchar(${length})`;
34
+ }
35
+ mapBinary() {
36
+ return "longblob";
37
+ }
38
+ mapBool() {
39
+ return "boolean";
40
+ }
41
+ mapDecimal() {
42
+ return "decimal";
43
+ }
44
+ mapTimestamp() {
45
+ return "datetime";
46
+ }
47
+ mapDate() {
48
+ return "date";
49
+ }
50
+ mapJson() {
51
+ return "json";
52
+ }
53
+ };
54
+
55
+ //#endregion
56
+ export { MySQLTypeMapper };
57
+ //# sourceMappingURL=mysql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mysql.js","names":[],"sources":["../../../../src/schema/type-conversion/dialect/mysql.ts"],"sourcesContent":["import type { AnyColumn } from \"../../create\";\nimport { SQLTypeMapper, type MySQLDatabaseType } from \"../type-mapping\";\n\n/**\n * MySQL-specific type mapper.\n *\n * MySQL supports:\n * - BIGINT for large integers (with AUTO_INCREMENT for internal IDs)\n * - INTEGER for integers\n * - BOOLEAN for booleans (alias for TINYINT(1))\n * - JSON for JSON data (native support in MySQL 5.7+)\n * - TEXT for strings\n * - VARCHAR(n) for variable-length strings\n * - LONGBLOB for binary data\n * - DATETIME for timestamps without timezone\n * - DATE for dates\n * - DECIMAL for decimals\n */\nexport class MySQLTypeMapper extends SQLTypeMapper<MySQLDatabaseType> {\n protected getInternalIdType(): MySQLDatabaseType {\n // MySQL uses bigint with AUTO_INCREMENT applied separately\n return \"bigint\";\n }\n\n protected mapInteger(_column: AnyColumn | Pick<AnyColumn, \"type\">): MySQLDatabaseType {\n return \"integer\";\n }\n\n protected mapBigint(_column: AnyColumn | Pick<AnyColumn, \"type\">): MySQLDatabaseType {\n return \"bigint\";\n }\n\n protected mapString(): MySQLDatabaseType {\n return \"text\";\n }\n\n protected mapVarchar(length: number): MySQLDatabaseType {\n return `varchar(${length})`;\n }\n\n protected mapBinary(): MySQLDatabaseType {\n return \"longblob\";\n }\n\n protected mapBool(): MySQLDatabaseType {\n return \"boolean\";\n }\n\n protected mapDecimal(): MySQLDatabaseType {\n return \"decimal\";\n }\n\n protected mapTimestamp(): MySQLDatabaseType {\n return \"datetime\";\n }\n\n protected mapDate(): MySQLDatabaseType {\n return \"date\";\n }\n\n protected mapJson(): MySQLDatabaseType {\n return \"json\";\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,IAAa,kBAAb,cAAqC,cAAiC;CACpE,AAAU,oBAAuC;AAE/C,SAAO;;CAGT,AAAU,WAAW,SAAiE;AACpF,SAAO;;CAGT,AAAU,UAAU,SAAiE;AACnF,SAAO;;CAGT,AAAU,YAA+B;AACvC,SAAO;;CAGT,AAAU,WAAW,QAAmC;AACtD,SAAO,WAAW,OAAO;;CAG3B,AAAU,YAA+B;AACvC,SAAO;;CAGT,AAAU,UAA6B;AACrC,SAAO;;CAGT,AAAU,aAAgC;AACxC,SAAO;;CAGT,AAAU,eAAkC;AAC1C,SAAO;;CAGT,AAAU,UAA6B;AACrC,SAAO;;CAGT,AAAU,UAA6B;AACrC,SAAO"}
@@ -0,0 +1,56 @@
1
+ import { SQLTypeMapper } from "../type-mapping.js";
2
+
3
+ //#region src/schema/type-conversion/dialect/postgres.ts
4
+ /**
5
+ * PostgreSQL-specific type mapper.
6
+ *
7
+ * PostgreSQL supports:
8
+ * - BIGSERIAL for auto-increment
9
+ * - BOOLEAN for booleans
10
+ * - JSON for JSON data
11
+ * - TEXT for strings
12
+ * - VARCHAR(n) for variable-length strings
13
+ * - BYTEA for binary data
14
+ * - Full timestamp and date support
15
+ * - BIGINT and INTEGER for integers
16
+ * - DECIMAL for decimals
17
+ */
18
+ var PostgreSQLTypeMapper = class extends SQLTypeMapper {
19
+ getInternalIdType() {
20
+ return "bigserial";
21
+ }
22
+ mapInteger(_column) {
23
+ return "integer";
24
+ }
25
+ mapBigint(_column) {
26
+ return "bigint";
27
+ }
28
+ mapString() {
29
+ return "text";
30
+ }
31
+ mapVarchar(length) {
32
+ return `varchar(${length})`;
33
+ }
34
+ mapBinary() {
35
+ return "bytea";
36
+ }
37
+ mapBool() {
38
+ return "boolean";
39
+ }
40
+ mapDecimal() {
41
+ return "decimal";
42
+ }
43
+ mapTimestamp() {
44
+ return "timestamp";
45
+ }
46
+ mapDate() {
47
+ return "date";
48
+ }
49
+ mapJson() {
50
+ return "json";
51
+ }
52
+ };
53
+
54
+ //#endregion
55
+ export { PostgreSQLTypeMapper };
56
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","names":[],"sources":["../../../../src/schema/type-conversion/dialect/postgres.ts"],"sourcesContent":["import type { AnyColumn } from \"../../create\";\nimport { SQLTypeMapper, type PostgreSQLDatabaseType } from \"../type-mapping\";\n\n/**\n * PostgreSQL-specific type mapper.\n *\n * PostgreSQL supports:\n * - BIGSERIAL for auto-increment\n * - BOOLEAN for booleans\n * - JSON for JSON data\n * - TEXT for strings\n * - VARCHAR(n) for variable-length strings\n * - BYTEA for binary data\n * - Full timestamp and date support\n * - BIGINT and INTEGER for integers\n * - DECIMAL for decimals\n */\nexport class PostgreSQLTypeMapper extends SQLTypeMapper<PostgreSQLDatabaseType> {\n protected getInternalIdType(): PostgreSQLDatabaseType {\n return \"bigserial\";\n }\n\n protected mapInteger(_column: AnyColumn | Pick<AnyColumn, \"type\">): PostgreSQLDatabaseType {\n return \"integer\";\n }\n\n protected mapBigint(_column: AnyColumn | Pick<AnyColumn, \"type\">): PostgreSQLDatabaseType {\n return \"bigint\";\n }\n\n protected mapString(): PostgreSQLDatabaseType {\n return \"text\";\n }\n\n protected mapVarchar(length: number): PostgreSQLDatabaseType {\n return `varchar(${length})`;\n }\n\n protected mapBinary(): PostgreSQLDatabaseType {\n return \"bytea\";\n }\n\n protected mapBool(): PostgreSQLDatabaseType {\n return \"boolean\";\n }\n\n protected mapDecimal(): PostgreSQLDatabaseType {\n return \"decimal\";\n }\n\n protected mapTimestamp(): PostgreSQLDatabaseType {\n return \"timestamp\";\n }\n\n protected mapDate(): PostgreSQLDatabaseType {\n return \"date\";\n }\n\n protected mapJson(): PostgreSQLDatabaseType {\n return \"json\";\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAa,uBAAb,cAA0C,cAAsC;CAC9E,AAAU,oBAA4C;AACpD,SAAO;;CAGT,AAAU,WAAW,SAAsE;AACzF,SAAO;;CAGT,AAAU,UAAU,SAAsE;AACxF,SAAO;;CAGT,AAAU,YAAoC;AAC5C,SAAO;;CAGT,AAAU,WAAW,QAAwC;AAC3D,SAAO,WAAW,OAAO;;CAG3B,AAAU,YAAoC;AAC5C,SAAO;;CAGT,AAAU,UAAkC;AAC1C,SAAO;;CAGT,AAAU,aAAqC;AAC7C,SAAO;;CAGT,AAAU,eAAuC;AAC/C,SAAO;;CAGT,AAAU,UAAkC;AAC1C,SAAO;;CAGT,AAAU,UAAkC;AAC1C,SAAO"}
@@ -0,0 +1,52 @@
1
+ import { SQLTypeMapper } from "../type-mapping.js";
2
+
3
+ //#region src/schema/type-conversion/dialect/sqlite.ts
4
+ /**
5
+ * SQLite-specific type mapper.
6
+ *
7
+ * SQLite has a limited type system with only 4 storage classes:
8
+ * - INTEGER for integers, booleans, timestamps, dates (and reference columns)
9
+ * - BLOB for binary data and bigints (except for reference columns)
10
+ * - TEXT for strings, JSON, and varchar
11
+ * - REAL for decimals
12
+ */
13
+ var SQLiteTypeMapper = class extends SQLTypeMapper {
14
+ getInternalIdType() {
15
+ return "integer";
16
+ }
17
+ mapInteger(_column) {
18
+ return "integer";
19
+ }
20
+ mapBigint(column) {
21
+ if ("role" in column && column.role === "reference") return "integer";
22
+ return "blob";
23
+ }
24
+ mapString() {
25
+ return "text";
26
+ }
27
+ mapVarchar(_length) {
28
+ return "text";
29
+ }
30
+ mapBinary() {
31
+ return "blob";
32
+ }
33
+ mapBool() {
34
+ return "integer";
35
+ }
36
+ mapDecimal() {
37
+ return "real";
38
+ }
39
+ mapTimestamp() {
40
+ return "integer";
41
+ }
42
+ mapDate() {
43
+ return "integer";
44
+ }
45
+ mapJson() {
46
+ return "text";
47
+ }
48
+ };
49
+
50
+ //#endregion
51
+ export { SQLiteTypeMapper };
52
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","names":[],"sources":["../../../../src/schema/type-conversion/dialect/sqlite.ts"],"sourcesContent":["import type { AnyColumn } from \"../../create\";\nimport { SQLTypeMapper, type SQLiteDatabaseType } from \"../type-mapping\";\n\n/**\n * SQLite-specific type mapper.\n *\n * SQLite has a limited type system with only 4 storage classes:\n * - INTEGER for integers, booleans, timestamps, dates (and reference columns)\n * - BLOB for binary data and bigints (except for reference columns)\n * - TEXT for strings, JSON, and varchar\n * - REAL for decimals\n */\nexport class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {\n protected getInternalIdType(): SQLiteDatabaseType {\n // SQLite uses INTEGER for auto-increment (INTEGER PRIMARY KEY)\n return \"integer\";\n }\n\n protected mapInteger(_column: AnyColumn | Pick<AnyColumn, \"type\">): SQLiteDatabaseType {\n return \"integer\";\n }\n\n protected mapBigint(column: AnyColumn | Pick<AnyColumn, \"type\">): SQLiteDatabaseType {\n // SQLite special case: reference columns should use integer even if type is bigint\n if (\"role\" in column && column.role === \"reference\") {\n return \"integer\";\n }\n return \"blob\";\n }\n\n protected mapString(): SQLiteDatabaseType {\n return \"text\";\n }\n\n protected mapVarchar(_length: number): SQLiteDatabaseType {\n // SQLite doesn't support varchar - convert to text\n return \"text\";\n }\n\n protected mapBinary(): SQLiteDatabaseType {\n return \"blob\";\n }\n\n protected mapBool(): SQLiteDatabaseType {\n return \"integer\";\n }\n\n protected mapDecimal(): SQLiteDatabaseType {\n return \"real\";\n }\n\n protected mapTimestamp(): SQLiteDatabaseType {\n return \"integer\";\n }\n\n protected mapDate(): SQLiteDatabaseType {\n return \"integer\";\n }\n\n protected mapJson(): SQLiteDatabaseType {\n return \"text\";\n }\n}\n"],"mappings":";;;;;;;;;;;;AAYA,IAAa,mBAAb,cAAsC,cAAkC;CACtE,AAAU,oBAAwC;AAEhD,SAAO;;CAGT,AAAU,WAAW,SAAkE;AACrF,SAAO;;CAGT,AAAU,UAAU,QAAiE;AAEnF,MAAI,UAAU,UAAU,OAAO,SAAS,YACtC,QAAO;AAET,SAAO;;CAGT,AAAU,YAAgC;AACxC,SAAO;;CAGT,AAAU,WAAW,SAAqC;AAExD,SAAO;;CAGT,AAAU,YAAgC;AACxC,SAAO;;CAGT,AAAU,UAA8B;AACtC,SAAO;;CAGT,AAAU,aAAiC;AACzC,SAAO;;CAGT,AAAU,eAAmC;AAC3C,SAAO;;CAGT,AAAU,UAA8B;AACtC,SAAO;;CAGT,AAAU,UAA8B;AACtC,SAAO"}
@@ -0,0 +1,63 @@
1
+ //#region src/schema/type-conversion/type-mapping.ts
2
+ /**
3
+ * Abstract base class for SQL type mapping.
4
+ *
5
+ * Similar to SQLQueryCompiler and SQLGenerator, this class provides a framework
6
+ * for mapping schema column types to database-specific column types.
7
+ *
8
+ * Each database dialect extends this class and implements abstract methods
9
+ * for each column type. The base class handles the switch statement logic.
10
+ *
11
+ * @template TDatabaseType - The specific database type union for this dialect
12
+ */
13
+ var SQLTypeMapper = class {
14
+ database;
15
+ constructor(database) {
16
+ this.database = database;
17
+ }
18
+ /**
19
+ * Map a column type to a database-specific type.
20
+ * Contains the central switch statement that delegates to abstract methods.
21
+ */
22
+ mapColumnType(column) {
23
+ const { type } = column;
24
+ if (typeof type === "string" && type.startsWith("varchar")) {
25
+ const match = type.match(/^varchar\((\d+)\)$/);
26
+ if (match) {
27
+ const length = parseInt(match[1], 10);
28
+ return this.mapVarchar(length);
29
+ }
30
+ throw new Error(`Invalid varchar format: "${type}". Expected format: varchar(number), e.g., varchar(255)`);
31
+ }
32
+ switch (type) {
33
+ case "integer": return this.mapInteger(column);
34
+ case "bigint": return this.mapBigint(column);
35
+ case "string": return this.mapString();
36
+ case "binary": return this.mapBinary();
37
+ case "bool": return this.mapBool();
38
+ case "decimal": return this.mapDecimal();
39
+ case "timestamp": return this.mapTimestamp();
40
+ case "date": return this.mapDate();
41
+ case "json": return this.mapJson();
42
+ default: throw new Error(`Unsupported column type: ${type}`);
43
+ }
44
+ }
45
+ /**
46
+ * Map a schema column type to the appropriate database column type.
47
+ * Used for generating CREATE TABLE statements and migrations.
48
+ *
49
+ * Handles common cases like internal-id columns,
50
+ * then delegates to mapColumnType for other types.
51
+ *
52
+ * @param column - The column schema definition
53
+ * @returns The database-specific column type
54
+ */
55
+ getDatabaseType(column) {
56
+ if ("role" in column && column.role === "internal-id") return this.getInternalIdType();
57
+ return this.mapColumnType(column);
58
+ }
59
+ };
60
+
61
+ //#endregion
62
+ export { SQLTypeMapper };
63
+ //# sourceMappingURL=type-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-mapping.js","names":[],"sources":["../../../src/schema/type-conversion/type-mapping.ts"],"sourcesContent":["import type { SupportedDatabase } from \"../../adapters/generic-sql/driver-config\";\nimport type { AnyColumn } from \"../create\";\n\nexport interface AdditionalColumnMetadata {\n length?: number;\n precision?: number;\n scale?: number;\n}\n\n/**\n * PostgreSQL-specific database types\n */\nexport type PostgreSQLDatabaseType =\n | \"bigserial\"\n | \"serial\"\n | \"boolean\"\n | \"json\"\n | \"text\"\n | \"bytea\"\n | \"timestamp\"\n | \"timestamptz\"\n | \"bigint\"\n | \"integer\"\n | \"decimal\"\n | \"date\"\n | `varchar(${number})`;\n\n/**\n * MySQL-specific database types\n */\nexport type MySQLDatabaseType =\n | \"bigint\"\n | \"boolean\"\n | \"text\"\n | \"longblob\"\n | \"integer\"\n | \"decimal\"\n | \"date\"\n | \"datetime\"\n | \"json\"\n | \"timestamp\"\n | `varchar(${number})`;\n\n/**\n * SQLite-specific database types\n */\nexport type SQLiteDatabaseType = \"integer\" | \"blob\" | \"text\" | \"real\";\n\n/**\n * Union of all database-specific types\n */\nexport type DatabaseTypeLiteral = PostgreSQLDatabaseType | MySQLDatabaseType | SQLiteDatabaseType;\n\n/**\n * Abstract base class for SQL type mapping.\n *\n * Similar to SQLQueryCompiler and SQLGenerator, this class provides a framework\n * for mapping schema column types to database-specific column types.\n *\n * Each database dialect extends this class and implements abstract methods\n * for each column type. The base class handles the switch statement logic.\n *\n * @template TDatabaseType - The specific database type union for this dialect\n */\nexport abstract class SQLTypeMapper<TDatabaseType extends DatabaseTypeLiteral> {\n protected readonly database: SupportedDatabase;\n\n constructor(database: SupportedDatabase) {\n this.database = database;\n }\n\n /**\n * Get the database type for internal ID columns.\n */\n protected abstract getInternalIdType(): TDatabaseType;\n\n // Abstract methods for each column type that dialects must implement\n protected abstract mapInteger(column: AnyColumn | Pick<AnyColumn, \"type\">): TDatabaseType;\n protected abstract mapBigint(column: AnyColumn | Pick<AnyColumn, \"type\">): TDatabaseType;\n protected abstract mapString(): TDatabaseType;\n protected abstract mapVarchar(length: number): TDatabaseType;\n protected abstract mapBinary(): TDatabaseType;\n protected abstract mapBool(): TDatabaseType;\n protected abstract mapDecimal(): TDatabaseType;\n protected abstract mapTimestamp(): TDatabaseType;\n protected abstract mapDate(): TDatabaseType;\n protected abstract mapJson(): TDatabaseType;\n\n /**\n * Map a column type to a database-specific type.\n * Contains the central switch statement that delegates to abstract methods.\n */\n protected mapColumnType(column: AnyColumn | Pick<AnyColumn, \"type\">): TDatabaseType {\n const { type } = column;\n\n // Handle varchar with length parameter\n if (typeof type === \"string\" && type.startsWith(\"varchar\")) {\n const match = type.match(/^varchar\\((\\d+)\\)$/);\n if (match) {\n const length = parseInt(match[1], 10);\n return this.mapVarchar(length);\n }\n throw new Error(\n `Invalid varchar format: \"${type}\". Expected format: varchar(number), e.g., varchar(255)`,\n );\n }\n\n switch (type) {\n case \"integer\":\n return this.mapInteger(column);\n case \"bigint\":\n return this.mapBigint(column);\n case \"string\":\n return this.mapString();\n case \"binary\":\n return this.mapBinary();\n case \"bool\":\n return this.mapBool();\n case \"decimal\":\n return this.mapDecimal();\n case \"timestamp\":\n return this.mapTimestamp();\n case \"date\":\n return this.mapDate();\n case \"json\":\n return this.mapJson();\n default:\n // TypeScript should ensure we never reach here\n throw new Error(`Unsupported column type: ${type}`);\n }\n }\n\n /**\n * Map a schema column type to the appropriate database column type.\n * Used for generating CREATE TABLE statements and migrations.\n *\n * Handles common cases like internal-id columns,\n * then delegates to mapColumnType for other types.\n *\n * @param column - The column schema definition\n * @returns The database-specific column type\n */\n getDatabaseType(column: AnyColumn | Pick<AnyColumn, \"type\">): TDatabaseType {\n // Handle internal ID columns with auto-increment\n if (\"role\" in column && column.role === \"internal-id\") {\n return this.getInternalIdType();\n }\n\n // Delegate to type mapping logic\n // This includes reference columns, which should use their specified type\n return this.mapColumnType(column);\n }\n}\n"],"mappings":";;;;;;;;;;;;AAgEA,IAAsB,gBAAtB,MAA+E;CAC7E,AAAmB;CAEnB,YAAY,UAA6B;AACvC,OAAK,WAAW;;;;;;CAwBlB,AAAU,cAAc,QAA4D;EAClF,MAAM,EAAE,SAAS;AAGjB,MAAI,OAAO,SAAS,YAAY,KAAK,WAAW,UAAU,EAAE;GAC1D,MAAM,QAAQ,KAAK,MAAM,qBAAqB;AAC9C,OAAI,OAAO;IACT,MAAM,SAAS,SAAS,MAAM,IAAI,GAAG;AACrC,WAAO,KAAK,WAAW,OAAO;;AAEhC,SAAM,IAAI,MACR,4BAA4B,KAAK,yDAClC;;AAGH,UAAQ,MAAR;GACE,KAAK,UACH,QAAO,KAAK,WAAW,OAAO;GAChC,KAAK,SACH,QAAO,KAAK,UAAU,OAAO;GAC/B,KAAK,SACH,QAAO,KAAK,WAAW;GACzB,KAAK,SACH,QAAO,KAAK,WAAW;GACzB,KAAK,OACH,QAAO,KAAK,SAAS;GACvB,KAAK,UACH,QAAO,KAAK,YAAY;GAC1B,KAAK,YACH,QAAO,KAAK,cAAc;GAC5B,KAAK,OACH,QAAO,KAAK,SAAS;GACvB,KAAK,OACH,QAAO,KAAK,SAAS;GACvB,QAEE,OAAM,IAAI,MAAM,4BAA4B,OAAO;;;;;;;;;;;;;CAczD,gBAAgB,QAA4D;AAE1E,MAAI,UAAU,UAAU,OAAO,SAAS,cACtC,QAAO,KAAK,mBAAmB;AAKjC,SAAO,KAAK,cAAc,OAAO"}
@@ -0,0 +1,13 @@
1
+ import { DatabaseConnection } from "../sql-driver.js";
2
+
3
+ //#region src/sql-driver/connection/connection-provider.d.ts
4
+ interface ConnectionProvider {
5
+ /**
6
+ * Provides a connection for the callback and takes care of disposing
7
+ * the connection after the callback has been run.
8
+ */
9
+ provideConnection<T>(consumer: (connection: DatabaseConnection) => Promise<T>): Promise<T>;
10
+ }
11
+ //#endregion
12
+ export { ConnectionProvider };
13
+ //# sourceMappingURL=connection-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-provider.d.ts","names":[],"sources":["../../../src/sql-driver/connection/connection-provider.ts"],"sourcesContent":[],"mappings":";;;UAEiB,kBAAA;;AAAjB;;;EAKqE,iBAAA,CAAA,CAAA,CAAA,CAAA,QAAA,EAAA,CAAA,UAAA,EAAvB,kBAAuB,EAAA,GAAA,OAAA,CAAQ,CAAR,CAAA,CAAA,EAAa,OAAb,CAAqB,CAArB,CAAA"}
@@ -0,0 +1,19 @@
1
+ //#region src/sql-driver/connection/connection-provider.ts
2
+ var DefaultConnectionProvider = class {
3
+ #driver;
4
+ constructor(driver) {
5
+ this.#driver = driver;
6
+ }
7
+ async provideConnection(consumer) {
8
+ const connection = await this.#driver.acquireConnection();
9
+ try {
10
+ return await consumer(connection);
11
+ } finally {
12
+ await this.#driver.releaseConnection(connection);
13
+ }
14
+ }
15
+ };
16
+
17
+ //#endregion
18
+ export { DefaultConnectionProvider };
19
+ //# sourceMappingURL=connection-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-provider.js","names":["#driver"],"sources":["../../../src/sql-driver/connection/connection-provider.ts"],"sourcesContent":["import type { DatabaseConnection, Driver } from \"../sql-driver\";\n\nexport interface ConnectionProvider {\n /**\n * Provides a connection for the callback and takes care of disposing\n * the connection after the callback has been run.\n */\n provideConnection<T>(consumer: (connection: DatabaseConnection) => Promise<T>): Promise<T>;\n}\n\nexport class DefaultConnectionProvider implements ConnectionProvider {\n readonly #driver: Driver;\n\n constructor(driver: Driver) {\n this.#driver = driver;\n }\n\n async provideConnection<T>(consumer: (connection: DatabaseConnection) => Promise<T>): Promise<T> {\n const connection = await this.#driver.acquireConnection();\n\n try {\n return await consumer(connection);\n } finally {\n await this.#driver.releaseConnection(connection);\n }\n }\n}\n"],"mappings":";AAUA,IAAa,4BAAb,MAAqE;CACnE,CAASA;CAET,YAAY,QAAgB;AAC1B,QAAKA,SAAU;;CAGjB,MAAM,kBAAqB,UAAsE;EAC/F,MAAM,aAAa,MAAM,MAAKA,OAAQ,mBAAmB;AAEzD,MAAI;AACF,UAAO,MAAM,SAAS,WAAW;YACzB;AACR,SAAM,MAAKA,OAAQ,kBAAkB,WAAW"}
@@ -0,0 +1,23 @@
1
+ //#region src/sql-driver/connection/single-connection-provider.ts
2
+ const ignoreError = () => {};
3
+ var SingleConnectionProvider = class {
4
+ #connection;
5
+ #runningPromise;
6
+ constructor(connection) {
7
+ this.#connection = connection;
8
+ }
9
+ async provideConnection(consumer) {
10
+ while (this.#runningPromise) await this.#runningPromise.catch(ignoreError);
11
+ this.#runningPromise = this.#run(consumer).finally(() => {
12
+ this.#runningPromise = void 0;
13
+ });
14
+ return this.#runningPromise;
15
+ }
16
+ async #run(runner) {
17
+ return await runner(this.#connection);
18
+ }
19
+ };
20
+
21
+ //#endregion
22
+ export { SingleConnectionProvider };
23
+ //# sourceMappingURL=single-connection-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-connection-provider.js","names":["#connection","#runningPromise","#run"],"sources":["../../../src/sql-driver/connection/single-connection-provider.ts"],"sourcesContent":["/**\n * Adapted from Kysely's SingleConnectionProvider\n * Modified from: https://github.com/kysely-org/kysely\n * License: MIT\n * Copyright (c) 2022 Sami Koskimäki\n */\n\nimport type { DatabaseConnection } from \"../sql-driver\";\nimport type { ConnectionProvider } from \"./connection-provider\";\n\nconst ignoreError = () => {};\n\nexport class SingleConnectionProvider implements ConnectionProvider {\n readonly #connection: DatabaseConnection;\n // oxlint-disable-next-line no-explicit-any\n #runningPromise?: Promise<any>;\n\n constructor(connection: DatabaseConnection) {\n this.#connection = connection;\n }\n\n async provideConnection<T>(consumer: (connection: DatabaseConnection) => Promise<T>): Promise<T> {\n while (this.#runningPromise) {\n await this.#runningPromise.catch(ignoreError);\n }\n\n // `#runningPromise` must be set to undefined before it's\n // resolved or rejected. Otherwise the while loop above\n // will misbehave.\n this.#runningPromise = this.#run(consumer).finally(() => {\n this.#runningPromise = undefined;\n });\n\n return this.#runningPromise;\n }\n\n // Run the runner in an async function to make sure it doesn't\n // throw synchronous errors.\n async #run<T>(runner: (connection: DatabaseConnection) => Promise<T>): Promise<T> {\n return await runner(this.#connection);\n }\n}\n"],"mappings":";AAUA,MAAM,oBAAoB;AAE1B,IAAa,2BAAb,MAAoE;CAClE,CAASA;CAET;CAEA,YAAY,YAAgC;AAC1C,QAAKA,aAAc;;CAGrB,MAAM,kBAAqB,UAAsE;AAC/F,SAAO,MAAKC,eACV,OAAM,MAAKA,eAAgB,MAAM,YAAY;AAM/C,QAAKA,iBAAkB,MAAKC,IAAK,SAAS,CAAC,cAAc;AACvD,SAAKD,iBAAkB;IACvB;AAEF,SAAO,MAAKA;;CAKd,OAAMC,IAAQ,QAAoE;AAChF,SAAO,MAAM,OAAO,MAAKF,WAAY"}