qubu 0.4.0 → 0.4.2

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 (103) hide show
  1. package/dist/{canonical-BbnqavJm.mjs → canonical-BXUguqfo.mjs} +23 -23
  2. package/dist/codegen.d.mts +25 -33
  3. package/dist/codegen.mjs +38 -45
  4. package/dist/column-hqKr7-1I.mjs +620 -0
  5. package/dist/{complete-D5Djh-zo.mjs → complete-WYyVozgK.mjs} +50 -50
  6. package/dist/{complete-types-BavBtv8J.d.mts → complete-types-IjEn5VPN.d.mts} +56 -56
  7. package/dist/core.d.mts +2 -2
  8. package/dist/core.mjs +4 -4
  9. package/dist/ddl.d.mts +12 -12
  10. package/dist/ddl.mjs +13 -14
  11. package/dist/{dialect-b2-Z6uBF.mjs → dialect-wUKrnPMB.mjs} +2 -2
  12. package/dist/diff.d.mts +1 -1
  13. package/dist/diff.mjs +6 -7
  14. package/dist/{index-DH0qV6aS.d.mts → index-1DpA3mUh.d.mts} +20 -20
  15. package/dist/{index-D3ZOwPT-.d.mts → index-CPvfEheG.d.mts} +13 -15
  16. package/dist/index.d.mts +1 -1
  17. package/dist/index.mjs +94 -95
  18. package/dist/introspection.d.mts +8 -8
  19. package/dist/introspection.mjs +29 -30
  20. package/dist/{json-CUZlv4HT.mjs → json-Db7XRD91.mjs} +2 -2
  21. package/dist/migration.d.mts +20 -21
  22. package/dist/migration.mjs +5 -6
  23. package/dist/{mysql-CKEKGnj4.mjs → mysql-B_cYzzX2.mjs} +237 -7
  24. package/dist/mysql.d.mts +2 -2
  25. package/dist/mysql.mjs +3 -3
  26. package/dist/{on-conflict-4MOBl51J.mjs → on-conflict-hfPW0KmQ.mjs} +3 -4
  27. package/dist/postgres.d.mts +5 -5
  28. package/dist/postgres.mjs +6 -6
  29. package/dist/{registry-CXV8u7Pt.mjs → registry-BRMLYwDp.mjs} +26 -29
  30. package/dist/{relational-DuQ9IHSb.mjs → relational-BZ3WDPzC.mjs} +2 -2
  31. package/dist/schema.d.mts +1 -1
  32. package/dist/schema.mjs +5 -6
  33. package/dist/{snapshot-DJpfmxhQ.mjs → snapshot-C-W65HEd.mjs} +5 -5
  34. package/dist/snapshot.d.mts +3 -3
  35. package/dist/snapshot.mjs +5 -7
  36. package/dist/{source-DGO3DRgg.mjs → source-BcS2AsIg.mjs} +6 -8
  37. package/dist/{serialize-CFtYYAdk.mjs → sqlite-Cg0nwYEH.mjs} +326 -12
  38. package/dist/sqlite.d.mts +1 -1
  39. package/dist/sqlite.mjs +2 -2
  40. package/dist/{standard-BTVYKh_F.mjs → standard-DfcZEVOj.mjs} +1 -1
  41. package/dist/{table-D6rcs8SB.mjs → table-Bp5irMSj.mjs} +2 -3
  42. package/dist/{types-Deo_q43Y.d.mts → types-BK1COGZe.d.mts} +1113 -1128
  43. package/dist/{types-g-vVvj1B.mjs → types-JM3FcAnX.mjs} +7 -8
  44. package/dist/{types-CSNJTYaM.d.mts → types-JSZHpUEj.d.mts} +83 -84
  45. package/dist/{value-b6OFZXVS.mjs → value-Bi71Agyf.mjs} +1 -1
  46. package/dist/vite/ambient.d.ts +309 -340
  47. package/dist/vite.d.mts +5 -6
  48. package/dist/vite.mjs +3 -4
  49. package/docs/dialects-and-execution.md +45 -55
  50. package/docs/getting-started.md +4 -4
  51. package/docs/guides/better-auth.md +57 -0
  52. package/docs/guides/compose-queries.md +24 -67
  53. package/docs/guides/drizzle.md +23 -23
  54. package/docs/guides/extensions/dialects.md +4 -4
  55. package/docs/guides/extensions/sources-and-clauses.md +15 -15
  56. package/docs/guides/extensions/typed-expressions.md +13 -17
  57. package/docs/guides/extensions/unsafe-syntax.md +3 -3
  58. package/docs/guides/json.md +7 -7
  59. package/docs/guides/mutations.md +14 -21
  60. package/docs/guides/select/conditions.md +6 -8
  61. package/docs/guides/select/grouping-and-windows.md +4 -15
  62. package/docs/guides/select/ordering-and-pagination.md +6 -19
  63. package/docs/guides/select/overview.md +12 -26
  64. package/docs/guides/sql-templates.md +20 -24
  65. package/docs/guides/vite-plugin.md +9 -13
  66. package/docs/index.md +5 -7
  67. package/docs/query-model/fragments.md +4 -15
  68. package/docs/query-model/result-shapes.md +11 -14
  69. package/docs/query-model/source-scope.md +31 -49
  70. package/docs/reference/mysql-snapshot.md +2 -5
  71. package/docs/reference/postgres-snapshot.md +3 -3
  72. package/docs/reference/sqlite-snapshot.md +2 -5
  73. package/docs/reference/supported-surface.md +26 -26
  74. package/docs/schema/catalog-model.md +2 -5
  75. package/docs/schema/code-generation.md +18 -18
  76. package/docs/schema/columns-and-writes.md +17 -25
  77. package/docs/schema/constraints-and-indexes.md +36 -52
  78. package/docs/schema/ddl-emission.md +6 -6
  79. package/docs/schema/diff.md +5 -5
  80. package/docs/schema/introspection.md +7 -7
  81. package/docs/schema/migration-plans.md +9 -9
  82. package/docs/schema/snapshots.md +3 -3
  83. package/docs/schema/storage-and-schema-sql.md +11 -11
  84. package/docs/schema/tables-and-names.md +11 -14
  85. package/docs/sql-semantic-types.md +10 -10
  86. package/docs/troubleshooting.md +10 -10
  87. package/package.json +21 -33
  88. package/skills/qubu/agents/openai.yaml +3 -3
  89. package/dist/column-D-8OqGuV.mjs +0 -328
  90. package/dist/column-LV7oGQde.mjs +0 -296
  91. package/dist/drizzle-mysql.d.mts +0 -24
  92. package/dist/drizzle-mysql.mjs +0 -72
  93. package/dist/drizzle-postgres.d.mts +0 -24
  94. package/dist/drizzle-postgres.mjs +0 -73
  95. package/dist/drizzle-sqlite.d.mts +0 -57
  96. package/dist/drizzle-sqlite.mjs +0 -108
  97. package/dist/drizzle.d.mts +0 -13
  98. package/dist/drizzle.mjs +0 -2
  99. package/dist/errors-BGCoLe_r.mjs +0 -14
  100. package/dist/postgres-BK2APkKP.mjs +0 -236
  101. package/dist/runtime-Cn_Xgzta.mjs +0 -193
  102. package/dist/sqlite-CrsK0Fza.mjs +0 -320
  103. package/dist/types-DZsueVoI.d.mts +0 -45
@@ -1,12 +1,12 @@
1
- import { a as toSnapshotJsonValue } from "./canonical-BbnqavJm.mjs";
2
- import { a as hasIntrospectionErrors, i as createIntrospectionDiagnostic, n as introspectedPhysicalIdentityPolicy, r as IntrospectionError, t as mapCatalogToSnapshot } from "./snapshot-DJpfmxhQ.mjs";
3
- import { n as assertCompleteSchemaSnapshot } from "./complete-D5Djh-zo.mjs";
1
+ import { a as toSnapshotJsonValue } from "./canonical-BXUguqfo.mjs";
2
+ import { a as hasIntrospectionErrors, i as createIntrospectionDiagnostic, n as introspectedPhysicalIdentityPolicy, r as IntrospectionError, t as mapCatalogToSnapshot } from "./snapshot-C-W65HEd.mjs";
3
+ import { n as assertCompleteSchemaSnapshot } from "./complete-WYyVozgK.mjs";
4
4
  import "./snapshot.mjs";
5
5
  //#region src/introspection/catalog.ts
6
6
  /**
7
- * Materialize every optional object-family collection and deeply freeze the
8
- * normalized catalog. Catalog text and extension data remain values; this
9
- * helper never evaluates SQL or assigns persisted logical identities.
7
+ * Materialize every optional object-family collection and deeply freeze the normalized catalog.
8
+ * Catalog text and extension data remain values; this helper never evaluates SQL or assigns
9
+ * persisted logical identities.
10
10
  */
11
11
  function createCompleteIntrospectionCatalog(catalog) {
12
12
  return deepFreeze({
@@ -64,10 +64,9 @@ function compareColumn(left, right) {
64
64
  return left.ordinalPosition - right.ordinalPosition || compareId$1(left, right);
65
65
  }
66
66
  /**
67
- * Freeze nested catalog values without imposing JSON semantics on bigint or
68
- * opaque driver values. The normalized contract is expected to contain plain
69
- * records, arrays, and scalar values; unsupported prototypes are retained but
70
- * still frozen so the operation remains non-destructive.
67
+ * Freeze nested catalog values without imposing JSON semantics on bigint or opaque driver values.
68
+ * The normalized contract is expected to contain plain records, arrays, and scalar values;
69
+ * unsupported prototypes are retained but still frozen so the operation remains non-destructive.
71
70
  */
72
71
  function deepFreeze(value, seen = /* @__PURE__ */ new WeakSet()) {
73
72
  if (value === null || typeof value !== "object") return value;
@@ -80,9 +79,9 @@ function deepFreeze(value, seen = /* @__PURE__ */ new WeakSet()) {
80
79
  //#endregion
81
80
  //#region src/introspection/complete-snapshot.ts
82
81
  /**
83
- * Map a normalized catalog to strict Snapshot v2 data. This is intentionally
84
- * separate from the Snapshot v1 mapper: complete objects are never fabricated
85
- * as tables, and catalog references remain evidence rather than logical IDs.
82
+ * Map a normalized catalog to strict Snapshot v2 data. This is intentionally separate from the
83
+ * Snapshot v1 mapper: complete objects are never fabricated as tables, and catalog references
84
+ * remain evidence rather than logical IDs.
86
85
  */
87
86
  function mapCatalogToCompleteSnapshot(input) {
88
87
  const catalog = createCompleteIntrospectionCatalog(input);
@@ -1288,7 +1287,7 @@ function constraints(table, rows, tableByName, namespace, diagnostics) {
1288
1287
  function mapIndex(rows, table, namespace, diagnostics) {
1289
1288
  const first = rows[0];
1290
1289
  const physicalName = text$2(first.index_name);
1291
- if (!physicalName) return void 0;
1290
+ if (!physicalName) return;
1292
1291
  const terms = [];
1293
1292
  for (const row of rows) {
1294
1293
  const expression = text$2(row.expression);
@@ -1750,7 +1749,7 @@ function reference$2(kind, name, namespace, relation, key, value = name) {
1750
1749
  };
1751
1750
  }
1752
1751
  function literal(value, dataType) {
1753
- if (value === void 0) return void 0;
1752
+ if (value === void 0) return;
1754
1753
  if (value.toUpperCase() === "NULL") return null;
1755
1754
  if (value.toUpperCase() === "TRUE") return true;
1756
1755
  if (value.toUpperCase() === "FALSE") return false;
@@ -2825,11 +2824,11 @@ function storage(value) {
2825
2824
  return { nativeType: text$1(value) ?? "unknown" };
2826
2825
  }
2827
2826
  function factIfPresent(value) {
2828
- if (value === void 0 || value === null) return void 0;
2827
+ if (value === void 0 || value === null) return;
2829
2828
  return literalFact(value);
2830
2829
  }
2831
2830
  function literalFact(value) {
2832
- if (value === void 0) return void 0;
2831
+ if (value === void 0) return;
2833
2832
  if (value === null) return {
2834
2833
  kind: "literal",
2835
2834
  value: null
@@ -2994,7 +2993,7 @@ function constraint(row, table, columnsByNumber, tableByOid, namespace, diagnost
2994
2993
  ...common,
2995
2994
  expression: sql$1(text$1(row.definition) ?? "CHECK (true)", namespace, table, physicalName)
2996
2995
  };
2997
- if (kind !== "f") return void 0;
2996
+ if (kind !== "f") return;
2998
2997
  const targetTable = tableByOid.get(text$1(row.target_table_oid));
2999
2998
  if (!targetTable) {
3000
2999
  diagnostics.push(createIntrospectionDiagnostic({
@@ -3337,7 +3336,7 @@ function stringArray(value) {
3337
3336
  }
3338
3337
  function booleanOption(options, name) {
3339
3338
  const value = options.find((option) => option.startsWith(`${name}=`));
3340
- if (value === void 0) return void 0;
3339
+ if (value === void 0) return;
3341
3340
  const setting = value.slice(name.length + 1).toLowerCase();
3342
3341
  if (setting === "true" || setting === "on" || setting === "yes") return true;
3343
3342
  if (setting === "false" || setting === "off" || setting === "no") return false;
@@ -3703,7 +3702,7 @@ function sqliteView(row, sqlText, namespace, diagnostics) {
3703
3702
  };
3704
3703
  }
3705
3704
  function viewDefinition(sqlText) {
3706
- if (!sqlText) return void 0;
3705
+ if (!sqlText) return;
3707
3706
  return sqlText.match(/\bAS\b([\s\S]*)$/i)?.[1]?.trim().replace(/;\s*$/, "") || void 0;
3708
3707
  }
3709
3708
  function attachedDatabaseObject(row, selectedNamespace) {
@@ -3841,7 +3840,7 @@ function triggerCondition(sqlText, _onIndex, beginIndex) {
3841
3840
  return sqlText.slice(0, beginIndex).match(/\bWHEN\s+([\s\S]+)$/i)?.[1]?.trim();
3842
3841
  }
3843
3842
  function unquoteIdentifier(value) {
3844
- if (!value) return void 0;
3843
+ if (!value) return;
3845
3844
  const trimmed = value.trim();
3846
3845
  if (trimmed.length < 2) return trimmed;
3847
3846
  if (trimmed.startsWith("\"") && trimmed.endsWith("\"") || trimmed.startsWith("`") && trimmed.endsWith("`")) return trimmed.slice(1, -1).replace(/(""|``)/g, (match) => match[0]);
@@ -3864,11 +3863,11 @@ function sqliteExtension(data) {
3864
3863
  };
3865
3864
  }
3866
3865
  function indexExpressionFor(sqlText, position) {
3867
- if (!sqlText) return void 0;
3866
+ if (!sqlText) return;
3868
3867
  const open = sqlText.indexOf("(", sqlText.search(/\bON\b/i));
3869
- if (open < 0) return void 0;
3868
+ if (open < 0) return;
3870
3869
  const close = matchingParen(sqlText, open);
3871
- if (close < 0) return void 0;
3870
+ if (close < 0) return;
3872
3871
  const term = splitSqlList(sqlText.slice(open + 1, close))[position]?.trim();
3873
3872
  return term && !isSimpleIdentifier(term) ? term : void 0;
3874
3873
  }
@@ -4110,7 +4109,7 @@ function tableConstraints(table, rows, columns, sqlText, namespace) {
4110
4109
  }
4111
4110
  function sqliteIndex(table, row, infoRows, sqlText, namespace, diagnostics, opaqueObjects) {
4112
4111
  const physicalName = text(row.name);
4113
- if (!physicalName) return void 0;
4112
+ if (!physicalName) return;
4114
4113
  const terms = [];
4115
4114
  const collations = [];
4116
4115
  for (const info of infoRows.filter((item) => boolean(item.key))) {
@@ -4237,19 +4236,19 @@ function partialPredicate(sqlText, indexName, namespace, table) {
4237
4236
  return predicate ? sql(predicate, namespace, table, indexName) : void 0;
4238
4237
  }
4239
4238
  function generatedExpressionFor(sqlText, columnName) {
4240
- if (!sqlText) return void 0;
4239
+ if (!sqlText) return;
4241
4240
  const open = sqlText.indexOf("(");
4242
- if (open < 0) return void 0;
4241
+ if (open < 0) return;
4243
4242
  const close = matchingParen(sqlText, open);
4244
- if (close < 0) return void 0;
4243
+ if (close < 0) return;
4245
4244
  const definitions = splitSqlList(sqlText.slice(open + 1, close));
4246
4245
  for (const definition of definitions) {
4247
4246
  const identifier = definition.trim().match(/^("(?:[^"]|"")*"|`[^`]*`|\[[^\]]*\]|[A-Za-z_][A-Za-z0-9_$]*)/)?.[1];
4248
4247
  if (unquoteIdentifier(identifier) !== columnName) continue;
4249
4248
  const generated = definition.match(/\bAS\s*\(/i);
4250
- if (!generated || generated.index === void 0) return void 0;
4249
+ if (!generated || generated.index === void 0) return;
4251
4250
  const generatedOpen = definition.indexOf("(", generated.index);
4252
- if (generatedOpen < 0) return void 0;
4251
+ if (generatedOpen < 0) return;
4253
4252
  const generatedClose = matchingParen(definition, generatedOpen);
4254
4253
  return generatedClose < 0 ? void 0 : definition.slice(generatedOpen + 1, generatedClose).trim();
4255
4254
  }
@@ -32,8 +32,8 @@ function createDialect(options) {
32
32
  });
33
33
  }
34
34
  /**
35
- * Check a capability at runtime for callers that intentionally bypass the
36
- * typed render boundary or use a dialect supplied by an older integration.
35
+ * Check a capability at runtime for callers that intentionally bypass the typed render boundary or
36
+ * use a dialect supplied by an older integration.
37
37
  */
38
38
  function assertDialectCapability(dialect, capability) {
39
39
  if (dialect.capabilities?.includes(capability)) return;
@@ -1,25 +1,25 @@
1
- import { T as SnapshotJsonValue, m as SnapshotDialect } from "./types-Deo_q43Y.mjs";
2
- import { S as SnapshotDiffPath, _ as SnapshotDiffObjectKind, b as SnapshotDiffOperationType, f as SnapshotDiffDiagnostic, g as SnapshotDiffObject, m as SnapshotDiffEvidence, u as SnapshotDiff } from "./index-D3ZOwPT-.mjs";
1
+ import { T as SnapshotJsonValue, m as SnapshotDialect } from "./types-BK1COGZe.mjs";
2
+ import { S as SnapshotDiffPath, _ as SnapshotDiffObjectKind, b as SnapshotDiffOperationType, f as SnapshotDiffDiagnostic, g as SnapshotDiffObject, m as SnapshotDiffEvidence, u as SnapshotDiff } from "./index-CPvfEheG.mjs";
3
3
  //#region src/migration/types.d.ts
4
4
  /** The versioned envelope tag for dialect-neutral migration plans. */
5
5
  declare const migrationPlanFormat: "qubu-migration-plan";
6
6
  /** The first strict migration-plan format version. */
7
7
  declare const migrationPlanVersion: 1;
8
8
  /** Safety classifications carried by every planned operation. */
9
- type MigrationSafety = 'safe' | 'review-required' | 'destructive' | 'unsupported' | 'unknown';
9
+ type MigrationSafety = "safe" | "review-required" | "destructive" | "unsupported" | "unknown";
10
10
  /** Lock strength required by a planned operation. */
11
- type MigrationLockRequirement = 'none' | 'shared' | 'exclusive' | 'unknown';
11
+ type MigrationLockRequirement = "none" | "shared" | "exclusive" | "unknown";
12
12
  /** Transaction behavior required by a planned operation. */
13
- type MigrationTransactionRequirement = 'required' | 'optional' | 'forbidden' | 'unknown';
13
+ type MigrationTransactionRequirement = "required" | "optional" | "forbidden" | "unknown";
14
14
  /** Operations that can appear in a migration plan. */
15
- type MigrationOperationType = 'add' | 'remove' | 'property-change' | 'physical-rename' | 'custom-sql';
15
+ type MigrationOperationType = "add" | "remove" | "property-change" | "physical-rename" | "custom-sql";
16
16
  /** A condition a later executor must check before applying an operation. */
17
- type MigrationPreconditionType = 'snapshot-digest' | 'object-present' | 'object-absent' | 'property-equals';
17
+ type MigrationPreconditionType = "snapshot-digest" | "object-present" | "object-absent" | "property-equals";
18
18
  /** An immutable, serializable migration precondition. */
19
19
  interface MigrationPrecondition {
20
20
  readonly type: MigrationPreconditionType;
21
21
  readonly path: SnapshotDiffPath;
22
- readonly kind: SnapshotDiffObjectKind | 'custom-sql';
22
+ readonly kind: SnapshotDiffObjectKind | "custom-sql";
23
23
  readonly namespace?: string;
24
24
  readonly logicalId?: string;
25
25
  readonly physicalName?: string;
@@ -55,7 +55,7 @@ interface MigrationCustomSqlInput {
55
55
  }
56
56
  /** A user's explicit decision for an unsafe or incomplete fact. */
57
57
  interface MigrationDecision {
58
- readonly action: 'allow' | 'skip';
58
+ readonly action: "allow" | "skip";
59
59
  readonly reason: string;
60
60
  readonly operationId?: string;
61
61
  readonly kind?: SnapshotDiffObjectKind;
@@ -64,15 +64,15 @@ interface MigrationDecision {
64
64
  readonly code?: MigrationDiagnosticCode;
65
65
  }
66
66
  /** Why a plan was blocked or needs review. */
67
- type MigrationDiagnosticCode = 'decision-required' | 'dependency-cycle' | 'invalid-plan' | 'unknown' | 'lossy' | 'unsupported' | 'destructive' | 'ambiguous' | 'custom-sql' | 'dialect-mismatch' | 'non-canonical';
67
+ type MigrationDiagnosticCode = "decision-required" | "dependency-cycle" | "invalid-plan" | "unknown" | "lossy" | "unsupported" | "destructive" | "ambiguous" | "custom-sql" | "dialect-mismatch" | "non-canonical";
68
68
  /** A structured plan diagnostic that keeps source diff context. */
69
69
  interface MigrationDiagnostic {
70
70
  readonly code: MigrationDiagnosticCode;
71
- readonly severity: 'error' | 'warning';
71
+ readonly severity: "error" | "warning";
72
72
  readonly message: string;
73
73
  readonly path: SnapshotDiffPath;
74
74
  readonly operationId?: string;
75
- readonly kind?: SnapshotDiffObjectKind | 'custom-sql';
75
+ readonly kind?: SnapshotDiffObjectKind | "custom-sql";
76
76
  readonly namespace?: string;
77
77
  readonly logicalId?: string;
78
78
  readonly physicalName?: string;
@@ -98,8 +98,8 @@ interface MigrationOperationOrigin {
98
98
  interface MigrationOperation {
99
99
  readonly id: string;
100
100
  readonly type: MigrationOperationType;
101
- readonly kind: SnapshotDiffObjectKind | 'custom-sql';
102
- readonly objectKind: SnapshotDiffObjectKind | 'custom-sql';
101
+ readonly kind: SnapshotDiffObjectKind | "custom-sql";
102
+ readonly objectKind: SnapshotDiffObjectKind | "custom-sql";
103
103
  readonly namespace?: string;
104
104
  readonly path: SnapshotDiffPath;
105
105
  readonly logicalId?: string;
@@ -111,7 +111,7 @@ interface MigrationOperation {
111
111
  readonly lock: MigrationLockRequirement;
112
112
  readonly transaction: MigrationTransactionRequirement;
113
113
  readonly reversible: boolean;
114
- readonly reversibility: 'reversible' | 'irreversible';
114
+ readonly reversibility: "reversible" | "irreversible";
115
115
  readonly irreversibleReason?: string;
116
116
  readonly preconditions: readonly MigrationPrecondition[];
117
117
  readonly dependsOn: readonly string[];
@@ -119,14 +119,14 @@ interface MigrationOperation {
119
119
  readonly origin?: MigrationOperationOrigin;
120
120
  readonly customSql?: MigrationCustomSql;
121
121
  readonly decision?: MigrationDecision;
122
- readonly status: 'approved' | 'decision-required' | 'skipped';
122
+ readonly status: "approved" | "decision-required" | "skipped";
123
123
  readonly position: number;
124
124
  }
125
125
  /** A dependency edge. `from` must appear before `to`. */
126
126
  interface MigrationDependency {
127
127
  readonly from: string;
128
128
  readonly to: string;
129
- readonly reason: 'parent-before-child' | 'child-before-parent' | 'reference-before-dependent' | 'explicit-custom-sql';
129
+ readonly reason: "parent-before-child" | "child-before-parent" | "reference-before-dependent" | "explicit-custom-sql";
130
130
  }
131
131
  /** Immutable migration plan data. It contains no executor or SQL renderer. */
132
132
  interface MigrationPlan {
@@ -184,10 +184,9 @@ declare class MigrationPlanValidationError extends TypeError {
184
184
  /**
185
185
  * Convert a resolved SnapshotDiff into an immutable migration plan.
186
186
  *
187
- * This function only describes operations. It does not render SQL, open a
188
- * connection, execute a transaction, or infer SQL from opaque snapshot data.
189
- * A plan that still needs a safety decision is returned with `ok: false` so it
190
- * can be reviewed without being mistaken for an executable plan.
187
+ * This function only describes operations. It does not render SQL, open a connection, execute a
188
+ * transaction, or infer SQL from opaque snapshot data. A plan that still needs a safety decision is
189
+ * returned with `ok: false` so it can be reviewed without being mistaken for an executable plan.
191
190
  */
192
191
  declare function createMigrationPlan(diff: SnapshotDiff, options?: MigrationPlanOptions): MigrationPlanResult;
193
192
  /** Alias for callers that treat plan creation as the main migration action. */
@@ -1,4 +1,4 @@
1
- import { a as toSnapshotJsonValue, n as canonicalJson } from "./canonical-BbnqavJm.mjs";
1
+ import { a as toSnapshotJsonValue, n as canonicalJson } from "./canonical-BXUguqfo.mjs";
2
2
  //#region src/migration/types.ts
3
3
  /** The versioned envelope tag for dialect-neutral migration plans. */
4
4
  const migrationPlanFormat = "qubu-migration-plan";
@@ -82,10 +82,9 @@ const safetyRank = {
82
82
  /**
83
83
  * Convert a resolved SnapshotDiff into an immutable migration plan.
84
84
  *
85
- * This function only describes operations. It does not render SQL, open a
86
- * connection, execute a transaction, or infer SQL from opaque snapshot data.
87
- * A plan that still needs a safety decision is returned with `ok: false` so it
88
- * can be reviewed without being mistaken for an executable plan.
85
+ * This function only describes operations. It does not render SQL, open a connection, execute a
86
+ * transaction, or infer SQL from opaque snapshot data. A plan that still needs a safety decision is
87
+ * returned with `ok: false` so it can be reviewed without being mistaken for an executable plan.
89
88
  */
90
89
  function createMigrationPlan(diff, options = {}) {
91
90
  const diagnostics = [];
@@ -513,7 +512,7 @@ function findDecision(context, decisions, diagnostics, options) {
513
512
  if (direct !== void 0) return direct;
514
513
  const relevantCode = diagnostics.find((diagnostic) => pathRelated(diagnostic.path, context.operation.path))?.code;
515
514
  if (relevantCode !== void 0) return decisions.find((decision) => decision.code === mapDiffCode(relevantCode));
516
- if (optionAllows(context.operation.safety, options)) return void 0;
515
+ if (optionAllows(context.operation.safety, options)) return;
517
516
  }
518
517
  function requireDecisionsForUnmatchedDiagnostics(diagnostics, contexts, decisions, options, planDiagnostics) {
519
518
  for (const source of diagnostics) {
@@ -1,9 +1,239 @@
1
- import { d as isValidSchemaObjectName, r as isColumnReference } from "./column-D-8OqGuV.mjs";
2
- import { _ as isUnsafeSchemaSql, m as validateConstraintDialect, w as validateIndexDialect, y as renderSchemaExpression } from "./registry-CXV8u7Pt.mjs";
3
- import { t as createSchemaDialect } from "./dialect-b2-Z6uBF.mjs";
4
- import { a as toSnapshotJsonValue } from "./canonical-BbnqavJm.mjs";
5
- import { n as createSchemaSnapshot, s as tryCreateSchemaSnapshot } from "./serialize-CFtYYAdk.mjs";
1
+ import { P as isValidSchemaObjectName, r as isColumnReference } from "./column-hqKr7-1I.mjs";
2
+ import { _ as isUnsafeSchemaSql, m as validateConstraintDialect, w as validateIndexDialect, y as renderSchemaExpression } from "./registry-BRMLYwDp.mjs";
3
+ import { t as createSchemaDialect } from "./dialect-wUKrnPMB.mjs";
4
+ import { a as toSnapshotJsonValue } from "./canonical-BXUguqfo.mjs";
5
+ import { c as createSchemaSnapshot, p as tryCreateSchemaSnapshot } from "./sqlite-Cg0nwYEH.mjs";
6
+ import { postgresDialect } from "./postgres.mjs";
6
7
  import { mysqlDialect } from "./mysql.mjs";
8
+ //#region src/snapshot/postgres.ts
9
+ /** PostgreSQL's v1 snapshot extension identity. */
10
+ const postgresSnapshotDialect = Object.freeze({
11
+ name: "postgresql",
12
+ version: 1
13
+ });
14
+ var PostgresSnapshotDialectError = class extends TypeError {
15
+ code = "dialect-mismatch";
16
+ };
17
+ const postgresStorageTypes = Object.freeze({
18
+ integer: "INTEGER",
19
+ numeric: "NUMERIC",
20
+ text: "TEXT",
21
+ boolean: "BOOLEAN",
22
+ date: "DATE",
23
+ timestamp: "TIMESTAMP",
24
+ uuid: "UUID",
25
+ json: "JSONB",
26
+ bigint: "BIGINT",
27
+ binary: "BYTEA"
28
+ });
29
+ /** PostgreSQL's query dialect plus its schema metadata behavior. */
30
+ const postgresSchemaDialect = createSchemaDialect(postgresDialect(), {
31
+ version: 1,
32
+ validate: validatePostgresSchema,
33
+ encodeStorage(storage, context) {
34
+ return encodePostgresStorage(storage, context.dialect);
35
+ },
36
+ encodeExpression(expression, context) {
37
+ return encodePostgresExpression(expression, context.mode, context.dialect);
38
+ },
39
+ encodeDialectExtension(extension, context) {
40
+ return encodePostgresExtension(extension, context.dialect);
41
+ }
42
+ });
43
+ /** Snapshot adapter retaining the historical adapter-shaped entry point. */
44
+ const postgresSnapshotAdapter = Object.freeze({ dialect: postgresSchemaDialect });
45
+ /** Create a canonical PostgreSQL schema snapshot. */
46
+ function createPostgresSchemaSnapshot(schema, options = {}) {
47
+ return createSchemaSnapshot(schema, {
48
+ ...options,
49
+ adapter: postgresSnapshotAdapter
50
+ });
51
+ }
52
+ /** Return PostgreSQL capability diagnostics without throwing. */
53
+ function tryCreatePostgresSchemaSnapshot(schema, options = {}) {
54
+ return tryCreateSchemaSnapshot(schema, {
55
+ ...options,
56
+ adapter: postgresSnapshotAdapter
57
+ });
58
+ }
59
+ function encodePostgresStorage(storage, dialect) {
60
+ if (storage.kind === "native") {
61
+ if (storage.dialect !== dialect.name) throw new TypeError(`PostgreSQL storage cannot encode a native declaration owned by "${storage.dialect}"`);
62
+ if (storage.type.trim().length === 0) throw new TypeError("PostgreSQL native storage declarations cannot be empty");
63
+ return {
64
+ kind: "native",
65
+ dialect: dialect.name,
66
+ type: storage.type
67
+ };
68
+ }
69
+ const type = postgresStorageTypes[storage.type];
70
+ if (type === void 0) throw new TypeError(`Unsupported portable storage type for PostgreSQL: ${String(storage.type)}`);
71
+ return {
72
+ kind: "native",
73
+ dialect: dialect.name,
74
+ type
75
+ };
76
+ }
77
+ function encodePostgresExpression(expression, mode, dialect) {
78
+ if (isUnsafeSchemaSql(expression) && expression.schemaSqlDialect !== dialect.name) throw new PostgresSnapshotDialectError(`Schema SQL is tagged for "${expression.schemaSqlDialect}" but the PostgreSQL schema dialect is "${dialect.name}"`);
79
+ const rendered = renderSchemaExpression(expression, {
80
+ mode,
81
+ dialect
82
+ });
83
+ if (rendered.parameters.length !== 0) throw new TypeError("PostgreSQL schema expressions must be parameter-free");
84
+ return {
85
+ kind: "expression",
86
+ expressionKind: expression.expressionKind,
87
+ sql: rendered.text,
88
+ ...isUnsafeSchemaSql(expression) ? { dialect: dialect.name } : {}
89
+ };
90
+ }
91
+ function encodePostgresExtension(extension, dialect) {
92
+ if (extension.dialect !== dialect.name) throw new TypeError(`PostgreSQL schema extensions require dialect "${dialect.name}"`);
93
+ const data = Object.fromEntries(Object.entries(extension).filter(([key]) => key !== "dialect").sort(([left], [right]) => left.localeCompare(right)));
94
+ return {
95
+ dialect: dialect.name,
96
+ version: dialect.schema.version,
97
+ data: sortSnapshotJson$1(toSnapshotJsonValue(data))
98
+ };
99
+ }
100
+ function sortSnapshotJson$1(value) {
101
+ if (Array.isArray(value)) return value.map(sortSnapshotJson$1);
102
+ if (typeof value !== "object" || value === null) return value;
103
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortSnapshotJson$1(child)]));
104
+ }
105
+ function validatePostgresSchema(schema, context) {
106
+ const diagnostics = [];
107
+ const tableEntries = Object.entries(schema.registry).sort(([left], [right]) => compareIds$1(left, right));
108
+ const relationNames = /* @__PURE__ */ new Map();
109
+ if (schema.namespace !== void 0) validatePostgresName(schema.namespace, ["namespace"], "PostgreSQL namespace", diagnostics);
110
+ for (const [id, entry] of tableEntries) {
111
+ const tablePath = ["tables", id];
112
+ validatePostgresName(entry.physicalName, [...tablePath, "physicalName"], "PostgreSQL table", diagnostics);
113
+ addRelationName(relationNames, entry.physicalName, [...tablePath, "physicalName"], "table", diagnostics);
114
+ }
115
+ for (const [id, entry] of tableEntries) validatePostgresTable(id, entry, context, relationNames, diagnostics);
116
+ return Object.freeze(diagnostics);
117
+ }
118
+ function validatePostgresTable(tableId, entry, context, relationNames, diagnostics) {
119
+ const table = entry.table;
120
+ const tablePath = ["tables", tableId];
121
+ const definitions = table.definitions;
122
+ for (const [columnId, definition] of Object.entries(definitions).sort(([left], [right]) => compareIds$1(left, right))) {
123
+ validatePostgresName(table.sqlNames[columnId] ?? columnId, [
124
+ ...tablePath,
125
+ "columns",
126
+ columnId,
127
+ "physicalName"
128
+ ], "PostgreSQL column", diagnostics);
129
+ if (definition.onUpdate !== void 0) diagnostics.push({
130
+ code: "unsupported-dialect-option",
131
+ message: "MySQL ON UPDATE expressions are not supported by PostgreSQL",
132
+ path: [
133
+ ...tablePath,
134
+ "columns",
135
+ columnId,
136
+ "onUpdate"
137
+ ]
138
+ });
139
+ const generated = definition.generatedColumn;
140
+ if (generated !== void 0 && generated.kind === "expression" && generated.mode === "virtual") diagnostics.push({
141
+ code: "unsupported-dialect-option",
142
+ message: "PostgreSQL v1 snapshots support stored generated columns only; virtual generated columns are not supported",
143
+ path: [
144
+ ...tablePath,
145
+ "columns",
146
+ columnId,
147
+ "generatedColumn",
148
+ "mode"
149
+ ]
150
+ });
151
+ }
152
+ const metadata = table;
153
+ const constraintNames = /* @__PURE__ */ new Map();
154
+ const constraints = Object.entries(metadata.constraints);
155
+ for (const [constraintId, constraint] of constraints.sort(([left], [right]) => compareIds$1(left, right))) {
156
+ const constraintPath = [
157
+ ...tablePath,
158
+ "constraints",
159
+ constraintId
160
+ ];
161
+ const physicalName = constraint.physicalName ?? constraintId;
162
+ validatePostgresName(physicalName, [...constraintPath, "physicalName"], "PostgreSQL constraint", diagnostics);
163
+ addScopedName$1(constraintNames, physicalName, [...constraintPath, "physicalName"], "constraint", diagnostics);
164
+ appendMetadataDiagnostics$1(diagnostics, validateConstraintDialect(constraint, context.dialect.name, constraintPath));
165
+ if (constraint.kind === "check" && constraint.deferrable === true) diagnostics.push({
166
+ code: "unsupported-dialect-option",
167
+ message: "PostgreSQL CHECK constraints cannot be DEFERRABLE",
168
+ path: [...constraintPath, "deferrable"]
169
+ });
170
+ if (constraint.kind === "foreign-key" && constraint.match === "partial") diagnostics.push({
171
+ code: "unsupported-dialect-option",
172
+ message: "PostgreSQL does not implement MATCH PARTIAL foreign keys",
173
+ path: [...constraintPath, "match"]
174
+ });
175
+ if (constraint.kind === "unique-constraint" && constraint.nulls === "not-distinct") diagnostics.push({
176
+ code: "unsupported-dialect-option",
177
+ message: "PostgreSQL NULLS NOT DISTINCT requires a server-version policy; the v1 adapter does not assume PostgreSQL 15 or newer",
178
+ path: [...constraintPath, "nulls"]
179
+ });
180
+ }
181
+ const indexes = Object.entries(metadata.indexes);
182
+ for (const [indexId, index] of indexes.sort(([left], [right]) => compareIds$1(left, right))) {
183
+ const indexPath = [
184
+ ...tablePath,
185
+ "indexes",
186
+ indexId
187
+ ];
188
+ const physicalName = index.physicalName ?? indexId;
189
+ validatePostgresName(physicalName, [...indexPath, "physicalName"], "PostgreSQL index", diagnostics);
190
+ addRelationName(relationNames, physicalName, [...indexPath, "physicalName"], "index", diagnostics);
191
+ appendMetadataDiagnostics$1(diagnostics, validateIndexDialect(index, context.dialect.name, indexPath));
192
+ }
193
+ }
194
+ function validatePostgresName(name, path, kind, diagnostics) {
195
+ if (!isValidSchemaObjectName(name) || name.length === 0) diagnostics.push({
196
+ code: "invalid-schema",
197
+ message: `${kind} name "${name}" is not a valid unqualified identifier`,
198
+ path
199
+ });
200
+ if (new TextEncoder().encode(name).length > 63) diagnostics.push({
201
+ code: "unsupported-dialect-option",
202
+ message: `${kind} name exceeds PostgreSQL's 63-byte identifier limit`,
203
+ path
204
+ });
205
+ }
206
+ function addRelationName(names, name, path, kind, diagnostics) {
207
+ addScopedName$1(names, name, path, kind, diagnostics);
208
+ }
209
+ function addScopedName$1(names, name, path, kind, diagnostics) {
210
+ const previousPath = names.get(name);
211
+ if (previousPath !== void 0) {
212
+ diagnostics.push({
213
+ code: "invalid-schema",
214
+ message: `PostgreSQL ${kind} name "${name}" collides with another relation or metadata object`,
215
+ path,
216
+ relatedPaths: [previousPath]
217
+ });
218
+ return;
219
+ }
220
+ names.set(name, path);
221
+ }
222
+ function appendMetadataDiagnostics$1(diagnostics, issues) {
223
+ for (const issue of issues) {
224
+ if (issue.code === "dialect-mismatch") continue;
225
+ diagnostics.push({
226
+ code: issue.code === "unsupported-dialect-option" ? "unsupported-dialect-option" : "invalid-schema",
227
+ message: issue.message,
228
+ path: issue.path,
229
+ ...issue.relatedPaths === void 0 ? {} : { relatedPaths: issue.relatedPaths }
230
+ });
231
+ }
232
+ }
233
+ function compareIds$1(left, right) {
234
+ return left < right ? -1 : left > right ? 1 : 0;
235
+ }
236
+ //#endregion
7
237
  //#region src/snapshot/mysql.ts
8
238
  /** MySQL's v1 snapshot extension identity. */
9
239
  const mysqlSnapshotDialect = Object.freeze({
@@ -293,7 +523,7 @@ function validateMysqlAutoIncrement(columnId, definition, metadata, columnPath,
293
523
  });
294
524
  }
295
525
  function mysqlDeclaration(storage) {
296
- if (storage === void 0) return void 0;
526
+ if (storage === void 0) return;
297
527
  return storage.kind === "native" ? storage.type : mysqlStorageTypes[storage.type];
298
528
  }
299
529
  function isMysqlIntegerDeclaration(declaration) {
@@ -352,4 +582,4 @@ function compareIds(left, right) {
352
582
  return left < right ? -1 : left > right ? 1 : 0;
353
583
  }
354
584
  //#endregion
355
- export { tryCreateMysqlSchemaSnapshot as a, mysqlSnapshotDialect as i, mysqlSchemaDialect as n, mysqlSnapshotAdapter as r, createMysqlSchemaSnapshot as t };
585
+ export { tryCreateMysqlSchemaSnapshot as a, postgresSnapshotAdapter as c, mysqlSnapshotDialect as i, postgresSnapshotDialect as l, mysqlSchemaDialect as n, createPostgresSchemaSnapshot as o, mysqlSnapshotAdapter as r, postgresSchemaDialect as s, createMysqlSchemaSnapshot as t, tryCreatePostgresSchemaSnapshot as u };
package/dist/mysql.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { V as Dialect } from "./types-Deo_q43Y.mjs";
1
+ import { V as Dialect } from "./types-BK1COGZe.mjs";
2
2
  //#region src/dialects/mysql.d.ts
3
- declare function mysqlDialect(): Dialect<"json" | "row-locking">;
3
+ declare function mysqlDialect(): Dialect<"row-locking" | "json">;
4
4
  //#endregion
5
5
  export { mysqlDialect };
package/dist/mysql.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { o as createDialect, t as mysqlJson } from "./json-CUZlv4HT.mjs";
1
+ import { o as createDialect, t as mysqlJson } from "./json-Db7XRD91.mjs";
2
2
  import { n as queryValidationError } from "./errors-Dxv73YJu.mjs";
3
3
  import { t as mysqlExplain } from "./explain-CkIK13L_.mjs";
4
4
  //#region src/dialects/mysql.ts
@@ -18,11 +18,11 @@ function renderMySqlPagination(context, parts) {
18
18
  const fetch = parts.find((part) => part.kind === "fetch");
19
19
  const offset = parts.find((part) => part.kind === "offset");
20
20
  context.append("LIMIT ");
21
- if (fetch) context.parameter(fetch.rows);
21
+ if (fetch) context.append(String(fetch.rows));
22
22
  else context.append("18446744073709551615");
23
23
  if (offset) {
24
24
  context.append(" OFFSET ");
25
- context.parameter(offset.rows);
25
+ context.append(String(offset.rows));
26
26
  }
27
27
  }
28
28
  function mysqlDialect() {
@@ -1,9 +1,8 @@
1
- import { a as assertDialectCapability } from "./json-CUZlv4HT.mjs";
1
+ import { a as assertDialectCapability } from "./json-Db7XRD91.mjs";
2
2
  import { n as queryValidationError } from "./errors-Dxv73YJu.mjs";
3
- import { C as fragment, g as isExpression, i as identifier, t as createColumnReference } from "./column-D-8OqGuV.mjs";
4
- import { a as columnResultValue } from "./column-LV7oGQde.mjs";
3
+ import { K as fragment, i as identifier, t as createColumnReference, u as columnResultValue, z as isExpression } from "./column-hqKr7-1I.mjs";
5
4
  import { t as omit } from "./omit-OxV58AwX.mjs";
6
- import { r as exposeColumns, t as createSource } from "./source-DGO3DRgg.mjs";
5
+ import { r as exposeColumns, t as createSource } from "./source-BcS2AsIg.mjs";
7
6
  //#region src/query/mutation/on-conflict.ts
8
7
  /** Columns from the proposed INSERT row, available inside DO UPDATE. */
9
8
  function excluded(table) {
@@ -1,12 +1,12 @@
1
- import { An as excluded, Au as SqlBoolean, Ba as Operand, Ca as ComparisonValidation, Cn as ConflictTarget, Dn as OnConflictClause, Du as AnySqlType, En as ExcludedSource, Gu as SqlUnknown, Ha as OperandSqlType, Hu as SqlTextLike, On as doNothing, Sn as ConflictAction, Tn as DoUpdateAction, Ua as SqlCapabilityValidation, V as Dialect, Va as OperandNullability, Wl as ExpressionMeta, fu as RequiresCapabilityMeta, jn as onConflict, kn as doUpdate, tu as MetadataOf, vl as ExpressionWithOutput, vu as ResultMeta, wn as DoNothingAction, yl as SchemaExpression } from "./types-Deo_q43Y.mjs";
1
+ import { Au as SqlBoolean, Do as SqlCapabilityValidation, Du as AnySqlType, Eo as OperandSqlType, Gu as SqlUnknown, Hu as SqlTextLike, To as OperandNullability, V as Dialect, Wl as ExpressionMeta, _n as doNothing, bn as onConflict, dn as ConflictAction, fn as ConflictTarget, fu as RequiresCapabilityMeta, gn as OnConflictClause, hn as ExcludedSource, mn as DoUpdateAction, pn as DoNothingAction, so as ComparisonValidation, tu as MetadataOf, vl as ExpressionWithOutput, vn as doUpdate, vu as ResultMeta, wo as Operand, yl as SchemaExpression, yn as excluded } from "./types-BK1COGZe.mjs";
2
2
  //#region src/dialects/postgres.d.ts
3
3
  /**
4
- * PostgreSQL's only core rendering difference is positional parameters.
5
- * PostgreSQL-specific expressions and clauses should remain separate modules.
4
+ * PostgreSQL's only core rendering difference is positional parameters. PostgreSQL-specific
5
+ * expressions and clauses should remain separate modules.
6
6
  */
7
- declare function postgresDialect(): Dialect<"json" | "ilike" | "on-conflict" | "row-locking">;
7
+ declare function postgresDialect(): Dialect<"row-locking" | "json" | "ilike" | "on-conflict">;
8
8
  /** PostgreSQL's case-insensitive pattern-match operator. */
9
- declare function ilike<TLeft extends ExpressionWithOutput<string>, R extends Operand<string>>(left: TLeft & ComparisonValidation<TLeft, R, 'ILIKE'>, pattern: R): SchemaExpression<ResultMeta<boolean, ((MetadataOf<TLeft & SqlCapabilityValidation<(MetadataOf<TLeft> extends (infer T) ? T extends MetadataOf<TLeft> ? T extends {
9
+ declare function ilike<TLeft extends ExpressionWithOutput<string>, R extends Operand<string>>(left: TLeft & ComparisonValidation<TLeft, R, "ILIKE">, pattern: R): SchemaExpression<ResultMeta<boolean, ((MetadataOf<TLeft & SqlCapabilityValidation<(MetadataOf<TLeft> extends (infer T) ? T extends MetadataOf<TLeft> ? T extends {
10
10
  readonly kind: "result";
11
11
  } ? T : never : never : never) extends (infer T_1) ? T_1 extends (MetadataOf<TLeft> extends (infer T_2) ? T_2 extends MetadataOf<TLeft> ? T_2 extends {
12
12
  readonly kind: "result";