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
@@ -0,0 +1,97 @@
1
+ import {
2
+ normaliseEdges,
3
+ assertProvenance
4
+ } from "./t4tbsy9h.js";
5
+ import {
6
+ assertIdentifier2
7
+ } from "./nfzc5z0w.js";
8
+ import {
9
+ catalogError2
10
+ } from "./52szzakm.js";
11
+
12
+ // src/contracts/catalog/extension.ts
13
+ function extensionObject(input) {
14
+ assertIdentifier2(input.name, "extension");
15
+ assertIdentifier2(input.schema, "extension schema");
16
+ assertProvenance(input.provenance);
17
+ assertVersion(input.version);
18
+ const definition = {
19
+ schema: input.schema,
20
+ relocatable: input.relocatable ?? true,
21
+ ...input.version !== undefined ? { version: input.version } : {}
22
+ };
23
+ return {
24
+ kind: "extension",
25
+ identity: { kind: "extension", name: input.name },
26
+ owner: input.owner ?? "managed",
27
+ definition,
28
+ dependencies: normaliseEdges(input.dependencies ?? []),
29
+ provenance: input.provenance
30
+ };
31
+ }
32
+ function isExactVersion(version) {
33
+ return version !== undefined && /^\d+(?:\.\d+)*$/.test(version);
34
+ }
35
+ function compareExtensionVersions(left, right) {
36
+ const a = parts(left);
37
+ const b = parts(right);
38
+ const length = Math.max(a.length, b.length);
39
+ for (let index = 0;index < length; index += 1) {
40
+ const diff = (a[index] ?? 0) - (b[index] ?? 0);
41
+ if (diff !== 0)
42
+ return diff < 0 ? -1 : 1;
43
+ }
44
+ return 0;
45
+ }
46
+ function sameExtensionDefinition(before, after) {
47
+ if (before.definition.schema !== after.definition.schema)
48
+ return false;
49
+ if (before.definition.relocatable !== after.definition.relocatable)
50
+ return false;
51
+ return sameVersion(before.definition.version, after.definition.version);
52
+ }
53
+ function alignExtensionVersions(source, other) {
54
+ const loose = looseNames(source, other);
55
+ if (loose.size === 0)
56
+ return source;
57
+ let changed = false;
58
+ const objects = source.objects.map((object) => {
59
+ if (object.kind !== "extension" || object.definition.version === undefined)
60
+ return object;
61
+ if (!loose.has(object.identity.name))
62
+ return object;
63
+ changed = true;
64
+ const { version: _version, ...definition } = object.definition;
65
+ return { ...object, definition };
66
+ });
67
+ return changed ? { version: source.version, objects } : source;
68
+ }
69
+ function sameVersion(before, after) {
70
+ if (!isExactVersion(after) || !isExactVersion(before))
71
+ return true;
72
+ return before === after;
73
+ }
74
+ function looseNames(source, other) {
75
+ const names = new Set;
76
+ for (const catalog of [source, other]) {
77
+ for (const object of catalog.objects) {
78
+ if (object.kind !== "extension")
79
+ continue;
80
+ if (!isExactVersion(object.definition.version))
81
+ names.add(object.identity.name);
82
+ }
83
+ }
84
+ return names;
85
+ }
86
+ function assertVersion(version) {
87
+ if (version === undefined)
88
+ return;
89
+ if (isExactVersion(version) || /^>=\d+(?:\.\d+)*$/.test(version))
90
+ return;
91
+ catalogError2("OKM1020", `Extension version ${String(version)} must be a dotted version or a >= floor.`);
92
+ }
93
+ function parts(version) {
94
+ return version.split(".").map((part) => Number(part));
95
+ }
96
+
97
+ export { extensionObject, isExactVersion, compareExtensionVersions, sameExtensionDefinition, alignExtensionVersions };
@@ -0,0 +1,19 @@
1
+ // src/dialects/pg/quote.ts
2
+ function quoteLiteral(value) {
3
+ return `'${value.replaceAll("'", "''")}'`;
4
+ }
5
+ function arrayElement(encoded, raw) {
6
+ if (raw && (encoded === "true" || encoded === "false" || isBareNumber(encoded))) {
7
+ return encoded;
8
+ }
9
+ return `"${encoded.replaceAll("\\", "\\\\").replaceAll('"', "\\\"")}"`;
10
+ }
11
+ function isBareNumber(encoded) {
12
+ let pattern = bareNumber;
13
+ pattern ??= /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
14
+ bareNumber = pattern;
15
+ return pattern.test(encoded);
16
+ }
17
+ var bareNumber;
18
+
19
+ export { quoteLiteral, arrayElement };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  ColumnBuilder2
3
- } from "./dd4f8mnx.js";
3
+ } from "./c9z5g0fm.js";
4
4
  import {
5
5
  definition
6
- } from "./xatfg0gn.js";
6
+ } from "./tmbdywx0.js";
7
7
  import {
8
8
  OkmError2
9
9
  } from "./52szzakm.js";
@@ -0,0 +1,150 @@
1
+ import {
2
+ staticNamespace2,
3
+ assertNamespace2,
4
+ normaliseEdges,
5
+ assertProvenance
6
+ } from "./t4tbsy9h.js";
7
+ import {
8
+ assertIdentifier2
9
+ } from "./nfzc5z0w.js";
10
+ import {
11
+ catalogError2
12
+ } from "./52szzakm.js";
13
+
14
+ // src/contracts/catalog/routine.ts
15
+ var VOLATILITY = new Set(["volatile", "stable", "immutable"]);
16
+ var SECURITY = new Set(["invoker", "definer"]);
17
+ var TIMING = new Set(["before", "after", "instead"]);
18
+ var LEVEL = new Set(["row", "statement"]);
19
+ var EVENT_ORDER = ["insert", "update", "delete", "truncate"];
20
+ var TYPE_TEXT = /^[A-Za-z][A-Za-z0-9_ ]*(\(\d+(,\s*\d+)?\))?(\[\])*$/;
21
+ function functionObject(input) {
22
+ assertIdentifier2(input.name, "function");
23
+ const namespace = input.namespace ?? staticNamespace2("public");
24
+ assertNamespace2(namespace);
25
+ assertProvenance(input.provenance);
26
+ if (input.language !== "sql" && input.language !== "plpgsql") {
27
+ catalogError2("OKM1020", `Function ${input.name} language must be sql or plpgsql.`);
28
+ }
29
+ const volatility = input.volatility ?? "volatile";
30
+ if (!VOLATILITY.has(volatility)) {
31
+ catalogError2("OKM1020", `Function ${input.name} volatility ${volatility} is not supported.`);
32
+ }
33
+ const security = input.security ?? "invoker";
34
+ if (!SECURITY.has(security)) {
35
+ catalogError2("OKM1020", `Function ${input.name} security ${security} is not supported.`);
36
+ }
37
+ assertTypeName(input.returns, `function ${input.name} return type`);
38
+ const args = (input.arguments ?? []).map((argument) => readArgument(input.name, argument));
39
+ if (input.body.length === 0) {
40
+ catalogError2("OKM1020", `Function ${input.name} needs a body.`);
41
+ }
42
+ const atomic = input.atomic === true;
43
+ if (atomic && input.language !== "sql") {
44
+ catalogError2("OKM1020", `Function ${input.name} BEGIN ATOMIC needs language sql.`);
45
+ }
46
+ if (input.searchPath !== undefined && input.searchPath.trim().length === 0) {
47
+ catalogError2("OKM1020", `Function ${input.name} search_path is empty.`);
48
+ }
49
+ const definition = {
50
+ arguments: args,
51
+ returns: input.returns,
52
+ language: input.language,
53
+ volatility,
54
+ security,
55
+ body: input.body,
56
+ ...input.searchPath !== undefined ? { searchPath: input.searchPath } : {},
57
+ ...atomic ? { atomic: true } : {}
58
+ };
59
+ return {
60
+ kind: "function",
61
+ identity: {
62
+ kind: "function",
63
+ namespace,
64
+ name: input.name,
65
+ argTypes: args.map((arg) => arg.type)
66
+ },
67
+ owner: input.owner ?? "managed",
68
+ definition,
69
+ dependencies: normaliseEdges(input.dependencies ?? []),
70
+ provenance: input.provenance
71
+ };
72
+ }
73
+ function triggerObject(input) {
74
+ assertIdentifier2(input.name, "trigger");
75
+ assertNamespace2(input.parent.namespace);
76
+ assertIdentifier2(input.parent.name, "trigger table");
77
+ assertProvenance(input.provenance);
78
+ if (!TIMING.has(input.timing)) {
79
+ catalogError2("OKM1020", `Trigger ${input.name} timing ${input.timing} is not supported.`);
80
+ }
81
+ if (!LEVEL.has(input.level)) {
82
+ catalogError2("OKM1020", `Trigger ${input.name} level ${input.level} is not supported.`);
83
+ }
84
+ const events = EVENT_ORDER.filter((event) => input.events.includes(event));
85
+ if (events.length === 0) {
86
+ catalogError2("OKM1020", `Trigger ${input.name} needs an event.`);
87
+ }
88
+ const updateOf = input.updateOf === undefined ? undefined : [...input.updateOf];
89
+ if (updateOf !== undefined) {
90
+ if (!events.includes("update")) {
91
+ catalogError2("OKM1020", `Trigger ${input.name} lists UPDATE OF columns without an update event.`);
92
+ }
93
+ if (input.level !== "row") {
94
+ catalogError2("OKM1020", `Trigger ${input.name} UPDATE OF columns need level row.`);
95
+ }
96
+ for (const column of updateOf)
97
+ assertIdentifier2(column, "trigger column");
98
+ }
99
+ assertIdentifier2(input.calls.name, "trigger function");
100
+ assertNamespace2(input.calls.namespace);
101
+ for (const typeName of input.calls.argTypes)
102
+ assertTypeName(typeName, `trigger ${input.name}`);
103
+ const edges = [
104
+ { kind: "table", namespace: input.parent.namespace, name: input.parent.name },
105
+ {
106
+ kind: "function",
107
+ namespace: input.calls.namespace,
108
+ name: input.calls.name,
109
+ argTypes: input.calls.argTypes
110
+ },
111
+ ...(updateOf ?? []).map((column) => ({
112
+ kind: "column",
113
+ parent: input.parent,
114
+ name: column
115
+ })),
116
+ ...input.dependencies ?? []
117
+ ];
118
+ const definition = {
119
+ timing: input.timing,
120
+ events,
121
+ level: input.level,
122
+ calls: {
123
+ namespace: input.calls.namespace,
124
+ name: input.calls.name,
125
+ argTypes: [...input.calls.argTypes]
126
+ },
127
+ ...updateOf !== undefined && updateOf.length > 0 ? { updateOf } : {},
128
+ ...input.when !== undefined && input.when.length > 0 ? { when: input.when } : {}
129
+ };
130
+ return {
131
+ kind: "trigger",
132
+ identity: { kind: "trigger", parent: input.parent, name: input.name },
133
+ owner: input.owner ?? "managed",
134
+ definition,
135
+ dependencies: normaliseEdges(edges),
136
+ provenance: input.provenance
137
+ };
138
+ }
139
+ function readArgument(fn, argument) {
140
+ assertIdentifier2(argument.name, `function ${fn} argument`);
141
+ assertTypeName(argument.type, `function ${fn} argument ${argument.name}`);
142
+ return { name: argument.name, type: argument.type };
143
+ }
144
+ function assertTypeName(typeName, role) {
145
+ if (!TYPE_TEXT.test(typeName)) {
146
+ catalogError2("OKM1020", `${role} ${typeName} is not a type name.`);
147
+ }
148
+ }
149
+
150
+ export { functionObject, triggerObject };
@@ -0,0 +1,11 @@
1
+ // src/runtime/compat-words.ts
2
+ var CURRENT = "current";
3
+ var BEHIND_EXPAND = "behind by expand";
4
+ var BEHIND_CONTRACT = "behind by contract";
5
+ var AHEAD_EXPAND = "ahead by expand";
6
+ var AHEAD_CONTRACT = "ahead by contract";
7
+ function failedAt(step) {
8
+ return `failed at step ${String(step)} (resume with okm migrate apply)`;
9
+ }
10
+
11
+ export { CURRENT, BEHIND_EXPAND, BEHIND_CONTRACT, AHEAD_EXPAND, AHEAD_CONTRACT, failedAt };
@@ -0,0 +1,72 @@
1
+ import {
2
+ open2
3
+ } from "./wqem4jed.js";
4
+ import"./8jb4ymh2.js";
5
+ import {
6
+ createdOf,
7
+ testing2
8
+ } from "./ygem90rn.js";
9
+ import"./n442h54c.js";
10
+ import {
11
+ assertTargetPolicy,
12
+ assertDirectConnection,
13
+ selectTarget,
14
+ loadConfig,
15
+ loadSchema
16
+ } from "./q6zsyh31.js";
17
+ import"./n5y9zyj1.js";
18
+ import"./41kv2xdm.js";
19
+ import {
20
+ OkmError2
21
+ } from "./52szzakm.js";
22
+
23
+ // src/tooling/migrate/seed.ts
24
+ import { existsSync } from "node:fs";
25
+ import { join } from "node:path";
26
+ import { pathToFileURL } from "node:url";
27
+ async function seedProject(cwd, file, flags) {
28
+ const config = await loadConfig(cwd);
29
+ const target = selectTarget(config, flags.target);
30
+ assertTargetPolicy(target, "seed", flags.allowProtected);
31
+ const path = join(cwd, file);
32
+ if (!existsSync(path)) {
33
+ throw new OkmError2("invalid", `Seed file ${file} was not found.`, {
34
+ fix: { summary: "Pass okm seed <file> a module in this project." }
35
+ });
36
+ }
37
+ assertDirectConnection(target.url, flags.allowPooler || config.allowPooler === true);
38
+ const schema = await loadSchema(cwd, config.schema);
39
+ const pool = open2({ url: target.url, max: 1 });
40
+ const harness = await testing2(schema, { driver: pool, migrate: false });
41
+ try {
42
+ const imported = await import(`${pathToFileURL(path).href}?okm=${Date.now()}`);
43
+ const seed = isRecord(imported) ? imported.default : undefined;
44
+ if (typeof seed !== "function") {
45
+ throw new OkmError2("invalid", `${file} must default-export a function.`, {
46
+ fix: { summary: "export default async function seed(t) { ... }." }
47
+ });
48
+ }
49
+ await seed(harness);
50
+ return formatCreated(target.name, createdOf(harness));
51
+ } finally {
52
+ await harness.close();
53
+ }
54
+ }
55
+ function formatCreated(target, counts) {
56
+ const lines = [`target ${target}`];
57
+ if (counts.length === 0)
58
+ lines.push("created nothing");
59
+ else {
60
+ for (const item of counts)
61
+ lines.push(`${item.table} ${String(item.count)}`);
62
+ }
63
+ return `${lines.join(`
64
+ `)}
65
+ `;
66
+ }
67
+ function isRecord(value) {
68
+ return typeof value === "object" && value !== null;
69
+ }
70
+ export {
71
+ seedProject
72
+ };
@@ -2,10 +2,7 @@ import {
2
2
  assertOperatorFits,
3
3
  textArray,
4
4
  arrayElementType
5
- } from "./zt8y0wzb.js";
6
- import {
7
- runWrite
8
- } from "./n4jqhpqz.js";
5
+ } from "./n7mcc1gk.js";
9
6
  import {
10
7
  stack
11
8
  } from "./672t5vym.js";
@@ -14,12 +11,15 @@ import {
14
11
  fieldSealed,
15
12
  sealingTrait
16
13
  } from "./7m88x3e9.js";
14
+ import {
15
+ runWrite
16
+ } from "./n4jqhpqz.js";
17
17
  import {
18
18
  writeWouldValidate
19
- } from "./3a5ne750.js";
19
+ } from "./9m80mkac.js";
20
20
  import {
21
21
  encodeJson
22
- } from "./yw5c610b.js";
22
+ } from "./gjthds9j.js";
23
23
  import {
24
24
  withRowFilters,
25
25
  archiveRules,
@@ -5,9 +5,10 @@ import {
5
5
  assertBoundText,
6
6
  assertRegconfig,
7
7
  textArray
8
- } from "./zt8y0wzb.js";
8
+ } from "./n7mcc1gk.js";
9
9
  import {
10
10
  installOperatorSql,
11
+ quote,
11
12
  isRecord,
12
13
  fail
13
14
  } from "./xrfnq5k8.js";
@@ -35,6 +36,10 @@ function emitStructured(column, ref, name, value, sink) {
35
36
  emitMatches(column, ref, value, sink);
36
37
  return;
37
38
  }
39
+ if (name === "similar" || name === "wordSimilar") {
40
+ emitTrigram(column, ref, name, value, sink);
41
+ return;
42
+ }
38
43
  assertOperatorFits(column, name);
39
44
  fail("OKM1121", `${name} is not a value operator on ${column.field}. Use has, none, or every on a relation.`);
40
45
  }
@@ -135,4 +140,17 @@ function emitMatches(column, ref, value, sink) {
135
140
  sink.param(value.query);
136
141
  sink.text(")");
137
142
  }
143
+ function emitTrigram(column, ref, name, value, sink) {
144
+ if (!isRecord(value) || typeof value.query !== "string" || typeof value.schema !== "string") {
145
+ fail("OKM1121", `${name} on ${column.field} needs query text.`);
146
+ }
147
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value.schema)) {
148
+ fail("OKM1121", `${name} on ${column.field} needs an extension schema name.`);
149
+ }
150
+ sink.text(ref);
151
+ sink.text(" operator(");
152
+ sink.text(quote(value.schema));
153
+ sink.text(name === "similar" ? ".%) " : ".<%) ");
154
+ sink.param(value.query);
155
+ }
138
156
  installOperatorSql(emitStructured);
@@ -1,16 +1,28 @@
1
1
  import {
2
2
  open2
3
- } from "./ecdzej21.js";
4
- import"./d2whjz4k.js";
3
+ } from "./wqem4jed.js";
4
+ import"./8jb4ymh2.js";
5
5
  import"./n442h54c.js";
6
6
  import {
7
- loadMigrations
8
- } from "./rtnaqre0.js";
7
+ CURRENT,
8
+ BEHIND_EXPAND,
9
+ BEHIND_CONTRACT,
10
+ AHEAD_EXPAND,
11
+ AHEAD_CONTRACT,
12
+ failedAt
13
+ } from "./9yn6a2vd.js";
14
+ import {
15
+ loadMigrations,
16
+ expandProvisioned,
17
+ provisionHistoryIsKnown
18
+ } from "./7nk68fj8.js";
9
19
  import {
10
20
  assertTargetPolicy,
11
21
  listTargets,
12
22
  loadConfig
13
- } from "./5z4q2zda.js";
23
+ } from "./q6zsyh31.js";
24
+ import"./n5y9zyj1.js";
25
+ import"./41kv2xdm.js";
14
26
  import {
15
27
  OkmError2
16
28
  } from "./52szzakm.js";
@@ -18,8 +30,8 @@ import {
18
30
  // src/tooling/migrate/status.ts
19
31
  import { join } from "node:path";
20
32
  function describeStatus(migrations, history, recorded) {
21
- const done = new Set(history.map((row) => `${row.migrationId}:${String(row.stepIndex)}`));
22
33
  const known = new Set(migrations.map((migration) => migration.id));
34
+ const done = expandProvisioned(migrations, new Set(history.map((row) => `${row.migrationId}:${String(row.stepIndex)}`)), history.map((row) => row.migrationId));
23
35
  for (const migration of migrations) {
24
36
  let have = 0;
25
37
  let missing = -1;
@@ -33,33 +45,33 @@ function describeStatus(migrations, history, recorded) {
33
45
  return {
34
46
  version: migration.id,
35
47
  catalogHash: recorded?.hash ?? "-",
36
- state: `failed at step ${String(missing)}`
48
+ state: failedAt(missing)
37
49
  };
38
50
  }
39
51
  }
40
- const extra = history.some((row) => !known.has(row.migrationId));
41
52
  const pending = migrations.filter((migration) => migration.steps.some((_, index) => !done.has(`${migration.id}:${String(index)}`)));
42
53
  const finished = lastComplete(migrations, done);
43
54
  const version = recorded?.version ?? finished ?? "-";
44
55
  const catalogHash = recorded?.hash ?? "-";
56
+ const extra = history.some((row) => !provisionHistoryIsKnown(row.migrationId, known));
45
57
  if (extra)
46
- return { version, catalogHash, state: "ahead" };
58
+ return { version, catalogHash, state: aheadState(history, known) };
47
59
  if (pending.length > 0) {
48
60
  const contract = pending.some((migration) => migration.steps.some((step) => step.class !== "expand"));
49
61
  return {
50
62
  version,
51
63
  catalogHash,
52
- state: contract ? "behind by contract" : "behind by expand"
64
+ state: contract ? BEHIND_CONTRACT : BEHIND_EXPAND
53
65
  };
54
66
  }
55
67
  const last = migrations.at(-1);
56
68
  if (last !== undefined && recorded !== undefined && recorded.hash !== last.catalogHash) {
57
- return { version, catalogHash, state: "ahead" };
69
+ return { version, catalogHash, state: aheadState(history, known) };
58
70
  }
59
71
  return {
60
72
  version: recorded?.version ?? last?.id ?? "-",
61
73
  catalogHash: recorded?.hash ?? last?.catalogHash ?? "-",
62
- state: "current"
74
+ state: CURRENT
63
75
  };
64
76
  }
65
77
  async function readTargetStatus(input) {
@@ -81,7 +93,8 @@ async function readTargetStatus(input) {
81
93
  version: described.version,
82
94
  catalogHash: described.catalogHash,
83
95
  state: described.state,
84
- protected: input.protected
96
+ protected: input.protected,
97
+ backfills: await readBackfills(pool)
85
98
  };
86
99
  } finally {
87
100
  await pool.close();
@@ -104,8 +117,17 @@ async function statusProject(cwd, flags) {
104
117
  }
105
118
  function formatStatus(rows) {
106
119
  const lines = ["target\tversion\tcatalog\tstate\tprotected"];
120
+ const backfills = [];
107
121
  for (const row of rows) {
108
122
  lines.push([row.target, row.version, row.catalogHash, row.state, row.protected ? "true" : "false"].join("\t"));
123
+ backfills.push(...row.backfills);
124
+ }
125
+ if (backfills.length > 0) {
126
+ lines.push("backfill");
127
+ lines.push("migration\tstep\trows\tkey\tstate");
128
+ for (const item of backfills) {
129
+ lines.push([item.migrationId, String(item.stepIndex), item.rows, item.lastKey, item.state].join("\t"));
130
+ }
109
131
  }
110
132
  return `${lines.join(`
111
133
  `)}
@@ -159,7 +181,33 @@ async function readHistory(pool) {
159
181
  rows.push({
160
182
  migrationId,
161
183
  stepIndex: Number(step),
162
- class: stepClass === "contract" || stepClass === "unclassified" ? stepClass : "expand"
184
+ class: storedClass(stepClass)
185
+ });
186
+ }
187
+ return rows;
188
+ }
189
+ async function readBackfills(pool) {
190
+ const present = await pool.execute("select to_regclass('okm_backfill') is not null");
191
+ if (!wireTrue(present.rows[0]?.[0] ?? null))
192
+ return [];
193
+ const result = await pool.execute(`select migration_id, step_index::text, rows_touched::text, last_key, state
194
+ from okm_backfill
195
+ where state <> 'done'
196
+ order by migration_id, step_index`);
197
+ const rows = [];
198
+ for (const row of result.rows) {
199
+ const migrationId = row[0];
200
+ const step = row[1];
201
+ const touched = row[2];
202
+ const state = row[4];
203
+ if (migrationId == null || step == null || touched == null || state == null)
204
+ continue;
205
+ rows.push({
206
+ migrationId,
207
+ stepIndex: Number(step),
208
+ rows: touched,
209
+ lastKey: row[3] ?? "-",
210
+ state
163
211
  });
164
212
  }
165
213
  return rows;
@@ -167,6 +215,26 @@ async function readHistory(pool) {
167
215
  function wireTrue(value) {
168
216
  return value === "t" || value === "true";
169
217
  }
218
+ function aheadState(history, known) {
219
+ let sawExtra = false;
220
+ let expandOnly = true;
221
+ for (const row of history) {
222
+ if (known.has(row.migrationId))
223
+ continue;
224
+ sawExtra = true;
225
+ if (row.class !== "expand")
226
+ expandOnly = false;
227
+ }
228
+ if (!sawExtra) {
229
+ expandOnly = history.length > 0 && history.every((row) => row.class === "expand");
230
+ }
231
+ return expandOnly ? AHEAD_EXPAND : AHEAD_CONTRACT;
232
+ }
233
+ function storedClass(value) {
234
+ if (value === "expand" || value === "contract" || value === "unclassified")
235
+ return value;
236
+ return "unclassified";
237
+ }
170
238
  export {
171
239
  statusProject
172
240
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  validationGate
3
- } from "./3a5ne750.js";
3
+ } from "./9m80mkac.js";
4
4
  import {
5
5
  isOperator
6
6
  } from "./cn0n68ft.js";
@@ -1,10 +1,12 @@
1
1
  import {
2
2
  definition,
3
3
  rejected,
4
- quoteLiteral,
5
4
  writeArray,
6
5
  readArray
7
- } from "./xatfg0gn.js";
6
+ } from "./tmbdywx0.js";
7
+ import {
8
+ quoteLiteral
9
+ } from "./94ez8kzh.js";
8
10
  import {
9
11
  REFERENTIAL_ACTIONS,
10
12
  referentialAction
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  encodeText,
3
3
  decodeText
4
- } from "./sacqha1y.js";
4
+ } from "./4m9fn52z.js";
5
5
  import {
6
6
  required,
7
7
  openColumn
8
- } from "./dd4f8mnx.js";
8
+ } from "./c9z5g0fm.js";
9
9
  import {
10
10
  definition,
11
11
  rejected
12
- } from "./xatfg0gn.js";
12
+ } from "./tmbdywx0.js";
13
13
  import {
14
14
  readClientGenerator
15
15
  } from "./rwmrejjz.js";
@@ -66,4 +66,4 @@ function uuidText() {
66
66
  }
67
67
  var uuidPattern;
68
68
 
69
- export { id2, uuid2 };
69
+ export { id2, uuid2, encodeUuid, decodeUuid };
@@ -9,7 +9,7 @@ import {
9
9
  runCall,
10
10
  EMPTY_NOTICES,
11
11
  resultFrom
12
- } from "./9k6vetvf.js";
12
+ } from "./rrstp3kb.js";
13
13
 
14
14
  // src/adapters/pg/pglite.ts
15
15
  import { PGlite } from "@electric-sql/pglite";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  send,
3
3
  connectClient
4
- } from "./38crxbgn.js";
4
+ } from "./6p5k20sm.js";
5
5
  import {
6
6
  isConnectionLost
7
7
  } from "./tbszx8mz.js";
8
8
  import {
9
9
  WireSession
10
- } from "./cstgkzdx.js";
10
+ } from "./zvbjc949.js";
11
11
  import {
12
12
  rejectClosed,
13
13
  runCall
14
- } from "./9k6vetvf.js";
14
+ } from "./rrstp3kb.js";
15
15
 
16
16
  // src/adapters/pg/nodepostgres-extra.ts
17
17
  var RESET_ALL = "RESET ALL";