@warlock.js/cascade 5.29.0 → 5.31.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 (392) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -5
  3. package/cjs/index.cjs +101 -102
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/context/database-data-source-context.d.mts +1 -1
  6. package/esm/context/database-data-source-context.d.mts.map +1 -1
  7. package/esm/context/database-data-source-context.mjs +1 -1
  8. package/esm/context/database-data-source-context.mjs.map +1 -1
  9. package/esm/context/database-transaction-context.d.mts +1 -1
  10. package/esm/context/database-transaction-context.d.mts.map +1 -1
  11. package/esm/context/database-transaction-context.mjs +1 -1
  12. package/esm/context/database-transaction-context.mjs.map +1 -1
  13. package/esm/contracts/database-driver.contract.d.mts +1 -1
  14. package/esm/contracts/database-driver.contract.d.mts.map +1 -1
  15. package/esm/contracts/database-id-generator.contract.d.mts +1 -1
  16. package/esm/contracts/database-id-generator.contract.d.mts.map +1 -1
  17. package/esm/contracts/database-remover.contract.d.mts +1 -1
  18. package/esm/contracts/database-remover.contract.d.mts.map +1 -1
  19. package/esm/contracts/database-restorer.contract.d.mts +1 -1
  20. package/esm/contracts/database-restorer.contract.d.mts.map +1 -1
  21. package/esm/contracts/database-writer.contract.d.mts +1 -1
  22. package/esm/contracts/database-writer.contract.d.mts.map +1 -1
  23. package/esm/contracts/driver-blueprint.contract.d.mts +1 -1
  24. package/esm/contracts/driver-blueprint.contract.d.mts.map +1 -1
  25. package/esm/contracts/migration-driver.contract.d.mts +1 -1
  26. package/esm/contracts/migration-driver.contract.d.mts.map +1 -1
  27. package/esm/contracts/query-builder.contract.d.mts +1 -1
  28. package/esm/contracts/query-builder.contract.d.mts.map +1 -1
  29. package/esm/contracts/sync-adapter.contract.d.mts +1 -1
  30. package/esm/contracts/sync-adapter.contract.d.mts.map +1 -1
  31. package/esm/data-source/data-source-registry.d.mts +1 -1
  32. package/esm/data-source/data-source-registry.d.mts.map +1 -1
  33. package/esm/data-source/data-source-registry.mjs +1 -1
  34. package/esm/data-source/data-source-registry.mjs.map +1 -1
  35. package/esm/data-source/data-source.d.mts +1 -1
  36. package/esm/data-source/data-source.d.mts.map +1 -1
  37. package/esm/data-source/data-source.mjs +1 -1
  38. package/esm/data-source/data-source.mjs.map +1 -1
  39. package/esm/database-dirty-tracker.d.mts +1 -1
  40. package/esm/database-dirty-tracker.d.mts.map +1 -1
  41. package/esm/database-dirty-tracker.mjs +1 -1
  42. package/esm/database-dirty-tracker.mjs.map +1 -1
  43. package/esm/drivers/mongodb/mongodb-blueprint.mjs +1 -1
  44. package/esm/drivers/mongodb/mongodb-blueprint.mjs.map +1 -1
  45. package/esm/drivers/mongodb/mongodb-driver.d.mts +1 -1
  46. package/esm/drivers/mongodb/mongodb-driver.d.mts.map +1 -1
  47. package/esm/drivers/mongodb/mongodb-driver.mjs +1 -1
  48. package/esm/drivers/mongodb/mongodb-driver.mjs.map +1 -1
  49. package/esm/drivers/mongodb/mongodb-id-generator.d.mts +1 -1
  50. package/esm/drivers/mongodb/mongodb-id-generator.d.mts.map +1 -1
  51. package/esm/drivers/mongodb/mongodb-id-generator.mjs +1 -1
  52. package/esm/drivers/mongodb/mongodb-id-generator.mjs.map +1 -1
  53. package/esm/drivers/mongodb/mongodb-migration-driver.d.mts +1 -1
  54. package/esm/drivers/mongodb/mongodb-migration-driver.d.mts.map +1 -1
  55. package/esm/drivers/mongodb/mongodb-migration-driver.mjs +1 -1
  56. package/esm/drivers/mongodb/mongodb-migration-driver.mjs.map +1 -1
  57. package/esm/drivers/mongodb/mongodb-query-builder.d.mts +1 -1
  58. package/esm/drivers/mongodb/mongodb-query-builder.d.mts.map +1 -1
  59. package/esm/drivers/mongodb/mongodb-query-builder.mjs +1 -1
  60. package/esm/drivers/mongodb/mongodb-query-builder.mjs.map +1 -1
  61. package/esm/drivers/mongodb/mongodb-query-operations.d.mts +1 -1
  62. package/esm/drivers/mongodb/mongodb-query-operations.d.mts.map +1 -1
  63. package/esm/drivers/mongodb/mongodb-query-operations.mjs +1 -1
  64. package/esm/drivers/mongodb/mongodb-query-operations.mjs.map +1 -1
  65. package/esm/drivers/mongodb/mongodb-query-parser.d.mts +1 -1
  66. package/esm/drivers/mongodb/mongodb-query-parser.d.mts.map +1 -1
  67. package/esm/drivers/mongodb/mongodb-query-parser.mjs +1 -1
  68. package/esm/drivers/mongodb/mongodb-query-parser.mjs.map +1 -1
  69. package/esm/drivers/mongodb/mongodb-sync-adapter.d.mts +1 -1
  70. package/esm/drivers/mongodb/mongodb-sync-adapter.d.mts.map +1 -1
  71. package/esm/drivers/mongodb/mongodb-sync-adapter.mjs +1 -1
  72. package/esm/drivers/mongodb/mongodb-sync-adapter.mjs.map +1 -1
  73. package/esm/drivers/mongodb/mongodb-update-translator.mjs +1 -1
  74. package/esm/drivers/mongodb/mongodb-update-translator.mjs.map +1 -1
  75. package/esm/drivers/mongodb/pipeline-stage-object.mjs +1 -1
  76. package/esm/drivers/mongodb/pipeline-stage-object.mjs.map +1 -1
  77. package/esm/drivers/mongodb/types.d.mts +1 -1
  78. package/esm/drivers/mongodb/types.d.mts.map +1 -1
  79. package/esm/drivers/postgres/naming.mjs +1 -1
  80. package/esm/drivers/postgres/naming.mjs.map +1 -1
  81. package/esm/drivers/postgres/postgres-blueprint.d.mts +1 -1
  82. package/esm/drivers/postgres/postgres-blueprint.d.mts.map +1 -1
  83. package/esm/drivers/postgres/postgres-blueprint.mjs +1 -1
  84. package/esm/drivers/postgres/postgres-blueprint.mjs.map +1 -1
  85. package/esm/drivers/postgres/postgres-dialect.d.mts +1 -1
  86. package/esm/drivers/postgres/postgres-dialect.d.mts.map +1 -1
  87. package/esm/drivers/postgres/postgres-dialect.mjs +1 -1
  88. package/esm/drivers/postgres/postgres-dialect.mjs.map +1 -1
  89. package/esm/drivers/postgres/postgres-driver.d.mts +1 -1
  90. package/esm/drivers/postgres/postgres-driver.d.mts.map +1 -1
  91. package/esm/drivers/postgres/postgres-driver.mjs +1 -1
  92. package/esm/drivers/postgres/postgres-driver.mjs.map +1 -1
  93. package/esm/drivers/postgres/postgres-migration-driver.d.mts +1 -1
  94. package/esm/drivers/postgres/postgres-migration-driver.d.mts.map +1 -1
  95. package/esm/drivers/postgres/postgres-migration-driver.mjs +1 -1
  96. package/esm/drivers/postgres/postgres-migration-driver.mjs.map +1 -1
  97. package/esm/drivers/postgres/postgres-query-builder.d.mts +1 -1
  98. package/esm/drivers/postgres/postgres-query-builder.d.mts.map +1 -1
  99. package/esm/drivers/postgres/postgres-query-builder.mjs +1 -1
  100. package/esm/drivers/postgres/postgres-query-builder.mjs.map +1 -1
  101. package/esm/drivers/postgres/postgres-query-parser.d.mts +1 -1
  102. package/esm/drivers/postgres/postgres-query-parser.d.mts.map +1 -1
  103. package/esm/drivers/postgres/postgres-query-parser.mjs +1 -2
  104. package/esm/drivers/postgres/postgres-query-parser.mjs.map +1 -1
  105. package/esm/drivers/postgres/postgres-sql-serializer.mjs +1 -1
  106. package/esm/drivers/postgres/postgres-sql-serializer.mjs.map +1 -1
  107. package/esm/drivers/postgres/postgres-ttl-purge.mjs +1 -1
  108. package/esm/drivers/postgres/postgres-ttl-purge.mjs.map +1 -1
  109. package/esm/drivers/postgres/postgres-type-converters.mjs +1 -1
  110. package/esm/drivers/postgres/postgres-type-converters.mjs.map +1 -1
  111. package/esm/drivers/postgres/postgres-update-validator.mjs +1 -1
  112. package/esm/drivers/postgres/postgres-update-validator.mjs.map +1 -1
  113. package/esm/drivers/postgres/types.d.mts +1 -1
  114. package/esm/drivers/postgres/types.d.mts.map +1 -1
  115. package/esm/drivers/sql/sql-dialect.contract.d.mts +1 -1
  116. package/esm/drivers/sql/sql-dialect.contract.d.mts.map +1 -1
  117. package/esm/drivers/sql/sql-types.d.mts +1 -1
  118. package/esm/drivers/sql/sql-types.d.mts.map +1 -1
  119. package/esm/errors/missing-data-source.error.d.mts +1 -1
  120. package/esm/errors/missing-data-source.error.d.mts.map +1 -1
  121. package/esm/errors/missing-data-source.error.mjs +1 -1
  122. package/esm/errors/missing-data-source.error.mjs.map +1 -1
  123. package/esm/errors/transaction-rollback.error.d.mts +1 -1
  124. package/esm/errors/transaction-rollback.error.d.mts.map +1 -1
  125. package/esm/errors/transaction-rollback.error.mjs +1 -1
  126. package/esm/errors/transaction-rollback.error.mjs.map +1 -1
  127. package/esm/errors/undefined-where-value.error.d.mts +1 -1
  128. package/esm/errors/undefined-where-value.error.d.mts.map +1 -1
  129. package/esm/errors/undefined-where-value.error.mjs +1 -1
  130. package/esm/errors/undefined-where-value.error.mjs.map +1 -1
  131. package/esm/errors/unsafe-filter.error.d.mts +1 -1
  132. package/esm/errors/unsafe-filter.error.d.mts.map +1 -1
  133. package/esm/errors/unsafe-filter.error.mjs +1 -1
  134. package/esm/errors/unsafe-filter.error.mjs.map +1 -1
  135. package/esm/errors/unsafe-raw-expression.error.d.mts +1 -1
  136. package/esm/errors/unsafe-raw-expression.error.d.mts.map +1 -1
  137. package/esm/errors/unsafe-raw-expression.error.mjs +1 -1
  138. package/esm/errors/unsafe-raw-expression.error.mjs.map +1 -1
  139. package/esm/errors/unsupported-lean-operation.error.d.mts +1 -1
  140. package/esm/errors/unsupported-lean-operation.error.d.mts.map +1 -1
  141. package/esm/errors/unsupported-lean-operation.error.mjs +1 -1
  142. package/esm/errors/unsupported-lean-operation.error.mjs.map +1 -1
  143. package/esm/errors/unsupported-lock-for-update.error.d.mts +1 -1
  144. package/esm/errors/unsupported-lock-for-update.error.d.mts.map +1 -1
  145. package/esm/errors/unsupported-lock-for-update.error.mjs +1 -1
  146. package/esm/errors/unsupported-lock-for-update.error.mjs.map +1 -1
  147. package/esm/errors/unsupported-query-operation.error.d.mts +1 -1
  148. package/esm/errors/unsupported-query-operation.error.d.mts.map +1 -1
  149. package/esm/errors/unsupported-query-operation.error.mjs +1 -1
  150. package/esm/errors/unsupported-query-operation.error.mjs.map +1 -1
  151. package/esm/errors/unsupported-update-operation.error.d.mts +1 -1
  152. package/esm/errors/unsupported-update-operation.error.d.mts.map +1 -1
  153. package/esm/errors/unsupported-update-operation.error.mjs +1 -1
  154. package/esm/errors/unsupported-update-operation.error.mjs.map +1 -1
  155. package/esm/events/model-events.d.mts +1 -1
  156. package/esm/events/model-events.d.mts.map +1 -1
  157. package/esm/events/model-events.mjs +1 -1
  158. package/esm/events/model-events.mjs.map +1 -1
  159. package/esm/expressions/aggregate-expressions.d.mts +1 -1
  160. package/esm/expressions/aggregate-expressions.d.mts.map +1 -1
  161. package/esm/expressions/aggregate-expressions.mjs +1 -1
  162. package/esm/expressions/aggregate-expressions.mjs.map +1 -1
  163. package/esm/expressions/column-expressions.d.mts +1 -1
  164. package/esm/expressions/column-expressions.d.mts.map +1 -1
  165. package/esm/expressions/column-expressions.mjs +1 -1
  166. package/esm/expressions/column-expressions.mjs.map +1 -1
  167. package/esm/migration/column-builder.d.mts +1 -1
  168. package/esm/migration/column-builder.d.mts.map +1 -1
  169. package/esm/migration/column-builder.mjs +1 -1
  170. package/esm/migration/column-builder.mjs.map +1 -1
  171. package/esm/migration/column-helpers.d.mts +1 -1
  172. package/esm/migration/column-helpers.d.mts.map +1 -1
  173. package/esm/migration/column-helpers.mjs +1 -1
  174. package/esm/migration/column-helpers.mjs.map +1 -1
  175. package/esm/migration/foreign-key-builder.d.mts +1 -1
  176. package/esm/migration/foreign-key-builder.d.mts.map +1 -1
  177. package/esm/migration/foreign-key-builder.mjs +1 -1
  178. package/esm/migration/foreign-key-builder.mjs.map +1 -1
  179. package/esm/migration/migration-order.mjs +1 -1
  180. package/esm/migration/migration-order.mjs.map +1 -1
  181. package/esm/migration/migration-runner.d.mts +1 -1
  182. package/esm/migration/migration-runner.d.mts.map +1 -1
  183. package/esm/migration/migration-runner.mjs +1 -1
  184. package/esm/migration/migration-runner.mjs.map +1 -1
  185. package/esm/migration/migration.d.mts +1 -1
  186. package/esm/migration/migration.d.mts.map +1 -1
  187. package/esm/migration/migration.mjs +1 -1
  188. package/esm/migration/migration.mjs.map +1 -1
  189. package/esm/migration/parse-created-at.mjs +1 -1
  190. package/esm/migration/parse-created-at.mjs.map +1 -1
  191. package/esm/migration/sql-grammar.mjs +1 -1
  192. package/esm/migration/sql-grammar.mjs.map +1 -1
  193. package/esm/migration/sql-serializer.d.mts +1 -1
  194. package/esm/migration/sql-serializer.d.mts.map +1 -1
  195. package/esm/migration/sql-serializer.mjs +1 -1
  196. package/esm/migration/sql-serializer.mjs.map +1 -1
  197. package/esm/migration/types.d.mts +1 -1
  198. package/esm/migration/types.d.mts.map +1 -1
  199. package/esm/model/generate-model-id.mjs +1 -1
  200. package/esm/model/generate-model-id.mjs.map +1 -1
  201. package/esm/model/methods/accessor-methods.mjs +1 -1
  202. package/esm/model/methods/accessor-methods.mjs.map +1 -1
  203. package/esm/model/methods/delete-methods.mjs +1 -1
  204. package/esm/model/methods/delete-methods.mjs.map +1 -1
  205. package/esm/model/methods/dirty-methods.mjs +1 -1
  206. package/esm/model/methods/dirty-methods.mjs.map +1 -1
  207. package/esm/model/methods/hydration-methods.mjs +1 -1
  208. package/esm/model/methods/hydration-methods.mjs.map +1 -1
  209. package/esm/model/methods/instance-event-methods.mjs +1 -1
  210. package/esm/model/methods/instance-event-methods.mjs.map +1 -1
  211. package/esm/model/methods/meta-methods.mjs +1 -1
  212. package/esm/model/methods/meta-methods.mjs.map +1 -1
  213. package/esm/model/methods/pivot-methods.mjs +1 -1
  214. package/esm/model/methods/pivot-methods.mjs.map +1 -1
  215. package/esm/model/methods/query-methods.mjs +1 -1
  216. package/esm/model/methods/query-methods.mjs.map +1 -1
  217. package/esm/model/methods/restore-methods.mjs +1 -1
  218. package/esm/model/methods/restore-methods.mjs.map +1 -1
  219. package/esm/model/methods/scope-methods.mjs +1 -1
  220. package/esm/model/methods/scope-methods.mjs.map +1 -1
  221. package/esm/model/methods/serialization-methods.mjs +1 -1
  222. package/esm/model/methods/serialization-methods.mjs.map +1 -1
  223. package/esm/model/methods/static-event-methods.mjs +1 -1
  224. package/esm/model/methods/static-event-methods.mjs.map +1 -1
  225. package/esm/model/methods/write-methods.d.mts +1 -1
  226. package/esm/model/methods/write-methods.d.mts.map +1 -1
  227. package/esm/model/methods/write-methods.mjs +1 -1
  228. package/esm/model/methods/write-methods.mjs.map +1 -1
  229. package/esm/model/model.d.mts +1 -1
  230. package/esm/model/model.d.mts.map +1 -1
  231. package/esm/model/model.mjs +1 -1
  232. package/esm/model/model.mjs.map +1 -1
  233. package/esm/model/model.types.d.mts +1 -1
  234. package/esm/model/model.types.d.mts.map +1 -1
  235. package/esm/model/register-model.d.mts +1 -1
  236. package/esm/model/register-model.d.mts.map +1 -1
  237. package/esm/model/register-model.mjs +1 -1
  238. package/esm/model/register-model.mjs.map +1 -1
  239. package/esm/model/relation-decorators.d.mts +1 -1
  240. package/esm/model/relation-decorators.d.mts.map +1 -1
  241. package/esm/model/relation-decorators.mjs +1 -1
  242. package/esm/model/relation-decorators.mjs.map +1 -1
  243. package/esm/operations/database.d.mts +1 -1
  244. package/esm/operations/database.d.mts.map +1 -1
  245. package/esm/operations/database.mjs +1 -1
  246. package/esm/operations/database.mjs.map +1 -1
  247. package/esm/operations/migrations.d.mts +1 -1
  248. package/esm/operations/migrations.d.mts.map +1 -1
  249. package/esm/operations/migrations.mjs +1 -1
  250. package/esm/operations/migrations.mjs.map +1 -1
  251. package/esm/query-builder/lean-records.mjs +1 -1
  252. package/esm/query-builder/lean-records.mjs.map +1 -1
  253. package/esm/query-builder/query-builder.d.mts +1 -1
  254. package/esm/query-builder/query-builder.d.mts.map +1 -1
  255. package/esm/query-builder/query-builder.mjs +1 -1
  256. package/esm/query-builder/query-builder.mjs.map +1 -1
  257. package/esm/relations/key-conventions.mjs +1 -1
  258. package/esm/relations/key-conventions.mjs.map +1 -1
  259. package/esm/relations/pivot-operations.d.mts +1 -1
  260. package/esm/relations/pivot-operations.d.mts.map +1 -1
  261. package/esm/relations/pivot-operations.mjs +1 -1
  262. package/esm/relations/pivot-operations.mjs.map +1 -1
  263. package/esm/relations/relation-hydrator.d.mts +1 -1
  264. package/esm/relations/relation-hydrator.d.mts.map +1 -1
  265. package/esm/relations/relation-hydrator.mjs +1 -1
  266. package/esm/relations/relation-hydrator.mjs.map +1 -1
  267. package/esm/relations/relation-loader.d.mts +1 -1
  268. package/esm/relations/relation-loader.d.mts.map +1 -1
  269. package/esm/relations/relation-loader.mjs +1 -1
  270. package/esm/relations/relation-loader.mjs.map +1 -1
  271. package/esm/relations/types.d.mts +1 -1
  272. package/esm/relations/types.d.mts.map +1 -1
  273. package/esm/remover/database-remover.d.mts +1 -1
  274. package/esm/remover/database-remover.d.mts.map +1 -1
  275. package/esm/remover/database-remover.mjs +1 -1
  276. package/esm/remover/database-remover.mjs.map +1 -1
  277. package/esm/restorer/database-restorer.d.mts +1 -1
  278. package/esm/restorer/database-restorer.d.mts.map +1 -1
  279. package/esm/restorer/database-restorer.mjs +1 -1
  280. package/esm/restorer/database-restorer.mjs.map +1 -1
  281. package/esm/sql-database-dirty-tracker.d.mts +1 -1
  282. package/esm/sql-database-dirty-tracker.d.mts.map +1 -1
  283. package/esm/sql-database-dirty-tracker.mjs +1 -1
  284. package/esm/sql-database-dirty-tracker.mjs.map +1 -1
  285. package/esm/sync/model-events.mjs +1 -1
  286. package/esm/sync/model-events.mjs.map +1 -1
  287. package/esm/sync/model-sync-operation.d.mts +1 -1
  288. package/esm/sync/model-sync-operation.d.mts.map +1 -1
  289. package/esm/sync/model-sync-operation.mjs +1 -1
  290. package/esm/sync/model-sync-operation.mjs.map +1 -1
  291. package/esm/sync/model-sync.d.mts +1 -1
  292. package/esm/sync/model-sync.d.mts.map +1 -1
  293. package/esm/sync/model-sync.mjs +1 -1
  294. package/esm/sync/model-sync.mjs.map +1 -1
  295. package/esm/sync/sync-context.d.mts +1 -1
  296. package/esm/sync/sync-context.d.mts.map +1 -1
  297. package/esm/sync/sync-context.mjs +1 -1
  298. package/esm/sync/sync-context.mjs.map +1 -1
  299. package/esm/sync/sync-fanout.mjs +1 -1
  300. package/esm/sync/sync-fanout.mjs.map +1 -1
  301. package/esm/sync/sync-manager.d.mts +1 -1
  302. package/esm/sync/sync-manager.d.mts.map +1 -1
  303. package/esm/sync/sync-manager.mjs +1 -1
  304. package/esm/sync/sync-manager.mjs.map +1 -1
  305. package/esm/sync/types.d.mts +1 -1
  306. package/esm/sync/types.d.mts.map +1 -1
  307. package/esm/transactions/after-commit.d.mts +1 -1
  308. package/esm/transactions/after-commit.d.mts.map +1 -1
  309. package/esm/transactions/after-commit.mjs +1 -1
  310. package/esm/transactions/after-commit.mjs.map +1 -1
  311. package/esm/types.d.mts +1 -1
  312. package/esm/types.d.mts.map +1 -1
  313. package/esm/utils/connect-to-database.d.mts +1 -1
  314. package/esm/utils/connect-to-database.d.mts.map +1 -1
  315. package/esm/utils/connect-to-database.mjs +1 -1
  316. package/esm/utils/connect-to-database.mjs.map +1 -1
  317. package/esm/utils/database-writer.utils.d.mts +1 -1
  318. package/esm/utils/database-writer.utils.d.mts.map +1 -1
  319. package/esm/utils/database-writer.utils.mjs +1 -1
  320. package/esm/utils/database-writer.utils.mjs.map +1 -1
  321. package/esm/utils/define-model.d.mts +1 -1
  322. package/esm/utils/define-model.d.mts.map +1 -1
  323. package/esm/utils/define-model.mjs +1 -1
  324. package/esm/utils/define-model.mjs.map +1 -1
  325. package/esm/utils/escape-regex.d.mts +1 -1
  326. package/esm/utils/escape-regex.d.mts.map +1 -1
  327. package/esm/utils/escape-regex.mjs +1 -1
  328. package/esm/utils/escape-regex.mjs.map +1 -1
  329. package/esm/utils/is-valid-date-value.mjs +1 -1
  330. package/esm/utils/is-valid-date-value.mjs.map +1 -1
  331. package/esm/utils/once-connected.d.mts +1 -1
  332. package/esm/utils/once-connected.d.mts.map +1 -1
  333. package/esm/utils/once-connected.mjs +1 -1
  334. package/esm/utils/once-connected.mjs.map +1 -1
  335. package/esm/utils/prune-empty-parents.mjs +1 -1
  336. package/esm/utils/prune-empty-parents.mjs.map +1 -1
  337. package/esm/utils/sanitize-filter.d.mts +1 -1
  338. package/esm/utils/sanitize-filter.d.mts.map +1 -1
  339. package/esm/utils/sanitize-filter.mjs +1 -1
  340. package/esm/utils/sanitize-filter.mjs.map +1 -1
  341. package/esm/validation/database-seal-plugins.mjs +1 -1
  342. package/esm/validation/database-seal-plugins.mjs.map +1 -1
  343. package/esm/validation/database-writer-validation-error.d.mts +1 -1
  344. package/esm/validation/database-writer-validation-error.d.mts.map +1 -1
  345. package/esm/validation/database-writer-validation-error.mjs +1 -1
  346. package/esm/validation/database-writer-validation-error.mjs.map +1 -1
  347. package/esm/validation/mutators/embed-mutator.mjs +1 -1
  348. package/esm/validation/mutators/embed-mutator.mjs.map +1 -1
  349. package/esm/validation/plugins/database-rules-plugin.d.mts +1 -1
  350. package/esm/validation/plugins/database-rules-plugin.d.mts.map +1 -1
  351. package/esm/validation/plugins/database-rules-plugin.mjs +1 -1
  352. package/esm/validation/plugins/database-rules-plugin.mjs.map +1 -1
  353. package/esm/validation/plugins/embed-validator-plugin.d.mts +1 -1
  354. package/esm/validation/plugins/embed-validator-plugin.d.mts.map +1 -1
  355. package/esm/validation/plugins/embed-validator-plugin.mjs +1 -1
  356. package/esm/validation/plugins/embed-validator-plugin.mjs.map +1 -1
  357. package/esm/validation/rules/database-model-rule.mjs +1 -1
  358. package/esm/validation/rules/database-model-rule.mjs.map +1 -1
  359. package/esm/validation/rules/exists-rule.mjs +1 -1
  360. package/esm/validation/rules/exists-rule.mjs.map +1 -1
  361. package/esm/validation/rules/unique-rule.mjs +1 -1
  362. package/esm/validation/rules/unique-rule.mjs.map +1 -1
  363. package/esm/validation/transformers/embed-model-transformer.mjs +1 -1
  364. package/esm/validation/transformers/embed-model-transformer.mjs.map +1 -1
  365. package/esm/validation/types.d.mts +1 -1
  366. package/esm/validation/types.d.mts.map +1 -1
  367. package/esm/validation/validators/embed-validator.d.mts +1 -1
  368. package/esm/validation/validators/embed-validator.d.mts.map +1 -1
  369. package/esm/validation/validators/embed-validator.mjs +1 -1
  370. package/esm/validation/validators/embed-validator.mjs.map +1 -1
  371. package/esm/writer/database-writer.d.mts +1 -1
  372. package/esm/writer/database-writer.d.mts.map +1 -1
  373. package/esm/writer/database-writer.mjs +1 -1
  374. package/esm/writer/database-writer.mjs.map +1 -1
  375. package/llms-full.txt +541 -434
  376. package/package.json +7 -6
  377. package/skills/aggregate-data/SKILL.md +28 -17
  378. package/skills/alter-migration/SKILL.md +325 -233
  379. package/skills/cascade-basics/SKILL.md +19 -19
  380. package/skills/configure-delete-strategy/SKILL.md +11 -11
  381. package/skills/define-model/SKILL.md +19 -17
  382. package/skills/define-relations/SKILL.md +13 -18
  383. package/skills/index.md +3 -0
  384. package/skills/manage-transactions/SKILL.md +18 -12
  385. package/skills/paginate-results/SKILL.md +6 -8
  386. package/skills/perform-atomic-ops/SKILL.md +26 -21
  387. package/skills/query-data/SKILL.md +27 -33
  388. package/skills/run-cascade-cli/SKILL.md +11 -10
  389. package/skills/search-by-vector/SKILL.md +8 -5
  390. package/skills/subscribe-to-model-events/SKILL.md +17 -17
  391. package/skills/track-changes/SKILL.md +9 -9
  392. package/skills/write-migration/SKILL.md +4 -4
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/migration/parse-created-at.ts
1
+ //#region ../../packages/cascade/src/migration/parse-created-at.ts
2
2
  /**
3
3
  * Parse a migration's `createdAt` stamp into a `Date`.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"parse-created-at.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/parse-created-at.ts"],"sourcesContent":["/**\n * Parse a migration's `createdAt` stamp into a `Date`.\n *\n * Migration filenames generated by the framework carry a\n * `MM-DD-YYYY_HH-MM-SS` prefix, which **`new Date()` cannot parse** — it\n * returns `Invalid Date`. Anything ordering migrations by timestamp must come\n * through here; using the native constructor silently yields `NaN` and\n * degrades the sort into whatever its tiebreaker is.\n *\n * Supports `MM-DD-YYYY_HH-MM-SS` and `DD-MM-YYYY_HH-MM-SS`, telling them apart\n * by whether the first field exceeds 12 (a month cannot), and falls back to\n * native parsing for ISO strings.\n *\n * @returns the parsed date, or `undefined` when the stamp is unusable.\n */\nexport function parseCreatedAt(createdAt: string): Date | undefined {\n const match = createdAt.match(/^(\\d{2})-(\\d{2})-(\\d{4})_(\\d{2})-(\\d{2})-(\\d{2})$/);\n\n if (match) {\n const [, first, second, year, hour, minute, second_time] = match;\n\n // All six groups are present whenever the pattern matched — but that is a\n // property of the regex literal above, not something the compiler carries\n // to here, so each is `string | undefined`. Returning `undefined` is\n // exactly this function's documented answer for a stamp it cannot use, so\n // the guard costs nothing and removes six assertions.\n if (\n first === undefined ||\n second === undefined ||\n year === undefined ||\n hour === undefined ||\n minute === undefined ||\n second_time === undefined\n ) {\n return undefined;\n }\n\n const firstNum = parseInt(first);\n const secondNum = parseInt(second);\n\n let month: number, day: number;\n\n // Intelligently detect format:\n // If first > 12, it must be DD-MM-YYYY (day can't be month)\n // If second > 12, it must be MM-DD-YYYY (day can't be month)\n // Otherwise, assume MM-DD-YYYY (US format as default)\n if (firstNum > 12) {\n // DD-MM-YYYY format\n day = firstNum;\n month = secondNum;\n } else if (secondNum > 12) {\n // MM-DD-YYYY format\n month = firstNum;\n day = secondNum;\n } else {\n // Ambiguous — default to MM-DD-YYYY\n month = firstNum;\n day = secondNum;\n }\n\n const date = new Date(\n parseInt(year),\n month - 1, // JavaScript months are 0-indexed\n day,\n parseInt(hour),\n parseInt(minute),\n parseInt(second_time),\n );\n\n // Validate the date is actually valid\n if (isNaN(date.getTime())) {\n return undefined;\n }\n\n return date;\n }\n\n // Fallback to standard Date parsing for ISO strings\n try {\n const date = new Date(createdAt);\n\n return isNaN(date.getTime()) ? undefined : date;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Compare two migration timestamps for ordering.\n *\n * Shared by every migration comparator so they cannot drift apart: a stamp\n * that parses always sorts before one that doesn't, and two unparseable\n * stamps are equal (leaving the caller's own tiebreaker to decide).\n *\n * Returns `undefined` when the timestamps do not settle the comparison.\n */\nexport function compareCreatedAt(\n a: string | undefined,\n b: string | undefined,\n): number | undefined {\n const dateA = a ? parseCreatedAt(a) : undefined;\n const dateB = b ? parseCreatedAt(b) : undefined;\n\n if (dateA && dateB) {\n const difference = dateA.getTime() - dateB.getTime();\n\n return difference === 0 ? undefined : difference;\n }\n\n if (dateA) {\n return -1;\n }\n\n if (dateB) {\n return 1;\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,eAAe,WAAqC;CAClE,MAAM,QAAQ,UAAU,MAAM,mDAAmD;CAEjF,IAAI,OAAO;EACT,MAAM,GAAG,OAAO,QAAQ,MAAM,MAAM,QAAQ,eAAe;EAO3D,IACE,UAAU,UACV,WAAW,UACX,SAAS,UACT,SAAS,UACT,WAAW,UACX,gBAAgB,QAEhB;EAGF,MAAM,WAAW,SAAS,KAAK;EAC/B,MAAM,YAAY,SAAS,MAAM;EAEjC,IAAI,OAAe;EAMnB,IAAI,WAAW,IAAI;GAEjB,MAAM;GACN,QAAQ;EACV,OAAO,IAAI,YAAY,IAAI;GAEzB,QAAQ;GACR,MAAM;EACR,OAAO;GAEL,QAAQ;GACR,MAAM;EACR;EAEA,MAAM,OAAO,IAAI,KACf,SAAS,IAAI,GACb,QAAQ,GACR,KACA,SAAS,IAAI,GACb,SAAS,MAAM,GACf,SAAS,WAAW,CACtB;EAGA,IAAI,MAAM,KAAK,QAAQ,CAAC,GACtB;EAGF,OAAO;CACT;CAGA,IAAI;EACF,MAAM,OAAO,IAAI,KAAK,SAAS;EAE/B,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,SAAY;CAC7C,QAAQ;EACN;CACF;AACF;;;;;;;;;;AAWA,SAAgB,iBACd,GACA,GACoB;CACpB,MAAM,QAAQ,IAAI,eAAe,CAAC,IAAI;CACtC,MAAM,QAAQ,IAAI,eAAe,CAAC,IAAI;CAEtC,IAAI,SAAS,OAAO;EAClB,MAAM,aAAa,MAAM,QAAQ,IAAI,MAAM,QAAQ;EAEnD,OAAO,eAAe,IAAI,SAAY;CACxC;CAEA,IAAI,OACF,OAAO;CAGT,IAAI,OACF,OAAO;AAIX"}
1
+ {"version":3,"file":"parse-created-at.mjs","names":[],"sources":["../../../../../../../../packages/cascade/src/migration/parse-created-at.ts"],"sourcesContent":["/**\n * Parse a migration's `createdAt` stamp into a `Date`.\n *\n * Migration filenames generated by the framework carry a\n * `MM-DD-YYYY_HH-MM-SS` prefix, which **`new Date()` cannot parse** — it\n * returns `Invalid Date`. Anything ordering migrations by timestamp must come\n * through here; using the native constructor silently yields `NaN` and\n * degrades the sort into whatever its tiebreaker is.\n *\n * Supports `MM-DD-YYYY_HH-MM-SS` and `DD-MM-YYYY_HH-MM-SS`, telling them apart\n * by whether the first field exceeds 12 (a month cannot), and falls back to\n * native parsing for ISO strings.\n *\n * @returns the parsed date, or `undefined` when the stamp is unusable.\n */\nexport function parseCreatedAt(createdAt: string): Date | undefined {\n const match = createdAt.match(/^(\\d{2})-(\\d{2})-(\\d{4})_(\\d{2})-(\\d{2})-(\\d{2})$/);\n\n if (match) {\n const [, first, second, year, hour, minute, second_time] = match;\n\n // All six groups are present whenever the pattern matched — but that is a\n // property of the regex literal above, not something the compiler carries\n // to here, so each is `string | undefined`. Returning `undefined` is\n // exactly this function's documented answer for a stamp it cannot use, so\n // the guard costs nothing and removes six assertions.\n if (\n first === undefined ||\n second === undefined ||\n year === undefined ||\n hour === undefined ||\n minute === undefined ||\n second_time === undefined\n ) {\n return undefined;\n }\n\n const firstNum = parseInt(first);\n const secondNum = parseInt(second);\n\n let month: number, day: number;\n\n // Intelligently detect format:\n // If first > 12, it must be DD-MM-YYYY (day can't be month)\n // If second > 12, it must be MM-DD-YYYY (day can't be month)\n // Otherwise, assume MM-DD-YYYY (US format as default)\n if (firstNum > 12) {\n // DD-MM-YYYY format\n day = firstNum;\n month = secondNum;\n } else if (secondNum > 12) {\n // MM-DD-YYYY format\n month = firstNum;\n day = secondNum;\n } else {\n // Ambiguous — default to MM-DD-YYYY\n month = firstNum;\n day = secondNum;\n }\n\n const date = new Date(\n parseInt(year),\n month - 1, // JavaScript months are 0-indexed\n day,\n parseInt(hour),\n parseInt(minute),\n parseInt(second_time),\n );\n\n // Validate the date is actually valid\n if (isNaN(date.getTime())) {\n return undefined;\n }\n\n return date;\n }\n\n // Fallback to standard Date parsing for ISO strings\n try {\n const date = new Date(createdAt);\n\n return isNaN(date.getTime()) ? undefined : date;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Compare two migration timestamps for ordering.\n *\n * Shared by every migration comparator so they cannot drift apart: a stamp\n * that parses always sorts before one that doesn't, and two unparseable\n * stamps are equal (leaving the caller's own tiebreaker to decide).\n *\n * Returns `undefined` when the timestamps do not settle the comparison.\n */\nexport function compareCreatedAt(a: string | undefined, b: string | undefined): number | undefined {\n const dateA = a ? parseCreatedAt(a) : undefined;\n const dateB = b ? parseCreatedAt(b) : undefined;\n\n if (dateA && dateB) {\n const difference = dateA.getTime() - dateB.getTime();\n\n return difference === 0 ? undefined : difference;\n }\n\n if (dateA) {\n return -1;\n }\n\n if (dateB) {\n return 1;\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,eAAe,WAAqC;CAClE,MAAM,QAAQ,UAAU,MAAM,mDAAmD;CAEjF,IAAI,OAAO;EACT,MAAM,GAAG,OAAO,QAAQ,MAAM,MAAM,QAAQ,eAAe;EAO3D,IACE,UAAU,UACV,WAAW,UACX,SAAS,UACT,SAAS,UACT,WAAW,UACX,gBAAgB,QAEhB;EAGF,MAAM,WAAW,SAAS,KAAK;EAC/B,MAAM,YAAY,SAAS,MAAM;EAEjC,IAAI,OAAe;EAMnB,IAAI,WAAW,IAAI;GAEjB,MAAM;GACN,QAAQ;EACV,OAAO,IAAI,YAAY,IAAI;GAEzB,QAAQ;GACR,MAAM;EACR,OAAO;GAEL,QAAQ;GACR,MAAM;EACR;EAEA,MAAM,OAAO,IAAI,KACf,SAAS,IAAI,GACb,QAAQ,GACR,KACA,SAAS,IAAI,GACb,SAAS,MAAM,GACf,SAAS,WAAW,CACtB;EAGA,IAAI,MAAM,KAAK,QAAQ,CAAC,GACtB;EAGF,OAAO;CACT;CAGA,IAAI;EACF,MAAM,OAAO,IAAI,KAAK,SAAS;EAE/B,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,SAAY;CAC7C,QAAQ;EACN;CACF;AACF;;;;;;;;;;AAWA,SAAgB,iBAAiB,GAAuB,GAA2C;CACjG,MAAM,QAAQ,IAAI,eAAe,CAAC,IAAI;CACtC,MAAM,QAAQ,IAAI,eAAe,CAAC,IAAI;CAEtC,IAAI,SAAS,OAAO;EAClB,MAAM,aAAa,MAAM,QAAQ,IAAI,MAAM,QAAQ;EAEnD,OAAO,eAAe,IAAI,SAAY;CACxC;CAEA,IAAI,OACF,OAAO;CAGT,IAAI,OACF,OAAO;AAIX"}
@@ -1,6 +1,6 @@
1
1
  import { compareCreatedAt } from "./parse-created-at.mjs";
2
2
 
3
- //#region ../cascade/src/migration/sql-grammar.ts
3
+ //#region ../../packages/cascade/src/migration/sql-grammar.ts
4
4
  /**
5
5
  * Parses and sorts SQL statements globally based on their execution phase,
6
6
  * and classifies statements by their semantic type.
@@ -1 +1 @@
1
- {"version":3,"file":"sql-grammar.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/sql-grammar.ts"],"sourcesContent":["import { compareCreatedAt } from \"./parse-created-at\";\nimport type { SQLStatementType, TaggedSQL } from \"./types\";\n\n/**\n * Parses and sorts SQL statements globally based on their execution phase,\n * and classifies statements by their semantic type.\n */\nexport class SQLGrammar {\n /**\n * Determine the execution phase of a SQL statement (1–6).\n *\n * Phase ordering ensures DDL operations run in dependency-safe order\n * regardless of which migration file they originate from.\n *\n * | Phase | Statements |\n * |-------|-----------------------------------------------|\n * | 1 | CREATE EXTENSION, TYPE, DOMAIN, SCHEMA |\n * | 2 | CREATE TABLE |\n * | 3 | ADD COLUMN, ADD PRIMARY KEY |\n * | 4 | CREATE INDEX, ADD FOREIGN KEY |\n * | 5 | DROP COLUMN, ALTER COLUMN, DROP TABLE |\n * | 6 | Raw / unclassified |\n *\n * @example\n * SQLGrammar.phase(\"CREATE EXTENSION IF NOT EXISTS vector\"); // => 1\n * SQLGrammar.phase(\"ALTER TABLE users ADD COLUMN email TEXT\"); // => 3\n */\n public static phase(sql: string): 1 | 2 | 3 | 4 | 5 | 6 {\n const s = sql.trim().toUpperCase();\n\n // Phase 1: Preparation (Extensions, Enums, Domains, Types)\n if (\n s.startsWith(\"CREATE EXTENSION\") ||\n s.startsWith(\"CREATE TYPE\") ||\n s.startsWith(\"CREATE DOMAIN\") ||\n s.startsWith(\"CREATE SCHEMA\")\n ) {\n return 1;\n }\n\n // Phase 2: Table Creation\n if (s.startsWith(\"CREATE TABLE\")) {\n return 2;\n }\n\n // Phase 3 / 4 / 5: ALTER TABLE — broken down by clause\n if (s.startsWith(\"ALTER TABLE\")) {\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"FOREIGN KEY\")) return 4;\n if (s.includes(\"DROP COLUMN\") || s.includes(\"DROP CONSTRAINT\") || s.includes(\"ALTER COLUMN\")) return 5;\n if (s.includes(\"ADD COLUMN\")) return 3;\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"PRIMARY KEY\")) return 3;\n }\n\n // Phase 4: Index Creation\n if (s.startsWith(\"CREATE INDEX\") || s.startsWith(\"CREATE UNIQUE INDEX\")) {\n return 4;\n }\n\n // Phase 5: Destructive table/index operations\n if (s.startsWith(\"DROP TABLE\") || s.startsWith(\"TRUNCATE TABLE\") || s.startsWith(\"DROP INDEX\")) {\n return 5;\n }\n\n // Phase 6: Raw / unclassified (DML, triggers, procedures, views)\n return 6;\n }\n\n /**\n * Classify a SQL statement into its semantic statement type.\n *\n * This is independent of execution phase — it identifies *what* a statement\n * does, not *when* it should run. Use this for pre-flight checks, dry-run\n * display, selective filtering, and extension detection.\n *\n * @example\n * SQLGrammar.classify(\"CREATE EXTENSION IF NOT EXISTS vector\");\n * // => \"CREATE_EXTENSION\"\n *\n * SQLGrammar.classify(\"ALTER TABLE users ADD COLUMN email TEXT\");\n * // => \"ADD_COLUMN\"\n */\n public static classify(sql: string): SQLStatementType {\n const s = sql.trim().toUpperCase();\n\n if (s.startsWith(\"CREATE EXTENSION\")) return \"CREATE_EXTENSION\";\n if (s.startsWith(\"CREATE SCHEMA\")) return \"CREATE_SCHEMA\";\n if (s.startsWith(\"CREATE TYPE\")) return \"CREATE_TYPE\";\n if (s.startsWith(\"CREATE DOMAIN\")) return \"CREATE_DOMAIN\";\n if (s.startsWith(\"CREATE TABLE\")) return \"CREATE_TABLE\";\n if (s.startsWith(\"DROP TABLE\")) return \"DROP_TABLE\";\n if (s.startsWith(\"TRUNCATE TABLE\")) return \"TRUNCATE_TABLE\";\n if (s.startsWith(\"DROP INDEX\")) return \"DROP_INDEX\";\n\n // Must check UNIQUE before plain INDEX to avoid misclassification\n if (s.startsWith(\"CREATE UNIQUE INDEX\")) return \"CREATE_UNIQUE_INDEX\";\n if (s.startsWith(\"CREATE INDEX\")) return \"CREATE_INDEX\";\n\n if (s.startsWith(\"ALTER TABLE\")) {\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"FOREIGN KEY\")) return \"ADD_FOREIGN_KEY\";\n if (s.includes(\"DROP CONSTRAINT\") && s.includes(\"FOREIGN KEY\")) return \"DROP_FOREIGN_KEY\";\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"PRIMARY KEY\")) return \"ADD_PRIMARY_KEY\";\n if (s.includes(\"DROP CONSTRAINT\")) return \"DROP_PRIMARY_KEY\";\n if (s.includes(\"ADD COLUMN\")) return \"ADD_COLUMN\";\n if (s.includes(\"DROP COLUMN\")) return \"DROP_COLUMN\";\n if (s.includes(\"RENAME COLUMN\")) return \"RENAME_COLUMN\";\n if (s.includes(\"RENAME TO\")) return \"RENAME_TABLE\";\n if (s.includes(\"ALTER COLUMN\")) return \"MODIFY_COLUMN\";\n }\n\n return \"RAW\";\n }\n\n /**\n * Extract the extension name from a CREATE EXTENSION statement.\n *\n * Returns undefined if the statement is not a CREATE EXTENSION statement\n * or the name cannot be parsed.\n *\n * @example\n * SQLGrammar.extractExtensionName(\"CREATE EXTENSION IF NOT EXISTS vector\");\n * // => \"vector\"\n *\n * SQLGrammar.extractExtensionName(\"CREATE EXTENSION postgis\");\n * // => \"postgis\"\n */\n public static extractExtensionName(sql: string): string | undefined {\n // Matches: CREATE EXTENSION [IF NOT EXISTS] <name>\n const match = sql\n .trim()\n .match(/^CREATE\\s+EXTENSION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i);\n\n return match?.[1]?.toLowerCase();\n }\n\n /**\n * Sort an array of tagged SQL statements by phase, then creation date, then migration name.\n *\n * This is the sort that decides **execution order** — it runs across every\n * pending migration's statements at once, after the migration list itself\n * has been ordered, so whatever it decides is final.\n *\n * The creation date must go through {@link compareCreatedAt}. Parsing these\n * stamps with `new Date()` returns `Invalid Date` for the framework's own\n * `MM-DD-YYYY_HH-MM-SS` filename format, which collapsed every timestamp to\n * the same value and quietly handed the whole ordering to the alphabetical\n * tiebreaker below — running, for example, a January 2026 migration before a\n * December 2025 one.\n */\n public static sort(statements: TaggedSQL[]): TaggedSQL[] {\n return statements.slice().sort((a, b) => {\n // 1. Sort by Phase (ascending)\n if (a.phase !== b.phase) {\n return a.phase - b.phase;\n }\n\n // 2. Sort by CreatedAt (within same phase)\n const byCreatedAt = compareCreatedAt(a.createdAt, b.createdAt);\n\n if (byCreatedAt !== undefined) {\n return byCreatedAt;\n }\n\n // 3. Sort by Migration Name (tie-breaker)\n const nameA = a.migrationName || \"\";\n const nameB = b.migrationName || \"\";\n return nameA.localeCompare(nameB);\n });\n }\n}\n"],"mappings":";;;;;;;AAOA,IAAa,aAAb,MAAwB;;;;;;;;;;;;;;;;;;;;CAoBtB,OAAc,MAAM,KAAoC;EACtD,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;EAGjC,IACE,EAAE,WAAW,kBAAkB,KAC/B,EAAE,WAAW,aAAa,KAC1B,EAAE,WAAW,eAAe,KAC5B,EAAE,WAAW,eAAe,GAE5B,OAAO;EAIT,IAAI,EAAE,WAAW,cAAc,GAC7B,OAAO;EAIT,IAAI,EAAE,WAAW,aAAa,GAAG;GAC/B,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACtE,IAAI,EAAE,SAAS,aAAa,KAAK,EAAE,SAAS,iBAAiB,KAAK,EAAE,SAAS,cAAc,GAAG,OAAO;GACrG,IAAI,EAAE,SAAS,YAAY,GAAG,OAAO;GACrC,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;EACxE;EAGA,IAAI,EAAE,WAAW,cAAc,KAAK,EAAE,WAAW,qBAAqB,GACpE,OAAO;EAIT,IAAI,EAAE,WAAW,YAAY,KAAK,EAAE,WAAW,gBAAgB,KAAK,EAAE,WAAW,YAAY,GAC3F,OAAO;EAIT,OAAO;CACT;;;;;;;;;;;;;;;CAgBA,OAAc,SAAS,KAA+B;EACpD,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;EAEjC,IAAI,EAAE,WAAW,kBAAkB,GAAG,OAAO;EAC7C,IAAI,EAAE,WAAW,eAAe,GAAG,OAAO;EAC1C,IAAI,EAAE,WAAW,aAAa,GAAG,OAAO;EACxC,IAAI,EAAE,WAAW,eAAe,GAAG,OAAO;EAC1C,IAAI,EAAE,WAAW,cAAc,GAAG,OAAO;EACzC,IAAI,EAAE,WAAW,YAAY,GAAG,OAAO;EACvC,IAAI,EAAE,WAAW,gBAAgB,GAAG,OAAO;EAC3C,IAAI,EAAE,WAAW,YAAY,GAAG,OAAO;EAGvC,IAAI,EAAE,WAAW,qBAAqB,GAAG,OAAO;EAChD,IAAI,EAAE,WAAW,cAAc,GAAG,OAAO;EAEzC,IAAI,EAAE,WAAW,aAAa,GAAG;GAC/B,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACtE,IAAI,EAAE,SAAS,iBAAiB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACvE,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACtE,IAAI,EAAE,SAAS,iBAAiB,GAAG,OAAO;GAC1C,IAAI,EAAE,SAAS,YAAY,GAAG,OAAO;GACrC,IAAI,EAAE,SAAS,aAAa,GAAG,OAAO;GACtC,IAAI,EAAE,SAAS,eAAe,GAAG,OAAO;GACxC,IAAI,EAAE,SAAS,WAAW,GAAG,OAAO;GACpC,IAAI,EAAE,SAAS,cAAc,GAAG,OAAO;EACzC;EAEA,OAAO;CACT;;;;;;;;;;;;;;CAeA,OAAc,qBAAqB,KAAiC;EAMlE,OAJc,IACX,KAAK,CAAC,CACN,MAAM,uDAEE,CAAC,GAAG,EAAE,EAAE,YAAY;CACjC;;;;;;;;;;;;;;;CAgBA,OAAc,KAAK,YAAsC;EACvD,OAAO,WAAW,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM;GAEvC,IAAI,EAAE,UAAU,EAAE,OAChB,OAAO,EAAE,QAAQ,EAAE;GAIrB,MAAM,cAAc,iBAAiB,EAAE,WAAW,EAAE,SAAS;GAE7D,IAAI,gBAAgB,QAClB,OAAO;GAIT,MAAM,QAAQ,EAAE,iBAAiB;GACjC,MAAM,QAAQ,EAAE,iBAAiB;GACjC,OAAO,MAAM,cAAc,KAAK;EAClC,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"sql-grammar.mjs","names":[],"sources":["../../../../../../../../packages/cascade/src/migration/sql-grammar.ts"],"sourcesContent":["import { compareCreatedAt } from \"./parse-created-at\";\nimport type { SQLStatementType, TaggedSQL } from \"./types\";\n\n/**\n * Parses and sorts SQL statements globally based on their execution phase,\n * and classifies statements by their semantic type.\n */\nexport class SQLGrammar {\n /**\n * Determine the execution phase of a SQL statement (1–6).\n *\n * Phase ordering ensures DDL operations run in dependency-safe order\n * regardless of which migration file they originate from.\n *\n * | Phase | Statements |\n * |-------|-----------------------------------------------|\n * | 1 | CREATE EXTENSION, TYPE, DOMAIN, SCHEMA |\n * | 2 | CREATE TABLE |\n * | 3 | ADD COLUMN, ADD PRIMARY KEY |\n * | 4 | CREATE INDEX, ADD FOREIGN KEY |\n * | 5 | DROP COLUMN, ALTER COLUMN, DROP TABLE |\n * | 6 | Raw / unclassified |\n *\n * @example\n * SQLGrammar.phase(\"CREATE EXTENSION IF NOT EXISTS vector\"); // => 1\n * SQLGrammar.phase(\"ALTER TABLE users ADD COLUMN email TEXT\"); // => 3\n */\n public static phase(sql: string): 1 | 2 | 3 | 4 | 5 | 6 {\n const s = sql.trim().toUpperCase();\n\n // Phase 1: Preparation (Extensions, Enums, Domains, Types)\n if (\n s.startsWith(\"CREATE EXTENSION\") ||\n s.startsWith(\"CREATE TYPE\") ||\n s.startsWith(\"CREATE DOMAIN\") ||\n s.startsWith(\"CREATE SCHEMA\")\n ) {\n return 1;\n }\n\n // Phase 2: Table Creation\n if (s.startsWith(\"CREATE TABLE\")) {\n return 2;\n }\n\n // Phase 3 / 4 / 5: ALTER TABLE — broken down by clause\n if (s.startsWith(\"ALTER TABLE\")) {\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"FOREIGN KEY\")) return 4;\n if (s.includes(\"DROP COLUMN\") || s.includes(\"DROP CONSTRAINT\") || s.includes(\"ALTER COLUMN\"))\n return 5;\n if (s.includes(\"ADD COLUMN\")) return 3;\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"PRIMARY KEY\")) return 3;\n }\n\n // Phase 4: Index Creation\n if (s.startsWith(\"CREATE INDEX\") || s.startsWith(\"CREATE UNIQUE INDEX\")) {\n return 4;\n }\n\n // Phase 5: Destructive table/index operations\n if (\n s.startsWith(\"DROP TABLE\") ||\n s.startsWith(\"TRUNCATE TABLE\") ||\n s.startsWith(\"DROP INDEX\")\n ) {\n return 5;\n }\n\n // Phase 6: Raw / unclassified (DML, triggers, procedures, views)\n return 6;\n }\n\n /**\n * Classify a SQL statement into its semantic statement type.\n *\n * This is independent of execution phase — it identifies *what* a statement\n * does, not *when* it should run. Use this for pre-flight checks, dry-run\n * display, selective filtering, and extension detection.\n *\n * @example\n * SQLGrammar.classify(\"CREATE EXTENSION IF NOT EXISTS vector\");\n * // => \"CREATE_EXTENSION\"\n *\n * SQLGrammar.classify(\"ALTER TABLE users ADD COLUMN email TEXT\");\n * // => \"ADD_COLUMN\"\n */\n public static classify(sql: string): SQLStatementType {\n const s = sql.trim().toUpperCase();\n\n if (s.startsWith(\"CREATE EXTENSION\")) return \"CREATE_EXTENSION\";\n if (s.startsWith(\"CREATE SCHEMA\")) return \"CREATE_SCHEMA\";\n if (s.startsWith(\"CREATE TYPE\")) return \"CREATE_TYPE\";\n if (s.startsWith(\"CREATE DOMAIN\")) return \"CREATE_DOMAIN\";\n if (s.startsWith(\"CREATE TABLE\")) return \"CREATE_TABLE\";\n if (s.startsWith(\"DROP TABLE\")) return \"DROP_TABLE\";\n if (s.startsWith(\"TRUNCATE TABLE\")) return \"TRUNCATE_TABLE\";\n if (s.startsWith(\"DROP INDEX\")) return \"DROP_INDEX\";\n\n // Must check UNIQUE before plain INDEX to avoid misclassification\n if (s.startsWith(\"CREATE UNIQUE INDEX\")) return \"CREATE_UNIQUE_INDEX\";\n if (s.startsWith(\"CREATE INDEX\")) return \"CREATE_INDEX\";\n\n if (s.startsWith(\"ALTER TABLE\")) {\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"FOREIGN KEY\")) return \"ADD_FOREIGN_KEY\";\n if (s.includes(\"DROP CONSTRAINT\") && s.includes(\"FOREIGN KEY\")) return \"DROP_FOREIGN_KEY\";\n if (s.includes(\"ADD CONSTRAINT\") && s.includes(\"PRIMARY KEY\")) return \"ADD_PRIMARY_KEY\";\n if (s.includes(\"DROP CONSTRAINT\")) return \"DROP_PRIMARY_KEY\";\n if (s.includes(\"ADD COLUMN\")) return \"ADD_COLUMN\";\n if (s.includes(\"DROP COLUMN\")) return \"DROP_COLUMN\";\n if (s.includes(\"RENAME COLUMN\")) return \"RENAME_COLUMN\";\n if (s.includes(\"RENAME TO\")) return \"RENAME_TABLE\";\n if (s.includes(\"ALTER COLUMN\")) return \"MODIFY_COLUMN\";\n }\n\n return \"RAW\";\n }\n\n /**\n * Extract the extension name from a CREATE EXTENSION statement.\n *\n * Returns undefined if the statement is not a CREATE EXTENSION statement\n * or the name cannot be parsed.\n *\n * @example\n * SQLGrammar.extractExtensionName(\"CREATE EXTENSION IF NOT EXISTS vector\");\n * // => \"vector\"\n *\n * SQLGrammar.extractExtensionName(\"CREATE EXTENSION postgis\");\n * // => \"postgis\"\n */\n public static extractExtensionName(sql: string): string | undefined {\n // Matches: CREATE EXTENSION [IF NOT EXISTS] <name>\n const match = sql.trim().match(/^CREATE\\s+EXTENSION\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(\\w+)/i);\n\n return match?.[1]?.toLowerCase();\n }\n\n /**\n * Sort an array of tagged SQL statements by phase, then creation date, then migration name.\n *\n * This is the sort that decides **execution order** — it runs across every\n * pending migration's statements at once, after the migration list itself\n * has been ordered, so whatever it decides is final.\n *\n * The creation date must go through {@link compareCreatedAt}. Parsing these\n * stamps with `new Date()` returns `Invalid Date` for the framework's own\n * `MM-DD-YYYY_HH-MM-SS` filename format, which collapsed every timestamp to\n * the same value and quietly handed the whole ordering to the alphabetical\n * tiebreaker below — running, for example, a January 2026 migration before a\n * December 2025 one.\n */\n public static sort(statements: TaggedSQL[]): TaggedSQL[] {\n return statements.slice().sort((a, b) => {\n // 1. Sort by Phase (ascending)\n if (a.phase !== b.phase) {\n return a.phase - b.phase;\n }\n\n // 2. Sort by CreatedAt (within same phase)\n const byCreatedAt = compareCreatedAt(a.createdAt, b.createdAt);\n\n if (byCreatedAt !== undefined) {\n return byCreatedAt;\n }\n\n // 3. Sort by Migration Name (tie-breaker)\n const nameA = a.migrationName || \"\";\n const nameB = b.migrationName || \"\";\n return nameA.localeCompare(nameB);\n });\n }\n}\n"],"mappings":";;;;;;;AAOA,IAAa,aAAb,MAAwB;;;;;;;;;;;;;;;;;;;;CAoBtB,OAAc,MAAM,KAAoC;EACtD,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;EAGjC,IACE,EAAE,WAAW,kBAAkB,KAC/B,EAAE,WAAW,aAAa,KAC1B,EAAE,WAAW,eAAe,KAC5B,EAAE,WAAW,eAAe,GAE5B,OAAO;EAIT,IAAI,EAAE,WAAW,cAAc,GAC7B,OAAO;EAIT,IAAI,EAAE,WAAW,aAAa,GAAG;GAC/B,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACtE,IAAI,EAAE,SAAS,aAAa,KAAK,EAAE,SAAS,iBAAiB,KAAK,EAAE,SAAS,cAAc,GACzF,OAAO;GACT,IAAI,EAAE,SAAS,YAAY,GAAG,OAAO;GACrC,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;EACxE;EAGA,IAAI,EAAE,WAAW,cAAc,KAAK,EAAE,WAAW,qBAAqB,GACpE,OAAO;EAIT,IACE,EAAE,WAAW,YAAY,KACzB,EAAE,WAAW,gBAAgB,KAC7B,EAAE,WAAW,YAAY,GAEzB,OAAO;EAIT,OAAO;CACT;;;;;;;;;;;;;;;CAgBA,OAAc,SAAS,KAA+B;EACpD,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;EAEjC,IAAI,EAAE,WAAW,kBAAkB,GAAG,OAAO;EAC7C,IAAI,EAAE,WAAW,eAAe,GAAG,OAAO;EAC1C,IAAI,EAAE,WAAW,aAAa,GAAG,OAAO;EACxC,IAAI,EAAE,WAAW,eAAe,GAAG,OAAO;EAC1C,IAAI,EAAE,WAAW,cAAc,GAAG,OAAO;EACzC,IAAI,EAAE,WAAW,YAAY,GAAG,OAAO;EACvC,IAAI,EAAE,WAAW,gBAAgB,GAAG,OAAO;EAC3C,IAAI,EAAE,WAAW,YAAY,GAAG,OAAO;EAGvC,IAAI,EAAE,WAAW,qBAAqB,GAAG,OAAO;EAChD,IAAI,EAAE,WAAW,cAAc,GAAG,OAAO;EAEzC,IAAI,EAAE,WAAW,aAAa,GAAG;GAC/B,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACtE,IAAI,EAAE,SAAS,iBAAiB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACvE,IAAI,EAAE,SAAS,gBAAgB,KAAK,EAAE,SAAS,aAAa,GAAG,OAAO;GACtE,IAAI,EAAE,SAAS,iBAAiB,GAAG,OAAO;GAC1C,IAAI,EAAE,SAAS,YAAY,GAAG,OAAO;GACrC,IAAI,EAAE,SAAS,aAAa,GAAG,OAAO;GACtC,IAAI,EAAE,SAAS,eAAe,GAAG,OAAO;GACxC,IAAI,EAAE,SAAS,WAAW,GAAG,OAAO;GACpC,IAAI,EAAE,SAAS,cAAc,GAAG,OAAO;EACzC;EAEA,OAAO;CACT;;;;;;;;;;;;;;CAeA,OAAc,qBAAqB,KAAiC;EAIlE,OAFc,IAAI,KAAK,CAAC,CAAC,MAAM,uDAEpB,CAAC,GAAG,EAAE,EAAE,YAAY;CACjC;;;;;;;;;;;;;;;CAgBA,OAAc,KAAK,YAAsC;EACvD,OAAO,WAAW,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM;GAEvC,IAAI,EAAE,UAAU,EAAE,OAChB,OAAO,EAAE,QAAQ,EAAE;GAIrB,MAAM,cAAc,iBAAiB,EAAE,WAAW,EAAE,SAAS;GAE7D,IAAI,gBAAgB,QAClB,OAAO;GAIT,MAAM,QAAQ,EAAE,iBAAiB;GACjC,MAAM,QAAQ,EAAE,iBAAiB;GACjC,OAAO,MAAM,cAAc,KAAK;EAClC,CAAC;CACH;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { PendingOperation } from "./migration.mjs";
2
2
 
3
- //#region ../cascade/src/migration/sql-serializer.d.ts
3
+ //#region ../../packages/cascade/src/migration/sql-serializer.d.ts
4
4
  /**
5
5
  * Converts PendingOperation objects to SQL strings for a specific dialect.
6
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"sql-serializer.d.mts","names":[],"sources":["../../../../../../../cascade/src/migration/sql-serializer.ts"],"mappings":";;;;;AAKA;uBAAsB,aAAA;;;;;;;;WAQX,SAAA,CAAU,SAAA,EAAW,gBAAA,EAAkB,KAAA;EAQnC;;;AAA6C;;;EAA1D,YAAA,CAAa,UAAA,EAAY,gBAAgB,IAAI,KAAA;AAAA"}
1
+ {"version":3,"file":"sql-serializer.d.mts","names":[],"sources":["../../../../../../../../packages/cascade/src/migration/sql-serializer.ts"],"mappings":";;;;;AAKA;uBAAsB,aAAA;;;;;;;;WAQX,SAAA,CAAU,SAAA,EAAW,gBAAA,EAAkB,KAAA;EAQnC;;;AAA6C;;;EAA1D,YAAA,CAAa,UAAA,EAAY,gBAAgB,IAAI,KAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/migration/sql-serializer.ts
1
+ //#region ../../packages/cascade/src/migration/sql-serializer.ts
2
2
  /**
3
3
  * Converts PendingOperation objects to SQL strings for a specific dialect.
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"sql-serializer.mjs","names":[],"sources":["../../../../../../../cascade/src/migration/sql-serializer.ts"],"sourcesContent":["import type { PendingOperation } from \"./migration\";\n\n/**\n * Converts PendingOperation objects to SQL strings for a specific dialect.\n */\nexport abstract class SQLSerializer {\n /**\n * Serialize a single pending operation into one or more SQL strings.\n *\n * Return `string` for single-statement operations, `string[]` for\n * multi-statement ones (e.g. `createTimestamps` emits two ALTER TABLE\n * statements), and `null` for no-ops.\n */\n abstract serialize(operation: PendingOperation, table: string): string | string[] | null;\n\n /**\n * Serialize an array of operations to a flat list of SQL strings.\n *\n * Array results from serialize() are automatically flattened, and nulls\n * (no-ops) are filtered out.\n */\n serializeAll(operations: PendingOperation[], table: string): string[] {\n const result: string[] = [];\n\n for (const op of operations) {\n const sql = this.serialize(op, table);\n if (sql === null) continue;\n if (Array.isArray(sql)) {\n result.push(...sql);\n } else {\n result.push(sql);\n }\n }\n\n return result;\n }\n}\n"],"mappings":";;;;AAKA,IAAsB,gBAAtB,MAAoC;;;;;;;CAgBlC,aAAa,YAAgC,OAAyB;EACpE,MAAM,SAAmB,CAAC;EAE1B,KAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,MAAM,KAAK,UAAU,IAAI,KAAK;GACpC,IAAI,QAAQ,MAAM;GAClB,IAAI,MAAM,QAAQ,GAAG,GACnB,OAAO,KAAK,GAAG,GAAG;QAElB,OAAO,KAAK,GAAG;EAEnB;EAEA,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"sql-serializer.mjs","names":[],"sources":["../../../../../../../../packages/cascade/src/migration/sql-serializer.ts"],"sourcesContent":["import type { PendingOperation } from \"./migration\";\n\n/**\n * Converts PendingOperation objects to SQL strings for a specific dialect.\n */\nexport abstract class SQLSerializer {\n /**\n * Serialize a single pending operation into one or more SQL strings.\n *\n * Return `string` for single-statement operations, `string[]` for\n * multi-statement ones (e.g. `createTimestamps` emits two ALTER TABLE\n * statements), and `null` for no-ops.\n */\n abstract serialize(operation: PendingOperation, table: string): string | string[] | null;\n\n /**\n * Serialize an array of operations to a flat list of SQL strings.\n *\n * Array results from serialize() are automatically flattened, and nulls\n * (no-ops) are filtered out.\n */\n serializeAll(operations: PendingOperation[], table: string): string[] {\n const result: string[] = [];\n\n for (const op of operations) {\n const sql = this.serialize(op, table);\n if (sql === null) continue;\n if (Array.isArray(sql)) {\n result.push(...sql);\n } else {\n result.push(sql);\n }\n }\n\n return result;\n }\n}\n"],"mappings":";;;;AAKA,IAAsB,gBAAtB,MAAoC;;;;;;;CAgBlC,aAAa,YAAgC,OAAyB;EACpE,MAAM,SAAmB,CAAC;EAE1B,KAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,MAAM,KAAK,UAAU,IAAI,KAAK;GACpC,IAAI,QAAQ,MAAM;GAClB,IAAI,MAAM,QAAQ,GAAG,GACnB,OAAO,KAAK,GAAG,GAAG;QAElB,OAAO,KAAK,GAAG;EAEnB;EAEA,OAAO;CACT;AACF"}
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/migration/types.d.ts
1
+ //#region ../../packages/cascade/src/migration/types.d.ts
2
2
  /**
3
3
  * Result of a single migration execution.
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../cascade/src/migration/types.ts"],"mappings":";;;AAKA;UAAiB,eAAA;;WAEN,IAAA;EAAA;EAAA,SAEA,KAAA;EAEA;EAAA,SAAA,SAAA;EAIA;EAAA,SAFA,OAAA;EAMA;EAAA,SAJA,KAAA;EAIgB;EAAA,SAFhB,UAAA;EAQM;EAAA,SANN,UAAA,EAAY,IAAI;AAAA;;;;UAMV,eAAA;EAQN;EAAA,SANA,IAAA;EAQY;EAAA,SANZ,KAAA;EAQQ;EAAA,SANR,QAAA;EA4BM;EAAA,SA1BN,KAAA;;WAEA,UAAA,EAAY,IAAI;EA0BzB;EAAA,SAxBS,QAAA;AAAA;AAoEO;AAMlB;;AANkB,UA9CD,eAAA;EAyDN;EAvDT,IAAA;EAkEe;EAhEf,KAAA;;EAEA,UAAA,EAAY,IAAA;EAoEH;EAlET,SAAA,EAAW,IAAI;AAAA;;AA4EA;;UAtEA,sBAAA;;;;;;WAMN,OAAA;;;;WAKA,SAAA;;;;;;WAOA,eAAA;;;;;;WAOA,MAAA;;;;;;WAOA,OAAA;AAAA;;;;UAMM,oBAAA;;;;;WAKN,IAAA;;;;WAKA,MAAM;AAAA;;;;UAMA,eAAA;;;;;;WAMN,OAAA;;;;WAKA,IAAA;;;;WAKA,MAAA;AAAA"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../../packages/cascade/src/migration/types.ts"],"mappings":";;;AAKA;UAAiB,eAAA;;WAEN,IAAA;EAAA;EAAA,SAEA,KAAA;EAEA;EAAA,SAAA,SAAA;EAIA;EAAA,SAFA,OAAA;EAMA;EAAA,SAJA,KAAA;EAIgB;EAAA,SAFhB,UAAA;EAQM;EAAA,SANN,UAAA,EAAY,IAAI;AAAA;;;;UAMV,eAAA;EAQN;EAAA,SANA,IAAA;EAQY;EAAA,SANZ,KAAA;EAQQ;EAAA,SANR,QAAA;EA4BM;EAAA,SA1BN,KAAA;;WAEA,UAAA,EAAY,IAAI;EA0BzB;EAAA,SAxBS,QAAA;AAAA;AAoEO;AAMlB;;AANkB,UA9CD,eAAA;EAyDN;EAvDT,IAAA;EAkEe;EAhEf,KAAA;;EAEA,UAAA,EAAY,IAAA;EAoEH;EAlET,SAAA,EAAW,IAAI;AAAA;;AA4EA;;UAtEA,sBAAA;;;;;;WAMN,OAAA;;;;WAKA,SAAA;;;;;;WAOA,eAAA;;;;;;WAOA,MAAA;;;;;;WAOA,OAAA;AAAA;;;;UAMM,oBAAA;;;;;WAKN,IAAA;;;;WAKA,MAAM;AAAA;;;;UAMA,eAAA;;;;;;WAMN,OAAA;;;;WAKA,IAAA;;;;WAKA,MAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/model/generate-model-id.ts
1
+ //#region ../../packages/cascade/src/model/generate-model-id.ts
2
2
  /**
3
3
  * Generate the next model id using the model's configured sequence options.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"generate-model-id.mjs","names":[],"sources":["../../../../../../../cascade/src/model/generate-model-id.ts"],"sourcesContent":["import type { ChildModel, Model } from \"./model\";\n\n/**\n * Generate the next model id using the model's configured sequence options.\n *\n * This is shared by normal inserts and MongoDB upserts so both write paths\n * resolve random and configured sequence settings identically.\n */\nexport async function generateModelId<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n): Promise<number | undefined> {\n const idGenerator = ModelClass.getDataSource().idGenerator;\n\n if (!idGenerator) {\n return undefined;\n }\n\n const randomInt = (min: number, max: number) =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n const initialId = ModelClass.initialId\n ? ModelClass.initialId\n : ModelClass.randomInitialId\n ? typeof ModelClass.randomInitialId === \"function\"\n ? ModelClass.randomInitialId()\n : randomInt(10000, 499999)\n : 1;\n const incrementIdBy = ModelClass.randomIncrement\n ? typeof ModelClass.randomIncrement === \"function\"\n ? ModelClass.randomIncrement()\n : randomInt(1, 10)\n : ModelClass.incrementIdBy || 1;\n\n return await idGenerator.generateNextId({\n table: ModelClass.table,\n initialId,\n incrementIdBy,\n });\n}\n"],"mappings":";;;;;;;AAQA,eAAsB,gBACpB,YAC6B;CAC7B,MAAM,cAAc,WAAW,cAAc,CAAC,CAAC;CAE/C,IAAI,CAAC,aACH;CAGF,MAAM,aAAa,KAAa,QAC9B,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;CAChD,MAAM,YAAY,WAAW,YACzB,WAAW,YACX,WAAW,kBACT,OAAO,WAAW,oBAAoB,aACpC,WAAW,gBAAgB,IAC3B,UAAU,KAAO,MAAM,IACzB;CACN,MAAM,gBAAgB,WAAW,kBAC7B,OAAO,WAAW,oBAAoB,aACpC,WAAW,gBAAgB,IAC3B,UAAU,GAAG,EAAE,IACjB,WAAW,iBAAiB;CAEhC,OAAO,MAAM,YAAY,eAAe;EACtC,OAAO,WAAW;EAClB;EACA;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"generate-model-id.mjs","names":[],"sources":["../../../../../../../../packages/cascade/src/model/generate-model-id.ts"],"sourcesContent":["import type { ChildModel, Model } from \"./model\";\n\n/**\n * Generate the next model id using the model's configured sequence options.\n *\n * This is shared by normal inserts and MongoDB upserts so both write paths\n * resolve random and configured sequence settings identically.\n */\nexport async function generateModelId<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n): Promise<number | undefined> {\n const idGenerator = ModelClass.getDataSource().idGenerator;\n\n if (!idGenerator) {\n return undefined;\n }\n\n const randomInt = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min;\n const initialId = ModelClass.initialId\n ? ModelClass.initialId\n : ModelClass.randomInitialId\n ? typeof ModelClass.randomInitialId === \"function\"\n ? ModelClass.randomInitialId()\n : randomInt(10000, 499999)\n : 1;\n const incrementIdBy = ModelClass.randomIncrement\n ? typeof ModelClass.randomIncrement === \"function\"\n ? ModelClass.randomIncrement()\n : randomInt(1, 10)\n : ModelClass.incrementIdBy || 1;\n\n return await idGenerator.generateNextId({\n table: ModelClass.table,\n initialId,\n incrementIdBy,\n });\n}\n"],"mappings":";;;;;;;AAQA,eAAsB,gBACpB,YAC6B;CAC7B,MAAM,cAAc,WAAW,cAAc,CAAC,CAAC;CAE/C,IAAI,CAAC,aACH;CAGF,MAAM,aAAa,KAAa,QAAgB,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;CAC9F,MAAM,YAAY,WAAW,YACzB,WAAW,YACX,WAAW,kBACT,OAAO,WAAW,oBAAoB,aACpC,WAAW,gBAAgB,IAC3B,UAAU,KAAO,MAAM,IACzB;CACN,MAAM,gBAAgB,WAAW,kBAC7B,OAAO,WAAW,oBAAoB,aACpC,WAAW,gBAAgB,IAC3B,UAAU,GAAG,EAAE,IACjB,WAAW,iBAAiB;CAEhC,OAAO,MAAM,YAAY,eAAe;EACtC,OAAO,WAAW;EAClB;EACA;CACF,CAAC;AACH"}
@@ -1,7 +1,7 @@
1
1
  import { pruneEmptyParents } from "../../utils/prune-empty-parents.mjs";
2
2
  import { get, merge, only, set, unset } from "@mongez/reinforcements";
3
3
 
4
- //#region ../cascade/src/model/methods/accessor-methods.ts
4
+ //#region ../../packages/cascade/src/model/methods/accessor-methods.ts
5
5
  /**
6
6
  * Sentinel symbol to distinguish a genuinely missing field from a field
7
7
  * whose value is `undefined`. Encapsulated here — callers use `hasField()`.
@@ -1 +1 @@
1
- {"version":3,"file":"accessor-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/accessor-methods.ts"],"sourcesContent":["import { get, merge, only, set, unset } from \"@mongez/reinforcements\";\nimport { pruneEmptyParents } from \"../../utils/prune-empty-parents\";\nimport type { Model } from \"../model\";\n\n/**\n * Sentinel symbol to distinguish a genuinely missing field from a field\n * whose value is `undefined`. Encapsulated here — callers use `hasField()`.\n */\nconst MISSING_VALUE = Symbol(\"missing\");\n\nexport function getFieldValue(model: Model, field: string, defaultValue?: unknown): any {\n return get(model.data, field, defaultValue);\n}\n\nexport function setFieldValue(model: Model, field: string, value: unknown): Model {\n const path = String(field);\n set(model.data, path, value);\n\n model.dirtyTracker.setAtPath(path, value);\n\n return model;\n}\n\nexport function hasField(model: Model, field: string): boolean {\n return get(model.data, field, MISSING_VALUE as any) !== MISSING_VALUE;\n}\n\nexport function incrementField(model: Model, field: string, amount?: number): Model {\n const value = getFieldValue(model, field, 0) as number;\n const incrementedValue = value + (amount ?? 1);\n return setFieldValue(model, field, incrementedValue);\n}\n\nexport function decrementField(model: Model, field: string, amount?: number): Model {\n const value = getFieldValue(model, field, 0) as number;\n const decrementedValue = value - (amount ?? 1);\n return setFieldValue(model, field, decrementedValue);\n}\n\n/**\n * Remove fields from the model data.\n *\n * Unsetting the last key of a nested object also removes the parents that this\n * unset left empty (`unset(\"a.b\")` on `{ a: { b: 1 } }` leaves `{}`, not\n * `{ a: {} }`). A parent is pruned only when this unset emptied it: an object\n * the user stored as `{}` is never touched, and arrays are never pruned.\n */\nexport function unsetFields(model: Model, ...fields: string[]): Model {\n const existing = fields.filter(field => hasField(model, field));\n\n model.data = unset(model.data, fields);\n\n for (const field of existing) {\n pruneEmptyParents(model.data, field);\n }\n\n model.dirtyTracker.unset(fields);\n\n return model;\n}\n\n/**\n * Identity columns that a mass-assignment payload may never carry into an\n * already-persisted model. `merge()` is the method request bodies reach\n * (`model.merge(req.body)` / `save({ merge })`), and the primary key is what\n * the UPDATE filter is built from — letting it through means a payload of\n * `{ id: \"<victim-id>\" }` rewrites which document the save targets. Both the\n * configured primary key and the two framework identity columns are dropped,\n * because `id` and `_id` are managed by the writer/driver either way.\n *\n * A NEW model is untouched: creating with an explicit id is a legitimate flow,\n * and the writer itself merges the driver-returned document (`_id`, defaults)\n * back onto the instance before it is marked persisted.\n */\nfunction stripIdentityColumns(\n model: Model,\n values: Record<string, unknown>,\n): Record<string, unknown> {\n if (model.isNew) return values;\n\n const identityColumns = new Set([model.getPrimaryKey(), \"id\", \"_id\"]);\n const blockedKeys = Object.keys(values).filter(key => identityColumns.has(key));\n\n if (blockedKeys.length === 0) return values;\n\n // Copy — the caller's object (often the request body itself) is not ours to mutate.\n const safeValues = { ...values };\n for (const key of blockedKeys) {\n delete safeValues[key];\n }\n\n return safeValues;\n}\n\nexport function mergeFields(model: Model, values: Record<string, unknown>): Model {\n return mergeDriverFields(model, stripIdentityColumns(model, values));\n}\n\n/**\n * Merge a document the DRIVER produced (generated `_id`, `RETURNING *`, DB\n * defaults) back onto the model, identity columns included.\n *\n * Framework-internal counterpart of {@link mergeFields}: the write pipeline is\n * the one caller allowed to set identity columns on an already-persisted\n * instance, because the values come from the database rather than from a\n * request. Never route caller-supplied data through this.\n */\nexport function mergeDriverFields(model: Model, values: Record<string, unknown>): Model {\n model.data = merge(model.data, values) as any;\n model.dirtyTracker.mergeChanges(values);\n return model;\n}\n\nexport function getOnlyFields(model: Model, fields: string[]): Record<string, unknown> {\n return only(model.data, fields);\n}\n\nexport function getStringField(model: Model, key: string, defaultValue?: string): string | undefined {\n return getFieldValue(model, key, defaultValue) as string | undefined;\n}\n\nexport function getNumberField(model: Model, key: string, defaultValue?: number): number | undefined {\n return getFieldValue(model, key, defaultValue) as number | undefined;\n}\n\nexport function getBooleanField(model: Model, key: string, defaultValue?: boolean): boolean | undefined {\n return getFieldValue(model, key, defaultValue) as boolean | undefined;\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,gBAAgB,OAAO,SAAS;AAEtC,SAAgB,cAAc,OAAc,OAAe,cAA6B;CACtF,OAAO,IAAI,MAAM,MAAM,OAAO,YAAY;AAC5C;AAEA,SAAgB,cAAc,OAAc,OAAe,OAAuB;CAChF,MAAM,OAAO,OAAO,KAAK;CACzB,IAAI,MAAM,MAAM,MAAM,KAAK;CAE3B,MAAM,aAAa,UAAU,MAAM,KAAK;CAExC,OAAO;AACT;AAEA,SAAgB,SAAS,OAAc,OAAwB;CAC7D,OAAO,IAAI,MAAM,MAAM,OAAO,aAAoB,MAAM;AAC1D;AAEA,SAAgB,eAAe,OAAc,OAAe,QAAwB;CAGlF,OAAO,cAAc,OAAO,OAFd,cAAc,OAAO,OAAO,CACb,KAAK,UAAU,EACO;AACrD;AAEA,SAAgB,eAAe,OAAc,OAAe,QAAwB;CAGlF,OAAO,cAAc,OAAO,OAFd,cAAc,OAAO,OAAO,CACb,KAAK,UAAU,EACO;AACrD;;;;;;;;;AAUA,SAAgB,YAAY,OAAc,GAAG,QAAyB;CACpE,MAAM,WAAW,OAAO,QAAO,UAAS,SAAS,OAAO,KAAK,CAAC;CAE9D,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM;CAErC,KAAK,MAAM,SAAS,UAClB,kBAAkB,MAAM,MAAM,KAAK;CAGrC,MAAM,aAAa,MAAM,MAAM;CAE/B,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAS,qBACP,OACA,QACyB;CACzB,IAAI,MAAM,OAAO,OAAO;CAExB,MAAM,kBAAkB,IAAI,IAAI;EAAC,MAAM,cAAc;EAAG;EAAM;CAAK,CAAC;CACpE,MAAM,cAAc,OAAO,KAAK,MAAM,CAAC,CAAC,QAAO,QAAO,gBAAgB,IAAI,GAAG,CAAC;CAE9E,IAAI,YAAY,WAAW,GAAG,OAAO;CAGrC,MAAM,aAAa,EAAE,GAAG,OAAO;CAC/B,KAAK,MAAM,OAAO,aAChB,OAAO,WAAW;CAGpB,OAAO;AACT;AAEA,SAAgB,YAAY,OAAc,QAAwC;CAChF,OAAO,kBAAkB,OAAO,qBAAqB,OAAO,MAAM,CAAC;AACrE;;;;;;;;;;AAWA,SAAgB,kBAAkB,OAAc,QAAwC;CACtF,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM;CACrC,MAAM,aAAa,aAAa,MAAM;CACtC,OAAO;AACT;AAEA,SAAgB,cAAc,OAAc,QAA2C;CACrF,OAAO,KAAK,MAAM,MAAM,MAAM;AAChC;AAEA,SAAgB,eAAe,OAAc,KAAa,cAA2C;CACnG,OAAO,cAAc,OAAO,KAAK,YAAY;AAC/C;AAEA,SAAgB,eAAe,OAAc,KAAa,cAA2C;CACnG,OAAO,cAAc,OAAO,KAAK,YAAY;AAC/C;AAEA,SAAgB,gBAAgB,OAAc,KAAa,cAA6C;CACtG,OAAO,cAAc,OAAO,KAAK,YAAY;AAC/C"}
1
+ {"version":3,"file":"accessor-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/accessor-methods.ts"],"sourcesContent":["import { get, merge, only, set, unset } from \"@mongez/reinforcements\";\nimport { pruneEmptyParents } from \"../../utils/prune-empty-parents\";\nimport type { Model } from \"../model\";\n\n/**\n * Sentinel symbol to distinguish a genuinely missing field from a field\n * whose value is `undefined`. Encapsulated here — callers use `hasField()`.\n */\nconst MISSING_VALUE = Symbol(\"missing\");\n\nexport function getFieldValue(model: Model, field: string, defaultValue?: unknown): any {\n return get(model.data, field, defaultValue);\n}\n\nexport function setFieldValue(model: Model, field: string, value: unknown): Model {\n const path = String(field);\n set(model.data, path, value);\n\n model.dirtyTracker.setAtPath(path, value);\n\n return model;\n}\n\nexport function hasField(model: Model, field: string): boolean {\n return get(model.data, field, MISSING_VALUE as any) !== MISSING_VALUE;\n}\n\nexport function incrementField(model: Model, field: string, amount?: number): Model {\n const value = getFieldValue(model, field, 0) as number;\n const incrementedValue = value + (amount ?? 1);\n return setFieldValue(model, field, incrementedValue);\n}\n\nexport function decrementField(model: Model, field: string, amount?: number): Model {\n const value = getFieldValue(model, field, 0) as number;\n const decrementedValue = value - (amount ?? 1);\n return setFieldValue(model, field, decrementedValue);\n}\n\n/**\n * Remove fields from the model data.\n *\n * Unsetting the last key of a nested object also removes the parents that this\n * unset left empty (`unset(\"a.b\")` on `{ a: { b: 1 } }` leaves `{}`, not\n * `{ a: {} }`). A parent is pruned only when this unset emptied it: an object\n * the user stored as `{}` is never touched, and arrays are never pruned.\n */\nexport function unsetFields(model: Model, ...fields: string[]): Model {\n const existing = fields.filter((field) => hasField(model, field));\n\n model.data = unset(model.data, fields);\n\n for (const field of existing) {\n pruneEmptyParents(model.data, field);\n }\n\n model.dirtyTracker.unset(fields);\n\n return model;\n}\n\n/**\n * Identity columns that a mass-assignment payload may never carry into an\n * already-persisted model. `merge()` is the method request bodies reach\n * (`model.merge(req.body)` / `save({ merge })`), and the primary key is what\n * the UPDATE filter is built from — letting it through means a payload of\n * `{ id: \"<victim-id>\" }` rewrites which document the save targets. Both the\n * configured primary key and the two framework identity columns are dropped,\n * because `id` and `_id` are managed by the writer/driver either way.\n *\n * A NEW model is untouched: creating with an explicit id is a legitimate flow,\n * and the writer itself merges the driver-returned document (`_id`, defaults)\n * back onto the instance before it is marked persisted.\n */\nfunction stripIdentityColumns(\n model: Model,\n values: Record<string, unknown>,\n): Record<string, unknown> {\n if (model.isNew) return values;\n\n const identityColumns = new Set([model.getPrimaryKey(), \"id\", \"_id\"]);\n const blockedKeys = Object.keys(values).filter((key) => identityColumns.has(key));\n\n if (blockedKeys.length === 0) return values;\n\n // Copy — the caller's object (often the request body itself) is not ours to mutate.\n const safeValues = { ...values };\n for (const key of blockedKeys) {\n delete safeValues[key];\n }\n\n return safeValues;\n}\n\nexport function mergeFields(model: Model, values: Record<string, unknown>): Model {\n return mergeDriverFields(model, stripIdentityColumns(model, values));\n}\n\n/**\n * Merge a document the DRIVER produced (generated `_id`, `RETURNING *`, DB\n * defaults) back onto the model, identity columns included.\n *\n * Framework-internal counterpart of {@link mergeFields}: the write pipeline is\n * the one caller allowed to set identity columns on an already-persisted\n * instance, because the values come from the database rather than from a\n * request. Never route caller-supplied data through this.\n */\nexport function mergeDriverFields(model: Model, values: Record<string, unknown>): Model {\n model.data = merge(model.data, values) as any;\n model.dirtyTracker.mergeChanges(values);\n return model;\n}\n\nexport function getOnlyFields(model: Model, fields: string[]): Record<string, unknown> {\n return only(model.data, fields);\n}\n\nexport function getStringField(\n model: Model,\n key: string,\n defaultValue?: string,\n): string | undefined {\n return getFieldValue(model, key, defaultValue) as string | undefined;\n}\n\nexport function getNumberField(\n model: Model,\n key: string,\n defaultValue?: number,\n): number | undefined {\n return getFieldValue(model, key, defaultValue) as number | undefined;\n}\n\nexport function getBooleanField(\n model: Model,\n key: string,\n defaultValue?: boolean,\n): boolean | undefined {\n return getFieldValue(model, key, defaultValue) as boolean | undefined;\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,gBAAgB,OAAO,SAAS;AAEtC,SAAgB,cAAc,OAAc,OAAe,cAA6B;CACtF,OAAO,IAAI,MAAM,MAAM,OAAO,YAAY;AAC5C;AAEA,SAAgB,cAAc,OAAc,OAAe,OAAuB;CAChF,MAAM,OAAO,OAAO,KAAK;CACzB,IAAI,MAAM,MAAM,MAAM,KAAK;CAE3B,MAAM,aAAa,UAAU,MAAM,KAAK;CAExC,OAAO;AACT;AAEA,SAAgB,SAAS,OAAc,OAAwB;CAC7D,OAAO,IAAI,MAAM,MAAM,OAAO,aAAoB,MAAM;AAC1D;AAEA,SAAgB,eAAe,OAAc,OAAe,QAAwB;CAGlF,OAAO,cAAc,OAAO,OAFd,cAAc,OAAO,OAAO,CACb,KAAK,UAAU,EACO;AACrD;AAEA,SAAgB,eAAe,OAAc,OAAe,QAAwB;CAGlF,OAAO,cAAc,OAAO,OAFd,cAAc,OAAO,OAAO,CACb,KAAK,UAAU,EACO;AACrD;;;;;;;;;AAUA,SAAgB,YAAY,OAAc,GAAG,QAAyB;CACpE,MAAM,WAAW,OAAO,QAAQ,UAAU,SAAS,OAAO,KAAK,CAAC;CAEhE,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM;CAErC,KAAK,MAAM,SAAS,UAClB,kBAAkB,MAAM,MAAM,KAAK;CAGrC,MAAM,aAAa,MAAM,MAAM;CAE/B,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAS,qBACP,OACA,QACyB;CACzB,IAAI,MAAM,OAAO,OAAO;CAExB,MAAM,kBAAkB,IAAI,IAAI;EAAC,MAAM,cAAc;EAAG;EAAM;CAAK,CAAC;CACpE,MAAM,cAAc,OAAO,KAAK,MAAM,CAAC,CAAC,QAAQ,QAAQ,gBAAgB,IAAI,GAAG,CAAC;CAEhF,IAAI,YAAY,WAAW,GAAG,OAAO;CAGrC,MAAM,aAAa,EAAE,GAAG,OAAO;CAC/B,KAAK,MAAM,OAAO,aAChB,OAAO,WAAW;CAGpB,OAAO;AACT;AAEA,SAAgB,YAAY,OAAc,QAAwC;CAChF,OAAO,kBAAkB,OAAO,qBAAqB,OAAO,MAAM,CAAC;AACrE;;;;;;;;;;AAWA,SAAgB,kBAAkB,OAAc,QAAwC;CACtF,MAAM,OAAO,MAAM,MAAM,MAAM,MAAM;CACrC,MAAM,aAAa,aAAa,MAAM;CACtC,OAAO;AACT;AAEA,SAAgB,cAAc,OAAc,QAA2C;CACrF,OAAO,KAAK,MAAM,MAAM,MAAM;AAChC;AAEA,SAAgB,eACd,OACA,KACA,cACoB;CACpB,OAAO,cAAc,OAAO,KAAK,YAAY;AAC/C;AAEA,SAAgB,eACd,OACA,KACA,cACoB;CACpB,OAAO,cAAc,OAAO,KAAK,YAAY;AAC/C;AAEA,SAAgB,gBACd,OACA,KACA,cACqB;CACrB,OAAO,cAAc,OAAO,KAAK,YAAY;AAC/C"}
@@ -1,7 +1,7 @@
1
1
  import { DatabaseRemover } from "../../remover/database-remover.mjs";
2
2
  import { sanitizeFilter } from "../../utils/sanitize-filter.mjs";
3
3
 
4
- //#region ../cascade/src/model/methods/delete-methods.ts
4
+ //#region ../../packages/cascade/src/model/methods/delete-methods.ts
5
5
  async function destroyModel(model, options) {
6
6
  return new DatabaseRemover(model).destroy(options);
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"delete-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/delete-methods.ts"],"sourcesContent":["import { DatabaseRemover } from \"../../remover/database-remover\";\nimport type { DeleteStrategy } from \"../../types\";\nimport type { RemoverResult } from \"../../contracts\";\nimport { sanitizeFilter } from \"../../utils/sanitize-filter\";\nimport type { ChildModel, Model } from \"../model\";\n\nexport async function destroyModel(\n model: Model,\n options?: { strategy?: DeleteStrategy; skipEvents?: boolean },\n): Promise<RemoverResult> {\n const remover = new DatabaseRemover(model);\n return remover.destroy(options);\n}\n\nexport async function deleteRecords(\n ModelClass: ChildModel<any>,\n filter?: Record<string, unknown>,\n): Promise<number> {\n const sanitized = filter ? sanitizeFilter(filter) : undefined;\n\n if (!sanitized || Object.keys(sanitized).length === 0) {\n throw new Error(\n `${ModelClass.name}.delete() requires a filter: pass an explicit filter, or use ${ModelClass.name}.deleteAll() / ${ModelClass.name}.query().delete() to delete every row.`,\n );\n }\n\n // Through the query builder so global scopes (tenant, soft delete) apply.\n return ModelClass.query().where(sanitized).delete();\n}\n\n/** Delete every row visible to the model's global scopes. Explicit on purpose. */\nexport async function deleteAllRecords(ModelClass: ChildModel<any>): Promise<number> {\n return ModelClass.query().delete();\n}\n\nexport async function deleteOneRecord(\n ModelClass: ChildModel<any>,\n filter?: Record<string, unknown>,\n): Promise<number> {\n const query = ModelClass.query();\n\n if (filter && Object.keys(filter).length > 0) {\n query.where(sanitizeFilter(filter));\n }\n\n return query.deleteOne();\n}\n"],"mappings":";;;;AAMA,eAAsB,aACpB,OACA,SACwB;CAExB,OAAO,IADa,gBAAgB,KACvB,CAAC,CAAC,QAAQ,OAAO;AAChC;AAEA,eAAsB,cACpB,YACA,QACiB;CACjB,MAAM,YAAY,SAAS,eAAe,MAAM,IAAI;CAEpD,IAAI,CAAC,aAAa,OAAO,KAAK,SAAS,CAAC,CAAC,WAAW,GAClD,MAAM,IAAI,MACR,GAAG,WAAW,KAAK,+DAA+D,WAAW,KAAK,iBAAiB,WAAW,KAAK,uCACrI;CAIF,OAAO,WAAW,MAAM,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO;AACpD;AAOA,eAAsB,gBACpB,YACA,QACiB;CACjB,MAAM,QAAQ,WAAW,MAAM;CAE/B,IAAI,UAAU,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,GACzC,MAAM,MAAM,eAAe,MAAM,CAAC;CAGpC,OAAO,MAAM,UAAU;AACzB"}
1
+ {"version":3,"file":"delete-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/delete-methods.ts"],"sourcesContent":["import { DatabaseRemover } from \"../../remover/database-remover\";\nimport type { DeleteStrategy } from \"../../types\";\nimport type { RemoverResult } from \"../../contracts\";\nimport { sanitizeFilter } from \"../../utils/sanitize-filter\";\nimport type { ChildModel, Model } from \"../model\";\n\nexport async function destroyModel(\n model: Model,\n options?: { strategy?: DeleteStrategy; skipEvents?: boolean },\n): Promise<RemoverResult> {\n const remover = new DatabaseRemover(model);\n return remover.destroy(options);\n}\n\nexport async function deleteRecords(\n ModelClass: ChildModel<any>,\n filter?: Record<string, unknown>,\n): Promise<number> {\n const sanitized = filter ? sanitizeFilter(filter) : undefined;\n\n if (!sanitized || Object.keys(sanitized).length === 0) {\n throw new Error(\n `${ModelClass.name}.delete() requires a filter: pass an explicit filter, or use ${ModelClass.name}.deleteAll() / ${ModelClass.name}.query().delete() to delete every row.`,\n );\n }\n\n // Through the query builder so global scopes (tenant, soft delete) apply.\n return ModelClass.query().where(sanitized).delete();\n}\n\n/** Delete every row visible to the model's global scopes. Explicit on purpose. */\nexport async function deleteAllRecords(ModelClass: ChildModel<any>): Promise<number> {\n return ModelClass.query().delete();\n}\n\nexport async function deleteOneRecord(\n ModelClass: ChildModel<any>,\n filter?: Record<string, unknown>,\n): Promise<number> {\n const query = ModelClass.query();\n\n if (filter && Object.keys(filter).length > 0) {\n query.where(sanitizeFilter(filter));\n }\n\n return query.deleteOne();\n}\n"],"mappings":";;;;AAMA,eAAsB,aACpB,OACA,SACwB;CAExB,OAAO,IADa,gBAAgB,KACvB,CAAC,CAAC,QAAQ,OAAO;AAChC;AAEA,eAAsB,cACpB,YACA,QACiB;CACjB,MAAM,YAAY,SAAS,eAAe,MAAM,IAAI;CAEpD,IAAI,CAAC,aAAa,OAAO,KAAK,SAAS,CAAC,CAAC,WAAW,GAClD,MAAM,IAAI,MACR,GAAG,WAAW,KAAK,+DAA+D,WAAW,KAAK,iBAAiB,WAAW,KAAK,uCACrI;CAIF,OAAO,WAAW,MAAM,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO;AACpD;AAOA,eAAsB,gBACpB,YACA,QACiB;CACjB,MAAM,QAAQ,WAAW,MAAM;CAE/B,IAAI,UAAU,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,GACzC,MAAM,MAAM,eAAe,MAAM,CAAC;CAGpC,OAAO,MAAM,UAAU;AACzB"}
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/model/methods/dirty-methods.ts
1
+ //#region ../../packages/cascade/src/model/methods/dirty-methods.ts
2
2
  function checkHasChanges(model) {
3
3
  return model.dirtyTracker.hasChanges();
4
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dirty-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/dirty-methods.ts"],"sourcesContent":["import type { Model } from \"../model\";\n\nexport function checkHasChanges(model: Model): boolean {\n return model.dirtyTracker.hasChanges();\n}\n\nexport function checkIsDirty(model: Model, column: string): boolean {\n return model.dirtyTracker.isDirty(column);\n}\n\nexport function getDirtyColumnsWithValues(model: Model): Record<string, { oldValue: unknown; newValue: unknown }> {\n return model.dirtyTracker.getDirtyColumnsWithValues();\n}\n\nexport function getRemovedColumns(model: Model): string[] {\n return model.dirtyTracker.getRemovedColumns();\n}\n\nexport function getDirtyColumns(model: Model): string[] {\n return model.dirtyTracker.getDirtyColumns();\n}\n"],"mappings":";AAEA,SAAgB,gBAAgB,OAAuB;CACrD,OAAO,MAAM,aAAa,WAAW;AACvC;AAEA,SAAgB,aAAa,OAAc,QAAyB;CAClE,OAAO,MAAM,aAAa,QAAQ,MAAM;AAC1C;AAEA,SAAgB,0BAA0B,OAAwE;CAChH,OAAO,MAAM,aAAa,0BAA0B;AACtD;AAEA,SAAgB,kBAAkB,OAAwB;CACxD,OAAO,MAAM,aAAa,kBAAkB;AAC9C;AAEA,SAAgB,gBAAgB,OAAwB;CACtD,OAAO,MAAM,aAAa,gBAAgB;AAC5C"}
1
+ {"version":3,"file":"dirty-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/dirty-methods.ts"],"sourcesContent":["import type { Model } from \"../model\";\n\nexport function checkHasChanges(model: Model): boolean {\n return model.dirtyTracker.hasChanges();\n}\n\nexport function checkIsDirty(model: Model, column: string): boolean {\n return model.dirtyTracker.isDirty(column);\n}\n\nexport function getDirtyColumnsWithValues(\n model: Model,\n): Record<string, { oldValue: unknown; newValue: unknown }> {\n return model.dirtyTracker.getDirtyColumnsWithValues();\n}\n\nexport function getRemovedColumns(model: Model): string[] {\n return model.dirtyTracker.getRemovedColumns();\n}\n\nexport function getDirtyColumns(model: Model): string[] {\n return model.dirtyTracker.getDirtyColumns();\n}\n"],"mappings":";AAEA,SAAgB,gBAAgB,OAAuB;CACrD,OAAO,MAAM,aAAa,WAAW;AACvC;AAEA,SAAgB,aAAa,OAAc,QAAyB;CAClE,OAAO,MAAM,aAAa,QAAQ,MAAM;AAC1C;AAEA,SAAgB,0BACd,OAC0D;CAC1D,OAAO,MAAM,aAAa,0BAA0B;AACtD;AAEA,SAAgB,kBAAkB,OAAwB;CACxD,OAAO,MAAM,aAAa,kBAAkB;AAC9C;AAEA,SAAgB,gBAAgB,OAAwB;CACtD,OAAO,MAAM,aAAa,gBAAgB;AAC5C"}
@@ -2,7 +2,7 @@ import { RelationHydrator } from "../../relations/relation-hydrator.mjs";
2
2
  import { clone } from "@mongez/reinforcements";
3
3
  import { DateValidator } from "@warlock.js/seal";
4
4
 
5
- //#region ../cascade/src/model/methods/hydration-methods.ts
5
+ //#region ../../packages/cascade/src/model/methods/hydration-methods.ts
6
6
  /**
7
7
  * Drivers re-inflate any ISO-looking string into a Date. Only fields the model
8
8
  * schema declares as dates may be converted, so put every other string back.
@@ -1 +1 @@
1
- {"version":3,"file":"hydration-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/hydration-methods.ts"],"sourcesContent":["import { clone } from \"@mongez/reinforcements\";\nimport { DateValidator } from \"@warlock.js/seal\";\nimport { RelationHydrator, type ModelSnapshot, type SerializedRelation } from \"../../relations/relation-hydrator\";\nimport type { ChildModel, Model } from \"../model\";\n\n/**\n * Drivers re-inflate any ISO-looking string into a Date. Only fields the model\n * schema declares as dates may be converted, so put every other string back.\n */\nfunction restoreUndeclaredDateStrings<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n original: Record<string, string>,\n data: Record<string, unknown>,\n): void {\n const shape = ModelClass.schema?.schema ?? {};\n\n for (const [key, value] of Object.entries(original)) {\n if (data[key] instanceof Date && !(shape[key] instanceof DateValidator)) {\n data[key] = value;\n }\n }\n}\n\nexport function hydrateModel<TModel extends Model = Model>(\n ModelClass: ChildModel<TModel>,\n data: Record<string, unknown>,\n): TModel {\n const strings: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === \"string\") strings[key] = value;\n }\n\n const deserialized = ModelClass.getDriver().deserialize(data);\n restoreUndeclaredDateStrings(ModelClass, strings, deserialized);\n\n const model = new ModelClass(deserialized);\n model.isNew = false;\n return model;\n}\n\nexport function modelFromSnapshot<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n snapshot: ModelSnapshot,\n): TModel {\n const model = ModelClass.hydrate(snapshot.data) as TModel;\n RelationHydrator.hydrate(model, ModelClass.relations, snapshot.relations);\n return model;\n}\n\nexport function modelToSnapshot(model: Model): ModelSnapshot {\n const driver = (model.constructor as typeof Model).getDataSource().driver;\n const relations: Record<string, SerializedRelation> = {};\n\n for (const [name, related] of model.loadedRelations) {\n if (related === null) {\n relations[name] = null;\n } else if (Array.isArray(related)) {\n relations[name] = related.map((m) => (m instanceof Object && typeof m.toSnapshot === \"function\" ? m.toSnapshot() : m));\n } else if (related instanceof Object && typeof related.toSnapshot === \"function\") {\n relations[name] = related.toSnapshot();\n }\n }\n\n return {\n data: driver.serialize({ ...model.data }) as Record<string, unknown>,\n relations,\n };\n}\n\nexport function serializeModel(model: Model) {\n return (model.constructor as typeof Model).getDataSource().driver.serialize(model.data);\n}\n\nexport function cloneModel<TModel extends Model>(model: TModel): TModel {\n const clonedData = clone(model.data);\n const ModelClass = model.self();\n const clonedModel = new ModelClass(clonedData) as TModel;\n\n clonedModel.isNew = model.isNew;\n deepFreezeObject(clonedModel.data);\n clonedModel.dirtyTracker.reset();\n\n return clonedModel;\n}\n\nexport function deepFreezeObject<T>(obj: T): T {\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach((prop) => {\n const value = (obj as any)[prop];\n if (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n !Object.isFrozen(value)\n ) {\n deepFreezeObject(value);\n }\n });\n\n return obj;\n}\n\nexport function replaceModelData<TModel extends Model>(\n model: TModel,\n data: Record<string, unknown>,\n): void {\n model.data = data as any;\n model.dirtyTracker.replaceCurrentData(data);\n}\n"],"mappings":";;;;;;;;;AASA,SAAS,6BACP,YACA,UACA,MACM;CACN,MAAM,QAAQ,WAAW,QAAQ,UAAU,CAAC;CAE5C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,IAAI,KAAK,gBAAgB,QAAQ,EAAE,MAAM,gBAAgB,gBACvD,KAAK,OAAO;AAGlB;AAEA,SAAgB,aACd,YACA,MACQ;CACR,MAAM,UAAkC,CAAC;CAEzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAC5C,IAAI,OAAO,UAAU,UAAU,QAAQ,OAAO;CAGhD,MAAM,eAAe,WAAW,UAAU,CAAC,CAAC,YAAY,IAAI;CAC5D,6BAA6B,YAAY,SAAS,YAAY;CAE9D,MAAM,QAAQ,IAAI,WAAW,YAAY;CACzC,MAAM,QAAQ;CACd,OAAO;AACT;AAEA,SAAgB,kBACd,YACA,UACQ;CACR,MAAM,QAAQ,WAAW,QAAQ,SAAS,IAAI;CAC9C,iBAAiB,QAAQ,OAAO,WAAW,WAAW,SAAS,SAAS;CACxE,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAA6B;CAC3D,MAAM,SAAU,MAAM,YAA6B,cAAc,CAAC,CAAC;CACnE,MAAM,YAAgD,CAAC;CAEvD,KAAK,MAAM,CAAC,MAAM,YAAY,MAAM,iBAClC,IAAI,YAAY,MACd,UAAU,QAAQ;MACb,IAAI,MAAM,QAAQ,OAAO,GAC9B,UAAU,QAAQ,QAAQ,KAAK,MAAO,aAAa,UAAU,OAAO,EAAE,eAAe,aAAa,EAAE,WAAW,IAAI,CAAE;MAChH,IAAI,mBAAmB,UAAU,OAAO,QAAQ,eAAe,YACpE,UAAU,QAAQ,QAAQ,WAAW;CAIzC,OAAO;EACL,MAAM,OAAO,UAAU,EAAE,GAAG,MAAM,KAAK,CAAC;EACxC;CACF;AACF;AAEA,SAAgB,eAAe,OAAc;CAC3C,OAAQ,MAAM,YAA6B,cAAc,CAAC,CAAC,OAAO,UAAU,MAAM,IAAI;AACxF;AAEA,SAAgB,WAAiC,OAAuB;CACtE,MAAM,aAAa,MAAM,MAAM,IAAI;CAEnC,MAAM,cAAc,KADD,MAAM,KACQ,GAAE,UAAU;CAE7C,YAAY,QAAQ,MAAM;CAC1B,iBAAiB,YAAY,IAAI;CACjC,YAAY,aAAa,MAAM;CAE/B,OAAO;AACT;AAEA,SAAgB,iBAAoB,KAAW;CAC7C,OAAO,OAAO,GAAG;CAEjB,OAAO,oBAAoB,GAAG,CAAC,CAAC,SAAS,SAAS;EAChD,MAAM,QAAS,IAAY;EAC3B,IACE,UAAU,SACT,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,CAAC,OAAO,SAAS,KAAK,GAEtB,iBAAiB,KAAK;CAE1B,CAAC;CAED,OAAO;AACT;AAEA,SAAgB,iBACd,OACA,MACM;CACN,MAAM,OAAO;CACb,MAAM,aAAa,mBAAmB,IAAI;AAC5C"}
1
+ {"version":3,"file":"hydration-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/hydration-methods.ts"],"sourcesContent":["import { clone } from \"@mongez/reinforcements\";\nimport { DateValidator } from \"@warlock.js/seal\";\nimport {\n RelationHydrator,\n type ModelSnapshot,\n type SerializedRelation,\n} from \"../../relations/relation-hydrator\";\nimport type { ChildModel, Model } from \"../model\";\n\n/**\n * Drivers re-inflate any ISO-looking string into a Date. Only fields the model\n * schema declares as dates may be converted, so put every other string back.\n */\nfunction restoreUndeclaredDateStrings<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n original: Record<string, string>,\n data: Record<string, unknown>,\n): void {\n const shape = ModelClass.schema?.schema ?? {};\n\n for (const [key, value] of Object.entries(original)) {\n if (data[key] instanceof Date && !(shape[key] instanceof DateValidator)) {\n data[key] = value;\n }\n }\n}\n\nexport function hydrateModel<TModel extends Model = Model>(\n ModelClass: ChildModel<TModel>,\n data: Record<string, unknown>,\n): TModel {\n const strings: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === \"string\") strings[key] = value;\n }\n\n const deserialized = ModelClass.getDriver().deserialize(data);\n restoreUndeclaredDateStrings(ModelClass, strings, deserialized);\n\n const model = new ModelClass(deserialized);\n model.isNew = false;\n return model;\n}\n\nexport function modelFromSnapshot<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n snapshot: ModelSnapshot,\n): TModel {\n const model = ModelClass.hydrate(snapshot.data) as TModel;\n RelationHydrator.hydrate(model, ModelClass.relations, snapshot.relations);\n return model;\n}\n\nexport function modelToSnapshot(model: Model): ModelSnapshot {\n const driver = (model.constructor as typeof Model).getDataSource().driver;\n const relations: Record<string, SerializedRelation> = {};\n\n for (const [name, related] of model.loadedRelations) {\n if (related === null) {\n relations[name] = null;\n } else if (Array.isArray(related)) {\n relations[name] = related.map((m) =>\n m instanceof Object && typeof m.toSnapshot === \"function\" ? m.toSnapshot() : m,\n );\n } else if (related instanceof Object && typeof related.toSnapshot === \"function\") {\n relations[name] = related.toSnapshot();\n }\n }\n\n return {\n data: driver.serialize({ ...model.data }) as Record<string, unknown>,\n relations,\n };\n}\n\nexport function serializeModel(model: Model) {\n return (model.constructor as typeof Model).getDataSource().driver.serialize(model.data);\n}\n\nexport function cloneModel<TModel extends Model>(model: TModel): TModel {\n const clonedData = clone(model.data);\n const ModelClass = model.self();\n const clonedModel = new ModelClass(clonedData) as TModel;\n\n clonedModel.isNew = model.isNew;\n deepFreezeObject(clonedModel.data);\n clonedModel.dirtyTracker.reset();\n\n return clonedModel;\n}\n\nexport function deepFreezeObject<T>(obj: T): T {\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach((prop) => {\n const value = (obj as any)[prop];\n if (\n value !== null &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n !Object.isFrozen(value)\n ) {\n deepFreezeObject(value);\n }\n });\n\n return obj;\n}\n\nexport function replaceModelData<TModel extends Model>(\n model: TModel,\n data: Record<string, unknown>,\n): void {\n model.data = data as any;\n model.dirtyTracker.replaceCurrentData(data);\n}\n"],"mappings":";;;;;;;;;AAaA,SAAS,6BACP,YACA,UACA,MACM;CACN,MAAM,QAAQ,WAAW,QAAQ,UAAU,CAAC;CAE5C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,IAAI,KAAK,gBAAgB,QAAQ,EAAE,MAAM,gBAAgB,gBACvD,KAAK,OAAO;AAGlB;AAEA,SAAgB,aACd,YACA,MACQ;CACR,MAAM,UAAkC,CAAC;CAEzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAC5C,IAAI,OAAO,UAAU,UAAU,QAAQ,OAAO;CAGhD,MAAM,eAAe,WAAW,UAAU,CAAC,CAAC,YAAY,IAAI;CAC5D,6BAA6B,YAAY,SAAS,YAAY;CAE9D,MAAM,QAAQ,IAAI,WAAW,YAAY;CACzC,MAAM,QAAQ;CACd,OAAO;AACT;AAEA,SAAgB,kBACd,YACA,UACQ;CACR,MAAM,QAAQ,WAAW,QAAQ,SAAS,IAAI;CAC9C,iBAAiB,QAAQ,OAAO,WAAW,WAAW,SAAS,SAAS;CACxE,OAAO;AACT;AAEA,SAAgB,gBAAgB,OAA6B;CAC3D,MAAM,SAAU,MAAM,YAA6B,cAAc,CAAC,CAAC;CACnE,MAAM,YAAgD,CAAC;CAEvD,KAAK,MAAM,CAAC,MAAM,YAAY,MAAM,iBAClC,IAAI,YAAY,MACd,UAAU,QAAQ;MACb,IAAI,MAAM,QAAQ,OAAO,GAC9B,UAAU,QAAQ,QAAQ,KAAK,MAC7B,aAAa,UAAU,OAAO,EAAE,eAAe,aAAa,EAAE,WAAW,IAAI,CAC/E;MACK,IAAI,mBAAmB,UAAU,OAAO,QAAQ,eAAe,YACpE,UAAU,QAAQ,QAAQ,WAAW;CAIzC,OAAO;EACL,MAAM,OAAO,UAAU,EAAE,GAAG,MAAM,KAAK,CAAC;EACxC;CACF;AACF;AAEA,SAAgB,eAAe,OAAc;CAC3C,OAAQ,MAAM,YAA6B,cAAc,CAAC,CAAC,OAAO,UAAU,MAAM,IAAI;AACxF;AAEA,SAAgB,WAAiC,OAAuB;CACtE,MAAM,aAAa,MAAM,MAAM,IAAI;CAEnC,MAAM,cAAc,KADD,MAAM,KACQ,GAAE,UAAU;CAE7C,YAAY,QAAQ,MAAM;CAC1B,iBAAiB,YAAY,IAAI;CACjC,YAAY,aAAa,MAAM;CAE/B,OAAO;AACT;AAEA,SAAgB,iBAAoB,KAAW;CAC7C,OAAO,OAAO,GAAG;CAEjB,OAAO,oBAAoB,GAAG,CAAC,CAAC,SAAS,SAAS;EAChD,MAAM,QAAS,IAAY;EAC3B,IACE,UAAU,SACT,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,CAAC,OAAO,SAAS,KAAK,GAEtB,iBAAiB,KAAK;CAE1B,CAAC;CAED,OAAO;AACT;AAEA,SAAgB,iBACd,OACA,MACM;CACN,MAAM,OAAO;CACb,MAAM,aAAa,mBAAmB,IAAI;AAC5C"}
@@ -1,7 +1,7 @@
1
1
  import { globalModelEvents } from "../../events/model-events.mjs";
2
2
  import { emitStaticEvent } from "./static-event-methods.mjs";
3
3
 
4
- //#region ../cascade/src/model/methods/instance-event-methods.ts
4
+ //#region ../../packages/cascade/src/model/methods/instance-event-methods.ts
5
5
  async function emitModelEvent(model, event, context) {
6
6
  const ctor = model.constructor;
7
7
  await model.events.emit(event, model, context);
@@ -1 +1 @@
1
- {"version":3,"file":"instance-event-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/instance-event-methods.ts"],"sourcesContent":["import {\n globalModelEvents,\n type ModelEventListener,\n type ModelEventName,\n} from \"../../events/model-events\";\nimport type { Model } from \"../model\";\nimport { emitStaticEvent } from \"./static-event-methods\";\n\nexport async function emitModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n context?: TContext,\n): Promise<void> {\n const ctor = model.constructor as any;\n await model.events.emit(event, model, context as TContext);\n await emitStaticEvent(ctor, event, model, context as TContext);\n await globalModelEvents.emit(event, model, context as TContext);\n}\n\nexport function onModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n listener: ModelEventListener<any, TContext>,\n): () => void {\n return model.events.on(event, listener);\n}\n\nexport function onceModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n listener: ModelEventListener<any, TContext>,\n): () => void {\n return model.events.once(event, listener);\n}\n\nexport function offModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n listener: ModelEventListener<any, TContext>,\n): void {\n model.events.off(event, listener);\n}\n"],"mappings":";;;;AAQA,eAAsB,eACpB,OACA,OACA,SACe;CACf,MAAM,OAAO,MAAM;CACnB,MAAM,MAAM,OAAO,KAAK,OAAO,OAAO,OAAmB;CACzD,MAAM,gBAAgB,MAAM,OAAO,OAAO,OAAmB;CAC7D,MAAM,kBAAkB,KAAK,OAAO,OAAO,OAAmB;AAChE;AAEA,SAAgB,aACd,OACA,OACA,UACY;CACZ,OAAO,MAAM,OAAO,GAAG,OAAO,QAAQ;AACxC;AAEA,SAAgB,eACd,OACA,OACA,UACY;CACZ,OAAO,MAAM,OAAO,KAAK,OAAO,QAAQ;AAC1C;AAEA,SAAgB,cACd,OACA,OACA,UACM;CACN,MAAM,OAAO,IAAI,OAAO,QAAQ;AAClC"}
1
+ {"version":3,"file":"instance-event-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/instance-event-methods.ts"],"sourcesContent":["import {\n globalModelEvents,\n type ModelEventListener,\n type ModelEventName,\n} from \"../../events/model-events\";\nimport type { Model } from \"../model\";\nimport { emitStaticEvent } from \"./static-event-methods\";\n\nexport async function emitModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n context?: TContext,\n): Promise<void> {\n const ctor = model.constructor as any;\n await model.events.emit(event, model, context as TContext);\n await emitStaticEvent(ctor, event, model, context as TContext);\n await globalModelEvents.emit(event, model, context as TContext);\n}\n\nexport function onModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n listener: ModelEventListener<any, TContext>,\n): () => void {\n return model.events.on(event, listener);\n}\n\nexport function onceModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n listener: ModelEventListener<any, TContext>,\n): () => void {\n return model.events.once(event, listener);\n}\n\nexport function offModelEvent<TContext = unknown>(\n model: Model,\n event: ModelEventName,\n listener: ModelEventListener<any, TContext>,\n): void {\n model.events.off(event, listener);\n}\n"],"mappings":";;;;AAQA,eAAsB,eACpB,OACA,OACA,SACe;CACf,MAAM,OAAO,MAAM;CACnB,MAAM,MAAM,OAAO,KAAK,OAAO,OAAO,OAAmB;CACzD,MAAM,gBAAgB,MAAM,OAAO,OAAO,OAAmB;CAC7D,MAAM,kBAAkB,KAAK,OAAO,OAAO,OAAmB;AAChE;AAEA,SAAgB,aACd,OACA,OACA,UACY;CACZ,OAAO,MAAM,OAAO,GAAG,OAAO,QAAQ;AACxC;AAEA,SAAgB,eACd,OACA,OACA,UACY;CACZ,OAAO,MAAM,OAAO,KAAK,OAAO,QAAQ;AAC1C;AAEA,SAAgB,cACd,OACA,OACA,UACM;CACN,MAAM,OAAO,IAAI,OAAO,QAAQ;AAClC"}
@@ -1,7 +1,7 @@
1
1
  import { DatabaseWriter } from "../../writer/database-writer.mjs";
2
2
  import { get, set } from "@mongez/reinforcements";
3
3
 
4
- //#region ../cascade/src/model/methods/meta-methods.ts
4
+ //#region ../../packages/cascade/src/model/methods/meta-methods.ts
5
5
  /**
6
6
  * Whether a subclass (or an intermediate base below `Model`) set the static
7
7
  * itself. The base `Model` initialises several statics (strictMode,
@@ -1 +1 @@
1
- {"version":3,"file":"meta-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/meta-methods.ts"],"sourcesContent":["import { get, set } from \"@mongez/reinforcements\";\nimport { DatabaseWriter } from \"../../writer/database-writer\";\nimport type { Model } from \"../model\";\n\n/**\n * Whether a subclass (or an intermediate base below `Model`) set the static\n * itself. The base `Model` initialises several statics (strictMode,\n * autoGenerateId, incrementIdBy, deletedAtColumn), so comparing to\n * `undefined` would never let data-source defaults apply.\n */\nfunction isExplicitStatic(ModelClass: any, key: string): boolean {\n let current = ModelClass;\n\n // The base Model is the class whose parent is `Function.prototype`; its own\n // initialisers are framework fallbacks, not explicit choices.\n while (current && Object.getPrototypeOf(current) !== Function.prototype) {\n if (Object.prototype.hasOwnProperty.call(current, key) && current[key] !== undefined) {\n return true;\n }\n\n current = Object.getPrototypeOf(current);\n }\n\n return false;\n}\n\nexport function applyDefaultsToModel(ModelClass: any, defaults: any): void {\n // Only apply defaults if model doesn't have its own value\n\n // ============================================================================\n // ID Generation\n // ============================================================================\n if (defaults.autoGenerateId !== undefined && !isExplicitStatic(ModelClass, \"autoGenerateId\")) {\n ModelClass.autoGenerateId = defaults.autoGenerateId;\n }\n if (defaults.initialId !== undefined && !isExplicitStatic(ModelClass, \"initialId\")) {\n ModelClass.initialId = defaults.initialId;\n }\n if (defaults.randomInitialId !== undefined && !isExplicitStatic(ModelClass, \"randomInitialId\")) {\n ModelClass.randomInitialId = defaults.randomInitialId;\n }\n if (defaults.incrementIdBy !== undefined && !isExplicitStatic(ModelClass, \"incrementIdBy\")) {\n ModelClass.incrementIdBy = defaults.incrementIdBy;\n }\n if (defaults.randomIncrement !== undefined && !isExplicitStatic(ModelClass, \"randomIncrement\")) {\n ModelClass.randomIncrement = defaults.randomIncrement;\n }\n\n // ============================================================================\n // Timestamps\n // ============================================================================\n if (defaults.createdAtColumn !== undefined && !isExplicitStatic(ModelClass, \"createdAtColumn\")) {\n ModelClass.createdAtColumn = defaults.createdAtColumn;\n }\n\n if (defaults.updatedAtColumn !== undefined && !isExplicitStatic(ModelClass, \"updatedAtColumn\")) {\n ModelClass.updatedAtColumn = defaults.updatedAtColumn;\n }\n\n // ============================================================================\n // Deletion\n // ============================================================================\n if (defaults.deleteStrategy !== undefined && !isExplicitStatic(ModelClass, \"deleteStrategy\")) {\n ModelClass.deleteStrategy = defaults.deleteStrategy;\n }\n if (defaults.deletedAtColumn !== undefined && !isExplicitStatic(ModelClass, \"deletedAtColumn\")) {\n ModelClass.deletedAtColumn = defaults.deletedAtColumn;\n }\n if (defaults.trashTable !== undefined && !isExplicitStatic(ModelClass, \"trashTable\")) {\n // Handle function-based trash table\n if (typeof defaults.trashTable === \"function\") {\n ModelClass.trashTable = defaults.trashTable(ModelClass.table);\n } else {\n ModelClass.trashTable = defaults.trashTable;\n }\n }\n\n // ============================================================================\n // Validation\n // ============================================================================\n if (defaults.strictMode !== undefined && !isExplicitStatic(ModelClass, \"strictMode\")) {\n ModelClass.strictMode = defaults.strictMode;\n }\n}\n\nexport async function generateModelNextId(model: Model): Promise<number | string> {\n const writer = new DatabaseWriter(model);\n await writer.generateNextId();\n return model.id!;\n}\n\nexport async function performAtomicUpdate(\n model: Model,\n operations: Record<string, unknown>,\n): Promise<number> {\n return model.self().atomic({ [model.self().primaryKey]: model.trustedPrimaryKey }, operations);\n}\n\n/**\n * Apply an atomic delta to the local value without marking the field dirty.\n * The database already holds the change, so a later `save()` must not send a\n * stale `$set` for it. Other pending changes stay dirty.\n */\nfunction applyLocalDelta(model: Model, field: string, delta: number): void {\n const tracker = model.dirtyTracker;\n const fieldWasDirty = tracker.isDirty(field);\n const value = (get(model.data, field, 0) as number) + delta;\n\n set(model.data, field, value);\n\n // A removed column can't be replayed after a baseline reset, so fall back to\n // plain dirty tracking for that rare case.\n if (fieldWasDirty || tracker.getRemovedColumns().length > 0) {\n tracker.setAtPath(field, value);\n return;\n }\n\n const pending = tracker.getDirtyColumnsWithValues();\n const baseline = structuredClone(model.data) as Record<string, unknown>;\n\n for (const [column, values] of Object.entries(pending)) {\n set(baseline, column, values.oldValue);\n }\n\n tracker.reset(baseline);\n\n for (const [column, values] of Object.entries(pending)) {\n tracker.setAtPath(column, values.newValue);\n }\n}\n\nexport async function performAtomicIncrement<T extends string>(\n model: Model,\n field: T,\n amount = 1,\n): Promise<number> {\n const result = await performAtomicUpdate(model, { $inc: { [field]: amount } });\n applyLocalDelta(model, field, amount);\n return result;\n}\n\nexport async function performAtomicDecrement<T extends string>(\n model: Model,\n field: T,\n amount = 1,\n): Promise<number> {\n const result = await performAtomicUpdate(model, { $inc: { [field]: -amount } });\n applyLocalDelta(model, field, -amount);\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"meta-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/meta-methods.ts"],"sourcesContent":["import { get, set } from \"@mongez/reinforcements\";\nimport { DatabaseWriter } from \"../../writer/database-writer\";\nimport type { Model } from \"../model\";\n\n/**\n * Whether a subclass (or an intermediate base below `Model`) set the static\n * itself. The base `Model` initialises several statics (strictMode,\n * autoGenerateId, incrementIdBy, deletedAtColumn), so comparing to\n * `undefined` would never let data-source defaults apply.\n */\nfunction isExplicitStatic(ModelClass: any, key: string): boolean {\n let current = ModelClass;\n\n // The base Model is the class whose parent is `Function.prototype`; its own\n // initialisers are framework fallbacks, not explicit choices.\n while (current && Object.getPrototypeOf(current) !== Function.prototype) {\n if (Object.prototype.hasOwnProperty.call(current, key) && current[key] !== undefined) {\n return true;\n }\n\n current = Object.getPrototypeOf(current);\n }\n\n return false;\n}\n\nexport function applyDefaultsToModel(ModelClass: any, defaults: any): void {\n // Only apply defaults if model doesn't have its own value\n\n // ============================================================================\n // ID Generation\n // ============================================================================\n if (defaults.autoGenerateId !== undefined && !isExplicitStatic(ModelClass, \"autoGenerateId\")) {\n ModelClass.autoGenerateId = defaults.autoGenerateId;\n }\n if (defaults.initialId !== undefined && !isExplicitStatic(ModelClass, \"initialId\")) {\n ModelClass.initialId = defaults.initialId;\n }\n if (defaults.randomInitialId !== undefined && !isExplicitStatic(ModelClass, \"randomInitialId\")) {\n ModelClass.randomInitialId = defaults.randomInitialId;\n }\n if (defaults.incrementIdBy !== undefined && !isExplicitStatic(ModelClass, \"incrementIdBy\")) {\n ModelClass.incrementIdBy = defaults.incrementIdBy;\n }\n if (defaults.randomIncrement !== undefined && !isExplicitStatic(ModelClass, \"randomIncrement\")) {\n ModelClass.randomIncrement = defaults.randomIncrement;\n }\n\n // ============================================================================\n // Timestamps\n // ============================================================================\n if (defaults.createdAtColumn !== undefined && !isExplicitStatic(ModelClass, \"createdAtColumn\")) {\n ModelClass.createdAtColumn = defaults.createdAtColumn;\n }\n\n if (defaults.updatedAtColumn !== undefined && !isExplicitStatic(ModelClass, \"updatedAtColumn\")) {\n ModelClass.updatedAtColumn = defaults.updatedAtColumn;\n }\n\n // ============================================================================\n // Deletion\n // ============================================================================\n if (defaults.deleteStrategy !== undefined && !isExplicitStatic(ModelClass, \"deleteStrategy\")) {\n ModelClass.deleteStrategy = defaults.deleteStrategy;\n }\n if (defaults.deletedAtColumn !== undefined && !isExplicitStatic(ModelClass, \"deletedAtColumn\")) {\n ModelClass.deletedAtColumn = defaults.deletedAtColumn;\n }\n if (defaults.trashTable !== undefined && !isExplicitStatic(ModelClass, \"trashTable\")) {\n // Handle function-based trash table\n if (typeof defaults.trashTable === \"function\") {\n ModelClass.trashTable = defaults.trashTable(ModelClass.table);\n } else {\n ModelClass.trashTable = defaults.trashTable;\n }\n }\n\n // ============================================================================\n // Validation\n // ============================================================================\n if (defaults.strictMode !== undefined && !isExplicitStatic(ModelClass, \"strictMode\")) {\n ModelClass.strictMode = defaults.strictMode;\n }\n}\n\nexport async function generateModelNextId(model: Model): Promise<number | string> {\n const writer = new DatabaseWriter(model);\n await writer.generateNextId();\n return model.id!;\n}\n\nexport async function performAtomicUpdate(\n model: Model,\n operations: Record<string, unknown>,\n): Promise<number> {\n return model.self().atomic({ [model.self().primaryKey]: model.trustedPrimaryKey }, operations);\n}\n\n/**\n * Apply an atomic delta to the local value without marking the field dirty.\n * The database already holds the change, so a later `save()` must not send a\n * stale `$set` for it. Other pending changes stay dirty.\n */\nfunction applyLocalDelta(model: Model, field: string, delta: number): void {\n const tracker = model.dirtyTracker;\n const fieldWasDirty = tracker.isDirty(field);\n const value = (get(model.data, field, 0) as number) + delta;\n\n set(model.data, field, value);\n\n // A removed column can't be replayed after a baseline reset, so fall back to\n // plain dirty tracking for that rare case.\n if (fieldWasDirty || tracker.getRemovedColumns().length > 0) {\n tracker.setAtPath(field, value);\n return;\n }\n\n const pending = tracker.getDirtyColumnsWithValues();\n const baseline = structuredClone(model.data) as Record<string, unknown>;\n\n for (const [column, values] of Object.entries(pending)) {\n set(baseline, column, values.oldValue);\n }\n\n tracker.reset(baseline);\n\n for (const [column, values] of Object.entries(pending)) {\n tracker.setAtPath(column, values.newValue);\n }\n}\n\nexport async function performAtomicIncrement<T extends string>(\n model: Model,\n field: T,\n amount = 1,\n): Promise<number> {\n const result = await performAtomicUpdate(model, { $inc: { [field]: amount } });\n applyLocalDelta(model, field, amount);\n return result;\n}\n\nexport async function performAtomicDecrement<T extends string>(\n model: Model,\n field: T,\n amount = 1,\n): Promise<number> {\n const result = await performAtomicUpdate(model, { $inc: { [field]: -amount } });\n applyLocalDelta(model, field, -amount);\n return result;\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createPivotOperations } from "../../relations/pivot-operations.mjs";
2
2
 
3
- //#region ../cascade/src/model/methods/pivot-methods.ts
3
+ //#region ../../packages/cascade/src/model/methods/pivot-methods.ts
4
4
  /**
5
5
  * Get the pivot-operations handle for a `belongsToMany` relation.
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pivot-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/pivot-methods.ts"],"sourcesContent":["import { createPivotOperations, type PivotOperations } from \"../../relations/pivot-operations\";\nimport type { PivotData, PivotIds } from \"../../relations/types\";\nimport type { Model } from \"../model\";\n\n/**\n * Get the pivot-operations handle for a `belongsToMany` relation.\n *\n * Returns the `PivotOperations` object exposing `attach` / `detach` /\n * `sync` / `toggle` for the named relation's pivot table.\n *\n * @throws Error if the relation is not a belongsToMany relation.\n *\n * @example\n * await post.pivot(\"tags\").attach([1, 2, 3]);\n * await post.pivot(\"tags\").sync([1, 3, 5]);\n * await post.pivot(\"tags\").toggle([1, 7]);\n */\nexport function pivotRelation(model: Model, relation: string): PivotOperations {\n return createPivotOperations(model, relation);\n}\n\n/**\n * Attach one or more related records to a belongsToMany pivot table.\n *\n * @throws Error if the relation is not a belongsToMany relation.\n *\n * @example\n * await post.attach(\"tags\", [1, 2, 3]);\n * await post.attach(\"tags\", [4], { addedBy: currentUserId });\n */\nexport async function attachPivotRelation(\n model: Model,\n relation: string,\n ids: PivotIds,\n pivotData?: PivotData,\n): Promise<void> {\n return createPivotOperations(model, relation).attach(ids, pivotData);\n}\n\n/**\n * Detach related records from a belongsToMany pivot table. Omit `ids` to\n * detach every row for this side of the relation.\n *\n * @throws Error if the relation is not a belongsToMany relation.\n *\n * @example\n * await post.detach(\"tags\", [2]);\n * await post.detach(\"tags\"); // detach all\n */\nexport async function detachPivotRelation(\n model: Model,\n relation: string,\n ids?: PivotIds,\n): Promise<void> {\n return createPivotOperations(model, relation).detach(ids);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,OAAc,UAAmC;CAC7E,OAAO,sBAAsB,OAAO,QAAQ;AAC9C;;;;;;;;;;AAWA,eAAsB,oBACpB,OACA,UACA,KACA,WACe;CACf,OAAO,sBAAsB,OAAO,QAAQ,CAAC,CAAC,OAAO,KAAK,SAAS;AACrE;;;;;;;;;;;AAYA,eAAsB,oBACpB,OACA,UACA,KACe;CACf,OAAO,sBAAsB,OAAO,QAAQ,CAAC,CAAC,OAAO,GAAG;AAC1D"}
1
+ {"version":3,"file":"pivot-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/pivot-methods.ts"],"sourcesContent":["import { createPivotOperations, type PivotOperations } from \"../../relations/pivot-operations\";\nimport type { PivotData, PivotIds } from \"../../relations/types\";\nimport type { Model } from \"../model\";\n\n/**\n * Get the pivot-operations handle for a `belongsToMany` relation.\n *\n * Returns the `PivotOperations` object exposing `attach` / `detach` /\n * `sync` / `toggle` for the named relation's pivot table.\n *\n * @throws Error if the relation is not a belongsToMany relation.\n *\n * @example\n * await post.pivot(\"tags\").attach([1, 2, 3]);\n * await post.pivot(\"tags\").sync([1, 3, 5]);\n * await post.pivot(\"tags\").toggle([1, 7]);\n */\nexport function pivotRelation(model: Model, relation: string): PivotOperations {\n return createPivotOperations(model, relation);\n}\n\n/**\n * Attach one or more related records to a belongsToMany pivot table.\n *\n * @throws Error if the relation is not a belongsToMany relation.\n *\n * @example\n * await post.attach(\"tags\", [1, 2, 3]);\n * await post.attach(\"tags\", [4], { addedBy: currentUserId });\n */\nexport async function attachPivotRelation(\n model: Model,\n relation: string,\n ids: PivotIds,\n pivotData?: PivotData,\n): Promise<void> {\n return createPivotOperations(model, relation).attach(ids, pivotData);\n}\n\n/**\n * Detach related records from a belongsToMany pivot table. Omit `ids` to\n * detach every row for this side of the relation.\n *\n * @throws Error if the relation is not a belongsToMany relation.\n *\n * @example\n * await post.detach(\"tags\", [2]);\n * await post.detach(\"tags\"); // detach all\n */\nexport async function detachPivotRelation(\n model: Model,\n relation: string,\n ids?: PivotIds,\n): Promise<void> {\n return createPivotOperations(model, relation).detach(ids);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,SAAgB,cAAc,OAAc,UAAmC;CAC7E,OAAO,sBAAsB,OAAO,QAAQ;AAC9C;;;;;;;;;;AAWA,eAAsB,oBACpB,OACA,UACA,KACA,WACe;CACf,OAAO,sBAAsB,OAAO,QAAQ,CAAC,CAAC,OAAO,KAAK,SAAS;AACrE;;;;;;;;;;;AAYA,eAAsB,oBACpB,OACA,UACA,KACe;CACf,OAAO,sBAAsB,OAAO,QAAQ,CAAC,CAAC,OAAO,GAAG;AAC1D"}
@@ -4,7 +4,7 @@ import { emitStaticEvent } from "./static-event-methods.mjs";
4
4
  import { generateModelId } from "../generate-model-id.mjs";
5
5
  import { warnUndeclaredSensitiveFields } from "./serialization-methods.mjs";
6
6
 
7
- //#region ../cascade/src/model/methods/query-methods.ts
7
+ //#region ../../packages/cascade/src/model/methods/query-methods.ts
8
8
  function buildQuery(ModelClass, BaseModel) {
9
9
  const queryBuilder = ModelClass.newQueryBuilder();
10
10
  queryBuilder.pendingGlobalScopes = new Map([...BaseModel.globalScopes, ...ModelClass.globalScopes]);
@@ -1 +1 @@
1
- {"version":3,"file":"query-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/query-methods.ts"],"sourcesContent":["import type {\n AtomicUpdate,\n AtomicUpdateOptions,\n FindOneAndUpdateOptions,\n PaginationOptions,\n PaginationResult,\n QueryBuilderContract,\n} from \"../../contracts\";\nimport type { DataSource } from \"../../data-source/data-source\";\nimport { dataSourceRegistry } from \"../../data-source/data-source-registry\";\nimport { sanitizeFilter } from \"../../utils/sanitize-filter\";\nimport { generateModelId } from \"../generate-model-id\";\nimport type { ChildModel, GlobalScopeDefinition, Model } from \"../model\";\nimport { emitStaticEvent } from \"./static-event-methods\";\nimport { warnUndeclaredSensitiveFields } from \"./serialization-methods\";\n\nexport function buildQuery<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n BaseModel: typeof Model,\n): QueryBuilderContract<TModel> {\n const queryBuilder = ModelClass.newQueryBuilder<TModel>();\n const qb = queryBuilder;\n\n // Collect global scopes from base Model and child model\n const allGlobalScopes = new Map<string, GlobalScopeDefinition>([\n ...BaseModel.globalScopes,\n ...ModelClass.globalScopes,\n ]);\n\n queryBuilder.pendingGlobalScopes = allGlobalScopes;\n queryBuilder.availableLocalScopes = ModelClass.localScopes;\n queryBuilder.disabledGlobalScopes = new Set();\n queryBuilder.relationDefinitions = ModelClass.relations;\n queryBuilder.modelClass = ModelClass;\n\n let fetchStartedAt = Date.now();\n\n // Emitted from the builder's execute path (awaited), not at construction, so\n // listener changes apply before the query runs and a throwing listener fails\n // the query instead of becoming an unhandled rejection.\n queryBuilder.onFetching(async () => {\n fetchStartedAt = Date.now();\n\n await emitStaticEvent(ModelClass, \"fetching\", queryBuilder, {\n table: ModelClass.table,\n modelClass: ModelClass,\n });\n });\n\n queryBuilder.onHydrating(async (records: any[], context: any) => {\n await emitStaticEvent(ModelClass, \"hydrating\", records as any, {\n query: queryBuilder,\n hydrateCallback: context?.hydrateCallback,\n });\n });\n\n queryBuilder.hydrate((data: any) => {\n return ModelClass.hydrate(data);\n });\n\n // Eager-loading runs inside the driver's `get()` so it works for any\n // builder construction path (Model.query, Model.newQueryBuilder, custom\n // subclassed builders). This hook only handles the model-level `fetched`\n // event emission.\n queryBuilder.onFetched(async (models: any[], context: any) => {\n await emitStaticEvent(ModelClass, \"fetched\", models as any, {\n query: queryBuilder,\n rawRecords: context?.rawRecords ?? [],\n duration: context?.duration ?? Date.now() - fetchStartedAt,\n });\n });\n\n return queryBuilder;\n}\n\nexport function buildNewQueryBuilder<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n): QueryBuilderContract<TModel> {\n const dataSource = ModelClass.getDataSource();\n\n if (ModelClass.builder) {\n const BuilderClass = ModelClass.builder;\n return new BuilderClass(ModelClass.table, dataSource) as QueryBuilderContract<TModel>;\n }\n\n const queryBuilder = dataSource.driver.queryBuilder<TModel>(ModelClass.table);\n return queryBuilder;\n}\n\nexport async function findFirst<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel | null> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return query.first();\n}\n\nexport async function findLast<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel | null> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n\n return query.last();\n}\n\nexport async function findAll<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel[]> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return query.get();\n}\n\nexport function countRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<number> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return query.count();\n}\n\nexport async function findById<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n id: string | number,\n): Promise<TModel | null> {\n const query = ModelClass.query();\n return query.where(ModelClass.primaryKey, id).first();\n}\n\nexport async function paginateRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n options: PaginationOptions & { filter?: Record<string, unknown> } = {},\n): Promise<PaginationResult<TModel>> {\n const query = ModelClass.query();\n if (options.filter) {\n query.where(options.filter);\n }\n\n return query.paginate({\n limit: options.limit,\n page: options.page,\n });\n}\n\nexport async function findLatest<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel[]> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return (await query.latest()) as unknown as TModel[];\n}\n\nexport function increaseField<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n field: string,\n amount: number,\n): Promise<number> {\n const query = ModelClass.query().where(filter);\n return query.increment(field, amount);\n}\n\nexport function decreaseField<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n field: string,\n amount: number,\n): Promise<number> {\n const query = ModelClass.query().where(filter);\n return query.decrement(field, amount);\n}\n\n// The atomic/find-and-modify statics below forward their filter straight to\n// the driver — they never pass through where(), so they must run the same\n// operator-injection check themselves. Only the FILTER is sanitized; update\n// operators ($set/$inc/…) are the point of these APIs and stay untouched.\n//\n// `trustedFilter` is the explicit, code-authored opt-out: it lets a conditional\n// filter such as `{ used: { $lt: 10 } }` through. It is stripped before the\n// options reach the driver.\nfunction resolveFilter(\n filter: Record<string, unknown>,\n options: AtomicUpdateOptions | undefined,\n): Record<string, unknown> {\n return options?.trustedFilter ? filter : sanitizeFilter(filter);\n}\n\nfunction toDriverOptions<TOptions extends AtomicUpdateOptions>(\n options: TOptions | undefined,\n): Omit<TOptions, \"trustedFilter\"> | undefined {\n if (!options) {\n return undefined;\n }\n\n const { trustedFilter: _trustedFilter, ...rest } = options;\n\n return rest;\n}\n\nfunction applyWriteFilter<TModel extends Model>(\n query: QueryBuilderContract<TModel>,\n filter: Record<string, unknown>,\n trustedFilter: boolean,\n): QueryBuilderContract<TModel> {\n // Query builders supplied by integrations predating `whereTrusted` can\n // still apply a code-authored filter through their regular `where` method.\n // Concrete Cascade builders implement `whereTrusted`, which is required for\n // MongoDB operator filters; retain the fallback for compatible custom\n // builders and test doubles.\n if (trustedFilter && typeof query.whereTrusted === \"function\") {\n return query.whereTrusted(filter);\n }\n\n return query.where(filter);\n}\n\n/**\n * Add the same generated `id` that normal Mongo inserts receive to an upsert's\n * insert branch. `$setOnInsert` keeps an existing document's id immutable.\n */\nasync function withAutoGeneratedUpsertId<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n operations: AtomicUpdate,\n options: AtomicUpdateOptions | undefined,\n): Promise<AtomicUpdate> {\n if (\n !options?.upsert ||\n !ModelClass.autoGenerateId ||\n ModelClass.getDriver().name !== \"mongodb\" ||\n Array.isArray(operations)\n ) {\n return operations;\n }\n\n const filterId = filter.id;\n const filterConstrainsId =\n Object.hasOwn(filter, \"id\") &&\n (filterId === null ||\n typeof filterId !== \"object\" ||\n (!Array.isArray(filterId) && Object.hasOwn(filterId, \"$eq\")));\n const updateSuppliesId =\n Object.hasOwn(operations.$set ?? {}, \"id\") ||\n Object.hasOwn(operations.$setOnInsert ?? {}, \"id\");\n\n if (filterConstrainsId || updateSuppliesId) {\n return operations;\n }\n\n const id = await generateModelId(ModelClass);\n\n if (id === undefined) {\n return operations;\n }\n\n return {\n ...operations,\n $setOnInsert: { ...operations.$setOnInsert, id },\n };\n}\n\n/**\n * Pin a driver-level write to the rows the model's global scopes (tenant, soft\n * delete) allow. The driver write APIs take a raw filter and never see scopes,\n * so the target ids are resolved through the scoped query builder and added to\n * the filter. `null` means no visible row matches: the write must be a no-op.\n */\nexport async function scopeWriteFilter(\n ModelClass: ChildModel<any>,\n filter: Record<string, unknown>,\n single: boolean,\n trustedFilter = false,\n): Promise<Record<string, unknown> | null> {\n const primaryKey = ModelClass.primaryKey;\n const query = ModelClass.query();\n const ids = await applyWriteFilter(query, filter, trustedFilter).pluck(primaryKey);\n\n if (ids.length === 0) {\n return null;\n }\n\n return { ...filter, [primaryKey]: single ? ids[0] : { $in: ids } };\n}\n\n/**\n * Scoped filter for a write that may insert (`upsert`). With no visible match\n * the driver would insert or, worse, update a row a scope hides (another\n * tenant's, a soft-deleted one), so a hidden match is refused.\n */\nexport async function scopeUpsertFilter(\n ModelClass: ChildModel<any>,\n filter: Record<string, unknown>,\n trustedFilter = false,\n): Promise<Record<string, unknown>> {\n const scoped = await scopeWriteFilter(ModelClass, filter, true, trustedFilter);\n\n if (scoped) {\n return scoped;\n }\n\n const query = ModelClass.query().withoutGlobalScopes();\n const hidden = await applyWriteFilter(query, filter, trustedFilter).exists();\n\n if (hidden) {\n throw new Error(\n `${ModelClass.name}: upsert matches a row hidden by a global scope (tenant or soft delete); refusing to touch it.`,\n );\n }\n\n return filter;\n}\n\n/**\n * Run an atomic update and return the number of documents modified plus the\n * number inserted by an `upsert`.\n */\nexport async function performAtomic<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n operations: AtomicUpdate,\n options?: AtomicUpdateOptions,\n): Promise<number> {\n const resolved = resolveFilter(filter, options);\n const scoped = options?.upsert\n ? await scopeUpsertFilter(ModelClass, resolved, options?.trustedFilter)\n : await scopeWriteFilter(ModelClass, resolved, false, options?.trustedFilter);\n\n if (!scoped) {\n return 0;\n }\n\n const upsertOperations = await withAutoGeneratedUpsertId(ModelClass, scoped, operations, options);\n\n const result = await ModelClass.getDriver().atomic(\n ModelClass.table,\n scoped,\n upsertOperations,\n toDriverOptions(options),\n );\n\n return result.modifiedCount + (result.upsertedCount ?? 0);\n}\n\n/**\n * Update a row by id through the model writer: the row is loaded (scopes\n * apply), merged, and saved, so the schema, strictMode, casting, `updatedAt`\n * and events all apply. Returns 1 when a row was saved, 0 when none is visible.\n */\nexport async function updateById<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n id: string | number,\n data: Record<string, unknown>,\n): Promise<number> {\n const model = await ModelClass.query().where(ModelClass.primaryKey, id).first();\n\n if (!model) {\n return 0;\n }\n\n model.merge(data);\n await model.save();\n\n return 1;\n}\n\nexport async function findAndUpdateRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n update: AtomicUpdate,\n options?: AtomicUpdateOptions,\n): Promise<TModel[]> {\n const primaryKey = ModelClass.primaryKey;\n const safeFilter = resolveFilter(filter, options);\n\n // Capture the matching ids first: the update usually changes the very field\n // the filter matches on, so re-querying with the filter would find nothing.\n const query = ModelClass.query();\n const ids = await applyWriteFilter(query, safeFilter, options?.trustedFilter ?? false).pluck(\n primaryKey,\n );\n\n if (ids.length === 0) {\n if (!options?.upsert) {\n return [];\n }\n\n await performAtomic(ModelClass, safeFilter, update, { ...options, trustedFilter: true });\n return await ModelClass.query().where(safeFilter).get();\n }\n\n await performAtomic(ModelClass, { [primaryKey]: { $in: ids } }, update, {\n ...options,\n trustedFilter: true,\n });\n\n return await ModelClass.query().whereIn(primaryKey, ids).get();\n}\n\nexport async function findOneAndUpdateRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n update: AtomicUpdate,\n options?: FindOneAndUpdateOptions,\n): Promise<TModel | null> {\n const resolved = resolveFilter(filter, options);\n const scoped = options?.upsert\n ? await scopeUpsertFilter(ModelClass, resolved, options?.trustedFilter)\n : await scopeWriteFilter(ModelClass, resolved, true, options?.trustedFilter);\n\n if (!scoped) return null;\n\n const upsertUpdate = await withAutoGeneratedUpsertId(ModelClass, scoped, update, options);\n\n const result = await ModelClass.getDriver().findOneAndUpdate(\n ModelClass.table,\n scoped,\n upsertUpdate,\n toDriverOptions(options),\n );\n if (!result) return null;\n return ModelClass.hydrate(result as Record<string, unknown>) as TModel;\n}\n\nexport async function findAndReplaceRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n document: Record<string, unknown>,\n): Promise<TModel | null> {\n const scoped = await scopeWriteFilter(ModelClass, sanitizeFilter(filter), true);\n\n if (!scoped) return null;\n\n const result = await ModelClass.getDriver().replace(ModelClass.table, scoped, document);\n if (!result) return null;\n return ModelClass.hydrate(result as Record<string, unknown>) as TModel;\n}\n\nexport async function findOneAndDeleteRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n options?: Record<string, unknown>,\n): Promise<TModel | null> {\n const scoped = await scopeWriteFilter(ModelClass, sanitizeFilter(filter), true);\n\n if (!scoped) {\n return null;\n }\n\n const result = await ModelClass.getDriver().findOneAndDelete(ModelClass.table, scoped, options);\n\n if (!result) {\n return null;\n }\n\n const model = ModelClass.hydrate(result as Record<string, unknown>);\n model.dirtyTracker.reset();\n return model;\n}\n\nexport function resolveDataSource<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n): DataSource {\n const ref = ModelClass.dataSource;\n let dataSource: DataSource;\n\n if (typeof ref === \"string\") {\n dataSource = dataSourceRegistry.get(ref);\n } else if (ref) {\n dataSource = ref;\n } else {\n dataSource = dataSourceRegistry.get();\n }\n\n if (!ModelClass.hasOwnProperty(\"_defaultsApplied\")) {\n const driverDefaults = dataSource.driver.modelDefaults || {};\n const dataSourceDefaults = dataSource.modelDefaults || {};\n\n const mergedDefaults = {\n ...driverDefaults,\n ...dataSourceDefaults,\n };\n\n if (Object.keys(mergedDefaults).length > 0) {\n (ModelClass as any).applyModelDefaults(mergedDefaults);\n }\n\n (ModelClass as any)._defaultsApplied = true;\n }\n\n // First data-source resolution is the earliest per-class hook every model\n // passes through — warn here (once) if the schema carries credential-shaped\n // fields that toJSON() would expose.\n warnUndeclaredSensitiveFields(ModelClass);\n\n return dataSource;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"query-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/query-methods.ts"],"sourcesContent":["import type {\n AtomicUpdate,\n AtomicUpdateOptions,\n FindOneAndUpdateOptions,\n PaginationOptions,\n PaginationResult,\n QueryBuilderContract,\n} from \"../../contracts\";\nimport type { DataSource } from \"../../data-source/data-source\";\nimport { dataSourceRegistry } from \"../../data-source/data-source-registry\";\nimport { sanitizeFilter } from \"../../utils/sanitize-filter\";\nimport { generateModelId } from \"../generate-model-id\";\nimport type { ChildModel, GlobalScopeDefinition, Model } from \"../model\";\nimport { emitStaticEvent } from \"./static-event-methods\";\nimport { warnUndeclaredSensitiveFields } from \"./serialization-methods\";\n\nexport function buildQuery<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n BaseModel: typeof Model,\n): QueryBuilderContract<TModel> {\n const queryBuilder = ModelClass.newQueryBuilder<TModel>();\n\n // Collect global scopes from base Model and child model\n const allGlobalScopes = new Map<string, GlobalScopeDefinition>([\n ...BaseModel.globalScopes,\n ...ModelClass.globalScopes,\n ]);\n\n queryBuilder.pendingGlobalScopes = allGlobalScopes;\n queryBuilder.availableLocalScopes = ModelClass.localScopes;\n queryBuilder.disabledGlobalScopes = new Set();\n queryBuilder.relationDefinitions = ModelClass.relations;\n queryBuilder.modelClass = ModelClass;\n\n let fetchStartedAt = Date.now();\n\n // Emitted from the builder's execute path (awaited), not at construction, so\n // listener changes apply before the query runs and a throwing listener fails\n // the query instead of becoming an unhandled rejection.\n queryBuilder.onFetching(async () => {\n fetchStartedAt = Date.now();\n\n await emitStaticEvent(ModelClass, \"fetching\", queryBuilder, {\n table: ModelClass.table,\n modelClass: ModelClass,\n });\n });\n\n queryBuilder.onHydrating(async (records: any[], context: any) => {\n await emitStaticEvent(ModelClass, \"hydrating\", records as any, {\n query: queryBuilder,\n hydrateCallback: context?.hydrateCallback,\n });\n });\n\n queryBuilder.hydrate((data: any) => {\n return ModelClass.hydrate(data);\n });\n\n // Eager-loading runs inside the driver's `get()` so it works for any\n // builder construction path (Model.query, Model.newQueryBuilder, custom\n // subclassed builders). This hook only handles the model-level `fetched`\n // event emission.\n queryBuilder.onFetched(async (models: any[], context: any) => {\n await emitStaticEvent(ModelClass, \"fetched\", models as any, {\n query: queryBuilder,\n rawRecords: context?.rawRecords ?? [],\n duration: context?.duration ?? Date.now() - fetchStartedAt,\n });\n });\n\n return queryBuilder;\n}\n\nexport function buildNewQueryBuilder<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n): QueryBuilderContract<TModel> {\n const dataSource = ModelClass.getDataSource();\n\n if (ModelClass.builder) {\n const BuilderClass = ModelClass.builder;\n return new BuilderClass(ModelClass.table, dataSource) as QueryBuilderContract<TModel>;\n }\n\n const queryBuilder = dataSource.driver.queryBuilder<TModel>(ModelClass.table);\n return queryBuilder;\n}\n\nexport async function findFirst<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel | null> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return query.first();\n}\n\nexport async function findLast<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel | null> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n\n return query.last();\n}\n\nexport async function findAll<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel[]> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return query.get();\n}\n\nexport function countRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<number> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return query.count();\n}\n\nexport async function findById<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n id: string | number,\n): Promise<TModel | null> {\n const query = ModelClass.query();\n return query.where(ModelClass.primaryKey, id).first();\n}\n\nexport async function paginateRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n options: PaginationOptions & { filter?: Record<string, unknown> } = {},\n): Promise<PaginationResult<TModel>> {\n const query = ModelClass.query();\n if (options.filter) {\n query.where(options.filter);\n }\n\n return query.paginate({\n limit: options.limit,\n page: options.page,\n });\n}\n\nexport async function findLatest<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter?: Record<string, unknown>,\n): Promise<TModel[]> {\n const query = ModelClass.query();\n if (filter) {\n query.where(filter);\n }\n return (await query.latest()) as unknown as TModel[];\n}\n\nexport function increaseField<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n field: string,\n amount: number,\n): Promise<number> {\n const query = ModelClass.query().where(filter);\n return query.increment(field, amount);\n}\n\nexport function decreaseField<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n field: string,\n amount: number,\n): Promise<number> {\n const query = ModelClass.query().where(filter);\n return query.decrement(field, amount);\n}\n\n// The atomic/find-and-modify statics below forward their filter straight to\n// the driver — they never pass through where(), so they must run the same\n// operator-injection check themselves. Only the FILTER is sanitized; update\n// operators ($set/$inc/…) are the point of these APIs and stay untouched.\n//\n// `trustedFilter` is the explicit, code-authored opt-out: it lets a conditional\n// filter such as `{ used: { $lt: 10 } }` through. It is stripped before the\n// options reach the driver.\nfunction resolveFilter(\n filter: Record<string, unknown>,\n options: AtomicUpdateOptions | undefined,\n): Record<string, unknown> {\n return options?.trustedFilter ? filter : sanitizeFilter(filter);\n}\n\nfunction toDriverOptions<TOptions extends AtomicUpdateOptions>(\n options: TOptions | undefined,\n): Omit<TOptions, \"trustedFilter\"> | undefined {\n if (!options) {\n return undefined;\n }\n\n const { trustedFilter: _trustedFilter, ...rest } = options;\n\n return rest;\n}\n\nfunction applyWriteFilter<TModel extends Model>(\n query: QueryBuilderContract<TModel>,\n filter: Record<string, unknown>,\n trustedFilter: boolean,\n): QueryBuilderContract<TModel> {\n // Query builders supplied by integrations predating `whereTrusted` can\n // still apply a code-authored filter through their regular `where` method.\n // Concrete Cascade builders implement `whereTrusted`, which is required for\n // MongoDB operator filters; retain the fallback for compatible custom\n // builders and test doubles.\n if (trustedFilter && typeof query.whereTrusted === \"function\") {\n return query.whereTrusted(filter);\n }\n\n return query.where(filter);\n}\n\n/**\n * Add the same generated `id` that normal Mongo inserts receive to an upsert's\n * insert branch. `$setOnInsert` keeps an existing document's id immutable.\n */\nasync function withAutoGeneratedUpsertId<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n operations: AtomicUpdate,\n options: AtomicUpdateOptions | undefined,\n): Promise<AtomicUpdate> {\n if (\n !options?.upsert ||\n !ModelClass.autoGenerateId ||\n ModelClass.getDriver().name !== \"mongodb\" ||\n Array.isArray(operations)\n ) {\n return operations;\n }\n\n const filterId = filter.id;\n const filterConstrainsId =\n Object.hasOwn(filter, \"id\") &&\n (filterId === null ||\n typeof filterId !== \"object\" ||\n (!Array.isArray(filterId) && Object.hasOwn(filterId, \"$eq\")));\n const updateSuppliesId =\n Object.hasOwn(operations.$set ?? {}, \"id\") ||\n Object.hasOwn(operations.$setOnInsert ?? {}, \"id\");\n\n if (filterConstrainsId || updateSuppliesId) {\n return operations;\n }\n\n const id = await generateModelId(ModelClass);\n\n if (id === undefined) {\n return operations;\n }\n\n return {\n ...operations,\n $setOnInsert: { ...operations.$setOnInsert, id },\n };\n}\n\n/**\n * Pin a driver-level write to the rows the model's global scopes (tenant, soft\n * delete) allow. The driver write APIs take a raw filter and never see scopes,\n * so the target ids are resolved through the scoped query builder and added to\n * the filter. `null` means no visible row matches: the write must be a no-op.\n */\nexport async function scopeWriteFilter(\n ModelClass: ChildModel<any>,\n filter: Record<string, unknown>,\n single: boolean,\n trustedFilter = false,\n): Promise<Record<string, unknown> | null> {\n const primaryKey = ModelClass.primaryKey;\n const query = ModelClass.query();\n const ids = await applyWriteFilter(query, filter, trustedFilter).pluck(primaryKey);\n\n if (ids.length === 0) {\n return null;\n }\n\n return { ...filter, [primaryKey]: single ? ids[0] : { $in: ids } };\n}\n\n/**\n * Scoped filter for a write that may insert (`upsert`). With no visible match\n * the driver would insert or, worse, update a row a scope hides (another\n * tenant's, a soft-deleted one), so a hidden match is refused.\n */\nexport async function scopeUpsertFilter(\n ModelClass: ChildModel<any>,\n filter: Record<string, unknown>,\n trustedFilter = false,\n): Promise<Record<string, unknown>> {\n const scoped = await scopeWriteFilter(ModelClass, filter, true, trustedFilter);\n\n if (scoped) {\n return scoped;\n }\n\n const query = ModelClass.query().withoutGlobalScopes();\n const hidden = await applyWriteFilter(query, filter, trustedFilter).exists();\n\n if (hidden) {\n throw new Error(\n `${ModelClass.name}: upsert matches a row hidden by a global scope (tenant or soft delete); refusing to touch it.`,\n );\n }\n\n return filter;\n}\n\n/**\n * Run an atomic update and return the number of documents modified plus the\n * number inserted by an `upsert`.\n */\nexport async function performAtomic<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n operations: AtomicUpdate,\n options?: AtomicUpdateOptions,\n): Promise<number> {\n const resolved = resolveFilter(filter, options);\n const scoped = options?.upsert\n ? await scopeUpsertFilter(ModelClass, resolved, options?.trustedFilter)\n : await scopeWriteFilter(ModelClass, resolved, false, options?.trustedFilter);\n\n if (!scoped) {\n return 0;\n }\n\n const upsertOperations = await withAutoGeneratedUpsertId(ModelClass, scoped, operations, options);\n\n const result = await ModelClass.getDriver().atomic(\n ModelClass.table,\n scoped,\n upsertOperations,\n toDriverOptions(options),\n );\n\n return result.modifiedCount + (result.upsertedCount ?? 0);\n}\n\n/**\n * Update a row by id through the model writer: the row is loaded (scopes\n * apply), merged, and saved, so the schema, strictMode, casting, `updatedAt`\n * and events all apply. Returns 1 when a row was saved, 0 when none is visible.\n */\nexport async function updateById<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n id: string | number,\n data: Record<string, unknown>,\n): Promise<number> {\n const model = await ModelClass.query().where(ModelClass.primaryKey, id).first();\n\n if (!model) {\n return 0;\n }\n\n model.merge(data);\n await model.save();\n\n return 1;\n}\n\nexport async function findAndUpdateRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n update: AtomicUpdate,\n options?: AtomicUpdateOptions,\n): Promise<TModel[]> {\n const primaryKey = ModelClass.primaryKey;\n const safeFilter = resolveFilter(filter, options);\n\n // Capture the matching ids first: the update usually changes the very field\n // the filter matches on, so re-querying with the filter would find nothing.\n const query = ModelClass.query();\n const ids = await applyWriteFilter(query, safeFilter, options?.trustedFilter ?? false).pluck(\n primaryKey,\n );\n\n if (ids.length === 0) {\n if (!options?.upsert) {\n return [];\n }\n\n await performAtomic(ModelClass, safeFilter, update, { ...options, trustedFilter: true });\n return await ModelClass.query().where(safeFilter).get();\n }\n\n await performAtomic(ModelClass, { [primaryKey]: { $in: ids } }, update, {\n ...options,\n trustedFilter: true,\n });\n\n return await ModelClass.query().whereIn(primaryKey, ids).get();\n}\n\nexport async function findOneAndUpdateRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n update: AtomicUpdate,\n options?: FindOneAndUpdateOptions,\n): Promise<TModel | null> {\n const resolved = resolveFilter(filter, options);\n const scoped = options?.upsert\n ? await scopeUpsertFilter(ModelClass, resolved, options?.trustedFilter)\n : await scopeWriteFilter(ModelClass, resolved, true, options?.trustedFilter);\n\n if (!scoped) return null;\n\n const upsertUpdate = await withAutoGeneratedUpsertId(ModelClass, scoped, update, options);\n\n const result = await ModelClass.getDriver().findOneAndUpdate(\n ModelClass.table,\n scoped,\n upsertUpdate,\n toDriverOptions(options),\n );\n if (!result) return null;\n return ModelClass.hydrate(result as Record<string, unknown>) as TModel;\n}\n\nexport async function findAndReplaceRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n document: Record<string, unknown>,\n): Promise<TModel | null> {\n const scoped = await scopeWriteFilter(ModelClass, sanitizeFilter(filter), true);\n\n if (!scoped) return null;\n\n const result = await ModelClass.getDriver().replace(ModelClass.table, scoped, document);\n if (!result) return null;\n return ModelClass.hydrate(result as Record<string, unknown>) as TModel;\n}\n\nexport async function findOneAndDeleteRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n filter: Record<string, unknown>,\n options?: Record<string, unknown>,\n): Promise<TModel | null> {\n const scoped = await scopeWriteFilter(ModelClass, sanitizeFilter(filter), true);\n\n if (!scoped) {\n return null;\n }\n\n const result = await ModelClass.getDriver().findOneAndDelete(ModelClass.table, scoped, options);\n\n if (!result) {\n return null;\n }\n\n const model = ModelClass.hydrate(result as Record<string, unknown>);\n model.dirtyTracker.reset();\n return model;\n}\n\nexport function resolveDataSource<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n): DataSource {\n const ref = ModelClass.dataSource;\n let dataSource: DataSource;\n\n if (typeof ref === \"string\") {\n dataSource = dataSourceRegistry.get(ref);\n } else if (ref) {\n dataSource = ref;\n } else {\n dataSource = dataSourceRegistry.get();\n }\n\n if (!ModelClass.hasOwnProperty(\"_defaultsApplied\")) {\n const driverDefaults = dataSource.driver.modelDefaults || {};\n const dataSourceDefaults = dataSource.modelDefaults || {};\n\n const mergedDefaults = {\n ...driverDefaults,\n ...dataSourceDefaults,\n };\n\n if (Object.keys(mergedDefaults).length > 0) {\n (ModelClass as any).applyModelDefaults(mergedDefaults);\n }\n\n (ModelClass as any)._defaultsApplied = true;\n }\n\n // First data-source resolution is the earliest per-class hook every model\n // passes through — warn here (once) if the schema carries credential-shaped\n // fields that toJSON() would expose.\n warnUndeclaredSensitiveFields(ModelClass);\n\n return dataSource;\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { DatabaseRestorer } from "../../restorer/database-restorer.mjs";
2
2
 
3
- //#region ../cascade/src/model/methods/restore-methods.ts
3
+ //#region ../../packages/cascade/src/model/methods/restore-methods.ts
4
4
  async function restoreRecord(ModelClass, id, options) {
5
5
  const result = await new DatabaseRestorer(ModelClass).restore(id, options);
6
6
  if (!result.restoredRecord) throw new Error(`Failed to restore ${ModelClass.name} with ${ModelClass.primaryKey} ${id}: no record returned.`);
@@ -1 +1 @@
1
- {"version":3,"file":"restore-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/restore-methods.ts"],"sourcesContent":["import { DatabaseRestorer } from \"../../restorer/database-restorer\";\nimport type { ChildModel, Model } from \"../model\";\n\nexport async function restoreRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n id: string | number,\n options?: { onIdConflict?: \"fail\" | \"assignNew\"; skipEvents?: boolean },\n): Promise<TModel> {\n const restorer = new DatabaseRestorer(ModelClass as unknown as typeof Model);\n const result = await restorer.restore(id, options);\n\n if (!result.restoredRecord) {\n throw new Error(\n `Failed to restore ${ModelClass.name} with ${ModelClass.primaryKey} ${id}: no record returned.`,\n );\n }\n\n return result.restoredRecord as TModel;\n}\n\nexport async function restoreAllRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n options?: { onIdConflict?: \"fail\" | \"assignNew\"; skipEvents?: boolean },\n): Promise<TModel[]> {\n const restorer = new DatabaseRestorer(ModelClass as unknown as typeof Model);\n const result = await restorer.restoreAll(options);\n\n return result.restoredCount === 0 ? [] : (result.restoredRecords as TModel[]);\n}\n"],"mappings":";;;AAGA,eAAsB,cACpB,YACA,IACA,SACiB;CAEjB,MAAM,SAAS,MAAM,IADA,iBAAiB,UACV,CAAC,CAAC,QAAQ,IAAI,OAAO;CAEjD,IAAI,CAAC,OAAO,gBACV,MAAM,IAAI,MACR,qBAAqB,WAAW,KAAK,QAAQ,WAAW,WAAW,GAAG,GAAG,sBAC3E;CAGF,OAAO,OAAO;AAChB;AAEA,eAAsB,kBACpB,YACA,SACmB;CAEnB,MAAM,SAAS,MAAM,IADA,iBAAiB,UACV,CAAC,CAAC,WAAW,OAAO;CAEhD,OAAO,OAAO,kBAAkB,IAAI,CAAC,IAAK,OAAO;AACnD"}
1
+ {"version":3,"file":"restore-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/restore-methods.ts"],"sourcesContent":["import { DatabaseRestorer } from \"../../restorer/database-restorer\";\nimport type { ChildModel, Model } from \"../model\";\n\nexport async function restoreRecord<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n id: string | number,\n options?: { onIdConflict?: \"fail\" | \"assignNew\"; skipEvents?: boolean },\n): Promise<TModel> {\n const restorer = new DatabaseRestorer(ModelClass as unknown as typeof Model);\n const result = await restorer.restore(id, options);\n\n if (!result.restoredRecord) {\n throw new Error(\n `Failed to restore ${ModelClass.name} with ${ModelClass.primaryKey} ${id}: no record returned.`,\n );\n }\n\n return result.restoredRecord as TModel;\n}\n\nexport async function restoreAllRecords<TModel extends Model>(\n ModelClass: ChildModel<TModel>,\n options?: { onIdConflict?: \"fail\" | \"assignNew\"; skipEvents?: boolean },\n): Promise<TModel[]> {\n const restorer = new DatabaseRestorer(ModelClass as unknown as typeof Model);\n const result = await restorer.restoreAll(options);\n\n return result.restoredCount === 0 ? [] : (result.restoredRecords as TModel[]);\n}\n"],"mappings":";;;AAGA,eAAsB,cACpB,YACA,IACA,SACiB;CAEjB,MAAM,SAAS,MAAM,IADA,iBAAiB,UACV,CAAC,CAAC,QAAQ,IAAI,OAAO;CAEjD,IAAI,CAAC,OAAO,gBACV,MAAM,IAAI,MACR,qBAAqB,WAAW,KAAK,QAAQ,WAAW,WAAW,GAAG,GAAG,sBAC3E;CAGF,OAAO,OAAO;AAChB;AAEA,eAAsB,kBACpB,YACA,SACmB;CAEnB,MAAM,SAAS,MAAM,IADA,iBAAiB,UACV,CAAC,CAAC,WAAW,OAAO;CAEhD,OAAO,OAAO,kBAAkB,IAAI,CAAC,IAAK,OAAO;AACnD"}
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/model/methods/scope-methods.ts
1
+ //#region ../../packages/cascade/src/model/methods/scope-methods.ts
2
2
  /**
3
3
  * Give the model class its OWN scope map before mutating.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"scope-methods.mjs","names":[],"sources":["../../../../../../../../cascade/src/model/methods/scope-methods.ts"],"sourcesContent":["import type { QueryBuilderContract } from \"../../contracts\";\nimport type { GlobalScopeOptions, LocalScopeCallback, ChildModel, Model } from \"../model\";\n\n/**\n * Give the model class its OWN scope map before mutating.\n *\n * The `globalScopes` / `localScopes` statics live on the base `Model`; without\n * this, `ModelClass.globalScopes.set(...)` from any subclass mutates the ONE\n * inherited Map and the scope leaks onto every other model (a soft-delete\n * `notDeleted` scope registered on `User` would filter `Post` too). The own\n * map snapshots the currently-inherited entries so parent scopes registered so\n * far are kept.\n */\nfunction ownScopeMap(\n ModelClass: ChildModel<any>,\n property: \"globalScopes\" | \"localScopes\",\n): Map<string, any> {\n if (!Object.prototype.hasOwnProperty.call(ModelClass, property)) {\n (ModelClass as any)[property] = new Map((ModelClass as any)[property]);\n }\n\n return (ModelClass as any)[property];\n}\n\nexport function addGlobalModelScope(\n ModelClass: ChildModel<any>,\n name: string,\n callback: (query: QueryBuilderContract) => void,\n options: GlobalScopeOptions = {},\n): void {\n ownScopeMap(ModelClass, \"globalScopes\").set(name, {\n callback,\n timing: options.timing || \"before\",\n });\n}\n\nexport function removeGlobalModelScope(ModelClass: ChildModel<any>, name: string): void {\n ownScopeMap(ModelClass, \"globalScopes\").delete(name);\n}\n\nexport function addLocalModelScope(\n ModelClass: ChildModel<any>,\n name: string,\n callback: LocalScopeCallback,\n): void {\n ownScopeMap(ModelClass, \"localScopes\").set(name, callback);\n}\n\nexport function removeLocalModelScope(ModelClass: ChildModel<any>, name: string): void {\n ownScopeMap(ModelClass, \"localScopes\").delete(name);\n}\n"],"mappings":";;;;;;;;;;;AAaA,SAAS,YACP,YACA,UACkB;CAClB,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,YAAY,QAAQ,GAC5D,AAAC,WAAmB,YAAY,IAAI,IAAK,WAAmB,SAAS;CAGvE,OAAQ,WAAmB;AAC7B;AAEA,SAAgB,oBACd,YACA,MACA,UACA,UAA8B,CAAC,GACzB;CACN,YAAY,YAAY,cAAc,CAAC,CAAC,IAAI,MAAM;EAChD;EACA,QAAQ,QAAQ,UAAU;CAC5B,CAAC;AACH;AAEA,SAAgB,uBAAuB,YAA6B,MAAoB;CACtF,YAAY,YAAY,cAAc,CAAC,CAAC,OAAO,IAAI;AACrD;AAEA,SAAgB,mBACd,YACA,MACA,UACM;CACN,YAAY,YAAY,aAAa,CAAC,CAAC,IAAI,MAAM,QAAQ;AAC3D;AAEA,SAAgB,sBAAsB,YAA6B,MAAoB;CACrF,YAAY,YAAY,aAAa,CAAC,CAAC,OAAO,IAAI;AACpD"}
1
+ {"version":3,"file":"scope-methods.mjs","names":[],"sources":["../../../../../../../../../packages/cascade/src/model/methods/scope-methods.ts"],"sourcesContent":["import type { QueryBuilderContract } from \"../../contracts\";\nimport type { GlobalScopeOptions, LocalScopeCallback, ChildModel } from \"../model\";\n\n/**\n * Give the model class its OWN scope map before mutating.\n *\n * The `globalScopes` / `localScopes` statics live on the base `Model`; without\n * this, `ModelClass.globalScopes.set(...)` from any subclass mutates the ONE\n * inherited Map and the scope leaks onto every other model (a soft-delete\n * `notDeleted` scope registered on `User` would filter `Post` too). The own\n * map snapshots the currently-inherited entries so parent scopes registered so\n * far are kept.\n */\nfunction ownScopeMap(\n ModelClass: ChildModel<any>,\n property: \"globalScopes\" | \"localScopes\",\n): Map<string, any> {\n if (!Object.prototype.hasOwnProperty.call(ModelClass, property)) {\n (ModelClass as any)[property] = new Map((ModelClass as any)[property]);\n }\n\n return (ModelClass as any)[property];\n}\n\nexport function addGlobalModelScope(\n ModelClass: ChildModel<any>,\n name: string,\n callback: (query: QueryBuilderContract) => void,\n options: GlobalScopeOptions = {},\n): void {\n ownScopeMap(ModelClass, \"globalScopes\").set(name, {\n callback,\n timing: options.timing || \"before\",\n });\n}\n\nexport function removeGlobalModelScope(ModelClass: ChildModel<any>, name: string): void {\n ownScopeMap(ModelClass, \"globalScopes\").delete(name);\n}\n\nexport function addLocalModelScope(\n ModelClass: ChildModel<any>,\n name: string,\n callback: LocalScopeCallback,\n): void {\n ownScopeMap(ModelClass, \"localScopes\").set(name, callback);\n}\n\nexport function removeLocalModelScope(ModelClass: ChildModel<any>, name: string): void {\n ownScopeMap(ModelClass, \"localScopes\").delete(name);\n}\n"],"mappings":";;;;;;;;;;;AAaA,SAAS,YACP,YACA,UACkB;CAClB,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,YAAY,QAAQ,GAC5D,AAAC,WAAmB,YAAY,IAAI,IAAK,WAAmB,SAAS;CAGvE,OAAQ,WAAmB;AAC7B;AAEA,SAAgB,oBACd,YACA,MACA,UACA,UAA8B,CAAC,GACzB;CACN,YAAY,YAAY,cAAc,CAAC,CAAC,IAAI,MAAM;EAChD;EACA,QAAQ,QAAQ,UAAU;CAC5B,CAAC;AACH;AAEA,SAAgB,uBAAuB,YAA6B,MAAoB;CACtF,YAAY,YAAY,cAAc,CAAC,CAAC,OAAO,IAAI;AACrD;AAEA,SAAgB,mBACd,YACA,MACA,UACM;CACN,YAAY,YAAY,aAAa,CAAC,CAAC,IAAI,MAAM,QAAQ;AAC3D;AAEA,SAAgB,sBAAsB,YAA6B,MAAoB;CACrF,YAAY,YAAY,aAAa,CAAC,CAAC,OAAO,IAAI;AACpD"}
@@ -1,4 +1,4 @@
1
- //#region ../cascade/src/model/methods/serialization-methods.ts
1
+ //#region ../../packages/cascade/src/model/methods/serialization-methods.ts
2
2
  /**
3
3
  * Field names that commonly hold credentials/secrets. Used only to emit a
4
4
  * one-time warning when such a field exists in a model's schema but is not