@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,356 @@
1
+ import { UnsupportedArgumentError } from '@owlmeans/resource';
2
+ import { DEF_ID_DEFAULT, DEF_JSON_TYPE, DEF_SQL_TYPE, ID_FIELD, PG_KEYWORD, PgIndexMethod } from '../consts.js';
3
+ import { pgIdentifier, qualify, quoteIdent } from './name.js';
4
+ const INT32_MAX = 2147483647;
5
+ /**
6
+ * Normalize a Postgres type name to the spelling `format_type()` reports, so the drift
7
+ * comparison against a live table is an exact string match instead of a fuzzy one.
8
+ */
9
+ export const toFormatType = (type) => {
10
+ const trimmed = type.trim().toLowerCase();
11
+ const match = /^([a-z0-9_ ]+?)\s*(\(([^)]*)\))?\s*(\[\])?$/.exec(trimmed);
12
+ if (match == null) {
13
+ return trimmed;
14
+ }
15
+ const [, base, , args, array] = match;
16
+ const aliases = {
17
+ int: 'integer', int4: 'integer', int2: 'smallint', int8: 'bigint', serial: 'integer',
18
+ bool: 'boolean', float4: 'real', float8: 'double precision', decimal: 'numeric',
19
+ varchar: 'character varying', char: 'character', bpchar: 'character',
20
+ timestamptz: 'timestamp with time zone', timetz: 'time with time zone',
21
+ timestamp: 'timestamp without time zone', time: 'time without time zone'
22
+ };
23
+ const resolved = aliases[base.trim()] ?? base.trim();
24
+ /** Postgres prints multi-argument typmods without spaces: `numeric(12,2)`. */
25
+ const suffix = args != null ? `(${args.split(',').map(part => part.trim()).join(',')})` : '';
26
+ return `${resolved}${suffix}${array ?? ''}`;
27
+ };
28
+ const readOverride = (property) => property[PG_KEYWORD] ?? {};
29
+ /**
30
+ * Nullability is decided in exactly one place and threaded down from there. Mongo's mapper
31
+ * recomputes it per branch and lost it twice — on `date-time` and on optional objects.
32
+ */
33
+ const isNullable = (property, isRequired) => {
34
+ const override = readOverride(property);
35
+ if (override.nullable != null) {
36
+ return override.nullable;
37
+ }
38
+ if (property.nullable === true) {
39
+ return true;
40
+ }
41
+ if (Array.isArray(property.type) && property.type.includes('null')) {
42
+ return true;
43
+ }
44
+ return !isRequired;
45
+ };
46
+ const baseType = (property) => Array.isArray(property.type) ? property.type.find(type => type !== 'null') : property.type;
47
+ const scalarSqlType = (property) => {
48
+ const override = readOverride(property);
49
+ const type = baseType(property);
50
+ switch (type) {
51
+ case 'string':
52
+ switch (property.format) {
53
+ case 'date-time': return { sqlType: 'timestamp with time zone', jsonType: 'date' };
54
+ case 'date': return { sqlType: 'date', jsonType: 'date' };
55
+ case 'time': return { sqlType: 'time without time zone', jsonType: 'string' };
56
+ case 'uuid': return { sqlType: 'uuid', jsonType: 'string' };
57
+ case 'binary': return { sqlType: 'bytea', jsonType: 'binary' };
58
+ default: break;
59
+ }
60
+ return property.maxLength != null
61
+ ? { sqlType: `character varying(${property.maxLength})`, jsonType: 'string' }
62
+ : { sqlType: DEF_SQL_TYPE, jsonType: 'string' };
63
+ case 'integer':
64
+ return property.maximum != null && property.maximum > INT32_MAX
65
+ ? { sqlType: 'bigint', jsonType: 'bigint' }
66
+ : { sqlType: 'integer', jsonType: 'integer' };
67
+ case 'number':
68
+ return override.precision != null
69
+ ? { sqlType: `numeric(${override.precision},${override.scale ?? 0})`, jsonType: 'number' }
70
+ : { sqlType: 'double precision', jsonType: 'number' };
71
+ case 'boolean':
72
+ return { sqlType: 'boolean', jsonType: 'boolean' };
73
+ case 'object':
74
+ /**
75
+ * The framework's date convention — `{ type: 'object', format: 'date-time' }`. Mongo's
76
+ * mapper broke twice on exactly this branch by dropping nullability, so nullability is
77
+ * decided by the caller, never here.
78
+ */
79
+ return property.format === 'date-time'
80
+ ? { sqlType: 'timestamp with time zone', jsonType: 'date' }
81
+ : { sqlType: DEF_JSON_TYPE, jsonType: 'object' };
82
+ default:
83
+ return { sqlType: DEF_JSON_TYPE, jsonType: 'unknown' };
84
+ }
85
+ };
86
+ const arraySqlType = (property) => {
87
+ const items = property.items;
88
+ const itemType = items != null ? baseType(items) : undefined;
89
+ /** Only scalar element types become Postgres arrays; anything else stays jsonb. */
90
+ if (items != null && itemType != null && ['string', 'integer', 'number', 'boolean'].includes(itemType)
91
+ && items.format == null && items.enum == null) {
92
+ const scalar = scalarSqlType(items);
93
+ return { sqlType: `${scalar.sqlType}[]`, jsonType: 'array', array: true };
94
+ }
95
+ return { sqlType: DEF_JSON_TYPE, jsonType: 'array', array: false };
96
+ };
97
+ const compileColumn = (name, property, required) => {
98
+ const override = readOverride(property);
99
+ const secure = property.secure === true;
100
+ const type = baseType(property);
101
+ const nullable = isNullable(property, required.includes(name));
102
+ let sqlType;
103
+ let jsonType;
104
+ let array = false;
105
+ if (override.type != null) {
106
+ sqlType = override.type;
107
+ jsonType = secure ? 'string' : scalarSqlType(property).jsonType;
108
+ array = override.array === true || override.type.endsWith('[]');
109
+ }
110
+ else if (secure) {
111
+ /**
112
+ * A secure field is stored as ciphertext, so its declared JSON type says nothing about
113
+ * its column. It's always unbounded text: `maxLength` would truncate the ciphertext,
114
+ * an enum CHECK would never match it, and jsonb would fail to parse it.
115
+ */
116
+ sqlType = DEF_SQL_TYPE;
117
+ jsonType = 'string';
118
+ }
119
+ else if (type === 'array') {
120
+ const resolved = arraySqlType(property);
121
+ sqlType = resolved.sqlType;
122
+ jsonType = resolved.jsonType;
123
+ array = resolved.array;
124
+ }
125
+ else {
126
+ const resolved = scalarSqlType(property);
127
+ sqlType = resolved.sqlType;
128
+ jsonType = resolved.jsonType;
129
+ }
130
+ if (override.length != null) {
131
+ sqlType = `character varying(${override.length})`;
132
+ }
133
+ if (override.array === true && !array && !sqlType.endsWith('[]')) {
134
+ sqlType = `${sqlType}[]`;
135
+ array = true;
136
+ }
137
+ if (override.jsonb === true) {
138
+ sqlType = DEF_JSON_TYPE;
139
+ jsonType = jsonType === 'array' ? 'array' : 'object';
140
+ array = false;
141
+ }
142
+ const formatted = toFormatType(sqlType);
143
+ const isJsonb = formatted === 'jsonb' || formatted === 'json';
144
+ const column = {
145
+ property: name,
146
+ /** No implicit snake_casing — a silent rename is a silent DROP plus ADD. */
147
+ column: pgIdentifier(override.column ?? name),
148
+ sqlType: formatted,
149
+ jsonType,
150
+ notNull: override.nullable === false ? true : !nullable,
151
+ primaryKey: override.primaryKey === true,
152
+ secure,
153
+ jsonb: isJsonb,
154
+ array,
155
+ managed: override.managed !== false,
156
+ ...(override.using != null ? { using: override.using } : {}),
157
+ ...(override.comment != null ? { comment: override.comment } : {})
158
+ };
159
+ if (override.defaultRaw != null) {
160
+ column.defaultRaw = override.defaultRaw;
161
+ }
162
+ else if (override.default !== undefined) {
163
+ column.defaultLiteral = override.default;
164
+ }
165
+ else if (property.default !== undefined && !isJsonb && !array) {
166
+ /** Non-scalar defaults stay in `getDefaults()` only — they'd need casting in DDL. */
167
+ column.defaultLiteral = property.default;
168
+ }
169
+ return column;
170
+ };
171
+ const collectProperties = (schema) => {
172
+ const properties = { ...schema.properties };
173
+ const required = [...(schema.required ?? [])];
174
+ /** `allOf` composition is used across the framework's schemas — flatten it like mongo does. */
175
+ for (const part of schema.allOf ?? []) {
176
+ const nested = collectProperties(part);
177
+ Object.assign(properties, nested.properties);
178
+ required.push(...nested.required);
179
+ }
180
+ return { properties, required };
181
+ };
182
+ /**
183
+ * Compile a resource's AJV schema into the table specification that drives both DDL
184
+ * emission and drift detection.
185
+ *
186
+ * `extraIndexes` carries what `resource.index()` declared. It's compiled here rather than
187
+ * merged afterwards so chained declarations get the same property-to-column mapping and
188
+ * the same generated names as schema-borne ones.
189
+ *
190
+ * @throws {UnsupportedArgumentError} when an override asks for something unrepresentable.
191
+ */
192
+ export const schemaToTableSpec = (alias, schema, pgSchema, table, autoSync, extraIndexes = []) => {
193
+ const raw = (schema ?? {});
194
+ const root = raw[PG_KEYWORD] ?? {};
195
+ const { properties, required } = collectProperties(raw);
196
+ const columns = [];
197
+ const uniques = [...(root.unique ?? [])];
198
+ const checks = [...(root.checks ?? [])];
199
+ const indexes = [...(root.indexes ?? []), ...extraIndexes];
200
+ const references = [];
201
+ const resolvedTable = pgIdentifier(root.table ?? table);
202
+ const resolvedSchema = pgIdentifier(root.schema ?? pgSchema);
203
+ for (const [name, property] of Object.entries(properties)) {
204
+ const column = compileColumn(name, property, required);
205
+ columns.push(column);
206
+ const override = readOverride(property);
207
+ if (override.unique != null && override.unique !== false) {
208
+ if (column.secure) {
209
+ /**
210
+ * Encryption uses a managed nonce, so two identical plaintexts encrypt to different
211
+ * ciphertexts — a unique constraint on the column would never collide, silently.
212
+ */
213
+ throw new UnsupportedArgumentError(`secure-unique:${name}`);
214
+ }
215
+ uniques.push({
216
+ columns: [name],
217
+ ...(typeof override.unique === 'string' ? { name: override.unique } : {})
218
+ });
219
+ }
220
+ if (override.index != null && override.index !== false) {
221
+ if (column.secure) {
222
+ console.warn(`@owlmeans/postgres-resource: index on secure column "${alias}.${name}" — encryption`
223
+ + ' is non-deterministic, so equality lookups through it will never match.');
224
+ }
225
+ const specs = override.index === true
226
+ ? [{ columns: [name] }]
227
+ : Array.isArray(override.index) ? override.index : [override.index];
228
+ indexes.push(...specs.map(spec => ({ ...spec, columns: spec.columns ?? [name] })));
229
+ }
230
+ if (override.references != null) {
231
+ references.push({
232
+ ...override.references,
233
+ property: name,
234
+ column: override.references.column ?? ID_FIELD,
235
+ name: pgIdentifier(override.references.name ?? `${resolvedTable}_${column.column}_fkey`)
236
+ });
237
+ }
238
+ if (override.check != null) {
239
+ checks.push({
240
+ name: `${resolvedTable}_${column.column}_check`,
241
+ expression: override.check.replace(/\{\{col\}\}/g, quoteIdent(column.column))
242
+ });
243
+ }
244
+ /** A string enum becomes a CHECK — a native PG enum can't drop values and can't be altered in a transaction. */
245
+ if (property.enum != null && !column.secure && override.type == null
246
+ && baseType(property) === 'string' && property.enum.every(value => typeof value === 'string')) {
247
+ const values = property.enum.map(value => `'${value.replace(/'/g, "''")}'`).join(', ');
248
+ const predicate = column.notNull
249
+ ? `${quoteIdent(column.column)} IN (${values})`
250
+ : `${quoteIdent(column.column)} IS NULL OR ${quoteIdent(column.column)} IN (${values})`;
251
+ checks.push({ name: `${resolvedTable}_${column.column}_enum`, expression: predicate });
252
+ }
253
+ }
254
+ const byProperty = {};
255
+ const byColumn = {};
256
+ for (const column of columns) {
257
+ byProperty[column.property] = column;
258
+ byColumn[column.column] = column;
259
+ }
260
+ let primaryKey = [];
261
+ if (root.primaryKey != null && root.primaryKey.length > 0) {
262
+ primaryKey = root.primaryKey.map(property => {
263
+ const column = byProperty[property];
264
+ if (column == null) {
265
+ throw new UnsupportedArgumentError(`primary-key:${property}`);
266
+ }
267
+ column.notNull = true;
268
+ return column.column;
269
+ });
270
+ }
271
+ else {
272
+ const explicit = columns.filter(column => column.primaryKey);
273
+ if (explicit.length > 0) {
274
+ primaryKey = explicit.map(column => {
275
+ column.notNull = true;
276
+ return column.column;
277
+ });
278
+ }
279
+ else {
280
+ /**
281
+ * Every OwlMeans record is addressed by `id`, so the column is synthesized when the
282
+ * schema doesn't declare it — `create()` and `load()` both assume it exists.
283
+ */
284
+ let id = byProperty[ID_FIELD];
285
+ if (id == null) {
286
+ id = {
287
+ property: ID_FIELD, column: ID_FIELD, sqlType: DEF_SQL_TYPE, jsonType: 'string',
288
+ notNull: true, primaryKey: true, secure: false, jsonb: false, array: false,
289
+ managed: true, defaultRaw: DEF_ID_DEFAULT
290
+ };
291
+ columns.unshift(id);
292
+ byProperty[ID_FIELD] = id;
293
+ byColumn[ID_FIELD] = id;
294
+ }
295
+ else {
296
+ id.notNull = true;
297
+ id.primaryKey = true;
298
+ if (id.defaultRaw == null && id.defaultLiteral === undefined) {
299
+ id.defaultRaw = id.sqlType === 'uuid' ? 'gen_random_uuid()' : DEF_ID_DEFAULT;
300
+ }
301
+ }
302
+ primaryKey = [id.column];
303
+ }
304
+ }
305
+ /** Index and unique specs address properties; map them onto physical columns once, here. */
306
+ const mapColumns = (names) => names.map(name => {
307
+ const column = byProperty[name];
308
+ if (column == null) {
309
+ throw new UnsupportedArgumentError(`unknown-property:${name}`);
310
+ }
311
+ return column.column;
312
+ });
313
+ const resolvedIndexes = indexes.map(spec => {
314
+ const list = spec.columns == null
315
+ ? []
316
+ : mapColumns(Array.isArray(spec.columns) ? spec.columns : [spec.columns]);
317
+ const suffix = spec.unique === true ? 'uq' : 'idx';
318
+ return {
319
+ ...spec,
320
+ columns: list,
321
+ method: spec.method ?? PgIndexMethod.BTree,
322
+ name: pgIdentifier(spec.name ?? `${resolvedTable}_${list.join('_')}_${suffix}`)
323
+ };
324
+ });
325
+ const resolvedUniques = uniques.map(spec => {
326
+ const list = mapColumns(spec.columns);
327
+ return { columns: list, name: pgIdentifier(spec.name ?? `${resolvedTable}_${list.join('_')}_key`) };
328
+ });
329
+ return {
330
+ alias,
331
+ schema: resolvedSchema,
332
+ table: resolvedTable,
333
+ qualified: qualify(resolvedSchema, resolvedTable),
334
+ columns,
335
+ byProperty,
336
+ byColumn,
337
+ primaryKey,
338
+ uniques: resolvedUniques,
339
+ checks: checks.map(check => ({ ...check, name: pgIdentifier(check.name ?? `${resolvedTable}_check`) })),
340
+ indexes: resolvedIndexes,
341
+ references,
342
+ unmanaged: [
343
+ ...(root.unmanaged ?? []).map(name => byProperty[name]?.column ?? pgIdentifier(name)),
344
+ ...columns.filter(column => !column.managed).map(column => column.column)
345
+ ],
346
+ autoSync: root.autoSync ?? autoSync,
347
+ ...(root.comment != null ? { comment: root.comment } : {})
348
+ };
349
+ };
350
+ /**
351
+ * AJV keyword registration for consumers running in strict mode. The mapper reads the raw
352
+ * schema object and never validates through AJV, so this is purely to stop strict mode
353
+ * rejecting a schema that carries `pg` overrides.
354
+ */
355
+ export const pgKeyword = { keyword: PG_KEYWORD, valid: true };
356
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/utils/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { BasicContext } from '@owlmeans/context';
2
+ import type { TableSpec } from '../types.js';
3
+ /**
4
+ * Fully qualified table of a registered postgres resource; omit the alias for `self`.
5
+ * This is what `PostgresTx.ref` and `PostgresResource.ref` resolve through.
6
+ *
7
+ * @throws {PostgresPlaceholderError}
8
+ */
9
+ export declare const refOf: (context: BasicContext<any>, self: TableSpec | null, alias?: string) => string;
10
+ /**
11
+ * Rewrite `{{...}}` placeholders into quoted identifiers.
12
+ *
13
+ * Identifiers only — `$1`-style parameters are left exactly as written and their values
14
+ * never pass through here. Postgres can't bind an identifier as a parameter, which is the
15
+ * whole reason this mechanism has to exist; values have no such excuse.
16
+ *
17
+ * @throws {PostgresPlaceholderError}
18
+ */
19
+ export declare const resolvePlaceholders: (text: string, context: BasicContext<any>, self: TableSpec | null) => string;
20
+ /** Testing seam — a rebuilt context is a fresh key, but a reused one keeps its entries. */
21
+ export declare const resetPlaceholderCache: () => void;
22
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/utils/sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIrD,OAAO,KAAK,EAAoB,SAAS,EAAE,MAAM,aAAa,CAAA;AA+D9D;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAChB,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,SAAS,GAAG,IAAI,EAAE,QAAQ,MAAM,KACjE,MAAsD,CAAA;AAEzD;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,MAAM,EAAE,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,SAAS,GAAG,IAAI,KAC/D,MAqCF,CAAA;AAED,2FAA2F;AAC3F,eAAO,MAAM,qBAAqB,QAAO,IAAkC,CAAA"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/utils/sql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { PoolClient } from 'pg';
2
+ import type { DdlPlan, TableSpec } from '../types.js';
3
+ /**
4
+ * Serialize initialization across replicas. A session level lock, not `xact`, because
5
+ * migrations run in their own transactions inside the critical section.
6
+ */
7
+ export declare const acquireLock: (client: PoolClient, qualified: string) => Promise<void>;
8
+ export declare const releaseLock: (client: PoolClient, qualified: string) => Promise<void>;
9
+ export declare const ensureSchema: (client: PoolClient, schema: string) => Promise<void>;
10
+ /**
11
+ * Apply a reconciliation plan in a single transaction.
12
+ *
13
+ * Postgres DDL is transactional, so a plan that fails partway leaves the table exactly as
14
+ * it was. That property is what makes converging without confirmation prompts tolerable —
15
+ * the table is either fully converged or untouched, never half migrated.
16
+ *
17
+ * @throws {PostgresCastRequired} Postgres refused an automatic cast.
18
+ * @throws {PostgresSyncError} any other statement failed — the message names the statement.
19
+ */
20
+ export declare const applyPlan: (client: PoolClient, spec: TableSpec, plan: DdlPlan) => Promise<DdlPlan>;
21
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/utils/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAIpC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAiBrD;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAU,QAAQ,UAAU,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAGrF,CAAA;AAED,eAAO,MAAM,WAAW,GAAU,QAAQ,UAAU,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAOrF,CAAA;AAED,eAAO,MAAM,YAAY,GAAU,QAAQ,UAAU,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAMnF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GACpB,QAAQ,UAAU,EAAE,MAAM,SAAS,EAAE,MAAM,OAAO,KACjD,OAAO,CAAC,OAAO,CA8CjB,CAAA"}
@@ -0,0 +1,93 @@
1
+ import { PgErrorCode } from '../consts.js';
2
+ import { PostgresCastRequired, PostgresSyncError, describePgError, pgErrorToResourceError } from '../errors.js';
3
+ import { countNonNull } from './introspect.js';
4
+ import { advisoryKey, quoteIdent } from './name.js';
5
+ /**
6
+ * Codes that mean "the cast is legal, the data isn't": a `text` column holding `'a'` retyped to
7
+ * `integer`, a value too wide for the new length, a number past the new range. Postgres refuses
8
+ * each of these rather than truncating, and the remedy is the same one a refused cast needs — so
9
+ * they are only read as a cast problem here, inside DDL. On the CRUD path the identical code means
10
+ * a caller passed a bad value, which is a different bug with a different fix.
11
+ */
12
+ const CAST_DATA_CODES = [
13
+ PgErrorCode.InvalidTextRepresentation,
14
+ PgErrorCode.StringDataRightTruncation,
15
+ PgErrorCode.NumericValueOutOfRange
16
+ ];
17
+ /**
18
+ * Serialize initialization across replicas. A session level lock, not `xact`, because
19
+ * migrations run in their own transactions inside the critical section.
20
+ */
21
+ export const acquireLock = async (client, qualified) => {
22
+ const [first, second] = advisoryKey(qualified);
23
+ await client.query('SELECT pg_advisory_lock($1, $2)', [first, second]);
24
+ };
25
+ export const releaseLock = async (client, qualified) => {
26
+ const [first, second] = advisoryKey(qualified);
27
+ try {
28
+ await client.query('SELECT pg_advisory_unlock($1, $2)', [first, second]);
29
+ }
30
+ catch {
31
+ /** Releasing the session drops the lock anyway — never mask the original failure. */
32
+ }
33
+ };
34
+ export const ensureSchema = async (client, schema) => {
35
+ try {
36
+ await client.query(`CREATE SCHEMA IF NOT EXISTS ${quoteIdent(schema)}`);
37
+ }
38
+ catch (error) {
39
+ throw pgErrorToResourceError(error);
40
+ }
41
+ };
42
+ /**
43
+ * Apply a reconciliation plan in a single transaction.
44
+ *
45
+ * Postgres DDL is transactional, so a plan that fails partway leaves the table exactly as
46
+ * it was. That property is what makes converging without confirmation prompts tolerable —
47
+ * the table is either fully converged or untouched, never half migrated.
48
+ *
49
+ * @throws {PostgresCastRequired} Postgres refused an automatic cast.
50
+ * @throws {PostgresSyncError} any other statement failed — the message names the statement.
51
+ */
52
+ export const applyPlan = async (client, spec, plan) => {
53
+ if (plan.statements.length < 1) {
54
+ return plan;
55
+ }
56
+ /** Read what a drop would cost before the transaction opens, so the log can say it. */
57
+ for (const statement of plan.statements) {
58
+ if (statement.destructive === true) {
59
+ statement.affected = await countNonNull(client, spec.qualified, statement.target);
60
+ }
61
+ }
62
+ await client.query('BEGIN');
63
+ let current = '';
64
+ try {
65
+ for (const statement of plan.statements) {
66
+ current = statement.sql;
67
+ if (statement.destructive === true && (statement.affected ?? 0) > 0) {
68
+ console.warn(`@owlmeans/postgres-resource: dropping ${spec.qualified}.${statement.target} —`
69
+ + ` ${statement.affected} row(s) hold a value. Declare it under \`pg.unmanaged\``
70
+ + ' or set `pg: { managed: false }` to keep it.');
71
+ }
72
+ await client.query(statement.sql);
73
+ }
74
+ await client.query('COMMIT');
75
+ }
76
+ catch (error) {
77
+ await client.query('ROLLBACK').catch(() => undefined);
78
+ const translated = pgErrorToResourceError(error);
79
+ const code = error?.code;
80
+ if (translated instanceof PostgresCastRequired || (code != null && CAST_DATA_CODES.includes(code))) {
81
+ const failure = new PostgresCastRequired(`${spec.qualified}: ${describePgError(error)} — statement: ${current}.`
82
+ + ' Declare `pg: { using: \'<expr>\' }` on the property, or perform the change in a'
83
+ + ' `pre` migration so reconciliation observes no drift.');
84
+ failure.cause = error;
85
+ throw failure;
86
+ }
87
+ const failure = new PostgresSyncError(`${spec.qualified}: ${describePgError(error)} — statement: ${current}`);
88
+ failure.cause = error;
89
+ throw failure;
90
+ }
91
+ return plan;
92
+ };
93
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/utils/sync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAE/G,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEnD;;;;;;GAMG;AACH,MAAM,eAAe,GAAa;IAChC,WAAW,CAAC,yBAAyB;IACrC,WAAW,CAAC,yBAAyB;IACrC,WAAW,CAAC,sBAAsB;CACnC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,MAAkB,EAAE,SAAiB,EAAiB,EAAE;IACxF,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;IAC9C,MAAM,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AACxE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,MAAkB,EAAE,SAAiB,EAAiB,EAAE;IACxF,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,qFAAqF;IACvF,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,MAAkB,EAAE,MAAc,EAAiB,EAAE;IACtF,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,+BAA+B,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,MAAkB,EAAE,IAAe,EAAE,IAAa,EAChC,EAAE;IACpB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,uFAAuF;IACvF,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,IAAI,SAAS,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YACnC,SAAS,CAAC,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;QACnF,CAAC;IACH,CAAC;IAED,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,CAAC;QACH,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,OAAO,GAAG,SAAS,CAAC,GAAG,CAAA;YACvB,IAAI,SAAS,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpE,OAAO,CAAC,IAAI,CACV,yCAAyC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,IAAI;sBAC7E,IAAI,SAAS,CAAC,QAAQ,yDAAyD;sBAC/E,8CAA8C,CACjD,CAAA;YACH,CAAC;YACD,MAAM,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACnC,CAAC;QACD,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACrD,MAAM,UAAU,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAChD,MAAM,IAAI,GAAI,KAAkC,EAAE,IAAI,CAAA;QACtD,IAAI,UAAU,YAAY,oBAAoB,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACnG,MAAM,OAAO,GAAG,IAAI,oBAAoB,CACtC,GAAG,IAAI,CAAC,SAAS,KAAK,eAAe,CAAC,KAAK,CAAC,iBAAiB,OAAO,GAAG;kBACrE,kFAAkF;kBAClF,uDAAuD,CAC1D,CAAA;YACD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;YACrB,MAAM,OAAO,CAAA;QACf,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,eAAe,CAAC,KAAK,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAA;QAC7G,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACrB,MAAM,OAAO,CAAA;IACf,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { PgRuntimeTable, TableSpec } from '../types.js';
2
+ /**
3
+ * Build the Drizzle table used for CRUD query construction. Structure DDL is emitted from
4
+ * the {@link TableSpec} directly — Drizzle exposes no runtime DDL generator (that lives in
5
+ * drizzle-kit, which would be a second owner of the same tables).
6
+ */
7
+ export declare const specToTable: (spec: TableSpec) => PgRuntimeTable;
8
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAkB5D;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAG,cAgD7C,CAAA"}
@@ -0,0 +1,68 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import { customType, index, pgSchema, primaryKey, uniqueIndex } from 'drizzle-orm/pg-core';
3
+ import { PgIndexMethod } from '../consts.js';
4
+ /**
5
+ * One universal column builder.
6
+ *
7
+ * Drizzle's typed builders (`text()`, `integer()`, ...) exist to drive compile time
8
+ * inference from a statically declared schema. Our tables are compiled at runtime from
9
+ * JSON Schema, so there's nothing to infer and a per-type switch would buy nothing but a
10
+ * mapping to keep in sync. `customType` lets the already-canonical `sqlType` string
11
+ * through verbatim, and `getSQLType()` reads it straight back for the drift cross-check.
12
+ *
13
+ * Marshalling is deliberately identity here — coercion lives in `marshal.ts`, which is
14
+ * driven by the same spec and also serves the raw-SQL path that never touches Drizzle.
15
+ */
16
+ const pgRaw = customType({
17
+ dataType: config => config?.sqlType ?? 'text'
18
+ });
19
+ /**
20
+ * Build the Drizzle table used for CRUD query construction. Structure DDL is emitted from
21
+ * the {@link TableSpec} directly — Drizzle exposes no runtime DDL generator (that lives in
22
+ * drizzle-kit, which would be a second owner of the same tables).
23
+ */
24
+ export const specToTable = (spec) => {
25
+ const namespace = pgSchema(spec.schema);
26
+ const columns = {};
27
+ for (const column of spec.columns) {
28
+ let builder = pgRaw(column.column, { sqlType: column.sqlType });
29
+ if (column.notNull) {
30
+ builder = builder.notNull();
31
+ }
32
+ if (column.defaultRaw != null) {
33
+ builder = builder.default(sql.raw(column.defaultRaw));
34
+ }
35
+ else if (column.defaultLiteral !== undefined) {
36
+ builder = builder.default(column.defaultLiteral);
37
+ }
38
+ /** Composite keys are declared in the extra-config callback instead. */
39
+ if (column.primaryKey && spec.primaryKey.length === 1) {
40
+ builder = builder.primaryKey();
41
+ }
42
+ columns[column.property] = builder;
43
+ }
44
+ return namespace.table(spec.table, columns, (table) => [
45
+ ...spec.indexes
46
+ .filter(entry => entry.columns != null && entry.columns.length > 0 && entry.expression == null)
47
+ .map(entry => {
48
+ const properties = entry.columns
49
+ .map(name => spec.byColumn[name]?.property)
50
+ .filter((name) => name != null && table[name] != null);
51
+ const builder = entry.unique === true ? uniqueIndex(entry.name) : index(entry.name);
52
+ /**
53
+ * Both `using` and `primaryKey` want a non-empty tuple of statically known columns.
54
+ * Nothing here is statically known — the columns were compiled a few lines above —
55
+ * so the tuple shape is asserted rather than proven.
56
+ */
57
+ return builder.using(entry.method ?? PgIndexMethod.BTree, ...properties.map(name => table[name]));
58
+ }),
59
+ ...(spec.primaryKey.length > 1
60
+ ? [primaryKey({
61
+ columns: spec.primaryKey
62
+ .map(name => table[spec.byColumn[name]?.property ?? name])
63
+ .filter((column) => column != null)
64
+ })]
65
+ : [])
66
+ ]);
67
+ };
68
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"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"}