@famgia/omnify-laravel 2.0.21 → 2.0.22
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.
- package/dist/{chunk-U3NDJ6S6.js → chunk-RSC5ATSV.js} +201 -9
- package/dist/chunk-RSC5ATSV.js.map +1 -0
- package/dist/index.cjs +200 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1 -1
- package/dist/plugin.cjs +200 -8
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-U3NDJ6S6.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -192,6 +192,17 @@ interface SchemaToBlueprintOptions {
|
|
|
192
192
|
pluginEnums?: ReadonlyMap<string, PluginEnumDefinition>;
|
|
193
193
|
/** Locale resolution options for displayName */
|
|
194
194
|
locale?: LocaleResolutionOptions;
|
|
195
|
+
/**
|
|
196
|
+
* Set of FK constraints to exclude from this blueprint.
|
|
197
|
+
* Format: "schemaName.propertyName" (e.g., "Employee.department")
|
|
198
|
+
* Used for deferring circular FK dependencies to a separate migration.
|
|
199
|
+
*/
|
|
200
|
+
excludeFKs?: Set<string>;
|
|
201
|
+
/**
|
|
202
|
+
* Current schema name (for FK exclusion matching).
|
|
203
|
+
* Set automatically when excludeFKs is provided.
|
|
204
|
+
*/
|
|
205
|
+
schemaName?: string;
|
|
195
206
|
}
|
|
196
207
|
/**
|
|
197
208
|
* Generates table blueprint from schema.
|
|
@@ -435,6 +446,8 @@ declare function generateProviderRegistration(existingContent: string | null, la
|
|
|
435
446
|
interface FactoryGeneratorOptions {
|
|
436
447
|
/** Model namespace */
|
|
437
448
|
modelNamespace?: string;
|
|
449
|
+
/** Factory namespace (defaults to Database\Factories) */
|
|
450
|
+
factoryNamespace?: string;
|
|
438
451
|
/** Factory output path */
|
|
439
452
|
factoryPath?: string;
|
|
440
453
|
/** Faker locale */
|
package/dist/index.d.ts
CHANGED
|
@@ -192,6 +192,17 @@ interface SchemaToBlueprintOptions {
|
|
|
192
192
|
pluginEnums?: ReadonlyMap<string, PluginEnumDefinition>;
|
|
193
193
|
/** Locale resolution options for displayName */
|
|
194
194
|
locale?: LocaleResolutionOptions;
|
|
195
|
+
/**
|
|
196
|
+
* Set of FK constraints to exclude from this blueprint.
|
|
197
|
+
* Format: "schemaName.propertyName" (e.g., "Employee.department")
|
|
198
|
+
* Used for deferring circular FK dependencies to a separate migration.
|
|
199
|
+
*/
|
|
200
|
+
excludeFKs?: Set<string>;
|
|
201
|
+
/**
|
|
202
|
+
* Current schema name (for FK exclusion matching).
|
|
203
|
+
* Set automatically when excludeFKs is provided.
|
|
204
|
+
*/
|
|
205
|
+
schemaName?: string;
|
|
195
206
|
}
|
|
196
207
|
/**
|
|
197
208
|
* Generates table blueprint from schema.
|
|
@@ -435,6 +446,8 @@ declare function generateProviderRegistration(existingContent: string | null, la
|
|
|
435
446
|
interface FactoryGeneratorOptions {
|
|
436
447
|
/** Model namespace */
|
|
437
448
|
modelNamespace?: string;
|
|
449
|
+
/** Factory namespace (defaults to Database\Factories) */
|
|
450
|
+
factoryNamespace?: string;
|
|
438
451
|
/** Factory output path */
|
|
439
452
|
factoryPath?: string;
|
|
440
453
|
/** Faker locale */
|
package/dist/index.js
CHANGED
package/dist/plugin.cjs
CHANGED
|
@@ -455,7 +455,8 @@ function expandCompoundType(propName, property, customTypes, options = {}) {
|
|
|
455
455
|
return expanded;
|
|
456
456
|
}
|
|
457
457
|
function schemaToBlueprint(schema, allSchemas, options = {}) {
|
|
458
|
-
const { customTypes = /* @__PURE__ */ new Map(), pluginEnums = /* @__PURE__ */ new Map(), locale } = options;
|
|
458
|
+
const { customTypes = /* @__PURE__ */ new Map(), pluginEnums = /* @__PURE__ */ new Map(), locale, excludeFKs } = options;
|
|
459
|
+
const schemaName = options.schemaName ?? schema.name;
|
|
459
460
|
const compoundOptions = { locale, pluginEnums };
|
|
460
461
|
const tableName = schema.options?.tableName ?? toTableName(schema.name);
|
|
461
462
|
const columns = [];
|
|
@@ -525,7 +526,10 @@ function schemaToBlueprint(schema, allSchemas, options = {}) {
|
|
|
525
526
|
if (!explicitColumnNames.has(fkResult.column.name)) {
|
|
526
527
|
columns.push(fkResult.column);
|
|
527
528
|
}
|
|
528
|
-
|
|
529
|
+
const fkKey = `${schemaName}.${propName}`;
|
|
530
|
+
if (!excludeFKs?.has(fkKey)) {
|
|
531
|
+
foreignKeys.push(fkResult.foreignKey);
|
|
532
|
+
}
|
|
529
533
|
indexes.push(fkResult.index);
|
|
530
534
|
}
|
|
531
535
|
const polyResult = generatePolymorphicColumns(propName, property, allSchemas);
|
|
@@ -1021,6 +1025,143 @@ function extractDependencies(schema) {
|
|
|
1021
1025
|
}
|
|
1022
1026
|
return deps;
|
|
1023
1027
|
}
|
|
1028
|
+
function detectCircularDependencies(schemas) {
|
|
1029
|
+
const circularFKs = /* @__PURE__ */ new Set();
|
|
1030
|
+
const graph = /* @__PURE__ */ new Map();
|
|
1031
|
+
for (const schema of Object.values(schemas)) {
|
|
1032
|
+
if (schema.kind === "enum" || !schema.properties) continue;
|
|
1033
|
+
const refs = /* @__PURE__ */ new Map();
|
|
1034
|
+
for (const [propName, property] of Object.entries(schema.properties)) {
|
|
1035
|
+
if (property.type !== "Association") continue;
|
|
1036
|
+
const assocProp = property;
|
|
1037
|
+
if ((assocProp.relation === "ManyToOne" || assocProp.relation === "OneToOne") && !assocProp.mappedBy && assocProp.target && assocProp.target !== schema.name) {
|
|
1038
|
+
refs.set(assocProp.target, propName);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
if (refs.size > 0) {
|
|
1042
|
+
graph.set(schema.name, refs);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
for (const [schemaA, refsA] of graph) {
|
|
1046
|
+
for (const [targetB, propNameA] of refsA) {
|
|
1047
|
+
if (targetB === schemaA) continue;
|
|
1048
|
+
const refsB = graph.get(targetB);
|
|
1049
|
+
if (refsB && refsB.has(schemaA)) {
|
|
1050
|
+
if (schemaA > targetB) {
|
|
1051
|
+
circularFKs.add(`${schemaA}.${propNameA}`);
|
|
1052
|
+
} else {
|
|
1053
|
+
const propNameB = refsB.get(schemaA);
|
|
1054
|
+
circularFKs.add(`${targetB}.${propNameB}`);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
return circularFKs;
|
|
1060
|
+
}
|
|
1061
|
+
function extractDeferredFKs(schemas, circularFKs) {
|
|
1062
|
+
const deferred = [];
|
|
1063
|
+
for (const schema of Object.values(schemas)) {
|
|
1064
|
+
if (schema.kind === "enum" || !schema.properties) continue;
|
|
1065
|
+
const tableName = schema.options?.tableName ?? toTableName(schema.name);
|
|
1066
|
+
for (const [propName, property] of Object.entries(schema.properties)) {
|
|
1067
|
+
const key = `${schema.name}.${propName}`;
|
|
1068
|
+
if (!circularFKs.has(key)) continue;
|
|
1069
|
+
const assocProp = property;
|
|
1070
|
+
if (!assocProp.target) continue;
|
|
1071
|
+
const targetSchema = schemas[assocProp.target];
|
|
1072
|
+
const targetTable = targetSchema?.options?.tableName ?? toTableName(assocProp.target);
|
|
1073
|
+
const columnName = toColumnName(propName) + "_id";
|
|
1074
|
+
deferred.push({
|
|
1075
|
+
tableName,
|
|
1076
|
+
columnName,
|
|
1077
|
+
targetTable,
|
|
1078
|
+
onDelete: assocProp.onDelete,
|
|
1079
|
+
onUpdate: assocProp.onUpdate
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
return deferred;
|
|
1084
|
+
}
|
|
1085
|
+
function generateDeferredFKMigration(deferredFKs, options = {}) {
|
|
1086
|
+
if (deferredFKs.length === 0) return null;
|
|
1087
|
+
const timestamp = options.timestamp ?? generateTimestamp();
|
|
1088
|
+
const fileName = `${timestamp}_add_circular_foreign_keys.php`;
|
|
1089
|
+
const connection = options.connection ? `
|
|
1090
|
+
protected $connection = '${options.connection}';
|
|
1091
|
+
` : "";
|
|
1092
|
+
const byTable = /* @__PURE__ */ new Map();
|
|
1093
|
+
for (const fk of deferredFKs) {
|
|
1094
|
+
const existing = byTable.get(fk.tableName) ?? [];
|
|
1095
|
+
existing.push(fk);
|
|
1096
|
+
byTable.set(fk.tableName, existing);
|
|
1097
|
+
}
|
|
1098
|
+
const upStatements = [];
|
|
1099
|
+
const downStatements = [];
|
|
1100
|
+
for (const [tableName, fks] of byTable) {
|
|
1101
|
+
const fkLines = fks.map((fk) => {
|
|
1102
|
+
let line = ` $table->foreign('${fk.columnName}')->references('id')->on('${fk.targetTable}')`;
|
|
1103
|
+
if (fk.onDelete) line += `->onDelete('${fk.onDelete}')`;
|
|
1104
|
+
if (fk.onUpdate) line += `->onUpdate('${fk.onUpdate}')`;
|
|
1105
|
+
return line + ";";
|
|
1106
|
+
});
|
|
1107
|
+
upStatements.push(` Schema::table('${tableName}', function (Blueprint $table) {
|
|
1108
|
+
${fkLines.join("\n")}
|
|
1109
|
+
});`);
|
|
1110
|
+
const dropLines = fks.map(
|
|
1111
|
+
(fk) => ` $table->dropForeign(['${fk.columnName}']);`
|
|
1112
|
+
);
|
|
1113
|
+
downStatements.push(` Schema::table('${tableName}', function (Blueprint $table) {
|
|
1114
|
+
${dropLines.join("\n")}
|
|
1115
|
+
});`);
|
|
1116
|
+
}
|
|
1117
|
+
const content = `<?php
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* \u26A0\uFE0F DO NOT EDIT THIS FILE! \u26A0\uFE0F
|
|
1121
|
+
* \u3053\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u7DE8\u96C6\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF01
|
|
1122
|
+
* KH\xD4NG \u0110\u01AF\u1EE2C S\u1EECA FILE N\xC0Y!
|
|
1123
|
+
*
|
|
1124
|
+
* This file is AUTO-GENERATED by Omnify.
|
|
1125
|
+
* Any manual changes will be OVERWRITTEN on next generation.
|
|
1126
|
+
*
|
|
1127
|
+
* This migration adds foreign key constraints for circular dependencies.
|
|
1128
|
+
* These constraints are deferred to run after all tables are created.
|
|
1129
|
+
*
|
|
1130
|
+
* @generated by @famgia/omnify-laravel
|
|
1131
|
+
*/
|
|
1132
|
+
|
|
1133
|
+
use Illuminate\\Database\\Migrations\\Migration;
|
|
1134
|
+
use Illuminate\\Database\\Schema\\Blueprint;
|
|
1135
|
+
use Illuminate\\Support\\Facades\\Schema;
|
|
1136
|
+
|
|
1137
|
+
return new class extends Migration
|
|
1138
|
+
{${connection}
|
|
1139
|
+
/**
|
|
1140
|
+
* Run the migrations.
|
|
1141
|
+
*/
|
|
1142
|
+
public function up(): void
|
|
1143
|
+
{
|
|
1144
|
+
${upStatements.join("\n\n")}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* Reverse the migrations.
|
|
1149
|
+
*/
|
|
1150
|
+
public function down(): void
|
|
1151
|
+
{
|
|
1152
|
+
${downStatements.join("\n\n")}
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
`;
|
|
1156
|
+
const tables = [...byTable.keys()];
|
|
1157
|
+
return {
|
|
1158
|
+
fileName,
|
|
1159
|
+
className: "AddCircularForeignKeys",
|
|
1160
|
+
content,
|
|
1161
|
+
tables,
|
|
1162
|
+
type: "alter"
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1024
1165
|
function topologicalSort(schemas) {
|
|
1025
1166
|
const schemaList = Object.values(schemas).filter((s) => s.kind !== "enum");
|
|
1026
1167
|
const sorted = [];
|
|
@@ -1054,6 +1195,7 @@ function generateMigrations(schemas, options = {}) {
|
|
|
1054
1195
|
const migrations = [];
|
|
1055
1196
|
const pivotTablesGenerated = /* @__PURE__ */ new Set();
|
|
1056
1197
|
let timestampOffset = 0;
|
|
1198
|
+
const circularFKs = detectCircularDependencies(schemas);
|
|
1057
1199
|
const sortedSchemas = topologicalSort(schemas);
|
|
1058
1200
|
const baseTimestamp = options.timestamp ?? generateTimestamp();
|
|
1059
1201
|
for (const schema of sortedSchemas) {
|
|
@@ -1062,7 +1204,9 @@ function generateMigrations(schemas, options = {}) {
|
|
|
1062
1204
|
const blueprint = schemaToBlueprint(schema, schemas, {
|
|
1063
1205
|
customTypes: options.customTypes,
|
|
1064
1206
|
pluginEnums: options.pluginEnums,
|
|
1065
|
-
locale: options.locale
|
|
1207
|
+
locale: options.locale,
|
|
1208
|
+
excludeFKs: circularFKs,
|
|
1209
|
+
schemaName: schema.name
|
|
1066
1210
|
});
|
|
1067
1211
|
const migration = generateCreateMigration(blueprint, {
|
|
1068
1212
|
...options,
|
|
@@ -1102,6 +1246,19 @@ function generateMigrations(schemas, options = {}) {
|
|
|
1102
1246
|
});
|
|
1103
1247
|
}
|
|
1104
1248
|
}
|
|
1249
|
+
if (circularFKs.size > 0) {
|
|
1250
|
+
const deferredFKs = extractDeferredFKs(schemas, circularFKs);
|
|
1251
|
+
if (deferredFKs.length > 0) {
|
|
1252
|
+
const offsetTimestamp = incrementTimestamp(baseTimestamp, timestampOffset);
|
|
1253
|
+
const deferredMigration = generateDeferredFKMigration(deferredFKs, {
|
|
1254
|
+
...options,
|
|
1255
|
+
timestamp: offsetTimestamp
|
|
1256
|
+
});
|
|
1257
|
+
if (deferredMigration) {
|
|
1258
|
+
migrations.push(deferredMigration);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1105
1262
|
return migrations;
|
|
1106
1263
|
}
|
|
1107
1264
|
function incrementTimestamp(timestamp, seconds) {
|
|
@@ -1181,8 +1338,16 @@ function generateTimestamp2() {
|
|
|
1181
1338
|
const seconds = String(now.getSeconds()).padStart(2, "0");
|
|
1182
1339
|
return `${year}_${month}_${day}_${hours}${minutes}${seconds}`;
|
|
1183
1340
|
}
|
|
1341
|
+
function shouldSkipAssociationColumn(prop) {
|
|
1342
|
+
if (prop.type !== "Association") return false;
|
|
1343
|
+
if (isAssociationWithFkColumn(prop)) return false;
|
|
1344
|
+
return true;
|
|
1345
|
+
}
|
|
1184
1346
|
function formatAddColumn(columnName, prop) {
|
|
1185
1347
|
const lines = [];
|
|
1348
|
+
if (shouldSkipAssociationColumn(prop)) {
|
|
1349
|
+
return lines;
|
|
1350
|
+
}
|
|
1186
1351
|
if (isAssociationWithFkColumn(prop)) {
|
|
1187
1352
|
const fkColumn = getAssociationFkColumnName(columnName);
|
|
1188
1353
|
let code2 = `$table->unsignedBigInteger('${fkColumn}')`;
|
|
@@ -1222,6 +1387,9 @@ function formatAddColumn(columnName, prop) {
|
|
|
1222
1387
|
}
|
|
1223
1388
|
function formatDropColumn(columnName, prop) {
|
|
1224
1389
|
const lines = [];
|
|
1390
|
+
if (prop && shouldSkipAssociationColumn(prop)) {
|
|
1391
|
+
return lines;
|
|
1392
|
+
}
|
|
1225
1393
|
if (prop && isAssociationWithFkColumn(prop)) {
|
|
1226
1394
|
const fkColumn = getAssociationFkColumnName(columnName);
|
|
1227
1395
|
lines.push(`$table->dropForeign(['${fkColumn}']);`);
|
|
@@ -2871,9 +3039,26 @@ ${providerLine}
|
|
|
2871
3039
|
}
|
|
2872
3040
|
|
|
2873
3041
|
// src/factory/generator.ts
|
|
3042
|
+
function deriveFactoryNamespace(modelNamespace) {
|
|
3043
|
+
if (modelNamespace === "App\\Models") {
|
|
3044
|
+
return "Database\\Factories";
|
|
3045
|
+
}
|
|
3046
|
+
if (modelNamespace.endsWith("\\Models")) {
|
|
3047
|
+
const base = modelNamespace.slice(0, -7);
|
|
3048
|
+
return `${base}\\Database\\Factories`;
|
|
3049
|
+
}
|
|
3050
|
+
const parts = modelNamespace.split("\\");
|
|
3051
|
+
if (parts.length > 1 && parts[parts.length - 1] === "Models") {
|
|
3052
|
+
parts.pop();
|
|
3053
|
+
return [...parts, "Database", "Factories"].join("\\");
|
|
3054
|
+
}
|
|
3055
|
+
return "Database\\Factories";
|
|
3056
|
+
}
|
|
2874
3057
|
function resolveOptions2(options) {
|
|
3058
|
+
const modelNamespace = options?.modelNamespace ?? "App\\Models";
|
|
2875
3059
|
return {
|
|
2876
|
-
modelNamespace
|
|
3060
|
+
modelNamespace,
|
|
3061
|
+
factoryNamespace: options?.factoryNamespace ?? deriveFactoryNamespace(modelNamespace),
|
|
2877
3062
|
factoryPath: options?.factoryPath ?? "database/factories",
|
|
2878
3063
|
fakerLocale: options?.fakerLocale ?? "en_US",
|
|
2879
3064
|
customTypes: options?.customTypes ?? /* @__PURE__ */ new Map(),
|
|
@@ -2886,16 +3071,18 @@ function resolveSchemaOptions2(schema, globalOptions) {
|
|
|
2886
3071
|
return globalOptions;
|
|
2887
3072
|
}
|
|
2888
3073
|
const base = pkgOutput.base;
|
|
3074
|
+
const modelNamespace = pkgOutput.modelsNamespace;
|
|
2889
3075
|
return {
|
|
2890
3076
|
...globalOptions,
|
|
2891
|
-
modelNamespace
|
|
3077
|
+
modelNamespace,
|
|
3078
|
+
factoryNamespace: pkgOutput.factoriesNamespace ?? deriveFactoryNamespace(modelNamespace),
|
|
2892
3079
|
factoryPath: `${base}/${pkgOutput.factoriesPath ?? "database/factories"}`
|
|
2893
3080
|
};
|
|
2894
3081
|
}
|
|
2895
3082
|
function getStubContent2() {
|
|
2896
3083
|
return `<?php
|
|
2897
3084
|
|
|
2898
|
-
namespace
|
|
3085
|
+
namespace {{FACTORY_NAMESPACE}};
|
|
2899
3086
|
|
|
2900
3087
|
use {{MODEL_NAMESPACE}}\\{{MODEL_NAME}};
|
|
2901
3088
|
use Illuminate\\Database\\Eloquent\\Factories\\Factory;
|
|
@@ -3192,6 +3379,7 @@ function generateFactory(schema, schemas, options, stubContent) {
|
|
|
3192
3379
|
}
|
|
3193
3380
|
}
|
|
3194
3381
|
let content = stubContent;
|
|
3382
|
+
content = content.replace(/\{\{FACTORY_NAMESPACE\}\}/g, options.factoryNamespace);
|
|
3195
3383
|
content = content.replace(/\{\{MODEL_NAMESPACE\}\}/g, options.modelNamespace);
|
|
3196
3384
|
content = content.replace(/\{\{MODEL_NAME\}\}/g, modelName);
|
|
3197
3385
|
const uniqueImports = [...new Set(imports)];
|
|
@@ -4813,9 +5001,10 @@ function laravelPlugin(options) {
|
|
|
4813
5001
|
name: "laravel-migrations",
|
|
4814
5002
|
description: "Generate Laravel migration files",
|
|
4815
5003
|
generate: async (ctx) => {
|
|
5004
|
+
const baseTimestamp = resolved.timestamp ?? generateTimestamp();
|
|
4816
5005
|
const migrationOptions = {
|
|
4817
5006
|
connection: resolved.connection,
|
|
4818
|
-
timestamp:
|
|
5007
|
+
timestamp: baseTimestamp,
|
|
4819
5008
|
customTypes: ctx.customTypes,
|
|
4820
5009
|
pluginEnums: ctx.pluginEnums
|
|
4821
5010
|
};
|
|
@@ -4837,6 +5026,7 @@ function laravelPlugin(options) {
|
|
|
4837
5026
|
if (ctx.changes.length === 0) {
|
|
4838
5027
|
return outputs;
|
|
4839
5028
|
}
|
|
5029
|
+
let timestampOffset = 0;
|
|
4840
5030
|
const addedSchemaNames = new Set(
|
|
4841
5031
|
ctx.changes.filter((c) => c.changeType === "added").map((c) => c.schemaName)
|
|
4842
5032
|
);
|
|
@@ -4861,15 +5051,17 @@ function laravelPlugin(options) {
|
|
|
4861
5051
|
schemaName: migration.schemaName
|
|
4862
5052
|
}
|
|
4863
5053
|
});
|
|
5054
|
+
timestampOffset++;
|
|
4864
5055
|
}
|
|
4865
5056
|
}
|
|
4866
5057
|
const alterChanges = ctx.changes.filter(
|
|
4867
5058
|
(c) => c.changeType === "modified" || c.changeType === "removed"
|
|
4868
5059
|
);
|
|
4869
5060
|
if (alterChanges.length > 0) {
|
|
5061
|
+
const alterTimestamp = timestampOffset > 0 ? incrementTimestamp(baseTimestamp, timestampOffset) : baseTimestamp;
|
|
4870
5062
|
const alterMigrations = generateMigrationsFromChanges(
|
|
4871
5063
|
alterChanges,
|
|
4872
|
-
migrationOptions
|
|
5064
|
+
{ ...migrationOptions, timestamp: alterTimestamp }
|
|
4873
5065
|
);
|
|
4874
5066
|
for (const migration of alterMigrations) {
|
|
4875
5067
|
outputs.push({
|