@owlmeans/postgres-resource 0.1.15

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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +219 -0
  3. package/agent-meta/instructions/postgres-resource.instructions.md +60 -0
  4. package/agent-meta/manifest.json +23 -0
  5. package/agent-meta/skills/postgres-resource/SKILL.md +186 -0
  6. package/build/consts.d.ts +81 -0
  7. package/build/consts.d.ts.map +1 -0
  8. package/build/consts.js +86 -0
  9. package/build/consts.js.map +1 -0
  10. package/build/declarations.d.ts +12 -0
  11. package/build/declarations.d.ts.map +1 -0
  12. package/build/declarations.js +28 -0
  13. package/build/declarations.js.map +1 -0
  14. package/build/errors.d.ts +70 -0
  15. package/build/errors.d.ts.map +1 -0
  16. package/build/errors.js +201 -0
  17. package/build/errors.js.map +1 -0
  18. package/build/helper.d.ts +4 -0
  19. package/build/helper.d.ts.map +1 -0
  20. package/build/helper.js +5 -0
  21. package/build/helper.js.map +1 -0
  22. package/build/index.d.ts +8 -0
  23. package/build/index.d.ts.map +1 -0
  24. package/build/index.js +7 -0
  25. package/build/index.js.map +1 -0
  26. package/build/resource.d.ts +4 -0
  27. package/build/resource.d.ts.map +1 -0
  28. package/build/resource.js +395 -0
  29. package/build/resource.js.map +1 -0
  30. package/build/types.d.ts +273 -0
  31. package/build/types.d.ts.map +1 -0
  32. package/build/types.js +2 -0
  33. package/build/types.js.map +1 -0
  34. package/build/utils/criteria.d.ts +24 -0
  35. package/build/utils/criteria.d.ts.map +1 -0
  36. package/build/utils/criteria.js +209 -0
  37. package/build/utils/criteria.js.map +1 -0
  38. package/build/utils/diff.d.ts +24 -0
  39. package/build/utils/diff.d.ts.map +1 -0
  40. package/build/utils/diff.js +330 -0
  41. package/build/utils/diff.js.map +1 -0
  42. package/build/utils/index.d.ts +12 -0
  43. package/build/utils/index.d.ts.map +1 -0
  44. package/build/utils/index.js +12 -0
  45. package/build/utils/index.js.map +1 -0
  46. package/build/utils/introspect.d.ts +7 -0
  47. package/build/utils/introspect.d.ts.map +1 -0
  48. package/build/utils/introspect.js +70 -0
  49. package/build/utils/introspect.js.map +1 -0
  50. package/build/utils/life-cycle.d.ts +39 -0
  51. package/build/utils/life-cycle.d.ts.map +1 -0
  52. package/build/utils/life-cycle.js +119 -0
  53. package/build/utils/life-cycle.js.map +1 -0
  54. package/build/utils/marshal.d.ts +36 -0
  55. package/build/utils/marshal.d.ts.map +1 -0
  56. package/build/utils/marshal.js +152 -0
  57. package/build/utils/marshal.js.map +1 -0
  58. package/build/utils/migrations.d.ts +16 -0
  59. package/build/utils/migrations.d.ts.map +1 -0
  60. package/build/utils/migrations.js +108 -0
  61. package/build/utils/migrations.js.map +1 -0
  62. package/build/utils/name.d.ts +39 -0
  63. package/build/utils/name.d.ts.map +1 -0
  64. package/build/utils/name.js +63 -0
  65. package/build/utils/name.js.map +1 -0
  66. package/build/utils/schema.d.ts +28 -0
  67. package/build/utils/schema.d.ts.map +1 -0
  68. package/build/utils/schema.js +356 -0
  69. package/build/utils/schema.js.map +1 -0
  70. package/build/utils/sql.d.ts +22 -0
  71. package/build/utils/sql.d.ts.map +1 -0
  72. package/build/utils/sql.js +0 -0
  73. package/build/utils/sql.js.map +1 -0
  74. package/build/utils/sync.d.ts +21 -0
  75. package/build/utils/sync.d.ts.map +1 -0
  76. package/build/utils/sync.js +93 -0
  77. package/build/utils/sync.js.map +1 -0
  78. package/build/utils/table.d.ts +8 -0
  79. package/build/utils/table.d.ts.map +1 -0
  80. package/build/utils/table.js +68 -0
  81. package/build/utils/table.js.map +1 -0
  82. package/package.json +50 -0
  83. package/src/consts.ts +95 -0
  84. package/src/declarations.ts +41 -0
  85. package/src/errors.ts +242 -0
  86. package/src/helper.ts +7 -0
  87. package/src/index.ts +7 -0
  88. package/src/resource.ts +524 -0
  89. package/src/types.ts +310 -0
  90. package/src/utils/criteria.ts +246 -0
  91. package/src/utils/diff.ts +363 -0
  92. package/src/utils/index.ts +11 -0
  93. package/src/utils/introspect.ts +87 -0
  94. package/src/utils/life-cycle.ts +155 -0
  95. package/src/utils/marshal.ts +175 -0
  96. package/src/utils/migrations.ts +135 -0
  97. package/src/utils/name.ts +79 -0
  98. package/src/utils/schema.ts +426 -0
  99. package/src/utils/sql.ts +0 -0
  100. package/src/utils/sync.ts +106 -0
  101. package/src/utils/table.ts +76 -0
  102. package/tests/errors.spec.ts +121 -0
  103. package/tests/name.spec.ts +75 -0
  104. package/tests/schema.spec.ts +258 -0
  105. package/tests/sql.spec.ts +104 -0
  106. package/tsconfig.json +16 -0
@@ -0,0 +1,273 @@
1
+ import type { DbLocker, ListCriteria, ListOptions, MigrationRegistry, MigrationStage, Resource, ResourceDbService, ResourceLocker, ResourceRecord } from '@owlmeans/resource';
2
+ import type { AnySchema } from 'ajv';
3
+ import type { Pool, PoolClient, QueryResultRow } from 'pg';
4
+ import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
5
+ import type { PgAutoSync, PgIndexMethod, PgReferentialAction } from './consts.js';
6
+ /**
7
+ * The handle {@link PostgresDbService.db} resolves to. Carries the pool alongside the
8
+ * query builder because structure reconciliation, advisory locking and custom SQL all
9
+ * need a raw session that Drizzle doesn't expose.
10
+ */
11
+ export interface PostgresDb {
12
+ /** Drizzle bound to this config alias' pool. */
13
+ drizzle: NodePgDatabase<Record<string, never>>;
14
+ pool: Pool;
15
+ /** The Postgres SCHEMA — i.e. `service.name(alias)`, layer suffixed. */
16
+ schema: string;
17
+ /** The Postgres DATABASE — i.e. `config.meta.database`. Never layer suffixed. */
18
+ database: string;
19
+ }
20
+ export interface PostgresDbService extends ResourceDbService<PostgresDb, Pool>, DbLocker<ResourceRecord> {
21
+ /** Fully qualified `"schema"."table"` of a registered postgres resource. */
22
+ qualify: (resourceAlias: string, configAlias?: string) => string;
23
+ /** Parameterised query straight on the pool — `$1` style placeholders, values never interpolated. */
24
+ query: <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[], configAlias?: string) => Promise<Row[]>;
25
+ transaction: <R>(fn: (tx: PostgresTx) => Promise<R>, configAlias?: string) => Promise<R>;
26
+ /**
27
+ * Work held back until every resource has initialized — foreign keys whose target table
28
+ * belongs to a resource whose own `init()` may not have run yet. Drained by the Loading
29
+ * middleware `appendPostgres` registers.
30
+ */
31
+ defer: (configAlias: string, task: () => Promise<void>) => void;
32
+ /** Run every task {@link defer} has queued for a config alias, then clear the queue. */
33
+ drain: (configAlias?: string) => Promise<void>;
34
+ }
35
+ /** `DbConfig.meta` shape this package understands. */
36
+ export interface PostgresMeta {
37
+ /** Postgres DATABASE. Falls back to the connection user, per libpq. */
38
+ database?: string;
39
+ /** Structure reconciliation policy. Defaults to {@link PgAutoSync.Full}. */
40
+ autoSync?: PgAutoSync | `${PgAutoSync}`;
41
+ /** Passed straight to `pg.Pool`. */
42
+ ssl?: boolean | Record<string, unknown>;
43
+ max?: number;
44
+ idleTimeoutMillis?: number;
45
+ connectionTimeoutMillis?: number;
46
+ statementTimeoutMillis?: number;
47
+ /** Attempts of the `SELECT 1` readiness probe. */
48
+ retries?: number;
49
+ retryDelayMillis?: number;
50
+ /** Whole connection string — wins over host/user/secret when present. */
51
+ url?: string;
52
+ }
53
+ /** Transaction scoped façade handed to migrations and {@link PostgresResource.transaction}. */
54
+ export interface PostgresTx {
55
+ client: PoolClient;
56
+ /** `{{alias}}` placeholders resolved against the context, `$1..$n` bound. */
57
+ query: <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[]) => Promise<Row[]>;
58
+ queryOne: <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[]) => Promise<Row | null>;
59
+ /** Returns the affected row count. */
60
+ execute: (text: string, params?: unknown[]) => Promise<number>;
61
+ /** Fully qualified identifier of a registered resource; omit for the owning resource. */
62
+ ref: (resourceAlias?: string) => string;
63
+ }
64
+ export interface PostgresResource<T extends ResourceRecord> extends Resource<T>, ResourceLocker<T> {
65
+ /** Physical table name override. Defaults to the resource alias, sanitized. */
66
+ name?: string;
67
+ /** The AJV schema — single source of truth for the table structure. */
68
+ schema?: AnySchema;
69
+ /** Compiled table specification. Available once `init()` has run. */
70
+ table: TableSpec;
71
+ /** The Drizzle runtime table built from {@link table}. */
72
+ entity: PgRuntimeTable;
73
+ migrations: MigrationRegistry<PostgresTx>;
74
+ db: () => Promise<PostgresDb>;
75
+ client: () => Promise<Pool>;
76
+ /** Declare an index the JSON schema can't express. Chainable. */
77
+ index: <Type extends PostgresResource<T>>(name: string, spec: PgIndexSpec) => Type;
78
+ /** Register a code migration. Chainable. */
79
+ migration: <Type extends PostgresResource<T>>(name: string, apply: (tx: PostgresTx) => Promise<void>, stage?: MigrationStage) => Type;
80
+ getDefaults: () => Partial<T>;
81
+ /** Raw rows, no marshalling. */
82
+ query: <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[]) => Promise<Row[]>;
83
+ queryOne: <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[]) => Promise<Row | null>;
84
+ /** Returns the affected row count. */
85
+ execute: (text: string, params?: unknown[]) => Promise<number>;
86
+ /** Rows marshalled back into `T` through the table spec. */
87
+ select: <Type extends T>(text: string, params?: unknown[]) => Promise<Type[]>;
88
+ selectOne: <Type extends T>(text: string, params?: unknown[]) => Promise<Type | null>;
89
+ /** Fully qualified `"schema"."table"`; pass an alias to reference another resource. */
90
+ ref: (resourceAlias?: string) => string;
91
+ transaction: <R>(fn: (tx: PostgresTx) => Promise<R>) => Promise<R>;
92
+ /** Create with a caller supplied id — `create()` refuses one, mirroring mongo. */
93
+ insert: <Type extends T>(record: Partial<Type>) => Promise<Type>;
94
+ /** `INSERT ... ON CONFLICT (...) DO UPDATE`. Defaults to conflicting on the primary key. */
95
+ upsert: <Type extends T>(record: Partial<Type>, conflict?: string[]) => Promise<Type>;
96
+ /** Merge semantics — `update()` replaces the whole record, mirroring mongo's `replaceOne`. */
97
+ patch: <Type extends T>(record: Partial<Type>, opts?: string | {
98
+ field?: string;
99
+ }) => Promise<Type>;
100
+ /** Bulk delete by criteria. Returns the deleted row count. */
101
+ purge: (criteria: ListCriteria) => Promise<number>;
102
+ count: (criteria?: ListCriteria | ListOptions) => Promise<number>;
103
+ }
104
+ /** Compiled, database ready description of a resource's table. */
105
+ export interface TableSpec {
106
+ alias: string;
107
+ /** Postgres namespace. */
108
+ schema: string;
109
+ /** Physical table name. */
110
+ table: string;
111
+ /** `"schema"."table"` — already quoted. */
112
+ qualified: string;
113
+ columns: ColumnSpec[];
114
+ byProperty: Record<string, ColumnSpec>;
115
+ byColumn: Record<string, ColumnSpec>;
116
+ /** Column names. */
117
+ primaryKey: string[];
118
+ uniques: PgUniqueSpec[];
119
+ checks: PgCheckSpec[];
120
+ indexes: PgIndexSpec[];
121
+ references: PgReferenceSpec[];
122
+ /** Columns reconciliation must never touch. */
123
+ unmanaged: string[];
124
+ autoSync: boolean;
125
+ comment?: string;
126
+ }
127
+ export interface ColumnSpec {
128
+ /** JSON schema property name. */
129
+ property: string;
130
+ /** Physical column name. */
131
+ column: string;
132
+ /** Canonical `format_type` spelling, e.g. `character varying(320)`. */
133
+ sqlType: string;
134
+ jsonType: ColumnJsonType;
135
+ notNull: boolean;
136
+ primaryKey: boolean;
137
+ defaultLiteral?: string | number | boolean | null;
138
+ /** Raw SQL default expression, e.g. `now()`. */
139
+ defaultRaw?: string;
140
+ /** `secure: true` in the JSON schema — the stored value is ciphertext. */
141
+ secure: boolean;
142
+ /** Value has to be `JSON.stringify`d on the way in. */
143
+ jsonb: boolean;
144
+ /** Postgres array column. */
145
+ array: boolean;
146
+ /** `USING` expression for `ALTER COLUMN ... TYPE`. */
147
+ using?: string;
148
+ managed: boolean;
149
+ comment?: string;
150
+ }
151
+ export type ColumnJsonType = 'string' | 'number' | 'integer' | 'bigint' | 'boolean' | 'object' | 'array' | 'date' | 'binary' | 'unknown';
152
+ /** Per-property `pg` keyword vocabulary. */
153
+ export interface PgPropertyOverride {
154
+ column?: string;
155
+ /** Raw Postgres type — wins over everything inferred from the JSON schema. */
156
+ type?: string;
157
+ length?: number;
158
+ precision?: number;
159
+ scale?: number;
160
+ nullable?: boolean;
161
+ default?: string | number | boolean | null;
162
+ defaultRaw?: string;
163
+ primaryKey?: boolean;
164
+ unique?: boolean | string;
165
+ index?: boolean | PgIndexSpec | PgIndexSpec[];
166
+ references?: PgReferenceSpec;
167
+ jsonb?: boolean;
168
+ array?: boolean;
169
+ /** `{{col}}` expands to the quoted column name. */
170
+ check?: string;
171
+ using?: string;
172
+ /** `false` puts the column outside reconciliation's authority. */
173
+ managed?: boolean;
174
+ comment?: string;
175
+ }
176
+ /** Root level `pg` keyword vocabulary. */
177
+ export interface PgRootOverride {
178
+ table?: string;
179
+ schema?: string;
180
+ /** Property names forming a composite primary key. */
181
+ primaryKey?: string[];
182
+ unique?: PgUniqueSpec[];
183
+ indexes?: PgIndexSpec[];
184
+ checks?: PgCheckSpec[];
185
+ /** Physical column names reconciliation must leave alone. */
186
+ unmanaged?: string[];
187
+ autoSync?: boolean;
188
+ comment?: string;
189
+ }
190
+ export interface PgIndexSpec {
191
+ name?: string;
192
+ /** Property names — mapped to physical columns at compile time. */
193
+ columns?: string | string[];
194
+ /** Raw expression index. Wins over `columns`. */
195
+ expression?: string;
196
+ unique?: boolean;
197
+ method?: PgIndexMethod | `${PgIndexMethod}`;
198
+ /** Partial index predicate. */
199
+ where?: string;
200
+ }
201
+ export interface PgUniqueSpec {
202
+ name?: string;
203
+ /** Property names. */
204
+ columns: string[];
205
+ }
206
+ export interface PgCheckSpec {
207
+ name?: string;
208
+ expression: string;
209
+ }
210
+ export interface PgReferenceSpec {
211
+ /** Local property holding the key. Filled in by the compiler. */
212
+ property?: string;
213
+ /** Resolve the target table from a registered resource alias... */
214
+ resource?: string;
215
+ /** ...or name it directly. */
216
+ table?: string;
217
+ schema?: string;
218
+ /** Target column. Defaults to `id`. */
219
+ column?: string;
220
+ name?: string;
221
+ onDelete?: PgReferentialAction | `${PgReferentialAction}`;
222
+ onUpdate?: PgReferentialAction | `${PgReferentialAction}`;
223
+ }
224
+ /**
225
+ * The Drizzle table object. Deliberately opaque — tables are built at runtime from JSON
226
+ * schemas, so Drizzle's compile time inference has nothing to infer from and every
227
+ * column would be `any` anyway. Cast it at the call site when you need the typed builder.
228
+ */
229
+ export type PgRuntimeTable = Record<string, any>;
230
+ /** One column as Postgres currently reports it. */
231
+ export interface LiveColumn {
232
+ name: string;
233
+ /** `format_type` output — directly comparable with {@link ColumnSpec.sqlType}. */
234
+ type: string;
235
+ notNull: boolean;
236
+ defaultExpr: string | null;
237
+ identity: string;
238
+ generated: string;
239
+ ordinal: number;
240
+ }
241
+ export interface LiveIndex {
242
+ name: string;
243
+ definition: string;
244
+ }
245
+ export interface LiveConstraint {
246
+ name: string;
247
+ /** `p` primary, `u` unique, `f` foreign, `c` check. */
248
+ type: string;
249
+ definition: string;
250
+ }
251
+ export interface LiveTable {
252
+ exists: boolean;
253
+ columns: LiveColumn[];
254
+ indexes: LiveIndex[];
255
+ constraints: LiveConstraint[];
256
+ }
257
+ /** One reconciliation step, kept separate from its SQL so it can be logged and explained. */
258
+ export interface DdlStatement {
259
+ kind: DdlKind;
260
+ /** What the statement touches — column, index or constraint name. */
261
+ target: string;
262
+ sql: string;
263
+ /** True when applying this loses data. */
264
+ destructive?: boolean;
265
+ /** Rows that would be affected, sampled immediately before a destructive step. */
266
+ affected?: number;
267
+ }
268
+ export type DdlKind = 'create-schema' | 'create-table' | 'add-column' | 'set-default' | 'backfill' | 'alter-type' | 'set-not-null' | 'drop-not-null' | 'drop-constraint' | 'add-constraint' | 'drop-index' | 'create-index' | 'add-foreign-key' | 'drop-column' | 'comment';
269
+ export interface DdlPlan {
270
+ fresh: boolean;
271
+ statements: DdlStatement[];
272
+ }
273
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import type { ListCriteria, ListSort } from '@owlmeans/resource';
2
+ import type { SQL } from 'drizzle-orm';
3
+ import type { PgRuntimeTable, TableSpec } from '../types.js';
4
+ /**
5
+ * Translate `ListCriteria` into a WHERE clause.
6
+ *
7
+ * An unknown key raises rather than being skipped: a typo silently widening a query to
8
+ * the whole table is the failure mode worth being loud about.
9
+ *
10
+ * @throws {UnsupportedArgumentError}
11
+ */
12
+ export declare const criteriaToSql: (criteria: ListCriteria | undefined, spec: TableSpec, table: PgRuntimeTable) => SQL | undefined;
13
+ /**
14
+ * Translate `ListPager.sort` into ORDER BY. `[field, true]` is descending, matching the
15
+ * `order ? -1 : 1` mapping mongo uses.
16
+ *
17
+ * The primary key is always appended as a tiebreak. Postgres has no implicit row order, so
18
+ * paginating on a non-unique sort key silently duplicates and skips rows between pages —
19
+ * a difference from mongo that would otherwise surface as a data bug rather than an error.
20
+ *
21
+ * @throws {UnsupportedArgumentError}
22
+ */
23
+ export declare const sortToSql: (sort: ListSort[] | undefined, spec: TableSpec, table: PgRuntimeTable) => SQL[];
24
+ //# sourceMappingURL=criteria.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"criteria.d.ts","sourceRoot":"","sources":["../../src/utils/criteria.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAEhE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEtC,OAAO,KAAK,EAAc,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAqHxE;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,UAAU,YAAY,GAAG,SAAS,EAAE,MAAM,SAAS,EAAE,OAAO,cAAc,KACzE,GAAG,GAAG,SAIR,CAAA;AAuED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,QAAQ,EAAE,GAAG,SAAS,EAAE,MAAM,SAAS,EAAE,OAAO,cAAc,KACnE,GAAG,EA0BL,CAAA"}
@@ -0,0 +1,209 @@
1
+ import { UnsupportedArgumentError } from '@owlmeans/resource';
2
+ import { and, asc, desc, or, sql } from 'drizzle-orm';
3
+ const COMPARISON = {
4
+ $eq: '=', $ne: '<>', $gt: '>', $gte: '>=', $lt: '<', $lte: '<='
5
+ };
6
+ const columnRef = (table, column) => sql `${table[column.property]}`;
7
+ const value = (raw, column) => {
8
+ if (column.jsonb && raw != null && typeof raw !== 'string') {
9
+ return sql `${JSON.stringify(raw)}`;
10
+ }
11
+ return sql `${raw}`;
12
+ };
13
+ const inList = (table, column, values, negate) => {
14
+ const present = values.filter(entry => entry != null);
15
+ const hasNull = present.length !== values.length;
16
+ if (present.length < 1) {
17
+ /** Postgres rejects an empty `IN ()`, and an empty set matches nothing (or everything, negated). */
18
+ return hasNull
19
+ ? sql `${columnRef(table, column)} IS ${negate ? sql `NOT` : sql ``} NULL`
20
+ : negate ? sql `TRUE` : sql `FALSE`;
21
+ }
22
+ const list = sql.join(present.map(entry => value(entry, column)), sql `, `);
23
+ const membership = negate
24
+ ? sql `${columnRef(table, column)} NOT IN (${list})`
25
+ : sql `${columnRef(table, column)} IN (${list})`;
26
+ if (!hasNull) {
27
+ return membership;
28
+ }
29
+ /**
30
+ * `IN` never matches NULL, so `{ $in: [null, 'x'] }` — a real shape in this codebase —
31
+ * has to be widened explicitly or the null branch silently disappears.
32
+ */
33
+ return negate
34
+ ? sql `(${membership} AND ${columnRef(table, column)} IS NOT NULL)`
35
+ : sql `(${membership} OR ${columnRef(table, column)} IS NULL)`;
36
+ };
37
+ const operators = (table, column, spec) => {
38
+ const conditions = [];
39
+ for (const [operator, operand] of Object.entries(spec)) {
40
+ if (operator in COMPARISON) {
41
+ conditions.push(operand == null
42
+ ? sql `${columnRef(table, column)} IS ${operator === '$ne' ? sql `NOT` : sql ``} NULL`
43
+ : sql `${columnRef(table, column)} ${sql.raw(COMPARISON[operator])} ${value(operand, column)}`);
44
+ continue;
45
+ }
46
+ switch (operator) {
47
+ case '$in':
48
+ case '$nin':
49
+ conditions.push(inList(table, column, Array.isArray(operand) ? operand : [operand], operator === '$nin'));
50
+ break;
51
+ case '$exists':
52
+ conditions.push(operand === false
53
+ ? sql `${columnRef(table, column)} IS NULL`
54
+ : sql `${columnRef(table, column)} IS NOT NULL`);
55
+ break;
56
+ case '$null':
57
+ conditions.push(operand === false
58
+ ? sql `${columnRef(table, column)} IS NOT NULL`
59
+ : sql `${columnRef(table, column)} IS NULL`);
60
+ break;
61
+ case '$like':
62
+ conditions.push(sql `${columnRef(table, column)} LIKE ${operand}`);
63
+ break;
64
+ case '$ilike':
65
+ conditions.push(sql `${columnRef(table, column)} ILIKE ${operand}`);
66
+ break;
67
+ case '$regex':
68
+ conditions.push(sql `${columnRef(table, column)} ~ ${operand}`);
69
+ break;
70
+ case '$startsWith':
71
+ conditions.push(sql `${columnRef(table, column)} LIKE ${`${escapeLike(`${operand}`)}%`}`);
72
+ break;
73
+ case '$endsWith':
74
+ conditions.push(sql `${columnRef(table, column)} LIKE ${`%${escapeLike(`${operand}`)}`}`);
75
+ break;
76
+ case '$between': {
77
+ if (!Array.isArray(operand) || operand.length !== 2) {
78
+ throw new UnsupportedArgumentError(`criteria:$between:${column.property}`);
79
+ }
80
+ conditions.push(sql `${columnRef(table, column)} BETWEEN ${value(operand[0], column)} AND ${value(operand[1], column)}`);
81
+ break;
82
+ }
83
+ case '$contains':
84
+ conditions.push(sql `${columnRef(table, column)} @> ${value(operand, column)}`);
85
+ break;
86
+ case '$contained':
87
+ conditions.push(sql `${columnRef(table, column)} <@ ${value(operand, column)}`);
88
+ break;
89
+ case '$overlaps':
90
+ conditions.push(sql `${columnRef(table, column)} && ${value(operand, column)}`);
91
+ break;
92
+ default:
93
+ throw new UnsupportedArgumentError(`criteria-operator:${operator}`);
94
+ }
95
+ }
96
+ return conditions;
97
+ };
98
+ const escapeLike = (value) => value.replace(/[\\%_]/g, match => `\\${match}`);
99
+ const isOperatorSpec = (value) => value != null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)
100
+ && Object.keys(value).some(key => key.startsWith('$'));
101
+ /**
102
+ * Translate `ListCriteria` into a WHERE clause.
103
+ *
104
+ * An unknown key raises rather than being skipped: a typo silently widening a query to
105
+ * the whole table is the failure mode worth being loud about.
106
+ *
107
+ * @throws {UnsupportedArgumentError}
108
+ */
109
+ export const criteriaToSql = (criteria, spec, table) => {
110
+ const conditions = build(criteria, spec, table);
111
+ return conditions.length > 0 ? and(...conditions) : undefined;
112
+ };
113
+ const build = (criteria, spec, table) => {
114
+ const conditions = [];
115
+ for (const [key, raw] of Object.entries(criteria ?? {})) {
116
+ if (raw === undefined) {
117
+ continue;
118
+ }
119
+ if (key === '$and' || key === '$or') {
120
+ const parts = (Array.isArray(raw) ? raw : [raw])
121
+ .map(entry => and(...build(entry, spec, table)))
122
+ .filter((entry) => entry != null);
123
+ if (parts.length > 0) {
124
+ const combined = key === '$and' ? and(...parts) : or(...parts);
125
+ if (combined != null) {
126
+ conditions.push(combined);
127
+ }
128
+ }
129
+ continue;
130
+ }
131
+ if (key === '$not') {
132
+ const inner = and(...build(raw, spec, table));
133
+ if (inner != null) {
134
+ conditions.push(sql `NOT (${inner})`);
135
+ }
136
+ continue;
137
+ }
138
+ /** `profile.city` reaches into a jsonb column rather than naming a column. */
139
+ const [head, ...path] = key.split('.');
140
+ const column = spec.byProperty[head];
141
+ if (column == null) {
142
+ throw new UnsupportedArgumentError(`criteria:${key}`);
143
+ }
144
+ if (path.length > 0) {
145
+ if (!column.jsonb) {
146
+ throw new UnsupportedArgumentError(`criteria-path:${key}`);
147
+ }
148
+ conditions.push(sql `${columnRef(table, column)} #>> ${`{${path.join(',')}}`} = ${`${raw}`}`);
149
+ continue;
150
+ }
151
+ if (raw === null) {
152
+ conditions.push(sql `${columnRef(table, column)} IS NULL`);
153
+ continue;
154
+ }
155
+ if (isOperatorSpec(raw)) {
156
+ conditions.push(...operators(table, column, raw));
157
+ continue;
158
+ }
159
+ if (Array.isArray(raw)) {
160
+ /**
161
+ * A bare array means `IN` for a relational store, which is overwhelmingly the intent.
162
+ * Exact array equality against a `text[]` column stays available as `{ $eq: [...] }`.
163
+ */
164
+ conditions.push(inList(table, column, raw, false));
165
+ continue;
166
+ }
167
+ if (column.jsonb && typeof raw === 'object') {
168
+ conditions.push(sql `${columnRef(table, column)} @> ${JSON.stringify(raw)}`);
169
+ continue;
170
+ }
171
+ conditions.push(sql `${columnRef(table, column)} = ${value(raw, column)}`);
172
+ }
173
+ return conditions;
174
+ };
175
+ /**
176
+ * Translate `ListPager.sort` into ORDER BY. `[field, true]` is descending, matching the
177
+ * `order ? -1 : 1` mapping mongo uses.
178
+ *
179
+ * The primary key is always appended as a tiebreak. Postgres has no implicit row order, so
180
+ * paginating on a non-unique sort key silently duplicates and skips rows between pages —
181
+ * a difference from mongo that would otherwise surface as a data bug rather than an error.
182
+ *
183
+ * @throws {UnsupportedArgumentError}
184
+ */
185
+ export const sortToSql = (sort, spec, table) => {
186
+ const order = [];
187
+ const seen = [];
188
+ for (const entry of sort ?? []) {
189
+ /** Both `ListSort` forms are handled explicitly — destructuring a plain string yields characters. */
190
+ const [property, descending] = typeof entry === 'string' ? [entry, false] : [entry[0], entry[1] === true];
191
+ const column = spec.byProperty[property];
192
+ if (column == null) {
193
+ throw new UnsupportedArgumentError(`sort:${property}`);
194
+ }
195
+ seen.push(column.column);
196
+ order.push(descending ? desc(table[column.property]) : asc(table[column.property]));
197
+ }
198
+ for (const key of spec.primaryKey) {
199
+ if (seen.includes(key)) {
200
+ continue;
201
+ }
202
+ const column = spec.byColumn[key];
203
+ if (column != null) {
204
+ order.push(asc(table[column.property]));
205
+ }
206
+ }
207
+ return order;
208
+ };
209
+ //# sourceMappingURL=criteria.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"criteria.js","sourceRoot":"","sources":["../../src/utils/criteria.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { BasicContext } from '@owlmeans/context';
2
+ import type { DdlPlan, DdlStatement, LiveTable, TableSpec } from '../types.js';
3
+ /**
4
+ * Foreign keys are planned separately from the rest of the table, and applied only once
5
+ * every resource has initialized: a key points at a table another resource owns, and that
6
+ * resource's own `init()` may not have run yet.
7
+ *
8
+ * @throws {PostgresPlaceholderError} when a target can't be resolved.
9
+ */
10
+ export declare const planForeignKeys: (spec: TableSpec, context?: BasicContext<any>) => DdlStatement[];
11
+ /**
12
+ * Compare the compiled specification against the live table and produce the ordered DDL
13
+ * that converges one onto the other.
14
+ *
15
+ * Statement order is load bearing:
16
+ * - `DROP COLUMN` is last, because a `USING` cast or a backfill may legitimately read a
17
+ * column that is about to disappear.
18
+ * - A primary key constraint is never dropped: it cascades into every referencing key and
19
+ * can't be undone inside the same transaction once dependents exist.
20
+ *
21
+ * Foreign keys are not part of the plan at all — see {@link planForeignKeys}.
22
+ */
23
+ export declare const planSync: (spec: TableSpec, live: LiveTable, additive?: boolean) => DdlPlan;
24
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/utils/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAKrD,OAAO,KAAK,EACE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAiC,SAAS,EACvF,MAAM,aAAa,CAAA;AAqDpB;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,SAAS,EAAE,UAAU,YAAY,CAAC,GAAG,CAAC,KAC3C,YAAY,EAwCb,CAAA;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,GACnB,MAAM,SAAS,EAAE,MAAM,SAAS,EAAE,WAAU,OAAe,KAC1D,OAuNF,CAAA"}