@quilla-be-kit/persistence-init-test 0.1.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 (211) hide show
  1. package/README.md +684 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/dao/audit-columns.d.ts +19 -0
  4. package/dist/dao/audit-columns.d.ts.map +1 -0
  5. package/dist/dao/audit-columns.js +26 -0
  6. package/dist/dao/audit-columns.js.map +1 -0
  7. package/dist/dao/base-read.dao.d.ts +50 -0
  8. package/dist/dao/base-read.dao.d.ts.map +1 -0
  9. package/dist/dao/base-read.dao.js +65 -0
  10. package/dist/dao/base-read.dao.js.map +1 -0
  11. package/dist/dao/base-write.dao.d.ts +49 -0
  12. package/dist/dao/base-write.dao.d.ts.map +1 -0
  13. package/dist/dao/base-write.dao.js +130 -0
  14. package/dist/dao/base-write.dao.js.map +1 -0
  15. package/dist/dao/index.d.ts +3 -0
  16. package/dist/dao/index.d.ts.map +1 -0
  17. package/dist/dao/index.js +3 -0
  18. package/dist/dao/index.js.map +1 -0
  19. package/dist/database/database-health.type.d.ts +4 -0
  20. package/dist/database/database-health.type.d.ts.map +1 -0
  21. package/dist/database/database-health.type.js +2 -0
  22. package/dist/database/database-health.type.js.map +1 -0
  23. package/dist/database/database-result.type.d.ts +5 -0
  24. package/dist/database/database-result.type.d.ts.map +1 -0
  25. package/dist/database/database-result.type.js +2 -0
  26. package/dist/database/database-result.type.js.map +1 -0
  27. package/dist/database/database-transaction.interface.d.ts +10 -0
  28. package/dist/database/database-transaction.interface.d.ts.map +1 -0
  29. package/dist/database/database-transaction.interface.js +2 -0
  30. package/dist/database/database-transaction.interface.js.map +1 -0
  31. package/dist/database/database.interface.d.ts +10 -0
  32. package/dist/database/database.interface.d.ts.map +1 -0
  33. package/dist/database/database.interface.js +2 -0
  34. package/dist/database/database.interface.js.map +1 -0
  35. package/dist/database/index.d.ts +5 -0
  36. package/dist/database/index.d.ts.map +1 -0
  37. package/dist/database/index.js +2 -0
  38. package/dist/database/index.js.map +1 -0
  39. package/dist/db-adapter/filter-query.type.d.ts +4 -0
  40. package/dist/db-adapter/filter-query.type.d.ts.map +1 -0
  41. package/dist/db-adapter/filter-query.type.js +2 -0
  42. package/dist/db-adapter/filter-query.type.js.map +1 -0
  43. package/dist/db-adapter/index.d.ts +4 -0
  44. package/dist/db-adapter/index.d.ts.map +1 -0
  45. package/dist/db-adapter/index.js +2 -0
  46. package/dist/db-adapter/index.js.map +1 -0
  47. package/dist/db-adapter/read-db-adapter.interface.d.ts +37 -0
  48. package/dist/db-adapter/read-db-adapter.interface.d.ts.map +1 -0
  49. package/dist/db-adapter/read-db-adapter.interface.js +2 -0
  50. package/dist/db-adapter/read-db-adapter.interface.js.map +1 -0
  51. package/dist/db-adapter/write-db-adapter.interface.d.ts +61 -0
  52. package/dist/db-adapter/write-db-adapter.interface.d.ts.map +1 -0
  53. package/dist/db-adapter/write-db-adapter.interface.js +2 -0
  54. package/dist/db-adapter/write-db-adapter.interface.js.map +1 -0
  55. package/dist/errors/cross-scope-access.error.d.ts +10 -0
  56. package/dist/errors/cross-scope-access.error.d.ts.map +1 -0
  57. package/dist/errors/cross-scope-access.error.js +15 -0
  58. package/dist/errors/cross-scope-access.error.js.map +1 -0
  59. package/dist/errors/index.d.ts +3 -0
  60. package/dist/errors/index.d.ts.map +1 -0
  61. package/dist/errors/index.js +3 -0
  62. package/dist/errors/index.js.map +1 -0
  63. package/dist/errors/optimistic-lock.error.d.ts +9 -0
  64. package/dist/errors/optimistic-lock.error.d.ts.map +1 -0
  65. package/dist/errors/optimistic-lock.error.js +11 -0
  66. package/dist/errors/optimistic-lock.error.js.map +1 -0
  67. package/dist/index.d.ts +8 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +8 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/postgres/index.d.ts +7 -0
  72. package/dist/postgres/index.d.ts.map +1 -0
  73. package/dist/postgres/index.js +7 -0
  74. package/dist/postgres/index.js.map +1 -0
  75. package/dist/postgres/pg-query-builder.d.ts +42 -0
  76. package/dist/postgres/pg-query-builder.d.ts.map +1 -0
  77. package/dist/postgres/pg-query-builder.js +260 -0
  78. package/dist/postgres/pg-query-builder.js.map +1 -0
  79. package/dist/postgres/pg-read-db-adapter.d.ts +20 -0
  80. package/dist/postgres/pg-read-db-adapter.d.ts.map +1 -0
  81. package/dist/postgres/pg-read-db-adapter.js +28 -0
  82. package/dist/postgres/pg-read-db-adapter.js.map +1 -0
  83. package/dist/postgres/pg-sql.d.ts +44 -0
  84. package/dist/postgres/pg-sql.d.ts.map +1 -0
  85. package/dist/postgres/pg-sql.js +128 -0
  86. package/dist/postgres/pg-sql.js.map +1 -0
  87. package/dist/postgres/pg-write-db-adapter.d.ts +30 -0
  88. package/dist/postgres/pg-write-db-adapter.d.ts.map +1 -0
  89. package/dist/postgres/pg-write-db-adapter.js +133 -0
  90. package/dist/postgres/pg-write-db-adapter.js.map +1 -0
  91. package/dist/postgres/pg.database.d.ts +25 -0
  92. package/dist/postgres/pg.database.d.ts.map +1 -0
  93. package/dist/postgres/pg.database.js +48 -0
  94. package/dist/postgres/pg.database.js.map +1 -0
  95. package/dist/postgres/pg.transaction.d.ts +22 -0
  96. package/dist/postgres/pg.transaction.d.ts.map +1 -0
  97. package/dist/postgres/pg.transaction.js +78 -0
  98. package/dist/postgres/pg.transaction.js.map +1 -0
  99. package/dist/query/case.d.ts +3 -0
  100. package/dist/query/case.d.ts.map +1 -0
  101. package/dist/query/case.js +7 -0
  102. package/dist/query/case.js.map +1 -0
  103. package/dist/query/column-resolver.interface.d.ts +4 -0
  104. package/dist/query/column-resolver.interface.d.ts.map +1 -0
  105. package/dist/query/column-resolver.interface.js +2 -0
  106. package/dist/query/column-resolver.interface.js.map +1 -0
  107. package/dist/query/default.resolver.d.ts +10 -0
  108. package/dist/query/default.resolver.d.ts.map +1 -0
  109. package/dist/query/default.resolver.js +14 -0
  110. package/dist/query/default.resolver.js.map +1 -0
  111. package/dist/query/field-descriptor.type.d.ts +11 -0
  112. package/dist/query/field-descriptor.type.d.ts.map +1 -0
  113. package/dist/query/field-descriptor.type.js +20 -0
  114. package/dist/query/field-descriptor.type.js.map +1 -0
  115. package/dist/query/filter-query.type.d.ts +4 -0
  116. package/dist/query/filter-query.type.d.ts.map +1 -0
  117. package/dist/query/filter-query.type.js +2 -0
  118. package/dist/query/filter-query.type.js.map +1 -0
  119. package/dist/query/index.d.ts +9 -0
  120. package/dist/query/index.d.ts.map +1 -0
  121. package/dist/query/index.js +3 -0
  122. package/dist/query/index.js.map +1 -0
  123. package/dist/query/list-query.type.d.ts +12 -0
  124. package/dist/query/list-query.type.d.ts.map +1 -0
  125. package/dist/query/list-query.type.js +2 -0
  126. package/dist/query/list-query.type.js.map +1 -0
  127. package/dist/query/paginated-result.type.d.ts +7 -0
  128. package/dist/query/paginated-result.type.d.ts.map +1 -0
  129. package/dist/query/paginated-result.type.js +2 -0
  130. package/dist/query/paginated-result.type.js.map +1 -0
  131. package/dist/query/query-product.type.d.ts +6 -0
  132. package/dist/query/query-product.type.d.ts.map +1 -0
  133. package/dist/query/query-product.type.js +2 -0
  134. package/dist/query/query-product.type.js.map +1 -0
  135. package/dist/query/read-query-builder.interface.d.ts +17 -0
  136. package/dist/query/read-query-builder.interface.d.ts.map +1 -0
  137. package/dist/query/read-query-builder.interface.js +2 -0
  138. package/dist/query/read-query-builder.interface.js.map +1 -0
  139. package/dist/query/sql-query-builder.interface.d.ts +99 -0
  140. package/dist/query/sql-query-builder.interface.d.ts.map +1 -0
  141. package/dist/query/sql-query-builder.interface.js +2 -0
  142. package/dist/query/sql-query-builder.interface.js.map +1 -0
  143. package/dist/query/sql-statement.type.d.ts +5 -0
  144. package/dist/query/sql-statement.type.d.ts.map +1 -0
  145. package/dist/query/sql-statement.type.js +2 -0
  146. package/dist/query/sql-statement.type.js.map +1 -0
  147. package/dist/query/write-query-builder.interface.d.ts +34 -0
  148. package/dist/query/write-query-builder.interface.d.ts.map +1 -0
  149. package/dist/query/write-query-builder.interface.js +2 -0
  150. package/dist/query/write-query-builder.interface.js.map +1 -0
  151. package/dist/query-schema/field-descriptor-from-zod.d.ts +4 -0
  152. package/dist/query-schema/field-descriptor-from-zod.d.ts.map +1 -0
  153. package/dist/query-schema/field-descriptor-from-zod.js +31 -0
  154. package/dist/query-schema/field-descriptor-from-zod.js.map +1 -0
  155. package/dist/query-schema/index.d.ts +3 -0
  156. package/dist/query-schema/index.d.ts.map +1 -0
  157. package/dist/query-schema/index.js +3 -0
  158. package/dist/query-schema/index.js.map +1 -0
  159. package/dist/query-schema/zod.d.ts +73 -0
  160. package/dist/query-schema/zod.d.ts.map +1 -0
  161. package/dist/query-schema/zod.js +191 -0
  162. package/dist/query-schema/zod.js.map +1 -0
  163. package/dist/repository/base-aggregate.repository.d.ts +28 -0
  164. package/dist/repository/base-aggregate.repository.d.ts.map +1 -0
  165. package/dist/repository/base-aggregate.repository.js +49 -0
  166. package/dist/repository/base-aggregate.repository.js.map +1 -0
  167. package/dist/repository/base-basic.repository.d.ts +22 -0
  168. package/dist/repository/base-basic.repository.d.ts.map +1 -0
  169. package/dist/repository/base-basic.repository.js +30 -0
  170. package/dist/repository/base-basic.repository.js.map +1 -0
  171. package/dist/repository/base-persistence.mapper.d.ts +61 -0
  172. package/dist/repository/base-persistence.mapper.d.ts.map +1 -0
  173. package/dist/repository/base-persistence.mapper.js +119 -0
  174. package/dist/repository/base-persistence.mapper.js.map +1 -0
  175. package/dist/repository/base-scoped-aggregate.repository.d.ts +19 -0
  176. package/dist/repository/base-scoped-aggregate.repository.d.ts.map +1 -0
  177. package/dist/repository/base-scoped-aggregate.repository.js +35 -0
  178. package/dist/repository/base-scoped-aggregate.repository.js.map +1 -0
  179. package/dist/repository/base-unscoped-aggregate.repository.d.ts +17 -0
  180. package/dist/repository/base-unscoped-aggregate.repository.d.ts.map +1 -0
  181. package/dist/repository/base-unscoped-aggregate.repository.js +21 -0
  182. package/dist/repository/base-unscoped-aggregate.repository.js.map +1 -0
  183. package/dist/repository/index.d.ts +7 -0
  184. package/dist/repository/index.d.ts.map +1 -0
  185. package/dist/repository/index.js +6 -0
  186. package/dist/repository/index.js.map +1 -0
  187. package/dist/repository/mapper.interface.d.ts +5 -0
  188. package/dist/repository/mapper.interface.d.ts.map +1 -0
  189. package/dist/repository/mapper.interface.js +2 -0
  190. package/dist/repository/mapper.interface.js.map +1 -0
  191. package/dist/unit-of-work/event-sink.interface.d.ts +5 -0
  192. package/dist/unit-of-work/event-sink.interface.d.ts.map +1 -0
  193. package/dist/unit-of-work/event-sink.interface.js +2 -0
  194. package/dist/unit-of-work/event-sink.interface.js.map +1 -0
  195. package/dist/unit-of-work/index.d.ts +4 -0
  196. package/dist/unit-of-work/index.d.ts.map +1 -0
  197. package/dist/unit-of-work/index.js +2 -0
  198. package/dist/unit-of-work/index.js.map +1 -0
  199. package/dist/unit-of-work/outbox-writer.interface.d.ts +14 -0
  200. package/dist/unit-of-work/outbox-writer.interface.d.ts.map +1 -0
  201. package/dist/unit-of-work/outbox-writer.interface.js +2 -0
  202. package/dist/unit-of-work/outbox-writer.interface.js.map +1 -0
  203. package/dist/unit-of-work/unit-of-work-context.type.d.ts +8 -0
  204. package/dist/unit-of-work/unit-of-work-context.type.d.ts.map +1 -0
  205. package/dist/unit-of-work/unit-of-work-context.type.js +2 -0
  206. package/dist/unit-of-work/unit-of-work-context.type.js.map +1 -0
  207. package/dist/unit-of-work/unit-of-work.d.ts +20 -0
  208. package/dist/unit-of-work/unit-of-work.d.ts.map +1 -0
  209. package/dist/unit-of-work/unit-of-work.js +60 -0
  210. package/dist/unit-of-work/unit-of-work.js.map +1 -0
  211. package/package.json +83 -0
@@ -0,0 +1,99 @@
1
+ import type { PaginationOptions, SortOption } from './list-query.type.js';
2
+ import type { QueryProduct } from './query-product.type.js';
3
+ export type OrderByOptions = {
4
+ readonly defaults?: readonly SortOption[];
5
+ readonly enforced?: readonly SortOption[];
6
+ };
7
+ export type PaginateOptions = PaginationOptions & {
8
+ readonly distinctOn?: readonly string[];
9
+ };
10
+ /**
11
+ * Fluent SQL builder for read-side queries. Implementations are immutable:
12
+ * every chained call returns a new builder instance, so a base builder
13
+ * can be forked without accidental state sharing.
14
+ *
15
+ * Column names passed to `select` / `groupBy` / `orderBy` / `filters` are
16
+ * resolved through the builder's configured `ColumnResolver` (domain key
17
+ * → DB column). Raw strings passed to `from`, `join`, and `where` are
18
+ * emitted verbatim — the builder validates identifiers in the structured
19
+ * seams (select/filters/etc.) but trusts raw clauses.
20
+ *
21
+ * Identifiers passed to `from`, `join`, `groupBy`, and inside `select`
22
+ * column lists are validated against a strict identifier regex
23
+ * (`[a-zA-Z_][a-zA-Z0-9_]*`, with `.` permitted for `table.column` and
24
+ * optional `AS alias` suffixes). This is defense-in-depth: user input
25
+ * must never reach these seams — it flows through `.where(sql, ...params)`
26
+ * or `.filters({...})`, both of which parameterise.
27
+ */
28
+ export interface SqlQueryBuilder<TRow = unknown> {
29
+ /**
30
+ * Project columns. Column names are domain-keyed (camelCase); the
31
+ * builder emits `db_col AS "domainKey"` when the resolved column
32
+ * differs from the domain key, so read models receive the domain
33
+ * vocabulary. Accepts already-qualified expressions (`table.col`) too.
34
+ */
35
+ select(columns: readonly string[]): SqlQueryBuilder<TRow>;
36
+ /**
37
+ * Target table. Validated as an identifier; accepts `schema.table`.
38
+ */
39
+ from(table: string): SqlQueryBuilder<TRow>;
40
+ /**
41
+ * Raw JOIN clause, emitted verbatim. Use parameterised `where` for
42
+ * conditions that depend on runtime values.
43
+ */
44
+ join(clause: string): SqlQueryBuilder<TRow>;
45
+ /**
46
+ * GROUP BY — domain-keyed column list, resolved the same way as
47
+ * `select`.
48
+ */
49
+ groupBy(columns: readonly string[]): SqlQueryBuilder<TRow>;
50
+ /**
51
+ * Add a raw WHERE fragment with positional `?` placeholders. Each
52
+ * call is ANDed with previous conditions.
53
+ *
54
+ * @example
55
+ * .where('deleted_at IS NULL')
56
+ * .where('tags @> ?::jsonb', JSON.stringify(['urgent']))
57
+ */
58
+ where(condition: string, ...params: readonly unknown[]): SqlQueryBuilder<TRow>;
59
+ /**
60
+ * Structured filters using the suffix-operator DSL. The delimiter is
61
+ * double-underscore (`__`):
62
+ *
63
+ * - `field` → equality (`=`, or `IS NULL` if value is `null`)
64
+ * - `field__contains` → `ILIKE '%value%'` (string fields)
65
+ * - `field__in` / `field__notIn` → `= ANY($n)` / `<> ALL($n)`
66
+ * - `field__gt` / `__gte` / `__lt` / `__lte` → comparators
67
+ * - `field__isNull` / `field__isNotNull` → boolean-valued
68
+ *
69
+ * Field keys are domain-vocabulary (camelCase); the resolver
70
+ * translates to DB columns at build time.
71
+ *
72
+ * Each key in the map contributes one ANDed predicate. Calling
73
+ * `.filters()` multiple times merges (later keys override earlier
74
+ * ones for the same key).
75
+ *
76
+ * Undefined values are skipped — a filter key with `undefined`
77
+ * contributes nothing (so `filters({ foo: opts.foo })` works when
78
+ * `opts.foo` is optional).
79
+ */
80
+ filters(filters: Readonly<Record<string, unknown>>): SqlQueryBuilder<TRow>;
81
+ /**
82
+ * ORDER BY. Accepts the `[{ field: 'asc' }, { other: 'desc' }]` form.
83
+ * `enforced` options are always applied (e.g. tenant-first secondary
84
+ * sort); `defaults` apply only when user sort is empty.
85
+ */
86
+ orderBy(sort: readonly SortOption[] | undefined, options?: OrderByOptions): SqlQueryBuilder<TRow>;
87
+ /**
88
+ * LIMIT / OFFSET pagination. When present, `.build()` emits a
89
+ * `countSql` alongside `sql` so `findPaginated` can resolve total
90
+ * rows with the same parameters.
91
+ */
92
+ paginate(options: PaginateOptions): SqlQueryBuilder<TRow>;
93
+ /**
94
+ * Emit the final SQL + params. Result is a `QueryProduct` ready to
95
+ * hand to `BaseReadDao.findOne` / `findMany` / `findPaginated`.
96
+ */
97
+ build(): QueryProduct;
98
+ }
99
+ //# sourceMappingURL=sql-query-builder.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-query-builder.interface.d.ts","sourceRoot":"","sources":["../../src/query/sql-query-builder.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe,CAAC,IAAI,GAAG,OAAO;IAC7C;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE1D;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3C;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE5C;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3D;;;;;;;OAOG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE/E;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE3E;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAElG;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAE1D;;;OAGG;IACH,KAAK,IAAI,YAAY,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sql-query-builder.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-query-builder.interface.js","sourceRoot":"","sources":["../../src/query/sql-query-builder.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export type SqlStatement = {
2
+ readonly text: string;
3
+ readonly params: readonly unknown[];
4
+ };
5
+ //# sourceMappingURL=sql-statement.type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-statement.type.d.ts","sourceRoot":"","sources":["../../src/query/sql-statement.type.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;CACrC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sql-statement.type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-statement.type.js","sourceRoot":"","sources":["../../src/query/sql-statement.type.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import type { FilterQuery } from './filter-query.type.js';
2
+ import type { SqlStatement } from './sql-statement.type.js';
3
+ export type OptimisticLock = {
4
+ readonly column: string;
5
+ readonly expected: unknown;
6
+ };
7
+ export type InsertOptions = {
8
+ readonly table: string;
9
+ readonly rows: readonly Record<string, unknown>[];
10
+ readonly returning?: readonly string[];
11
+ };
12
+ export type UpdateOptions<T> = {
13
+ readonly table: string;
14
+ readonly set: Record<string, unknown>;
15
+ readonly where: FilterQuery<T>;
16
+ readonly optimisticLock?: OptimisticLock;
17
+ readonly returning?: readonly string[];
18
+ };
19
+ export type DeleteOptions<T> = {
20
+ readonly table: string;
21
+ readonly where: FilterQuery<T>;
22
+ };
23
+ export type SelectForUpdateOptions<T> = {
24
+ readonly table: string;
25
+ readonly columns?: readonly string[];
26
+ readonly where: FilterQuery<T>;
27
+ };
28
+ export interface WriteQueryBuilder {
29
+ insert(opts: InsertOptions): SqlStatement;
30
+ update<T>(opts: UpdateOptions<T>): SqlStatement;
31
+ delete<T>(opts: DeleteOptions<T>): SqlStatement;
32
+ selectForUpdate<T>(opts: SelectForUpdateOptions<T>): SqlStatement;
33
+ }
34
+ //# sourceMappingURL=write-query-builder.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-query-builder.interface.d.ts","sourceRoot":"","sources":["../../src/query/write-query-builder.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAClD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CAAC;IAC1C,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;IAChD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;IAChD,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;CACnE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=write-query-builder.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-query-builder.interface.js","sourceRoot":"","sources":["../../src/query/write-query-builder.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ import type { FieldDescriptorMap } from '../query/field-descriptor.type.js';
3
+ export declare function fieldDescriptorsFromZod(schema: z.ZodObject<z.ZodRawShape>): FieldDescriptorMap;
4
+ //# sourceMappingURL=field-descriptor-from-zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-descriptor-from-zod.d.ts","sourceRoot":"","sources":["../../src/query-schema/field-descriptor-from-zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,mCAAmC,CAAC;AAE3C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,kBAAkB,CAQ9F"}
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ export function fieldDescriptorsFromZod(schema) {
3
+ const shape = schema.shape;
4
+ const result = {};
5
+ for (const [key, fieldSchema] of Object.entries(shape)) {
6
+ const descriptor = descriptorFromZodField(fieldSchema);
7
+ if (descriptor)
8
+ result[key] = descriptor;
9
+ }
10
+ return result;
11
+ }
12
+ function descriptorFromZodField(schema) {
13
+ const optional = schema instanceof z.ZodOptional;
14
+ const inner = optional ? schema.unwrap() : schema;
15
+ const kind = kindOf(inner);
16
+ if (!kind)
17
+ return null;
18
+ return optional ? { kind, optional: true } : { kind };
19
+ }
20
+ function kindOf(schema) {
21
+ if (schema instanceof z.ZodString)
22
+ return 'string';
23
+ if (schema instanceof z.ZodNumber)
24
+ return 'number';
25
+ if (schema instanceof z.ZodBoolean)
26
+ return 'boolean';
27
+ if (schema instanceof z.ZodDate)
28
+ return 'date';
29
+ return null;
30
+ }
31
+ //# sourceMappingURL=field-descriptor-from-zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-descriptor-from-zod.js","sourceRoot":"","sources":["../../src/query-schema/field-descriptor-from-zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,MAAM,UAAU,uBAAuB,CAAC,MAAkC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,MAAM,GAAoC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,UAAU,GAAG,sBAAsB,CAAC,WAAwB,CAAC,CAAC;QACpE,IAAI,UAAU;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAiB;IAC/C,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,CAAC,WAAW,CAAC;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAE,MAAmC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAChF,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,MAAM,CAAC,MAAiB;IAC/B,IAAI,MAAM,YAAY,CAAC,CAAC,SAAS;QAAE,OAAO,QAAQ,CAAC;IACnD,IAAI,MAAM,YAAY,CAAC,CAAC,SAAS;QAAE,OAAO,QAAQ,CAAC;IACnD,IAAI,MAAM,YAAY,CAAC,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IACrD,IAAI,MAAM,YAAY,CAAC,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createQueryParametersSchema, type CreateQueryParametersSchemaOptions, } from './zod.js';
2
+ export { fieldDescriptorsFromZod } from './field-descriptor-from-zod.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query-schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,KAAK,kCAAkC,GACxC,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createQueryParametersSchema, } from './zod.js';
2
+ export { fieldDescriptorsFromZod } from './field-descriptor-from-zod.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query-schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,GAE5B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { z } from 'zod';
2
+ import type { StandardListQuery } from '../query/list-query.type.js';
3
+ export type CreateQueryParametersSchemaOptions<TExtra extends Record<string, unknown> = Record<string, never>> = {
4
+ readonly defaultPageSize?: number;
5
+ readonly maxPageSize?: number;
6
+ /**
7
+ * Strictness for client-supplied input that doesn't match the declared shape.
8
+ *
9
+ * - `false` (default) — tolerant. Unknown query keys are stripped; sort
10
+ * entries pointing at unknown fields or bad directions are dropped;
11
+ * non-positive / NaN page and pageSize values fall back to defaults.
12
+ * Appropriate for HTTP boundaries where you'd rather serve a valid
13
+ * response with sensible defaults than reject the request.
14
+ * - `true` — strict. Unknown query keys, unknown sort fields, bad sort
15
+ * directions, and invalid page / pageSize values surface as Zod
16
+ * validation errors (single `ZodError` with all issues). Appropriate
17
+ * when the caller is trusted code (internal RPC, background jobs) or
18
+ * when you want to surface client bugs loudly.
19
+ *
20
+ * `maxPageSize` is always enforced via clamping — strict mode does not
21
+ * reject oversized page requests (bounds enforcement ≠ validation; a
22
+ * client asking for more data than you're willing to serve isn't
23
+ * malformed input).
24
+ */
25
+ readonly strict?: boolean;
26
+ /**
27
+ * Extra top-level fields woven into the generated schema alongside
28
+ * `filters` / `sort` / `pagination`. Use this for fields that belong on
29
+ * the query envelope but aren't client-narrowable filters — typically
30
+ * auth-derived identifiers the server populates post-validation, like
31
+ * `scopeId` / `userId`. The keys:
32
+ *
33
+ * - Are declared at the top level of the generated schema (so strict
34
+ * mode accepts them and doesn't reject as unknown).
35
+ * - Are **not** expanded by the suffix-operator DSL (no `scopeId__in`,
36
+ * no `userId__contains` exposed to clients).
37
+ * - Pass through to the transform output at the top level — **not**
38
+ * nested under `filters`.
39
+ *
40
+ * Declare them as optional: `z.object({ scopeId: z.string().optional() })`.
41
+ * The server (via `@ValidateRequest`'s auth-injection) populates them;
42
+ * the generator only reserves the names.
43
+ */
44
+ readonly extraFields?: z.ZodObject<z.ZodRawShape>;
45
+ };
46
+ /**
47
+ * Generates a Zod schema that parses and transforms HTTP query parameters
48
+ * into a `StandardListQuery<TFilters>`. The output filter object is the
49
+ * flat suffix-keyed dict expected by `SqlQueryBuilder.filters(...)`:
50
+ *
51
+ * ?name__contains=foo&createdAt__gte=2026-01-01&sort=name:asc&page=2&pageSize=50
52
+ *
53
+ * becomes:
54
+ *
55
+ * {
56
+ * filters: { name__contains: 'foo', createdAt__gte: Date },
57
+ * sort: [{ name: 'asc' }],
58
+ * pagination: { page: 2, pageSize: 50 }
59
+ * }
60
+ *
61
+ * Operators available per field kind:
62
+ * - string: __contains, __in, __notIn, __isNull, __isNotNull
63
+ * - number: __gt, __gte, __lt, __lte, __in, __notIn, __isNull, __isNotNull
64
+ * - date: __gt, __gte, __lt, __lte, __in, __notIn, __isNull, __isNotNull
65
+ * - boolean: __isNull, __isNotNull
66
+ *
67
+ * Equality is the bare key (`name=Ada`). Invalid input is silently tolerated
68
+ * by default; opt into strict validation via `{ strict: true }`.
69
+ */
70
+ export declare function createQueryParametersSchema<TFilters extends Record<string, unknown>, TExtra extends Record<string, unknown> = Record<string, never>>(filterShape: z.ZodObject<{
71
+ [K in keyof TFilters]: z.ZodType<TFilters[K]>;
72
+ }>, options?: CreateQueryParametersSchemaOptions<TExtra>): z.ZodType<StandardListQuery<Partial<TFilters> & Record<string, unknown>> & Partial<TExtra>>;
73
+ //# sourceMappingURL=zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../src/query-schema/zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,MAAM,MAAM,kCAAkC,CAC5C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAC5D;IACF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;CACnD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAE9D,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC;KAAG,CAAC,IAAI,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,EAC3E,OAAO,GAAE,kCAAkC,CAAC,MAAM,CAAM,GACvD,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAgE7F"}
@@ -0,0 +1,191 @@
1
+ import { z } from 'zod';
2
+ import { FILTER_DELIMITER, OPERATORS_BY_KIND } from '../query/field-descriptor.type.js';
3
+ import { fieldDescriptorsFromZod } from './field-descriptor-from-zod.js';
4
+ const DEFAULT_PAGE = 1;
5
+ const DEFAULT_PAGE_SIZE = 20;
6
+ /**
7
+ * Generates a Zod schema that parses and transforms HTTP query parameters
8
+ * into a `StandardListQuery<TFilters>`. The output filter object is the
9
+ * flat suffix-keyed dict expected by `SqlQueryBuilder.filters(...)`:
10
+ *
11
+ * ?name__contains=foo&createdAt__gte=2026-01-01&sort=name:asc&page=2&pageSize=50
12
+ *
13
+ * becomes:
14
+ *
15
+ * {
16
+ * filters: { name__contains: 'foo', createdAt__gte: Date },
17
+ * sort: [{ name: 'asc' }],
18
+ * pagination: { page: 2, pageSize: 50 }
19
+ * }
20
+ *
21
+ * Operators available per field kind:
22
+ * - string: __contains, __in, __notIn, __isNull, __isNotNull
23
+ * - number: __gt, __gte, __lt, __lte, __in, __notIn, __isNull, __isNotNull
24
+ * - date: __gt, __gte, __lt, __lte, __in, __notIn, __isNull, __isNotNull
25
+ * - boolean: __isNull, __isNotNull
26
+ *
27
+ * Equality is the bare key (`name=Ada`). Invalid input is silently tolerated
28
+ * by default; opt into strict validation via `{ strict: true }`.
29
+ */
30
+ export function createQueryParametersSchema(filterShape, options = {}) {
31
+ const defaultPageSize = options.defaultPageSize ?? DEFAULT_PAGE_SIZE;
32
+ const maxPageSize = options.maxPageSize ?? 200;
33
+ const strict = options.strict ?? false;
34
+ const descriptors = fieldDescriptorsFromZod(filterShape);
35
+ const rawShape = {
36
+ page: z.string().optional(),
37
+ pageSize: z.string().optional(),
38
+ sort: z.union([z.string(), z.array(z.string())]).optional(),
39
+ };
40
+ const sortableKeys = [];
41
+ for (const [key, descriptor] of Object.entries(descriptors)) {
42
+ const base = filterShape.shape[key];
43
+ if (!base)
44
+ continue;
45
+ rawShape[key] = base instanceof z.ZodOptional ? base : base.optional();
46
+ sortableKeys.push(key);
47
+ for (const op of OPERATORS_BY_KIND[descriptor.kind]) {
48
+ const opKey = `${key}${FILTER_DELIMITER}${op}`;
49
+ rawShape[opKey] = schemaForOperator(descriptor.kind, op);
50
+ }
51
+ }
52
+ const extraShape = options.extraFields?.shape ?? {};
53
+ const extraKeys = new Set(Object.keys(extraShape));
54
+ for (const [key, schema] of Object.entries(extraShape)) {
55
+ if (key in rawShape) {
56
+ throw new Error(`createQueryParametersSchema: extraFields key "${key}" collides with a reserved name (page, pageSize, sort) or a filter field already declared in the filter shape.`);
57
+ }
58
+ rawShape[key] = schema instanceof z.ZodOptional ? schema : schema.optional();
59
+ }
60
+ const rawSchema = strict ? z.object(rawShape).strict() : z.object(rawShape).strip();
61
+ return rawSchema.transform((raw, ctx) => {
62
+ const filters = {};
63
+ const extras = {};
64
+ for (const [key, value] of Object.entries(raw)) {
65
+ if (value === undefined)
66
+ continue;
67
+ if (key === 'page' || key === 'pageSize' || key === 'sort')
68
+ continue;
69
+ if (extraKeys.has(key)) {
70
+ extras[key] = value;
71
+ }
72
+ else {
73
+ filters[key] = value;
74
+ }
75
+ }
76
+ const pagination = parsePagination(raw, defaultPageSize, maxPageSize, strict, ctx);
77
+ const sort = parseSort(raw.sort, sortableKeys, strict, ctx);
78
+ return {
79
+ ...extras,
80
+ filters,
81
+ ...(sort.length > 0 ? { sort } : {}),
82
+ ...(pagination ? { pagination } : {}),
83
+ };
84
+ });
85
+ }
86
+ function schemaForOperator(kind, operator) {
87
+ if (operator === 'isNull' || operator === 'isNotNull') {
88
+ return z
89
+ .preprocess((v) => (v === 'true' ? true : v === 'false' ? false : v), z.boolean())
90
+ .optional();
91
+ }
92
+ if (operator === 'in' || operator === 'notIn') {
93
+ const elementSchema = elementSchemaFor(kind);
94
+ return z.preprocess((v) => toStringArray(v), z.array(elementSchema)).optional();
95
+ }
96
+ if (operator === 'contains') {
97
+ return z.string().optional();
98
+ }
99
+ // gt / gte / lt / lte — scalar of the field's kind
100
+ return scalarSchemaFor(kind).optional();
101
+ }
102
+ function scalarSchemaFor(kind) {
103
+ switch (kind) {
104
+ case 'number':
105
+ return z.coerce.number();
106
+ case 'date':
107
+ return z.coerce.date();
108
+ case 'boolean':
109
+ return z.coerce.boolean();
110
+ default:
111
+ return z.string();
112
+ }
113
+ }
114
+ function elementSchemaFor(kind) {
115
+ return scalarSchemaFor(kind);
116
+ }
117
+ function toStringArray(value) {
118
+ if (Array.isArray(value)) {
119
+ return value.flatMap((v) => (typeof v === 'string' ? v.split(',') : []));
120
+ }
121
+ if (typeof value === 'string') {
122
+ return value.split(',');
123
+ }
124
+ return [];
125
+ }
126
+ function parsePagination(raw, defaultPageSize, maxPageSize, strict, ctx) {
127
+ const hasPage = raw.page !== undefined;
128
+ const hasPageSize = raw.pageSize !== undefined;
129
+ if (!hasPage && !hasPageSize)
130
+ return null;
131
+ const parsedPage = hasPage ? Number.parseInt(String(raw.page), 10) : DEFAULT_PAGE;
132
+ const parsedSize = hasPageSize ? Number.parseInt(String(raw.pageSize), 10) : defaultPageSize;
133
+ const pageValid = Number.isFinite(parsedPage) && parsedPage > 0;
134
+ const sizeValid = Number.isFinite(parsedSize) && parsedSize > 0;
135
+ if (strict && hasPage && !pageValid) {
136
+ ctx.addIssue({
137
+ code: 'custom',
138
+ message: `Invalid page "${String(raw.page)}"; expected a positive integer`,
139
+ path: ['page'],
140
+ });
141
+ }
142
+ if (strict && hasPageSize && !sizeValid) {
143
+ ctx.addIssue({
144
+ code: 'custom',
145
+ message: `Invalid pageSize "${String(raw.pageSize)}"; expected a positive integer`,
146
+ path: ['pageSize'],
147
+ });
148
+ }
149
+ const page = pageValid ? parsedPage : DEFAULT_PAGE;
150
+ const pageSize = sizeValid ? Math.min(parsedSize, maxPageSize) : defaultPageSize;
151
+ return { page, pageSize };
152
+ }
153
+ function parseSort(value, sortableKeys, strict, ctx) {
154
+ if (value === undefined)
155
+ return [];
156
+ const entries = Array.isArray(value)
157
+ ? value.filter((v) => typeof v === 'string')
158
+ : typeof value === 'string'
159
+ ? [value]
160
+ : [];
161
+ const allowed = new Set(sortableKeys);
162
+ const deduped = new Set(entries.map((e) => e.trim()));
163
+ const result = [];
164
+ for (const entry of deduped) {
165
+ const [field, direction] = entry.split(':');
166
+ if (!field || !allowed.has(field)) {
167
+ if (strict) {
168
+ ctx.addIssue({
169
+ code: 'custom',
170
+ message: `Unknown sort field "${field ?? ''}"; allowed: ${sortableKeys.join(', ')}`,
171
+ path: ['sort'],
172
+ });
173
+ }
174
+ continue;
175
+ }
176
+ const dir = direction?.toLowerCase();
177
+ if (dir !== 'asc' && dir !== 'desc') {
178
+ if (strict) {
179
+ ctx.addIssue({
180
+ code: 'custom',
181
+ message: `Invalid sort direction "${direction ?? ''}" for field "${field}"; expected "asc" or "desc"`,
182
+ path: ['sort'],
183
+ });
184
+ }
185
+ continue;
186
+ }
187
+ result.push({ [field]: dir });
188
+ }
189
+ return result;
190
+ }
191
+ //# sourceMappingURL=zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod.js","sourceRoot":"","sources":["../../src/query-schema/zod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { AggregateRoot } from '@quilla-be-kit/ddd';
2
+ import type { BaseWriteDao } from '../dao/base-write.dao.js';
3
+ import type { UnitOfWorkContext } from '../unit-of-work/unit-of-work-context.type.js';
4
+ import type { PersistenceMapper } from './mapper.interface.js';
5
+ /**
6
+ * Base repository for aggregates. Handles persistence through a mapper and
7
+ * registers aggregates in the `UnitOfWorkContext` so the UoW can drain
8
+ * their domain events into the outbox at commit.
9
+ *
10
+ * Verb: `loadById` / `loadForUpdate...` — returns `TAggregate` (DDD
11
+ * language). Persistence I/O delegates to `BaseWriteDao`'s `find*` methods.
12
+ */
13
+ export declare abstract class BaseAggregateRepository<TAggregate extends AggregateRoot<object> & {
14
+ id: string;
15
+ }, TRow extends {
16
+ id: string;
17
+ }> {
18
+ protected readonly mapper: PersistenceMapper<TAggregate, TRow>;
19
+ protected readonly writeDao: BaseWriteDao<TRow>;
20
+ constructor(mapper: PersistenceMapper<TAggregate, TRow>, writeDao: BaseWriteDao<TRow>);
21
+ create(aggregate: TAggregate, ctx: UnitOfWorkContext): Promise<void>;
22
+ createMany(aggregates: readonly TAggregate[], ctx: UnitOfWorkContext): Promise<void>;
23
+ update(aggregate: TAggregate, ctx: UnitOfWorkContext): Promise<void>;
24
+ updateMany(aggregates: readonly TAggregate[], ctx: UnitOfWorkContext): Promise<void>;
25
+ delete(aggregate: TAggregate, ctx: UnitOfWorkContext): Promise<void>;
26
+ deleteMany(aggregates: readonly TAggregate[], ctx: UnitOfWorkContext): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=base-aggregate.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-aggregate.repository.d.ts","sourceRoot":"","sources":["../../src/repository/base-aggregate.repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D;;;;;;;GAOG;AACH,8BAAsB,uBAAuB,CAC3C,UAAU,SAAS,aAAa,CAAC,MAAM,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACzD,IAAI,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAGzB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC;IAC9D,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC;gBAD5B,MAAM,EAAE,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,EAC3C,QAAQ,EAAE,YAAY,CAAC,IAAI,CAAC;IAG3C,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,UAAU,CAAC,UAAU,EAAE,SAAS,UAAU,EAAE,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpF,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpE,UAAU,CAAC,UAAU,EAAE,SAAS,UAAU,EAAE,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpF,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpE,UAAU,CAAC,UAAU,EAAE,SAAS,UAAU,EAAE,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ3F"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Base repository for aggregates. Handles persistence through a mapper and
3
+ * registers aggregates in the `UnitOfWorkContext` so the UoW can drain
4
+ * their domain events into the outbox at commit.
5
+ *
6
+ * Verb: `loadById` / `loadForUpdate...` — returns `TAggregate` (DDD
7
+ * language). Persistence I/O delegates to `BaseWriteDao`'s `find*` methods.
8
+ */
9
+ export class BaseAggregateRepository {
10
+ mapper;
11
+ writeDao;
12
+ constructor(mapper, writeDao) {
13
+ this.mapper = mapper;
14
+ this.writeDao = writeDao;
15
+ }
16
+ async create(aggregate, ctx) {
17
+ await this.writeDao.create(this.mapper.toPersistence(aggregate), ctx.trx);
18
+ ctx.registerAggregate(aggregate);
19
+ }
20
+ async createMany(aggregates, ctx) {
21
+ if (aggregates.length === 0)
22
+ return;
23
+ const rows = aggregates.map((a) => this.mapper.toPersistence(a));
24
+ await this.writeDao.createMany(rows, ctx.trx);
25
+ ctx.registerAggregate(...aggregates);
26
+ }
27
+ async update(aggregate, ctx) {
28
+ await this.writeDao.update(this.mapper.toPersistence(aggregate), ctx.trx);
29
+ // Aggregate already registered in ctx via loadForUpdate*.
30
+ }
31
+ async updateMany(aggregates, ctx) {
32
+ if (aggregates.length === 0)
33
+ return;
34
+ const rows = aggregates.map((a) => this.mapper.toPersistence(a));
35
+ await this.writeDao.updateMany(rows, ctx.trx);
36
+ // Aggregates already registered in ctx via loadForUpdate*.
37
+ }
38
+ async delete(aggregate, ctx) {
39
+ await this.writeDao.delete(aggregate.id, ctx.trx);
40
+ // Aggregate already registered in ctx via loadForUpdate*.
41
+ }
42
+ async deleteMany(aggregates, ctx) {
43
+ if (aggregates.length === 0)
44
+ return;
45
+ await this.writeDao.deleteMany(aggregates.map((a) => a.id), ctx.trx);
46
+ // Aggregates already registered in ctx via loadForUpdate*.
47
+ }
48
+ }
49
+ //# sourceMappingURL=base-aggregate.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-aggregate.repository.js","sourceRoot":"","sources":["../../src/repository/base-aggregate.repository.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,OAAgB,uBAAuB;IAKtB;IACA;IAFrB,YACqB,MAA2C,EAC3C,QAA4B;QAD5B,WAAM,GAAN,MAAM,CAAqC;QAC3C,aAAQ,GAAR,QAAQ,CAAoB;IAC9C,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,SAAqB,EAAE,GAAsB;QACxD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC1E,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAiC,EAAE,GAAsB;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,GAAG,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAqB,EAAE,GAAsB;QACxD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CACxB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAiC,EACpE,GAAG,CAAC,GAAG,CACR,CAAC;QACF,0DAA0D;IAC5D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAiC,EAAE,GAAsB;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,2DAA2D;IAC7D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAqB,EAAE,GAAsB;QACxD,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAClD,0DAA0D;IAC5D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAiC,EAAE,GAAsB;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAC5B,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAC3B,GAAG,CAAC,GAAG,CACR,CAAC;QACF,2DAA2D;IAC7D,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ import type { BaseWriteDao } from '../dao/base-write.dao.js';
2
+ import type { DatabaseTransaction } from '../database/database-transaction.interface.js';
3
+ /**
4
+ * Repository for non-aggregate entities (no domain events, no aggregate
5
+ * registration). Use for simple persistence shapes without DDD tactical
6
+ * pattern requirements.
7
+ */
8
+ export declare abstract class BaseBasicRepository<TRow extends {
9
+ id: string;
10
+ }> {
11
+ protected readonly writeDao: BaseWriteDao<TRow>;
12
+ constructor(writeDao: BaseWriteDao<TRow>);
13
+ create(row: TRow, trx?: DatabaseTransaction): Promise<void>;
14
+ createMany(rows: readonly TRow[], trx?: DatabaseTransaction): Promise<void>;
15
+ update(row: TRow & {
16
+ updated_at?: Date;
17
+ }, trx?: DatabaseTransaction): Promise<void>;
18
+ updateMany(rows: readonly TRow[], trx: DatabaseTransaction): Promise<void>;
19
+ delete(id: string, trx?: DatabaseTransaction): Promise<void>;
20
+ deleteMany(ids: readonly string[], trx?: DatabaseTransaction): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=base-basic.repository.d.ts.map