@prisma/orm-target-mysql 0.0.0-stage → 8.0.0-rc.21

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 (159) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +20 -2
  3. package/dist/adapter-_WBomuTw.d.mts +27 -0
  4. package/dist/adapter-_WBomuTw.d.mts.map +1 -0
  5. package/dist/adapter.d.mts +6 -0
  6. package/dist/adapter.mjs +3 -0
  7. package/dist/adapter__adapter.d.mts +2 -0
  8. package/dist/adapter__adapter.mjs +2 -0
  9. package/dist/adapter__codec-types.d.mts +3 -0
  10. package/dist/adapter__codec-types.mjs +1 -0
  11. package/dist/adapter__control.d.mts +2 -0
  12. package/dist/adapter__control.mjs +2 -0
  13. package/dist/adapter__runtime.d.mts +2 -0
  14. package/dist/adapter__runtime.mjs +417 -0
  15. package/dist/adapter__runtime.mjs.map +1 -0
  16. package/dist/codec-descriptor-DXyubAS6-siA0R8Ow.d.mts +43 -0
  17. package/dist/codec-descriptor-DXyubAS6-siA0R8Ow.d.mts.map +1 -0
  18. package/dist/codec-descriptor-Du6DSz-3-ytBCu_mq.mjs +93 -0
  19. package/dist/codec-descriptor-Du6DSz-3-ytBCu_mq.mjs.map +1 -0
  20. package/dist/codec-descriptor-J3TP08l8-ekLvUVxW.d.mts +1 -0
  21. package/dist/codec-descriptor-oLRh9E29.d.mts +2 -0
  22. package/dist/codec-ids-BHUwoNOM.d.mts +2 -0
  23. package/dist/codec-ids-C00hAFkc.mjs +2 -0
  24. package/dist/codec-ids-cjxtOcLM-vFeQhgPm.mjs +10 -0
  25. package/dist/codec-ids-cjxtOcLM-vFeQhgPm.mjs.map +1 -0
  26. package/dist/codec-ids-sMOU8F-B-BQbCq2dr.d.mts +10 -0
  27. package/dist/codec-ids-sMOU8F-B-BQbCq2dr.d.mts.map +1 -0
  28. package/dist/codec-types-Bd7DL1Mr-CZWNfnp9.d.mts +21 -0
  29. package/dist/codec-types-Bd7DL1Mr-CZWNfnp9.d.mts.map +1 -0
  30. package/dist/codec-types-Bo3Jfilx.d.mts +1 -0
  31. package/dist/codec-types-Ja2kLzLS.d.mts +1 -0
  32. package/dist/codecs-C00kjHgh.mjs +282 -0
  33. package/dist/codecs-C00kjHgh.mjs.map +1 -0
  34. package/dist/codecs-CO_VNEYU-CwAnKzRs.d.mts +102 -0
  35. package/dist/codecs-CO_VNEYU-CwAnKzRs.d.mts.map +1 -0
  36. package/dist/codecs-DM61agRr.d.mts +21 -0
  37. package/dist/codecs-DM61agRr.d.mts.map +1 -0
  38. package/dist/contract-contributions-B9njRJbt-ClEtrK2L.mjs +14 -0
  39. package/dist/contract-contributions-B9njRJbt-ClEtrK2L.mjs.map +1 -0
  40. package/dist/contract-free-BvCdx_Ee.mjs +71 -0
  41. package/dist/contract-free-BvCdx_Ee.mjs.map +1 -0
  42. package/dist/contract-free-Cw9Mjcro.d.mts +22 -0
  43. package/dist/contract-free-Cw9Mjcro.d.mts.map +1 -0
  44. package/dist/control-C9zxRXNN.mjs +74 -0
  45. package/dist/control-C9zxRXNN.mjs.map +1 -0
  46. package/dist/control-DHkZbo58.d.mts +25 -0
  47. package/dist/control-DHkZbo58.d.mts.map +1 -0
  48. package/dist/control-Ez_PtlFI.d.mts +121 -0
  49. package/dist/control-Ez_PtlFI.d.mts.map +1 -0
  50. package/dist/control-WTY7Jpxk.mjs +577 -0
  51. package/dist/control-WTY7Jpxk.mjs.map +1 -0
  52. package/dist/control-_4epnrIW.d.mts +27 -0
  53. package/dist/control-_4epnrIW.d.mts.map +1 -0
  54. package/dist/control-tables-CHw2F-rg.d.mts +9 -0
  55. package/dist/control-tables-CHw2F-rg.d.mts.map +1 -0
  56. package/dist/control-tables-CcQ77JE7-CxTQYoQJ.mjs +9 -0
  57. package/dist/control-tables-CcQ77JE7-CxTQYoQJ.mjs.map +1 -0
  58. package/dist/data-type-entries-B0AoBozh-f9AEUIUQ.mjs +42 -0
  59. package/dist/data-type-entries-B0AoBozh-f9AEUIUQ.mjs.map +1 -0
  60. package/dist/data-types-BpihGKoK-BMW-m4EN.d.mts +52 -0
  61. package/dist/data-types-BpihGKoK-BMW-m4EN.d.mts.map +1 -0
  62. package/dist/data-types-Dv9gwVRV-BZPzCWZk.mjs +181 -0
  63. package/dist/data-types-Dv9gwVRV-BZPzCWZk.mjs.map +1 -0
  64. package/dist/data-types-SXrh0Lou.d.mts +8 -0
  65. package/dist/data-types-SXrh0Lou.d.mts.map +1 -0
  66. package/dist/ddl-CT6DPEqg.d.mts +1 -0
  67. package/dist/ddl-DDmMHyA_-Bb8sXoS0.mjs +12 -0
  68. package/dist/ddl-DDmMHyA_-Bb8sXoS0.mjs.map +1 -0
  69. package/dist/default-normalizer-BBhGpw7r.d.mts +27 -0
  70. package/dist/default-normalizer-BBhGpw7r.d.mts.map +1 -0
  71. package/dist/default-normalizer-BDUgHXUn-Xk7HQJuI.mjs +90 -0
  72. package/dist/default-normalizer-BDUgHXUn-Xk7HQJuI.mjs.map +1 -0
  73. package/dist/descriptor-meta-BurjcSiU-Cbk2L1jf.mjs +82 -0
  74. package/dist/descriptor-meta-BurjcSiU-Cbk2L1jf.mjs.map +1 -0
  75. package/dist/descriptor-meta-runtime-Bk_00UrX-BLN4Ahpj.mjs +17 -0
  76. package/dist/descriptor-meta-runtime-Bk_00UrX-BLN4Ahpj.mjs.map +1 -0
  77. package/dist/driver.d.mts +3 -0
  78. package/dist/driver.mjs +2 -0
  79. package/dist/driver__control.d.mts +2 -0
  80. package/dist/driver__control.mjs +2 -0
  81. package/dist/driver__runtime.d.mts +2 -0
  82. package/dist/driver__runtime.mjs +325 -0
  83. package/dist/driver__runtime.mjs.map +1 -0
  84. package/dist/errors-BYhjQT7y.d.mts +10 -0
  85. package/dist/errors-BYhjQT7y.d.mts.map +1 -0
  86. package/dist/errors-rvH_F2Yj-BQrO_--u.mjs +20 -0
  87. package/dist/errors-rvH_F2Yj-BQrO_--u.mjs.map +1 -0
  88. package/dist/marker-lock-CmGvN4hw-Com29AtQ.mjs +51 -0
  89. package/dist/marker-lock-CmGvN4hw-Com29AtQ.mjs.map +1 -0
  90. package/dist/marker-lock-su6IxinO.d.mts +18 -0
  91. package/dist/marker-lock-su6IxinO.d.mts.map +1 -0
  92. package/dist/marker-read-aEaHihYj-Cyg16yn1.mjs +78 -0
  93. package/dist/marker-read-aEaHihYj-Cyg16yn1.mjs.map +1 -0
  94. package/dist/migration-DmlblTTw.d.mts +284 -0
  95. package/dist/migration-DmlblTTw.d.mts.map +1 -0
  96. package/dist/migration-tFuoN9GB.mjs +5 -0
  97. package/dist/mysql-contract-serializer-DLv0uW_f-Cg4A43Ry.mjs +160 -0
  98. package/dist/mysql-contract-serializer-DLv0uW_f-Cg4A43Ry.mjs.map +1 -0
  99. package/dist/nodes-CvcX47ot-B-ZaUYRj.mjs +25 -0
  100. package/dist/nodes-CvcX47ot-B-ZaUYRj.mjs.map +1 -0
  101. package/dist/nodes-xc0cR0_c-2YbhgEjb.d.mts +27 -0
  102. package/dist/nodes-xc0cR0_c-2YbhgEjb.d.mts.map +1 -0
  103. package/dist/pack-YVG-iBMQ.d.mts +1073 -0
  104. package/dist/pack-YVG-iBMQ.d.mts.map +1 -0
  105. package/dist/planner-target-details-D6g2uSp--C5NKHmCc.d.mts +12 -0
  106. package/dist/planner-target-details-D6g2uSp--C5NKHmCc.d.mts.map +1 -0
  107. package/dist/runner-C4r6yEd1-BWQrxW9q.mjs +1644 -0
  108. package/dist/runner-C4r6yEd1-BWQrxW9q.mjs.map +1 -0
  109. package/dist/runtime-BGyTXcQH.d.mts +36 -0
  110. package/dist/runtime-BGyTXcQH.d.mts.map +1 -0
  111. package/dist/runtime-CeuRr9nE.d.mts +29 -0
  112. package/dist/runtime-CeuRr9nE.d.mts.map +1 -0
  113. package/dist/runtime-Cl0BbTZq.d.mts +22 -0
  114. package/dist/runtime-Cl0BbTZq.d.mts.map +1 -0
  115. package/dist/sql-utils-BOS1c2QT.d.mts +30 -0
  116. package/dist/sql-utils-BOS1c2QT.d.mts.map +1 -0
  117. package/dist/sql-utils-Db0IQO_B-PaULnfrE.mjs +30 -0
  118. package/dist/sql-utils-Db0IQO_B-PaULnfrE.mjs.map +1 -0
  119. package/dist/sql-utils-RW0vJvDl.mjs +94 -0
  120. package/dist/sql-utils-RW0vJvDl.mjs.map +1 -0
  121. package/dist/statement-A6bbPBf1-q61iHQLb.mjs +483 -0
  122. package/dist/statement-A6bbPBf1-q61iHQLb.mjs.map +1 -0
  123. package/dist/target.d.mts +24 -0
  124. package/dist/target.mjs +19 -0
  125. package/dist/target__codec-descriptor.d.mts +3 -0
  126. package/dist/target__codec-descriptor.mjs +2 -0
  127. package/dist/target__codec-ids.d.mts +3 -0
  128. package/dist/target__codec-ids.mjs +3 -0
  129. package/dist/target__codec-types.d.mts +3 -0
  130. package/dist/target__codec-types.mjs +1 -0
  131. package/dist/target__codecs.d.mts +3 -0
  132. package/dist/target__codecs.mjs +2 -0
  133. package/dist/target__contract-free.d.mts +2 -0
  134. package/dist/target__contract-free.mjs +3 -0
  135. package/dist/target__control-tables.d.mts +2 -0
  136. package/dist/target__control-tables.mjs +2 -0
  137. package/dist/target__control.d.mts +3 -0
  138. package/dist/target__control.mjs +58 -0
  139. package/dist/target__control.mjs.map +1 -0
  140. package/dist/target__data-types.d.mts +3 -0
  141. package/dist/target__data-types.mjs +3 -0
  142. package/dist/target__ddl.d.mts +3 -0
  143. package/dist/target__ddl.mjs +2 -0
  144. package/dist/target__default-normalizer.d.mts +2 -0
  145. package/dist/target__default-normalizer.mjs +2 -0
  146. package/dist/target__errors.d.mts +2 -0
  147. package/dist/target__errors.mjs +2 -0
  148. package/dist/target__marker-lock.d.mts +2 -0
  149. package/dist/target__marker-lock.mjs +2 -0
  150. package/dist/target__migration.d.mts +2 -0
  151. package/dist/target__migration.mjs +3 -0
  152. package/dist/target__pack.d.mts +2 -0
  153. package/dist/target__pack.mjs +2 -0
  154. package/dist/target__runtime.d.mts +2 -0
  155. package/dist/target__runtime.mjs +17 -0
  156. package/dist/target__runtime.mjs.map +1 -0
  157. package/dist/target__sql-utils.d.mts +2 -0
  158. package/dist/target__sql-utils.mjs +3 -0
  159. package/package.json +71 -3
@@ -0,0 +1,1644 @@
1
+ import { t as mysqlError } from "./errors-rvH_F2Yj-BQrO_--u.mjs";
2
+ import { n as quoteIdentifier } from "./sql-utils-Db0IQO_B-PaULnfrE.mjs";
3
+ import { t as CONTROL_TABLE_NAMES } from "./control-tables-CcQ77JE7-CxTQYoQJ.mjs";
4
+ import { t as createTable } from "./ddl-DDmMHyA_-Bb8sXoS0.mjs";
5
+ import { t as mysqlResolveDefault } from "./default-normalizer-BDUgHXUn-Xk7HQJuI.mjs";
6
+ import { i as withMarkerLock } from "./marker-lock-CmGvN4hw-Com29AtQ.mjs";
7
+ import { dataTypeParams } from "@prisma/orm-framework/components/codec";
8
+ import { blindCast } from "@prisma/orm-framework/utils/casts";
9
+ import { InternalError, isInternalError } from "@prisma/orm-framework/utils/internal-error";
10
+ import { isStructuredError } from "@prisma/orm-framework/utils/structured-error";
11
+ import { DdlColumn, FunctionColumnDefault, LiteralColumnDefault, PrimaryKeyConstraint, UniqueConstraint, opaqueSql } from "@prisma/orm-family-sql/relational-core/ast";
12
+ import { isSqlDataType, renderSqlTypeName } from "@prisma/orm-family-sql/contract/data-type";
13
+ import { contractSnapshotJsonSpecifier, contractSnapshotTypesSpecifier, diffSchemas, expectAbsent, expectPresent, failedPostcheckWhy, failedPrecheckWhy, issueOutcome, migrationRunnerFailure, orderIssuesByDependencies, schemaCheckWhy, withDatabaseUnchanged, withFailingSpace } from "@prisma/orm-framework/components/control";
14
+ import { UNBOUND_NAMESPACE_ID, entityAt } from "@prisma/orm-framework/components/ir";
15
+ import { NO_RENAMED_ORIGINS, contractToSchemaIR, createSqlTextSources, plannerFailure, runnerFailure, runnerSuccess, sqlTypeLookupsOf, subjectsOfCalls } from "@prisma/orm-family-sql/family/control";
16
+ import { RelationalSchemaNodeKind, SqlSchemaIR, sqlColumnTypesEqual } from "@prisma/orm-family-sql/schema-ir/types";
17
+ import { notOk, ok, okVoid } from "@prisma/orm-framework/utils/result";
18
+ import { TsExpression, jsonToTsSource, renderImports } from "@prisma/orm-framework/ts-render";
19
+ import { ifDefined } from "@prisma/orm-framework/utils/defined";
20
+ import { REFERENTIAL_ACTION_SQL } from "@prisma/orm-family-sql/contract/referential-action-sql";
21
+ import { Migration } from "@prisma/orm-family-sql/family/migration";
22
+ import { isThenable } from "@prisma/orm-framework/utils/promise";
23
+ import { resolveRequirementSpecifiers } from "@prisma/orm-framework/components/emission";
24
+ import { detectScaffoldRuntime, shebangLineFor } from "@prisma/orm-toolchain/migration-tools/migration-ts";
25
+ //#region ../../../3-targets/mysql/1-target/dist/runner-C4r6yEd1.mjs
26
+ /**
27
+ * The schema IR a contract describes on MySQL: one flat tree of tables, each column typed by the data type its codec represents. A MySQL database holds no schemas, so foreign keys name no referenced schema, as introspection reports them.
28
+ */
29
+ function mysqlContractToSchema(contract, types) {
30
+ return contractToSchemaIR(contract, {
31
+ annotationNamespace: "mysql",
32
+ resolveDefault: mysqlResolveDefault,
33
+ dataTypeLookup: types.dataTypeLookup,
34
+ codecLookup: types.codecLookup
35
+ });
36
+ }
37
+ /** The control policy of the table an issue is about. The tree is flat, so the table's name is the second segment of the issue's path. */
38
+ function resolveControlPolicy(issue, contract) {
39
+ const tableName = issue.path[1];
40
+ if (tableName === void 0) return void 0;
41
+ for (const namespaceId of Object.keys(contract.storage.namespaces)) {
42
+ const table = entityAt(contract.storage, {
43
+ namespaceId,
44
+ entityKind: "table",
45
+ entityName: tableName
46
+ });
47
+ if (table !== void 0) return table.control;
48
+ }
49
+ }
50
+ /** The full-tree diff `db verify` derives its verdict from: the contract's tree against the one introspection built. */
51
+ function diffMysqlSchema(input) {
52
+ if (!(input.schema instanceof SqlSchemaIR)) throw mysqlError("CONTRACT.TARGET_MISMATCH", "The MySQL schema diff received a schema tree that MySQL introspection did not build.");
53
+ const expected = mysqlContractToSchema(input.contract, sqlTypeLookupsOf(input.frameworkComponents));
54
+ const actual = input.schema;
55
+ const namespacesWithTables = Object.values(input.contract.storage.namespaces).filter((ns) => Object.keys(ns.entries.table ?? {}).length > 0);
56
+ return {
57
+ issues: diffSchemas(expected, actual),
58
+ resolveControlPolicy: (issue) => resolveControlPolicy(issue, input.contract),
59
+ namespacePairs: namespacesWithTables.map(() => ({ actual }))
60
+ };
61
+ }
62
+ /** The type DDL writes for a column node: the type it is stored as, with the parameters the contract writes, as MySQL reports it in `COLUMN_TYPE`. */
63
+ function columnTypeSql(column) {
64
+ const type = column.storedType;
65
+ if (type === void 0 || !isSqlDataType(type)) throw new InternalError(`column "${column.name}" has no data type; the expected tree must be derived via contractToSchemaIR for planning`);
66
+ return renderSqlTypeName(type, dataTypeParams(type, column.codecRef?.typeParams));
67
+ }
68
+ function ddlDefaultOf(columnDefault) {
69
+ if (columnDefault === void 0) return void 0;
70
+ return columnDefault.kind === "literal" ? new LiteralColumnDefault(columnDefault.value) : new FunctionColumnDefault(opaqueSql(columnDefault.expression));
71
+ }
72
+ /** The default a column node's DDL writes: the one the contract authored, which `resolvedDefault` normalises for the diff. */
73
+ function columnDefaultOf(column) {
74
+ return column.authoredDefault ?? column.resolvedDefault;
75
+ }
76
+ /** The `DdlColumn` of a column node. An `autoincrement()` default stays a function default, which the adapter writes as `AUTO_INCREMENT`. */
77
+ function ddlColumnFromNode(column) {
78
+ const columnDefault = ddlDefaultOf(columnDefaultOf(column));
79
+ return new DdlColumn({
80
+ name: column.name,
81
+ type: columnTypeSql(column),
82
+ ...column.nullable ? {} : { notNull: true },
83
+ ...columnDefault === void 0 ? {} : { default: columnDefault },
84
+ ...column.codecRef === void 0 ? {} : { codecRef: column.codecRef }
85
+ });
86
+ }
87
+ /** The name a unique constraint is created and dropped by; MySQL names an unnamed one after its first column, which the contract never leaves to it. */
88
+ function uniqueName(table, unique) {
89
+ return unique.name ?? `${table}_${unique.columns.join("_")}_key`;
90
+ }
91
+ /** The constraints `CREATE TABLE` writes for a table node: its primary key and unique constraints. Foreign keys are added after every table exists, so tables can reference each other. */
92
+ function tableConstraintsFromNode(table) {
93
+ return [...table.primaryKey === void 0 ? [] : [new PrimaryKeyConstraint({ columns: table.primaryKey.columns })], ...table.uniques.map((unique) => new UniqueConstraint({
94
+ columns: unique.columns,
95
+ name: uniqueName(table.name, unique)
96
+ }))];
97
+ }
98
+ function step(description, sql, params, expectation) {
99
+ return {
100
+ description,
101
+ sql,
102
+ ...ifDefined("params", params),
103
+ ...ifDefined("expectation", expectation)
104
+ };
105
+ }
106
+ const IN_DATABASE = "TABLE_SCHEMA = DATABASE()";
107
+ function count(from, where, params) {
108
+ return {
109
+ sql: `SELECT COUNT(*) FROM information_schema.${from} WHERE ${IN_DATABASE} AND ${where}`,
110
+ params
111
+ };
112
+ }
113
+ function present(query) {
114
+ return {
115
+ sql: `SELECT (${query.sql}) > 0 AS result`,
116
+ params: query.params
117
+ };
118
+ }
119
+ function absent(query) {
120
+ return {
121
+ sql: `SELECT (${query.sql}) = 0 AS result`,
122
+ params: query.params
123
+ };
124
+ }
125
+ const tableQuery = (table) => count("TABLES", "TABLE_NAME = ?", [table]);
126
+ const columnQuery = (table, column) => count("COLUMNS", "TABLE_NAME = ? AND COLUMN_NAME = ?", [table, column]);
127
+ const indexQuery = (table, index) => count("STATISTICS", "TABLE_NAME = ? AND INDEX_NAME = ?", [table, index]);
128
+ const constraintQuery = (table, name, type) => count("TABLE_CONSTRAINTS", "TABLE_NAME = ? AND CONSTRAINT_NAME = ? AND CONSTRAINT_TYPE = ?", [
129
+ table,
130
+ name,
131
+ type
132
+ ]);
133
+ /** A step that holds when `query` finds the object, or finds none, as `holds` says. */
134
+ function check(description, query, holds, object) {
135
+ const { sql, params } = holds === "present" ? present(query) : absent(query);
136
+ return step(description, sql, params, holds === "present" ? expectPresent(object) : expectAbsent(object));
137
+ }
138
+ const tableChecks = (table) => ({
139
+ present: (description) => check(description, tableQuery(table), "present", `table "${table}"`),
140
+ absent: (description) => check(description, tableQuery(table), "absent", `table "${table}"`)
141
+ });
142
+ const columnChecks = (table, column) => ({
143
+ present: (description) => check(description, columnQuery(table, column), "present", `column "${column}" on "${table}"`),
144
+ absent: (description) => check(description, columnQuery(table, column), "absent", `column "${column}" on "${table}"`)
145
+ });
146
+ const indexChecks = (table, index) => ({
147
+ present: (description) => check(description, indexQuery(table, index), "present", `index "${index}" on "${table}"`),
148
+ absent: (description) => check(description, indexQuery(table, index), "absent", `index "${index}" on "${table}"`)
149
+ });
150
+ const constraintChecks = (table, name, type) => {
151
+ const object = `${type === "UNIQUE" ? "unique constraint" : "foreign key"} "${name}" on "${table}"`;
152
+ return {
153
+ present: (description) => check(description, constraintQuery(table, name, type), "present", object),
154
+ absent: (description) => check(description, constraintQuery(table, name, type), "absent", object)
155
+ };
156
+ };
157
+ function columnList(columns) {
158
+ return columns.map(quoteIdentifier).join(", ");
159
+ }
160
+ /** The column definition `ALTER TABLE … ADD COLUMN` writes, with the default the adapter renders through the column's codec. */
161
+ async function columnDefinitionSql(column, table, lowerer) {
162
+ const defaultClause = await lowerer.renderColumnDefault(column, table);
163
+ return [
164
+ quoteIdentifier(column.name),
165
+ column.type,
166
+ ...column.notNull ? ["NOT NULL"] : [],
167
+ ...defaultClause.length > 0 ? [defaultClause] : []
168
+ ].join(" ");
169
+ }
170
+ function foreignKeyActionsSql(actions) {
171
+ return [...actions.onDelete === void 0 ? [] : [` ON DELETE ${REFERENTIAL_ACTION_SQL[actions.onDelete]}`], ...actions.onUpdate === void 0 ? [] : [` ON UPDATE ${REFERENTIAL_ACTION_SQL[actions.onUpdate]}`]].join("");
172
+ }
173
+ /** An operation written out in full in `migration.ts`, such as a table rename made by hand. */
174
+ function rawSql(op) {
175
+ return op;
176
+ }
177
+ function buildTargetDetails(objectType, name, table) {
178
+ return {
179
+ objectType,
180
+ name,
181
+ ...ifDefined("table", table)
182
+ };
183
+ }
184
+ const TARGET_MIGRATION_MODULE = "@internal/mysql/migration";
185
+ /** The refusal of a `MysqlMigration` operation that needs the control adapter, on an instance built without a control stack. */
186
+ function mysqlMigrationStackMissing(operation) {
187
+ return mysqlError("MIGRATION.MYSQL_CONTROL_STACK_MISSING", `MysqlMigration.${operation} requires a control adapter`, {
188
+ why: `MysqlMigration.${operation} was invoked on an instance constructed without a ControlStack, so it cannot render its DDL.`,
189
+ fix: "Construct the migration via the migration CLI entrypoint, which assembles a ControlStack from prisma.config.ts, or pass a ControlStack with a MySQL adapter to the migration constructor in test fixtures.",
190
+ meta: { operation }
191
+ });
192
+ }
193
+ var MysqlOpFactoryCallNode = class extends TsExpression {
194
+ importRequirements() {
195
+ return [];
196
+ }
197
+ freeze() {
198
+ Object.freeze(this);
199
+ }
200
+ lowererFor(lowerer) {
201
+ if (lowerer === void 0) throw mysqlMigrationStackMissing(this.factoryName);
202
+ return lowerer;
203
+ }
204
+ };
205
+ /** Whether `call` is one of this target's calls. */
206
+ function isMysqlOpFactoryCall(call) {
207
+ return call instanceof MysqlOpFactoryCallNode;
208
+ }
209
+ function renderColumnDefault(def, sql) {
210
+ return def.kind === "literal" ? `lit(${jsonToTsSource(def.value)})` : `fn(${sql.source(def.expression.text)})`;
211
+ }
212
+ function renderColumn(column, sql) {
213
+ const options = [
214
+ ...column.notNull ? ["notNull: true"] : [],
215
+ ...column.default === void 0 ? [] : [`default: ${renderColumnDefault(column.default, sql)}`],
216
+ ...column.codecRef === void 0 ? [] : [`codecRef: ${jsonToTsSource(column.codecRef)}`]
217
+ ];
218
+ const optionsSource = options.length > 0 ? `, { ${options.join(", ")} }` : "";
219
+ return `col(${jsonToTsSource(column.name)}, ${jsonToTsSource(column.type)}${optionsSource})`;
220
+ }
221
+ function renderConstraint(constraint) {
222
+ const named = constraint.name === void 0 ? "" : `, { name: ${jsonToTsSource(constraint.name)} }`;
223
+ switch (constraint.kind) {
224
+ case "primary-key": return `primaryKey(${jsonToTsSource(constraint.columns)}${named})`;
225
+ case "unique": return `unique(${jsonToTsSource(constraint.columns)}${named})`;
226
+ case "foreign-key":
227
+ case "check-expression": throw mysqlError("CONTRACT.CONSTRAINT_INVALID", `The MySQL createTable call writes primary keys and unique constraints only; add ${constraint.kind === "foreign-key" ? "a foreign key with addForeignKey" : "no CHECK constraint"} (constraint "${constraint.name ?? ""}").`, { meta: { constraintKind: constraint.kind } });
228
+ }
229
+ }
230
+ function columnImports(columns) {
231
+ const symbols = new Set(columns.length > 0 ? ["col"] : []);
232
+ for (const column of columns) {
233
+ if (column.default?.kind === "literal") symbols.add("lit");
234
+ if (column.default?.kind === "function") symbols.add("fn");
235
+ }
236
+ return [...symbols].map((symbol) => ({
237
+ moduleSpecifier: TARGET_MIGRATION_MODULE,
238
+ symbol
239
+ }));
240
+ }
241
+ var CreateTableCall = class extends MysqlOpFactoryCallNode {
242
+ tableName;
243
+ factoryName = "createTable";
244
+ operationClass = "additive";
245
+ label;
246
+ columns;
247
+ constraints;
248
+ constructor(tableName, columns, constraints) {
249
+ super();
250
+ this.tableName = tableName;
251
+ this.columns = Object.freeze([...columns]);
252
+ this.constraints = Object.freeze([...constraints]);
253
+ this.label = `Create table ${tableName}`;
254
+ this.freeze();
255
+ }
256
+ async toOp(lowerer) {
257
+ const statement = await this.lowererFor(lowerer).lowerToExecuteRequest(createTable({
258
+ table: this.tableName,
259
+ columns: this.columns,
260
+ constraints: this.constraints
261
+ }));
262
+ const table = tableChecks(this.tableName);
263
+ return {
264
+ id: `table.${this.tableName}`,
265
+ label: this.label,
266
+ summary: `Creates table ${this.tableName} with its columns, primary key and unique constraints`,
267
+ operationClass: "additive",
268
+ target: {
269
+ id: "mysql",
270
+ details: buildTargetDetails("table", this.tableName)
271
+ },
272
+ precheck: [table.absent(`ensure table "${this.tableName}" does not exist`)],
273
+ execute: [step(`create table "${this.tableName}"`, statement.sql, statement.params)],
274
+ postcheck: [table.present(`verify table "${this.tableName}" exists`)]
275
+ };
276
+ }
277
+ renderTypeScript() {
278
+ return this.#written().source;
279
+ }
280
+ importRequirements() {
281
+ return this.#written().imports;
282
+ }
283
+ #written() {
284
+ const sql = createSqlTextSources(TARGET_MIGRATION_MODULE);
285
+ const columns = this.columns.map((column) => renderColumn(column, sql)).join(", ");
286
+ const constraints = this.constraints.map(renderConstraint);
287
+ const source = `this.createTable({ table: ${jsonToTsSource(this.tableName)}, columns: [${columns}]${constraints.length > 0 ? `, constraints: [${constraints.join(", ")}]` : ""} })`;
288
+ const constraintImports = [...new Set(this.constraints.map((c) => c.kind === "primary-key" ? "primaryKey" : "unique"))].map((symbol) => ({
289
+ moduleSpecifier: TARGET_MIGRATION_MODULE,
290
+ symbol
291
+ }));
292
+ return {
293
+ source,
294
+ imports: [
295
+ ...columnImports(this.columns),
296
+ ...constraintImports,
297
+ ...sql.imports()
298
+ ]
299
+ };
300
+ }
301
+ };
302
+ var DropTableCall = class extends MysqlOpFactoryCallNode {
303
+ tableName;
304
+ factoryName = "dropTable";
305
+ operationClass = "destructive";
306
+ label;
307
+ constructor(tableName) {
308
+ super();
309
+ this.tableName = tableName;
310
+ this.label = `Drop table ${tableName}`;
311
+ this.freeze();
312
+ }
313
+ toOp() {
314
+ const table = tableChecks(this.tableName);
315
+ return {
316
+ id: `dropTable.${this.tableName}`,
317
+ label: this.label,
318
+ summary: `Drops table ${this.tableName} which is not in the contract`,
319
+ operationClass: "destructive",
320
+ target: {
321
+ id: "mysql",
322
+ details: buildTargetDetails("table", this.tableName)
323
+ },
324
+ precheck: [table.present(`ensure table "${this.tableName}" exists`)],
325
+ execute: [step(`drop table "${this.tableName}"`, `DROP TABLE ${quoteIdentifier(this.tableName)}`)],
326
+ postcheck: [table.absent(`verify table "${this.tableName}" is gone`)]
327
+ };
328
+ }
329
+ renderTypeScript() {
330
+ return `this.dropTable({ table: ${jsonToTsSource(this.tableName)} })`;
331
+ }
332
+ };
333
+ var AddColumnCall = class extends MysqlOpFactoryCallNode {
334
+ tableName;
335
+ column;
336
+ factoryName = "addColumn";
337
+ operationClass = "additive";
338
+ label;
339
+ columnName;
340
+ constructor(tableName, column) {
341
+ super();
342
+ this.tableName = tableName;
343
+ this.column = column;
344
+ this.columnName = column.name;
345
+ this.label = `Add column ${column.name} on ${tableName}`;
346
+ this.freeze();
347
+ }
348
+ async toOp(lowerer) {
349
+ const definition = await columnDefinitionSql(this.column, this.tableName, this.lowererFor(lowerer));
350
+ const column = columnChecks(this.tableName, this.columnName);
351
+ return {
352
+ id: `column.${this.tableName}.${this.columnName}`,
353
+ label: this.label,
354
+ summary: `Adds column ${this.columnName} to ${this.tableName}`,
355
+ operationClass: "additive",
356
+ target: {
357
+ id: "mysql",
358
+ details: buildTargetDetails("column", this.columnName, this.tableName)
359
+ },
360
+ precheck: [tableChecks(this.tableName).present(`ensure table "${this.tableName}" exists`), column.absent(`ensure column "${this.columnName}" is missing on "${this.tableName}"`)],
361
+ execute: [step(`add column "${this.columnName}" to "${this.tableName}"`, `ALTER TABLE ${quoteIdentifier(this.tableName)} ADD COLUMN ${definition}`)],
362
+ postcheck: [column.present(`verify column "${this.columnName}" exists on "${this.tableName}"`)]
363
+ };
364
+ }
365
+ renderTypeScript() {
366
+ return this.#written().source;
367
+ }
368
+ importRequirements() {
369
+ return this.#written().imports;
370
+ }
371
+ #written() {
372
+ const sql = createSqlTextSources(TARGET_MIGRATION_MODULE);
373
+ return {
374
+ source: `this.addColumn({ table: ${jsonToTsSource(this.tableName)}, column: ${renderColumn(this.column, sql)} })`,
375
+ imports: [...columnImports([this.column]), ...sql.imports()]
376
+ };
377
+ }
378
+ };
379
+ var DropColumnCall = class extends MysqlOpFactoryCallNode {
380
+ tableName;
381
+ columnName;
382
+ factoryName = "dropColumn";
383
+ operationClass = "destructive";
384
+ label;
385
+ constructor(tableName, columnName) {
386
+ super();
387
+ this.tableName = tableName;
388
+ this.columnName = columnName;
389
+ this.label = `Drop column ${columnName} on ${tableName}`;
390
+ this.freeze();
391
+ }
392
+ toOp() {
393
+ const column = columnChecks(this.tableName, this.columnName);
394
+ return {
395
+ id: `dropColumn.${this.tableName}.${this.columnName}`,
396
+ label: this.label,
397
+ summary: `Drops column ${this.columnName} on ${this.tableName} which is not in the contract`,
398
+ operationClass: "destructive",
399
+ target: {
400
+ id: "mysql",
401
+ details: buildTargetDetails("column", this.columnName, this.tableName)
402
+ },
403
+ precheck: [column.present(`ensure column "${this.columnName}" exists on "${this.tableName}"`)],
404
+ execute: [step(`drop column "${this.columnName}" from "${this.tableName}"`, `ALTER TABLE ${quoteIdentifier(this.tableName)} DROP COLUMN ${quoteIdentifier(this.columnName)}`)],
405
+ postcheck: [column.absent(`verify column "${this.columnName}" is gone from "${this.tableName}"`)]
406
+ };
407
+ }
408
+ renderTypeScript() {
409
+ return `this.dropColumn({ table: ${jsonToTsSource(this.tableName)}, column: ${jsonToTsSource(this.columnName)} })`;
410
+ }
411
+ };
412
+ var CreateIndexCall = class extends MysqlOpFactoryCallNode {
413
+ tableName;
414
+ indexName;
415
+ columns;
416
+ unique;
417
+ factoryName = "createIndex";
418
+ operationClass = "additive";
419
+ label;
420
+ constructor(tableName, indexName, columns, unique) {
421
+ super();
422
+ this.tableName = tableName;
423
+ this.indexName = indexName;
424
+ this.columns = columns;
425
+ this.unique = unique;
426
+ this.label = `Create ${unique ? "unique " : ""}index ${indexName} on ${tableName}`;
427
+ this.freeze();
428
+ }
429
+ toOp() {
430
+ const index = indexChecks(this.tableName, this.indexName);
431
+ return {
432
+ id: `index.${this.tableName}.${this.indexName}`,
433
+ label: this.label,
434
+ summary: `Creates ${this.unique ? "unique " : ""}index ${this.indexName} on ${this.tableName}`,
435
+ operationClass: "additive",
436
+ target: {
437
+ id: "mysql",
438
+ details: buildTargetDetails("index", this.indexName, this.tableName)
439
+ },
440
+ precheck: [index.absent(`ensure index "${this.indexName}" is missing`)],
441
+ execute: [step(`create index "${this.indexName}"`, `CREATE ${this.unique ? "UNIQUE " : ""}INDEX ${quoteIdentifier(this.indexName)} ON ${quoteIdentifier(this.tableName)} (${columnList(this.columns)})`)],
442
+ postcheck: [index.present(`verify index "${this.indexName}" exists`)]
443
+ };
444
+ }
445
+ renderTypeScript() {
446
+ return `this.createIndex({ table: ${jsonToTsSource(this.tableName)}, index: ${jsonToTsSource(this.indexName)}, columns: ${jsonToTsSource(this.columns)}${this.unique ? ", unique: true" : ""} })`;
447
+ }
448
+ };
449
+ var DropIndexCall = class extends MysqlOpFactoryCallNode {
450
+ tableName;
451
+ indexName;
452
+ factoryName = "dropIndex";
453
+ operationClass = "widening";
454
+ label;
455
+ constructor(tableName, indexName) {
456
+ super();
457
+ this.tableName = tableName;
458
+ this.indexName = indexName;
459
+ this.label = `Drop index ${indexName} on ${tableName}`;
460
+ this.freeze();
461
+ }
462
+ toOp() {
463
+ const index = indexChecks(this.tableName, this.indexName);
464
+ return {
465
+ id: `dropIndex.${this.tableName}.${this.indexName}`,
466
+ label: this.label,
467
+ summary: `Drops index ${this.indexName} on ${this.tableName} which is not in the contract`,
468
+ operationClass: "widening",
469
+ target: {
470
+ id: "mysql",
471
+ details: buildTargetDetails("index", this.indexName, this.tableName)
472
+ },
473
+ precheck: [index.present(`ensure index "${this.indexName}" exists`)],
474
+ execute: [step(`drop index "${this.indexName}"`, `DROP INDEX ${quoteIdentifier(this.indexName)} ON ${quoteIdentifier(this.tableName)}`)],
475
+ postcheck: [index.absent(`verify index "${this.indexName}" is gone`)]
476
+ };
477
+ }
478
+ renderTypeScript() {
479
+ return `this.dropIndex({ table: ${jsonToTsSource(this.tableName)}, index: ${jsonToTsSource(this.indexName)} })`;
480
+ }
481
+ };
482
+ var AddUniqueCall = class extends MysqlOpFactoryCallNode {
483
+ tableName;
484
+ constraintName;
485
+ columns;
486
+ factoryName = "addUnique";
487
+ operationClass = "additive";
488
+ label;
489
+ constructor(tableName, constraintName, columns) {
490
+ super();
491
+ this.tableName = tableName;
492
+ this.constraintName = constraintName;
493
+ this.columns = columns;
494
+ this.label = `Add unique constraint ${constraintName} on ${tableName}`;
495
+ this.freeze();
496
+ }
497
+ toOp() {
498
+ const constraint = constraintChecks(this.tableName, this.constraintName, "UNIQUE");
499
+ return {
500
+ id: `unique.${this.tableName}.${this.constraintName}`,
501
+ label: this.label,
502
+ summary: `Adds unique constraint ${this.constraintName} on ${this.tableName}`,
503
+ operationClass: "additive",
504
+ target: {
505
+ id: "mysql",
506
+ details: buildTargetDetails("unique", this.constraintName, this.tableName)
507
+ },
508
+ precheck: [constraint.absent(`ensure unique constraint "${this.constraintName}" is missing`)],
509
+ execute: [step(`add unique constraint "${this.constraintName}"`, `ALTER TABLE ${quoteIdentifier(this.tableName)} ADD CONSTRAINT ${quoteIdentifier(this.constraintName)} UNIQUE (${columnList(this.columns)})`)],
510
+ postcheck: [constraint.present(`verify unique constraint "${this.constraintName}" exists`)]
511
+ };
512
+ }
513
+ renderTypeScript() {
514
+ return `this.addUnique({ table: ${jsonToTsSource(this.tableName)}, name: ${jsonToTsSource(this.constraintName)}, columns: ${jsonToTsSource(this.columns)} })`;
515
+ }
516
+ };
517
+ var DropUniqueCall = class extends MysqlOpFactoryCallNode {
518
+ tableName;
519
+ constraintName;
520
+ factoryName = "dropUnique";
521
+ operationClass = "widening";
522
+ label;
523
+ constructor(tableName, constraintName) {
524
+ super();
525
+ this.tableName = tableName;
526
+ this.constraintName = constraintName;
527
+ this.label = `Drop unique constraint ${constraintName} on ${tableName}`;
528
+ this.freeze();
529
+ }
530
+ toOp() {
531
+ const constraint = constraintChecks(this.tableName, this.constraintName, "UNIQUE");
532
+ return {
533
+ id: `dropUnique.${this.tableName}.${this.constraintName}`,
534
+ label: this.label,
535
+ summary: `Drops unique constraint ${this.constraintName} on ${this.tableName} which is not in the contract`,
536
+ operationClass: "widening",
537
+ target: {
538
+ id: "mysql",
539
+ details: buildTargetDetails("unique", this.constraintName, this.tableName)
540
+ },
541
+ precheck: [constraint.present(`ensure unique constraint "${this.constraintName}" exists`)],
542
+ execute: [step(`drop unique constraint "${this.constraintName}"`, `ALTER TABLE ${quoteIdentifier(this.tableName)} DROP INDEX ${quoteIdentifier(this.constraintName)}`)],
543
+ postcheck: [constraint.absent(`verify unique constraint "${this.constraintName}" is gone`)]
544
+ };
545
+ }
546
+ renderTypeScript() {
547
+ return `this.dropUnique({ table: ${jsonToTsSource(this.tableName)}, name: ${jsonToTsSource(this.constraintName)} })`;
548
+ }
549
+ };
550
+ var AddForeignKeyCall = class extends MysqlOpFactoryCallNode {
551
+ tableName;
552
+ foreignKey;
553
+ factoryName = "addForeignKey";
554
+ operationClass = "additive";
555
+ label;
556
+ constructor(tableName, foreignKey) {
557
+ super();
558
+ this.tableName = tableName;
559
+ this.foreignKey = foreignKey;
560
+ this.label = `Add foreign key ${foreignKey.name} on ${tableName}`;
561
+ this.freeze();
562
+ }
563
+ toOp() {
564
+ const { name, columns, references } = this.foreignKey;
565
+ const constraint = constraintChecks(this.tableName, name, "FOREIGN KEY");
566
+ return {
567
+ id: `foreignKey.${this.tableName}.${name}`,
568
+ label: this.label,
569
+ summary: `Adds foreign key ${name} on ${this.tableName} referencing ${references.table}`,
570
+ operationClass: "additive",
571
+ target: {
572
+ id: "mysql",
573
+ details: buildTargetDetails("foreignKey", name, this.tableName)
574
+ },
575
+ precheck: [constraint.absent(`ensure foreign key "${name}" is missing`)],
576
+ execute: [step(`add foreign key "${name}"`, `ALTER TABLE ${quoteIdentifier(this.tableName)} ADD CONSTRAINT ${quoteIdentifier(name)} FOREIGN KEY (${columnList(columns)}) REFERENCES ${quoteIdentifier(references.table)} (${columnList(references.columns)})${foreignKeyActionsSql(this.foreignKey)}`)],
577
+ postcheck: [constraint.present(`verify foreign key "${name}" exists`)]
578
+ };
579
+ }
580
+ renderTypeScript() {
581
+ const { name, columns, references, onDelete, onUpdate } = this.foreignKey;
582
+ return `this.addForeignKey({ ${[
583
+ `table: ${jsonToTsSource(this.tableName)}`,
584
+ `name: ${jsonToTsSource(name)}`,
585
+ `columns: ${jsonToTsSource(columns)}`,
586
+ `references: ${jsonToTsSource(references)}`,
587
+ ...onDelete === void 0 ? [] : [`onDelete: ${jsonToTsSource(onDelete)}`],
588
+ ...onUpdate === void 0 ? [] : [`onUpdate: ${jsonToTsSource(onUpdate)}`]
589
+ ].join(", ")} })`;
590
+ }
591
+ };
592
+ var DropForeignKeyCall = class extends MysqlOpFactoryCallNode {
593
+ tableName;
594
+ constraintName;
595
+ factoryName = "dropForeignKey";
596
+ operationClass = "widening";
597
+ label;
598
+ constructor(tableName, constraintName) {
599
+ super();
600
+ this.tableName = tableName;
601
+ this.constraintName = constraintName;
602
+ this.label = `Drop foreign key ${constraintName} on ${tableName}`;
603
+ this.freeze();
604
+ }
605
+ toOp() {
606
+ const constraint = constraintChecks(this.tableName, this.constraintName, "FOREIGN KEY");
607
+ return {
608
+ id: `dropForeignKey.${this.tableName}.${this.constraintName}`,
609
+ label: this.label,
610
+ summary: `Drops foreign key ${this.constraintName} on ${this.tableName} which is not in the contract`,
611
+ operationClass: "widening",
612
+ target: {
613
+ id: "mysql",
614
+ details: buildTargetDetails("foreignKey", this.constraintName, this.tableName)
615
+ },
616
+ precheck: [constraint.present(`ensure foreign key "${this.constraintName}" exists`)],
617
+ execute: [step(`drop foreign key "${this.constraintName}"`, `ALTER TABLE ${quoteIdentifier(this.tableName)} DROP FOREIGN KEY ${quoteIdentifier(this.constraintName)}`)],
618
+ postcheck: [constraint.absent(`verify foreign key "${this.constraintName}" is gone`)]
619
+ };
620
+ }
621
+ renderTypeScript() {
622
+ return `this.dropForeignKey({ table: ${jsonToTsSource(this.tableName)}, name: ${jsonToTsSource(this.constraintName)} })`;
623
+ }
624
+ };
625
+ /** An operation built elsewhere, such as the table rename a user writes by hand, carried as it is and written as `rawSql({...})`. */
626
+ var RawSqlCall = class extends MysqlOpFactoryCallNode {
627
+ op;
628
+ factoryName = "rawSql";
629
+ operationClass;
630
+ label;
631
+ constructor(op) {
632
+ super();
633
+ this.op = op;
634
+ this.label = op.label;
635
+ this.operationClass = op.operationClass;
636
+ this.freeze();
637
+ }
638
+ toOp() {
639
+ return this.op;
640
+ }
641
+ renderTypeScript() {
642
+ return `rawSql(${jsonToTsSource(this.op)})`;
643
+ }
644
+ importRequirements() {
645
+ return [{
646
+ moduleSpecifier: TARGET_MIGRATION_MODULE,
647
+ symbol: "rawSql"
648
+ }];
649
+ }
650
+ };
651
+ /** The table rename a user writes by hand on MySQL, which the planner does not plan yet. */
652
+ function renameTableByHandOp(from, to) {
653
+ const fromTable = tableChecks(from);
654
+ const toTable = tableChecks(to);
655
+ return {
656
+ id: `renameTable.${from}`,
657
+ label: `Rename table ${from} to ${to}`,
658
+ operationClass: "widening",
659
+ target: {
660
+ id: "mysql",
661
+ details: buildTargetDetails("table", to)
662
+ },
663
+ precheck: [fromTable.present(`ensure table "${from}" exists`), toTable.absent(`ensure table "${to}" does not exist`)],
664
+ execute: [step(`rename table "${from}" to "${to}"`, `RENAME TABLE ${quoteIdentifier(from)} TO ${quoteIdentifier(to)}`)],
665
+ postcheck: [toTable.present(`verify table "${to}" exists`), fromTable.absent(`verify table "${from}" no longer exists`)]
666
+ };
667
+ }
668
+ function foreignKeySpecOf(fk, table) {
669
+ return {
670
+ name: fk.name ?? `${table}_${fk.columns.join("_")}_fkey`,
671
+ columns: fk.columns,
672
+ references: {
673
+ table: fk.referencedTable,
674
+ columns: fk.referencedColumns
675
+ },
676
+ ...ifDefined("onDelete", fk.onDelete),
677
+ ...ifDefined("onUpdate", fk.onUpdate)
678
+ };
679
+ }
680
+ /**
681
+ * Drops each issue under a missing or extra node: the call for a table or column accounts for everything beneath it.
682
+ */
683
+ function coalesceSubtreeIssues(issues) {
684
+ const collapsing = issues.filter((issue) => {
685
+ const outcome = issueOutcome(issue);
686
+ return outcome === "not-found" || outcome === "not-expected";
687
+ }).map((issue) => issue.path);
688
+ return issues.filter((issue) => !collapsing.some((ancestor) => issue.path.length > ancestor.length && ancestor.every((segment, index) => issue.path[index] === segment)));
689
+ }
690
+ function issueNode(issue) {
691
+ const node = issue.expected ?? issue.actual;
692
+ return node === void 0 ? void 0 : blindCast(node);
693
+ }
694
+ function expectedNode(issue) {
695
+ return blindCast(issue.expected);
696
+ }
697
+ function actualNode(issue) {
698
+ return blindCast(issue.actual);
699
+ }
700
+ function location(table, column) {
701
+ return {
702
+ entityKind: "table",
703
+ ...table === void 0 ? {} : { entityName: table },
704
+ ...column === void 0 ? {} : { column }
705
+ };
706
+ }
707
+ function placeOf(issue, at) {
708
+ if (at?.entityName === void 0) return issue.path.slice(1).join(".");
709
+ return at.column === void 0 ? at.entityName : `${at.entityName}.${at.column}`;
710
+ }
711
+ /** The conflict for a change the MySQL planner does not plan yet. */
712
+ function notYetSupported(kind, change, issue, conflictLocation) {
713
+ return {
714
+ kind,
715
+ summary: `${change} is not yet supported on MySQL (${placeOf(issue, conflictLocation)})`,
716
+ why: "The MySQL planner creates and drops tables, columns, indexes, unique constraints and foreign keys; it does not change a column, a default, a primary key or a CHECK constraint yet. Use `migration new` to write this change by hand.",
717
+ ...conflictLocation === void 0 ? {} : { location: conflictLocation }
718
+ };
719
+ }
720
+ function createTableCalls(table) {
721
+ return [
722
+ new CreateTableCall(table.name, Object.values(table.columns).map(ddlColumnFromNode), tableConstraintsFromNode(table)),
723
+ ...table.indexes.flatMap((index) => index.columns === void 0 ? [] : [new CreateIndexCall(table.name, index.name, index.columns, index.unique)]),
724
+ ...table.foreignKeys.map((fk) => new AddForeignKeyCall(table.name, foreignKeySpecOf(fk, table.name)))
725
+ ];
726
+ }
727
+ function mapTableIssue(issue) {
728
+ switch (issueOutcome(issue)) {
729
+ case "not-found": {
730
+ const table = expectedNode(issue);
731
+ return table.indexes.find((index) => index.columns === void 0) === void 0 ? ok(createTableCalls(table)) : notOk(notYetSupported("indexIncompatible", "An expression index", issue, location(table.name)));
732
+ }
733
+ case "not-expected": {
734
+ const table = actualNode(issue);
735
+ return ok(CONTROL_TABLE_NAMES.has(table.name) ? [] : [new DropTableCall(table.name)]);
736
+ }
737
+ default: return notOk(notYetSupported("unsupportedOperation", "Changing a table", issue));
738
+ }
739
+ }
740
+ function mapColumnIssue(issue, table) {
741
+ switch (issueOutcome(issue)) {
742
+ case "not-found": {
743
+ const column = expectedNode(issue);
744
+ const columnDefault = columnDefaultOf(column);
745
+ return column.nullable || columnDefault !== void 0 && !(columnDefault.kind === "function" && columnDefault.expression === "autoincrement()") ? ok([new AddColumnCall(table, ddlColumnFromNode(column))]) : notOk(notYetSupported("nullabilityConflict", "Adding a required column without a default", issue, location(table, column.name)));
746
+ }
747
+ case "not-expected": return ok([new DropColumnCall(table, actualNode(issue).name)]);
748
+ default: {
749
+ const expected = expectedNode(issue);
750
+ const typesEqual = sqlColumnTypesEqual(expected, actualNode(issue));
751
+ return notOk(notYetSupported(typesEqual ? "nullabilityConflict" : "typeMismatch", typesEqual ? "Changing a column's nullability" : "Changing a column's type", issue, location(table, expected.name)));
752
+ }
753
+ }
754
+ }
755
+ function mapIndexIssue(issue, table) {
756
+ switch (issueOutcome(issue)) {
757
+ case "not-found": {
758
+ const index = expectedNode(issue);
759
+ return index.columns === void 0 ? notOk(notYetSupported("indexIncompatible", "An expression index", issue, location(table))) : ok([new CreateIndexCall(table, index.name, index.columns, index.unique)]);
760
+ }
761
+ case "not-expected": return ok([new DropIndexCall(table, actualNode(issue).name)]);
762
+ default: return notOk(notYetSupported("indexIncompatible", "Changing an index", issue, location(table)));
763
+ }
764
+ }
765
+ function mapUniqueIssue(issue, table) {
766
+ switch (issueOutcome(issue)) {
767
+ case "not-found": {
768
+ const unique = expectedNode(issue);
769
+ return ok([new AddUniqueCall(table, uniqueName(table, unique), unique.columns)]);
770
+ }
771
+ case "not-expected": return ok([new DropUniqueCall(table, uniqueName(table, actualNode(issue)))]);
772
+ default: return notOk(notYetSupported("indexIncompatible", "Changing a unique constraint", issue, location(table)));
773
+ }
774
+ }
775
+ function mapForeignKeyIssue(issue, table) {
776
+ switch (issueOutcome(issue)) {
777
+ case "not-found": return ok([new AddForeignKeyCall(table, foreignKeySpecOf(expectedNode(issue), table))]);
778
+ case "not-expected": return ok([new DropForeignKeyCall(table, foreignKeySpecOf(actualNode(issue), table).name)]);
779
+ default: return notOk(notYetSupported("foreignKeyConflict", "Changing a foreign key", issue, location(table)));
780
+ }
781
+ }
782
+ function mapIssueToCalls(issue) {
783
+ const node = issueNode(issue);
784
+ const table = issue.path[1];
785
+ if (node === void 0) return notOk(notYetSupported("unsupportedOperation", "A change with no node", issue));
786
+ if (node.nodeKind === RelationalSchemaNodeKind.table) return mapTableIssue(issue);
787
+ if (table === void 0) return notOk(notYetSupported("unsupportedOperation", `A ${node.nodeKind} change`, issue));
788
+ switch (node.nodeKind) {
789
+ case RelationalSchemaNodeKind.column: return mapColumnIssue(issue, table);
790
+ case RelationalSchemaNodeKind.index: return mapIndexIssue(issue, table);
791
+ case RelationalSchemaNodeKind.unique: return mapUniqueIssue(issue, table);
792
+ case RelationalSchemaNodeKind.foreignKey: return mapForeignKeyIssue(issue, table);
793
+ case RelationalSchemaNodeKind.columnDefault: return notOk(notYetSupported("unsupportedOperation", "Changing a column's default", issue, location(table)));
794
+ case RelationalSchemaNodeKind.primaryKey: return notOk(notYetSupported("indexIncompatible", "Changing a primary key", issue, location(table)));
795
+ case RelationalSchemaNodeKind.check: return notOk(notYetSupported("unsupportedOperation", "A CHECK constraint", issue, location(table)));
796
+ default: return notOk(notYetSupported("unsupportedOperation", `A ${node.nodeKind} change`, issue));
797
+ }
798
+ }
799
+ /**
800
+ * The order calls run in: foreign keys are dropped before the tables, columns and indexes they use, and added after every table, column and index they need exists. The index InnoDB made for a dropped key is dropped right after the key, before any key is added, so a new key on the same columns makes its own.
801
+ */
802
+ const CALL_ORDER = [
803
+ "dropForeignKey",
804
+ "createTable",
805
+ "addColumn",
806
+ "addUnique",
807
+ "createIndex",
808
+ "addForeignKey",
809
+ "dropUnique",
810
+ "dropIndex",
811
+ "dropColumn",
812
+ "dropTable",
813
+ "rawSql"
814
+ ];
815
+ function locationOfCall(call) {
816
+ return "tableName" in call ? {
817
+ entityKind: "table",
818
+ entityName: call.tableName,
819
+ ..."columnName" in call ? { column: call.columnName } : {},
820
+ ..."indexName" in call ? { index: call.indexName } : {}
821
+ } : void 0;
822
+ }
823
+ function conflictForDisallowedCall(call, allowed) {
824
+ const callLocation = locationOfCall(call);
825
+ return {
826
+ kind: call instanceof CreateIndexCall || call instanceof DropIndexCall ? "indexIncompatible" : "missingButNonAdditive",
827
+ summary: `Operation "${call.label}" requires class "${call.operationClass}", but policy allows only: ${allowed.join(", ")}`,
828
+ why: "Use `migration new` to author a custom migration for this change.",
829
+ refusedOperationClass: call.operationClass,
830
+ ...callLocation === void 0 ? {} : { location: callLocation }
831
+ };
832
+ }
833
+ const MAX_IDENTIFIER_CHARACTERS = 64;
834
+ /** The names a call gives new objects, each with where the conflict that refuses it points. */
835
+ function namesGiven(call) {
836
+ if (call instanceof CreateTableCall) return [
837
+ {
838
+ name: call.tableName,
839
+ at: location(call.tableName)
840
+ },
841
+ ...call.columns.map((column) => ({
842
+ name: column.name,
843
+ at: location(call.tableName, column.name)
844
+ })),
845
+ ...call.constraints.flatMap((constraint) => constraint.name === void 0 ? [] : [{
846
+ name: constraint.name,
847
+ at: {
848
+ ...location(call.tableName),
849
+ constraint: constraint.name
850
+ }
851
+ }])
852
+ ];
853
+ if (call instanceof AddColumnCall) return [{
854
+ name: call.column.name,
855
+ at: location(call.tableName, call.column.name)
856
+ }];
857
+ if (call instanceof CreateIndexCall) return [{
858
+ name: call.indexName,
859
+ at: {
860
+ ...location(call.tableName),
861
+ index: call.indexName
862
+ }
863
+ }];
864
+ if (call instanceof AddUniqueCall) return [{
865
+ name: call.constraintName,
866
+ at: {
867
+ ...location(call.tableName),
868
+ constraint: call.constraintName
869
+ }
870
+ }];
871
+ if (call instanceof AddForeignKeyCall) return [{
872
+ name: call.foreignKey.name,
873
+ at: {
874
+ ...location(call.tableName),
875
+ constraint: call.foreignKey.name
876
+ }
877
+ }];
878
+ return [];
879
+ }
880
+ function placeText(at) {
881
+ return at.column === void 0 ? `${at.entityName}` : `${at.entityName}.${at.column}`;
882
+ }
883
+ /** MySQL refuses a name longer than 64 characters only when the statement runs, after the statements before it committed, so the planner refuses it first. */
884
+ function longNameConflicts(call) {
885
+ return namesGiven(call).filter(({ name }) => Array.from(name).length > MAX_IDENTIFIER_CHARACTERS).map(({ name, at }) => ({
886
+ kind: "unsupportedOperation",
887
+ summary: `The name ${name} is longer than the ${MAX_IDENTIFIER_CHARACTERS} characters MySQL allows (${placeText(at)})`,
888
+ why: `MySQL refuses a table, column, index or constraint name longer than ${MAX_IDENTIFIER_CHARACTERS} characters. Give it a shorter name in the contract.`,
889
+ location: at
890
+ }));
891
+ }
892
+ function isAutoincrement(column) {
893
+ return column.default?.kind === "function" && column.default.expression.text === "autoincrement()";
894
+ }
895
+ /** MySQL refuses a table whose `AUTO_INCREMENT` column does not lead a key, so the planner refuses it first. */
896
+ function autoincrementKeyConflicts(call) {
897
+ if (!(call instanceof CreateTableCall)) return [];
898
+ const keyLeaders = new Set(call.constraints.flatMap((constraint) => constraint.kind === "primary-key" || constraint.kind === "unique" ? constraint.columns.slice(0, 1) : []));
899
+ return call.columns.filter((column) => isAutoincrement(column) && !column.primaryKey && !keyLeaders.has(column.name)).map((column) => ({
900
+ kind: "unsupportedOperation",
901
+ summary: `An autoincrement column that is not the first column of the primary key or a unique constraint is not supported on MySQL (${call.tableName}.${column.name})`,
902
+ why: "MySQL requires an AUTO_INCREMENT column to be the first column of a key, and refuses the table otherwise.",
903
+ location: location(call.tableName, column.name)
904
+ }));
905
+ }
906
+ /** Whether an index on `indexColumns` can serve a foreign key on `keyColumns`: InnoDB needs the key's columns first, in order. */
907
+ function servesKey(indexColumns, keyColumns) {
908
+ return keyColumns.length <= indexColumns.length && keyColumns.every((column, position) => indexColumns[position] === column);
909
+ }
910
+ function indexColumnLists(table, leaving) {
911
+ return [
912
+ ...table.primaryKey === void 0 ? [] : [table.primaryKey.columns],
913
+ ...table.uniques.flatMap((unique) => uniqueName(table.name, unique) === leaving ? [] : [unique.columns]),
914
+ ...table.indexes.flatMap((index) => index.name === leaving || index.columns === void 0 ? [] : [index.columns])
915
+ ];
916
+ }
917
+ function isKeyServed(table, keyColumns, leaving) {
918
+ return indexColumnLists(table, leaving).some((columns) => servesKey(columns, keyColumns));
919
+ }
920
+ /**
921
+ * When a foreign key is dropped and no other index served it, InnoDB made an index of its own, with the key's name, and keeps it after the key is gone. Introspection leaves that index out while the key exists, so it is dropped with the key unless the destination keeps an index of that name.
922
+ */
923
+ function innoDbIndexDrops(calls, expected, actual) {
924
+ return calls.flatMap((call) => {
925
+ if (!(call instanceof DropForeignKeyCall)) return [];
926
+ const before = actual.tables[call.tableName];
927
+ const after = expected.tables[call.tableName];
928
+ const key = before?.foreignKeys.find((fk) => foreignKeySpecOf(fk, call.tableName).name === call.constraintName);
929
+ if (before === void 0 || after === void 0 || key === void 0) return [];
930
+ if (isKeyServed(before, key.columns)) return [];
931
+ if (after.indexes.some((index) => index.name === call.constraintName)) return [];
932
+ return [{
933
+ call: new DropIndexCall(call.tableName, call.constraintName),
934
+ indexName: call.constraintName,
935
+ columns: key.columns
936
+ }];
937
+ });
938
+ }
939
+ function droppedIndexes(calls, actual) {
940
+ return calls.flatMap((call) => {
941
+ const table = "tableName" in call ? actual.tables[call.tableName] : void 0;
942
+ if (table === void 0) return [];
943
+ if (call instanceof DropIndexCall) {
944
+ const index = table.indexes.find(({ name }) => name === call.indexName);
945
+ return index?.columns === void 0 ? [] : [{
946
+ call,
947
+ indexName: call.indexName,
948
+ columns: index.columns
949
+ }];
950
+ }
951
+ if (call instanceof DropUniqueCall) {
952
+ const unique = table.uniques.find((candidate) => uniqueName(table.name, candidate) === call.constraintName);
953
+ return unique === void 0 ? [] : [{
954
+ call,
955
+ indexName: call.constraintName,
956
+ columns: unique.columns
957
+ }];
958
+ }
959
+ return [];
960
+ });
961
+ }
962
+ /**
963
+ * A dropped index that one of `protectedKeys` uses, when no index the destination keeps can take over: MySQL refuses that drop.
964
+ */
965
+ function conflictForIndexAKeyUses(dropped, expected, protectedKeys) {
966
+ const tableName = dropped.call.tableName;
967
+ const table = expected.tables[tableName];
968
+ const key = table?.foreignKeys.find((fk) => protectedKeys(tableName, fk) && servesKey(dropped.columns, fk.columns) && !isKeyServed(table, fk.columns, dropped.indexName));
969
+ if (key === void 0) return void 0;
970
+ return {
971
+ kind: "indexIncompatible",
972
+ summary: `Dropping index ${dropped.indexName}, which foreign key ${foreignKeySpecOf(key, tableName).name} uses, is not yet supported on MySQL (${tableName})`,
973
+ why: "MySQL refuses to drop an index a foreign key uses. Keep an index whose first columns are the foreign key's columns, or use `migration new` to drop the foreign key, drop the index and add the foreign key again.",
974
+ location: {
975
+ entityKind: "table",
976
+ entityName: tableName,
977
+ index: dropped.indexName
978
+ }
979
+ };
980
+ }
981
+ /** The calls that turn `actual` into `expected` for `issues`, in the order they run, or the conflicts that stop the plan. */
982
+ function planIssues(input) {
983
+ const calls = [];
984
+ const conflicts = [];
985
+ const allowed = input.policy.allowedOperationClasses;
986
+ for (const issue of orderIssuesByDependencies(input.issues)) {
987
+ const mapped = mapIssueToCalls(issue);
988
+ if (!mapped.ok) {
989
+ conflicts.push(mapped.failure);
990
+ continue;
991
+ }
992
+ for (const call of mapped.value) {
993
+ conflicts.push(...longNameConflicts(call), ...autoincrementKeyConflicts(call));
994
+ if (allowed.includes(call.operationClass)) calls.push(call);
995
+ else conflicts.push(conflictForDisallowedCall(call, allowed));
996
+ }
997
+ }
998
+ const droppedKeys = new Set(calls.flatMap((call) => call instanceof DropForeignKeyCall ? [`${call.tableName}.${call.constraintName}`] : []));
999
+ const isKeptKey = (tableName, fk) => !droppedKeys.has(`${tableName}.${foreignKeySpecOf(fk, tableName).name}`);
1000
+ for (const dropped of droppedIndexes(calls, input.actual)) {
1001
+ const conflict = conflictForIndexAKeyUses(dropped, input.expected, () => true);
1002
+ if (conflict !== void 0) conflicts.push(conflict);
1003
+ }
1004
+ const innoDbIndexes = innoDbIndexDrops(calls, input.expected, input.actual);
1005
+ for (const dropped of innoDbIndexes) {
1006
+ const conflict = conflictForIndexAKeyUses(dropped, input.expected, isKeptKey);
1007
+ if (conflict !== void 0) conflicts.push(conflict);
1008
+ if (!allowed.includes(dropped.call.operationClass)) conflicts.push(conflictForDisallowedCall(dropped.call, allowed));
1009
+ }
1010
+ if (conflicts.length > 0) return notOk(conflicts);
1011
+ const inOrder = (factoryName) => calls.filter((call) => call.factoryName === factoryName);
1012
+ return ok([
1013
+ ...inOrder("dropForeignKey"),
1014
+ ...innoDbIndexes.map(({ call }) => call),
1015
+ ...CALL_ORDER.filter((factoryName) => factoryName !== "dropForeignKey").flatMap(inOrder)
1016
+ ]);
1017
+ }
1018
+ /**
1019
+ * The base class of a MySQL `migration.ts`. Each protected method returns the operation its name says, rendered through the MySQL control adapter the migration CLI builds from `prisma.config.ts`.
1020
+ */
1021
+ var MysqlMigration = class extends Migration {
1022
+ targetId = "mysql";
1023
+ controlAdapter;
1024
+ constructor(stack) {
1025
+ super(stack);
1026
+ this.controlAdapter = stack?.adapter === void 0 ? void 0 : blindCast(stack.adapter.create(stack));
1027
+ }
1028
+ adapterFor(operation) {
1029
+ if (this.controlAdapter === void 0) throw mysqlMigrationStackMissing(operation);
1030
+ return this.controlAdapter;
1031
+ }
1032
+ createTable(options) {
1033
+ return new CreateTableCall(options.table, options.columns, options.constraints ?? []).toOp(this.adapterFor("createTable"));
1034
+ }
1035
+ dropTable(options) {
1036
+ return new DropTableCall(options.table).toOp();
1037
+ }
1038
+ addColumn(options) {
1039
+ return new AddColumnCall(options.table, options.column).toOp(this.adapterFor("addColumn"));
1040
+ }
1041
+ dropColumn(options) {
1042
+ return new DropColumnCall(options.table, options.column).toOp();
1043
+ }
1044
+ createIndex(options) {
1045
+ return new CreateIndexCall(options.table, options.index, options.columns, options.unique === true).toOp();
1046
+ }
1047
+ dropIndex(options) {
1048
+ return new DropIndexCall(options.table, options.index).toOp();
1049
+ }
1050
+ addUnique(options) {
1051
+ return new AddUniqueCall(options.table, options.name, options.columns).toOp();
1052
+ }
1053
+ dropUnique(options) {
1054
+ return new DropUniqueCall(options.table, options.name).toOp();
1055
+ }
1056
+ addForeignKey(options) {
1057
+ return new AddForeignKeyCall(options.table, {
1058
+ name: options.name,
1059
+ columns: options.columns,
1060
+ references: options.references,
1061
+ ...ifDefined("onDelete", options.onDelete),
1062
+ ...ifDefined("onUpdate", options.onUpdate)
1063
+ }).toOp();
1064
+ }
1065
+ dropForeignKey(options) {
1066
+ return new DropForeignKeyCall(options.table, options.name).toOp();
1067
+ }
1068
+ };
1069
+ function assertMysqlOp(op, factoryName) {
1070
+ const targetId = blindCast(op).target?.id;
1071
+ if (targetId !== "mysql") throw new InternalError(`renderOps: expected a mysql operation but got target.id="${String(targetId)}" for op.id="${op.id}" (factoryName="${factoryName}").`);
1072
+ }
1073
+ function checkedOp(opOrPromise, factoryName) {
1074
+ if (isThenable(opOrPromise)) {
1075
+ const checked = opOrPromise.then((op) => {
1076
+ assertMysqlOp(op, factoryName);
1077
+ return op;
1078
+ });
1079
+ checked.catch(() => void 0);
1080
+ return checked;
1081
+ }
1082
+ assertMysqlOp(opOrPromise, factoryName);
1083
+ return opOrPromise;
1084
+ }
1085
+ /** The operations `calls` lower to, in order, each checked to be a MySQL operation. */
1086
+ function renderOps(calls, lowerer) {
1087
+ return calls.map((call) => checkedOp(isMysqlOpFactoryCall(call) ? call.toOp(lowerer) : blindCast(call).toOp(lowerer), call.factoryName));
1088
+ }
1089
+ /** The base class and the CLI entrypoint every scaffold imports, both from the MySQL facade's `migration` module. */
1090
+ const BASE_IMPORTS = [{
1091
+ moduleSpecifier: "@internal/mysql/migration",
1092
+ symbol: "Migration"
1093
+ }, {
1094
+ moduleSpecifier: "@internal/mysql/migration",
1095
+ symbol: "MigrationCLI"
1096
+ }];
1097
+ function renderCallsToTypeScript(calls, meta) {
1098
+ const imports = buildImports(calls, meta);
1099
+ const operationsBody = calls.map((c) => c.renderTypeScript()).join(",\n");
1100
+ const hasStart = meta.from !== null;
1101
+ const startField = hasStart ? [" override readonly startContractJson = startContract;"] : [];
1102
+ return [
1103
+ shebangLineFor(detectScaffoldRuntime()),
1104
+ imports,
1105
+ "",
1106
+ `export default class M extends Migration<${hasStart ? "Start" : "never"}, End> {`,
1107
+ ...startField,
1108
+ " override readonly endContractJson = endContract;",
1109
+ "",
1110
+ " override get operations() {",
1111
+ " return [",
1112
+ indent(operationsBody, 6),
1113
+ " ];",
1114
+ " }",
1115
+ "}",
1116
+ "",
1117
+ "MigrationCLI.run(import.meta.url, M);",
1118
+ ""
1119
+ ].join("\n");
1120
+ }
1121
+ function buildImports(calls, meta) {
1122
+ const requirements = [...BASE_IMPORTS, ...contractImports(meta)];
1123
+ for (const call of calls) for (const req of call.importRequirements()) requirements.push(req);
1124
+ return renderImports(resolveRequirementSpecifiers(requirements, meta.resolveImportSpecifier));
1125
+ }
1126
+ function contractImports(meta) {
1127
+ const reqs = [{
1128
+ moduleSpecifier: contractSnapshotJsonSpecifier(meta.snapshotsImportPath, meta.to),
1129
+ symbol: "endContract",
1130
+ kind: "default",
1131
+ attributes: { type: "json" }
1132
+ }, {
1133
+ moduleSpecifier: contractSnapshotTypesSpecifier(meta.snapshotsImportPath, meta.to),
1134
+ symbol: "Contract",
1135
+ alias: "End",
1136
+ typeOnly: true
1137
+ }];
1138
+ if (meta.from !== null) {
1139
+ reqs.push({
1140
+ moduleSpecifier: contractSnapshotJsonSpecifier(meta.snapshotsImportPath, meta.from),
1141
+ symbol: "startContract",
1142
+ kind: "default",
1143
+ attributes: { type: "json" }
1144
+ });
1145
+ reqs.push({
1146
+ moduleSpecifier: contractSnapshotTypesSpecifier(meta.snapshotsImportPath, meta.from),
1147
+ symbol: "Contract",
1148
+ alias: "Start",
1149
+ typeOnly: true
1150
+ });
1151
+ }
1152
+ return reqs;
1153
+ }
1154
+ function indent(text, spaces) {
1155
+ const pad = " ".repeat(spaces);
1156
+ return text.split("\n").map((line) => line.trim() ? `${pad}${line}` : line).join("\n");
1157
+ }
1158
+ /** The plan the MySQL planner produces: its operations, and the `migration.ts` that writes them. */
1159
+ var TypeScriptRenderableMysqlMigration = class extends MysqlMigration {
1160
+ #calls;
1161
+ #meta;
1162
+ #destination;
1163
+ #spaceId;
1164
+ #snapshotsImportPath;
1165
+ #lowerer;
1166
+ #operationsCache;
1167
+ constructor(options) {
1168
+ super();
1169
+ this.#calls = options.calls;
1170
+ this.#meta = options.meta;
1171
+ this.#spaceId = options.spaceId;
1172
+ this.#snapshotsImportPath = options.snapshotsImportPath;
1173
+ this.#destination = options.destination ?? { storageHash: options.meta.to };
1174
+ this.#lowerer = options.lowerer;
1175
+ }
1176
+ get operations() {
1177
+ this.#operationsCache ??= renderOps(this.#calls, this.#lowerer);
1178
+ return this.#operationsCache;
1179
+ }
1180
+ describe() {
1181
+ return this.#meta;
1182
+ }
1183
+ get destination() {
1184
+ return this.#destination;
1185
+ }
1186
+ get spaceId() {
1187
+ return this.#spaceId;
1188
+ }
1189
+ renderTypeScript(resolveImportSpecifier) {
1190
+ return renderCallsToTypeScript(this.#calls, {
1191
+ from: this.#meta.from,
1192
+ to: this.#meta.to,
1193
+ snapshotsImportPath: this.#snapshotsImportPath,
1194
+ resolveImportSpecifier
1195
+ });
1196
+ }
1197
+ };
1198
+ const mysqlTableRenameByHand = {
1199
+ renderTableRename: (rename) => new RawSqlCall(renameTableByHandOp(rename.from, rename.to)).renderTypeScript(),
1200
+ tableRenameByHand: (rename) => [`RENAME TABLE ${quoteIdentifier(rename.from)} TO ${quoteIdentifier(rename.to)}`]
1201
+ };
1202
+ function tableTarget(table, column) {
1203
+ return {
1204
+ storageName: column === void 0 ? table : `${table}.${column}`,
1205
+ table: {
1206
+ namespaceId: UNBOUND_NAMESPACE_ID,
1207
+ table,
1208
+ column
1209
+ }
1210
+ };
1211
+ }
1212
+ function callSubjects(call) {
1213
+ const dataLoss = call instanceof DropTableCall ? [{
1214
+ ...tableTarget(call.tableName),
1215
+ loss: "drop"
1216
+ }] : call instanceof DropColumnCall ? [{
1217
+ ...tableTarget(call.tableName, call.columnName),
1218
+ loss: "drop"
1219
+ }] : [];
1220
+ return {
1221
+ operationCount: 1,
1222
+ label: call.label,
1223
+ dataLoss,
1224
+ accessChanges: [],
1225
+ temporaryValues: []
1226
+ };
1227
+ }
1228
+ /** Whether `issue` is an extra table some contract space owns, which this space must leave alone. */
1229
+ function isTableOwnedElsewhere(issue, ownership) {
1230
+ if (issueOutcome(issue) !== "not-expected") return false;
1231
+ if (issueNode(issue)?.nodeKind !== RelationalSchemaNodeKind.table) return false;
1232
+ const table = issue.path[1];
1233
+ return table !== void 0 && ownership.declaresEntity({
1234
+ namespaceId: UNBOUND_NAMESPACE_ID,
1235
+ entityKind: "table",
1236
+ entityName: table
1237
+ });
1238
+ }
1239
+ /**
1240
+ * The MySQL migration planner. It diffs the contract's schema against the live one and plans creating and dropping tables, columns, indexes, unique constraints and foreign keys. Every other change, and every statement such as a rename, is refused with a conflict that says it is not yet supported on MySQL.
1241
+ */
1242
+ var MysqlMigrationPlanner = class {
1243
+ #lowerer;
1244
+ constructor(lowerer) {
1245
+ this.#lowerer = lowerer;
1246
+ }
1247
+ plan(options) {
1248
+ return this.#planSql(blindCast(options));
1249
+ }
1250
+ emptyMigration(context, spaceId) {
1251
+ return new TypeScriptRenderableMysqlMigration({
1252
+ calls: [],
1253
+ meta: {
1254
+ from: context.fromHash,
1255
+ to: context.toHash
1256
+ },
1257
+ spaceId,
1258
+ snapshotsImportPath: context.snapshotsImportPath,
1259
+ lowerer: this.#lowerer
1260
+ });
1261
+ }
1262
+ #planSql(options) {
1263
+ if (!options.policy.allowedOperationClasses.includes("additive")) return plannerFailure([{
1264
+ kind: "unsupportedOperation",
1265
+ summary: "Migration planner requires additive operations be allowed",
1266
+ why: "The planner requires the \"additive\" operation class to be allowed in the policy."
1267
+ }]);
1268
+ const [statement] = options.statements;
1269
+ if (statement !== void 0) return plannerFailure([statementNotYetSupported(statement)]);
1270
+ if (!(options.schema instanceof SqlSchemaIR)) throw mysqlError("CONTRACT.TARGET_MISMATCH", "The MySQL planner received a schema tree that neither MySQL introspection nor contractToSchema built.");
1271
+ const expected = mysqlContractToSchema(options.contract, sqlTypeLookupsOf(options.frameworkComponents));
1272
+ const actual = options.schema;
1273
+ const allowed = options.policy.allowedOperationClasses;
1274
+ const strict = allowed.includes("widening") || allowed.includes("destructive");
1275
+ const { ownership } = options;
1276
+ const planned = planIssues({
1277
+ issues: coalesceSubtreeIssues(diffSchemas(expected, actual)).filter((issue) => (strict || issueOutcome(issue) !== "not-expected") && (ownership === void 0 || !isTableOwnedElsewhere(issue, ownership))),
1278
+ expected,
1279
+ actual,
1280
+ policy: options.policy
1281
+ });
1282
+ if (!planned.ok) return plannerFailure(planned.failure);
1283
+ const calls = planned.value;
1284
+ return {
1285
+ kind: "success",
1286
+ plan: new TypeScriptRenderableMysqlMigration({
1287
+ calls,
1288
+ meta: {
1289
+ from: options.origin?.storageHash ?? null,
1290
+ to: options.contract.storage.storageHash
1291
+ },
1292
+ spaceId: options.spaceId,
1293
+ snapshotsImportPath: options.snapshotsImportPath,
1294
+ destination: {
1295
+ storageHash: options.contract.storage.storageHash,
1296
+ ...options.contract.profileHash === void 0 ? {} : { profileHash: options.contract.profileHash }
1297
+ },
1298
+ lowerer: this.#lowerer
1299
+ }),
1300
+ appliedStatements: [],
1301
+ ...subjectsOfCalls(calls.map(callSubjects), {
1302
+ fromContract: options.fromContract,
1303
+ contract: options.contract,
1304
+ origins: NO_RENAMED_ORIGINS,
1305
+ byHand: mysqlTableRenameByHand
1306
+ })
1307
+ };
1308
+ }
1309
+ };
1310
+ function statementNotYetSupported(statement) {
1311
+ return {
1312
+ kind: "statementRefused",
1313
+ summary: `A ${statement.kind} statement is not yet supported on MySQL`,
1314
+ why: "The MySQL planner plans no rename, conversion or backfill yet. Plan the change without the statement, or write it by hand in a migration of its own with `migration new`.",
1315
+ refusedStatement: statement
1316
+ };
1317
+ }
1318
+ function createMysqlMigrationPlanner(lowerer) {
1319
+ return new MysqlMigrationPlanner(lowerer);
1320
+ }
1321
+ /** An error without a structured code, such as a driver's socket error, thrown while a space applied: reported as `MIGRATION.EXECUTION_FAILED`, with its own code, when it has one, in `errorCode`. */
1322
+ function failureFromThrown(error) {
1323
+ const errorCode = typeof error === "object" && error !== null ? Reflect.get(error, "code") : void 0;
1324
+ return migrationRunnerFailure("MIGRATION.EXECUTION_FAILED", error instanceof Error ? error.message : String(error), {
1325
+ meta: typeof errorCode === "string" ? { errorCode } : {},
1326
+ cause: error
1327
+ });
1328
+ }
1329
+ /** The structured error thrown while a space applied, keeping its code, advice and docs link, with the space and whether the database changed added to its facts. */
1330
+ function withSpaceFacts(error, failingSpace, databaseUnchanged) {
1331
+ return Object.assign(error, { meta: {
1332
+ ...error.meta ?? {},
1333
+ failingSpace,
1334
+ databaseUnchanged
1335
+ } });
1336
+ }
1337
+ function stepHolds(rows) {
1338
+ const value = rows[0] === void 0 ? void 0 : Object.values(rows[0])[0];
1339
+ if (typeof value === "string") return value !== "0" && value.length > 0;
1340
+ return Boolean(value);
1341
+ }
1342
+ function skipRecord(operation) {
1343
+ return Object.freeze({
1344
+ id: operation.id,
1345
+ label: operation.label,
1346
+ ...ifDefined("summary", operation.summary),
1347
+ operationClass: operation.operationClass,
1348
+ target: operation.target,
1349
+ precheck: Object.freeze([]),
1350
+ execute: Object.freeze([]),
1351
+ postcheck: Object.freeze([...operation.postcheck]),
1352
+ meta: Object.freeze({
1353
+ ...operation.meta ?? {},
1354
+ runner: Object.freeze({
1355
+ skipped: true,
1356
+ reason: "postcheck_pre_satisfied"
1357
+ })
1358
+ })
1359
+ });
1360
+ }
1361
+ /**
1362
+ * The MySQL migration runner. MySQL commits every DDL statement as it runs, so no transaction can undo an apply: the runner applies one space at a time, checks each operation before and after it runs, verifies the space's schema with the caller's strictness (every space, not only the app space), and only then writes the space's marker and ledger entries, in one transaction. A failure leaves the spaces before it applied, and running the apply again skips what already holds. The whole apply holds the marker lock, which MySQL keeps for the session, so it is released on the same connection when the apply ends.
1363
+ */
1364
+ var MysqlMigrationRunner = class {
1365
+ family;
1366
+ constructor(family) {
1367
+ this.family = family;
1368
+ }
1369
+ async execute(options) {
1370
+ const { driver, perSpaceOptions } = options;
1371
+ if (perSpaceOptions.length === 0) return ok({ perSpaceResults: [] });
1372
+ return withMarkerLock(driver, () => this.#applySpaces(driver, perSpaceOptions), (result) => result.ok);
1373
+ }
1374
+ async executeOnConnection(options) {
1375
+ return this.#applySpace(options, { changedDatabase: false });
1376
+ }
1377
+ async #applySpaces(driver, perSpaceOptions) {
1378
+ const perSpaceResults = [];
1379
+ let changedBefore = false;
1380
+ for (const spaceOptions of perSpaceOptions) {
1381
+ const space = spaceOptions.space ?? spaceOptions.plan.spaceId;
1382
+ const progress = { changedDatabase: false };
1383
+ let result;
1384
+ try {
1385
+ result = await this.#applySpace({
1386
+ ...spaceOptions,
1387
+ driver,
1388
+ space
1389
+ }, progress);
1390
+ } catch (error) {
1391
+ if (isInternalError(error)) throw error;
1392
+ const databaseUnchanged = !changedBefore && !progress.changedDatabase;
1393
+ if (isStructuredError(error)) throw withSpaceFacts(error, space, databaseUnchanged);
1394
+ result = notOk(failureFromThrown(error));
1395
+ }
1396
+ if (!result.ok) return notOk(withFailingSpace(withDatabaseUnchanged(result.failure, !changedBefore && !progress.changedDatabase), space));
1397
+ changedBefore ||= progress.changedDatabase;
1398
+ perSpaceResults.push({
1399
+ space,
1400
+ value: result.value
1401
+ });
1402
+ }
1403
+ return ok({ perSpaceResults });
1404
+ }
1405
+ async #applySpace(options, progress) {
1406
+ const { driver } = options;
1407
+ if (options.space !== void 0 && options.space !== options.plan.spaceId) throw mysqlError("MIGRATION.CONTRACT_SPACE_VIOLATION", `SqlMigrationRunner: options.space (${options.space}) does not match plan.spaceId (${options.plan.spaceId})`, { meta: {
1408
+ space: options.space,
1409
+ planSpaceId: options.plan.spaceId
1410
+ } });
1411
+ const space = options.plan.spaceId;
1412
+ const operations = blindCast(await Promise.all(options.plan.operations));
1413
+ const destinationCheck = this.#checkDestination(options.plan.destination, options.destinationContract);
1414
+ if (!destinationCheck.ok) return destinationCheck;
1415
+ const policyCheck = this.#checkPolicy(options.policy, operations);
1416
+ if (!policyCheck.ok) return policyCheck;
1417
+ await this.#ensureControlTables(driver, options);
1418
+ const existingMarker = await this.family.readMarker({
1419
+ driver,
1420
+ space
1421
+ });
1422
+ const originCheck = this.#checkOrigin(existingMarker, options.plan.origin ?? null);
1423
+ if (!originCheck.ok) return originCheck;
1424
+ const isSelfEdge = options.plan.origin?.storageHash === options.plan.destination.storageHash;
1425
+ const applied = existingMarker !== null && existingMarker.storageHash === options.plan.destination.storageHash && (options.plan.destination.profileHash === void 0 || existingMarker.profileHash === options.plan.destination.profileHash) && options.plan.origin != null && !isSelfEdge ? {
1426
+ result: okVoid(),
1427
+ executed: [],
1428
+ executedCount: 0
1429
+ } : await this.#applyOperations(driver, options, operations, progress);
1430
+ if (!applied.result.ok) return applied.result;
1431
+ const schema = await this.family.introspect({
1432
+ driver,
1433
+ contract: options.destinationContract
1434
+ });
1435
+ const verified = this.family.verifySchema({
1436
+ contract: options.destinationContract,
1437
+ schema,
1438
+ strict: options.strictVerification ?? true,
1439
+ frameworkComponents: options.frameworkComponents
1440
+ });
1441
+ if (!verified.ok) return runnerFailure("MIGRATION.SCHEMA_VERIFY_FAILED", verified.summary, {
1442
+ why: schemaCheckWhy(verified.schema.issues),
1443
+ meta: { schemaIssues: verified.schema.issues }
1444
+ });
1445
+ const existingInvariants = new Set(existingMarker?.invariants ?? []);
1446
+ if (!(isSelfEdge && applied.executedCount === 0 && options.plan.providedInvariants.every((id) => existingInvariants.has(id)))) {
1447
+ const written = await this.#writeMarkerAndLedger(driver, options, existingMarker, applied.executed, progress);
1448
+ if (!written.ok) return written;
1449
+ }
1450
+ return runnerSuccess({
1451
+ operationsPlanned: operations.length,
1452
+ operationsExecuted: applied.executedCount
1453
+ });
1454
+ }
1455
+ async #ensureControlTables(driver, options) {
1456
+ for (const query of this.family.bootstrapControlTableQueries()) {
1457
+ const statement = await this.family.lowerAst(query, { contract: options.destinationContract });
1458
+ await driver.query(statement.sql, statement.params);
1459
+ }
1460
+ }
1461
+ async #applyOperations(driver, options, operations, progress) {
1462
+ const checks = options.executionChecks;
1463
+ const runPrechecks = checks?.prechecks !== false;
1464
+ const runPostchecks = checks?.postchecks !== false;
1465
+ const runIdempotency = checks?.idempotencyChecks !== false;
1466
+ const executed = [];
1467
+ let executedCount = 0;
1468
+ const stop = (result) => ({
1469
+ result,
1470
+ executed,
1471
+ executedCount
1472
+ });
1473
+ for (const operation of operations) {
1474
+ options.callbacks?.onOperationStart?.(operation);
1475
+ try {
1476
+ if (runPostchecks && runIdempotency && await this.#allHold(driver, operation.postcheck)) {
1477
+ executed.push(skipRecord(operation));
1478
+ continue;
1479
+ }
1480
+ if (runPrechecks) {
1481
+ const precheck = await this.#runChecks(driver, operation, "precheck");
1482
+ if (!precheck.ok) return stop(precheck);
1483
+ }
1484
+ const execution = await this.#runSteps(driver, operation, progress);
1485
+ if (!execution.ok) return stop(execution);
1486
+ executedCount += 1;
1487
+ if (runPostchecks) {
1488
+ const postcheck = await this.#runChecks(driver, operation, "postcheck");
1489
+ if (!postcheck.ok) return stop(postcheck);
1490
+ }
1491
+ executed.push(operation);
1492
+ } finally {
1493
+ options.callbacks?.onOperationComplete?.(operation);
1494
+ }
1495
+ }
1496
+ return stop(okVoid());
1497
+ }
1498
+ async #allHold(driver, steps) {
1499
+ if (steps.length === 0) return false;
1500
+ for (const step of steps) if (!stepHolds((await driver.query(step.sql, step.params ?? [])).rows)) return false;
1501
+ return true;
1502
+ }
1503
+ async #runChecks(driver, operation, phase) {
1504
+ for (const step of operation[phase]) {
1505
+ if (stepHolds((await driver.query(step.sql, step.params ?? [])).rows)) continue;
1506
+ const failedCheck = {
1507
+ operationId: operation.id,
1508
+ phase,
1509
+ description: step.description,
1510
+ ...ifDefined("expectation", step.expectation)
1511
+ };
1512
+ return runnerFailure(phase === "precheck" ? "MIGRATION.PRECHECK_FAILED" : "MIGRATION.POSTCHECK_FAILED", `Operation ${operation.id} failed during ${phase}: ${step.description}`, {
1513
+ why: phase === "precheck" ? failedPrecheckWhy(failedCheck) : failedPostcheckWhy(failedCheck),
1514
+ meta: { failedCheck }
1515
+ });
1516
+ }
1517
+ return okVoid();
1518
+ }
1519
+ /** Runs an operation's steps, and records in `progress` each one that reached the database, which a DDL statement changes for good. */
1520
+ async #runSteps(driver, operation, progress) {
1521
+ for (const step of operation.execute) try {
1522
+ await driver.query(step.sql, step.params ?? []);
1523
+ progress.changedDatabase = true;
1524
+ } catch (error) {
1525
+ const message = error instanceof Error ? error.message : String(error);
1526
+ return runnerFailure("MIGRATION.EXECUTION_FAILED", `Operation ${operation.id} failed during execution: ${step.description}`, {
1527
+ why: message,
1528
+ meta: {
1529
+ operationId: operation.id,
1530
+ stepDescription: step.description,
1531
+ sql: step.sql
1532
+ }
1533
+ });
1534
+ }
1535
+ return okVoid();
1536
+ }
1537
+ async #writeMarkerAndLedger(driver, options, existingMarker, executed, progress) {
1538
+ const { plan } = options;
1539
+ const destination = {
1540
+ storageHash: plan.destination.storageHash,
1541
+ profileHash: plan.destination.profileHash ?? options.destinationContract.profileHash ?? plan.destination.storageHash,
1542
+ invariants: plan.providedInvariants
1543
+ };
1544
+ await driver.query("START TRANSACTION");
1545
+ try {
1546
+ if (existingMarker === null) await this.family.initMarker({
1547
+ driver,
1548
+ space: plan.spaceId,
1549
+ destination
1550
+ });
1551
+ else if (!await this.family.updateMarker({
1552
+ driver,
1553
+ space: plan.spaceId,
1554
+ expectedFrom: existingMarker.storageHash,
1555
+ destination
1556
+ })) {
1557
+ await driver.query("ROLLBACK");
1558
+ const found = await this.family.readMarker({
1559
+ driver,
1560
+ space: plan.spaceId
1561
+ });
1562
+ return runnerFailure("MIGRATION.MARKER_CAS_FAILURE", "Marker was modified by another process during migration execution.", { meta: {
1563
+ space: plan.spaceId,
1564
+ expectedStorageHash: existingMarker.storageHash,
1565
+ foundStorageHash: found?.storageHash ?? null,
1566
+ destinationStorageHash: plan.destination.storageHash
1567
+ } });
1568
+ }
1569
+ await this.#writeLedger(driver, options, executed);
1570
+ } catch (error) {
1571
+ await driver.query("ROLLBACK").catch(() => void 0);
1572
+ throw error;
1573
+ }
1574
+ progress.changedDatabase = true;
1575
+ await driver.query("COMMIT");
1576
+ return okVoid();
1577
+ }
1578
+ async #writeLedger(driver, options, executed) {
1579
+ const { plan, migrationEdges } = options;
1580
+ const edgeOperations = migrationEdges.reduce((sum, edge) => sum + edge.operationCount, 0);
1581
+ if (edgeOperations !== plan.operations.length) throw new InternalError(`Ledger write: plan.operations length (${plan.operations.length}) does not match sum of migrationEdges operationCount (${edgeOperations})`);
1582
+ let offset = 0;
1583
+ for (const edge of migrationEdges) {
1584
+ const operations = executed.slice(offset, offset + edge.operationCount);
1585
+ offset += edge.operationCount;
1586
+ await this.family.writeLedgerEntry({
1587
+ driver,
1588
+ space: plan.spaceId,
1589
+ entry: {
1590
+ edgeId: `${edge.from}->${edge.to}`,
1591
+ from: edge.from,
1592
+ to: edge.to,
1593
+ migrationName: edge.dirName,
1594
+ migrationHash: edge.migrationHash,
1595
+ operations
1596
+ }
1597
+ });
1598
+ }
1599
+ }
1600
+ #checkDestination(destination, contract) {
1601
+ if (destination.storageHash !== contract.storage.storageHash) return runnerFailure("MIGRATION.DESTINATION_CONTRACT_MISMATCH", `Plan destination storage hash (${destination.storageHash}) does not match provided contract storage hash (${contract.storage.storageHash}).`, { meta: {
1602
+ planStorageHash: destination.storageHash,
1603
+ contractStorageHash: contract.storage.storageHash
1604
+ } });
1605
+ if (destination.profileHash !== void 0 && contract.profileHash !== void 0 && destination.profileHash !== contract.profileHash) return runnerFailure("MIGRATION.DESTINATION_CONTRACT_MISMATCH", `Plan destination profile hash (${destination.profileHash}) does not match provided contract profile hash (${contract.profileHash}).`, { meta: {
1606
+ planProfileHash: destination.profileHash,
1607
+ contractProfileHash: contract.profileHash
1608
+ } });
1609
+ return okVoid();
1610
+ }
1611
+ #checkPolicy(policy, operations) {
1612
+ const allowed = new Set(policy.allowedOperationClasses);
1613
+ const refused = operations.find((operation) => !allowed.has(operation.operationClass));
1614
+ if (refused === void 0) return okVoid();
1615
+ return runnerFailure("MIGRATION.POLICY_VIOLATION", `Operation ${refused.id} has class "${refused.operationClass}" which is not allowed by policy.`, {
1616
+ why: `Policy only allows: ${policy.allowedOperationClasses.join(", ")}.`,
1617
+ meta: {
1618
+ operationId: refused.id,
1619
+ operationClass: refused.operationClass,
1620
+ allowedClasses: policy.allowedOperationClasses
1621
+ }
1622
+ });
1623
+ }
1624
+ #checkOrigin(marker, origin) {
1625
+ if (origin === null) return okVoid();
1626
+ if (marker === null) return runnerFailure("MIGRATION.MARKER_ORIGIN_MISMATCH", `Missing contract marker: expected origin storage hash ${origin.storageHash}.`, { meta: { expectedOriginStorageHash: origin.storageHash } });
1627
+ if (marker.storageHash !== origin.storageHash) return runnerFailure("MIGRATION.MARKER_ORIGIN_MISMATCH", `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`, { meta: {
1628
+ markerStorageHash: marker.storageHash,
1629
+ expectedOriginStorageHash: origin.storageHash
1630
+ } });
1631
+ if (origin.profileHash !== void 0 && marker.profileHash !== origin.profileHash) return runnerFailure("MIGRATION.MARKER_ORIGIN_MISMATCH", `Existing contract marker profile hash (${marker.profileHash}) does not match plan origin profile hash (${origin.profileHash}).`, { meta: {
1632
+ markerProfileHash: marker.profileHash,
1633
+ expectedOriginProfileHash: origin.profileHash
1634
+ } });
1635
+ return okVoid();
1636
+ }
1637
+ };
1638
+ function createMysqlMigrationRunner(family) {
1639
+ return new MysqlMigrationRunner(family);
1640
+ }
1641
+ //#endregion
1642
+ export { diffMysqlSchema as _, CreateTableCall as a, DropIndexCall as c, MysqlMigration as d, MysqlMigrationPlanner as f, createMysqlMigrationRunner as g, createMysqlMigrationPlanner as h, CreateIndexCall as i, DropTableCall as l, TypeScriptRenderableMysqlMigration as m, AddForeignKeyCall as n, DropColumnCall as o, RawSqlCall as p, AddUniqueCall as r, DropForeignKeyCall as s, AddColumnCall as t, DropUniqueCall as u, mysqlContractToSchema as v, rawSql as y };
1643
+
1644
+ //# sourceMappingURL=runner-C4r6yEd1-BWQrxW9q.mjs.map