@famgia/omnify-cli 2.0.9 → 2.0.11
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/cli.js +357 -170
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +331 -131
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -1
- package/dist/index.d.ts +80 -1
- package/dist/index.js +297 -104
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/cli.js
CHANGED
|
@@ -7,8 +7,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
// src/cli.ts
|
|
10
|
-
import { existsSync as
|
|
11
|
-
import { resolve as
|
|
10
|
+
import { existsSync as existsSync14 } from "fs";
|
|
11
|
+
import { resolve as resolve14 } from "path";
|
|
12
12
|
import { Command } from "commander";
|
|
13
13
|
import { OmnifyError as OmnifyError7 } from "@famgia/omnify-core";
|
|
14
14
|
|
|
@@ -1108,8 +1108,8 @@ function registerDiffCommand(program2) {
|
|
|
1108
1108
|
}
|
|
1109
1109
|
|
|
1110
1110
|
// src/commands/generate.ts
|
|
1111
|
-
import { existsSync as
|
|
1112
|
-
import { resolve as
|
|
1111
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, writeFileSync as writeFileSync5, readdirSync as readdirSync2 } from "fs";
|
|
1112
|
+
import { resolve as resolve9, dirname as dirname6, relative } from "path";
|
|
1113
1113
|
import {
|
|
1114
1114
|
loadSchemas as loadSchemas3,
|
|
1115
1115
|
mergePartialSchemas as mergePartialSchemas3,
|
|
@@ -1144,17 +1144,19 @@ import { generateTypeScript, generateAIGuides as generateTypescriptAIGuides, sho
|
|
|
1144
1144
|
// src/guides/index.ts
|
|
1145
1145
|
import { existsSync as existsSync7, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3 } from "fs";
|
|
1146
1146
|
import { resolve as resolve7, dirname as dirname5, join } from "path";
|
|
1147
|
-
|
|
1148
|
-
var
|
|
1147
|
+
var OMNIFY_SECTION_START = "<!-- OMNIFY_SECTION_START -->";
|
|
1148
|
+
var OMNIFY_SECTION_END = "<!-- OMNIFY_SECTION_END -->";
|
|
1149
|
+
var OMNIFY_SECTION = `${OMNIFY_SECTION_START}
|
|
1150
|
+
## Omnify Schema System
|
|
1149
1151
|
|
|
1150
1152
|
This project uses **Omnify** for schema-driven code generation.
|
|
1151
1153
|
|
|
1152
|
-
|
|
1154
|
+
### Quick Reference
|
|
1153
1155
|
|
|
1154
1156
|
- **Schema Guide**: @.claude/omnify/guides/omnify/schema-guide.md
|
|
1155
1157
|
- **Config Guide**: @.claude/omnify/guides/omnify/config-guide.md
|
|
1156
1158
|
|
|
1157
|
-
|
|
1159
|
+
### Commands
|
|
1158
1160
|
|
|
1159
1161
|
\`\`\`bash
|
|
1160
1162
|
npx omnify generate # Generate code from schemas
|
|
@@ -1162,41 +1164,52 @@ npx omnify validate # Validate schemas
|
|
|
1162
1164
|
php artisan migrate # Run database migrations
|
|
1163
1165
|
\`\`\`
|
|
1164
1166
|
|
|
1165
|
-
|
|
1167
|
+
### Critical Rules
|
|
1166
1168
|
|
|
1167
|
-
|
|
1169
|
+
#### \u26D4 DO NOT EDIT Auto-Generated Files
|
|
1168
1170
|
- \`database/migrations/omnify/**\` - Regenerated on \`npx omnify generate\`
|
|
1169
1171
|
- \`app/Models/OmnifyBase/**\` - Base models (extend, don't edit)
|
|
1170
1172
|
- \`app/Http/Requests/OmnifyBase/**\` - Base requests
|
|
1171
1173
|
- \`app/Http/Resources/OmnifyBase/**\` - Base resources
|
|
1172
1174
|
|
|
1173
|
-
|
|
1175
|
+
#### \u2705 Schema-First Workflow
|
|
1174
1176
|
1. Edit YAML schema in \`schemas/\`
|
|
1175
1177
|
2. Run \`npx omnify generate\`
|
|
1176
1178
|
3. Run \`php artisan migrate\`
|
|
1177
1179
|
|
|
1178
1180
|
**NEVER use \`php artisan make:migration\`** - Always use schemas!
|
|
1181
|
+
${OMNIFY_SECTION_END}`;
|
|
1182
|
+
function updateClaudeMd(rootDir) {
|
|
1183
|
+
const claudeMdPath = resolve7(rootDir, "CLAUDE.md");
|
|
1184
|
+
if (!existsSync7(claudeMdPath)) {
|
|
1185
|
+
writeFileSync3(claudeMdPath, `# Project Documentation
|
|
1179
1186
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1187
|
+
${OMNIFY_SECTION}
|
|
1188
|
+
`);
|
|
1189
|
+
return true;
|
|
1190
|
+
}
|
|
1191
|
+
const currentContent = readFileSync3(claudeMdPath, "utf8");
|
|
1192
|
+
const hasOmnifySection = currentContent.includes(OMNIFY_SECTION_START);
|
|
1193
|
+
if (hasOmnifySection) {
|
|
1194
|
+
const regex = new RegExp(
|
|
1195
|
+
`${escapeRegExp(OMNIFY_SECTION_START)}[\\s\\S]*?${escapeRegExp(OMNIFY_SECTION_END)}`,
|
|
1196
|
+
"g"
|
|
1197
|
+
);
|
|
1198
|
+
const newContent = currentContent.replace(regex, OMNIFY_SECTION);
|
|
1199
|
+
if (newContent !== currentContent) {
|
|
1200
|
+
writeFileSync3(claudeMdPath, newContent);
|
|
1201
|
+
return true;
|
|
1202
|
+
}
|
|
1203
|
+
return false;
|
|
1204
|
+
} else {
|
|
1205
|
+
const newContent = currentContent.trimEnd() + "\n\n" + OMNIFY_SECTION + "\n";
|
|
1206
|
+
writeFileSync3(claudeMdPath, newContent);
|
|
1207
|
+
return true;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
function escapeRegExp(string) {
|
|
1211
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1212
|
+
}
|
|
1200
1213
|
function copyOmnifyGuides(rootDir) {
|
|
1201
1214
|
let filesWritten = 0;
|
|
1202
1215
|
const omnifyPkgPaths = [
|
|
@@ -1251,20 +1264,141 @@ function copyOmnifyGuides(rootDir) {
|
|
|
1251
1264
|
}
|
|
1252
1265
|
function generateAIGuides(rootDir, _plugins) {
|
|
1253
1266
|
let filesWritten = 0;
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1267
|
+
if (updateClaudeMd(rootDir)) {
|
|
1268
|
+
filesWritten++;
|
|
1269
|
+
}
|
|
1257
1270
|
filesWritten += copyOmnifyGuides(rootDir);
|
|
1258
1271
|
return filesWritten;
|
|
1259
1272
|
}
|
|
1260
1273
|
|
|
1274
|
+
// src/version-lock/index.ts
|
|
1275
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync8 } from "fs";
|
|
1276
|
+
import { resolve as resolve8 } from "path";
|
|
1277
|
+
var VERSION_LOCK_FILE = ".omnify-versions.lock";
|
|
1278
|
+
function readVersionLock(rootDir) {
|
|
1279
|
+
const lockPath = resolve8(rootDir, VERSION_LOCK_FILE);
|
|
1280
|
+
if (!existsSync8(lockPath)) {
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
try {
|
|
1284
|
+
const content = readFileSync4(lockPath, "utf-8");
|
|
1285
|
+
return JSON.parse(content);
|
|
1286
|
+
} catch {
|
|
1287
|
+
return null;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
function writeVersionLock(rootDir, lock) {
|
|
1291
|
+
const lockPath = resolve8(rootDir, VERSION_LOCK_FILE);
|
|
1292
|
+
const content = JSON.stringify(lock, null, 2);
|
|
1293
|
+
writeFileSync4(lockPath, content + "\n");
|
|
1294
|
+
}
|
|
1295
|
+
function parseVersion(version) {
|
|
1296
|
+
const cleanVersion = version.replace(/^v/, "");
|
|
1297
|
+
const match = cleanVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
1298
|
+
if (!match) {
|
|
1299
|
+
return null;
|
|
1300
|
+
}
|
|
1301
|
+
return {
|
|
1302
|
+
major: parseInt(match[1], 10),
|
|
1303
|
+
minor: parseInt(match[2], 10),
|
|
1304
|
+
patch: parseInt(match[3], 10)
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
function compareVersions(a, b) {
|
|
1308
|
+
const parsedA = parseVersion(a);
|
|
1309
|
+
const parsedB = parseVersion(b);
|
|
1310
|
+
if (!parsedA || !parsedB) {
|
|
1311
|
+
return 0;
|
|
1312
|
+
}
|
|
1313
|
+
if (parsedA.major !== parsedB.major) {
|
|
1314
|
+
return parsedA.major > parsedB.major ? 1 : -1;
|
|
1315
|
+
}
|
|
1316
|
+
if (parsedA.minor !== parsedB.minor) {
|
|
1317
|
+
return parsedA.minor > parsedB.minor ? 1 : -1;
|
|
1318
|
+
}
|
|
1319
|
+
if (parsedA.patch !== parsedB.patch) {
|
|
1320
|
+
return parsedA.patch > parsedB.patch ? 1 : -1;
|
|
1321
|
+
}
|
|
1322
|
+
return 0;
|
|
1323
|
+
}
|
|
1324
|
+
function checkPluginVersions(plugins, lockFile) {
|
|
1325
|
+
const mismatches = [];
|
|
1326
|
+
const newPlugins = [];
|
|
1327
|
+
const lockedVersions = /* @__PURE__ */ new Map();
|
|
1328
|
+
for (const entry of lockFile.plugins) {
|
|
1329
|
+
lockedVersions.set(entry.name, entry.version);
|
|
1330
|
+
}
|
|
1331
|
+
for (const plugin of plugins) {
|
|
1332
|
+
const lockedVersion = lockedVersions.get(plugin.name);
|
|
1333
|
+
if (!lockedVersion) {
|
|
1334
|
+
newPlugins.push(plugin.name);
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
const comparison = compareVersions(plugin.version, lockedVersion);
|
|
1338
|
+
if (comparison < 0) {
|
|
1339
|
+
mismatches.push({
|
|
1340
|
+
name: plugin.name,
|
|
1341
|
+
required: lockedVersion,
|
|
1342
|
+
installed: plugin.version
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
return {
|
|
1347
|
+
valid: mismatches.length === 0,
|
|
1348
|
+
mismatches,
|
|
1349
|
+
newPlugins
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
function updateVersionLock(rootDir, plugins, cliVersion) {
|
|
1353
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1354
|
+
const existingLock = readVersionLock(rootDir);
|
|
1355
|
+
const existingEntries = /* @__PURE__ */ new Map();
|
|
1356
|
+
if (existingLock) {
|
|
1357
|
+
for (const entry of existingLock.plugins) {
|
|
1358
|
+
existingEntries.set(entry.name, entry);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
const pluginEntries = [];
|
|
1362
|
+
for (const plugin of plugins) {
|
|
1363
|
+
const existing = existingEntries.get(plugin.name);
|
|
1364
|
+
if (!existing || compareVersions(plugin.version, existing.version) > 0) {
|
|
1365
|
+
pluginEntries.push({
|
|
1366
|
+
name: plugin.name,
|
|
1367
|
+
version: plugin.version,
|
|
1368
|
+
updatedAt: now
|
|
1369
|
+
});
|
|
1370
|
+
} else {
|
|
1371
|
+
pluginEntries.push(existing);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
pluginEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
1375
|
+
const lock = {
|
|
1376
|
+
version: 1,
|
|
1377
|
+
cliVersion,
|
|
1378
|
+
plugins: pluginEntries,
|
|
1379
|
+
updatedAt: now
|
|
1380
|
+
};
|
|
1381
|
+
writeVersionLock(rootDir, lock);
|
|
1382
|
+
return lock;
|
|
1383
|
+
}
|
|
1384
|
+
function getCliVersion() {
|
|
1385
|
+
try {
|
|
1386
|
+
const pkgPath = new URL("../../package.json", import.meta.url);
|
|
1387
|
+
const pkgContent = readFileSync4(pkgPath, "utf-8");
|
|
1388
|
+
const pkg = JSON.parse(pkgContent);
|
|
1389
|
+
return pkg.version;
|
|
1390
|
+
} catch {
|
|
1391
|
+
return "unknown";
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1261
1395
|
// src/commands/generate.ts
|
|
1262
1396
|
function hasPluginGenerators(plugins) {
|
|
1263
1397
|
return plugins.some((p) => p.generators && p.generators.length > 0);
|
|
1264
1398
|
}
|
|
1265
1399
|
function getExistingMigrationTables(migrationsDir) {
|
|
1266
1400
|
const existingTables = /* @__PURE__ */ new Set();
|
|
1267
|
-
if (!
|
|
1401
|
+
if (!existsSync9(migrationsDir)) {
|
|
1268
1402
|
return existingTables;
|
|
1269
1403
|
}
|
|
1270
1404
|
try {
|
|
@@ -1457,17 +1591,17 @@ function schemaChangeToVersionChange(change) {
|
|
|
1457
1591
|
function writeGeneratorOutputs(outputs, rootDir) {
|
|
1458
1592
|
const counts = { migrations: 0, types: 0, models: 0, factories: 0, other: 0 };
|
|
1459
1593
|
for (const output of outputs) {
|
|
1460
|
-
const filePath =
|
|
1594
|
+
const filePath = resolve9(rootDir, output.path);
|
|
1461
1595
|
const dir = dirname6(filePath);
|
|
1462
|
-
if (!
|
|
1596
|
+
if (!existsSync9(dir)) {
|
|
1463
1597
|
mkdirSync3(dir, { recursive: true });
|
|
1464
1598
|
logger.debug(`Created directory: ${dir}`);
|
|
1465
1599
|
}
|
|
1466
|
-
if (output.skipIfExists &&
|
|
1600
|
+
if (output.skipIfExists && existsSync9(filePath)) {
|
|
1467
1601
|
logger.debug(`Skipped (exists): ${output.path}`);
|
|
1468
1602
|
continue;
|
|
1469
1603
|
}
|
|
1470
|
-
|
|
1604
|
+
writeFileSync5(filePath, output.content);
|
|
1471
1605
|
logger.debug(`Created: ${output.path}`);
|
|
1472
1606
|
if (output.type === "migration") counts.migrations++;
|
|
1473
1607
|
else if (output.type === "type") counts.types++;
|
|
@@ -1477,7 +1611,7 @@ function writeGeneratorOutputs(outputs, rootDir) {
|
|
|
1477
1611
|
}
|
|
1478
1612
|
return counts;
|
|
1479
1613
|
}
|
|
1480
|
-
async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes) {
|
|
1614
|
+
async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes, localeConfig) {
|
|
1481
1615
|
const pluginManager = new PluginManager({
|
|
1482
1616
|
cwd: rootDir,
|
|
1483
1617
|
verbose,
|
|
@@ -1486,7 +1620,8 @@ async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes)
|
|
|
1486
1620
|
info: (msg) => logger.info(msg),
|
|
1487
1621
|
warn: (msg) => logger.warn(msg),
|
|
1488
1622
|
error: (msg) => logger.error(msg)
|
|
1489
|
-
}
|
|
1623
|
+
},
|
|
1624
|
+
localeConfig
|
|
1490
1625
|
});
|
|
1491
1626
|
for (const plugin of plugins) {
|
|
1492
1627
|
await pluginManager.register(plugin);
|
|
@@ -1523,8 +1658,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1523
1658
|
}
|
|
1524
1659
|
if (!options.typesOnly && config.output.laravel) {
|
|
1525
1660
|
logger.step("Generating Laravel migrations...");
|
|
1526
|
-
const migrationsDir =
|
|
1527
|
-
if (!
|
|
1661
|
+
const migrationsDir = resolve9(rootDir, config.output.laravel.migrationsPath);
|
|
1662
|
+
if (!existsSync9(migrationsDir)) {
|
|
1528
1663
|
mkdirSync3(migrationsDir, { recursive: true });
|
|
1529
1664
|
logger.debug(`Created directory: ${migrationsDir}`);
|
|
1530
1665
|
}
|
|
@@ -1546,8 +1681,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1546
1681
|
logger.debug(`Skipped CREATE for ${tableName} (already exists)`);
|
|
1547
1682
|
continue;
|
|
1548
1683
|
}
|
|
1549
|
-
const filePath =
|
|
1550
|
-
|
|
1684
|
+
const filePath = resolve9(migrationsDir, migration.fileName);
|
|
1685
|
+
writeFileSync5(filePath, migration.content);
|
|
1551
1686
|
logger.debug(`Created: ${migration.fileName}`);
|
|
1552
1687
|
migrationsGenerated++;
|
|
1553
1688
|
}
|
|
@@ -1555,8 +1690,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1555
1690
|
if (alterChanges.length > 0) {
|
|
1556
1691
|
const alterMigrations = generateMigrationsFromChanges(alterChanges);
|
|
1557
1692
|
for (const migration of alterMigrations) {
|
|
1558
|
-
const filePath =
|
|
1559
|
-
|
|
1693
|
+
const filePath = resolve9(migrationsDir, migration.fileName);
|
|
1694
|
+
writeFileSync5(filePath, migration.content);
|
|
1560
1695
|
logger.debug(`Created: ${migration.fileName}`);
|
|
1561
1696
|
migrationsGenerated++;
|
|
1562
1697
|
}
|
|
@@ -1567,12 +1702,12 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1567
1702
|
logger.step("Generating Laravel models...");
|
|
1568
1703
|
const modelsPath = config.output.laravel.modelsPath;
|
|
1569
1704
|
const baseModelsPath = config.output.laravel.baseModelsPath ?? `${modelsPath}/OmnifyBase`;
|
|
1570
|
-
const modelsDir =
|
|
1571
|
-
const baseModelsDir =
|
|
1572
|
-
if (!
|
|
1705
|
+
const modelsDir = resolve9(rootDir, modelsPath);
|
|
1706
|
+
const baseModelsDir = resolve9(rootDir, baseModelsPath);
|
|
1707
|
+
if (!existsSync9(modelsDir)) {
|
|
1573
1708
|
mkdirSync3(modelsDir, { recursive: true });
|
|
1574
1709
|
}
|
|
1575
|
-
if (!
|
|
1710
|
+
if (!existsSync9(baseModelsDir)) {
|
|
1576
1711
|
mkdirSync3(baseModelsDir, { recursive: true });
|
|
1577
1712
|
}
|
|
1578
1713
|
const providersPath = config.output.laravel.providersPath ?? "app/Providers";
|
|
@@ -1583,16 +1718,16 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1583
1718
|
customTypes: customTypesMap
|
|
1584
1719
|
});
|
|
1585
1720
|
for (const model of models) {
|
|
1586
|
-
const filePath =
|
|
1721
|
+
const filePath = resolve9(rootDir, getModelPath(model));
|
|
1587
1722
|
const fileDir = dirname6(filePath);
|
|
1588
|
-
if (!
|
|
1723
|
+
if (!existsSync9(fileDir)) {
|
|
1589
1724
|
mkdirSync3(fileDir, { recursive: true });
|
|
1590
1725
|
}
|
|
1591
|
-
if (!model.overwrite &&
|
|
1726
|
+
if (!model.overwrite && existsSync9(filePath)) {
|
|
1592
1727
|
logger.debug(`Skipped (exists): ${getModelPath(model)}`);
|
|
1593
1728
|
continue;
|
|
1594
1729
|
}
|
|
1595
|
-
|
|
1730
|
+
writeFileSync5(filePath, model.content);
|
|
1596
1731
|
logger.debug(`Created: ${getModelPath(model)}`);
|
|
1597
1732
|
modelsGenerated++;
|
|
1598
1733
|
}
|
|
@@ -1601,24 +1736,24 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1601
1736
|
if (!options.typesOnly && config.output.laravel?.factoriesPath) {
|
|
1602
1737
|
logger.step("Generating Laravel factories...");
|
|
1603
1738
|
const factoriesPath = config.output.laravel.factoriesPath;
|
|
1604
|
-
const factoriesDir =
|
|
1605
|
-
if (!
|
|
1739
|
+
const factoriesDir = resolve9(rootDir, factoriesPath);
|
|
1740
|
+
if (!existsSync9(factoriesDir)) {
|
|
1606
1741
|
mkdirSync3(factoriesDir, { recursive: true });
|
|
1607
1742
|
}
|
|
1608
1743
|
const factories = generateFactories(schemas, {
|
|
1609
1744
|
factoryPath: factoriesPath
|
|
1610
1745
|
});
|
|
1611
1746
|
for (const factory of factories) {
|
|
1612
|
-
const filePath =
|
|
1747
|
+
const filePath = resolve9(rootDir, getFactoryPath(factory));
|
|
1613
1748
|
const fileDir = dirname6(filePath);
|
|
1614
|
-
if (!
|
|
1749
|
+
if (!existsSync9(fileDir)) {
|
|
1615
1750
|
mkdirSync3(fileDir, { recursive: true });
|
|
1616
1751
|
}
|
|
1617
|
-
if (!factory.overwrite &&
|
|
1752
|
+
if (!factory.overwrite && existsSync9(filePath)) {
|
|
1618
1753
|
logger.debug(`Skipped (exists): ${getFactoryPath(factory)}`);
|
|
1619
1754
|
continue;
|
|
1620
1755
|
}
|
|
1621
|
-
|
|
1756
|
+
writeFileSync5(filePath, factory.content);
|
|
1622
1757
|
logger.debug(`Created: ${getFactoryPath(factory)}`);
|
|
1623
1758
|
factoriesGenerated++;
|
|
1624
1759
|
}
|
|
@@ -1627,32 +1762,32 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1627
1762
|
if (!options.migrationsOnly && config.output.typescript) {
|
|
1628
1763
|
logger.step("Generating TypeScript types...");
|
|
1629
1764
|
const tsConfig = config.output.typescript;
|
|
1630
|
-
const basePath =
|
|
1631
|
-
const schemasDir =
|
|
1632
|
-
const enumDir =
|
|
1633
|
-
const omnifyBaseDir =
|
|
1634
|
-
const pluginEnumDir =
|
|
1635
|
-
const baseSchemasDir =
|
|
1765
|
+
const basePath = resolve9(rootDir, tsConfig.path);
|
|
1766
|
+
const schemasDir = resolve9(basePath, tsConfig.schemasDir ?? "schemas");
|
|
1767
|
+
const enumDir = resolve9(basePath, tsConfig.enumDir ?? "enum");
|
|
1768
|
+
const omnifyBaseDir = resolve9(rootDir, "node_modules/@omnify-base");
|
|
1769
|
+
const pluginEnumDir = resolve9(omnifyBaseDir, "enum");
|
|
1770
|
+
const baseSchemasDir = resolve9(omnifyBaseDir, "schemas");
|
|
1636
1771
|
const enumImportPrefix = relative(schemasDir, enumDir).replace(/\\/g, "/");
|
|
1637
|
-
if (!
|
|
1772
|
+
if (!existsSync9(schemasDir)) {
|
|
1638
1773
|
mkdirSync3(schemasDir, { recursive: true });
|
|
1639
1774
|
logger.debug(`Created directory: ${schemasDir}`);
|
|
1640
1775
|
}
|
|
1641
|
-
if (!
|
|
1776
|
+
if (!existsSync9(enumDir)) {
|
|
1642
1777
|
mkdirSync3(enumDir, { recursive: true });
|
|
1643
1778
|
logger.debug(`Created directory: ${enumDir}`);
|
|
1644
1779
|
}
|
|
1645
|
-
if (!
|
|
1780
|
+
if (!existsSync9(pluginEnumDir)) {
|
|
1646
1781
|
mkdirSync3(pluginEnumDir, { recursive: true });
|
|
1647
1782
|
logger.debug(`Created directory: ${pluginEnumDir}`);
|
|
1648
1783
|
}
|
|
1649
|
-
if (!
|
|
1784
|
+
if (!existsSync9(baseSchemasDir)) {
|
|
1650
1785
|
mkdirSync3(baseSchemasDir, { recursive: true });
|
|
1651
1786
|
logger.debug(`Created directory: ${baseSchemasDir}`);
|
|
1652
1787
|
}
|
|
1653
|
-
const omnifyPkgJson =
|
|
1654
|
-
if (!
|
|
1655
|
-
|
|
1788
|
+
const omnifyPkgJson = resolve9(omnifyBaseDir, "package.json");
|
|
1789
|
+
if (!existsSync9(omnifyPkgJson)) {
|
|
1790
|
+
writeFileSync5(omnifyPkgJson, JSON.stringify({
|
|
1656
1791
|
name: "@omnify-base",
|
|
1657
1792
|
version: "0.0.0",
|
|
1658
1793
|
private: true,
|
|
@@ -1689,16 +1824,16 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1689
1824
|
} else {
|
|
1690
1825
|
outputDir = schemasDir;
|
|
1691
1826
|
}
|
|
1692
|
-
const filePath =
|
|
1827
|
+
const filePath = resolve9(outputDir, outputFilePath);
|
|
1693
1828
|
const fileDir = dirname6(filePath);
|
|
1694
|
-
if (!
|
|
1829
|
+
if (!existsSync9(fileDir)) {
|
|
1695
1830
|
mkdirSync3(fileDir, { recursive: true });
|
|
1696
1831
|
}
|
|
1697
|
-
if (!file.overwrite &&
|
|
1832
|
+
if (!file.overwrite && existsSync9(filePath)) {
|
|
1698
1833
|
logger.debug(`Skipped (exists): ${file.filePath}`);
|
|
1699
1834
|
continue;
|
|
1700
1835
|
}
|
|
1701
|
-
|
|
1836
|
+
writeFileSync5(filePath, file.content);
|
|
1702
1837
|
logger.debug(`Created: ${file.filePath}`);
|
|
1703
1838
|
typesGenerated++;
|
|
1704
1839
|
}
|
|
@@ -1728,7 +1863,49 @@ async function runGenerate(options) {
|
|
|
1728
1863
|
const { config, configPath: configPath2 } = await loadConfig();
|
|
1729
1864
|
const rootDir = configPath2 ? dirname6(configPath2) : process.cwd();
|
|
1730
1865
|
validateConfig(config, rootDir);
|
|
1731
|
-
|
|
1866
|
+
if (config.plugins.length > 0) {
|
|
1867
|
+
const versionLock = readVersionLock(rootDir);
|
|
1868
|
+
if (versionLock) {
|
|
1869
|
+
logger.debug("Checking plugin versions against lock file...");
|
|
1870
|
+
const versionCheck = checkPluginVersions(config.plugins, versionLock);
|
|
1871
|
+
if (!versionCheck.valid) {
|
|
1872
|
+
logger.newline();
|
|
1873
|
+
logger.error("\u{1F512} PLUGIN VERSION MISMATCH");
|
|
1874
|
+
logger.error("");
|
|
1875
|
+
logger.error("The following plugins are older than required by the version lock:");
|
|
1876
|
+
logger.newline();
|
|
1877
|
+
for (const mismatch of versionCheck.mismatches) {
|
|
1878
|
+
logger.error(` \u2022 ${mismatch.name}`);
|
|
1879
|
+
logger.error(` Required: ${mismatch.required}`);
|
|
1880
|
+
logger.error(` Installed: ${mismatch.installed}`);
|
|
1881
|
+
}
|
|
1882
|
+
logger.newline();
|
|
1883
|
+
logger.error(`Version lock file: ${VERSION_LOCK_FILE}`);
|
|
1884
|
+
logger.newline();
|
|
1885
|
+
logger.info("To fix this, upgrade the outdated plugins:");
|
|
1886
|
+
logger.info("");
|
|
1887
|
+
for (const mismatch of versionCheck.mismatches) {
|
|
1888
|
+
logger.info(` npm install ${mismatch.name}@latest`);
|
|
1889
|
+
}
|
|
1890
|
+
logger.newline();
|
|
1891
|
+
logger.info("Or if you intentionally want to use older versions, delete the lock file:");
|
|
1892
|
+
logger.info(` rm ${VERSION_LOCK_FILE}`);
|
|
1893
|
+
logger.newline();
|
|
1894
|
+
throw new OmnifyError4(
|
|
1895
|
+
"Plugin version mismatch: installed versions are older than lock file requirements",
|
|
1896
|
+
"E501",
|
|
1897
|
+
void 0,
|
|
1898
|
+
"Upgrade plugins or delete the version lock file to regenerate it."
|
|
1899
|
+
);
|
|
1900
|
+
}
|
|
1901
|
+
if (versionCheck.newPlugins.length > 0) {
|
|
1902
|
+
logger.debug(`New plugins detected: ${versionCheck.newPlugins.join(", ")}`);
|
|
1903
|
+
}
|
|
1904
|
+
} else {
|
|
1905
|
+
logger.debug(`No version lock file found (${VERSION_LOCK_FILE})`);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
const schemaPath = resolve9(rootDir, config.schemasDir);
|
|
1732
1909
|
logger.step(`Loading schemas from ${schemaPath}`);
|
|
1733
1910
|
let schemas = await loadSchemas3(schemaPath);
|
|
1734
1911
|
logger.debug(`Found ${Object.keys(schemas).length} schema(s) in main directory`);
|
|
@@ -1737,9 +1914,9 @@ async function runGenerate(options) {
|
|
|
1737
1914
|
if (additionalPaths.length > 0) {
|
|
1738
1915
|
logger.step(`Loading schemas from ${additionalPaths.length} additional path(s)`);
|
|
1739
1916
|
for (const entry of additionalPaths) {
|
|
1740
|
-
const absolutePath =
|
|
1917
|
+
const absolutePath = resolve9(rootDir, entry.path);
|
|
1741
1918
|
logger.debug(` Checking: ${entry.path} \u2192 ${absolutePath}`);
|
|
1742
|
-
if (
|
|
1919
|
+
if (existsSync9(absolutePath)) {
|
|
1743
1920
|
let packageSchemas = await loadSchemas3(absolutePath, { skipPartialResolution: true });
|
|
1744
1921
|
if (entry.output) {
|
|
1745
1922
|
const schemasWithOutput = {};
|
|
@@ -1794,12 +1971,12 @@ async function runGenerate(options) {
|
|
|
1794
1971
|
process.exit(2);
|
|
1795
1972
|
}
|
|
1796
1973
|
logger.step("Checking for changes...");
|
|
1797
|
-
const lockPath =
|
|
1974
|
+
const lockPath = resolve9(rootDir, config.lockFilePath);
|
|
1798
1975
|
const existingLock = await readLockFile(lockPath);
|
|
1799
1976
|
const currentSnapshots = await buildSchemaSnapshots(schemas);
|
|
1800
1977
|
const v2Lock = existingLock && isLockFileV2(existingLock) ? existingLock : null;
|
|
1801
1978
|
const comparison = compareSchemasDeep(currentSnapshots, v2Lock);
|
|
1802
|
-
const chainFilePath =
|
|
1979
|
+
const chainFilePath = resolve9(rootDir, VERSION_CHAIN_FILE);
|
|
1803
1980
|
const versionChain = await readVersionChain(chainFilePath);
|
|
1804
1981
|
if (versionChain && comparison.hasChanges) {
|
|
1805
1982
|
const schemaActions = [];
|
|
@@ -1836,7 +2013,7 @@ async function runGenerate(options) {
|
|
|
1836
2013
|
}
|
|
1837
2014
|
}
|
|
1838
2015
|
if (existingLock && config.output.laravel?.migrationsPath) {
|
|
1839
|
-
const migrationsDir =
|
|
2016
|
+
const migrationsDir = resolve9(rootDir, config.output.laravel.migrationsPath);
|
|
1840
2017
|
const migrationValidation = await validateMigrations(existingLock, migrationsDir);
|
|
1841
2018
|
if (!migrationValidation.valid) {
|
|
1842
2019
|
logger.newline();
|
|
@@ -1896,7 +2073,7 @@ async function runGenerate(options) {
|
|
|
1896
2073
|
const alterMigrations = toRegenerate.filter((m) => m.type === "alter" || m.type === "drop");
|
|
1897
2074
|
if (createMigrations.length > 0) {
|
|
1898
2075
|
logger.info(`Regenerating ${createMigrations.length} missing CREATE migration(s) with original timestamps...`);
|
|
1899
|
-
const migrationsDir2 =
|
|
2076
|
+
const migrationsDir2 = resolve9(rootDir, config.output.laravel.migrationsPath);
|
|
1900
2077
|
const customTypesMap2 = /* @__PURE__ */ new Map();
|
|
1901
2078
|
for (const plugin of config.plugins) {
|
|
1902
2079
|
if (plugin.types) {
|
|
@@ -1918,8 +2095,8 @@ async function runGenerate(options) {
|
|
|
1918
2095
|
customTypes: customTypesMap2
|
|
1919
2096
|
});
|
|
1920
2097
|
for (const mig of regenerated) {
|
|
1921
|
-
const filePath =
|
|
1922
|
-
|
|
2098
|
+
const filePath = resolve9(migrationsDir2, migData.fileName);
|
|
2099
|
+
writeFileSync5(filePath, mig.content);
|
|
1923
2100
|
logger.success(` Regenerated: ${migData.fileName}`);
|
|
1924
2101
|
}
|
|
1925
2102
|
}
|
|
@@ -1975,7 +2152,8 @@ async function runGenerate(options) {
|
|
|
1975
2152
|
schemas,
|
|
1976
2153
|
rootDir,
|
|
1977
2154
|
options.verbose ?? false,
|
|
1978
|
-
comparison.changes
|
|
2155
|
+
comparison.changes,
|
|
2156
|
+
config.locale
|
|
1979
2157
|
);
|
|
1980
2158
|
migrationsGenerated = counts.migrations;
|
|
1981
2159
|
typesGenerated = counts.types;
|
|
@@ -1997,32 +2175,32 @@ async function runGenerate(options) {
|
|
|
1997
2175
|
if (!options.migrationsOnly && config.output.typescript && typesGenerated === 0) {
|
|
1998
2176
|
logger.step("Generating TypeScript types...");
|
|
1999
2177
|
const tsConfig2 = config.output.typescript;
|
|
2000
|
-
const basePath2 =
|
|
2001
|
-
const schemasDir2 =
|
|
2002
|
-
const enumDir2 =
|
|
2003
|
-
const omnifyBaseDir2 =
|
|
2004
|
-
const pluginEnumDir2 =
|
|
2005
|
-
const baseSchemasDir2 =
|
|
2178
|
+
const basePath2 = resolve9(rootDir, tsConfig2.path);
|
|
2179
|
+
const schemasDir2 = resolve9(basePath2, tsConfig2.schemasDir ?? "schemas");
|
|
2180
|
+
const enumDir2 = resolve9(basePath2, tsConfig2.enumDir ?? "enum");
|
|
2181
|
+
const omnifyBaseDir2 = resolve9(rootDir, "node_modules/@omnify-base");
|
|
2182
|
+
const pluginEnumDir2 = resolve9(omnifyBaseDir2, "enum");
|
|
2183
|
+
const baseSchemasDir2 = resolve9(omnifyBaseDir2, "schemas");
|
|
2006
2184
|
const enumImportPrefix2 = relative(schemasDir2, enumDir2).replace(/\\/g, "/");
|
|
2007
|
-
if (!
|
|
2185
|
+
if (!existsSync9(schemasDir2)) {
|
|
2008
2186
|
mkdirSync3(schemasDir2, { recursive: true });
|
|
2009
2187
|
logger.debug(`Created directory: ${schemasDir2}`);
|
|
2010
2188
|
}
|
|
2011
|
-
if (!
|
|
2189
|
+
if (!existsSync9(enumDir2)) {
|
|
2012
2190
|
mkdirSync3(enumDir2, { recursive: true });
|
|
2013
2191
|
logger.debug(`Created directory: ${enumDir2}`);
|
|
2014
2192
|
}
|
|
2015
|
-
if (!
|
|
2193
|
+
if (!existsSync9(pluginEnumDir2)) {
|
|
2016
2194
|
mkdirSync3(pluginEnumDir2, { recursive: true });
|
|
2017
2195
|
logger.debug(`Created directory: ${pluginEnumDir2}`);
|
|
2018
2196
|
}
|
|
2019
|
-
if (!
|
|
2197
|
+
if (!existsSync9(baseSchemasDir2)) {
|
|
2020
2198
|
mkdirSync3(baseSchemasDir2, { recursive: true });
|
|
2021
2199
|
logger.debug(`Created directory: ${baseSchemasDir2}`);
|
|
2022
2200
|
}
|
|
2023
|
-
const omnifyPkgJson2 =
|
|
2024
|
-
if (!
|
|
2025
|
-
|
|
2201
|
+
const omnifyPkgJson2 = resolve9(omnifyBaseDir2, "package.json");
|
|
2202
|
+
if (!existsSync9(omnifyPkgJson2)) {
|
|
2203
|
+
writeFileSync5(omnifyPkgJson2, JSON.stringify({
|
|
2026
2204
|
name: "@omnify-base",
|
|
2027
2205
|
version: "0.0.0",
|
|
2028
2206
|
private: true,
|
|
@@ -2059,16 +2237,16 @@ async function runGenerate(options) {
|
|
|
2059
2237
|
} else {
|
|
2060
2238
|
outputDir2 = schemasDir2;
|
|
2061
2239
|
}
|
|
2062
|
-
const filePath =
|
|
2240
|
+
const filePath = resolve9(outputDir2, outputFilePath2);
|
|
2063
2241
|
const fileDir = dirname6(filePath);
|
|
2064
|
-
if (!
|
|
2242
|
+
if (!existsSync9(fileDir)) {
|
|
2065
2243
|
mkdirSync3(fileDir, { recursive: true });
|
|
2066
2244
|
}
|
|
2067
|
-
if (!file.overwrite &&
|
|
2245
|
+
if (!file.overwrite && existsSync9(filePath)) {
|
|
2068
2246
|
logger.debug(`Skipped (exists): ${file.filePath}`);
|
|
2069
2247
|
continue;
|
|
2070
2248
|
}
|
|
2071
|
-
|
|
2249
|
+
writeFileSync5(filePath, file.content);
|
|
2072
2250
|
logger.debug(`Created: ${file.filePath}`);
|
|
2073
2251
|
typesGenerated++;
|
|
2074
2252
|
}
|
|
@@ -2138,6 +2316,15 @@ async function runGenerate(options) {
|
|
|
2138
2316
|
} catch (guideError) {
|
|
2139
2317
|
logger.debug(`Could not generate AI guides: ${guideError.message}`);
|
|
2140
2318
|
}
|
|
2319
|
+
if (config.plugins.length > 0) {
|
|
2320
|
+
try {
|
|
2321
|
+
const cliVersion = getCliVersion();
|
|
2322
|
+
const updatedLock = updateVersionLock(rootDir, config.plugins, cliVersion);
|
|
2323
|
+
logger.debug(`Updated version lock: ${updatedLock.plugins.length} plugin(s)`);
|
|
2324
|
+
} catch (lockError) {
|
|
2325
|
+
logger.debug(`Could not update version lock: ${lockError.message}`);
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2141
2328
|
logger.newline();
|
|
2142
2329
|
logger.success("Generation complete!");
|
|
2143
2330
|
if (migrationsGenerated > 0 && config.output.laravel) {
|
|
@@ -2168,23 +2355,23 @@ function registerGenerateCommand(program2) {
|
|
|
2168
2355
|
}
|
|
2169
2356
|
|
|
2170
2357
|
// src/commands/reset.ts
|
|
2171
|
-
import { existsSync as
|
|
2172
|
-
import { resolve as
|
|
2358
|
+
import { existsSync as existsSync10, readdirSync as readdirSync3, rmSync, statSync } from "fs";
|
|
2359
|
+
import { resolve as resolve10, dirname as dirname7, join as join2 } from "path";
|
|
2173
2360
|
import { createInterface } from "readline";
|
|
2174
2361
|
async function confirm2(message) {
|
|
2175
2362
|
const rl = createInterface({
|
|
2176
2363
|
input: process.stdin,
|
|
2177
2364
|
output: process.stdout
|
|
2178
2365
|
});
|
|
2179
|
-
return new Promise((
|
|
2366
|
+
return new Promise((resolve15) => {
|
|
2180
2367
|
rl.question(`${message} (y/N) `, (answer) => {
|
|
2181
2368
|
rl.close();
|
|
2182
|
-
|
|
2369
|
+
resolve15(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
2183
2370
|
});
|
|
2184
2371
|
});
|
|
2185
2372
|
}
|
|
2186
2373
|
function countFiles(dir) {
|
|
2187
|
-
if (!
|
|
2374
|
+
if (!existsSync10(dir)) return 0;
|
|
2188
2375
|
let count = 0;
|
|
2189
2376
|
const entries = readdirSync3(dir);
|
|
2190
2377
|
for (const entry of entries) {
|
|
@@ -2199,7 +2386,7 @@ function countFiles(dir) {
|
|
|
2199
2386
|
return count;
|
|
2200
2387
|
}
|
|
2201
2388
|
function deleteDir(dir, verbose) {
|
|
2202
|
-
if (!
|
|
2389
|
+
if (!existsSync10(dir)) return 0;
|
|
2203
2390
|
const count = countFiles(dir);
|
|
2204
2391
|
rmSync(dir, { recursive: true, force: true });
|
|
2205
2392
|
if (verbose) {
|
|
@@ -2208,7 +2395,7 @@ function deleteDir(dir, verbose) {
|
|
|
2208
2395
|
return count;
|
|
2209
2396
|
}
|
|
2210
2397
|
function deleteFilesInDir(dir, pattern, verbose) {
|
|
2211
|
-
if (!
|
|
2398
|
+
if (!existsSync10(dir)) return 0;
|
|
2212
2399
|
let count = 0;
|
|
2213
2400
|
const entries = readdirSync3(dir);
|
|
2214
2401
|
for (const entry of entries) {
|
|
@@ -2243,8 +2430,8 @@ async function runReset(options) {
|
|
|
2243
2430
|
];
|
|
2244
2431
|
for (const { name, paths: relPaths } of omnifyBasePaths) {
|
|
2245
2432
|
for (const relPath of relPaths) {
|
|
2246
|
-
const omnifyBasePath =
|
|
2247
|
-
if (
|
|
2433
|
+
const omnifyBasePath = resolve10(rootDir, relPath);
|
|
2434
|
+
if (existsSync10(omnifyBasePath)) {
|
|
2248
2435
|
paths.push({ name, path: omnifyBasePath, type: "dir" });
|
|
2249
2436
|
break;
|
|
2250
2437
|
}
|
|
@@ -2252,8 +2439,8 @@ async function runReset(options) {
|
|
|
2252
2439
|
}
|
|
2253
2440
|
for (const { name, paths: relPaths } of legacyGeneratedPaths) {
|
|
2254
2441
|
for (const relPath of relPaths) {
|
|
2255
|
-
const legacyPath =
|
|
2256
|
-
if (
|
|
2442
|
+
const legacyPath = resolve10(rootDir, relPath);
|
|
2443
|
+
if (existsSync10(legacyPath)) {
|
|
2257
2444
|
paths.push({ name, path: legacyPath, type: "dir" });
|
|
2258
2445
|
break;
|
|
2259
2446
|
}
|
|
@@ -2264,8 +2451,8 @@ async function runReset(options) {
|
|
|
2264
2451
|
"backend/database/migrations/omnify"
|
|
2265
2452
|
];
|
|
2266
2453
|
for (const relPath of migrationPaths) {
|
|
2267
|
-
const migrationsPath =
|
|
2268
|
-
if (
|
|
2454
|
+
const migrationsPath = resolve10(rootDir, relPath);
|
|
2455
|
+
if (existsSync10(migrationsPath)) {
|
|
2269
2456
|
paths.push({
|
|
2270
2457
|
name: "Omnify migrations",
|
|
2271
2458
|
path: migrationsPath,
|
|
@@ -2277,15 +2464,15 @@ async function runReset(options) {
|
|
|
2277
2464
|
}
|
|
2278
2465
|
const laravelConfig = config.output.laravel;
|
|
2279
2466
|
if (laravelConfig?.modelsPath) {
|
|
2280
|
-
const modelsPath =
|
|
2467
|
+
const modelsPath = resolve10(rootDir, laravelConfig.modelsPath);
|
|
2281
2468
|
const omnifyBasePath = join2(modelsPath, "OmnifyBase");
|
|
2282
|
-
if (
|
|
2469
|
+
if (existsSync10(omnifyBasePath) && !paths.some((p) => p.path === omnifyBasePath)) {
|
|
2283
2470
|
paths.push({ name: "OmnifyBase models", path: omnifyBasePath, type: "dir" });
|
|
2284
2471
|
}
|
|
2285
2472
|
}
|
|
2286
2473
|
if (laravelConfig?.migrationsPath) {
|
|
2287
|
-
const migrationsPath =
|
|
2288
|
-
if (
|
|
2474
|
+
const migrationsPath = resolve10(rootDir, laravelConfig.migrationsPath);
|
|
2475
|
+
if (existsSync10(migrationsPath) && !paths.some((p) => p.path === migrationsPath)) {
|
|
2289
2476
|
paths.push({
|
|
2290
2477
|
name: "Omnify migrations",
|
|
2291
2478
|
path: migrationsPath,
|
|
@@ -2298,18 +2485,18 @@ async function runReset(options) {
|
|
|
2298
2485
|
for (const additionalPath of config.additionalSchemaPaths) {
|
|
2299
2486
|
const pkgOutput = additionalPath.output?.laravel;
|
|
2300
2487
|
if (pkgOutput?.base) {
|
|
2301
|
-
const pkgBase =
|
|
2488
|
+
const pkgBase = resolve10(rootDir, pkgOutput.base);
|
|
2302
2489
|
const pkgName = additionalPath.namespace ?? "Package";
|
|
2303
2490
|
const pkgOmnifyBase = join2(pkgBase, pkgOutput.baseModelsPath ?? "src/Models/OmnifyBase");
|
|
2304
|
-
if (
|
|
2491
|
+
if (existsSync10(pkgOmnifyBase) && !paths.some((p) => p.path === pkgOmnifyBase)) {
|
|
2305
2492
|
paths.push({ name: `${pkgName} OmnifyBase`, path: pkgOmnifyBase, type: "dir" });
|
|
2306
2493
|
}
|
|
2307
2494
|
const pkgGenerated = join2(pkgBase, "src/Models/Generated");
|
|
2308
|
-
if (
|
|
2495
|
+
if (existsSync10(pkgGenerated) && !paths.some((p) => p.path === pkgGenerated)) {
|
|
2309
2496
|
paths.push({ name: `${pkgName} Legacy Generated`, path: pkgGenerated, type: "dir" });
|
|
2310
2497
|
}
|
|
2311
2498
|
const pkgMigrations = join2(pkgBase, pkgOutput.migrationsPath ?? "database/migrations/omnify");
|
|
2312
|
-
if (
|
|
2499
|
+
if (existsSync10(pkgMigrations) && !paths.some((p) => p.path === pkgMigrations)) {
|
|
2313
2500
|
paths.push({
|
|
2314
2501
|
name: `${pkgName} migrations`,
|
|
2315
2502
|
path: pkgMigrations,
|
|
@@ -2317,18 +2504,18 @@ async function runReset(options) {
|
|
|
2317
2504
|
});
|
|
2318
2505
|
}
|
|
2319
2506
|
const pkgProviders = join2(pkgBase, pkgOutput.providersPath ?? "src/Providers");
|
|
2320
|
-
if (
|
|
2507
|
+
if (existsSync10(pkgProviders) && !paths.some((p) => p.path === pkgProviders)) {
|
|
2321
2508
|
paths.push({ name: `${pkgName} Providers`, path: pkgProviders, type: "dir" });
|
|
2322
2509
|
}
|
|
2323
2510
|
const pkgFactories = join2(pkgBase, pkgOutput.factoriesPath ?? "database/factories");
|
|
2324
|
-
if (
|
|
2511
|
+
if (existsSync10(pkgFactories) && !paths.some((p) => p.path === pkgFactories)) {
|
|
2325
2512
|
paths.push({ name: `${pkgName} Factories`, path: pkgFactories, type: "dir" });
|
|
2326
2513
|
}
|
|
2327
2514
|
}
|
|
2328
2515
|
}
|
|
2329
2516
|
}
|
|
2330
2517
|
const typescriptPath = config.output.typescript?.path;
|
|
2331
|
-
const tsBasePath = typescriptPath ?
|
|
2518
|
+
const tsBasePath = typescriptPath ? resolve10(rootDir, typescriptPath) : null;
|
|
2332
2519
|
const commonTsPaths = [
|
|
2333
2520
|
"resources/ts/omnify",
|
|
2334
2521
|
"resources/ts/omnify/schemas",
|
|
@@ -2338,45 +2525,45 @@ async function runReset(options) {
|
|
|
2338
2525
|
"src/types/models"
|
|
2339
2526
|
];
|
|
2340
2527
|
let foundTsPath = tsBasePath;
|
|
2341
|
-
if (!foundTsPath || !
|
|
2528
|
+
if (!foundTsPath || !existsSync10(foundTsPath)) {
|
|
2342
2529
|
for (const relPath of commonTsPaths) {
|
|
2343
|
-
const tsPath =
|
|
2344
|
-
if (
|
|
2530
|
+
const tsPath = resolve10(rootDir, relPath);
|
|
2531
|
+
if (existsSync10(tsPath)) {
|
|
2345
2532
|
foundTsPath = tsPath;
|
|
2346
2533
|
break;
|
|
2347
2534
|
}
|
|
2348
2535
|
}
|
|
2349
2536
|
}
|
|
2350
|
-
if (foundTsPath &&
|
|
2537
|
+
if (foundTsPath && existsSync10(foundTsPath)) {
|
|
2351
2538
|
const autoGeneratedDirs = ["base", "enum", "rules", "hooks", "lib"];
|
|
2352
2539
|
for (const subDir of autoGeneratedDirs) {
|
|
2353
2540
|
const subPath = join2(foundTsPath, subDir);
|
|
2354
|
-
if (
|
|
2541
|
+
if (existsSync10(subPath)) {
|
|
2355
2542
|
paths.push({ name: `TypeScript ${subDir}`, path: subPath, type: "dir" });
|
|
2356
2543
|
}
|
|
2357
2544
|
}
|
|
2358
2545
|
const autoGeneratedFiles = ["common.ts", "index.ts", "i18n.ts"];
|
|
2359
2546
|
for (const fileName of autoGeneratedFiles) {
|
|
2360
2547
|
const filePath = join2(foundTsPath, fileName);
|
|
2361
|
-
if (
|
|
2548
|
+
if (existsSync10(filePath)) {
|
|
2362
2549
|
paths.push({ name: `TypeScript ${fileName}`, path: filePath, type: "file" });
|
|
2363
2550
|
}
|
|
2364
2551
|
}
|
|
2365
2552
|
}
|
|
2366
|
-
const lockFilePath =
|
|
2367
|
-
if (
|
|
2553
|
+
const lockFilePath = resolve10(rootDir, config.lockFilePath);
|
|
2554
|
+
if (existsSync10(lockFilePath)) {
|
|
2368
2555
|
paths.push({ name: "Lock file", path: lockFilePath, type: "file" });
|
|
2369
2556
|
}
|
|
2370
|
-
const versionsDir =
|
|
2371
|
-
if (
|
|
2557
|
+
const versionsDir = resolve10(rootDir, ".omnify-versions");
|
|
2558
|
+
if (existsSync10(versionsDir)) {
|
|
2372
2559
|
paths.push({ name: "Version history", path: versionsDir, type: "dir" });
|
|
2373
2560
|
}
|
|
2374
|
-
const omnifyVersionsDir =
|
|
2375
|
-
if (
|
|
2561
|
+
const omnifyVersionsDir = resolve10(rootDir, ".omnify/versions");
|
|
2562
|
+
if (existsSync10(omnifyVersionsDir)) {
|
|
2376
2563
|
paths.push({ name: "Version history (.omnify/versions)", path: omnifyVersionsDir, type: "dir" });
|
|
2377
2564
|
}
|
|
2378
|
-
const logsDir =
|
|
2379
|
-
if (
|
|
2565
|
+
const logsDir = resolve10(rootDir, ".omnify/logs");
|
|
2566
|
+
if (existsSync10(logsDir)) {
|
|
2380
2567
|
paths.push({ name: "Logs", path: logsDir, type: "dir" });
|
|
2381
2568
|
}
|
|
2382
2569
|
if (paths.length === 0) {
|
|
@@ -2447,8 +2634,8 @@ function registerResetCommand(program2) {
|
|
|
2447
2634
|
|
|
2448
2635
|
// src/commands/create-project.ts
|
|
2449
2636
|
import { execSync, spawn } from "child_process";
|
|
2450
|
-
import { existsSync as
|
|
2451
|
-
import { resolve as
|
|
2637
|
+
import { existsSync as existsSync11, rmSync as rmSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
2638
|
+
import { resolve as resolve11 } from "path";
|
|
2452
2639
|
var BOILERPLATE_REPO = "https://github.com/omnifyjp/omnify-laravel-boilerplate.git";
|
|
2453
2640
|
var IS_WINDOWS = process.platform === "win32";
|
|
2454
2641
|
function checkGit() {
|
|
@@ -2549,9 +2736,9 @@ var GITIGNORE_ENTRIES_TO_REMOVE = [
|
|
|
2549
2736
|
".claude/omnify/"
|
|
2550
2737
|
];
|
|
2551
2738
|
function cleanupGitignore(targetDir) {
|
|
2552
|
-
const gitignorePath =
|
|
2553
|
-
if (!
|
|
2554
|
-
const content =
|
|
2739
|
+
const gitignorePath = resolve11(targetDir, ".gitignore");
|
|
2740
|
+
if (!existsSync11(gitignorePath)) return;
|
|
2741
|
+
const content = readFileSync5(gitignorePath, "utf-8");
|
|
2555
2742
|
const lines = content.split("\n");
|
|
2556
2743
|
const cleanedLines = lines.filter((line) => {
|
|
2557
2744
|
const trimmed = line.trim();
|
|
@@ -2560,13 +2747,13 @@ function cleanupGitignore(targetDir) {
|
|
|
2560
2747
|
while (cleanedLines.length > 0 && cleanedLines[0].trim() === "") {
|
|
2561
2748
|
cleanedLines.shift();
|
|
2562
2749
|
}
|
|
2563
|
-
|
|
2750
|
+
writeFileSync6(gitignorePath, cleanedLines.join("\n"));
|
|
2564
2751
|
}
|
|
2565
2752
|
function cloneRepo(repo, targetDir) {
|
|
2566
2753
|
logger.step(`Cloning boilerplate from ${repo}...`);
|
|
2567
2754
|
execSync(`git clone --depth 1 ${repo} "${targetDir}"`, { stdio: "inherit" });
|
|
2568
|
-
const gitDir =
|
|
2569
|
-
if (
|
|
2755
|
+
const gitDir = resolve11(targetDir, ".git");
|
|
2756
|
+
if (existsSync11(gitDir)) {
|
|
2570
2757
|
rmSync2(gitDir, { recursive: true, force: true });
|
|
2571
2758
|
}
|
|
2572
2759
|
cleanupGitignore(targetDir);
|
|
@@ -2574,7 +2761,7 @@ function cloneRepo(repo, targetDir) {
|
|
|
2574
2761
|
logger.success("Repository cloned successfully");
|
|
2575
2762
|
}
|
|
2576
2763
|
function runCommand(command, targetDir) {
|
|
2577
|
-
return new Promise((
|
|
2764
|
+
return new Promise((resolve15, reject) => {
|
|
2578
2765
|
const child = spawn(command, [], {
|
|
2579
2766
|
cwd: targetDir,
|
|
2580
2767
|
shell: true,
|
|
@@ -2582,7 +2769,7 @@ function runCommand(command, targetDir) {
|
|
|
2582
2769
|
});
|
|
2583
2770
|
child.on("close", (code) => {
|
|
2584
2771
|
if (code === 0) {
|
|
2585
|
-
|
|
2772
|
+
resolve15();
|
|
2586
2773
|
} else {
|
|
2587
2774
|
reject(new Error(`Command failed with exit code ${code}`));
|
|
2588
2775
|
}
|
|
@@ -2630,13 +2817,13 @@ async function runSetup(targetDir) {
|
|
|
2630
2817
|
}
|
|
2631
2818
|
}
|
|
2632
2819
|
async function runCreateProject(projectName, options) {
|
|
2633
|
-
const targetDir =
|
|
2820
|
+
const targetDir = resolve11(process.cwd(), projectName);
|
|
2634
2821
|
const repo = options.repo ?? BOILERPLATE_REPO;
|
|
2635
2822
|
if (!checkGit()) {
|
|
2636
2823
|
logger.error("Git is not installed. Please install git first.");
|
|
2637
2824
|
process.exit(1);
|
|
2638
2825
|
}
|
|
2639
|
-
if (
|
|
2826
|
+
if (existsSync11(targetDir)) {
|
|
2640
2827
|
logger.error(`Directory "${projectName}" already exists.`);
|
|
2641
2828
|
process.exit(1);
|
|
2642
2829
|
}
|
|
@@ -2662,7 +2849,7 @@ async function runCreateProject(projectName, options) {
|
|
|
2662
2849
|
logger.info(" pnpm run dev");
|
|
2663
2850
|
logger.newline();
|
|
2664
2851
|
} catch (error) {
|
|
2665
|
-
if (!cloneSucceeded &&
|
|
2852
|
+
if (!cloneSucceeded && existsSync11(targetDir)) {
|
|
2666
2853
|
rmSync2(targetDir, { recursive: true, force: true });
|
|
2667
2854
|
} else if (cloneSucceeded) {
|
|
2668
2855
|
logger.newline();
|
|
@@ -2688,8 +2875,8 @@ function registerCreateProjectCommand(program2) {
|
|
|
2688
2875
|
}
|
|
2689
2876
|
|
|
2690
2877
|
// src/commands/deploy.ts
|
|
2691
|
-
import { existsSync as
|
|
2692
|
-
import { resolve as
|
|
2878
|
+
import { existsSync as existsSync12 } from "fs";
|
|
2879
|
+
import { resolve as resolve12, dirname as dirname8 } from "path";
|
|
2693
2880
|
import { loadSchemas as loadSchemas4, OmnifyError as OmnifyError5 } from "@famgia/omnify-core";
|
|
2694
2881
|
import {
|
|
2695
2882
|
VERSION_CHAIN_FILE as VERSION_CHAIN_FILE2,
|
|
@@ -2704,7 +2891,7 @@ async function confirmDeploy(schemaCount, environment, version) {
|
|
|
2704
2891
|
input: process.stdin,
|
|
2705
2892
|
output: process.stdout
|
|
2706
2893
|
});
|
|
2707
|
-
return new Promise((
|
|
2894
|
+
return new Promise((resolve15) => {
|
|
2708
2895
|
logger.newline();
|
|
2709
2896
|
logger.warn("\u26A0\uFE0F WARNING: This action is IRREVERSIBLE!");
|
|
2710
2897
|
logger.warn("");
|
|
@@ -2720,7 +2907,7 @@ async function confirmDeploy(schemaCount, environment, version) {
|
|
|
2720
2907
|
logger.newline();
|
|
2721
2908
|
rl.question(' Type "LOCK" to confirm: ', (answer) => {
|
|
2722
2909
|
rl.close();
|
|
2723
|
-
|
|
2910
|
+
resolve15(answer.trim().toUpperCase() === "LOCK");
|
|
2724
2911
|
});
|
|
2725
2912
|
});
|
|
2726
2913
|
}
|
|
@@ -2743,9 +2930,9 @@ async function runDeploy(options) {
|
|
|
2743
2930
|
const { config, configPath: configPath2 } = await loadConfig();
|
|
2744
2931
|
const rootDir = configPath2 ? dirname8(configPath2) : process.cwd();
|
|
2745
2932
|
validateConfig(config, rootDir);
|
|
2746
|
-
const schemasDir =
|
|
2747
|
-
const chainFilePath =
|
|
2748
|
-
if (!
|
|
2933
|
+
const schemasDir = resolve12(rootDir, config.schemasDir);
|
|
2934
|
+
const chainFilePath = resolve12(rootDir, VERSION_CHAIN_FILE2);
|
|
2935
|
+
if (!existsSync12(schemasDir)) {
|
|
2749
2936
|
throw new OmnifyError5(
|
|
2750
2937
|
`Schemas directory not found: ${schemasDir}`,
|
|
2751
2938
|
"E003",
|
|
@@ -2899,8 +3086,8 @@ function registerDeployCommand(program2) {
|
|
|
2899
3086
|
}
|
|
2900
3087
|
|
|
2901
3088
|
// src/commands/verify.ts
|
|
2902
|
-
import { existsSync as
|
|
2903
|
-
import { resolve as
|
|
3089
|
+
import { existsSync as existsSync13 } from "fs";
|
|
3090
|
+
import { resolve as resolve13, dirname as dirname9 } from "path";
|
|
2904
3091
|
import { OmnifyError as OmnifyError6 } from "@famgia/omnify-core";
|
|
2905
3092
|
import {
|
|
2906
3093
|
VERSION_CHAIN_FILE as VERSION_CHAIN_FILE3,
|
|
@@ -2918,9 +3105,9 @@ async function runVerify(options) {
|
|
|
2918
3105
|
const { config, configPath: configPath2 } = await loadConfig();
|
|
2919
3106
|
const rootDir = configPath2 ? dirname9(configPath2) : process.cwd();
|
|
2920
3107
|
validateConfig(config, rootDir);
|
|
2921
|
-
const schemasDir =
|
|
2922
|
-
const chainFilePath =
|
|
2923
|
-
if (!
|
|
3108
|
+
const schemasDir = resolve13(rootDir, config.schemasDir);
|
|
3109
|
+
const chainFilePath = resolve13(rootDir, VERSION_CHAIN_FILE3);
|
|
3110
|
+
if (!existsSync13(chainFilePath)) {
|
|
2924
3111
|
if (options.json) {
|
|
2925
3112
|
console.log(JSON.stringify({
|
|
2926
3113
|
valid: true,
|
|
@@ -3100,8 +3287,8 @@ process.on("unhandledRejection", (reason) => {
|
|
|
3100
3287
|
var args = process.argv.slice(2);
|
|
3101
3288
|
var firstArg = args[0];
|
|
3102
3289
|
var hasCommand = firstArg !== void 0 && !firstArg.startsWith("-");
|
|
3103
|
-
var configPath =
|
|
3104
|
-
var hasConfig =
|
|
3290
|
+
var configPath = resolve14(process.cwd(), "omnify.config.ts");
|
|
3291
|
+
var hasConfig = existsSync14(configPath);
|
|
3105
3292
|
if (!hasCommand && !hasConfig) {
|
|
3106
3293
|
runInit({}).catch((error) => {
|
|
3107
3294
|
if (error instanceof Error) {
|