okmodel 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +882 -48
  2. package/dist/contracts/catalog/document.d.ts +6 -2
  3. package/dist/contracts/catalog/enum.d.ts +31 -4
  4. package/dist/contracts/catalog/extension.d.ts +61 -0
  5. package/dist/contracts/catalog/privilege.d.ts +64 -0
  6. package/dist/contracts/catalog/routine.d.ts +56 -0
  7. package/dist/contracts/catalog/types.d.ts +164 -10
  8. package/dist/contracts/catalog/view.d.ts +73 -0
  9. package/dist/dialects/pg/column.d.ts +3 -1
  10. package/dist/dialects/pg/ddl.d.ts +65 -1
  11. package/dist/dialects/pg/enum.d.ts +10 -8
  12. package/dist/dialects/pg/ext/citext.d.ts +14 -0
  13. package/dist/dialects/pg/ext/citext.js +11 -0
  14. package/dist/dialects/pg/ext/index.d.ts +52 -0
  15. package/dist/dialects/pg/ext/index.js +6 -0
  16. package/dist/dialects/pg/ext/pg-trgm.d.ts +53 -0
  17. package/dist/dialects/pg/ext/pg-trgm.js +42 -0
  18. package/dist/dialects/pg/fn/index.d.ts +107 -0
  19. package/dist/dialects/pg/fn/index.js +175 -0
  20. package/dist/dialects/pg/fn/touch.d.ts +14 -0
  21. package/dist/dialects/pg/index.js +104 -19
  22. package/dist/dialects/pg/introspect.d.ts +10 -1
  23. package/dist/dialects/pg/operators.d.ts +8 -1
  24. package/dist/dialects/pg/role/check.d.ts +45 -0
  25. package/dist/dialects/pg/role/index.d.ts +50 -0
  26. package/dist/dialects/pg/role/sql.d.ts +51 -0
  27. package/dist/dialects/pg/table.d.ts +24 -1
  28. package/dist/dialects/pg/tenancy.d.ts +9 -0
  29. package/dist/dialects/pg/view/client.d.ts +30 -0
  30. package/dist/dialects/pg/view/depend.d.ts +35 -0
  31. package/dist/dialects/pg/view/index.d.ts +114 -0
  32. package/dist/dialects/pg/view/index.js +289 -0
  33. package/dist/dialects/pg/view/scratch.d.ts +22 -0
  34. package/dist/dialects/pg/where.d.ts +2 -2
  35. package/dist/runtime/catalog-cache.d.ts +17 -0
  36. package/dist/runtime/compat-words.d.ts +23 -0
  37. package/dist/runtime/drift-detail.d.ts +20 -4
  38. package/dist/runtime/drift.d.ts +4 -2
  39. package/dist/runtime/pg/bun.js +3 -3
  40. package/dist/runtime/pg/pg.js +3 -3
  41. package/dist/runtime/pg/pglite.js +3 -3
  42. package/dist/runtime/pg/postgresjs.js +3 -3
  43. package/dist/runtime/tenancy/index.js +6 -3
  44. package/dist/runtime/traits/index.d.ts +7 -2
  45. package/dist/runtime/traits/index.js +151 -13
  46. package/dist/runtime/types.d.ts +2 -0
  47. package/dist/runtime/validate/index.js +4 -4
  48. package/dist/shared/{xkz8g6by.js → 1g0drakv.js} +2 -2
  49. package/dist/shared/2321avmn.js +418 -0
  50. package/dist/shared/{7mht49yd.js → 3p4b1fg0.js} +57 -18
  51. package/dist/shared/41kv2xdm.js +318 -0
  52. package/dist/shared/{97g2jnrw.js → 4ef7mmqf.js} +3 -3
  53. package/dist/shared/{sacqha1y.js → 4m9fn52z.js} +2 -2
  54. package/dist/shared/5mtf6cj3.js +94 -0
  55. package/dist/shared/{1dp5knt7.js → 5vdm4sgp.js} +2 -2
  56. package/dist/shared/{a1gdp7j9.js → 6693j9rs.js} +1 -1
  57. package/dist/shared/{38crxbgn.js → 6p5k20sm.js} +3 -3
  58. package/dist/shared/7nk68fj8.js +751 -0
  59. package/dist/shared/84ptn35q.js +71 -0
  60. package/dist/shared/{d2whjz4k.js → 8jb4ymh2.js} +581 -28
  61. package/dist/shared/8ktwd3rh.js +97 -0
  62. package/dist/shared/94ez8kzh.js +19 -0
  63. package/dist/shared/{3a5ne750.js → 9m80mkac.js} +2 -2
  64. package/dist/shared/9x25fxhc.js +150 -0
  65. package/dist/shared/9yn6a2vd.js +11 -0
  66. package/dist/shared/ady1ms74.js +72 -0
  67. package/dist/shared/{4jzzghr6.js → awrsqrn7.js} +6 -6
  68. package/dist/shared/{4b9da9d7.js → axhk06q1.js} +19 -1
  69. package/dist/shared/{d04j53v8.js → c5g81ngb.js} +82 -14
  70. package/dist/shared/{n47rd821.js → c8aghh05.js} +1 -1
  71. package/dist/shared/{dd4f8mnx.js → c9z5g0fm.js} +4 -2
  72. package/dist/shared/{ps43134h.js → dyj86cmj.js} +4 -4
  73. package/dist/shared/{0qkxbm1f.js → fa9vt245.js} +1 -1
  74. package/dist/shared/{qa5dsc7z.js → fb00y8fp.js} +3 -3
  75. package/dist/shared/{qxa0yb9j.js → g7ez901n.js} +30 -1
  76. package/dist/shared/{py3nh7jy.js → gdh9mrtp.js} +2 -2
  77. package/dist/shared/{yw5c610b.js → gjthds9j.js} +2 -2
  78. package/dist/shared/hcmdtwgh.js +102 -0
  79. package/dist/shared/hqjsxnz7.js +13 -0
  80. package/dist/shared/htnaj77v.js +17 -0
  81. package/dist/shared/{v18jva5b.js → jgxzjzcz.js} +1 -1
  82. package/dist/shared/{x9v1qgeb.js → jsd07prz.js} +3 -3
  83. package/dist/shared/{g9f0zqce.js → kafaa5zv.js} +1 -1
  84. package/dist/shared/kj680nxv.js +19 -0
  85. package/dist/shared/{mxmcdsh5.js → kkzwp3d2.js} +9 -9
  86. package/dist/shared/{g1b5zzj9.js → n0dgs0pb.js} +1 -1
  87. package/dist/shared/n5y9zyj1.js +2431 -0
  88. package/dist/shared/{zt8y0wzb.js → n7mcc1gk.js} +1 -1
  89. package/dist/shared/{ge03bfca.js → nxb42q7h.js} +2 -2
  90. package/dist/shared/q6zsyh31.js +2192 -0
  91. package/dist/shared/{sfh4pk75.js → q795afwa.js} +26 -21
  92. package/dist/shared/{10tjenmd.js → qn0srwwq.js} +1 -1
  93. package/dist/shared/s4mb6a4b.js +545 -0
  94. package/dist/shared/{ytg3xf9p.js → sf8m6tfy.js} +3 -3
  95. package/dist/shared/{zd93g3rq.js → sr5ms7b3.js} +1 -1
  96. package/dist/shared/{xatfg0gn.js → tmbdywx0.js} +4 -19
  97. package/dist/shared/tny2t3sm.js +100 -0
  98. package/dist/shared/{e7a268fy.js → v7tpnhnz.js} +1 -1
  99. package/dist/shared/{ecdzej21.js → wqem4jed.js} +7 -7
  100. package/dist/shared/xghkt7a9.js +1144 -0
  101. package/dist/shared/y005b761.js +112 -0
  102. package/dist/shared/ycatkxmq.js +84 -0
  103. package/dist/shared/ygem90rn.js +900 -0
  104. package/dist/shared/{eaxwrgby.js → yjw02enp.js} +6 -3
  105. package/dist/shared/{mrq77sgw.js → zg24x0hm.js} +1 -1
  106. package/dist/shared/{cstgkzdx.js → zvbjc949.js} +1 -1
  107. package/dist/tooling/cli.js +66 -13
  108. package/dist/tooling/migrate/apply.d.ts +75 -5
  109. package/dist/tooling/migrate/backfill.d.ts +136 -0
  110. package/dist/tooling/migrate/check.d.ts +65 -0
  111. package/dist/tooling/migrate/classify.d.ts +108 -0
  112. package/dist/tooling/migrate/commands.d.ts +2 -1
  113. package/dist/tooling/migrate/config.d.ts +30 -0
  114. package/dist/tooling/migrate/doctor.d.ts +28 -0
  115. package/dist/tooling/migrate/drift.d.ts +35 -0
  116. package/dist/tooling/migrate/estimate.d.ts +50 -0
  117. package/dist/tooling/migrate/ext.d.ts +17 -0
  118. package/dist/tooling/migrate/extensions.d.ts +53 -0
  119. package/dist/tooling/migrate/files.d.ts +12 -0
  120. package/dist/tooling/migrate/index.d.ts +3 -2
  121. package/dist/tooling/migrate/index.js +67 -1
  122. package/dist/tooling/migrate/lint-rules.d.ts +51 -0
  123. package/dist/tooling/migrate/lint.d.ts +71 -0
  124. package/dist/tooling/migrate/managed.d.ts +17 -0
  125. package/dist/tooling/migrate/plan.d.ts +78 -10
  126. package/dist/tooling/migrate/project.d.ts +64 -5
  127. package/dist/tooling/migrate/provision.d.ts +18 -0
  128. package/dist/tooling/migrate/reference.d.ts +40 -0
  129. package/dist/tooling/migrate/runner.d.ts +108 -0
  130. package/dist/tooling/migrate/safe.d.ts +77 -0
  131. package/dist/tooling/migrate/seed.d.ts +20 -0
  132. package/dist/tooling/migrate/snapshot.d.ts +78 -0
  133. package/dist/tooling/migrate/status.d.ts +25 -6
  134. package/dist/tooling/migrate/type-name.d.ts +19 -0
  135. package/dist/tooling/testing/factories.d.ts +117 -0
  136. package/dist/tooling/testing/facts.d.ts +72 -0
  137. package/dist/tooling/testing/index.d.ts +89 -0
  138. package/dist/tooling/testing/index.js +8 -0
  139. package/dist/tooling/testing/isolation.d.ts +30 -0
  140. package/dist/tooling/testing/random.d.ts +40 -0
  141. package/dist/tooling/testing/record.d.ts +38 -0
  142. package/package.json +26 -2
  143. package/dist/shared/5z4q2zda.js +0 -2073
  144. package/dist/shared/eqmtn1bj.js +0 -399
  145. package/dist/shared/rtnaqre0.js +0 -37
  146. package/dist/shared/zwmqxb0g.js +0 -79
  147. package/dist/shared/{m9tv7xn7.js → radd3z4g.js} +3 -3
  148. /package/dist/shared/{9k6vetvf.js → rrstp3kb.js} +0 -0
@@ -1,8 +1,22 @@
1
+ import {
2
+ functionObject,
3
+ triggerObject
4
+ } from "./9x25fxhc.js";
5
+ import {
6
+ viewObject,
7
+ materializedViewObject,
8
+ materializedViewIndex
9
+ } from "./y005b761.js";
10
+ import {
11
+ extensionObject
12
+ } from "./8ktwd3rh.js";
1
13
  import {
2
14
  dependencyOrder,
3
15
  catalog,
4
- enumType
5
- } from "./qxa0yb9j.js";
16
+ enumType,
17
+ domainType,
18
+ isDomain
19
+ } from "./g7ez901n.js";
6
20
  import {
7
21
  canonicalJson,
8
22
  staticNamespace2,
@@ -18,7 +32,9 @@ import {
18
32
  index3,
19
33
  constraint2,
20
34
  sequence2,
21
- compareText
35
+ normaliseEdges,
36
+ compareText,
37
+ assertProvenance
22
38
  } from "./t4tbsy9h.js";
23
39
  import {
24
40
  OWNERS2,
@@ -27,7 +43,9 @@ import {
27
43
  CATALOG_VERSION2
28
44
  } from "./4e4c6vq2.js";
29
45
  import {
30
- sha2562
46
+ sha2562,
47
+ assertIdentifier2,
48
+ fitIdentifier2
31
49
  } from "./nfzc5z0w.js";
32
50
  import {
33
51
  catalogError2
@@ -89,6 +107,60 @@ function isIdentPart(char) {
89
107
  return isIdentStart(char) || char >= "0" && char <= "9";
90
108
  }
91
109
 
110
+ // src/contracts/catalog/privilege.ts
111
+ function roleObject(input) {
112
+ assertIdentifier2(input.name, "role");
113
+ assertProvenance(input.provenance);
114
+ return {
115
+ kind: "role",
116
+ identity: { kind: "role", name: input.name },
117
+ owner: input.owner ?? "managed",
118
+ definition: {
119
+ login: input.login === true,
120
+ inherit: input.inherit !== false
121
+ },
122
+ dependencies: normaliseEdges(input.dependencies ?? []),
123
+ provenance: input.provenance
124
+ };
125
+ }
126
+ function grantObject(input) {
127
+ assertIdentifier2(input.role, "role");
128
+ assertProvenance(input.provenance);
129
+ return {
130
+ kind: "grant",
131
+ identity: {
132
+ kind: "grant",
133
+ role: input.role,
134
+ object: input.object,
135
+ privilege: input.privilege
136
+ },
137
+ owner: input.owner ?? "managed",
138
+ definition: {},
139
+ dependencies: normaliseEdges(input.dependencies ?? []),
140
+ provenance: input.provenance
141
+ };
142
+ }
143
+ function defaultPrivilegeObject(input) {
144
+ assertIdentifier2(input.forRole, "role");
145
+ assertIdentifier2(input.grantee, "role");
146
+ assertProvenance(input.provenance);
147
+ return {
148
+ kind: "defaultPrivilege",
149
+ identity: {
150
+ kind: "defaultPrivilege",
151
+ forRole: input.forRole,
152
+ namespace: input.namespace,
153
+ objectKind: input.objectKind,
154
+ grantee: input.grantee,
155
+ privilege: input.privilege
156
+ },
157
+ owner: input.owner ?? "managed",
158
+ definition: {},
159
+ dependencies: normaliseEdges(input.dependencies ?? []),
160
+ provenance: input.provenance
161
+ };
162
+ }
163
+
92
164
  // src/contracts/catalog/document.ts
93
165
  function creationOrder2(source) {
94
166
  return dependencyOrder(source.objects);
@@ -128,7 +200,7 @@ function renameTable2(source, change) {
128
200
  if (!found) {
129
201
  catalogError2("OKM1020", `Table ${change.from} is not in the catalog.`);
130
202
  }
131
- const next = source.objects.map((object) => rewriteTableName(object, change, fromKey, toIdentity));
203
+ const next = source.objects.map((object) => rewriteTableName(object, change, fromKey, toIdentity, source));
132
204
  return catalog(next);
133
205
  }
134
206
  var serializedText = new WeakMap;
@@ -219,10 +291,60 @@ function rewriteRenamed(object, change, fromKey, toIdentity) {
219
291
  return rewriteSequence(object, dependencies);
220
292
  case "type":
221
293
  return rewriteType(object, dependencies);
294
+ case "extension":
295
+ return retargeted(object, dependencies);
296
+ case "function": {
297
+ const local = object.dependencies.some((edge) => edge.target.kind === "column" && sameRef2(edge.target.parent, change.parent));
298
+ return functionObject({
299
+ namespace: object.identity.namespace,
300
+ name: object.identity.name,
301
+ arguments: object.definition.arguments,
302
+ returns: object.definition.returns,
303
+ language: object.definition.language,
304
+ volatility: object.definition.volatility,
305
+ security: object.definition.security,
306
+ body: rewriteExpr(object.definition.body, change, local),
307
+ owner: object.owner,
308
+ provenance: object.provenance,
309
+ dependencies,
310
+ ...object.definition.searchPath !== undefined ? { searchPath: object.definition.searchPath } : {},
311
+ ...object.definition.atomic === true ? { atomic: true } : {}
312
+ });
313
+ }
314
+ case "view":
315
+ case "materializedView": {
316
+ const local = object.dependencies.some((edge) => edge.target.kind === "column" && sameRef2(edge.target.parent, change.parent));
317
+ return rewriteView(object, dependencies, rewriteExpr(object.definition.query, change, local));
318
+ }
319
+ case "role":
320
+ case "grant":
321
+ case "defaultPrivilege":
322
+ return retargeted(object, dependencies);
323
+ case "trigger": {
324
+ const local = sameRef2(object.identity.parent, change.parent);
325
+ return triggerObject({
326
+ parent: object.identity.parent,
327
+ name: object.identity.name,
328
+ timing: object.definition.timing,
329
+ events: object.definition.events,
330
+ level: object.definition.level,
331
+ calls: object.definition.calls,
332
+ owner: object.owner,
333
+ provenance: object.provenance,
334
+ dependencies,
335
+ ...object.definition.updateOf !== undefined ? {
336
+ updateOf: local ? renameList(object.definition.updateOf, change.from, change.to) : object.definition.updateOf
337
+ } : {},
338
+ ...object.definition.when !== undefined ? { when: rewriteExpr(object.definition.when, change, local) } : {}
339
+ });
340
+ }
222
341
  default:
223
342
  return assertNever(object);
224
343
  }
225
344
  }
345
+ function retargeted(object, dependencies) {
346
+ return { ...object, dependencies: dependencies.map((target) => ({ target })) };
347
+ }
226
348
  function rewriteTable(object, change, dependencies) {
227
349
  const partition = object.definition.partition;
228
350
  const renamed = partition !== undefined && object.identity.name === change.parent.name && sameNamespace2(object.identity.namespace, change.parent.namespace);
@@ -266,17 +388,39 @@ function rewriteColumn(object, change, dependencies) {
266
388
  function rewriteIndex(object, change, dependencies) {
267
389
  const local = sameRef2(object.identity.parent, change.parent);
268
390
  const definition = object.definition;
391
+ return indexAgain(object, object.identity.parent, dependencies, {
392
+ columns: local ? renameList(definition.columns, change.from, change.to) : [...definition.columns],
393
+ ...definition.predicate !== undefined ? { predicate: rewriteExpr(definition.predicate, change, local) } : {},
394
+ ...definition.expression !== undefined ? { expression: rewriteExpr(definition.expression, change, local) } : {}
395
+ });
396
+ }
397
+ function indexAgain(object, parent, dependencies, patch) {
398
+ const onView = dependencies.some((edge) => edge.kind === "view" || edge.kind === "materializedView");
399
+ if (onView) {
400
+ return materializedViewIndex({
401
+ parent,
402
+ name: object.identity.name,
403
+ nameKey: object.definition.nameKey,
404
+ columns: patch.columns,
405
+ unique: object.definition.unique,
406
+ owner: object.owner,
407
+ provenance: object.provenance,
408
+ dependencies,
409
+ ...patch.predicate !== undefined ? { predicate: patch.predicate } : {},
410
+ ...patch.expression !== undefined ? { expression: patch.expression } : {}
411
+ });
412
+ }
269
413
  return index3({
270
- parent: object.identity.parent,
414
+ parent,
271
415
  name: object.identity.name,
272
- nameKey: definition.nameKey,
273
- columns: local ? renameList(definition.columns, change.from, change.to) : [...definition.columns],
274
- unique: definition.unique,
416
+ nameKey: object.definition.nameKey,
417
+ columns: patch.columns,
418
+ unique: object.definition.unique,
275
419
  owner: object.owner,
276
420
  provenance: object.provenance,
277
421
  dependencies,
278
- ...definition.predicate !== undefined ? { predicate: rewriteExpr(definition.predicate, change, local) } : {},
279
- ...definition.expression !== undefined ? { expression: rewriteExpr(definition.expression, change, local) } : {}
422
+ ...patch.predicate !== undefined ? { predicate: patch.predicate } : {},
423
+ ...patch.expression !== undefined ? { expression: patch.expression } : {}
280
424
  });
281
425
  }
282
426
  function rewriteConstraint(object, change, dependencies) {
@@ -305,13 +449,31 @@ function rewriteConstraint(object, change, dependencies) {
305
449
  ...referenced !== undefined ? { references: referenced } : {}
306
450
  });
307
451
  }
452
+ function rewriteView(object, dependencies, query) {
453
+ const input = {
454
+ namespace: object.identity.namespace,
455
+ name: object.identity.name,
456
+ columns: object.definition.columns,
457
+ query,
458
+ owner: object.owner,
459
+ provenance: object.provenance,
460
+ dependencies
461
+ };
462
+ if (object.kind === "materializedView") {
463
+ return materializedViewObject({
464
+ ...input,
465
+ ...object.definition.refresh !== undefined ? { refresh: object.definition.refresh } : {}
466
+ });
467
+ }
468
+ return viewObject(input);
469
+ }
308
470
  function rewriteExpr(text, change, active) {
309
471
  if (!active)
310
472
  return text;
311
473
  return replaceIdentifier(text, change.from, change.to);
312
474
  }
313
- function rewriteTableName(object, change, fromKey, toIdentity) {
314
- const dependencies = retarget(object.dependencies, fromKey, toIdentity);
475
+ function rewriteTableName(object, change, fromKey, toIdentity, source) {
476
+ const dependencies = retarget(object.dependencies, fromKey, toIdentity, change);
315
477
  const named = object.kind === "table" && object.identity.name === change.from && sameNamespace2(object.identity.namespace, change.namespace);
316
478
  if (object.kind === "table") {
317
479
  return table3({
@@ -344,15 +506,8 @@ function rewriteTableName(object, change, fromKey, toIdentity) {
344
506
  });
345
507
  }
346
508
  if (object.kind === "index") {
347
- return index3({
348
- parent,
349
- name: object.identity.name,
350
- nameKey: object.definition.nameKey,
509
+ return indexAgain(object, parent, dependencies, {
351
510
  columns: [...object.definition.columns],
352
- unique: object.definition.unique,
353
- owner: object.owner,
354
- provenance: object.provenance,
355
- dependencies,
356
511
  ...object.definition.predicate !== undefined ? {
357
512
  predicate: rewriteExpr(object.definition.predicate, { from: change.from, to: change.to }, local)
358
513
  } : {},
@@ -390,6 +545,69 @@ function rewriteTableName(object, change, fromKey, toIdentity) {
390
545
  return rewriteSequence(object, dependencies);
391
546
  if (object.kind === "type")
392
547
  return rewriteType(object, dependencies);
548
+ if (object.kind === "extension") {
549
+ return { ...object, dependencies: dependencies.map((target) => ({ target })) };
550
+ }
551
+ if (object.kind === "function") {
552
+ const local = object.dependencies.some((edge) => edge.target.kind === "table" && edge.target.name === change.from && sameNamespace2(edge.target.namespace, change.namespace));
553
+ return functionObject({
554
+ namespace: object.identity.namespace,
555
+ name: object.identity.name,
556
+ arguments: object.definition.arguments,
557
+ returns: object.definition.returns,
558
+ language: object.definition.language,
559
+ volatility: object.definition.volatility,
560
+ security: object.definition.security,
561
+ body: rewriteExpr(object.definition.body, { from: change.from, to: change.to }, local),
562
+ owner: object.owner,
563
+ provenance: object.provenance,
564
+ dependencies,
565
+ ...object.definition.searchPath !== undefined ? { searchPath: object.definition.searchPath } : {},
566
+ ...object.definition.atomic === true ? { atomic: true } : {}
567
+ });
568
+ }
569
+ if (object.kind === "view" || object.kind === "materializedView") {
570
+ const local = object.dependencies.some((edge) => {
571
+ if (edge.target.kind === "table") {
572
+ return edge.target.name === change.from && sameNamespace2(edge.target.namespace, change.namespace);
573
+ }
574
+ if (edge.target.kind === "column") {
575
+ return edge.target.parent.name === change.from && sameNamespace2(edge.target.parent.namespace, change.namespace);
576
+ }
577
+ return false;
578
+ });
579
+ return rewriteView(object, dependencies, rewriteExpr(object.definition.query, { from: change.from, to: change.to }, local));
580
+ }
581
+ if (object.kind === "role" || object.kind === "defaultPrivilege") {
582
+ return retargeted(object, dependencies);
583
+ }
584
+ if (object.kind === "grant") {
585
+ return grantObject({
586
+ role: object.identity.role,
587
+ object: movedGrantRef(object.identity.object, change, source),
588
+ privilege: object.identity.privilege,
589
+ owner: object.owner,
590
+ provenance: object.provenance,
591
+ dependencies
592
+ });
593
+ }
594
+ if (object.kind === "trigger") {
595
+ const parent = movedParent(object.identity.parent, change);
596
+ const local = parent.name !== object.identity.parent.name;
597
+ return triggerObject({
598
+ parent,
599
+ name: object.identity.name,
600
+ timing: object.definition.timing,
601
+ events: object.definition.events,
602
+ level: object.definition.level,
603
+ calls: object.definition.calls,
604
+ owner: object.owner,
605
+ provenance: object.provenance,
606
+ dependencies,
607
+ ...object.definition.updateOf !== undefined ? { updateOf: object.definition.updateOf } : {},
608
+ ...object.definition.when !== undefined ? { when: rewriteExpr(object.definition.when, { from: change.from, to: change.to }, local) } : {}
609
+ });
610
+ }
393
611
  return assertNever(object);
394
612
  }
395
613
  function movedParent(parent, change) {
@@ -399,6 +617,17 @@ function movedParent(parent, change) {
399
617
  return parent;
400
618
  }
401
619
  function rewriteType(object, dependencies) {
620
+ if (isDomain(object.definition)) {
621
+ return domainType({
622
+ namespace: object.identity.namespace,
623
+ name: object.identity.name,
624
+ base: object.definition.base,
625
+ check: object.definition.check,
626
+ owner: object.owner,
627
+ provenance: object.provenance,
628
+ dependencies
629
+ });
630
+ }
402
631
  return enumType({
403
632
  namespace: object.identity.namespace,
404
633
  name: object.identity.name,
@@ -424,8 +653,46 @@ function rewriteSequence(object, dependencies) {
424
653
  function renameList(names, from, to) {
425
654
  return names.map((name) => name === from ? to : name);
426
655
  }
427
- function retarget(edges, fromKey, to) {
428
- return edges.map((edge) => identityKey2(edge.target) === fromKey ? to : edge.target);
656
+ function retarget(edges, fromKey, to, change) {
657
+ return edges.map((edge) => {
658
+ if (identityKey2(edge.target) === fromKey)
659
+ return to;
660
+ if (change === undefined)
661
+ return edge.target;
662
+ return movedChild(edge.target, change);
663
+ });
664
+ }
665
+ function movedChild(target, change) {
666
+ if (!("parent" in target))
667
+ return target;
668
+ if (target.parent.name !== change.from || !sameNamespace2(target.parent.namespace, change.namespace)) {
669
+ return target;
670
+ }
671
+ return { ...target, parent: { namespace: target.parent.namespace, name: change.to } };
672
+ }
673
+ function movedGrantRef(object, change, source) {
674
+ if (object.kind === "table" && object.name === change.from && sameNamespace2(object.namespace, change.namespace)) {
675
+ return { ...object, name: change.to };
676
+ }
677
+ if (object.kind !== "sequence")
678
+ return object;
679
+ const next = renamedIdentitySequence(source, change, object.name);
680
+ if (next === undefined)
681
+ return object;
682
+ return { ...object, name: next };
683
+ }
684
+ function renamedIdentitySequence(source, change, sequenceName) {
685
+ for (const object of source.objects) {
686
+ if (object.kind !== "column" || object.definition.identity === undefined)
687
+ continue;
688
+ if (object.identity.parent.name !== change.from || !sameNamespace2(object.identity.parent.namespace, change.namespace)) {
689
+ continue;
690
+ }
691
+ if (fitIdentifier2(`${change.from}_${object.identity.name}_seq`) !== sequenceName)
692
+ continue;
693
+ return fitIdentifier2(`${change.to}_${object.identity.name}_seq`);
694
+ }
695
+ return;
429
696
  }
430
697
  function dependencyJson(edges) {
431
698
  const indexed = edges.map((edge) => ({
@@ -513,7 +780,68 @@ function definitionToJson(object) {
513
780
  start: object.definition.start
514
781
  };
515
782
  case "type":
516
- return { labels: object.definition.labels };
783
+ return isDomain(object.definition) ? { base: object.definition.base, check: object.definition.check } : { labels: object.definition.labels };
784
+ case "extension": {
785
+ const definition = object.definition;
786
+ return {
787
+ relocatable: definition.relocatable,
788
+ schema: definition.schema,
789
+ ...definition.version !== undefined ? { version: definition.version } : {}
790
+ };
791
+ }
792
+ case "function": {
793
+ const definition = object.definition;
794
+ return {
795
+ arguments: definition.arguments.map((argument) => ({
796
+ name: argument.name,
797
+ type: argument.type
798
+ })),
799
+ body: definition.body,
800
+ language: definition.language,
801
+ returns: definition.returns,
802
+ security: definition.security,
803
+ volatility: definition.volatility,
804
+ ...definition.atomic === true ? { atomic: true } : {},
805
+ ...definition.searchPath !== undefined ? { searchPath: definition.searchPath } : {}
806
+ };
807
+ }
808
+ case "trigger": {
809
+ const definition = object.definition;
810
+ return {
811
+ calls: {
812
+ argTypes: [...definition.calls.argTypes],
813
+ name: definition.calls.name,
814
+ namespace: namespaceToJson(definition.calls.namespace)
815
+ },
816
+ events: [...definition.events],
817
+ level: definition.level,
818
+ timing: definition.timing,
819
+ ...definition.updateOf !== undefined ? { updateOf: [...definition.updateOf] } : {},
820
+ ...definition.when !== undefined ? { when: definition.when } : {}
821
+ };
822
+ }
823
+ case "view":
824
+ return {
825
+ columns: object.definition.columns.map((column) => ({
826
+ dataType: column.dataType,
827
+ name: column.name
828
+ })),
829
+ query: object.definition.query
830
+ };
831
+ case "materializedView":
832
+ return {
833
+ columns: object.definition.columns.map((column) => ({
834
+ dataType: column.dataType,
835
+ name: column.name
836
+ })),
837
+ query: object.definition.query,
838
+ ...object.definition.refresh !== undefined ? { refresh: object.definition.refresh } : {}
839
+ };
840
+ case "role":
841
+ return { inherit: object.definition.inherit, login: object.definition.login };
842
+ case "grant":
843
+ case "defaultPrivilege":
844
+ return {};
517
845
  default:
518
846
  return assertNever(object);
519
847
  }
@@ -546,6 +874,21 @@ function parseObject(value) {
546
874
  return parseSequence(identity, definition, owner, provenance, dependencies);
547
875
  case "type":
548
876
  return parseType(identity, definition, owner, provenance, dependencies);
877
+ case "extension":
878
+ return parseExtension(identity, definition, owner, provenance, dependencies);
879
+ case "function":
880
+ return parseFunction(identity, definition, owner, provenance, dependencies);
881
+ case "trigger":
882
+ return parseTrigger(identity, definition, owner, provenance, dependencies);
883
+ case "view":
884
+ case "materializedView":
885
+ return parseView(kind, identity, definition, owner, provenance, dependencies);
886
+ case "role":
887
+ return parseRole(identity, definition, owner, provenance, dependencies);
888
+ case "grant":
889
+ return parseGrant(identity, definition, owner, provenance, dependencies);
890
+ case "defaultPrivilege":
891
+ return parseDefaultPrivilege(identity, definition, owner, provenance, dependencies);
549
892
  default:
550
893
  return assertNeverKind(kind);
551
894
  }
@@ -668,6 +1011,18 @@ function parseType(identity, definition, owner, provenance, dependencies) {
668
1011
  if (identity.kind !== "type") {
669
1012
  catalogError2("OKM1020", `Type object identity is ${identity.kind}, not a type.`);
670
1013
  }
1014
+ if ("base" in definition || "check" in definition) {
1015
+ rejectUnknown(definition, ["base", "check"], "type definition");
1016
+ return domainType({
1017
+ namespace: identity.namespace,
1018
+ name: identity.name,
1019
+ base: requireString(definition.base, "domain base"),
1020
+ check: requireString(definition.check, "domain check"),
1021
+ owner,
1022
+ provenance,
1023
+ dependencies
1024
+ });
1025
+ }
671
1026
  rejectUnknown(definition, ["labels"], "type definition");
672
1027
  return enumType({
673
1028
  namespace: identity.namespace,
@@ -678,6 +1033,160 @@ function parseType(identity, definition, owner, provenance, dependencies) {
678
1033
  dependencies
679
1034
  });
680
1035
  }
1036
+ function parseFunction(identity, definition, owner, provenance, dependencies) {
1037
+ if (identity.kind !== "function") {
1038
+ catalogError2("OKM1020", `Function object identity is ${identity.kind}, not a function.`);
1039
+ }
1040
+ rejectUnknown(definition, ["arguments", "atomic", "body", "language", "returns", "searchPath", "security", "volatility"], "function definition");
1041
+ const language = requireString(definition.language, "function language");
1042
+ if (language !== "sql" && language !== "plpgsql") {
1043
+ catalogError2("OKM1020", `Function ${identity.name} language must be sql or plpgsql.`);
1044
+ }
1045
+ const volatility = parseVolatility(definition.volatility);
1046
+ const security = parseSecurity(definition.security);
1047
+ return functionObject({
1048
+ namespace: identity.namespace,
1049
+ name: identity.name,
1050
+ arguments: parseArguments(definition.arguments),
1051
+ returns: requireString(definition.returns, "function returns"),
1052
+ language,
1053
+ body: requireString(definition.body, "function body"),
1054
+ owner,
1055
+ provenance,
1056
+ dependencies,
1057
+ ...volatility !== undefined ? { volatility } : {},
1058
+ ...security !== undefined ? { security } : {},
1059
+ ...definition.atomic === true ? { atomic: true } : {},
1060
+ ...definition.searchPath !== undefined ? { searchPath: requireString(definition.searchPath, "search path") } : {}
1061
+ });
1062
+ }
1063
+ function parseArguments(value) {
1064
+ if (value === undefined)
1065
+ return [];
1066
+ if (!Array.isArray(value))
1067
+ catalogError2("OKM1020", "Function arguments must be an array.");
1068
+ return value.map((item) => {
1069
+ const record = requireRecord(item, "function argument");
1070
+ rejectUnknown(record, ["name", "type"], "function argument");
1071
+ return {
1072
+ name: requireString(record.name, "argument name"),
1073
+ type: requireString(record.type, "argument type")
1074
+ };
1075
+ });
1076
+ }
1077
+ function parseVolatility(value) {
1078
+ if (value === undefined)
1079
+ return;
1080
+ const text = requireString(value, "volatility");
1081
+ if (text !== "volatile" && text !== "stable" && text !== "immutable") {
1082
+ catalogError2("OKM1020", `Volatility ${text} is not supported.`);
1083
+ }
1084
+ return text;
1085
+ }
1086
+ function parseSecurity(value) {
1087
+ if (value === undefined)
1088
+ return;
1089
+ const text = requireString(value, "security");
1090
+ if (text !== "invoker" && text !== "definer") {
1091
+ catalogError2("OKM1020", `Security ${text} is not supported.`);
1092
+ }
1093
+ return text;
1094
+ }
1095
+ function parseTrigger(identity, definition, owner, provenance, dependencies) {
1096
+ if (identity.kind !== "trigger") {
1097
+ catalogError2("OKM1020", `Trigger object identity is ${identity.kind}, not a trigger.`);
1098
+ }
1099
+ rejectUnknown(definition, ["calls", "events", "level", "timing", "updateOf", "when"], "trigger definition");
1100
+ const timing = requireString(definition.timing, "trigger timing");
1101
+ if (timing !== "before" && timing !== "after" && timing !== "instead") {
1102
+ catalogError2("OKM1020", `Trigger timing ${timing} is not supported.`);
1103
+ }
1104
+ const level = requireString(definition.level, "trigger level");
1105
+ if (level !== "row" && level !== "statement") {
1106
+ catalogError2("OKM1020", `Trigger level ${level} is not supported.`);
1107
+ }
1108
+ const calls = requireRecord(definition.calls, "trigger call");
1109
+ rejectUnknown(calls, ["argTypes", "name", "namespace"], "trigger call");
1110
+ return triggerObject({
1111
+ parent: identity.parent,
1112
+ name: identity.name,
1113
+ timing,
1114
+ events: requireStrings(definition.events, "trigger events").map(parseEvent),
1115
+ level,
1116
+ calls: {
1117
+ namespace: parseNamespace(calls.namespace),
1118
+ name: requireString(calls.name, "trigger function"),
1119
+ argTypes: requireStrings(calls.argTypes, "trigger argument types")
1120
+ },
1121
+ owner,
1122
+ provenance,
1123
+ dependencies,
1124
+ ...definition.updateOf !== undefined ? { updateOf: requireStrings(definition.updateOf, "update of") } : {},
1125
+ ...definition.when !== undefined ? { when: requireString(definition.when, "when") } : {}
1126
+ });
1127
+ }
1128
+ function parseView(kind, identity, definition, owner, provenance, dependencies) {
1129
+ if (identity.kind !== kind) {
1130
+ catalogError2("OKM1020", `View object identity is ${identity.kind}, not a ${kind}.`);
1131
+ }
1132
+ const fields = kind === "view" ? ["columns", "query"] : ["columns", "query", "refresh"];
1133
+ rejectUnknown(definition, fields, "view definition");
1134
+ const columns = parseViewColumns(definition.columns);
1135
+ const query = requireString(definition.query, "view query");
1136
+ const refresh = definition.refresh;
1137
+ if (refresh !== undefined && refresh !== "concurrently") {
1138
+ catalogError2("OKM1020", `Materialized view ${identity.name} refresh is not supported.`);
1139
+ }
1140
+ const input = {
1141
+ namespace: identity.namespace,
1142
+ name: identity.name,
1143
+ columns,
1144
+ query,
1145
+ owner,
1146
+ provenance,
1147
+ dependencies
1148
+ };
1149
+ if (kind === "materializedView") {
1150
+ return materializedViewObject({
1151
+ ...input,
1152
+ ...refresh === "concurrently" ? { refresh: "concurrently" } : {}
1153
+ });
1154
+ }
1155
+ return viewObject(input);
1156
+ }
1157
+ function parseViewColumns(value) {
1158
+ if (!Array.isArray(value))
1159
+ catalogError2("OKM1020", "View columns must be a list.");
1160
+ return value.map((item) => {
1161
+ const record = requireRecord(item, "view column");
1162
+ rejectUnknown(record, ["dataType", "name"], "view column");
1163
+ return {
1164
+ name: requireString(record.name, "view column"),
1165
+ dataType: requireString(record.dataType, "view column type")
1166
+ };
1167
+ });
1168
+ }
1169
+ function parseEvent(value) {
1170
+ if (value !== "insert" && value !== "update" && value !== "delete" && value !== "truncate") {
1171
+ catalogError2("OKM1020", `Trigger event ${value} is not supported.`);
1172
+ }
1173
+ return value;
1174
+ }
1175
+ function parseExtension(identity, definition, owner, provenance, dependencies) {
1176
+ if (identity.kind !== "extension") {
1177
+ catalogError2("OKM1020", `Extension object identity is ${identity.kind}, not an extension.`);
1178
+ }
1179
+ rejectUnknown(definition, ["relocatable", "schema", "version"], "extension definition");
1180
+ return extensionObject({
1181
+ name: identity.name,
1182
+ schema: requireString(definition.schema, "extension schema"),
1183
+ relocatable: requireBoolean(definition.relocatable, "relocatable"),
1184
+ ...definition.version !== undefined ? { version: requireString(definition.version, "extension version") } : {},
1185
+ owner,
1186
+ provenance,
1187
+ dependencies
1188
+ });
1189
+ }
681
1190
  function parseIdentity(value) {
682
1191
  const record = requireRecord(value, "identity");
683
1192
  const kind = requireString(record.kind, "identity kind");
@@ -763,8 +1272,8 @@ function parseGrantObject(value) {
763
1272
  const record = requireRecord(value, "grant object");
764
1273
  rejectUnknown(record, ["kind", "name", "namespace"], "grant object");
765
1274
  const kind = requireString(record.kind, "grant object kind");
766
- if (kind !== "table" && kind !== "sequence" && kind !== "namespace") {
767
- catalogError2("OKM1020", `Grant object kind ${kind} must be table, sequence, or namespace.`);
1275
+ if (kind !== "table" && kind !== "view" && kind !== "materializedView" && kind !== "sequence" && kind !== "function" && kind !== "namespace") {
1276
+ catalogError2("OKM1020", `Grant object kind ${kind} must be table, view, materializedView, sequence, function, or namespace.`);
768
1277
  }
769
1278
  return {
770
1279
  kind,
@@ -772,6 +1281,50 @@ function parseGrantObject(value) {
772
1281
  namespace: parseNamespace(record.namespace)
773
1282
  };
774
1283
  }
1284
+ function parseRole(identity, definition, owner, provenance, dependencies) {
1285
+ if (identity.kind !== "role") {
1286
+ catalogError2("OKM1020", `Role object identity is ${identity.kind}, not a role.`);
1287
+ }
1288
+ rejectUnknown(definition, ["inherit", "login"], "role definition");
1289
+ return roleObject({
1290
+ name: identity.name,
1291
+ login: requireBoolean(definition.login, "login"),
1292
+ inherit: requireBoolean(definition.inherit, "inherit"),
1293
+ owner,
1294
+ provenance,
1295
+ dependencies
1296
+ });
1297
+ }
1298
+ function parseGrant(identity, definition, owner, provenance, dependencies) {
1299
+ if (identity.kind !== "grant") {
1300
+ catalogError2("OKM1020", `Grant object identity is ${identity.kind}, not a grant.`);
1301
+ }
1302
+ rejectUnknown(definition, [], "grant definition");
1303
+ return grantObject({
1304
+ role: identity.role,
1305
+ object: identity.object,
1306
+ privilege: identity.privilege,
1307
+ owner,
1308
+ provenance,
1309
+ dependencies
1310
+ });
1311
+ }
1312
+ function parseDefaultPrivilege(identity, definition, owner, provenance, dependencies) {
1313
+ if (identity.kind !== "defaultPrivilege") {
1314
+ catalogError2("OKM1020", `Default privilege object identity is ${identity.kind}, not a default privilege.`);
1315
+ }
1316
+ rejectUnknown(definition, [], "default privilege definition");
1317
+ return defaultPrivilegeObject({
1318
+ forRole: identity.forRole,
1319
+ namespace: identity.namespace,
1320
+ objectKind: identity.objectKind,
1321
+ grantee: identity.grantee,
1322
+ privilege: identity.privilege,
1323
+ owner,
1324
+ provenance,
1325
+ dependencies
1326
+ });
1327
+ }
775
1328
  function parsePartition(value) {
776
1329
  const record = requireRecord(value, "partition");
777
1330
  rejectUnknown(record, ["columns", "method"], "partition");
@@ -845,7 +1398,7 @@ function parseDependencies(value) {
845
1398
  });
846
1399
  }
847
1400
  function isBuiltKind(kind) {
848
- return BUILT_KINDS2.includes(kind);
1401
+ return kind === "extension" || kind === "function" || kind === "trigger" || kind === "view" || kind === "materializedView" || kind === "role" || kind === "grant" || kind === "defaultPrivilege" || BUILT_KINDS2.includes(kind);
849
1402
  }
850
1403
  function isOwner(value) {
851
1404
  return OWNERS2.includes(value);
@@ -891,4 +1444,4 @@ function assertNeverKind(value) {
891
1444
  return catalogError2("OKM1020", `Unexpected kind ${JSON.stringify(value)}.`);
892
1445
  }
893
1446
 
894
- export { creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, loadTrustedCatalog2, parseCatalog2 };
1447
+ export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, loadTrustedCatalog2, parseCatalog2 };