@famgia/omnify-sql 0.0.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.
@@ -0,0 +1,1118 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/dialects/formatter.ts
2
+ function quoteIdentifier(name, dialect) {
3
+ switch (dialect) {
4
+ case "mysql":
5
+ return `\`${name}\``;
6
+ case "postgresql":
7
+ return `"${name}"`;
8
+ case "sqlite":
9
+ return `"${name}"`;
10
+ }
11
+ }
12
+ function quoteString(value) {
13
+ return `'${value.replace(/'/g, "''")}'`;
14
+ }
15
+ function formatColumn(column, dialect) {
16
+ const parts = [quoteIdentifier(column.name, dialect), column.type];
17
+ if (dialect === "mysql" && column.unsigned && !column.type.includes("UNSIGNED")) {
18
+ parts.push("UNSIGNED");
19
+ }
20
+ if (!column.nullable && !column.primaryKey) {
21
+ parts.push("NOT NULL");
22
+ } else if (column.nullable) {
23
+ parts.push("NULL");
24
+ }
25
+ if (column.autoIncrement) {
26
+ switch (dialect) {
27
+ case "mysql":
28
+ parts.push("AUTO_INCREMENT");
29
+ break;
30
+ case "sqlite":
31
+ break;
32
+ case "postgresql":
33
+ break;
34
+ }
35
+ }
36
+ if (column.primaryKey) {
37
+ parts.push("PRIMARY KEY");
38
+ if (dialect === "sqlite" && column.autoIncrement) {
39
+ parts.push("AUTOINCREMENT");
40
+ }
41
+ }
42
+ if (column.unique && !column.primaryKey) {
43
+ parts.push("UNIQUE");
44
+ }
45
+ if (column.defaultValue !== void 0) {
46
+ parts.push(`DEFAULT ${column.defaultValue}`);
47
+ }
48
+ if (column.comment && dialect === "mysql") {
49
+ parts.push(`COMMENT ${quoteString(column.comment)}`);
50
+ }
51
+ return parts.join(" ");
52
+ }
53
+ function formatForeignKey(fk, dialect) {
54
+ const localCols = fk.columns.map((c) => quoteIdentifier(c, dialect)).join(", ");
55
+ const refCols = fk.referencesColumns.map((c) => quoteIdentifier(c, dialect)).join(", ");
56
+ const refTable = quoteIdentifier(fk.referencesTable, dialect);
57
+ let sql = `CONSTRAINT ${quoteIdentifier(fk.name, dialect)} `;
58
+ sql += `FOREIGN KEY (${localCols}) `;
59
+ sql += `REFERENCES ${refTable} (${refCols})`;
60
+ if (fk.onDelete && fk.onDelete !== "NO ACTION") {
61
+ sql += ` ON DELETE ${fk.onDelete}`;
62
+ }
63
+ if (fk.onUpdate && fk.onUpdate !== "NO ACTION") {
64
+ sql += ` ON UPDATE ${fk.onUpdate}`;
65
+ }
66
+ return sql;
67
+ }
68
+ function formatIndex(index, tableName, dialect) {
69
+ const cols = index.columns.map((c) => quoteIdentifier(c, dialect)).join(", ");
70
+ const table = quoteIdentifier(tableName, dialect);
71
+ const name = quoteIdentifier(index.name, dialect);
72
+ if (index.type === "fulltext") {
73
+ switch (dialect) {
74
+ case "mysql":
75
+ return `CREATE FULLTEXT INDEX ${name} ON ${table} (${cols});`;
76
+ case "postgresql":
77
+ const tsvectorCols = index.columns.map((c) => `to_tsvector('english', ${quoteIdentifier(c, dialect)})`).join(" || ");
78
+ return `CREATE INDEX ${name} ON ${table} USING GIN (${tsvectorCols});`;
79
+ case "sqlite":
80
+ return `CREATE INDEX ${name} ON ${table} (${cols});`;
81
+ }
82
+ }
83
+ if (index.type === "spatial") {
84
+ switch (dialect) {
85
+ case "mysql":
86
+ return `CREATE SPATIAL INDEX ${name} ON ${table} (${cols});`;
87
+ case "postgresql":
88
+ return `CREATE INDEX ${name} ON ${table} USING GIST (${cols});`;
89
+ case "sqlite":
90
+ return `CREATE INDEX ${name} ON ${table} (${cols});`;
91
+ }
92
+ }
93
+ if (index.type === "gin" && dialect === "postgresql") {
94
+ return `CREATE INDEX ${name} ON ${table} USING GIN (${cols});`;
95
+ }
96
+ if (index.type === "gist" && dialect === "postgresql") {
97
+ return `CREATE INDEX ${name} ON ${table} USING GIST (${cols});`;
98
+ }
99
+ if (index.type === "hash") {
100
+ switch (dialect) {
101
+ case "mysql":
102
+ return `CREATE INDEX ${name} ON ${table} (${cols}) USING HASH;`;
103
+ case "postgresql":
104
+ return `CREATE INDEX ${name} ON ${table} USING HASH (${cols});`;
105
+ case "sqlite":
106
+ return `CREATE INDEX ${name} ON ${table} (${cols});`;
107
+ }
108
+ }
109
+ const indexType = index.unique ? "UNIQUE INDEX" : "INDEX";
110
+ return `CREATE ${indexType} ${name} ON ${table} (${cols});`;
111
+ }
112
+ function formatCreateTable(table, dialect, options) {
113
+ const tableName = quoteIdentifier(table.name, dialect);
114
+ const ifNotExists = _optionalChain([options, 'optionalAccess', _ => _.ifNotExists]) ? "IF NOT EXISTS " : "";
115
+ const lines = [];
116
+ for (const column of table.columns) {
117
+ lines.push(` ${formatColumn(column, dialect)}`);
118
+ }
119
+ for (const fk of table.foreignKeys) {
120
+ lines.push(` ${formatForeignKey(fk, dialect)}`);
121
+ }
122
+ let sql = `CREATE TABLE ${ifNotExists}${tableName} (
123
+ `;
124
+ sql += lines.join(",\n");
125
+ sql += "\n)";
126
+ if (dialect === "mysql") {
127
+ sql += " ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
128
+ }
129
+ sql += ";";
130
+ if (table.comment && dialect === "postgresql") {
131
+ sql += `
132
+
133
+ COMMENT ON TABLE ${tableName} IS ${quoteString(table.comment)};`;
134
+ }
135
+ return sql;
136
+ }
137
+ function formatDropTable(tableName, dialect, options) {
138
+ const table = quoteIdentifier(tableName, dialect);
139
+ const ifExists = _optionalChain([options, 'optionalAccess', _2 => _2.ifExists]) ? "IF EXISTS " : "";
140
+ const cascade = _optionalChain([options, 'optionalAccess', _3 => _3.cascade]) && dialect === "postgresql" ? " CASCADE" : "";
141
+ return `DROP TABLE ${ifExists}${table}${cascade};`;
142
+ }
143
+ function formatIndexes(table, dialect) {
144
+ return table.indexes.map((index) => formatIndex(index, table.name, dialect));
145
+ }
146
+ function formatColumnComments(table, dialect) {
147
+ if (dialect !== "postgresql") {
148
+ return [];
149
+ }
150
+ const statements = [];
151
+ const tableName = quoteIdentifier(table.name, dialect);
152
+ for (const column of table.columns) {
153
+ if (column.comment) {
154
+ const colName = quoteIdentifier(column.name, dialect);
155
+ statements.push(
156
+ `COMMENT ON COLUMN ${tableName}.${colName} IS ${quoteString(column.comment)};`
157
+ );
158
+ }
159
+ }
160
+ return statements;
161
+ }
162
+
163
+ // src/dialects/types.ts
164
+ var MYSQL_TYPES = {
165
+ String: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
166
+ Int: { type: "INT" },
167
+ BigInt: { type: "BIGINT" },
168
+ Float: { type: "DOUBLE" },
169
+ Decimal: { type: "DECIMAL", hasPrecision: true },
170
+ Boolean: { type: "TINYINT(1)" },
171
+ Text: { type: "TEXT" },
172
+ LongText: { type: "LONGTEXT" },
173
+ Date: { type: "DATE" },
174
+ Time: { type: "TIME" },
175
+ Timestamp: { type: "TIMESTAMP" },
176
+ Json: { type: "JSON" },
177
+ Email: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
178
+ Password: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
179
+ File: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
180
+ MultiFile: { type: "JSON" },
181
+ Uuid: { type: "CHAR(36)" },
182
+ Select: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
183
+ Lookup: { type: "BIGINT UNSIGNED" },
184
+ // Spatial types
185
+ Point: { type: "POINT" },
186
+ Coordinates: { type: "DECIMAL(10, 8)" }
187
+ // For latitude column (longitude uses DECIMAL(11, 8))
188
+ };
189
+ var POSTGRESQL_TYPES = {
190
+ String: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
191
+ Int: { type: "INTEGER" },
192
+ BigInt: { type: "BIGINT" },
193
+ Float: { type: "DOUBLE PRECISION" },
194
+ Decimal: { type: "DECIMAL", hasPrecision: true },
195
+ Boolean: { type: "BOOLEAN" },
196
+ Text: { type: "TEXT" },
197
+ LongText: { type: "TEXT" },
198
+ Date: { type: "DATE" },
199
+ Time: { type: "TIME" },
200
+ Timestamp: { type: "TIMESTAMP" },
201
+ Json: { type: "JSONB" },
202
+ Email: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
203
+ Password: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
204
+ File: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
205
+ MultiFile: { type: "JSONB" },
206
+ Uuid: { type: "UUID" },
207
+ Select: { type: "VARCHAR", hasLength: true, defaultLength: 255 },
208
+ Lookup: { type: "BIGINT" },
209
+ // Spatial types (requires PostGIS extension)
210
+ Point: { type: "geometry(Point, 4326)" },
211
+ Coordinates: { type: "DECIMAL(10, 8)" }
212
+ // For latitude column
213
+ };
214
+ var SQLITE_TYPES = {
215
+ String: { type: "TEXT" },
216
+ Int: { type: "INTEGER" },
217
+ BigInt: { type: "INTEGER" },
218
+ Float: { type: "REAL" },
219
+ Decimal: { type: "REAL" },
220
+ Boolean: { type: "INTEGER" },
221
+ Text: { type: "TEXT" },
222
+ LongText: { type: "TEXT" },
223
+ Date: { type: "TEXT" },
224
+ Time: { type: "TEXT" },
225
+ Timestamp: { type: "TEXT" },
226
+ Json: { type: "TEXT" },
227
+ Email: { type: "TEXT" },
228
+ Password: { type: "TEXT" },
229
+ File: { type: "TEXT" },
230
+ MultiFile: { type: "TEXT" },
231
+ Uuid: { type: "TEXT" },
232
+ Select: { type: "TEXT" },
233
+ Lookup: { type: "INTEGER" },
234
+ // Spatial types (no native support, use TEXT for JSON or REAL for lat/lon)
235
+ Point: { type: "TEXT" },
236
+ // JSON representation: {"lat": 0, "lon": 0}
237
+ Coordinates: { type: "REAL" }
238
+ // For latitude/longitude columns
239
+ };
240
+ var DIALECT_TYPES = {
241
+ mysql: MYSQL_TYPES,
242
+ postgresql: POSTGRESQL_TYPES,
243
+ sqlite: SQLITE_TYPES
244
+ };
245
+ function getSqlType(omnifyType, dialect, options) {
246
+ const mapping = DIALECT_TYPES[dialect][omnifyType];
247
+ if (!mapping) {
248
+ return dialect === "sqlite" ? "TEXT" : "VARCHAR(255)";
249
+ }
250
+ let type = mapping.type;
251
+ if (mapping.hasLength) {
252
+ const length = _nullishCoalesce(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.length]), () => ( mapping.defaultLength)), () => ( 255));
253
+ type = `${type}(${length})`;
254
+ }
255
+ if (mapping.hasPrecision && _optionalChain([options, 'optionalAccess', _5 => _5.precision])) {
256
+ const scale = _nullishCoalesce(options.scale, () => ( 2));
257
+ type = `${type}(${options.precision}, ${scale})`;
258
+ }
259
+ return type;
260
+ }
261
+ function getPrimaryKeyType(idType, dialect) {
262
+ switch (dialect) {
263
+ case "mysql":
264
+ switch (idType) {
265
+ case "Int":
266
+ return { type: "INT UNSIGNED", autoIncrement: true };
267
+ case "BigInt":
268
+ return { type: "BIGINT UNSIGNED", autoIncrement: true };
269
+ case "Uuid":
270
+ return { type: "CHAR(36)", autoIncrement: false };
271
+ case "String":
272
+ return { type: "VARCHAR(255)", autoIncrement: false };
273
+ }
274
+ break;
275
+ case "postgresql":
276
+ switch (idType) {
277
+ case "Int":
278
+ return { type: "SERIAL", autoIncrement: false };
279
+ // SERIAL handles auto-increment
280
+ case "BigInt":
281
+ return { type: "BIGSERIAL", autoIncrement: false };
282
+ case "Uuid":
283
+ return { type: "UUID", autoIncrement: false };
284
+ case "String":
285
+ return { type: "VARCHAR(255)", autoIncrement: false };
286
+ }
287
+ break;
288
+ case "sqlite":
289
+ switch (idType) {
290
+ case "Int":
291
+ case "BigInt":
292
+ return { type: "INTEGER", autoIncrement: true };
293
+ case "Uuid":
294
+ case "String":
295
+ return { type: "TEXT", autoIncrement: false };
296
+ }
297
+ break;
298
+ }
299
+ return { type: "BIGINT", autoIncrement: true };
300
+ }
301
+ function getForeignKeyType(referencedIdType, dialect) {
302
+ switch (dialect) {
303
+ case "mysql":
304
+ switch (referencedIdType) {
305
+ case "Int":
306
+ return "INT UNSIGNED";
307
+ case "BigInt":
308
+ return "BIGINT UNSIGNED";
309
+ case "Uuid":
310
+ return "CHAR(36)";
311
+ case "String":
312
+ return "VARCHAR(255)";
313
+ }
314
+ break;
315
+ case "postgresql":
316
+ switch (referencedIdType) {
317
+ case "Int":
318
+ return "INTEGER";
319
+ case "BigInt":
320
+ return "BIGINT";
321
+ case "Uuid":
322
+ return "UUID";
323
+ case "String":
324
+ return "VARCHAR(255)";
325
+ }
326
+ break;
327
+ case "sqlite":
328
+ switch (referencedIdType) {
329
+ case "Int":
330
+ case "BigInt":
331
+ return "INTEGER";
332
+ case "Uuid":
333
+ case "String":
334
+ return "TEXT";
335
+ }
336
+ break;
337
+ }
338
+ return "BIGINT";
339
+ }
340
+ function getEnumType(values, dialect, enumName) {
341
+ switch (dialect) {
342
+ case "mysql":
343
+ const enumValues = values.map((v) => `'${v}'`).join(", ");
344
+ return { type: `ENUM(${enumValues})` };
345
+ case "postgresql":
346
+ const typeName = _nullishCoalesce(enumName, () => ( "enum_type"));
347
+ const pgValues = values.map((v) => `'${v}'`).join(", ");
348
+ return {
349
+ type: typeName,
350
+ preStatement: `CREATE TYPE ${typeName} AS ENUM (${pgValues});`
351
+ };
352
+ case "sqlite":
353
+ return { type: "TEXT" };
354
+ }
355
+ }
356
+
357
+ // src/migration/schema-builder.ts
358
+ function toSnakeCase(str) {
359
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`).replace(/^_/, "");
360
+ }
361
+ function toTableName(schemaName) {
362
+ const snake = toSnakeCase(schemaName);
363
+ if (snake.endsWith("y") && !["ay", "ey", "oy", "uy"].some((v) => snake.endsWith(v))) {
364
+ return snake.slice(0, -1) + "ies";
365
+ }
366
+ if (snake.endsWith("s") || snake.endsWith("x") || snake.endsWith("ch") || snake.endsWith("sh")) {
367
+ return snake + "es";
368
+ }
369
+ return snake + "s";
370
+ }
371
+ function toColumnName(propertyName) {
372
+ return toSnakeCase(propertyName);
373
+ }
374
+ function generatePrimaryKey(idType, dialect) {
375
+ const pkInfo = getPrimaryKeyType(idType, dialect);
376
+ return {
377
+ name: "id",
378
+ type: pkInfo.type,
379
+ nullable: false,
380
+ primaryKey: true,
381
+ autoIncrement: pkInfo.autoIncrement,
382
+ unique: false,
383
+ unsigned: false
384
+ };
385
+ }
386
+ function generateTimestampColumns(dialect) {
387
+ const timestampType = dialect === "sqlite" ? "TEXT" : "TIMESTAMP";
388
+ return [
389
+ {
390
+ name: "created_at",
391
+ type: timestampType,
392
+ nullable: true,
393
+ primaryKey: false,
394
+ autoIncrement: false,
395
+ unique: false,
396
+ unsigned: false
397
+ },
398
+ {
399
+ name: "updated_at",
400
+ type: timestampType,
401
+ nullable: true,
402
+ primaryKey: false,
403
+ autoIncrement: false,
404
+ unique: false,
405
+ unsigned: false
406
+ }
407
+ ];
408
+ }
409
+ function generateSoftDeleteColumn(dialect) {
410
+ const timestampType = dialect === "sqlite" ? "TEXT" : "TIMESTAMP";
411
+ return {
412
+ name: "deleted_at",
413
+ type: timestampType,
414
+ nullable: true,
415
+ primaryKey: false,
416
+ autoIncrement: false,
417
+ unique: false,
418
+ unsigned: false
419
+ };
420
+ }
421
+ function generateCoordinatesColumns(name, property, dialect) {
422
+ const baseName = toColumnName(name);
423
+ const nullable = _nullishCoalesce(property.nullable, () => ( false));
424
+ const latType = dialect === "sqlite" ? "REAL" : "DECIMAL(10, 8)";
425
+ const lonType = dialect === "sqlite" ? "REAL" : "DECIMAL(11, 8)";
426
+ return [
427
+ {
428
+ name: `${baseName}_latitude`,
429
+ type: latType,
430
+ nullable,
431
+ primaryKey: false,
432
+ autoIncrement: false,
433
+ unique: false,
434
+ unsigned: false,
435
+ comment: `Latitude for ${name}`
436
+ },
437
+ {
438
+ name: `${baseName}_longitude`,
439
+ type: lonType,
440
+ nullable,
441
+ primaryKey: false,
442
+ autoIncrement: false,
443
+ unique: false,
444
+ unsigned: false,
445
+ comment: `Longitude for ${name}`
446
+ }
447
+ ];
448
+ }
449
+ function propertyToColumn(name, property, dialect, _allSchemas) {
450
+ if (property.type === "Association") {
451
+ return null;
452
+ }
453
+ if (property.type === "Coordinates") {
454
+ return null;
455
+ }
456
+ const columnName = toColumnName(name);
457
+ const baseProp = property;
458
+ if (property.type === "Enum") {
459
+ if (Array.isArray(baseProp.enum)) {
460
+ const enumInfo = getEnumType(baseProp.enum, dialect, `${columnName}_enum`);
461
+ return {
462
+ name: columnName,
463
+ type: enumInfo.type,
464
+ nullable: _nullishCoalesce(baseProp.nullable, () => ( false)),
465
+ primaryKey: false,
466
+ autoIncrement: false,
467
+ unique: _nullishCoalesce(baseProp.unique, () => ( false)),
468
+ unsigned: false,
469
+ defaultValue: baseProp.default !== void 0 ? `'${baseProp.default}'` : void 0,
470
+ comment: baseProp.displayName
471
+ };
472
+ }
473
+ }
474
+ if (property.type === "Select" && baseProp.options) {
475
+ const enumInfo = getEnumType(baseProp.options, dialect, `${columnName}_enum`);
476
+ return {
477
+ name: columnName,
478
+ type: enumInfo.type,
479
+ nullable: _nullishCoalesce(baseProp.nullable, () => ( false)),
480
+ primaryKey: false,
481
+ autoIncrement: false,
482
+ unique: _nullishCoalesce(baseProp.unique, () => ( false)),
483
+ unsigned: false,
484
+ defaultValue: baseProp.default !== void 0 ? `'${baseProp.default}'` : void 0,
485
+ comment: baseProp.displayName
486
+ };
487
+ }
488
+ const sqlType = getSqlType(property.type, dialect, {
489
+ length: baseProp.length,
490
+ precision: baseProp.precision,
491
+ scale: baseProp.scale
492
+ });
493
+ let defaultValue;
494
+ if (baseProp.default !== void 0) {
495
+ if (typeof baseProp.default === "string") {
496
+ defaultValue = `'${baseProp.default}'`;
497
+ } else if (typeof baseProp.default === "boolean") {
498
+ defaultValue = dialect === "postgresql" ? baseProp.default ? "TRUE" : "FALSE" : baseProp.default ? "1" : "0";
499
+ } else {
500
+ defaultValue = String(baseProp.default);
501
+ }
502
+ }
503
+ return {
504
+ name: columnName,
505
+ type: sqlType,
506
+ nullable: _nullishCoalesce(baseProp.nullable, () => ( false)),
507
+ primaryKey: false,
508
+ autoIncrement: false,
509
+ unique: _nullishCoalesce(baseProp.unique, () => ( false)),
510
+ unsigned: false,
511
+ defaultValue,
512
+ comment: baseProp.displayName
513
+ };
514
+ }
515
+ function generateForeignKey(name, property, schema, dialect, allSchemas) {
516
+ if (property.type !== "Association") {
517
+ return null;
518
+ }
519
+ const assocProp = property;
520
+ if (!["ManyToOne", "OneToOne"].includes(_nullishCoalesce(assocProp.relation, () => ( "")))) {
521
+ return null;
522
+ }
523
+ const targetName = assocProp.target;
524
+ if (!targetName) {
525
+ return null;
526
+ }
527
+ const targetSchema = allSchemas[targetName];
528
+ const targetIdType = _nullishCoalesce(_optionalChain([targetSchema, 'optionalAccess', _6 => _6.options, 'optionalAccess', _7 => _7.idType]), () => ( "BigInt"));
529
+ const columnName = `${toColumnName(name)}_id`;
530
+ const fkType = getForeignKeyType(targetIdType, dialect);
531
+ const constraintName = `fk_${toTableName(schema.name)}_${columnName}`;
532
+ const column = {
533
+ name: columnName,
534
+ type: fkType,
535
+ nullable: _nullishCoalesce(property.nullable, () => ( false)),
536
+ primaryKey: false,
537
+ autoIncrement: false,
538
+ unique: false,
539
+ unsigned: dialect === "mysql" && ["Int", "BigInt"].includes(targetIdType)
540
+ };
541
+ const foreignKey = {
542
+ name: constraintName,
543
+ columns: [columnName],
544
+ referencesTable: toTableName(targetName),
545
+ referencesColumns: ["id"],
546
+ onDelete: _nullishCoalesce(assocProp.onDelete, () => ( "CASCADE")),
547
+ onUpdate: _nullishCoalesce(assocProp.onUpdate, () => ( "CASCADE"))
548
+ };
549
+ return { column, foreignKey };
550
+ }
551
+ function generatePolymorphicColumns(name, property, dialect, allSchemas) {
552
+ if (property.type !== "Association") {
553
+ return null;
554
+ }
555
+ const assocProp = property;
556
+ if (assocProp.relation !== "MorphTo" || !_optionalChain([assocProp, 'access', _8 => _8.targets, 'optionalAccess', _9 => _9.length])) {
557
+ return null;
558
+ }
559
+ const baseName = toColumnName(name);
560
+ let useUuid = false;
561
+ for (const targetName of assocProp.targets) {
562
+ const targetSchema = allSchemas[targetName];
563
+ if (_optionalChain([targetSchema, 'optionalAccess', _10 => _10.options, 'optionalAccess', _11 => _11.idType]) === "Uuid") {
564
+ useUuid = true;
565
+ break;
566
+ }
567
+ }
568
+ const enumInfo = getEnumType(assocProp.targets, dialect, `${baseName}_type_enum`);
569
+ const typeColumn = {
570
+ name: `${baseName}_type`,
571
+ type: enumInfo.type,
572
+ nullable: true,
573
+ primaryKey: false,
574
+ autoIncrement: false,
575
+ unique: false,
576
+ unsigned: false
577
+ };
578
+ const idType = useUuid ? dialect === "mysql" ? "CHAR(36)" : dialect === "postgresql" ? "UUID" : "TEXT" : dialect === "mysql" ? "BIGINT UNSIGNED" : dialect === "postgresql" ? "BIGINT" : "INTEGER";
579
+ const idColumn = {
580
+ name: `${baseName}_id`,
581
+ type: idType,
582
+ nullable: true,
583
+ primaryKey: false,
584
+ autoIncrement: false,
585
+ unique: false,
586
+ unsigned: dialect === "mysql" && !useUuid
587
+ };
588
+ const index = {
589
+ name: `idx_${baseName}_type_id`,
590
+ columns: [`${baseName}_type`, `${baseName}_id`],
591
+ unique: false
592
+ };
593
+ return {
594
+ columns: [typeColumn, idColumn],
595
+ index
596
+ };
597
+ }
598
+ function schemaToTable(schema, allSchemas, options) {
599
+ const columns = [];
600
+ const foreignKeys = [];
601
+ const indexes = [];
602
+ const dialect = options.dialect;
603
+ if (_optionalChain([schema, 'access', _12 => _12.options, 'optionalAccess', _13 => _13.id]) !== false) {
604
+ const idType = _nullishCoalesce(_optionalChain([schema, 'access', _14 => _14.options, 'optionalAccess', _15 => _15.idType]), () => ( "BigInt"));
605
+ columns.push(generatePrimaryKey(idType, dialect));
606
+ }
607
+ if (schema.properties) {
608
+ for (const [propName, property] of Object.entries(schema.properties)) {
609
+ const column = propertyToColumn(propName, property, dialect, allSchemas);
610
+ if (column) {
611
+ columns.push(column);
612
+ if (column.unique) {
613
+ indexes.push({
614
+ name: `idx_${toTableName(schema.name)}_${column.name}_unique`,
615
+ columns: [column.name],
616
+ unique: true
617
+ });
618
+ }
619
+ continue;
620
+ }
621
+ const fkResult = generateForeignKey(propName, property, schema, dialect, allSchemas);
622
+ if (fkResult) {
623
+ columns.push(fkResult.column);
624
+ foreignKeys.push(fkResult.foreignKey);
625
+ indexes.push({
626
+ name: `idx_${toTableName(schema.name)}_${fkResult.column.name}`,
627
+ columns: [fkResult.column.name],
628
+ unique: false
629
+ });
630
+ continue;
631
+ }
632
+ const morphResult = generatePolymorphicColumns(propName, property, dialect, allSchemas);
633
+ if (morphResult) {
634
+ columns.push(...morphResult.columns);
635
+ indexes.push(morphResult.index);
636
+ continue;
637
+ }
638
+ if (property.type === "Coordinates") {
639
+ const coordColumns = generateCoordinatesColumns(propName, property, dialect);
640
+ columns.push(...coordColumns);
641
+ }
642
+ }
643
+ }
644
+ if (_optionalChain([schema, 'access', _16 => _16.options, 'optionalAccess', _17 => _17.timestamps]) !== false) {
645
+ columns.push(...generateTimestampColumns(dialect));
646
+ }
647
+ if (_optionalChain([schema, 'access', _18 => _18.options, 'optionalAccess', _19 => _19.softDelete])) {
648
+ columns.push(generateSoftDeleteColumn(dialect));
649
+ }
650
+ if (_optionalChain([schema, 'access', _20 => _20.options, 'optionalAccess', _21 => _21.indexes])) {
651
+ for (const indexDef of schema.options.indexes) {
652
+ const indexName = _nullishCoalesce(indexDef.name, () => ( `idx_${toTableName(schema.name)}_${indexDef.columns.map((c) => toColumnName(c)).join("_")}`));
653
+ indexes.push({
654
+ name: indexName,
655
+ columns: indexDef.columns.map((c) => toColumnName(c)),
656
+ unique: _nullishCoalesce(indexDef.unique, () => ( false)),
657
+ type: indexDef.type
658
+ });
659
+ }
660
+ }
661
+ return {
662
+ name: toTableName(schema.name),
663
+ columns,
664
+ foreignKeys,
665
+ indexes,
666
+ comment: schema.displayName
667
+ };
668
+ }
669
+ function generatePivotTable(sourceSchema, _propertyName, property, allSchemas, options) {
670
+ if (property.type !== "Association") {
671
+ return null;
672
+ }
673
+ const assocProp = property;
674
+ if (assocProp.relation !== "ManyToMany" || !assocProp.target) {
675
+ return null;
676
+ }
677
+ const targetSchema = allSchemas[assocProp.target];
678
+ if (!targetSchema) {
679
+ return null;
680
+ }
681
+ const dialect = options.dialect;
682
+ const sourceTable = toTableName(sourceSchema.name);
683
+ const targetTable = toTableName(assocProp.target);
684
+ const tables = [sourceTable, targetTable].sort();
685
+ const pivotName = _nullishCoalesce(assocProp.joinTable, () => ( `${tables[0]}_${tables[1]}`));
686
+ const sourceIdType = _nullishCoalesce(_optionalChain([sourceSchema, 'access', _22 => _22.options, 'optionalAccess', _23 => _23.idType]), () => ( "BigInt"));
687
+ const targetIdType = _nullishCoalesce(_optionalChain([targetSchema, 'access', _24 => _24.options, 'optionalAccess', _25 => _25.idType]), () => ( "BigInt"));
688
+ const sourceColName = `${toSnakeCase(sourceSchema.name)}_id`;
689
+ const targetColName = `${toSnakeCase(assocProp.target)}_id`;
690
+ const columns = [
691
+ {
692
+ name: sourceColName,
693
+ type: getForeignKeyType(sourceIdType, dialect),
694
+ nullable: false,
695
+ primaryKey: false,
696
+ autoIncrement: false,
697
+ unique: false,
698
+ unsigned: dialect === "mysql" && ["Int", "BigInt"].includes(sourceIdType)
699
+ },
700
+ {
701
+ name: targetColName,
702
+ type: getForeignKeyType(targetIdType, dialect),
703
+ nullable: false,
704
+ primaryKey: false,
705
+ autoIncrement: false,
706
+ unique: false,
707
+ unsigned: dialect === "mysql" && ["Int", "BigInt"].includes(targetIdType)
708
+ }
709
+ ];
710
+ const foreignKeys = [
711
+ {
712
+ name: `fk_${pivotName}_${sourceColName}`,
713
+ columns: [sourceColName],
714
+ referencesTable: sourceTable,
715
+ referencesColumns: ["id"],
716
+ onDelete: _nullishCoalesce(assocProp.onDelete, () => ( "CASCADE")),
717
+ onUpdate: "CASCADE"
718
+ },
719
+ {
720
+ name: `fk_${pivotName}_${targetColName}`,
721
+ columns: [targetColName],
722
+ referencesTable: targetTable,
723
+ referencesColumns: ["id"],
724
+ onDelete: _nullishCoalesce(assocProp.onDelete, () => ( "CASCADE")),
725
+ onUpdate: "CASCADE"
726
+ }
727
+ ];
728
+ const indexes = [
729
+ {
730
+ name: `idx_${pivotName}_unique`,
731
+ columns: [sourceColName, targetColName],
732
+ unique: true
733
+ },
734
+ {
735
+ name: `idx_${pivotName}_${sourceColName}`,
736
+ columns: [sourceColName],
737
+ unique: false
738
+ },
739
+ {
740
+ name: `idx_${pivotName}_${targetColName}`,
741
+ columns: [targetColName],
742
+ unique: false
743
+ }
744
+ ];
745
+ return {
746
+ name: pivotName,
747
+ columns,
748
+ foreignKeys,
749
+ indexes
750
+ };
751
+ }
752
+ function generateMorphPivotTable(sourceSchema, _propertyName, property, allSchemas, options) {
753
+ if (property.type !== "Association") {
754
+ return null;
755
+ }
756
+ const assocProp = property;
757
+ if (assocProp.relation !== "MorphToMany" || !assocProp.target) {
758
+ return null;
759
+ }
760
+ const targetSchema = allSchemas[assocProp.target];
761
+ if (!targetSchema) {
762
+ return null;
763
+ }
764
+ const dialect = options.dialect;
765
+ const morphName = toSnakeCase(assocProp.target).replace(/s$/, "") + "ables";
766
+ const pivotName = _nullishCoalesce(assocProp.joinTable, () => ( morphName));
767
+ const targetIdType = _nullishCoalesce(_optionalChain([targetSchema, 'access', _26 => _26.options, 'optionalAccess', _27 => _27.idType]), () => ( "BigInt"));
768
+ const targetColName = `${toSnakeCase(assocProp.target)}_id`;
769
+ const morphTypeName = `${morphName.replace(/s$/, "")}_type`;
770
+ const morphIdName = `${morphName.replace(/s$/, "")}_id`;
771
+ const morphTargets = [sourceSchema.name];
772
+ for (const [schemaName, schema] of Object.entries(allSchemas)) {
773
+ if (schemaName === sourceSchema.name) continue;
774
+ if (!schema.properties) continue;
775
+ for (const prop of Object.values(schema.properties)) {
776
+ const p = prop;
777
+ if (p.type === "Association" && p.relation === "MorphToMany" && p.target === assocProp.target) {
778
+ if (!morphTargets.includes(schemaName)) {
779
+ morphTargets.push(schemaName);
780
+ }
781
+ }
782
+ }
783
+ }
784
+ let useUuid = false;
785
+ for (const targetName of morphTargets) {
786
+ const schema = allSchemas[targetName];
787
+ if (_optionalChain([schema, 'optionalAccess', _28 => _28.options, 'optionalAccess', _29 => _29.idType]) === "Uuid") {
788
+ useUuid = true;
789
+ break;
790
+ }
791
+ }
792
+ const enumInfo = getEnumType(morphTargets, dialect, `${morphTypeName}_enum`);
793
+ const morphIdType = useUuid ? dialect === "mysql" ? "CHAR(36)" : dialect === "postgresql" ? "UUID" : "TEXT" : dialect === "mysql" ? "BIGINT UNSIGNED" : dialect === "postgresql" ? "BIGINT" : "INTEGER";
794
+ const columns = [
795
+ {
796
+ name: targetColName,
797
+ type: getForeignKeyType(targetIdType, dialect),
798
+ nullable: false,
799
+ primaryKey: false,
800
+ autoIncrement: false,
801
+ unique: false,
802
+ unsigned: dialect === "mysql" && ["Int", "BigInt"].includes(targetIdType)
803
+ },
804
+ {
805
+ name: morphTypeName,
806
+ type: enumInfo.type,
807
+ nullable: false,
808
+ primaryKey: false,
809
+ autoIncrement: false,
810
+ unique: false,
811
+ unsigned: false
812
+ },
813
+ {
814
+ name: morphIdName,
815
+ type: morphIdType,
816
+ nullable: false,
817
+ primaryKey: false,
818
+ autoIncrement: false,
819
+ unique: false,
820
+ unsigned: dialect === "mysql" && !useUuid
821
+ }
822
+ ];
823
+ const foreignKeys = [
824
+ {
825
+ name: `fk_${pivotName}_${targetColName}`,
826
+ columns: [targetColName],
827
+ referencesTable: toTableName(assocProp.target),
828
+ referencesColumns: ["id"],
829
+ onDelete: _nullishCoalesce(assocProp.onDelete, () => ( "CASCADE")),
830
+ onUpdate: "CASCADE"
831
+ }
832
+ ];
833
+ const indexes = [
834
+ {
835
+ name: `idx_${pivotName}_unique`,
836
+ columns: [targetColName, morphTypeName, morphIdName],
837
+ unique: true
838
+ },
839
+ {
840
+ name: `idx_${pivotName}_${targetColName}`,
841
+ columns: [targetColName],
842
+ unique: false
843
+ },
844
+ {
845
+ name: `idx_${pivotName}_morphable`,
846
+ columns: [morphTypeName, morphIdName],
847
+ unique: false
848
+ }
849
+ ];
850
+ return {
851
+ name: pivotName,
852
+ columns,
853
+ foreignKeys,
854
+ indexes
855
+ };
856
+ }
857
+
858
+ // src/migration/generator.ts
859
+ var DIALECT_INCOMPATIBLE_TYPES = {
860
+ Point: {
861
+ dialects: ["sqlite"],
862
+ reason: "SQLite does not support native spatial types. Point will be stored as TEXT (JSON), which is incompatible with MySQL/PostgreSQL spatial functions (ST_Distance, ST_Within, etc.). Use Coordinates type for cross-database compatibility."
863
+ }
864
+ };
865
+ var DIALECT_INCOMPATIBLE_INDEX_TYPES = {
866
+ gin: {
867
+ dialects: ["mysql", "sqlite"],
868
+ reason: "GIN (Generalized Inverted Index) is PostgreSQL-specific.",
869
+ suggestion: 'For fulltext search, use type: "fulltext" instead. For JSONB indexing, this only works in PostgreSQL.'
870
+ },
871
+ gist: {
872
+ dialects: ["mysql", "sqlite"],
873
+ reason: "GiST (Generalized Search Tree) is PostgreSQL-specific.",
874
+ suggestion: 'For spatial data, use type: "spatial" which works on both MySQL and PostgreSQL.'
875
+ },
876
+ fulltext: {
877
+ dialects: ["sqlite"],
878
+ reason: "SQLite does not support native fulltext indexes. FTS requires virtual tables which are not auto-generated.",
879
+ suggestion: "Consider using a regular index or implementing SQLite FTS manually."
880
+ },
881
+ spatial: {
882
+ dialects: ["sqlite"],
883
+ reason: "SQLite does not support spatial indexes.",
884
+ suggestion: "Use Coordinates type with regular indexes for cross-database compatibility."
885
+ }
886
+ };
887
+ function validateSchemaCompatibility(schemas, dialect) {
888
+ const errors = [];
889
+ for (const [schemaName, schema] of Object.entries(schemas)) {
890
+ if (schema.kind === "enum") continue;
891
+ if (schema.properties) {
892
+ for (const [propName, property] of Object.entries(schema.properties)) {
893
+ const propType = property.type;
894
+ const incompatibility = DIALECT_INCOMPATIBLE_TYPES[propType];
895
+ if (incompatibility && incompatibility.dialects.includes(dialect)) {
896
+ errors.push(
897
+ `Schema "${schemaName}", property "${propName}": Type "${propType}" is not supported in ${dialect}. ${incompatibility.reason}`
898
+ );
899
+ }
900
+ }
901
+ }
902
+ if (_optionalChain([schema, 'access', _30 => _30.options, 'optionalAccess', _31 => _31.indexes])) {
903
+ for (const indexDef of schema.options.indexes) {
904
+ if (indexDef.type) {
905
+ const incompatibility = DIALECT_INCOMPATIBLE_INDEX_TYPES[indexDef.type];
906
+ if (incompatibility && incompatibility.dialects.includes(dialect)) {
907
+ const indexName = _nullishCoalesce(indexDef.name, () => ( `index on [${indexDef.columns.join(", ")}]`));
908
+ let message = `Schema "${schemaName}", index "${indexName}": Index type "${indexDef.type}" is not supported in ${dialect}. ${incompatibility.reason}`;
909
+ if (incompatibility.suggestion) {
910
+ message += ` ${incompatibility.suggestion}`;
911
+ }
912
+ errors.push(message);
913
+ }
914
+ }
915
+ }
916
+ }
917
+ }
918
+ if (errors.length > 0) {
919
+ throw new Error(
920
+ `SQL Generator: Incompatible types detected for dialect "${dialect}":
921
+
922
+ ` + errors.map((e, i) => `${i + 1}. ${e}`).join("\n\n") + "\n\nTo fix: Either change the type/index or use a compatible dialect."
923
+ );
924
+ }
925
+ }
926
+ function resolveOptions(options) {
927
+ return {
928
+ dialect: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _32 => _32.dialect]), () => ( "mysql")),
929
+ ifNotExists: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _33 => _33.ifNotExists]), () => ( true)),
930
+ generateDown: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _34 => _34.generateDown]), () => ( true)),
931
+ startVersion: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _35 => _35.startVersion]), () => ( 1)),
932
+ versionPadding: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _36 => _36.versionPadding]), () => ( 4))
933
+ };
934
+ }
935
+ function formatVersion(version, padding) {
936
+ return String(version).padStart(padding, "0");
937
+ }
938
+ function generateFileName(version, name, padding) {
939
+ const versionStr = formatVersion(version, padding);
940
+ return `${versionStr}_${name}.sql`;
941
+ }
942
+ function generateCreateTableSql(table, options) {
943
+ const lines = [];
944
+ const dialect = options.dialect;
945
+ lines.push(`-- Migration: Create ${table.name} table`);
946
+ lines.push(`-- Generated by @famgia/omnify-sql`);
947
+ lines.push("");
948
+ lines.push(formatCreateTable(table, dialect, { ifNotExists: options.ifNotExists }));
949
+ lines.push("");
950
+ const indexStatements = formatIndexes(table, dialect);
951
+ if (indexStatements.length > 0) {
952
+ lines.push("-- Indexes");
953
+ lines.push(...indexStatements);
954
+ lines.push("");
955
+ }
956
+ const commentStatements = formatColumnComments(table, dialect);
957
+ if (commentStatements.length > 0) {
958
+ lines.push("-- Column comments");
959
+ lines.push(...commentStatements);
960
+ lines.push("");
961
+ }
962
+ if (options.generateDown) {
963
+ lines.push("-- Down migration");
964
+ lines.push(`-- ${formatDropTable(table.name, dialect, { ifExists: true, cascade: true })}`);
965
+ }
966
+ return lines.join("\n");
967
+ }
968
+ function topologicalSort(schemas) {
969
+ const sorted = [];
970
+ const visited = /* @__PURE__ */ new Set();
971
+ const visiting = /* @__PURE__ */ new Set();
972
+ function visit(schemaName) {
973
+ if (visited.has(schemaName)) return;
974
+ if (visiting.has(schemaName)) {
975
+ return;
976
+ }
977
+ visiting.add(schemaName);
978
+ const schema = schemas[schemaName];
979
+ if (!schema) return;
980
+ if (schema.properties) {
981
+ for (const property of Object.values(schema.properties)) {
982
+ if (property.type === "Association") {
983
+ const assocProp = property;
984
+ if (["ManyToOne", "OneToOne"].includes(_nullishCoalesce(assocProp.relation, () => ( ""))) && assocProp.target) {
985
+ visit(assocProp.target);
986
+ }
987
+ }
988
+ }
989
+ }
990
+ visiting.delete(schemaName);
991
+ visited.add(schemaName);
992
+ sorted.push(schema);
993
+ }
994
+ for (const schemaName of Object.keys(schemas)) {
995
+ visit(schemaName);
996
+ }
997
+ return sorted;
998
+ }
999
+ function generateMigrations(schemas, options) {
1000
+ const resolved = resolveOptions(options);
1001
+ validateSchemaCompatibility(schemas, resolved.dialect);
1002
+ const migrations = [];
1003
+ let version = resolved.startVersion;
1004
+ const objectSchemas = {};
1005
+ for (const [name, schema] of Object.entries(schemas)) {
1006
+ if (schema.kind !== "enum") {
1007
+ objectSchemas[name] = schema;
1008
+ }
1009
+ }
1010
+ const sortedSchemas = topologicalSort(objectSchemas);
1011
+ const createdPivots = /* @__PURE__ */ new Set();
1012
+ for (const schema of sortedSchemas) {
1013
+ const table = schemaToTable(schema, schemas, resolved);
1014
+ migrations.push({
1015
+ version,
1016
+ name: `create_${table.name}`,
1017
+ fileName: generateFileName(version, `create_${table.name}`, resolved.versionPadding),
1018
+ content: generateCreateTableSql(table, resolved),
1019
+ tables: [table.name],
1020
+ type: "create"
1021
+ });
1022
+ version++;
1023
+ }
1024
+ for (const schema of sortedSchemas) {
1025
+ if (!schema.properties) continue;
1026
+ for (const [propName, property] of Object.entries(schema.properties)) {
1027
+ const pivotTable = generatePivotTable(schema, propName, property, schemas, resolved);
1028
+ if (pivotTable && !createdPivots.has(pivotTable.name)) {
1029
+ createdPivots.add(pivotTable.name);
1030
+ migrations.push({
1031
+ version,
1032
+ name: `create_${pivotTable.name}`,
1033
+ fileName: generateFileName(version, `create_${pivotTable.name}`, resolved.versionPadding),
1034
+ content: generateCreateTableSql(pivotTable, resolved),
1035
+ tables: [pivotTable.name],
1036
+ type: "pivot"
1037
+ });
1038
+ version++;
1039
+ }
1040
+ const morphPivot = generateMorphPivotTable(schema, propName, property, schemas, resolved);
1041
+ if (morphPivot && !createdPivots.has(morphPivot.name)) {
1042
+ createdPivots.add(morphPivot.name);
1043
+ migrations.push({
1044
+ version,
1045
+ name: `create_${morphPivot.name}`,
1046
+ fileName: generateFileName(version, `create_${morphPivot.name}`, resolved.versionPadding),
1047
+ content: generateCreateTableSql(morphPivot, resolved),
1048
+ tables: [morphPivot.name],
1049
+ type: "pivot"
1050
+ });
1051
+ version++;
1052
+ }
1053
+ }
1054
+ }
1055
+ return migrations;
1056
+ }
1057
+ function generateMigrationFromSchema(schema, allSchemas, options) {
1058
+ const resolved = resolveOptions(options);
1059
+ const version = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _37 => _37.version]), () => ( resolved.startVersion));
1060
+ const table = schemaToTable(schema, allSchemas, resolved);
1061
+ return {
1062
+ version,
1063
+ name: `create_${table.name}`,
1064
+ fileName: generateFileName(version, `create_${table.name}`, resolved.versionPadding),
1065
+ content: generateCreateTableSql(table, resolved),
1066
+ tables: [table.name],
1067
+ type: "create"
1068
+ };
1069
+ }
1070
+ function generateDropMigration(tableName, options) {
1071
+ const resolved = resolveOptions(options);
1072
+ const version = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _38 => _38.version]), () => ( resolved.startVersion));
1073
+ const isTableName = tableName.includes("_") || tableName.endsWith("s") || tableName.endsWith("es");
1074
+ const snakeTable = isTableName ? tableName : toTableName(tableName);
1075
+ const dropSql = formatDropTable(snakeTable, resolved.dialect, { ifExists: true, cascade: true });
1076
+ const lines = [
1077
+ `-- Migration: Drop ${snakeTable} table`,
1078
+ "-- Generated by @famgia/omnify-sql",
1079
+ "",
1080
+ dropSql
1081
+ ];
1082
+ return {
1083
+ version,
1084
+ name: `drop_${snakeTable}`,
1085
+ fileName: generateFileName(version, `drop_${snakeTable}`, resolved.versionPadding),
1086
+ content: lines.join("\n"),
1087
+ tables: [snakeTable],
1088
+ type: "drop"
1089
+ };
1090
+ }
1091
+ function getMigrationPath(migration, basePath = "migrations") {
1092
+ return `${basePath}/${migration.fileName}`;
1093
+ }
1094
+
1095
+
1096
+
1097
+
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+ exports.quoteIdentifier = quoteIdentifier; exports.quoteString = quoteString; exports.formatColumn = formatColumn; exports.formatForeignKey = formatForeignKey; exports.formatIndex = formatIndex; exports.formatCreateTable = formatCreateTable; exports.formatDropTable = formatDropTable; exports.getSqlType = getSqlType; exports.getPrimaryKeyType = getPrimaryKeyType; exports.getForeignKeyType = getForeignKeyType; exports.getEnumType = getEnumType; exports.toSnakeCase = toSnakeCase; exports.toTableName = toTableName; exports.toColumnName = toColumnName; exports.schemaToTable = schemaToTable; exports.generatePivotTable = generatePivotTable; exports.generateMorphPivotTable = generateMorphPivotTable; exports.generateMigrations = generateMigrations; exports.generateMigrationFromSchema = generateMigrationFromSchema; exports.generateDropMigration = generateDropMigration; exports.getMigrationPath = getMigrationPath;
1118
+ //# sourceMappingURL=chunk-YNWO77KO.cjs.map