@dsqlbase/migration 0.1.0 → 0.1.3

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 (138) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/base.d.ts +87 -0
  3. package/dist/base.d.ts.map +1 -0
  4. package/dist/base.js +53 -0
  5. package/dist/base.js.map +1 -0
  6. package/dist/ddl/ast.d.ts +267 -0
  7. package/dist/ddl/ast.d.ts.map +1 -0
  8. package/dist/ddl/ast.js +10 -0
  9. package/dist/ddl/ast.js.map +1 -0
  10. package/dist/ddl/factory.d.ts +88 -0
  11. package/dist/ddl/factory.d.ts.map +1 -0
  12. package/dist/ddl/factory.js +186 -0
  13. package/dist/ddl/factory.js.map +1 -0
  14. package/dist/ddl/index.d.ts +5 -0
  15. package/dist/ddl/index.d.ts.map +1 -0
  16. package/dist/ddl/index.js +4 -0
  17. package/dist/ddl/index.js.map +1 -0
  18. package/dist/ddl/printer.d.ts +21 -0
  19. package/dist/ddl/printer.d.ts.map +1 -0
  20. package/dist/ddl/printer.js +278 -0
  21. package/dist/ddl/printer.js.map +1 -0
  22. package/dist/ddl/schema.d.ts +33 -0
  23. package/dist/ddl/schema.d.ts.map +1 -0
  24. package/dist/ddl/schema.js +133 -0
  25. package/dist/ddl/schema.js.map +1 -0
  26. package/dist/executor.d.ts +29 -0
  27. package/dist/executor.d.ts.map +1 -0
  28. package/dist/executor.js +93 -0
  29. package/dist/executor.js.map +1 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +7 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/introspection/introspect.d.ts +8 -0
  35. package/dist/introspection/introspect.d.ts.map +1 -0
  36. package/dist/introspection/introspect.js +14 -0
  37. package/dist/introspection/introspect.js.map +1 -0
  38. package/dist/introspection/normalizer.d.ts +96 -0
  39. package/dist/introspection/normalizer.d.ts.map +1 -0
  40. package/dist/introspection/normalizer.js +187 -0
  41. package/dist/introspection/normalizer.js.map +1 -0
  42. package/dist/introspection/query.d.ts +3 -0
  43. package/dist/introspection/query.d.ts.map +1 -0
  44. package/dist/introspection/query.js +284 -0
  45. package/dist/introspection/query.js.map +1 -0
  46. package/dist/reconciliation/diffs/base.d.ts +19 -0
  47. package/dist/reconciliation/diffs/base.d.ts.map +1 -0
  48. package/dist/reconciliation/diffs/base.js +58 -0
  49. package/dist/reconciliation/diffs/base.js.map +1 -0
  50. package/dist/reconciliation/diffs/column.d.ts +42 -0
  51. package/dist/reconciliation/diffs/column.d.ts.map +1 -0
  52. package/dist/reconciliation/diffs/column.js +48 -0
  53. package/dist/reconciliation/diffs/column.js.map +1 -0
  54. package/dist/reconciliation/diffs/constraint.d.ts +9 -0
  55. package/dist/reconciliation/diffs/constraint.d.ts.map +1 -0
  56. package/dist/reconciliation/diffs/constraint.js +122 -0
  57. package/dist/reconciliation/diffs/constraint.js.map +1 -0
  58. package/dist/reconciliation/diffs/domain.d.ts +17 -0
  59. package/dist/reconciliation/diffs/domain.d.ts.map +1 -0
  60. package/dist/reconciliation/diffs/domain.js +30 -0
  61. package/dist/reconciliation/diffs/domain.js.map +1 -0
  62. package/dist/reconciliation/diffs/indexes.d.ts +18 -0
  63. package/dist/reconciliation/diffs/indexes.d.ts.map +1 -0
  64. package/dist/reconciliation/diffs/indexes.js +59 -0
  65. package/dist/reconciliation/diffs/indexes.js.map +1 -0
  66. package/dist/reconciliation/diffs/sequence.d.ts +19 -0
  67. package/dist/reconciliation/diffs/sequence.d.ts.map +1 -0
  68. package/dist/reconciliation/diffs/sequence.js +17 -0
  69. package/dist/reconciliation/diffs/sequence.js.map +1 -0
  70. package/dist/reconciliation/diffs/table.d.ts +6 -0
  71. package/dist/reconciliation/diffs/table.d.ts.map +1 -0
  72. package/dist/reconciliation/diffs/table.js +52 -0
  73. package/dist/reconciliation/diffs/table.js.map +1 -0
  74. package/dist/reconciliation/operations/base.d.ts +54 -0
  75. package/dist/reconciliation/operations/base.d.ts.map +1 -0
  76. package/dist/reconciliation/operations/base.js +27 -0
  77. package/dist/reconciliation/operations/base.js.map +1 -0
  78. package/dist/reconciliation/operations/domain.d.ts +7 -0
  79. package/dist/reconciliation/operations/domain.d.ts.map +1 -0
  80. package/dist/reconciliation/operations/domain.js +88 -0
  81. package/dist/reconciliation/operations/domain.js.map +1 -0
  82. package/dist/reconciliation/operations/index.d.ts +6 -0
  83. package/dist/reconciliation/operations/index.d.ts.map +1 -0
  84. package/dist/reconciliation/operations/index.js +35 -0
  85. package/dist/reconciliation/operations/index.js.map +1 -0
  86. package/dist/reconciliation/operations/schema.d.ts +7 -0
  87. package/dist/reconciliation/operations/schema.d.ts.map +1 -0
  88. package/dist/reconciliation/operations/schema.js +41 -0
  89. package/dist/reconciliation/operations/schema.js.map +1 -0
  90. package/dist/reconciliation/operations/sequence.d.ts +7 -0
  91. package/dist/reconciliation/operations/sequence.d.ts.map +1 -0
  92. package/dist/reconciliation/operations/sequence.js +75 -0
  93. package/dist/reconciliation/operations/sequence.js.map +1 -0
  94. package/dist/reconciliation/operations/table.d.ts +9 -0
  95. package/dist/reconciliation/operations/table.d.ts.map +1 -0
  96. package/dist/reconciliation/operations/table.js +513 -0
  97. package/dist/reconciliation/operations/table.js.map +1 -0
  98. package/dist/reconciliation/planner.d.ts +3 -0
  99. package/dist/reconciliation/planner.d.ts.map +1 -0
  100. package/dist/reconciliation/planner.js +125 -0
  101. package/dist/reconciliation/planner.js.map +1 -0
  102. package/dist/reconciliation/reconcile.d.ts +22 -0
  103. package/dist/reconciliation/reconcile.d.ts.map +1 -0
  104. package/dist/reconciliation/reconcile.js +48 -0
  105. package/dist/reconciliation/reconcile.js.map +1 -0
  106. package/dist/runner.d.ts +41 -0
  107. package/dist/runner.d.ts.map +1 -0
  108. package/dist/runner.js +69 -0
  109. package/dist/runner.js.map +1 -0
  110. package/dist/validation/context.d.ts +32 -0
  111. package/dist/validation/context.d.ts.map +1 -0
  112. package/dist/validation/context.js +25 -0
  113. package/dist/validation/context.js.map +1 -0
  114. package/dist/validation/index.d.ts +3 -0
  115. package/dist/validation/index.d.ts.map +1 -0
  116. package/dist/validation/index.js +2 -0
  117. package/dist/validation/index.js.map +1 -0
  118. package/dist/validation/rules/global.d.ts +5 -0
  119. package/dist/validation/rules/global.d.ts.map +1 -0
  120. package/dist/validation/rules/global.js +35 -0
  121. package/dist/validation/rules/global.js.map +1 -0
  122. package/dist/validation/rules/schema.d.ts +4 -0
  123. package/dist/validation/rules/schema.d.ts.map +1 -0
  124. package/dist/validation/rules/schema.js +12 -0
  125. package/dist/validation/rules/schema.js.map +1 -0
  126. package/dist/validation/rules/sequence.d.ts +4 -0
  127. package/dist/validation/rules/sequence.d.ts.map +1 -0
  128. package/dist/validation/rules/sequence.js +13 -0
  129. package/dist/validation/rules/sequence.js.map +1 -0
  130. package/dist/validation/rules/table.d.ts +12 -0
  131. package/dist/validation/rules/table.d.ts.map +1 -0
  132. package/dist/validation/rules/table.js +164 -0
  133. package/dist/validation/rules/table.js.map +1 -0
  134. package/dist/validation/validate.d.ts +13 -0
  135. package/dist/validation/validate.d.ts.map +1 -0
  136. package/dist/validation/validate.js +42 -0
  137. package/dist/validation/validate.js.map +1 -0
  138. package/package.json +2 -2
@@ -0,0 +1,125 @@
1
+ import { qualifiedConstraintName, qualifiedName } from "./operations/index.js";
2
+ const CONSTRAINT_KINDS = new Set([
3
+ "PRIMARY_KEY_CONSTRAINT",
4
+ "UNIQUE_CONSTRAINT",
5
+ "CHECK_CONSTRAINT",
6
+ ]);
7
+ function isConstraintObject(obj) {
8
+ return CONSTRAINT_KINDS.has(obj.kind);
9
+ }
10
+ /**
11
+ * The subject string is the key other ops use in their `references[]` to
12
+ * point at this op. For most ops that's `qualifiedName(object)`. For
13
+ * standalone constraint ops (today only the UNIQUE promotion path), the
14
+ * parent table is the first entry of `references[]`.
15
+ */
16
+ function subjectOf(op) {
17
+ if (isConstraintObject(op.object)) {
18
+ const parent = op.references?.[0];
19
+ if (parent !== undefined) {
20
+ return qualifiedConstraintName(parent, op.object);
21
+ }
22
+ }
23
+ return qualifiedName(op.object);
24
+ }
25
+ function insertSorted(arr, value) {
26
+ let lo = 0;
27
+ let hi = arr.length;
28
+ while (lo < hi) {
29
+ const mid = (lo + hi) >>> 1;
30
+ if (arr[mid] < value)
31
+ lo = mid + 1;
32
+ else
33
+ hi = mid;
34
+ }
35
+ arr.splice(lo, 0, value);
36
+ }
37
+ function buildSubjectRegistry(ops) {
38
+ const registry = new Map();
39
+ for (const op of ops) {
40
+ const subject = subjectOf(op);
41
+ const list = registry.get(subject);
42
+ if (list) {
43
+ list.push(op.id);
44
+ }
45
+ else {
46
+ registry.set(subject, [op.id]);
47
+ }
48
+ }
49
+ return registry;
50
+ }
51
+ function buildDependencyGraph(ops, registry) {
52
+ const adjacency = new Map();
53
+ const inDegree = new Map();
54
+ for (const op of ops) {
55
+ inDegree.set(op.id, 0);
56
+ }
57
+ const addEdge = (from, to) => {
58
+ if (from === to)
59
+ return;
60
+ let outs = adjacency.get(from);
61
+ if (!outs) {
62
+ outs = new Set();
63
+ adjacency.set(from, outs);
64
+ }
65
+ if (!outs.has(to)) {
66
+ outs.add(to);
67
+ inDegree.set(to, (inDegree.get(to) ?? 0) + 1);
68
+ }
69
+ };
70
+ for (const op of ops) {
71
+ const refs = op.references ?? [];
72
+ for (const ref of refs) {
73
+ const refIds = registry.get(ref);
74
+ if (!refIds)
75
+ continue;
76
+ for (const refId of refIds) {
77
+ if (op.type === "DROP") {
78
+ // DROP X must come before ops that touch X's referenced subjects.
79
+ addEdge(op.id, refId);
80
+ }
81
+ else {
82
+ // CREATE/ALTER X must come after ops that touch X's referenced subjects.
83
+ addEdge(refId, op.id);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ return { adjacency, inDegree };
89
+ }
90
+ export function planOperations(ops) {
91
+ const opsById = new Map(ops.map((op) => [op.id, op]));
92
+ const registry = buildSubjectRegistry(ops);
93
+ const { adjacency, inDegree } = buildDependencyGraph(ops, registry);
94
+ // Kahn's algorithm with a stable min-id ordering of the ready set.
95
+ const ready = [];
96
+ for (const [id, deg] of inDegree) {
97
+ if (deg === 0)
98
+ ready.push(id);
99
+ }
100
+ ready.sort((a, b) => a - b);
101
+ const result = [];
102
+ while (ready.length > 0) {
103
+ const id = ready.shift();
104
+ const op = opsById.get(id);
105
+ if (!op)
106
+ continue;
107
+ result.push(op);
108
+ const outs = adjacency.get(id);
109
+ if (!outs)
110
+ continue;
111
+ for (const next of outs) {
112
+ const newDeg = (inDegree.get(next) ?? 0) - 1;
113
+ inDegree.set(next, newDeg);
114
+ if (newDeg === 0)
115
+ insertSorted(ready, next);
116
+ }
117
+ }
118
+ if (result.length !== ops.length) {
119
+ const remaining = ops.filter((op) => !result.includes(op)).map((op) => op.id);
120
+ throw new Error(`Cycle detected in DDL operation dependencies (op ids: ${remaining.join(", ")}). ` +
121
+ `This indicates a bug in operation emission, not user input.`);
122
+ }
123
+ return result;
124
+ }
125
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/reconciliation/planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { SerializedSchema } from "../base.js";
2
+ import { DDLOperationOptions } from "./operations/base.js";
3
+ import { DDLOperationError, IndexedDDLOperation } from "./operations/index.js";
4
+ export declare class SchemaReconciler {
5
+ private readonly _localSchema;
6
+ private readonly _remoteSchema;
7
+ private _operationIdCounter;
8
+ private readonly _operations;
9
+ private readonly _errors;
10
+ private readonly _options;
11
+ constructor(localSchema: SerializedSchema, remoteSchema: SerializedSchema, options?: Partial<DDLOperationOptions>);
12
+ private _pushOperation;
13
+ run(): {
14
+ operations: IndexedDDLOperation[];
15
+ errors: DDLOperationError<import("@dsqlbase/core").DefinitionNode<string, object>>[];
16
+ };
17
+ }
18
+ export declare function reconcileSchemas(local: SerializedSchema, remote: SerializedSchema, options?: Partial<DDLOperationOptions>): {
19
+ operations: IndexedDDLOperation[];
20
+ errors: DDLOperationError<import("@dsqlbase/core").DefinitionNode<string, object>>[];
21
+ };
22
+ //# sourceMappingURL=reconcile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/reconciliation/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEL,iBAAiB,EAGjB,mBAAmB,EAEpB,MAAM,uBAAuB,CAAC;AAG/B,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkD;IAC/E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkD;IAEhF,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;gBAG7C,WAAW,EAAE,gBAAgB,EAC7B,YAAY,EAAE,gBAAgB,EAC9B,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAU5C,OAAO,CAAC,cAAc;IAMf,GAAG;;;;CA0BX;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM;;;EAG3C"}
@@ -0,0 +1,48 @@
1
+ import { diffObjectOperations, dropObjectOperations, qualifiedName, } from "./operations/index.js";
2
+ import { planOperations } from "./planner.js";
3
+ export class SchemaReconciler {
4
+ _localSchema;
5
+ _remoteSchema;
6
+ _operationIdCounter = 0;
7
+ _operations = [];
8
+ _errors = [];
9
+ _options;
10
+ constructor(localSchema, remoteSchema, options = {}) {
11
+ this._localSchema = new Map(localSchema.map((obj) => [qualifiedName(obj), obj]));
12
+ this._remoteSchema = new Map(remoteSchema.map((obj) => [qualifiedName(obj), obj]));
13
+ this._options = {
14
+ asyncIndexes: options.asyncIndexes ?? true,
15
+ safeOperations: options.safeOperations ?? true,
16
+ };
17
+ }
18
+ _pushOperation(operation) {
19
+ const id = this._operationIdCounter++;
20
+ this._operations.push({ id, ...operation });
21
+ return id;
22
+ }
23
+ run() {
24
+ for (const [name, local] of this._localSchema.entries()) {
25
+ const remote = this._remoteSchema.get(name);
26
+ const { operations, errors } = diffObjectOperations(local, remote, this._options);
27
+ for (const operation of operations) {
28
+ this._pushOperation(operation);
29
+ }
30
+ for (const error of errors) {
31
+ this._errors.push(error);
32
+ }
33
+ this._remoteSchema.delete(name);
34
+ }
35
+ for (const remote of this._remoteSchema.values()) {
36
+ const operation = dropObjectOperations(remote, this._options);
37
+ this._pushOperation(operation);
38
+ }
39
+ return {
40
+ operations: planOperations(this._operations),
41
+ errors: this._errors,
42
+ };
43
+ }
44
+ }
45
+ export function reconcileSchemas(local, remote, options = {}) {
46
+ return new SchemaReconciler(local, remote, options).run();
47
+ }
48
+ //# sourceMappingURL=reconcile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/reconciliation/reconcile.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,oBAAoB,EACpB,oBAAoB,EAEpB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,OAAO,gBAAgB;IACV,YAAY,CAAkD;IAC9D,aAAa,CAAkD;IAExE,mBAAmB,GAAG,CAAC,CAAC;IACf,WAAW,GAA0B,EAAE,CAAC;IACxC,OAAO,GAAwB,EAAE,CAAC;IAClC,QAAQ,CAAsB;IAE/C,YACE,WAA6B,EAC7B,YAA8B,EAC9B,UAAwC,EAAE;QAE1C,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACjF,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC,QAAQ,GAAG;YACd,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;YAC1C,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,IAAI;SAC/C,CAAC;IACJ,CAAC;IAEO,cAAc,CAAC,SAAuB;QAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC;IACZ,CAAC;IAEM,GAAG;QACR,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAElF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YACjC,CAAC;YAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;YAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,MAAM,SAAS,GAAG,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9D,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;QAED,OAAO;YACL,UAAU,EAAE,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;YAC5C,MAAM,EAAE,IAAI,CAAC,OAAO;SACrB,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAuB,EACvB,MAAwB,EACxB,UAAwC,EAAE;IAE1C,OAAO,IAAI,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { Session } from "@dsqlbase/core";
2
+ import { SerializedSchema } from "./base.js";
3
+ import { DDLOperationError, IndexedDDLOperation } from "./reconciliation/operations/index.js";
4
+ import { ValidationResult } from "./validation/index.js";
5
+ import { OperationExecutionResult } from "./executor.js";
6
+ import { DDLOperationOptions } from "./reconciliation/operations/base.js";
7
+ export interface MigrationRunnerOptions extends Partial<DDLOperationOptions> {
8
+ /**
9
+ * If true, will destroy objects that don't match the local definition.
10
+ *
11
+ * **⚠️ Warning:** can cause data loss.
12
+ *
13
+ * @default false
14
+ */
15
+ destructive?: boolean;
16
+ }
17
+ export interface PlanResult {
18
+ operations: IndexedDDLOperation[];
19
+ errors: DDLOperationError[];
20
+ destructive: boolean;
21
+ }
22
+ export declare class MigrationRunner {
23
+ private readonly _session;
24
+ private readonly _print;
25
+ private readonly _executor;
26
+ constructor(session: Session);
27
+ validate(definition: SerializedSchema): ValidationResult;
28
+ introspect(): Promise<SerializedSchema>;
29
+ reconcile(local: SerializedSchema, remote: SerializedSchema, options?: Partial<DDLOperationOptions>): {
30
+ operations: IndexedDDLOperation[];
31
+ errors: DDLOperationError<import("@dsqlbase/core").DefinitionNode<string, object>>[];
32
+ };
33
+ plan(definition: SerializedSchema, options?: Partial<DDLOperationOptions>): Promise<PlanResult>;
34
+ dryRun(definition: SerializedSchema, options?: MigrationRunnerOptions): Promise<import("@dsqlbase/core").SQLStatement[]>;
35
+ run(definition: SerializedSchema, options?: MigrationRunnerOptions): Promise<{
36
+ count: number;
37
+ progress: OperationExecutionResult[];
38
+ }>;
39
+ }
40
+ export declare function createMigrationRunner(session: Session): MigrationRunner;
41
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAkB,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG7D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,wBAAwB,EAAqB,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE1E,MAAM,WAAW,sBAAuB,SAAQ,OAAO,CAAC,mBAAmB,CAAC;IAC1E;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAElC,OAAO,EAAE,OAAO;IAKrB,QAAQ,CAAC,UAAU,EAAE,gBAAgB,GAAG,gBAAgB;IAIxD,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIvC,SAAS,CACd,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM;;;;IAK/B,IAAI,CACf,UAAU,EAAE,gBAAgB,EAC5B,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,OAAO,CAAC,UAAU,CAAC;IAiBT,MAAM,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,GAAE,sBAA2B;IAgBzE,GAAG,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,GAAE,sBAA2B;;;;CA2BpF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAEvE"}
package/dist/runner.js ADDED
@@ -0,0 +1,69 @@
1
+ import { MigrationError } from "./base.js";
2
+ import { createPrinter } from "./ddl/printer.js";
3
+ import { introspect as introspectSchema } from "./introspection/introspect.js";
4
+ import { reconcileSchemas } from "./reconciliation/reconcile.js";
5
+ import { validateDefinition } from "./validation/validate.js";
6
+ import { OperationExecutor } from "./executor.js";
7
+ export class MigrationRunner {
8
+ _session;
9
+ _print = createPrinter();
10
+ _executor;
11
+ constructor(session) {
12
+ this._session = session;
13
+ this._executor = new OperationExecutor(session);
14
+ }
15
+ validate(definition) {
16
+ return validateDefinition(definition);
17
+ }
18
+ introspect() {
19
+ return introspectSchema(this._session);
20
+ }
21
+ reconcile(local, remote, options = {}) {
22
+ return reconcileSchemas(local, remote, options);
23
+ }
24
+ async plan(definition, options = {}) {
25
+ const validation = this.validate(definition);
26
+ if (!validation.isValid) {
27
+ throw new MigrationError("Schema validation failed", validation.errors);
28
+ }
29
+ const remote = await this.introspect();
30
+ const { operations, errors } = this.reconcile(definition, remote, options);
31
+ return {
32
+ operations,
33
+ destructive: operations.some((op) => op.type === "DROP"),
34
+ errors,
35
+ };
36
+ }
37
+ async dryRun(definition, options = {}) {
38
+ const { operations, errors, destructive } = await this.plan(definition, options);
39
+ if (errors.length > 0) {
40
+ throw new MigrationError("Schema reconciliation failed", errors);
41
+ }
42
+ if (destructive && !options.destructive) {
43
+ throw new MigrationError("Migration contains destructive operations. Set `destructive: true` in options to allow this.");
44
+ }
45
+ return operations.map((op) => this._print(op.statement));
46
+ }
47
+ async run(definition, options = {}) {
48
+ const { operations, errors, destructive } = await this.plan(definition, options);
49
+ if (errors.length > 0) {
50
+ throw new MigrationError("Schema reconciliation failed", errors);
51
+ }
52
+ const progress = [];
53
+ if (destructive && !options.destructive) {
54
+ throw new MigrationError("Migration contains destructive operations. Set `destructive: true` in options to allow this.");
55
+ }
56
+ for (const op of operations) {
57
+ let result = await this._executor.execute(op);
58
+ if (result.status === "processing" && result.asyncJob) {
59
+ result = await this._executor.waitAsyncJob(result);
60
+ }
61
+ progress.push(result);
62
+ }
63
+ return { count: progress.length, progress };
64
+ }
65
+ }
66
+ export function createMigrationRunner(session) {
67
+ return new MigrationRunner(session);
68
+ }
69
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAoB,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAA4B,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAoB5E,MAAM,OAAO,eAAe;IACT,QAAQ,CAAU;IAClB,MAAM,GAAG,aAAa,EAAE,CAAC;IACzB,SAAS,CAAoB;IAE9C,YAAY,OAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAEM,QAAQ,CAAC,UAA4B;QAC1C,OAAO,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAEM,UAAU;QACf,OAAO,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAEM,SAAS,CACd,KAAuB,EACvB,MAAwB,EACxB,UAAwC,EAAE;QAE1C,OAAO,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAEM,KAAK,CAAC,IAAI,CACf,UAA4B,EAC5B,UAAwC,EAAE;QAE1C,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAE7C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,cAAc,CAAC,0BAA0B,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACvC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAE3E,OAAO;YACL,UAAU;YACV,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC;YACxD,MAAM;SACP,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,UAA4B,EAAE,UAAkC,EAAE;QACpF,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEjF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,cAAc,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,WAAW,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,IAAI,cAAc,CACtB,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QAED,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3D,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,UAA4B,EAAE,UAAkC,EAAE;QACjF,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEjF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,cAAc,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,QAAQ,GAA+B,EAAE,CAAC;QAEhD,IAAI,WAAW,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,IAAI,cAAc,CACtB,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE9C,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtD,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrD,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { DefinitionNode } from "@dsqlbase/core/definition";
2
+ import { SchemaObjectType, SerializedObject, SerializedSchema } from "../base.js";
3
+ export interface ValidationIssue {
4
+ level: "error" | "warning";
5
+ code: string;
6
+ path: string[];
7
+ message: string;
8
+ hint?: string;
9
+ }
10
+ export interface ValidationResult {
11
+ isValid: boolean;
12
+ errors: ValidationIssue[];
13
+ warnings: ValidationIssue[];
14
+ }
15
+ export declare class ValidationContext {
16
+ readonly objects: Map<string, SerializedObject<SchemaObjectType>>;
17
+ readonly namespaces: Set<string>;
18
+ readonly issues: ValidationIssue[];
19
+ constructor(definition: SerializedSchema);
20
+ report(issue: ValidationIssue): void;
21
+ getResults(): ValidationResult;
22
+ }
23
+ export type Rule<T extends DefinitionNode> = (definition: SerializedObject<T>, context: ValidationContext) => void;
24
+ export type GlobalRule = (definition: SerializedSchema, context: ValidationContext) => void;
25
+ export type ValidationRules = {
26
+ [K in SchemaObjectType["kind"]]?: Extract<SchemaObjectType, {
27
+ kind: K;
28
+ }> extends DefinitionNode ? Rule<Extract<SchemaObjectType, {
29
+ kind: K;
30
+ }>>[] : never;
31
+ };
32
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/validation/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAEjC,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAM;gBAE5B,UAAU,EAAE,gBAAgB;IAUjC,MAAM,CAAC,KAAK,EAAE,eAAe;IAIpC,UAAU,IAAI,gBAAgB;CAU/B;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,SAAS,cAAc,IAAI,CAC3C,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,OAAO,EAAE,iBAAiB,KACvB,IAAI,CAAC;AAEV,MAAM,MAAM,UAAU,GAAG,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAE5F,MAAM,MAAM,eAAe,GAAG;KAC3B,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,SAAS,cAAc,GAC3F,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC,EAAE,GAC9C,KAAK;CACV,CAAC"}
@@ -0,0 +1,25 @@
1
+ export class ValidationContext {
2
+ objects;
3
+ namespaces;
4
+ issues = [];
5
+ constructor(definition) {
6
+ this.objects = new Map(definition.map((obj) => [obj.name, obj]));
7
+ this.namespaces = new Set(definition
8
+ .filter((obj) => obj.kind === "SCHEMA")
9
+ .map((schema) => schema.name)
10
+ .concat("public"));
11
+ }
12
+ report(issue) {
13
+ this.issues.push(issue);
14
+ }
15
+ getResults() {
16
+ const errors = this.issues.filter((issue) => issue.level === "error");
17
+ const warnings = this.issues.filter((issue) => issue.level === "warning");
18
+ return {
19
+ isValid: errors.length === 0,
20
+ errors,
21
+ warnings,
22
+ };
23
+ }
24
+ }
25
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/validation/context.ts"],"names":[],"mappings":"AAiBA,MAAM,OAAO,iBAAiB;IACnB,OAAO,CAAkD;IACzD,UAAU,CAAc;IAExB,MAAM,GAAsB,EAAE,CAAC;IAExC,YAAY,UAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CACvB,UAAU;aACP,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC;aACtC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;aAC5B,MAAM,CAAC,QAAQ,CAAC,CACpB,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,KAAsB;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,UAAU;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QAE1E,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;YAC5B,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export type { ValidationContext, ValidationResult, GlobalRule, Rule, ValidationRules, ValidationIssue, } from "./context.js";
2
+ export { defaultRules, globalRules, validateDefinition } from "./validate.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,IAAI,EACJ,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { defaultRules, globalRules, validateDefinition } from "./validate.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { DefinitionNode } from "@dsqlbase/core/definition";
2
+ import { GlobalRule, Rule } from "../context.js";
3
+ export declare const noDuplicateObjectNames: GlobalRule;
4
+ export declare const identifierTooLong: Rule<DefinitionNode>;
5
+ //# sourceMappingURL=global.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../../src/validation/rules/global.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIjD,eAAO,MAAM,sBAAsB,EAAE,UA6BpC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAUlD,CAAC"}
@@ -0,0 +1,35 @@
1
+ const MAX_IDENTIFIER_BYTES = 63;
2
+ export const noDuplicateObjectNames = (definition, context) => {
3
+ const nameByNamespace = new Map(Array.from(context.namespaces.keys()).map((namespace) => [namespace, new Set()]));
4
+ for (const obj of definition) {
5
+ if (obj.kind === "SCHEMA") {
6
+ continue;
7
+ }
8
+ const namespace = obj.namespace ?? "public";
9
+ if (!nameByNamespace.has(namespace)) {
10
+ nameByNamespace.set(namespace, new Set());
11
+ }
12
+ const names = nameByNamespace.get(namespace);
13
+ if (names?.has(obj.name)) {
14
+ context.report({
15
+ level: "error",
16
+ code: "DUPLICATE_OBJECT_NAME",
17
+ message: `Duplicate object name found: ${obj.name} in namespace: ${namespace}`,
18
+ path: [namespace, obj.name],
19
+ });
20
+ }
21
+ names?.add(obj.name);
22
+ }
23
+ };
24
+ export const identifierTooLong = (node, context) => {
25
+ const bytes = Buffer.byteLength(node.name, "utf8");
26
+ if (bytes <= MAX_IDENTIFIER_BYTES)
27
+ return;
28
+ context.report({
29
+ level: "error",
30
+ code: "IDENTIFIER_TOO_LONG",
31
+ message: `Identifier "${node.name}" is ${bytes} bytes; PostgreSQL limits identifiers to ${MAX_IDENTIFIER_BYTES} bytes.`,
32
+ path: [node.name],
33
+ });
34
+ };
35
+ //# sourceMappingURL=global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/validation/rules/global.ts"],"names":[],"mappings":"AAGA,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEhC,MAAM,CAAC,MAAM,sBAAsB,GAAe,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE;IACxE,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,EAAU,CAAC,CAAC,CACzF,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,QAAQ,CAAC;QAE5C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,EAAU,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE7C,IAAI,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,MAAM,CAAC;gBACb,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,gCAAgC,GAAG,CAAC,IAAI,kBAAkB,SAAS,EAAE;gBAC9E,IAAI,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,KAAK,IAAI,oBAAoB;QAAE,OAAO;IAE1C,OAAO,CAAC,MAAM,CAAC;QACb,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,eAAe,IAAI,CAAC,IAAI,QAAQ,KAAK,4CAA4C,oBAAoB,SAAS;QACvH,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;KAClB,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { AnyNamespaceDefinition } from "@dsqlbase/core/definition";
2
+ import { Rule } from "../context.js";
3
+ export declare const reservedNamespace: Rule<AnyNamespaceDefinition>;
4
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/validation/rules/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIrC,eAAO,MAAM,iBAAiB,EAAE,IAAI,CAAC,sBAAsB,CAS1D,CAAC"}
@@ -0,0 +1,12 @@
1
+ const RESERVED_NAMESPACES = new Set(["pg_catalog", "pg_toast", "information_schema", "sys"]);
2
+ export const reservedNamespace = (schema, context) => {
3
+ if (!RESERVED_NAMESPACES.has(schema.name) && !schema.name.startsWith("pg_"))
4
+ return;
5
+ context.report({
6
+ level: "error",
7
+ code: "RESERVED_NAMESPACE",
8
+ message: `Schema name "${schema.name}" is reserved by PostgreSQL.`,
9
+ path: [schema.name],
10
+ });
11
+ };
12
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/validation/rules/schema.ts"],"names":[],"mappings":"AAGA,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC;AAE7F,MAAM,CAAC,MAAM,iBAAiB,GAAiC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;IACjF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO;IAEpF,OAAO,CAAC,MAAM,CAAC;QACb,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,gBAAgB,MAAM,CAAC,IAAI,8BAA8B;QAClE,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;KACpB,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { AnySequenceDefinition } from "@dsqlbase/core/definition";
2
+ import { Rule } from "../context.js";
3
+ export declare const invalidSequenceCache: Rule<AnySequenceDefinition>;
4
+ //# sourceMappingURL=sequence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../../../src/validation/rules/sequence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIrC,eAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC,qBAAqB,CAU5D,CAAC"}
@@ -0,0 +1,13 @@
1
+ const MIN_DSQL_CACHE = 65536;
2
+ export const invalidSequenceCache = (sequence, context) => {
3
+ const cache = sequence.options.cache;
4
+ if (cache === undefined || cache === 1 || cache >= MIN_DSQL_CACHE)
5
+ return;
6
+ context.report({
7
+ level: "error",
8
+ code: "INVALID_SEQUENCE_CACHE",
9
+ message: `Sequence "${sequence.name}" has cache=${cache}; DSQL requires cache=1 or cache >= ${MIN_DSQL_CACHE}.`,
10
+ path: [sequence.namespace, sequence.name],
11
+ });
12
+ };
13
+ //# sourceMappingURL=sequence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequence.js","sourceRoot":"","sources":["../../../src/validation/rules/sequence.ts"],"names":[],"mappings":"AAGA,MAAM,cAAc,GAAG,KAAK,CAAC;AAE7B,MAAM,CAAC,MAAM,oBAAoB,GAAgC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;IACrF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC;IACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,IAAI,cAAc;QAAE,OAAO;IAE1E,OAAO,CAAC,MAAM,CAAC;QACb,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,aAAa,QAAQ,CAAC,IAAI,eAAe,KAAK,uCAAuC,cAAc,GAAG;QAC/G,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC;KAC1C,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { AnyTableDefinition } from "@dsqlbase/core/definition";
2
+ import { Rule } from "../context.js";
3
+ type TableRule = Rule<AnyTableDefinition>;
4
+ export declare const tableNoPrimaryKey: TableRule;
5
+ export declare const unknownColumnReference: TableRule;
6
+ export declare const emptyConstraintColumns: TableRule;
7
+ export declare const tableIdentifiersTooLong: TableRule;
8
+ export declare const redundantUniqueOnPk: TableRule;
9
+ export declare const duplicateIndexCoverage: TableRule;
10
+ export declare const varcharWithoutLength: TableRule;
11
+ export {};
12
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/validation/rules/table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,KAAK,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;AAE1C,eAAO,MAAM,iBAAiB,EAAE,SAa/B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,SAoDpC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,SAapC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,SAYrC,CAAC;AAgBF,eAAO,MAAM,mBAAmB,EAAE,SA4BjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,SAkBpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,SAYlC,CAAC"}