@fragno-dev/db 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/.turbo/turbo-build.log +202 -140
  2. package/CHANGELOG.md +35 -0
  3. package/README.md +30 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  19. package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  21. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  31. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +39 -29
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  41. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  42. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  43. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  44. package/dist/adapters/generic-sql/uow-decoder.js +7 -3
  45. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  46. package/dist/adapters/generic-sql/uow-encoder.js +28 -8
  47. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  48. package/dist/adapters/in-memory/condition-evaluator.js +131 -0
  49. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  50. package/dist/adapters/in-memory/errors.d.ts +13 -0
  51. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  52. package/dist/adapters/in-memory/errors.js +23 -0
  53. package/dist/adapters/in-memory/errors.js.map +1 -0
  54. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  55. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  56. package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
  57. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  58. package/dist/adapters/in-memory/in-memory-uow.js +648 -0
  59. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  60. package/dist/adapters/in-memory/index.d.ts +4 -0
  61. package/dist/adapters/in-memory/index.js +4 -0
  62. package/dist/adapters/in-memory/options.d.ts +28 -0
  63. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  64. package/dist/adapters/in-memory/options.js +61 -0
  65. package/dist/adapters/in-memory/options.js.map +1 -0
  66. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  67. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  68. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  69. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  70. package/dist/adapters/in-memory/store.js +71 -0
  71. package/dist/adapters/in-memory/store.js.map +1 -0
  72. package/dist/adapters/in-memory/value-comparison.js +28 -0
  73. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  74. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  75. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  76. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  77. package/dist/adapters/sql/index.d.ts +5 -0
  78. package/dist/adapters/sql/index.js +4 -0
  79. package/dist/db-fragment-definition-builder.d.ts +18 -7
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +116 -54
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
  84. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  85. package/dist/dispatchers/cloudflare-do/index.js +63 -0
  86. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  87. package/dist/dispatchers/node/index.d.ts +17 -0
  88. package/dist/dispatchers/node/index.d.ts.map +1 -0
  89. package/dist/dispatchers/node/index.js +59 -0
  90. package/dist/dispatchers/node/index.js.map +1 -0
  91. package/dist/fragments/internal-fragment.d.ts +79 -2
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +150 -32
  94. package/dist/fragments/internal-fragment.js.map +1 -1
  95. package/dist/fragments/internal-fragment.routes.js +29 -0
  96. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  97. package/dist/fragments/internal-fragment.schema.d.ts +9 -0
  98. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  99. package/dist/fragments/internal-fragment.schema.js +22 -0
  100. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  101. package/dist/hooks/durable-hooks-processor.d.ts +14 -0
  102. package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
  103. package/dist/hooks/durable-hooks-processor.js +32 -0
  104. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  105. package/dist/hooks/hooks.d.ts +42 -1
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +72 -6
  108. package/dist/hooks/hooks.js.map +1 -1
  109. package/dist/migration-engine/auto-from-schema.js +14 -11
  110. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  111. package/dist/migration-engine/generation-engine.d.ts +16 -10
  112. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  113. package/dist/migration-engine/generation-engine.js +72 -33
  114. package/dist/migration-engine/generation-engine.js.map +1 -1
  115. package/dist/migration-engine/shared.js.map +1 -1
  116. package/dist/mod.d.ts +15 -8
  117. package/dist/mod.d.ts.map +1 -1
  118. package/dist/mod.js +14 -8
  119. package/dist/mod.js.map +1 -1
  120. package/dist/naming/sql-naming.d.ts +19 -0
  121. package/dist/naming/sql-naming.d.ts.map +1 -0
  122. package/dist/naming/sql-naming.js +116 -0
  123. package/dist/naming/sql-naming.js.map +1 -0
  124. package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
  125. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
  126. package/dist/outbox/outbox-builder.js +156 -0
  127. package/dist/outbox/outbox-builder.js.map +1 -0
  128. package/dist/outbox/outbox.d.ts +52 -0
  129. package/dist/outbox/outbox.d.ts.map +1 -0
  130. package/dist/outbox/outbox.js +37 -0
  131. package/dist/outbox/outbox.js.map +1 -0
  132. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
  133. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
  134. package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
  135. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  136. package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
  137. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
  138. package/dist/packages/fragno/dist/api/route.js +14 -1
  139. package/dist/packages/fragno/dist/api/route.js.map +1 -1
  140. package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
  141. package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
  142. package/dist/query/column-defaults.js +20 -4
  143. package/dist/query/column-defaults.js.map +1 -1
  144. package/dist/query/cursor.d.ts +3 -1
  145. package/dist/query/cursor.d.ts.map +1 -1
  146. package/dist/query/cursor.js +45 -14
  147. package/dist/query/cursor.js.map +1 -1
  148. package/dist/query/db-now.d.ts +8 -0
  149. package/dist/query/db-now.d.ts.map +1 -0
  150. package/dist/query/db-now.js +7 -0
  151. package/dist/query/db-now.js.map +1 -0
  152. package/dist/query/serialize/create-sql-serializer.js +3 -2
  153. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  154. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  155. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  156. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  157. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  158. package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
  159. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  160. package/dist/query/serialize/sql-serializer.js +2 -2
  161. package/dist/query/serialize/sql-serializer.js.map +1 -1
  162. package/dist/query/simple-query-interface.d.ts +6 -1
  163. package/dist/query/simple-query-interface.d.ts.map +1 -1
  164. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  165. package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
  166. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  167. package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
  168. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  169. package/dist/query/unit-of-work/unit-of-work.js +86 -5
  170. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  171. package/dist/query/value-decoding.js +9 -6
  172. package/dist/query/value-decoding.js.map +1 -1
  173. package/dist/query/value-encoding.js +29 -9
  174. package/dist/query/value-encoding.js.map +1 -1
  175. package/dist/schema/create.d.ts +38 -14
  176. package/dist/schema/create.d.ts.map +1 -1
  177. package/dist/schema/create.js +81 -42
  178. package/dist/schema/create.js.map +1 -1
  179. package/dist/schema/generate-id.js +2 -2
  180. package/dist/schema/generate-id.js.map +1 -1
  181. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  182. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  183. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  184. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  185. package/dist/schema/validator.d.ts +10 -0
  186. package/dist/schema/validator.d.ts.map +1 -0
  187. package/dist/schema/validator.js +123 -0
  188. package/dist/schema/validator.js.map +1 -0
  189. package/dist/schema-output/drizzle.d.ts +30 -0
  190. package/dist/schema-output/drizzle.d.ts.map +1 -0
  191. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  192. package/dist/schema-output/drizzle.js.map +1 -0
  193. package/dist/schema-output/prisma.d.ts +17 -0
  194. package/dist/schema-output/prisma.d.ts.map +1 -0
  195. package/dist/schema-output/prisma.js +296 -0
  196. package/dist/schema-output/prisma.js.map +1 -0
  197. package/dist/util/default-database-adapter.js +61 -0
  198. package/dist/util/default-database-adapter.js.map +1 -0
  199. package/dist/with-database.d.ts +1 -1
  200. package/dist/with-database.d.ts.map +1 -1
  201. package/dist/with-database.js +12 -3
  202. package/dist/with-database.js.map +1 -1
  203. package/package.json +43 -28
  204. package/src/adapters/adapters.ts +30 -24
  205. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  206. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  207. package/src/adapters/drizzle/test-utils.ts +12 -8
  208. package/src/adapters/generic-sql/driver-config.ts +38 -0
  209. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  210. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  211. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  212. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  213. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  214. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  215. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  216. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  217. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  218. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  219. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  220. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  221. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  222. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  223. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  224. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  225. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  226. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  227. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  228. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  229. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  230. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  231. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  232. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  233. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  234. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  235. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  236. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  237. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
  238. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
  239. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  240. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  241. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  242. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  243. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  244. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  245. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  246. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  247. package/src/adapters/in-memory/errors.ts +20 -0
  248. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  249. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  250. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  251. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  252. package/src/adapters/in-memory/index.ts +3 -0
  253. package/src/adapters/in-memory/options.test.ts +41 -0
  254. package/src/adapters/in-memory/options.ts +87 -0
  255. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  256. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  257. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  258. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  259. package/src/adapters/in-memory/store.test.ts +68 -0
  260. package/src/adapters/in-memory/store.ts +145 -0
  261. package/src/adapters/in-memory/value-comparison.ts +53 -0
  262. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  263. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  264. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  265. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  266. package/src/adapters/sql/index.ts +12 -0
  267. package/src/db-fragment-definition-builder.test.ts +30 -12
  268. package/src/db-fragment-definition-builder.ts +142 -73
  269. package/src/db-fragment-instantiator.test.ts +105 -13
  270. package/src/db-fragment-integration.test.ts +9 -7
  271. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  272. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  273. package/src/dispatchers/node/index.test.ts +91 -0
  274. package/src/dispatchers/node/index.ts +87 -0
  275. package/src/fragments/internal-fragment.routes.ts +42 -0
  276. package/src/fragments/internal-fragment.schema.ts +51 -0
  277. package/src/fragments/internal-fragment.test.ts +458 -8
  278. package/src/fragments/internal-fragment.ts +322 -63
  279. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  280. package/src/hooks/durable-hooks-processor.ts +67 -0
  281. package/src/hooks/hooks.test.ts +165 -5
  282. package/src/hooks/hooks.ts +197 -9
  283. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  284. package/src/migration-engine/auto-from-schema.ts +5 -2
  285. package/src/migration-engine/create.test.ts +2 -2
  286. package/src/migration-engine/generation-engine.test.ts +229 -104
  287. package/src/migration-engine/generation-engine.ts +94 -64
  288. package/src/migration-engine/shared.ts +1 -0
  289. package/src/mod.ts +64 -26
  290. package/src/naming/sql-naming.ts +180 -0
  291. package/src/outbox/outbox-builder.ts +241 -0
  292. package/src/outbox/outbox.test.ts +253 -0
  293. package/src/outbox/outbox.ts +137 -0
  294. package/src/query/column-defaults.ts +41 -3
  295. package/src/query/condition-builder.test.ts +3 -3
  296. package/src/query/cursor.test.ts +116 -18
  297. package/src/query/cursor.ts +75 -26
  298. package/src/query/db-now.ts +6 -0
  299. package/src/query/query-type.test.ts +2 -2
  300. package/src/query/serialize/create-sql-serializer.ts +7 -2
  301. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  302. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  303. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  304. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  305. package/src/query/serialize/sql-serializer.ts +4 -4
  306. package/src/query/simple-query-interface.ts +5 -0
  307. package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
  308. package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
  309. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
  310. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  311. package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
  312. package/src/query/unit-of-work/unit-of-work.ts +203 -18
  313. package/src/query/value-decoding.test.ts +13 -2
  314. package/src/query/value-decoding.ts +17 -4
  315. package/src/query/value-encoding.test.ts +85 -2
  316. package/src/query/value-encoding.ts +56 -6
  317. package/src/schema/create.test.ts +129 -42
  318. package/src/schema/create.ts +185 -47
  319. package/src/schema/generate-id.test.ts +2 -2
  320. package/src/schema/generate-id.ts +2 -2
  321. package/src/schema/serialize.test.ts +14 -2
  322. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  323. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  324. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  325. package/src/schema/validator.test.ts +197 -0
  326. package/src/schema/validator.ts +231 -0
  327. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  328. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  329. package/src/schema-output/prisma.test.ts +536 -0
  330. package/src/schema-output/prisma.ts +573 -0
  331. package/src/util/default-database-adapter.ts +106 -0
  332. package/src/with-database.ts +22 -3
  333. package/tsdown.config.ts +6 -4
  334. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  335. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  337. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  338. package/dist/adapters/drizzle/generate.d.ts +0 -30
  339. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/generate.js.map +0 -1
  341. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  342. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  343. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  344. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  345. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  346. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  347. package/dist/adapters/shared/table-name-mapper.js +0 -43
  348. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  349. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  350. package/dist/schema-generator/schema-generator.d.ts +0 -15
  351. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  352. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  353. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  354. package/src/adapters/shared/table-name-mapper.ts +0 -50
  355. package/src/schema-generator/schema-generator.ts +0 -12
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","names":[],"sources":["../../src/migration-engine/shared.ts"],"sourcesContent":["export interface ForeignKeyInfo {\n name: string;\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n}\n\n/**\n * Provider-specific metadata that can be attached to operations during preprocessing.\n * This allows providers to add additional context without polluting the core operation types.\n */\nexport interface MigrationOperationMetadata {\n [key: string]: unknown;\n}\n\n/**\n * SQLite-specific metadata for create-table operations.\n * Includes foreign keys that should be created inline with the table.\n */\nexport interface SqliteCreateTableMetadata extends MigrationOperationMetadata {\n inlineForeignKeys?: ForeignKeyInfo[];\n}\n\nexport interface ColumnInfo {\n name: string;\n type:\n | \"string\"\n | \"integer\"\n | \"bigint\"\n | \"decimal\"\n | \"bool\"\n | \"date\"\n | \"timestamp\"\n | \"json\"\n | \"binary\"\n | `varchar(${number})`;\n isNullable: boolean;\n role: \"external-id\" | \"internal-id\" | \"version\" | \"reference\" | \"regular\";\n default?: { value: unknown } | { dbSpecial: \"now\" } | { runtime: \"cuid\" | \"now\" };\n}\n\nexport type MigrationOperation<\n TMeta extends MigrationOperationMetadata = MigrationOperationMetadata,\n> =\n | (TableOperation & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"add-foreign-key\";\n table: string;\n value: ForeignKeyInfo;\n } & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"drop-foreign-key\";\n table: string;\n name: string;\n } & { metadata?: TMeta })\n | ({\n type: \"drop-index\";\n table: string;\n name: string;\n } & { metadata?: TMeta })\n | ({\n type: \"add-index\";\n table: string;\n columns: string[];\n name: string;\n unique: boolean;\n } & { metadata?: TMeta })\n | (CustomOperation & { metadata?: TMeta });\n\nexport type CustomOperation = {\n type: \"custom\";\n} & Record<string, unknown>;\n\nexport type TableOperation =\n | {\n type: \"create-table\";\n name: string;\n columns: ColumnInfo[];\n }\n | {\n type: \"drop-table\";\n name: string;\n }\n | {\n type: \"alter-table\";\n name: string;\n value: ColumnOperation[];\n }\n | {\n type: \"rename-table\";\n from: string;\n to: string;\n };\n\nexport type ColumnOperation =\n | {\n type: \"rename-column\";\n from: string;\n to: string;\n }\n | {\n type: \"drop-column\";\n name: string;\n }\n | {\n /**\n * Note: unique constraints are not created, please use dedicated operations like `add-index` instead\n */\n type: \"create-column\";\n value: ColumnInfo;\n }\n | {\n /**\n * warning: Not supported by SQLite\n */\n type: \"update-column\";\n name: string;\n /**\n * For databases like MySQL, it requires the full definition for any modify column statement.\n * Hence, you need to specify the full information of your column here.\n *\n * Then, opt-in for in-detail modification for other databases that supports changing data type/nullable/default separately, such as PostgreSQL.\n *\n * Note: unique constraints are not updated, please use dedicated operations like `add-index` instead\n */\n value: ColumnInfo;\n\n updateNullable: boolean;\n updateDefault: boolean;\n updateDataType: boolean;\n };\n\nexport function isUpdated(op: Extract<ColumnOperation, { type: \"update-column\" }>): boolean {\n return op.updateDataType || op.updateDefault || op.updateNullable;\n}\n"],"mappings":";AAsIA,SAAgB,UAAU,IAAkE;AAC1F,QAAO,GAAG,kBAAkB,GAAG,iBAAiB,GAAG"}
1
+ {"version":3,"file":"shared.js","names":[],"sources":["../../src/migration-engine/shared.ts"],"sourcesContent":["export interface ForeignKeyInfo {\n name: string;\n columns: string[];\n referencedTable: string;\n referencedColumns: string[];\n}\n\n/**\n * Provider-specific metadata that can be attached to operations during preprocessing.\n * This allows providers to add additional context without polluting the core operation types.\n */\nexport interface MigrationOperationMetadata {\n [key: string]: unknown;\n}\n\n/**\n * SQLite-specific metadata for create-table operations.\n * Includes foreign keys that should be created inline with the table.\n */\nexport interface SqliteCreateTableMetadata extends MigrationOperationMetadata {\n inlineForeignKeys?: ForeignKeyInfo[];\n}\n\nexport interface ColumnInfo {\n name: string;\n type:\n | \"string\"\n | \"integer\"\n | \"bigint\"\n | \"decimal\"\n | \"bool\"\n | \"date\"\n | \"timestamp\"\n | \"json\"\n | \"binary\"\n | `varchar(${number})`;\n isNullable: boolean;\n role: \"external-id\" | \"internal-id\" | \"version\" | \"reference\" | \"regular\";\n default?: { value: unknown } | { dbSpecial: \"now\" } | { runtime: \"cuid\" | \"now\" };\n}\n\nexport type MigrationOperation<\n TMeta extends MigrationOperationMetadata = MigrationOperationMetadata,\n> =\n | (TableOperation & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"add-foreign-key\";\n table: string;\n value: ForeignKeyInfo;\n } & { metadata?: TMeta })\n | ({\n // warning: not supported by SQLite\n type: \"drop-foreign-key\";\n table: string;\n name: string;\n referencedTable: string;\n } & { metadata?: TMeta })\n | ({\n type: \"drop-index\";\n table: string;\n name: string;\n } & { metadata?: TMeta })\n | ({\n type: \"add-index\";\n table: string;\n columns: string[];\n name: string;\n unique: boolean;\n } & { metadata?: TMeta })\n | (CustomOperation & { metadata?: TMeta });\n\nexport type CustomOperation = {\n type: \"custom\";\n} & Record<string, unknown>;\n\nexport type TableOperation =\n | {\n type: \"create-table\";\n name: string;\n columns: ColumnInfo[];\n }\n | {\n type: \"drop-table\";\n name: string;\n }\n | {\n type: \"alter-table\";\n name: string;\n value: ColumnOperation[];\n }\n | {\n type: \"rename-table\";\n from: string;\n to: string;\n };\n\nexport type ColumnOperation =\n | {\n type: \"rename-column\";\n from: string;\n to: string;\n }\n | {\n type: \"drop-column\";\n name: string;\n }\n | {\n /**\n * Note: unique constraints are not created, please use dedicated operations like `add-index` instead\n */\n type: \"create-column\";\n value: ColumnInfo;\n }\n | {\n /**\n * warning: Not supported by SQLite\n */\n type: \"update-column\";\n name: string;\n /**\n * For databases like MySQL, it requires the full definition for any modify column statement.\n * Hence, you need to specify the full information of your column here.\n *\n * Then, opt-in for in-detail modification for other databases that supports changing data type/nullable/default separately, such as PostgreSQL.\n *\n * Note: unique constraints are not updated, please use dedicated operations like `add-index` instead\n */\n value: ColumnInfo;\n\n updateNullable: boolean;\n updateDefault: boolean;\n updateDataType: boolean;\n };\n\nexport function isUpdated(op: Extract<ColumnOperation, { type: \"update-column\" }>): boolean {\n return op.updateDataType || op.updateDefault || op.updateNullable;\n}\n"],"mappings":";AAuIA,SAAgB,UAAU,IAAkE;AAC1F,QAAO,GAAG,kBAAkB,GAAG,iBAAiB,GAAG"}
package/dist/mod.d.ts CHANGED
@@ -1,11 +1,18 @@
1
+ import { DbNow, dbNow } from "./query/db-now.js";
1
2
  import { AnySchema } from "./schema/create.js";
2
3
  import { Cursor, CursorData, CursorResult, decodeCursor } from "./query/cursor.js";
3
4
  import { ExponentialBackoffRetryPolicy, LinearBackoffRetryPolicy, NoRetryPolicy, RetryPolicy } from "./query/unit-of-work/retry-policy.js";
4
5
  import { BuilderTransformContextWithMutate, BuilderTransformContextWithoutMutate, ConcurrencyConflictError, ExtractServiceFinalResults, ExtractServiceRetrieveResults, HandlerBuilderMutateContext, HandlerTxBuilder, ServiceBuilderMutateContext, ServiceTxBuilder, TxResult, createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
5
- import { DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, DatabaseHandlerContext, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies } from "./db-fragment-definition-builder.js";
6
+ import { DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, DatabaseHandlerContext, DatabaseServiceContext, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies } from "./db-fragment-definition-builder.js";
7
+ import { InMemoryAdapterOptions } from "./adapters/in-memory/options.js";
8
+ import { InMemoryAdapter } from "./adapters/in-memory/in-memory-adapter.js";
9
+ import "./adapters/in-memory/index.js";
6
10
  import { withDatabase } from "./with-database.js";
11
+ import { OutboxConfig, OutboxEntry, OutboxMutation, OutboxPayload, OutboxRefMap } from "./outbox/outbox.js";
12
+ import { DurableHooksProcessor, createDurableHooksProcessor } from "./hooks/durable-hooks-processor.js";
13
+ import { internalSchema } from "./fragments/internal-fragment.schema.js";
7
14
  import { InternalFragmentInstance, internalFragmentDef } from "./fragments/internal-fragment.js";
8
- import { HookContext, HookFn, HookPayload, HooksMap, TriggerHookOptions } from "./hooks/hooks.js";
15
+ import { DurableHooksProcessingOptions, HookContext, HookFn, HookPayload, HooksMap, StuckHookProcessingEvent, StuckHookProcessingInfo, StuckHookProcessingTimeoutMinutes, TriggerHookOptions } from "./hooks/hooks.js";
9
16
  import { IUnitOfWork, IUnitOfWorkRestricted, TypedUnitOfWork, UOWCompiler, UOWDecoder, UOWExecutor, UnitOfWork, createUnitOfWork } from "./query/unit-of-work/unit-of-work.js";
10
17
  import { DatabaseAdapter } from "./adapters/adapters.js";
11
18
  import { AnyFragnoInstantiatedFragment, BoundServices, FragnoInstantiatedFragment } from "@fragno-dev/core";
@@ -14,7 +21,7 @@ import { AnyFragnoInstantiatedFragment, BoundServices, FragnoInstantiatedFragmen
14
21
  declare const fragnoDatabaseFakeSymbol: "$fragno-database";
15
22
  declare const fragnoDatabaseLibraryVersion: "0.1";
16
23
  interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {
17
- namespace: string;
24
+ namespace: string | null;
18
25
  schema: T;
19
26
  }
20
27
  declare function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema>;
@@ -25,16 +32,16 @@ declare function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySc
25
32
  declare class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {
26
33
  #private;
27
34
  constructor(options: {
28
- namespace: string;
35
+ namespace: string | null;
29
36
  schema: T;
30
37
  adapter: DatabaseAdapter<TUOWConfig>;
31
38
  });
32
39
  get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol;
33
- get namespace(): string;
40
+ get namespace(): string | null;
34
41
  get schema(): T;
35
42
  get adapter(): DatabaseAdapter<TUOWConfig>;
36
43
  }
37
- type AnyFragnoInstantiatedDatabaseFragment = FragnoInstantiatedFragment<any, ImplicitDatabaseDependencies<AnySchema>, any, any, any, any, FragnoPublicConfigWithDatabase, {
44
+ type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> = FragnoInstantiatedFragment<any, ImplicitDatabaseDependencies<TSchema>, any, any, any, any, FragnoPublicConfigWithDatabase, {
38
45
  _fragno_internal: InternalFragmentInstance;
39
46
  } & Record<string, AnyFragnoInstantiatedFragment>>;
40
47
  /**
@@ -59,7 +66,7 @@ type AnyFragnoInstantiatedDatabaseFragment = FragnoInstantiatedFragment<any, Imp
59
66
  * await migrate(fragment);
60
67
  * ```
61
68
  */
62
- declare function migrate(fragment: AnyFragnoInstantiatedDatabaseFragment): Promise<void>;
69
+ declare function migrate<TSchema extends AnySchema>(fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>): Promise<void>;
63
70
  //#endregion
64
- export { AnyFragnoInstantiatedDatabaseFragment, type BoundServices, type BuilderTransformContextWithMutate, type BuilderTransformContextWithoutMutate, ConcurrencyConflictError, CreateFragnoDatabaseDefinitionOptions, Cursor, type CursorData, type CursorResult, type DatabaseAdapter, type DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, type DatabaseHandlerContext as DatabaseRequestContext, ExponentialBackoffRetryPolicy, type ExtractServiceFinalResults, type ExtractServiceRetrieveResults, FragnoDatabase, type FragnoPublicConfigWithDatabase, type HandlerBuilderMutateContext, HandlerTxBuilder, type HookContext, type HookFn, type HookPayload, type HooksMap, type IUnitOfWork, type IUnitOfWorkRestricted, type ImplicitDatabaseDependencies, type InternalFragmentInstance, LinearBackoffRetryPolicy, NoRetryPolicy, type RetryPolicy, type ServiceBuilderMutateContext, ServiceTxBuilder, type TriggerHookOptions, type TxResult, TypedUnitOfWork, type UOWCompiler, type UOWDecoder, type UOWExecutor, UnitOfWork, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, decodeCursor, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, internalFragmentDef, isFragnoDatabase, migrate, withDatabase };
71
+ export { AnyFragnoInstantiatedDatabaseFragment, type BoundServices, type BuilderTransformContextWithMutate, type BuilderTransformContextWithoutMutate, ConcurrencyConflictError, CreateFragnoDatabaseDefinitionOptions, Cursor, type CursorData, type CursorResult, type DatabaseAdapter, type DatabaseFragmentContext, DatabaseFragmentDefinitionBuilder, type DatabaseHandlerContext as DatabaseRequestContext, type DatabaseServiceContext, type DbNow, type DurableHooksProcessingOptions, type DurableHooksProcessor, ExponentialBackoffRetryPolicy, type ExtractServiceFinalResults, type ExtractServiceRetrieveResults, FragnoDatabase, type FragnoPublicConfigWithDatabase, type HandlerBuilderMutateContext, HandlerTxBuilder, type HookContext, type HookFn, type HookPayload, type HooksMap, type IUnitOfWork, type IUnitOfWorkRestricted, type ImplicitDatabaseDependencies, InMemoryAdapter, type InMemoryAdapterOptions, type InternalFragmentInstance, LinearBackoffRetryPolicy, NoRetryPolicy, type OutboxConfig, type OutboxEntry, type OutboxMutation, type OutboxPayload, type OutboxRefMap, type RetryPolicy, type ServiceBuilderMutateContext, ServiceTxBuilder, type StuckHookProcessingEvent, type StuckHookProcessingInfo, type StuckHookProcessingTimeoutMinutes, type TriggerHookOptions, type TxResult, TypedUnitOfWork, type UOWCompiler, type UOWDecoder, type UOWExecutor, UnitOfWork, createDurableHooksProcessor, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, dbNow, decodeCursor, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, internalFragmentDef, internalSchema, isFragnoDatabase, migrate, withDatabase };
65
72
  //# sourceMappingURL=mod.d.ts.map
package/dist/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;cAiBa;cACA;UAEI,gDAAgD;;EAHpD,MAAA,EAKH,CALG;AACb;AAEiB,iBAKD,gBAAA,CALC,KAAqC,EAAA,OAAA,CAAW,EAAA,KAAA,IAKN,cAHhD,CAG+D,SAH/D,CAAA;AAGX;AAmBA;;;AAKgF,cALnE,cAKmE,CAAA,gBALpC,SAKoC,EAAA,aAAA,IAAA,CAAA,CAAA;EAAhB,CAAA,OAAA;EAMrB,WAAA,CAAA,OAAA,EAAA;IAApC,SAAA,EAAA,MAAA;IAQK,MAAA,EAdwC,CAcxC;IAIqB,OAAA,EAlB+B,eAkB/B,CAlB+C,UAkB/C,CAAA;EAAhB,CAAA;EAAe,KAZzB,wBAAA,GAYyB,EAAA,OAZW,wBAYX;EA2DpB,IAAA,SAAA,CAAA,CAAA,EAAA,MAAA;EAGmB,IAAA,MAAA,CAAA,CAAA,EAlEnB,CAkEmB;EAA7B,IAAA,OAAA,CAAA,CAAA,EA9De,eA8Df,CA9D+B,UA8D/B,CAAA;;KAHU,qCAAA,GAAwC,gCAGlD,6BAA6B,gCAS7B;oBAEoB;IAA6B,eAAe;;;;;;;;;;;;;;;;;;;;;;;iBAyB5C,OAAA,WAAkB,wCAAwC"}
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;cAuBa;cACA;UAEI,gDAAgD;;UAEvD;;AALG,iBAQG,gBAAA,CARmD,KAAA,EAAA,OAAA,CAAA,EAAA,KAAA,IAQR,cARQ,CAQO,SARP,CAAA;AACnE;AAEA;AAKA;AAmBA;AAA4C,cAA/B,cAA+B,CAAA,gBAAA,SAAA,EAAA,aAAA,IAAA,CAAA,CAAA;EAOhC,CAAA,OAAA;EACiB,WAAA,CAAA,OAAA,EAAA;IAAhB,SAAA,EAAA,MAAA,GAAA,IAAA;IAO8B,MAAA,EAR/B,CAQ+B;IAApC,OAAA,EAPM,eAON,CAPsB,UAOtB,CAAA;EAQK,CAAA;EAIqB,KAZ1B,wBAAA,GAY0B,EAAA,OAZU,wBAYV;EAAhB,IAAA,SAAA,CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAe,IAAA,MAAA,CAAA,CAAA,EAJpB,CAIoB;EAiFpB,IAAA,OAAA,CAAA,CAAA,EAjFK,eAiFL,CAjFqB,UAiFgB,CAAA;;AAyCrC,KAzCA,qCAyCA,CAAA,gBAzCsD,SAyCtD,GAzCkE,SAyClE,CAAA,GAxCV,0BAwCU,CAAA,GAAA,EArCR,4BAqCQ,CArCqB,OAqCrB,CAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EA5BR,8BA4BQ,EAAA;EACT,gBAAA,EA3BqB,wBA2BrB;CAAO,GA3B2C,MA2B3C,CAAA,MAAA,EA3B0D,6BA2B1D,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;iBAFY,wBAAwB,qBAClC,sCAAsC,WAC/C"}
package/dist/mod.js CHANGED
@@ -1,10 +1,16 @@
1
1
  import { ExponentialBackoffRetryPolicy, LinearBackoffRetryPolicy, NoRetryPolicy } from "./query/unit-of-work/retry-policy.js";
2
2
  import { ConcurrencyConflictError, HandlerTxBuilder, ServiceTxBuilder, createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
3
- import { DatabaseFragmentDefinitionBuilder } from "./db-fragment-definition-builder.js";
3
+ import { internalSchema } from "./fragments/internal-fragment.schema.js";
4
4
  import { Cursor, decodeCursor } from "./query/cursor.js";
5
+ import { dbNow } from "./query/db-now.js";
6
+ import { TypedUnitOfWork, UnitOfWork, createUnitOfWork } from "./query/unit-of-work/unit-of-work.js";
7
+ import { resolveDatabaseAdapter } from "./util/default-database-adapter.js";
8
+ import { DatabaseFragmentDefinitionBuilder } from "./db-fragment-definition-builder.js";
5
9
  import { getSchemaVersionFromDatabase, internalFragmentDef } from "./fragments/internal-fragment.js";
10
+ import { InMemoryAdapter } from "./adapters/in-memory/in-memory-adapter.js";
11
+ import "./adapters/in-memory/index.js";
6
12
  import { withDatabase } from "./with-database.js";
7
- import { TypedUnitOfWork, UnitOfWork, createUnitOfWork } from "./query/unit-of-work/unit-of-work.js";
13
+ import { createDurableHooksProcessor } from "./hooks/durable-hooks-processor.js";
8
14
 
9
15
  //#region src/mod.ts
10
16
  const fragnoDatabaseFakeSymbol = "$fragno-database";
@@ -64,18 +70,18 @@ var FragnoDatabase = class {
64
70
  */
65
71
  async function migrate(fragment) {
66
72
  const { options, deps, linkedFragments } = fragment.$internal;
67
- const adapter = options.databaseAdapter;
73
+ const adapter = resolveDatabaseAdapter(options, deps.schema);
68
74
  if (!adapter.prepareMigrations) throw new Error("Database adapter does not support prepareMigrations. Please use an adapter that implements this method.");
69
75
  const schema = deps.schema;
70
- const namespace = deps.namespace;
76
+ const namespace = deps.namespace ?? schema.name;
71
77
  const internalFragment = linkedFragments._fragno_internal;
72
78
  if (!internalFragment) throw new Error("Internal fragment not found. Please ensure the internal fragment is linked.");
73
79
  if (!await adapter.isConnectionHealthy()) throw new Error("Database connection is not healthy. Please check your database connection and try again.");
74
80
  const internalDeps = internalFragment.$internal.deps;
75
- const internalSchema = internalDeps.schema;
76
- const internalNamespace = internalDeps.namespace;
81
+ const internalSchema$1 = internalDeps.schema;
82
+ const internalNamespace = internalDeps.namespace ?? "";
77
83
  const internalCurrentVersion = await getSchemaVersionFromDatabase(internalFragment, internalNamespace);
78
- if (internalCurrentVersion < internalSchema.version) await adapter.prepareMigrations(internalSchema, internalNamespace).execute(internalCurrentVersion, internalSchema.version);
84
+ if (internalCurrentVersion < internalSchema$1.version) await adapter.prepareMigrations(internalSchema$1, internalNamespace).execute(internalCurrentVersion, internalSchema$1.version);
79
85
  const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);
80
86
  const targetVersion = schema.version;
81
87
  if (currentVersion === targetVersion) return;
@@ -84,5 +90,5 @@ async function migrate(fragment) {
84
90
  }
85
91
 
86
92
  //#endregion
87
- export { ConcurrencyConflictError, Cursor, DatabaseFragmentDefinitionBuilder, ExponentialBackoffRetryPolicy, FragnoDatabase, HandlerTxBuilder, LinearBackoffRetryPolicy, NoRetryPolicy, ServiceTxBuilder, TypedUnitOfWork, UnitOfWork, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, decodeCursor, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, internalFragmentDef, isFragnoDatabase, migrate, withDatabase };
93
+ export { ConcurrencyConflictError, Cursor, DatabaseFragmentDefinitionBuilder, ExponentialBackoffRetryPolicy, FragnoDatabase, HandlerTxBuilder, InMemoryAdapter, LinearBackoffRetryPolicy, NoRetryPolicy, ServiceTxBuilder, TypedUnitOfWork, UnitOfWork, createDurableHooksProcessor, createHandlerTxBuilder, createServiceTxBuilder, createUnitOfWork, dbNow, decodeCursor, fragnoDatabaseFakeSymbol, fragnoDatabaseLibraryVersion, internalFragmentDef, internalSchema, isFragnoDatabase, migrate, withDatabase };
88
94
  //# sourceMappingURL=mod.js.map
package/dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","names":["#namespace","#schema","#adapter"],"sources":["../src/mod.ts"],"sourcesContent":["import type { DatabaseAdapter } from \"./adapters/adapters\";\nimport type { AnySchema } from \"./schema/create\";\nimport type { CursorResult } from \"./query/cursor\";\nimport { Cursor } from \"./query/cursor\";\nimport type { FragnoInstantiatedFragment, AnyFragnoInstantiatedFragment } from \"@fragno-dev/core\";\nimport type {\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\nimport {\n getSchemaVersionFromDatabase,\n type InternalFragmentInstance,\n} from \"./fragments/internal-fragment\";\n\nexport type { DatabaseAdapter, CursorResult };\nexport { Cursor };\n\nexport const fragnoDatabaseFakeSymbol = \"$fragno-database\" as const;\nexport const fragnoDatabaseLibraryVersion = \"0.1\" as const;\n\nexport interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {\n namespace: string;\n schema: T;\n}\n\nexport function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema> {\n if (value instanceof FragnoDatabase) {\n return true;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n return (\n fragnoDatabaseFakeSymbol in value &&\n value[fragnoDatabaseFakeSymbol] === fragnoDatabaseFakeSymbol\n );\n}\n\n/**\n * A Fragno database instance with a bound adapter.\n * Created from a FragnoDatabaseDefinition by calling .create(adapter).\n */\nexport class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {\n #namespace: string;\n #schema: T;\n #adapter: DatabaseAdapter<TUOWConfig>;\n\n constructor(options: { namespace: string; schema: T; adapter: DatabaseAdapter<TUOWConfig> }) {\n this.#namespace = options.namespace;\n this.#schema = options.schema;\n this.#adapter = options.adapter;\n }\n\n get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol {\n return fragnoDatabaseFakeSymbol;\n }\n\n get namespace() {\n return this.#namespace;\n }\n\n get schema() {\n return this.#schema;\n }\n\n get adapter(): DatabaseAdapter<TUOWConfig> {\n return this.#adapter;\n }\n}\n\nexport {\n DatabaseFragmentDefinitionBuilder,\n type FragnoPublicConfigWithDatabase,\n type DatabaseFragmentContext,\n type DatabaseHandlerContext as DatabaseRequestContext,\n type ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\n\nexport { withDatabase } from \"./with-database\";\n\nexport { decodeCursor, type CursorData } from \"./query/cursor\";\n\nexport {\n createUnitOfWork,\n UnitOfWork,\n TypedUnitOfWork,\n type IUnitOfWork,\n type IUnitOfWorkRestricted,\n type UOWCompiler,\n type UOWExecutor,\n type UOWDecoder,\n} from \"./query/unit-of-work/unit-of-work\";\n\nexport {\n type RetryPolicy,\n NoRetryPolicy,\n ExponentialBackoffRetryPolicy,\n LinearBackoffRetryPolicy,\n} from \"./query/unit-of-work/retry-policy\";\n\nexport {\n ConcurrencyConflictError,\n // Builder pattern exports\n ServiceTxBuilder,\n HandlerTxBuilder,\n createServiceTxBuilder,\n createHandlerTxBuilder,\n type TxResult,\n // Builder context types\n type ServiceBuilderMutateContext,\n type HandlerBuilderMutateContext,\n type BuilderTransformContextWithMutate,\n type BuilderTransformContextWithoutMutate,\n type ExtractServiceRetrieveResults,\n type ExtractServiceFinalResults,\n} from \"./query/unit-of-work/execute-unit-of-work\";\n\nexport type { BoundServices } from \"@fragno-dev/core\";\n\nexport { internalFragmentDef } from \"./fragments/internal-fragment\";\nexport type { InternalFragmentInstance } from \"./fragments/internal-fragment\";\n\nexport type { HookContext, HooksMap, HookFn, HookPayload, TriggerHookOptions } from \"./hooks/hooks\";\n\nexport type AnyFragnoInstantiatedDatabaseFragment = FragnoInstantiatedFragment<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n ImplicitDatabaseDependencies<AnySchema>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n FragnoPublicConfigWithDatabase,\n // Ensure the fragment has the internal fragment linked\n { _fragno_internal: InternalFragmentInstance } & Record<string, AnyFragnoInstantiatedFragment>\n>;\n\n/**\n * Helper function to run migrations for a database fragment.\n * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.\n * This function:\n * 1. Ensures the internal settings fragment is migrated first\n * 2. Retrieves the current database version from the internal fragment\n * 3. Runs migration from current version to target version\n *\n * @param fragment - The instantiated fragment to run migrations for\n * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations\n *\n * @example\n * ```typescript\n * const fragment = instantiate(myFragmentDef)\n * .withConfig({})\n * .withRoutes([])\n * .withOptions({ databaseAdapter: myAdapter })\n * .build();\n *\n * await migrate(fragment);\n * ```\n */\nexport async function migrate(fragment: AnyFragnoInstantiatedDatabaseFragment): Promise<void> {\n const { options, deps, linkedFragments } = fragment.$internal;\n const adapter = options.databaseAdapter;\n\n // Check if adapter supports prepareMigrations\n if (!adapter.prepareMigrations) {\n throw new Error(\n \"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.\",\n );\n }\n\n const schema = deps.schema;\n const namespace = deps.namespace;\n\n // Step 1: Ensure the internal fragment (settings table) is migrated first\n const internalFragment = linkedFragments._fragno_internal;\n\n if (!internalFragment) {\n throw new Error(\"Internal fragment not found. Please ensure the internal fragment is linked.\");\n }\n\n if (!(await adapter.isConnectionHealthy())) {\n throw new Error(\n \"Database connection is not healthy. Please check your database connection and try again.\",\n );\n }\n\n const internalDeps = internalFragment.$internal.deps;\n const internalSchema = internalDeps.schema;\n const internalNamespace = internalDeps.namespace;\n\n const internalCurrentVersion = await getSchemaVersionFromDatabase(\n internalFragment,\n internalNamespace,\n );\n\n // Migrate internal fragment if needed\n if (internalCurrentVersion < internalSchema.version) {\n const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);\n await internalMigrations.execute(internalCurrentVersion, internalSchema.version);\n }\n\n // Step 2: Get current database version for this fragment's namespace\n const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);\n\n // Step 3: Run the migration from current version to target version\n const targetVersion = schema.version;\n\n if (currentVersion === targetVersion) {\n return;\n }\n\n if (currentVersion > targetVersion) {\n throw new Error(\n `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,\n );\n }\n\n const migrations = adapter.prepareMigrations(schema, namespace);\n await migrations.execute(currentVersion, targetVersion);\n}\n"],"mappings":";;;;;;;;;AAiBA,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAO5C,SAAgB,iBAAiB,OAAoD;AACnF,KAAI,iBAAiB,eACnB,QAAO;AAGT,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;AAGT,QACE,4BAA4B,SAC5B,MAAM,8BAA8B;;;;;;AAQxC,IAAa,iBAAb,MAA0E;CACxE;CACA;CACA;CAEA,YAAY,SAAiF;AAC3F,QAAKA,YAAa,QAAQ;AAC1B,QAAKC,SAAU,QAAQ;AACvB,QAAKC,UAAW,QAAQ;;CAG1B,KAAK,4BAA6D;AAChE,SAAO;;CAGT,IAAI,YAAY;AACd,SAAO,MAAKF;;CAGd,IAAI,SAAS;AACX,SAAO,MAAKC;;CAGd,IAAI,UAAuC;AACzC,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;;AAiGhB,eAAsB,QAAQ,UAAgE;CAC5F,MAAM,EAAE,SAAS,MAAM,oBAAoB,SAAS;CACpD,MAAM,UAAU,QAAQ;AAGxB,KAAI,CAAC,QAAQ,kBACX,OAAM,IAAI,MACR,0GACD;CAGH,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK;CAGvB,MAAM,mBAAmB,gBAAgB;AAEzC,KAAI,CAAC,iBACH,OAAM,IAAI,MAAM,8EAA8E;AAGhG,KAAI,CAAE,MAAM,QAAQ,qBAAqB,CACvC,OAAM,IAAI,MACR,2FACD;CAGH,MAAM,eAAe,iBAAiB,UAAU;CAChD,MAAM,iBAAiB,aAAa;CACpC,MAAM,oBAAoB,aAAa;CAEvC,MAAM,yBAAyB,MAAM,6BACnC,kBACA,kBACD;AAGD,KAAI,yBAAyB,eAAe,QAE1C,OAD2B,QAAQ,kBAAkB,gBAAgB,kBAAkB,CAC9D,QAAQ,wBAAwB,eAAe,QAAQ;CAIlF,MAAM,iBAAiB,MAAM,6BAA6B,kBAAkB,UAAU;CAGtF,MAAM,gBAAgB,OAAO;AAE7B,KAAI,mBAAmB,cACrB;AAGF,KAAI,iBAAiB,cACnB,OAAM,IAAI,MACR,8CAA8C,eAAe,sBAAsB,cAAc,GAClG;AAIH,OADmB,QAAQ,kBAAkB,QAAQ,UAAU,CAC9C,QAAQ,gBAAgB,cAAc"}
1
+ {"version":3,"file":"mod.js","names":["#namespace","#schema","#adapter","internalSchema"],"sources":["../src/mod.ts"],"sourcesContent":["import type { DatabaseAdapter } from \"./adapters/adapters\";\nimport type { AnySchema } from \"./schema/create\";\nimport type { CursorResult } from \"./query/cursor\";\nimport { Cursor } from \"./query/cursor\";\nimport { dbNow, type DbNow } from \"./query/db-now\";\nimport type { FragnoInstantiatedFragment, AnyFragnoInstantiatedFragment } from \"@fragno-dev/core\";\nimport type {\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\nimport {\n getSchemaVersionFromDatabase,\n type InternalFragmentInstance,\n} from \"./fragments/internal-fragment\";\nimport { resolveDatabaseAdapter } from \"./util/default-database-adapter\";\n\nexport type { DatabaseAdapter, CursorResult };\nexport { Cursor };\nexport { dbNow };\nexport type { DbNow };\nexport { InMemoryAdapter, type InMemoryAdapterOptions } from \"./adapters/in-memory\";\nexport { internalSchema } from \"./fragments/internal-fragment\";\n\nexport const fragnoDatabaseFakeSymbol = \"$fragno-database\" as const;\nexport const fragnoDatabaseLibraryVersion = \"0.1\" as const;\n\nexport interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {\n namespace: string | null;\n schema: T;\n}\n\nexport function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema> {\n if (value instanceof FragnoDatabase) {\n return true;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n return (\n fragnoDatabaseFakeSymbol in value &&\n value[fragnoDatabaseFakeSymbol] === fragnoDatabaseFakeSymbol\n );\n}\n\n/**\n * A Fragno database instance with a bound adapter.\n * Created from a FragnoDatabaseDefinition by calling .create(adapter).\n */\nexport class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {\n #namespace: string | null;\n #schema: T;\n #adapter: DatabaseAdapter<TUOWConfig>;\n\n constructor(options: {\n namespace: string | null;\n schema: T;\n adapter: DatabaseAdapter<TUOWConfig>;\n }) {\n this.#namespace = options.namespace;\n this.#schema = options.schema;\n this.#adapter = options.adapter;\n }\n\n get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol {\n return fragnoDatabaseFakeSymbol;\n }\n\n get namespace() {\n return this.#namespace;\n }\n\n get schema() {\n return this.#schema;\n }\n\n get adapter(): DatabaseAdapter<TUOWConfig> {\n return this.#adapter;\n }\n}\n\nexport {\n DatabaseFragmentDefinitionBuilder,\n type FragnoPublicConfigWithDatabase,\n type DatabaseFragmentContext,\n type DatabaseServiceContext,\n type DatabaseHandlerContext as DatabaseRequestContext,\n type ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\n\nexport { withDatabase } from \"./with-database\";\n\nexport { decodeCursor, type CursorData } from \"./query/cursor\";\n\nexport {\n createUnitOfWork,\n UnitOfWork,\n TypedUnitOfWork,\n type IUnitOfWork,\n type IUnitOfWorkRestricted,\n type UOWCompiler,\n type UOWExecutor,\n type UOWDecoder,\n} from \"./query/unit-of-work/unit-of-work\";\n\nexport {\n type RetryPolicy,\n NoRetryPolicy,\n ExponentialBackoffRetryPolicy,\n LinearBackoffRetryPolicy,\n} from \"./query/unit-of-work/retry-policy\";\n\nexport {\n ConcurrencyConflictError,\n // Builder pattern exports\n ServiceTxBuilder,\n HandlerTxBuilder,\n createServiceTxBuilder,\n createHandlerTxBuilder,\n type TxResult,\n // Builder context types\n type ServiceBuilderMutateContext,\n type HandlerBuilderMutateContext,\n type BuilderTransformContextWithMutate,\n type BuilderTransformContextWithoutMutate,\n type ExtractServiceRetrieveResults,\n type ExtractServiceFinalResults,\n} from \"./query/unit-of-work/execute-unit-of-work\";\n\nexport type { BoundServices } from \"@fragno-dev/core\";\n\nexport { internalFragmentDef } from \"./fragments/internal-fragment\";\nexport type { InternalFragmentInstance } from \"./fragments/internal-fragment\";\nexport type {\n OutboxConfig,\n OutboxEntry,\n OutboxPayload,\n OutboxMutation,\n OutboxRefMap,\n} from \"./outbox/outbox\";\n\nexport type {\n HookContext,\n HooksMap,\n HookFn,\n HookPayload,\n TriggerHookOptions,\n DurableHooksProcessingOptions,\n StuckHookProcessingInfo,\n StuckHookProcessingEvent,\n StuckHookProcessingTimeoutMinutes,\n} from \"./hooks/hooks\";\nexport {\n createDurableHooksProcessor,\n type DurableHooksProcessor,\n} from \"./hooks/durable-hooks-processor\";\n\nexport type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> =\n FragnoInstantiatedFragment<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n ImplicitDatabaseDependencies<TSchema>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n FragnoPublicConfigWithDatabase,\n // Ensure the fragment has the internal fragment linked\n { _fragno_internal: InternalFragmentInstance } & Record<string, AnyFragnoInstantiatedFragment>\n >;\n\n/**\n * Helper function to run migrations for a database fragment.\n * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.\n * This function:\n * 1. Ensures the internal settings fragment is migrated first\n * 2. Retrieves the current database version from the internal fragment\n * 3. Runs migration from current version to target version\n *\n * @param fragment - The instantiated fragment to run migrations for\n * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations\n *\n * @example\n * ```typescript\n * const fragment = instantiate(myFragmentDef)\n * .withConfig({})\n * .withRoutes([])\n * .withOptions({ databaseAdapter: myAdapter })\n * .build();\n *\n * await migrate(fragment);\n * ```\n */\nexport async function migrate<TSchema extends AnySchema>(\n fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>,\n): Promise<void> {\n const { options, deps, linkedFragments } = fragment.$internal;\n const adapter = resolveDatabaseAdapter(options, deps.schema);\n\n // Check if adapter supports prepareMigrations\n if (!adapter.prepareMigrations) {\n throw new Error(\n \"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.\",\n );\n }\n\n const schema = deps.schema;\n const namespace = deps.namespace ?? schema.name;\n\n // Step 1: Ensure the internal fragment (settings table) is migrated first\n const internalFragment = linkedFragments._fragno_internal;\n\n if (!internalFragment) {\n throw new Error(\"Internal fragment not found. Please ensure the internal fragment is linked.\");\n }\n\n if (!(await adapter.isConnectionHealthy())) {\n throw new Error(\n \"Database connection is not healthy. Please check your database connection and try again.\",\n );\n }\n\n const internalDeps = internalFragment.$internal.deps;\n const internalSchema = internalDeps.schema;\n // Internal fragment uses databaseNamespace: null (no table suffix).\n // Version tracking uses empty string so the key is \".schema_version\",\n // which matches both the legacy format and how the internal fragment was designed.\n const internalNamespace = internalDeps.namespace ?? \"\";\n\n const internalCurrentVersion = await getSchemaVersionFromDatabase(\n internalFragment,\n internalNamespace,\n );\n\n // Migrate internal fragment if needed\n if (internalCurrentVersion < internalSchema.version) {\n const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);\n await internalMigrations.execute(internalCurrentVersion, internalSchema.version);\n }\n\n // Step 2: Get current database version for this fragment's namespace\n const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);\n\n // Step 3: Run the migration from current version to target version\n const targetVersion = schema.version;\n\n if (currentVersion === targetVersion) {\n return;\n }\n\n if (currentVersion > targetVersion) {\n throw new Error(\n `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,\n );\n }\n\n const migrations = adapter.prepareMigrations(schema, namespace);\n await migrations.execute(currentVersion, targetVersion);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuBA,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAO5C,SAAgB,iBAAiB,OAAoD;AACnF,KAAI,iBAAiB,eACnB,QAAO;AAGT,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;AAGT,QACE,4BAA4B,SAC5B,MAAM,8BAA8B;;;;;;AAQxC,IAAa,iBAAb,MAA0E;CACxE;CACA;CACA;CAEA,YAAY,SAIT;AACD,QAAKA,YAAa,QAAQ;AAC1B,QAAKC,SAAU,QAAQ;AACvB,QAAKC,UAAW,QAAQ;;CAG1B,KAAK,4BAA6D;AAChE,SAAO;;CAGT,IAAI,YAAY;AACd,SAAO,MAAKF;;CAGd,IAAI,SAAS;AACX,SAAO,MAAKC;;CAGd,IAAI,UAAuC;AACzC,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;;AAwHhB,eAAsB,QACpB,UACe;CACf,MAAM,EAAE,SAAS,MAAM,oBAAoB,SAAS;CACpD,MAAM,UAAU,uBAAuB,SAAS,KAAK,OAAO;AAG5D,KAAI,CAAC,QAAQ,kBACX,OAAM,IAAI,MACR,0GACD;CAGH,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK,aAAa,OAAO;CAG3C,MAAM,mBAAmB,gBAAgB;AAEzC,KAAI,CAAC,iBACH,OAAM,IAAI,MAAM,8EAA8E;AAGhG,KAAI,CAAE,MAAM,QAAQ,qBAAqB,CACvC,OAAM,IAAI,MACR,2FACD;CAGH,MAAM,eAAe,iBAAiB,UAAU;CAChD,MAAMC,mBAAiB,aAAa;CAIpC,MAAM,oBAAoB,aAAa,aAAa;CAEpD,MAAM,yBAAyB,MAAM,6BACnC,kBACA,kBACD;AAGD,KAAI,yBAAyBA,iBAAe,QAE1C,OAD2B,QAAQ,kBAAkBA,kBAAgB,kBAAkB,CAC9D,QAAQ,wBAAwBA,iBAAe,QAAQ;CAIlF,MAAM,iBAAiB,MAAM,6BAA6B,kBAAkB,UAAU;CAGtF,MAAM,gBAAgB,OAAO;AAE7B,KAAI,mBAAmB,cACrB;AAGF,KAAI,iBAAiB,cACnB,OAAM,IAAI,MACR,8CAA8C,eAAe,sBAAsB,cAAc,GAClG;AAIH,OADmB,QAAQ,kBAAkB,QAAQ,UAAU,CAC9C,QAAQ,gBAAgB,cAAc"}
@@ -0,0 +1,19 @@
1
+ //#region src/naming/sql-naming.d.ts
2
+ type NamespaceScope = "suffix" | "schema";
3
+ interface SqlNamingStrategy {
4
+ namespaceScope: NamespaceScope;
5
+ namespaceToSchema: (namespace: string) => string;
6
+ tableName: (logicalTable: string, namespace: string | null) => string;
7
+ columnName: (logicalColumn: string, logicalTable: string) => string;
8
+ indexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;
9
+ uniqueIndexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;
10
+ foreignKeyName: (params: {
11
+ logicalTable: string;
12
+ logicalReferencedTable: string;
13
+ referenceName: string;
14
+ namespace: string | null;
15
+ }) => string;
16
+ }
17
+ //#endregion
18
+ export { SqlNamingStrategy };
19
+ //# sourceMappingURL=sql-naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-naming.d.ts","names":[],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":[],"mappings":";AAGY,KAAA,cAAA,GAAc,QAAA,GAAA,QAAA;AAET,UAAA,iBAAA,CAAiB;kBAChB"}
@@ -0,0 +1,116 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ //#region src/naming/sql-naming.ts
4
+ const normalizeNamespace = (namespace) => namespace && namespace.length > 0 ? namespace : null;
5
+ const buildNamespaceSuffix = (namespace) => {
6
+ const sanitized = normalizeNamespace(namespace);
7
+ return sanitized ? `_${sanitized}` : "";
8
+ };
9
+ const MAX_IDENTIFIER_LENGTH = 63;
10
+ const HASH_LENGTH = 8;
11
+ const withHash = (value) => {
12
+ return `${value}_${createHash("sha1").update(value).digest("hex").slice(0, 8)}`;
13
+ };
14
+ const truncateWithHash = (value) => {
15
+ if (value.length <= MAX_IDENTIFIER_LENGTH) return value;
16
+ const hash = createHash("sha1").update(value).digest("hex").slice(0, HASH_LENGTH);
17
+ return `${value.slice(0, MAX_IDENTIFIER_LENGTH - HASH_LENGTH)}${hash}`;
18
+ };
19
+ const buildIndexName = (prefix, logicalIndex, logicalTable, namespace) => {
20
+ return `${prefix}_${withHash(`${logicalTable}_${logicalIndex}${buildNamespaceSuffix(namespace)}`)}`;
21
+ };
22
+ const suffixNamingStrategy = {
23
+ namespaceScope: "suffix",
24
+ namespaceToSchema: (namespace) => namespace,
25
+ tableName: (logicalTable, namespace) => {
26
+ const sanitized = normalizeNamespace(namespace);
27
+ return truncateWithHash(sanitized ? `${logicalTable}_${sanitized}` : logicalTable);
28
+ },
29
+ columnName: (logicalColumn) => logicalColumn,
30
+ indexName: (logicalIndex, logicalTable, namespace) => truncateWithHash(buildIndexName("idx", logicalIndex, logicalTable, namespace)),
31
+ uniqueIndexName: (logicalIndex, logicalTable, namespace) => truncateWithHash(buildIndexName("uidx", logicalIndex, logicalTable, namespace)),
32
+ foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName, namespace }) => {
33
+ return truncateWithHash(`fk_${withHash(`${logicalTable}_${logicalReferencedTable}_${referenceName}${buildNamespaceSuffix(namespace)}`)}`);
34
+ }
35
+ };
36
+ const schemaNamingStrategy = {
37
+ namespaceScope: "schema",
38
+ namespaceToSchema: (namespace) => namespace,
39
+ tableName: (logicalTable) => truncateWithHash(logicalTable),
40
+ columnName: (logicalColumn) => logicalColumn,
41
+ indexName: (logicalIndex) => truncateWithHash(logicalIndex),
42
+ uniqueIndexName: (logicalIndex) => truncateWithHash(logicalIndex),
43
+ foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName }) => truncateWithHash(`fk_${logicalTable}_${logicalReferencedTable}_${referenceName}`)
44
+ };
45
+ var NamingResolver = class {
46
+ #namespace;
47
+ #strategy;
48
+ #tableNameMap = {};
49
+ #columnNameMaps = /* @__PURE__ */ new Map();
50
+ constructor(schema, namespace, strategy) {
51
+ this.#namespace = namespace;
52
+ this.#strategy = strategy;
53
+ for (const table of Object.values(schema.tables)) {
54
+ const physicalTable = this.getTableName(table.name);
55
+ this.#tableNameMap[physicalTable] = table.name;
56
+ const columnMap = {};
57
+ for (const column of Object.values(table.columns)) {
58
+ const physicalColumn = this.getColumnName(table.name, column.name);
59
+ columnMap[physicalColumn] = column.name;
60
+ }
61
+ this.#columnNameMaps.set(table.name, columnMap);
62
+ }
63
+ }
64
+ get namespace() {
65
+ return this.#namespace;
66
+ }
67
+ get strategy() {
68
+ return this.#strategy;
69
+ }
70
+ getSchemaName() {
71
+ if (this.#strategy.namespaceScope !== "schema") return null;
72
+ if (!this.#namespace || this.#namespace.length === 0) return null;
73
+ return this.#strategy.namespaceToSchema(this.#namespace);
74
+ }
75
+ getTableName(logicalTable) {
76
+ return this.#strategy.tableName(logicalTable, this.#namespace);
77
+ }
78
+ getColumnName(logicalTable, logicalColumn) {
79
+ return this.#strategy.columnName(logicalColumn, logicalTable);
80
+ }
81
+ getIndexName(logicalIndex, logicalTable) {
82
+ return this.#strategy.indexName(logicalIndex, logicalTable, this.#namespace);
83
+ }
84
+ getUniqueIndexName(logicalIndex, logicalTable) {
85
+ return this.#strategy.uniqueIndexName(logicalIndex, logicalTable, this.#namespace);
86
+ }
87
+ getForeignKeyName(params) {
88
+ return this.#strategy.foreignKeyName({
89
+ ...params,
90
+ namespace: this.#namespace
91
+ });
92
+ }
93
+ getTableNameMap() {
94
+ return { ...this.#tableNameMap };
95
+ }
96
+ getColumnNameMap(table) {
97
+ const tableName = typeof table === "string" ? table : table.name;
98
+ const map = this.#columnNameMaps.get(tableName);
99
+ return map ? { ...map } : {};
100
+ }
101
+ };
102
+ const createNamingResolver = (schema, namespace, strategy) => new NamingResolver(schema, namespace, strategy);
103
+ /**
104
+ * Sanitizes a namespace for use in SQL identifiers and TypeScript exports.
105
+ * Converts dashes to underscores to ensure compatibility with SQL identifiers.
106
+ *
107
+ * @example
108
+ * sanitizeNamespace("my-fragment") // => "my_fragment"
109
+ */
110
+ function sanitizeNamespace(namespace) {
111
+ return namespace.replace(/-/g, "_");
112
+ }
113
+
114
+ //#endregion
115
+ export { createNamingResolver, sanitizeNamespace, schemaNamingStrategy, suffixNamingStrategy };
116
+ //# sourceMappingURL=sql-naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-naming.js","names":["suffixNamingStrategy: SqlNamingStrategy","schemaNamingStrategy: SqlNamingStrategy","#namespace","#strategy","#tableNameMap","#columnNameMaps","columnMap: Record<string, string>"],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { AnySchema, AnyTable } from \"../schema/create\";\n\nexport type NamespaceScope = \"suffix\" | \"schema\";\n\nexport interface SqlNamingStrategy {\n namespaceScope: NamespaceScope;\n namespaceToSchema: (namespace: string) => string;\n\n tableName: (logicalTable: string, namespace: string | null) => string;\n columnName: (logicalColumn: string, logicalTable: string) => string;\n\n indexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n uniqueIndexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n foreignKeyName: (params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n namespace: string | null;\n }) => string;\n}\n\nconst normalizeNamespace = (namespace: string | null) =>\n namespace && namespace.length > 0 ? namespace : null;\n\nconst buildNamespaceSuffix = (namespace: string | null) => {\n const sanitized = normalizeNamespace(namespace);\n return sanitized ? `_${sanitized}` : \"\";\n};\n\nconst MAX_IDENTIFIER_LENGTH = 63;\nconst HASH_LENGTH = 8;\n\nconst withHash = (value: string) => {\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, 8);\n return `${value}_${hash}`;\n};\n\nconst truncateWithHash = (value: string) => {\n if (value.length <= MAX_IDENTIFIER_LENGTH) {\n return value;\n }\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, HASH_LENGTH);\n return `${value.slice(0, MAX_IDENTIFIER_LENGTH - HASH_LENGTH)}${hash}`;\n};\n\nconst buildIndexName = (\n prefix: \"idx\" | \"uidx\",\n logicalIndex: string,\n logicalTable: string,\n namespace: string | null,\n) => {\n const base = `${logicalTable}_${logicalIndex}${buildNamespaceSuffix(namespace)}`;\n return `${prefix}_${withHash(base)}`;\n};\n\nexport const suffixNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"suffix\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable, namespace) => {\n const sanitized = normalizeNamespace(namespace);\n return truncateWithHash(sanitized ? `${logicalTable}_${sanitized}` : logicalTable);\n },\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"idx\", logicalIndex, logicalTable, namespace)),\n uniqueIndexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"uidx\", logicalIndex, logicalTable, namespace)),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName, namespace }) => {\n const base = `${logicalTable}_${logicalReferencedTable}_${referenceName}${buildNamespaceSuffix(namespace)}`;\n return truncateWithHash(`fk_${withHash(base)}`);\n },\n};\n\nexport const schemaNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"schema\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable) => truncateWithHash(logicalTable),\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex) => truncateWithHash(logicalIndex),\n uniqueIndexName: (logicalIndex) => truncateWithHash(logicalIndex),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName }) =>\n truncateWithHash(`fk_${logicalTable}_${logicalReferencedTable}_${referenceName}`),\n};\n\nexport class NamingResolver {\n readonly #namespace: string | null;\n readonly #strategy: SqlNamingStrategy;\n readonly #tableNameMap: Record<string, string> = {};\n readonly #columnNameMaps = new Map<string, Record<string, string>>();\n\n constructor(schema: AnySchema, namespace: string | null, strategy: SqlNamingStrategy) {\n this.#namespace = namespace;\n this.#strategy = strategy;\n\n for (const table of Object.values(schema.tables)) {\n const physicalTable = this.getTableName(table.name);\n this.#tableNameMap[physicalTable] = table.name;\n\n const columnMap: Record<string, string> = {};\n for (const column of Object.values(table.columns)) {\n const physicalColumn = this.getColumnName(table.name, column.name);\n columnMap[physicalColumn] = column.name;\n }\n this.#columnNameMaps.set(table.name, columnMap);\n }\n }\n\n get namespace(): string | null {\n return this.#namespace;\n }\n\n get strategy(): SqlNamingStrategy {\n return this.#strategy;\n }\n\n getSchemaName(): string | null {\n if (this.#strategy.namespaceScope !== \"schema\") {\n return null;\n }\n if (!this.#namespace || this.#namespace.length === 0) {\n return null;\n }\n return this.#strategy.namespaceToSchema(this.#namespace);\n }\n\n getTableName(logicalTable: string): string {\n return this.#strategy.tableName(logicalTable, this.#namespace);\n }\n\n getColumnName(logicalTable: string, logicalColumn: string): string {\n return this.#strategy.columnName(logicalColumn, logicalTable);\n }\n\n getIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.indexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getUniqueIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.uniqueIndexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getForeignKeyName(params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n }): string {\n return this.#strategy.foreignKeyName({\n ...params,\n namespace: this.#namespace,\n });\n }\n\n getTableNameMap(): Record<string, string> {\n return { ...this.#tableNameMap };\n }\n\n getColumnNameMap(table: AnyTable | string): Record<string, string> {\n const tableName = typeof table === \"string\" ? table : table.name;\n const map = this.#columnNameMaps.get(tableName);\n return map ? { ...map } : {};\n }\n}\n\nexport const createNamingResolver = (\n schema: AnySchema,\n namespace: string | null,\n strategy: SqlNamingStrategy,\n): NamingResolver => new NamingResolver(schema, namespace, strategy);\n\n/**\n * Sanitizes a namespace for use in SQL identifiers and TypeScript exports.\n * Converts dashes to underscores to ensure compatibility with SQL identifiers.\n *\n * @example\n * sanitizeNamespace(\"my-fragment\") // => \"my_fragment\"\n */\nexport function sanitizeNamespace(namespace: string): string {\n return namespace.replace(/-/g, \"_\");\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- //#region ../../node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.mjs
1
+ //#region ../../node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.mjs
2
2
  const NullProtoObj = /* @__PURE__ */ (() => {
3
3
  const e = function() {};
4
4
  return e.prototype = Object.create(null), Object.freeze(e.prototype), e;
@@ -19,7 +19,7 @@ function splitPath(path) {
19
19
  function getMatchParams(segments, paramsMap) {
20
20
  const params = new NullProtoObj();
21
21
  for (const [index, name] of paramsMap) {
22
- const segment = index < 0 ? segments.slice(-1 * index).join("/") : segments[index];
22
+ const segment = index < 0 ? segments.slice(-(index + 1)).join("/") : segments[index];
23
23
  if (typeof name === "string") params[name] = segment;
24
24
  else {
25
25
  const match = segment.match(name);
@@ -34,18 +34,19 @@ function getMatchParams(segments, paramsMap) {
34
34
  function addRoute(ctx, method = "", path, data) {
35
35
  method = method.toUpperCase();
36
36
  if (path.charCodeAt(0) !== 47) path = `/${path}`;
37
+ path = path.replace(/\\:/g, "%3A");
37
38
  const segments = splitPath(path);
38
39
  let node = ctx.root;
39
40
  let _unnamedParamIndex = 0;
40
41
  const paramsMap = [];
41
42
  const paramsRegexp = [];
42
43
  for (let i = 0; i < segments.length; i++) {
43
- const segment = segments[i];
44
+ let segment = segments[i];
44
45
  if (segment.startsWith("**")) {
45
46
  if (!node.wildcard) node.wildcard = { key: "**" };
46
47
  node = node.wildcard;
47
48
  paramsMap.push([
48
- -i,
49
+ -(i + 1),
49
50
  segment.split(":")[1] || "_",
50
51
  segment.length === 2
51
52
  ]);
@@ -75,6 +76,8 @@ function addRoute(ctx, method = "", path, data) {
75
76
  ]);
76
77
  continue;
77
78
  }
79
+ if (segment === "\\*") segment = segments[i] = "*";
80
+ else if (segment === "\\*\\*") segment = segments[i] = "**";
78
81
  const child = node.static?.[segment];
79
82
  if (child) node = child;
80
83
  else {
@@ -92,7 +95,7 @@ function addRoute(ctx, method = "", path, data) {
92
95
  paramsRegexp,
93
96
  paramsMap: hasParams ? paramsMap : void 0
94
97
  });
95
- if (!hasParams) ctx.static[path] = node;
98
+ if (!hasParams) ctx.static["/" + segments.join("/")] = node;
96
99
  }
97
100
  function getParamRegexp(segment) {
98
101
  const regex = segment.replace(/:(\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\./g, "\\.");
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../../../../../node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.mjs"],"sourcesContent":["const NullProtoObj = /* @__PURE__ */ (() => {\n\tconst e = function() {};\n\treturn e.prototype = Object.create(null), Object.freeze(e.prototype), e;\n})();\n\n/**\n* Create a new router context.\n*/\nfunction createRouter() {\n\treturn {\n\t\troot: { key: \"\" },\n\t\tstatic: new NullProtoObj()\n\t};\n}\n\nfunction splitPath(path) {\n\tconst [_, ...s] = path.split(\"/\");\n\treturn s[s.length - 1] === \"\" ? s.slice(0, -1) : s;\n}\nfunction getMatchParams(segments, paramsMap) {\n\tconst params = new NullProtoObj();\n\tfor (const [index, name] of paramsMap) {\n\t\tconst segment = index < 0 ? segments.slice(-(index + 1)).join(\"/\") : segments[index];\n\t\tif (typeof name === \"string\") params[name] = segment;\n\t\telse {\n\t\t\tconst match = segment.match(name);\n\t\t\tif (match) for (const key in match.groups) params[key] = match.groups[key];\n\t\t}\n\t}\n\treturn params;\n}\n\n/**\n* Add a route to the router context.\n*/\nfunction addRoute(ctx, method = \"\", path, data) {\n\tmethod = method.toUpperCase();\n\tif (path.charCodeAt(0) !== 47) path = `/${path}`;\n\tpath = path.replace(/\\\\:/g, \"%3A\");\n\tconst segments = splitPath(path);\n\tlet node = ctx.root;\n\tlet _unnamedParamIndex = 0;\n\tconst paramsMap = [];\n\tconst paramsRegexp = [];\n\tfor (let i = 0; i < segments.length; i++) {\n\t\tlet segment = segments[i];\n\t\tif (segment.startsWith(\"**\")) {\n\t\t\tif (!node.wildcard) node.wildcard = { key: \"**\" };\n\t\t\tnode = node.wildcard;\n\t\t\tparamsMap.push([\n\t\t\t\t-(i + 1),\n\t\t\t\tsegment.split(\":\")[1] || \"_\",\n\t\t\t\tsegment.length === 2\n\t\t\t]);\n\t\t\tbreak;\n\t\t}\n\t\tif (segment === \"*\" || segment.includes(\":\")) {\n\t\t\tif (!node.param) node.param = { key: \"*\" };\n\t\t\tnode = node.param;\n\t\t\tif (segment === \"*\") paramsMap.push([\n\t\t\t\ti,\n\t\t\t\t`_${_unnamedParamIndex++}`,\n\t\t\t\ttrue\n\t\t\t]);\n\t\t\telse if (segment.includes(\":\", 1)) {\n\t\t\t\tconst regexp = getParamRegexp(segment);\n\t\t\t\tparamsRegexp[i] = regexp;\n\t\t\t\tnode.hasRegexParam = true;\n\t\t\t\tparamsMap.push([\n\t\t\t\t\ti,\n\t\t\t\t\tregexp,\n\t\t\t\t\tfalse\n\t\t\t\t]);\n\t\t\t} else paramsMap.push([\n\t\t\t\ti,\n\t\t\t\tsegment.slice(1),\n\t\t\t\tfalse\n\t\t\t]);\n\t\t\tcontinue;\n\t\t}\n\t\tif (segment === \"\\\\*\") segment = segments[i] = \"*\";\n\t\telse if (segment === \"\\\\*\\\\*\") segment = segments[i] = \"**\";\n\t\tconst child = node.static?.[segment];\n\t\tif (child) node = child;\n\t\telse {\n\t\t\tconst staticNode = { key: segment };\n\t\t\tif (!node.static) node.static = new NullProtoObj();\n\t\t\tnode.static[segment] = staticNode;\n\t\t\tnode = staticNode;\n\t\t}\n\t}\n\tconst hasParams = paramsMap.length > 0;\n\tif (!node.methods) node.methods = new NullProtoObj();\n\tnode.methods[method] ??= [];\n\tnode.methods[method].push({\n\t\tdata: data || null,\n\t\tparamsRegexp,\n\t\tparamsMap: hasParams ? paramsMap : void 0\n\t});\n\tif (!hasParams) ctx.static[\"/\" + segments.join(\"/\")] = node;\n}\nfunction getParamRegexp(segment) {\n\tconst regex = segment.replace(/:(\\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\\./g, \"\\\\.\");\n\treturn /* @__PURE__ */ new RegExp(`^${regex}$`);\n}\n\n/**\n* Find a route by path.\n*/\nfunction findRoute(ctx, method = \"\", path, opts) {\n\tif (path.charCodeAt(path.length - 1) === 47) path = path.slice(0, -1);\n\tconst staticNode = ctx.static[path];\n\tif (staticNode && staticNode.methods) {\n\t\tconst staticMatch = staticNode.methods[method] || staticNode.methods[\"\"];\n\t\tif (staticMatch !== void 0) return staticMatch[0];\n\t}\n\tconst segments = splitPath(path);\n\tconst match = _lookupTree(ctx, ctx.root, method, segments, 0)?.[0];\n\tif (match === void 0) return;\n\tif (opts?.params === false) return match;\n\treturn {\n\t\tdata: match.data,\n\t\tparams: match.paramsMap ? getMatchParams(segments, match.paramsMap) : void 0\n\t};\n}\nfunction _lookupTree(ctx, node, method, segments, index) {\n\tif (index === segments.length) {\n\t\tif (node.methods) {\n\t\t\tconst match = node.methods[method] || node.methods[\"\"];\n\t\t\tif (match) return match;\n\t\t}\n\t\tif (node.param && node.param.methods) {\n\t\t\tconst match = node.param.methods[method] || node.param.methods[\"\"];\n\t\t\tif (match) {\n\t\t\t\tconst pMap = match[0].paramsMap;\n\t\t\t\tif (pMap?.[pMap?.length - 1]?.[2]) return match;\n\t\t\t}\n\t\t}\n\t\tif (node.wildcard && node.wildcard.methods) {\n\t\t\tconst match = node.wildcard.methods[method] || node.wildcard.methods[\"\"];\n\t\t\tif (match) {\n\t\t\t\tconst pMap = match[0].paramsMap;\n\t\t\t\tif (pMap?.[pMap?.length - 1]?.[2]) return match;\n\t\t\t}\n\t\t}\n\t\treturn;\n\t}\n\tconst segment = segments[index];\n\tif (node.static) {\n\t\tconst staticChild = node.static[segment];\n\t\tif (staticChild) {\n\t\t\tconst match = _lookupTree(ctx, staticChild, method, segments, index + 1);\n\t\t\tif (match) return match;\n\t\t}\n\t}\n\tif (node.param) {\n\t\tconst match = _lookupTree(ctx, node.param, method, segments, index + 1);\n\t\tif (match) {\n\t\t\tif (node.param.hasRegexParam) {\n\t\t\t\tconst exactMatch = match.find((m) => m.paramsRegexp[index]?.test(segment)) || match.find((m) => !m.paramsRegexp[index]);\n\t\t\t\treturn exactMatch ? [exactMatch] : void 0;\n\t\t\t}\n\t\t\treturn match;\n\t\t}\n\t}\n\tif (node.wildcard && node.wildcard.methods) return node.wildcard.methods[method] || node.wildcard.methods[\"\"];\n}\n\n/**\n* Remove a route from the router context.\n*/\nfunction removeRoute(ctx, method, path) {\n\tconst segments = splitPath(path);\n\treturn _remove(ctx.root, method || \"\", segments, 0);\n}\nfunction _remove(node, method, segments, index) {\n\tif (index === segments.length) {\n\t\tif (node.methods && method in node.methods) {\n\t\t\tdelete node.methods[method];\n\t\t\tif (Object.keys(node.methods).length === 0) node.methods = void 0;\n\t\t}\n\t\treturn;\n\t}\n\tconst segment = segments[index];\n\tif (segment === \"*\") {\n\t\tif (node.param) {\n\t\t\t_remove(node.param, method, segments, index + 1);\n\t\t\tif (_isEmptyNode(node.param)) node.param = void 0;\n\t\t}\n\t\treturn;\n\t}\n\tif (segment.startsWith(\"**\")) {\n\t\tif (node.wildcard) {\n\t\t\t_remove(node.wildcard, method, segments, index + 1);\n\t\t\tif (_isEmptyNode(node.wildcard)) node.wildcard = void 0;\n\t\t}\n\t\treturn;\n\t}\n\tconst childNode = node.static?.[segment];\n\tif (childNode) {\n\t\t_remove(childNode, method, segments, index + 1);\n\t\tif (_isEmptyNode(childNode)) {\n\t\t\tdelete node.static[segment];\n\t\t\tif (Object.keys(node.static).length === 0) node.static = void 0;\n\t\t}\n\t}\n}\nfunction _isEmptyNode(node) {\n\treturn node.methods === void 0 && node.static === void 0 && node.param === void 0 && node.wildcard === void 0;\n}\n\n/**\n* Find all route patterns that match the given path.\n*/\nfunction findAllRoutes(ctx, method = \"\", path, opts) {\n\tif (path.charCodeAt(path.length - 1) === 47) path = path.slice(0, -1);\n\tconst segments = splitPath(path);\n\tconst matches = _findAll(ctx, ctx.root, method, segments, 0);\n\tif (opts?.params === false) return matches;\n\treturn matches.map((m) => {\n\t\treturn {\n\t\t\tdata: m.data,\n\t\t\tparams: m.paramsMap ? getMatchParams(segments, m.paramsMap) : void 0\n\t\t};\n\t});\n}\nfunction _findAll(ctx, node, method, segments, index, matches = []) {\n\tconst segment = segments[index];\n\tif (node.wildcard && node.wildcard.methods) {\n\t\tconst match = node.wildcard.methods[method] || node.wildcard.methods[\"\"];\n\t\tif (match) matches.push(...match);\n\t}\n\tif (node.param) {\n\t\t_findAll(ctx, node.param, method, segments, index + 1, matches);\n\t\tif (index === segments.length && node.param.methods) {\n\t\t\tconst match = node.param.methods[method] || node.param.methods[\"\"];\n\t\t\tif (match) {\n\t\t\t\tconst pMap = match[0].paramsMap;\n\t\t\t\tif (pMap?.[pMap?.length - 1]?.[2]) matches.push(...match);\n\t\t\t}\n\t\t}\n\t}\n\tconst staticChild = node.static?.[segment];\n\tif (staticChild) _findAll(ctx, staticChild, method, segments, index + 1, matches);\n\tif (index === segments.length && node.methods) {\n\t\tconst match = node.methods[method] || node.methods[\"\"];\n\t\tif (match) matches.push(...match);\n\t}\n\treturn matches;\n}\n\nfunction routeToRegExp(route = \"/\") {\n\tconst reSegments = [];\n\tlet idCtr = 0;\n\tfor (const segment of route.split(\"/\")) {\n\t\tif (!segment) continue;\n\t\tif (segment === \"*\") reSegments.push(`(?<_${idCtr++}>[^/]*)`);\n\t\telse if (segment.startsWith(\"**\")) reSegments.push(segment === \"**\" ? \"?(?<_>.*)\" : `?(?<${segment.slice(3)}>.+)`);\n\t\telse if (segment.includes(\":\")) reSegments.push(segment.replace(/:(\\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\\./g, \"\\\\.\"));\n\t\telse reSegments.push(segment);\n\t}\n\treturn /* @__PURE__ */ new RegExp(`^/${reSegments.join(\"/\")}/?$`);\n}\n\nexport { NullProtoObj, addRoute, createRouter, findAllRoutes, findRoute, removeRoute, routeToRegExp };"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import { FragnoId, FragnoReference } from "../schema/create.js";
2
+ import { internalSchema } from "../fragments/internal-fragment.schema.js";
3
+ import { encodeVersionstamp, versionstampToHex } from "./outbox.js";
4
+
5
+ //#region src/outbox/outbox-builder.ts
6
+ const INTERNAL_TABLE_NAMES = new Set(Object.keys(internalSchema.tables));
7
+ function buildOutboxPlan(operations) {
8
+ const drafts = [];
9
+ const lookups = [];
10
+ for (const op of operations) {
11
+ if (op.type === "check") continue;
12
+ if (isInternalMutation(op)) continue;
13
+ const table = getTable(op.schema, op.table);
14
+ const schemaName = op.namespace ?? "";
15
+ const namespace = op.namespace ? op.namespace : void 0;
16
+ const mutationIndex = drafts.length;
17
+ if (op.type === "create") {
18
+ drafts.push({
19
+ op: "create",
20
+ schema: schemaName,
21
+ namespace,
22
+ table: op.table,
23
+ externalId: op.generatedExternalId,
24
+ values: encodeOutboxValues({
25
+ table,
26
+ values: op.values,
27
+ mutationIndex,
28
+ namespace,
29
+ lookups
30
+ })
31
+ });
32
+ continue;
33
+ }
34
+ if (op.type === "update") {
35
+ drafts.push({
36
+ op: "update",
37
+ schema: schemaName,
38
+ namespace,
39
+ table: op.table,
40
+ externalId: getExternalId(op.id),
41
+ set: encodeOutboxValues({
42
+ table,
43
+ values: op.set,
44
+ mutationIndex,
45
+ namespace,
46
+ lookups
47
+ }),
48
+ checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : void 0
49
+ });
50
+ continue;
51
+ }
52
+ if (op.type === "delete") drafts.push({
53
+ op: "delete",
54
+ schema: schemaName,
55
+ namespace,
56
+ table: op.table,
57
+ externalId: getExternalId(op.id),
58
+ checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : void 0
59
+ });
60
+ }
61
+ return {
62
+ drafts,
63
+ lookups
64
+ };
65
+ }
66
+ function finalizeOutboxPayload(plan, transactionVersion) {
67
+ return {
68
+ version: 1,
69
+ mutations: plan.drafts.map((draft, index) => {
70
+ const versionstamp = versionstampToHex(encodeVersionstamp(transactionVersion, index));
71
+ return {
72
+ ...draft,
73
+ versionstamp
74
+ };
75
+ })
76
+ };
77
+ }
78
+ function encodeOutboxValues(options) {
79
+ const { table, values, mutationIndex, namespace, lookups } = options;
80
+ const output = {};
81
+ for (const [key, value] of Object.entries(values)) {
82
+ if (value === void 0) continue;
83
+ if (table.columns[key]?.role === "reference") {
84
+ output[key] = resolveReferenceValue({
85
+ value,
86
+ mutationIndex,
87
+ columnName: key,
88
+ table,
89
+ namespace,
90
+ lookups
91
+ });
92
+ continue;
93
+ }
94
+ if (value instanceof FragnoId) {
95
+ output[key] = value.externalId;
96
+ continue;
97
+ }
98
+ output[key] = value;
99
+ }
100
+ return output;
101
+ }
102
+ function resolveReferenceValue(options) {
103
+ const { value, mutationIndex, columnName, table, namespace, lookups } = options;
104
+ if (value === null) return null;
105
+ if (value instanceof FragnoId) return value.externalId;
106
+ if (typeof value === "string") return value;
107
+ if (value instanceof FragnoReference) return createReferencePlaceholder({
108
+ internalId: value.internalId,
109
+ mutationIndex,
110
+ columnName,
111
+ table,
112
+ namespace,
113
+ lookups
114
+ });
115
+ if (typeof value === "bigint" || typeof value === "number") return createReferencePlaceholder({
116
+ internalId: value,
117
+ mutationIndex,
118
+ columnName,
119
+ table,
120
+ namespace,
121
+ lookups
122
+ });
123
+ return value;
124
+ }
125
+ function createReferencePlaceholder(options) {
126
+ const { internalId, mutationIndex, columnName, table, namespace, lookups } = options;
127
+ const key = `${mutationIndex}.${columnName}`;
128
+ const referencedTable = resolveReferencedTable(table, columnName);
129
+ lookups.push({
130
+ key,
131
+ internalId,
132
+ table: referencedTable,
133
+ namespace
134
+ });
135
+ return { __fragno_ref: key };
136
+ }
137
+ function resolveReferencedTable(table, columnName) {
138
+ for (const relation of Object.values(table.relations)) if (relation.on.some(([localColumn]) => localColumn === columnName)) return relation.table;
139
+ throw new Error(`Reference column ${columnName} not found in table ${table.name}`);
140
+ }
141
+ function getExternalId(id) {
142
+ return typeof id === "string" ? id : id.externalId;
143
+ }
144
+ function isInternalMutation(op) {
145
+ if (op.schema === internalSchema) return true;
146
+ return op.namespace === "" && INTERNAL_TABLE_NAMES.has(op.table);
147
+ }
148
+ function getTable(schema, tableName) {
149
+ const table = schema.tables[tableName];
150
+ if (!table) throw new Error(`Invalid table name ${tableName}.`);
151
+ return table;
152
+ }
153
+
154
+ //#endregion
155
+ export { buildOutboxPlan, finalizeOutboxPayload };
156
+ //# sourceMappingURL=outbox-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-builder.js","names":["drafts: OutboxMutationDraft[]","lookups: OutboxRefLookup[]","output: Record<string, unknown>"],"sources":["../../src/outbox/outbox-builder.ts"],"sourcesContent":["import type { MutationOperation } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable } from \"../schema/create\";\nimport { FragnoId, FragnoReference } from \"../schema/create\";\nimport { internalSchema } from \"../fragments/internal-fragment.schema\";\nimport type { OutboxRefLookup, OutboxPayload, OutboxMutation } from \"./outbox\";\nimport { encodeVersionstamp, versionstampToHex } from \"./outbox\";\n\nconst INTERNAL_TABLE_NAMES = new Set(Object.keys(internalSchema.tables));\n\ntype OutboxMutationDraft = OutboxMutation extends infer T\n ? T extends OutboxMutation\n ? Omit<T, \"versionstamp\"> & { versionstamp?: string }\n : never\n : never;\n\nexport type OutboxPlan = {\n drafts: OutboxMutationDraft[];\n lookups: OutboxRefLookup[];\n};\n\nexport function buildOutboxPlan(operations: MutationOperation<AnySchema>[]): OutboxPlan {\n const drafts: OutboxMutationDraft[] = [];\n const lookups: OutboxRefLookup[] = [];\n\n for (const op of operations) {\n if (op.type === \"check\") {\n continue;\n }\n\n if (isInternalMutation(op)) {\n continue;\n }\n\n const table = getTable(op.schema, op.table);\n const schemaName = op.namespace ?? \"\";\n const namespace = op.namespace ? op.namespace : undefined;\n const mutationIndex = drafts.length;\n\n if (op.type === \"create\") {\n drafts.push({\n op: \"create\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: op.generatedExternalId,\n values: encodeOutboxValues({\n table,\n values: op.values,\n mutationIndex,\n namespace,\n lookups,\n }),\n });\n continue;\n }\n\n if (op.type === \"update\") {\n drafts.push({\n op: \"update\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n set: encodeOutboxValues({\n table,\n values: op.set,\n mutationIndex,\n namespace,\n lookups,\n }),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n continue;\n }\n\n if (op.type === \"delete\") {\n drafts.push({\n op: \"delete\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n }\n }\n\n return { drafts, lookups };\n}\n\nexport function finalizeOutboxPayload(plan: OutboxPlan, transactionVersion: bigint): OutboxPayload {\n const mutations: OutboxMutation[] = plan.drafts.map((draft, index) => {\n const versionstamp = versionstampToHex(encodeVersionstamp(transactionVersion, index));\n return { ...draft, versionstamp } as OutboxMutation;\n });\n\n return {\n version: 1,\n mutations,\n };\n}\n\nfunction encodeOutboxValues(options: {\n table: AnyTable;\n values: Record<string, unknown>;\n mutationIndex: number;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): Record<string, unknown> {\n const { table, values, mutationIndex, namespace, lookups } = options;\n const output: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) {\n continue;\n }\n\n const column = table.columns[key];\n\n if (column?.role === \"reference\") {\n const resolved = resolveReferenceValue({\n value,\n mutationIndex,\n columnName: key,\n table,\n namespace,\n lookups,\n });\n output[key] = resolved;\n continue;\n }\n\n if (value instanceof FragnoId) {\n output[key] = value.externalId;\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n\nfunction resolveReferenceValue(options: {\n value: unknown;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): unknown {\n const { value, mutationIndex, columnName, table, namespace, lookups } = options;\n\n if (value === null) {\n return null;\n }\n\n if (value instanceof FragnoId) {\n return value.externalId;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value instanceof FragnoReference) {\n return createReferencePlaceholder({\n internalId: value.internalId,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n if (typeof value === \"bigint\" || typeof value === \"number\") {\n return createReferencePlaceholder({\n internalId: value,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n return value;\n}\n\nfunction createReferencePlaceholder(options: {\n internalId: bigint | number;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): { __fragno_ref: string } {\n const { internalId, mutationIndex, columnName, table, namespace, lookups } = options;\n const key = `${mutationIndex}.${columnName}`;\n const referencedTable = resolveReferencedTable(table, columnName);\n\n lookups.push({\n key,\n internalId,\n table: referencedTable,\n namespace,\n });\n\n return { __fragno_ref: key };\n}\n\nfunction resolveReferencedTable(table: AnyTable, columnName: string): AnyTable {\n for (const relation of Object.values(table.relations)) {\n if (relation.on.some(([localColumn]) => localColumn === columnName)) {\n return relation.table;\n }\n }\n\n throw new Error(`Reference column ${columnName} not found in table ${table.name}`);\n}\n\nfunction getExternalId(id: FragnoId | string): string {\n return typeof id === \"string\" ? id : id.externalId;\n}\n\nfunction isInternalMutation(op: MutationOperation<AnySchema>): boolean {\n if (op.schema === internalSchema) {\n return true;\n }\n\n return op.namespace === \"\" && INTERNAL_TABLE_NAMES.has(op.table);\n}\n\nfunction getTable(schema: AnySchema, tableName: string): AnyTable {\n const table = schema.tables[tableName];\n if (!table) {\n throw new Error(`Invalid table name ${tableName}.`);\n }\n return table;\n}\n"],"mappings":"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"}