@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.
- package/README.md +684 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/dao/audit-columns.d.ts +19 -0
- package/dist/dao/audit-columns.d.ts.map +1 -0
- package/dist/dao/audit-columns.js +26 -0
- package/dist/dao/audit-columns.js.map +1 -0
- package/dist/dao/base-read.dao.d.ts +50 -0
- package/dist/dao/base-read.dao.d.ts.map +1 -0
- package/dist/dao/base-read.dao.js +65 -0
- package/dist/dao/base-read.dao.js.map +1 -0
- package/dist/dao/base-write.dao.d.ts +49 -0
- package/dist/dao/base-write.dao.d.ts.map +1 -0
- package/dist/dao/base-write.dao.js +130 -0
- package/dist/dao/base-write.dao.js.map +1 -0
- package/dist/dao/index.d.ts +3 -0
- package/dist/dao/index.d.ts.map +1 -0
- package/dist/dao/index.js +3 -0
- package/dist/dao/index.js.map +1 -0
- package/dist/database/database-health.type.d.ts +4 -0
- package/dist/database/database-health.type.d.ts.map +1 -0
- package/dist/database/database-health.type.js +2 -0
- package/dist/database/database-health.type.js.map +1 -0
- package/dist/database/database-result.type.d.ts +5 -0
- package/dist/database/database-result.type.d.ts.map +1 -0
- package/dist/database/database-result.type.js +2 -0
- package/dist/database/database-result.type.js.map +1 -0
- package/dist/database/database-transaction.interface.d.ts +10 -0
- package/dist/database/database-transaction.interface.d.ts.map +1 -0
- package/dist/database/database-transaction.interface.js +2 -0
- package/dist/database/database-transaction.interface.js.map +1 -0
- package/dist/database/database.interface.d.ts +10 -0
- package/dist/database/database.interface.d.ts.map +1 -0
- package/dist/database/database.interface.js +2 -0
- package/dist/database/database.interface.js.map +1 -0
- package/dist/database/index.d.ts +5 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +2 -0
- package/dist/database/index.js.map +1 -0
- package/dist/db-adapter/filter-query.type.d.ts +4 -0
- package/dist/db-adapter/filter-query.type.d.ts.map +1 -0
- package/dist/db-adapter/filter-query.type.js +2 -0
- package/dist/db-adapter/filter-query.type.js.map +1 -0
- package/dist/db-adapter/index.d.ts +4 -0
- package/dist/db-adapter/index.d.ts.map +1 -0
- package/dist/db-adapter/index.js +2 -0
- package/dist/db-adapter/index.js.map +1 -0
- package/dist/db-adapter/read-db-adapter.interface.d.ts +37 -0
- package/dist/db-adapter/read-db-adapter.interface.d.ts.map +1 -0
- package/dist/db-adapter/read-db-adapter.interface.js +2 -0
- package/dist/db-adapter/read-db-adapter.interface.js.map +1 -0
- package/dist/db-adapter/write-db-adapter.interface.d.ts +61 -0
- package/dist/db-adapter/write-db-adapter.interface.d.ts.map +1 -0
- package/dist/db-adapter/write-db-adapter.interface.js +2 -0
- package/dist/db-adapter/write-db-adapter.interface.js.map +1 -0
- package/dist/errors/cross-scope-access.error.d.ts +10 -0
- package/dist/errors/cross-scope-access.error.d.ts.map +1 -0
- package/dist/errors/cross-scope-access.error.js +15 -0
- package/dist/errors/cross-scope-access.error.js.map +1 -0
- package/dist/errors/index.d.ts +3 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +3 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/optimistic-lock.error.d.ts +9 -0
- package/dist/errors/optimistic-lock.error.d.ts.map +1 -0
- package/dist/errors/optimistic-lock.error.js +11 -0
- package/dist/errors/optimistic-lock.error.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/postgres/index.d.ts +7 -0
- package/dist/postgres/index.d.ts.map +1 -0
- package/dist/postgres/index.js +7 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/postgres/pg-query-builder.d.ts +42 -0
- package/dist/postgres/pg-query-builder.d.ts.map +1 -0
- package/dist/postgres/pg-query-builder.js +260 -0
- package/dist/postgres/pg-query-builder.js.map +1 -0
- package/dist/postgres/pg-read-db-adapter.d.ts +20 -0
- package/dist/postgres/pg-read-db-adapter.d.ts.map +1 -0
- package/dist/postgres/pg-read-db-adapter.js +28 -0
- package/dist/postgres/pg-read-db-adapter.js.map +1 -0
- package/dist/postgres/pg-sql.d.ts +44 -0
- package/dist/postgres/pg-sql.d.ts.map +1 -0
- package/dist/postgres/pg-sql.js +128 -0
- package/dist/postgres/pg-sql.js.map +1 -0
- package/dist/postgres/pg-write-db-adapter.d.ts +30 -0
- package/dist/postgres/pg-write-db-adapter.d.ts.map +1 -0
- package/dist/postgres/pg-write-db-adapter.js +133 -0
- package/dist/postgres/pg-write-db-adapter.js.map +1 -0
- package/dist/postgres/pg.database.d.ts +25 -0
- package/dist/postgres/pg.database.d.ts.map +1 -0
- package/dist/postgres/pg.database.js +48 -0
- package/dist/postgres/pg.database.js.map +1 -0
- package/dist/postgres/pg.transaction.d.ts +22 -0
- package/dist/postgres/pg.transaction.d.ts.map +1 -0
- package/dist/postgres/pg.transaction.js +78 -0
- package/dist/postgres/pg.transaction.js.map +1 -0
- package/dist/query/case.d.ts +3 -0
- package/dist/query/case.d.ts.map +1 -0
- package/dist/query/case.js +7 -0
- package/dist/query/case.js.map +1 -0
- package/dist/query/column-resolver.interface.d.ts +4 -0
- package/dist/query/column-resolver.interface.d.ts.map +1 -0
- package/dist/query/column-resolver.interface.js +2 -0
- package/dist/query/column-resolver.interface.js.map +1 -0
- package/dist/query/default.resolver.d.ts +10 -0
- package/dist/query/default.resolver.d.ts.map +1 -0
- package/dist/query/default.resolver.js +14 -0
- package/dist/query/default.resolver.js.map +1 -0
- package/dist/query/field-descriptor.type.d.ts +11 -0
- package/dist/query/field-descriptor.type.d.ts.map +1 -0
- package/dist/query/field-descriptor.type.js +20 -0
- package/dist/query/field-descriptor.type.js.map +1 -0
- package/dist/query/filter-query.type.d.ts +4 -0
- package/dist/query/filter-query.type.d.ts.map +1 -0
- package/dist/query/filter-query.type.js +2 -0
- package/dist/query/filter-query.type.js.map +1 -0
- package/dist/query/index.d.ts +9 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +3 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/list-query.type.d.ts +12 -0
- package/dist/query/list-query.type.d.ts.map +1 -0
- package/dist/query/list-query.type.js +2 -0
- package/dist/query/list-query.type.js.map +1 -0
- package/dist/query/paginated-result.type.d.ts +7 -0
- package/dist/query/paginated-result.type.d.ts.map +1 -0
- package/dist/query/paginated-result.type.js +2 -0
- package/dist/query/paginated-result.type.js.map +1 -0
- package/dist/query/query-product.type.d.ts +6 -0
- package/dist/query/query-product.type.d.ts.map +1 -0
- package/dist/query/query-product.type.js +2 -0
- package/dist/query/query-product.type.js.map +1 -0
- package/dist/query/read-query-builder.interface.d.ts +17 -0
- package/dist/query/read-query-builder.interface.d.ts.map +1 -0
- package/dist/query/read-query-builder.interface.js +2 -0
- package/dist/query/read-query-builder.interface.js.map +1 -0
- package/dist/query/sql-query-builder.interface.d.ts +99 -0
- package/dist/query/sql-query-builder.interface.d.ts.map +1 -0
- package/dist/query/sql-query-builder.interface.js +2 -0
- package/dist/query/sql-query-builder.interface.js.map +1 -0
- package/dist/query/sql-statement.type.d.ts +5 -0
- package/dist/query/sql-statement.type.d.ts.map +1 -0
- package/dist/query/sql-statement.type.js +2 -0
- package/dist/query/sql-statement.type.js.map +1 -0
- package/dist/query/write-query-builder.interface.d.ts +34 -0
- package/dist/query/write-query-builder.interface.d.ts.map +1 -0
- package/dist/query/write-query-builder.interface.js +2 -0
- package/dist/query/write-query-builder.interface.js.map +1 -0
- package/dist/query-schema/field-descriptor-from-zod.d.ts +4 -0
- package/dist/query-schema/field-descriptor-from-zod.d.ts.map +1 -0
- package/dist/query-schema/field-descriptor-from-zod.js +31 -0
- package/dist/query-schema/field-descriptor-from-zod.js.map +1 -0
- package/dist/query-schema/index.d.ts +3 -0
- package/dist/query-schema/index.d.ts.map +1 -0
- package/dist/query-schema/index.js +3 -0
- package/dist/query-schema/index.js.map +1 -0
- package/dist/query-schema/zod.d.ts +73 -0
- package/dist/query-schema/zod.d.ts.map +1 -0
- package/dist/query-schema/zod.js +191 -0
- package/dist/query-schema/zod.js.map +1 -0
- package/dist/repository/base-aggregate.repository.d.ts +28 -0
- package/dist/repository/base-aggregate.repository.d.ts.map +1 -0
- package/dist/repository/base-aggregate.repository.js +49 -0
- package/dist/repository/base-aggregate.repository.js.map +1 -0
- package/dist/repository/base-basic.repository.d.ts +22 -0
- package/dist/repository/base-basic.repository.d.ts.map +1 -0
- package/dist/repository/base-basic.repository.js +30 -0
- package/dist/repository/base-basic.repository.js.map +1 -0
- package/dist/repository/base-persistence.mapper.d.ts +61 -0
- package/dist/repository/base-persistence.mapper.d.ts.map +1 -0
- package/dist/repository/base-persistence.mapper.js +119 -0
- package/dist/repository/base-persistence.mapper.js.map +1 -0
- package/dist/repository/base-scoped-aggregate.repository.d.ts +19 -0
- package/dist/repository/base-scoped-aggregate.repository.d.ts.map +1 -0
- package/dist/repository/base-scoped-aggregate.repository.js +35 -0
- package/dist/repository/base-scoped-aggregate.repository.js.map +1 -0
- package/dist/repository/base-unscoped-aggregate.repository.d.ts +17 -0
- package/dist/repository/base-unscoped-aggregate.repository.d.ts.map +1 -0
- package/dist/repository/base-unscoped-aggregate.repository.js +21 -0
- package/dist/repository/base-unscoped-aggregate.repository.js.map +1 -0
- package/dist/repository/index.d.ts +7 -0
- package/dist/repository/index.d.ts.map +1 -0
- package/dist/repository/index.js +6 -0
- package/dist/repository/index.js.map +1 -0
- package/dist/repository/mapper.interface.d.ts +5 -0
- package/dist/repository/mapper.interface.d.ts.map +1 -0
- package/dist/repository/mapper.interface.js +2 -0
- package/dist/repository/mapper.interface.js.map +1 -0
- package/dist/unit-of-work/event-sink.interface.d.ts +5 -0
- package/dist/unit-of-work/event-sink.interface.d.ts.map +1 -0
- package/dist/unit-of-work/event-sink.interface.js +2 -0
- package/dist/unit-of-work/event-sink.interface.js.map +1 -0
- package/dist/unit-of-work/index.d.ts +4 -0
- package/dist/unit-of-work/index.d.ts.map +1 -0
- package/dist/unit-of-work/index.js +2 -0
- package/dist/unit-of-work/index.js.map +1 -0
- package/dist/unit-of-work/outbox-writer.interface.d.ts +14 -0
- package/dist/unit-of-work/outbox-writer.interface.d.ts.map +1 -0
- package/dist/unit-of-work/outbox-writer.interface.js +2 -0
- package/dist/unit-of-work/outbox-writer.interface.js.map +1 -0
- package/dist/unit-of-work/unit-of-work-context.type.d.ts +8 -0
- package/dist/unit-of-work/unit-of-work-context.type.d.ts.map +1 -0
- package/dist/unit-of-work/unit-of-work-context.type.js +2 -0
- package/dist/unit-of-work/unit-of-work-context.type.js.map +1 -0
- package/dist/unit-of-work/unit-of-work.d.ts +20 -0
- package/dist/unit-of-work/unit-of-work.d.ts.map +1 -0
- package/dist/unit-of-work/unit-of-work.js +60 -0
- package/dist/unit-of-work/unit-of-work.js.map +1 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"sql-query-builder.interface.js","sourceRoot":"","sources":["../../src/query/sql-query-builder.interface.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"write-query-builder.interface.js","sourceRoot":"","sources":["../../src/query/write-query-builder.interface.ts"],"names":[],"mappings":""}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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
|