@famgia/omnify-cli 2.0.10 → 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/index.js
CHANGED
|
@@ -1102,8 +1102,8 @@ function registerDiffCommand(program) {
|
|
|
1102
1102
|
}
|
|
1103
1103
|
|
|
1104
1104
|
// src/commands/generate.ts
|
|
1105
|
-
import { existsSync as
|
|
1106
|
-
import { resolve as
|
|
1105
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, writeFileSync as writeFileSync5, readdirSync as readdirSync2 } from "fs";
|
|
1106
|
+
import { resolve as resolve9, dirname as dirname6, relative } from "path";
|
|
1107
1107
|
import {
|
|
1108
1108
|
loadSchemas as loadSchemas3,
|
|
1109
1109
|
mergePartialSchemas as mergePartialSchemas3,
|
|
@@ -1138,17 +1138,19 @@ import { generateTypeScript, generateAIGuides as generateTypescriptAIGuides, sho
|
|
|
1138
1138
|
// src/guides/index.ts
|
|
1139
1139
|
import { existsSync as existsSync7, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3 } from "fs";
|
|
1140
1140
|
import { resolve as resolve7, dirname as dirname5, join } from "path";
|
|
1141
|
-
|
|
1142
|
-
var
|
|
1141
|
+
var OMNIFY_SECTION_START = "<!-- OMNIFY_SECTION_START -->";
|
|
1142
|
+
var OMNIFY_SECTION_END = "<!-- OMNIFY_SECTION_END -->";
|
|
1143
|
+
var OMNIFY_SECTION = `${OMNIFY_SECTION_START}
|
|
1144
|
+
## Omnify Schema System
|
|
1143
1145
|
|
|
1144
1146
|
This project uses **Omnify** for schema-driven code generation.
|
|
1145
1147
|
|
|
1146
|
-
|
|
1148
|
+
### Quick Reference
|
|
1147
1149
|
|
|
1148
1150
|
- **Schema Guide**: @.claude/omnify/guides/omnify/schema-guide.md
|
|
1149
1151
|
- **Config Guide**: @.claude/omnify/guides/omnify/config-guide.md
|
|
1150
1152
|
|
|
1151
|
-
|
|
1153
|
+
### Commands
|
|
1152
1154
|
|
|
1153
1155
|
\`\`\`bash
|
|
1154
1156
|
npx omnify generate # Generate code from schemas
|
|
@@ -1156,41 +1158,52 @@ npx omnify validate # Validate schemas
|
|
|
1156
1158
|
php artisan migrate # Run database migrations
|
|
1157
1159
|
\`\`\`
|
|
1158
1160
|
|
|
1159
|
-
|
|
1161
|
+
### Critical Rules
|
|
1160
1162
|
|
|
1161
|
-
|
|
1163
|
+
#### \u26D4 DO NOT EDIT Auto-Generated Files
|
|
1162
1164
|
- \`database/migrations/omnify/**\` - Regenerated on \`npx omnify generate\`
|
|
1163
1165
|
- \`app/Models/OmnifyBase/**\` - Base models (extend, don't edit)
|
|
1164
1166
|
- \`app/Http/Requests/OmnifyBase/**\` - Base requests
|
|
1165
1167
|
- \`app/Http/Resources/OmnifyBase/**\` - Base resources
|
|
1166
1168
|
|
|
1167
|
-
|
|
1169
|
+
#### \u2705 Schema-First Workflow
|
|
1168
1170
|
1. Edit YAML schema in \`schemas/\`
|
|
1169
1171
|
2. Run \`npx omnify generate\`
|
|
1170
1172
|
3. Run \`php artisan migrate\`
|
|
1171
1173
|
|
|
1172
1174
|
**NEVER use \`php artisan make:migration\`** - Always use schemas!
|
|
1175
|
+
${OMNIFY_SECTION_END}`;
|
|
1176
|
+
function updateClaudeMd(rootDir) {
|
|
1177
|
+
const claudeMdPath = resolve7(rootDir, "CLAUDE.md");
|
|
1178
|
+
if (!existsSync7(claudeMdPath)) {
|
|
1179
|
+
writeFileSync3(claudeMdPath, `# Project Documentation
|
|
1173
1180
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1181
|
+
${OMNIFY_SECTION}
|
|
1182
|
+
`);
|
|
1183
|
+
return true;
|
|
1184
|
+
}
|
|
1185
|
+
const currentContent = readFileSync3(claudeMdPath, "utf8");
|
|
1186
|
+
const hasOmnifySection = currentContent.includes(OMNIFY_SECTION_START);
|
|
1187
|
+
if (hasOmnifySection) {
|
|
1188
|
+
const regex = new RegExp(
|
|
1189
|
+
`${escapeRegExp(OMNIFY_SECTION_START)}[\\s\\S]*?${escapeRegExp(OMNIFY_SECTION_END)}`,
|
|
1190
|
+
"g"
|
|
1191
|
+
);
|
|
1192
|
+
const newContent = currentContent.replace(regex, OMNIFY_SECTION);
|
|
1193
|
+
if (newContent !== currentContent) {
|
|
1194
|
+
writeFileSync3(claudeMdPath, newContent);
|
|
1195
|
+
return true;
|
|
1196
|
+
}
|
|
1197
|
+
return false;
|
|
1198
|
+
} else {
|
|
1199
|
+
const newContent = currentContent.trimEnd() + "\n\n" + OMNIFY_SECTION + "\n";
|
|
1200
|
+
writeFileSync3(claudeMdPath, newContent);
|
|
1201
|
+
return true;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
function escapeRegExp(string) {
|
|
1205
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1206
|
+
}
|
|
1194
1207
|
function copyOmnifyGuides(rootDir) {
|
|
1195
1208
|
let filesWritten = 0;
|
|
1196
1209
|
const omnifyPkgPaths = [
|
|
@@ -1245,20 +1258,141 @@ function copyOmnifyGuides(rootDir) {
|
|
|
1245
1258
|
}
|
|
1246
1259
|
function generateAIGuides(rootDir, _plugins) {
|
|
1247
1260
|
let filesWritten = 0;
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1261
|
+
if (updateClaudeMd(rootDir)) {
|
|
1262
|
+
filesWritten++;
|
|
1263
|
+
}
|
|
1251
1264
|
filesWritten += copyOmnifyGuides(rootDir);
|
|
1252
1265
|
return filesWritten;
|
|
1253
1266
|
}
|
|
1254
1267
|
|
|
1268
|
+
// src/version-lock/index.ts
|
|
1269
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync8 } from "fs";
|
|
1270
|
+
import { resolve as resolve8 } from "path";
|
|
1271
|
+
var VERSION_LOCK_FILE = ".omnify-versions.lock";
|
|
1272
|
+
function readVersionLock(rootDir) {
|
|
1273
|
+
const lockPath = resolve8(rootDir, VERSION_LOCK_FILE);
|
|
1274
|
+
if (!existsSync8(lockPath)) {
|
|
1275
|
+
return null;
|
|
1276
|
+
}
|
|
1277
|
+
try {
|
|
1278
|
+
const content = readFileSync4(lockPath, "utf-8");
|
|
1279
|
+
return JSON.parse(content);
|
|
1280
|
+
} catch {
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
function writeVersionLock(rootDir, lock) {
|
|
1285
|
+
const lockPath = resolve8(rootDir, VERSION_LOCK_FILE);
|
|
1286
|
+
const content = JSON.stringify(lock, null, 2);
|
|
1287
|
+
writeFileSync4(lockPath, content + "\n");
|
|
1288
|
+
}
|
|
1289
|
+
function parseVersion(version) {
|
|
1290
|
+
const cleanVersion = version.replace(/^v/, "");
|
|
1291
|
+
const match = cleanVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
1292
|
+
if (!match) {
|
|
1293
|
+
return null;
|
|
1294
|
+
}
|
|
1295
|
+
return {
|
|
1296
|
+
major: parseInt(match[1], 10),
|
|
1297
|
+
minor: parseInt(match[2], 10),
|
|
1298
|
+
patch: parseInt(match[3], 10)
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
function compareVersions(a, b) {
|
|
1302
|
+
const parsedA = parseVersion(a);
|
|
1303
|
+
const parsedB = parseVersion(b);
|
|
1304
|
+
if (!parsedA || !parsedB) {
|
|
1305
|
+
return 0;
|
|
1306
|
+
}
|
|
1307
|
+
if (parsedA.major !== parsedB.major) {
|
|
1308
|
+
return parsedA.major > parsedB.major ? 1 : -1;
|
|
1309
|
+
}
|
|
1310
|
+
if (parsedA.minor !== parsedB.minor) {
|
|
1311
|
+
return parsedA.minor > parsedB.minor ? 1 : -1;
|
|
1312
|
+
}
|
|
1313
|
+
if (parsedA.patch !== parsedB.patch) {
|
|
1314
|
+
return parsedA.patch > parsedB.patch ? 1 : -1;
|
|
1315
|
+
}
|
|
1316
|
+
return 0;
|
|
1317
|
+
}
|
|
1318
|
+
function checkPluginVersions(plugins, lockFile) {
|
|
1319
|
+
const mismatches = [];
|
|
1320
|
+
const newPlugins = [];
|
|
1321
|
+
const lockedVersions = /* @__PURE__ */ new Map();
|
|
1322
|
+
for (const entry of lockFile.plugins) {
|
|
1323
|
+
lockedVersions.set(entry.name, entry.version);
|
|
1324
|
+
}
|
|
1325
|
+
for (const plugin of plugins) {
|
|
1326
|
+
const lockedVersion = lockedVersions.get(plugin.name);
|
|
1327
|
+
if (!lockedVersion) {
|
|
1328
|
+
newPlugins.push(plugin.name);
|
|
1329
|
+
continue;
|
|
1330
|
+
}
|
|
1331
|
+
const comparison = compareVersions(plugin.version, lockedVersion);
|
|
1332
|
+
if (comparison < 0) {
|
|
1333
|
+
mismatches.push({
|
|
1334
|
+
name: plugin.name,
|
|
1335
|
+
required: lockedVersion,
|
|
1336
|
+
installed: plugin.version
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
return {
|
|
1341
|
+
valid: mismatches.length === 0,
|
|
1342
|
+
mismatches,
|
|
1343
|
+
newPlugins
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
function updateVersionLock(rootDir, plugins, cliVersion) {
|
|
1347
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1348
|
+
const existingLock = readVersionLock(rootDir);
|
|
1349
|
+
const existingEntries = /* @__PURE__ */ new Map();
|
|
1350
|
+
if (existingLock) {
|
|
1351
|
+
for (const entry of existingLock.plugins) {
|
|
1352
|
+
existingEntries.set(entry.name, entry);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
const pluginEntries = [];
|
|
1356
|
+
for (const plugin of plugins) {
|
|
1357
|
+
const existing = existingEntries.get(plugin.name);
|
|
1358
|
+
if (!existing || compareVersions(plugin.version, existing.version) > 0) {
|
|
1359
|
+
pluginEntries.push({
|
|
1360
|
+
name: plugin.name,
|
|
1361
|
+
version: plugin.version,
|
|
1362
|
+
updatedAt: now
|
|
1363
|
+
});
|
|
1364
|
+
} else {
|
|
1365
|
+
pluginEntries.push(existing);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
pluginEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
1369
|
+
const lock = {
|
|
1370
|
+
version: 1,
|
|
1371
|
+
cliVersion,
|
|
1372
|
+
plugins: pluginEntries,
|
|
1373
|
+
updatedAt: now
|
|
1374
|
+
};
|
|
1375
|
+
writeVersionLock(rootDir, lock);
|
|
1376
|
+
return lock;
|
|
1377
|
+
}
|
|
1378
|
+
function getCliVersion() {
|
|
1379
|
+
try {
|
|
1380
|
+
const pkgPath = new URL("../../package.json", import.meta.url);
|
|
1381
|
+
const pkgContent = readFileSync4(pkgPath, "utf-8");
|
|
1382
|
+
const pkg = JSON.parse(pkgContent);
|
|
1383
|
+
return pkg.version;
|
|
1384
|
+
} catch {
|
|
1385
|
+
return "unknown";
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1255
1389
|
// src/commands/generate.ts
|
|
1256
1390
|
function hasPluginGenerators(plugins) {
|
|
1257
1391
|
return plugins.some((p) => p.generators && p.generators.length > 0);
|
|
1258
1392
|
}
|
|
1259
1393
|
function getExistingMigrationTables(migrationsDir) {
|
|
1260
1394
|
const existingTables = /* @__PURE__ */ new Set();
|
|
1261
|
-
if (!
|
|
1395
|
+
if (!existsSync9(migrationsDir)) {
|
|
1262
1396
|
return existingTables;
|
|
1263
1397
|
}
|
|
1264
1398
|
try {
|
|
@@ -1451,17 +1585,17 @@ function schemaChangeToVersionChange(change) {
|
|
|
1451
1585
|
function writeGeneratorOutputs(outputs, rootDir) {
|
|
1452
1586
|
const counts = { migrations: 0, types: 0, models: 0, factories: 0, other: 0 };
|
|
1453
1587
|
for (const output of outputs) {
|
|
1454
|
-
const filePath =
|
|
1588
|
+
const filePath = resolve9(rootDir, output.path);
|
|
1455
1589
|
const dir = dirname6(filePath);
|
|
1456
|
-
if (!
|
|
1590
|
+
if (!existsSync9(dir)) {
|
|
1457
1591
|
mkdirSync3(dir, { recursive: true });
|
|
1458
1592
|
logger.debug(`Created directory: ${dir}`);
|
|
1459
1593
|
}
|
|
1460
|
-
if (output.skipIfExists &&
|
|
1594
|
+
if (output.skipIfExists && existsSync9(filePath)) {
|
|
1461
1595
|
logger.debug(`Skipped (exists): ${output.path}`);
|
|
1462
1596
|
continue;
|
|
1463
1597
|
}
|
|
1464
|
-
|
|
1598
|
+
writeFileSync5(filePath, output.content);
|
|
1465
1599
|
logger.debug(`Created: ${output.path}`);
|
|
1466
1600
|
if (output.type === "migration") counts.migrations++;
|
|
1467
1601
|
else if (output.type === "type") counts.types++;
|
|
@@ -1471,7 +1605,7 @@ function writeGeneratorOutputs(outputs, rootDir) {
|
|
|
1471
1605
|
}
|
|
1472
1606
|
return counts;
|
|
1473
1607
|
}
|
|
1474
|
-
async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes) {
|
|
1608
|
+
async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes, localeConfig) {
|
|
1475
1609
|
const pluginManager = new PluginManager({
|
|
1476
1610
|
cwd: rootDir,
|
|
1477
1611
|
verbose,
|
|
@@ -1480,7 +1614,8 @@ async function runPluginGeneration(plugins, schemas, rootDir, verbose, changes)
|
|
|
1480
1614
|
info: (msg) => logger.info(msg),
|
|
1481
1615
|
warn: (msg) => logger.warn(msg),
|
|
1482
1616
|
error: (msg) => logger.error(msg)
|
|
1483
|
-
}
|
|
1617
|
+
},
|
|
1618
|
+
localeConfig
|
|
1484
1619
|
});
|
|
1485
1620
|
for (const plugin of plugins) {
|
|
1486
1621
|
await pluginManager.register(plugin);
|
|
@@ -1517,8 +1652,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1517
1652
|
}
|
|
1518
1653
|
if (!options.typesOnly && config.output.laravel) {
|
|
1519
1654
|
logger.step("Generating Laravel migrations...");
|
|
1520
|
-
const migrationsDir =
|
|
1521
|
-
if (!
|
|
1655
|
+
const migrationsDir = resolve9(rootDir, config.output.laravel.migrationsPath);
|
|
1656
|
+
if (!existsSync9(migrationsDir)) {
|
|
1522
1657
|
mkdirSync3(migrationsDir, { recursive: true });
|
|
1523
1658
|
logger.debug(`Created directory: ${migrationsDir}`);
|
|
1524
1659
|
}
|
|
@@ -1540,8 +1675,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1540
1675
|
logger.debug(`Skipped CREATE for ${tableName} (already exists)`);
|
|
1541
1676
|
continue;
|
|
1542
1677
|
}
|
|
1543
|
-
const filePath =
|
|
1544
|
-
|
|
1678
|
+
const filePath = resolve9(migrationsDir, migration.fileName);
|
|
1679
|
+
writeFileSync5(filePath, migration.content);
|
|
1545
1680
|
logger.debug(`Created: ${migration.fileName}`);
|
|
1546
1681
|
migrationsGenerated++;
|
|
1547
1682
|
}
|
|
@@ -1549,8 +1684,8 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1549
1684
|
if (alterChanges.length > 0) {
|
|
1550
1685
|
const alterMigrations = generateMigrationsFromChanges(alterChanges);
|
|
1551
1686
|
for (const migration of alterMigrations) {
|
|
1552
|
-
const filePath =
|
|
1553
|
-
|
|
1687
|
+
const filePath = resolve9(migrationsDir, migration.fileName);
|
|
1688
|
+
writeFileSync5(filePath, migration.content);
|
|
1554
1689
|
logger.debug(`Created: ${migration.fileName}`);
|
|
1555
1690
|
migrationsGenerated++;
|
|
1556
1691
|
}
|
|
@@ -1561,12 +1696,12 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1561
1696
|
logger.step("Generating Laravel models...");
|
|
1562
1697
|
const modelsPath = config.output.laravel.modelsPath;
|
|
1563
1698
|
const baseModelsPath = config.output.laravel.baseModelsPath ?? `${modelsPath}/OmnifyBase`;
|
|
1564
|
-
const modelsDir =
|
|
1565
|
-
const baseModelsDir =
|
|
1566
|
-
if (!
|
|
1699
|
+
const modelsDir = resolve9(rootDir, modelsPath);
|
|
1700
|
+
const baseModelsDir = resolve9(rootDir, baseModelsPath);
|
|
1701
|
+
if (!existsSync9(modelsDir)) {
|
|
1567
1702
|
mkdirSync3(modelsDir, { recursive: true });
|
|
1568
1703
|
}
|
|
1569
|
-
if (!
|
|
1704
|
+
if (!existsSync9(baseModelsDir)) {
|
|
1570
1705
|
mkdirSync3(baseModelsDir, { recursive: true });
|
|
1571
1706
|
}
|
|
1572
1707
|
const providersPath = config.output.laravel.providersPath ?? "app/Providers";
|
|
@@ -1577,16 +1712,16 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1577
1712
|
customTypes: customTypesMap
|
|
1578
1713
|
});
|
|
1579
1714
|
for (const model of models) {
|
|
1580
|
-
const filePath =
|
|
1715
|
+
const filePath = resolve9(rootDir, getModelPath(model));
|
|
1581
1716
|
const fileDir = dirname6(filePath);
|
|
1582
|
-
if (!
|
|
1717
|
+
if (!existsSync9(fileDir)) {
|
|
1583
1718
|
mkdirSync3(fileDir, { recursive: true });
|
|
1584
1719
|
}
|
|
1585
|
-
if (!model.overwrite &&
|
|
1720
|
+
if (!model.overwrite && existsSync9(filePath)) {
|
|
1586
1721
|
logger.debug(`Skipped (exists): ${getModelPath(model)}`);
|
|
1587
1722
|
continue;
|
|
1588
1723
|
}
|
|
1589
|
-
|
|
1724
|
+
writeFileSync5(filePath, model.content);
|
|
1590
1725
|
logger.debug(`Created: ${getModelPath(model)}`);
|
|
1591
1726
|
modelsGenerated++;
|
|
1592
1727
|
}
|
|
@@ -1595,24 +1730,24 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1595
1730
|
if (!options.typesOnly && config.output.laravel?.factoriesPath) {
|
|
1596
1731
|
logger.step("Generating Laravel factories...");
|
|
1597
1732
|
const factoriesPath = config.output.laravel.factoriesPath;
|
|
1598
|
-
const factoriesDir =
|
|
1599
|
-
if (!
|
|
1733
|
+
const factoriesDir = resolve9(rootDir, factoriesPath);
|
|
1734
|
+
if (!existsSync9(factoriesDir)) {
|
|
1600
1735
|
mkdirSync3(factoriesDir, { recursive: true });
|
|
1601
1736
|
}
|
|
1602
1737
|
const factories = generateFactories(schemas, {
|
|
1603
1738
|
factoryPath: factoriesPath
|
|
1604
1739
|
});
|
|
1605
1740
|
for (const factory of factories) {
|
|
1606
|
-
const filePath =
|
|
1741
|
+
const filePath = resolve9(rootDir, getFactoryPath(factory));
|
|
1607
1742
|
const fileDir = dirname6(filePath);
|
|
1608
|
-
if (!
|
|
1743
|
+
if (!existsSync9(fileDir)) {
|
|
1609
1744
|
mkdirSync3(fileDir, { recursive: true });
|
|
1610
1745
|
}
|
|
1611
|
-
if (!factory.overwrite &&
|
|
1746
|
+
if (!factory.overwrite && existsSync9(filePath)) {
|
|
1612
1747
|
logger.debug(`Skipped (exists): ${getFactoryPath(factory)}`);
|
|
1613
1748
|
continue;
|
|
1614
1749
|
}
|
|
1615
|
-
|
|
1750
|
+
writeFileSync5(filePath, factory.content);
|
|
1616
1751
|
logger.debug(`Created: ${getFactoryPath(factory)}`);
|
|
1617
1752
|
factoriesGenerated++;
|
|
1618
1753
|
}
|
|
@@ -1621,32 +1756,32 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1621
1756
|
if (!options.migrationsOnly && config.output.typescript) {
|
|
1622
1757
|
logger.step("Generating TypeScript types...");
|
|
1623
1758
|
const tsConfig = config.output.typescript;
|
|
1624
|
-
const basePath =
|
|
1625
|
-
const schemasDir =
|
|
1626
|
-
const enumDir =
|
|
1627
|
-
const omnifyBaseDir =
|
|
1628
|
-
const pluginEnumDir =
|
|
1629
|
-
const baseSchemasDir =
|
|
1759
|
+
const basePath = resolve9(rootDir, tsConfig.path);
|
|
1760
|
+
const schemasDir = resolve9(basePath, tsConfig.schemasDir ?? "schemas");
|
|
1761
|
+
const enumDir = resolve9(basePath, tsConfig.enumDir ?? "enum");
|
|
1762
|
+
const omnifyBaseDir = resolve9(rootDir, "node_modules/@omnify-base");
|
|
1763
|
+
const pluginEnumDir = resolve9(omnifyBaseDir, "enum");
|
|
1764
|
+
const baseSchemasDir = resolve9(omnifyBaseDir, "schemas");
|
|
1630
1765
|
const enumImportPrefix = relative(schemasDir, enumDir).replace(/\\/g, "/");
|
|
1631
|
-
if (!
|
|
1766
|
+
if (!existsSync9(schemasDir)) {
|
|
1632
1767
|
mkdirSync3(schemasDir, { recursive: true });
|
|
1633
1768
|
logger.debug(`Created directory: ${schemasDir}`);
|
|
1634
1769
|
}
|
|
1635
|
-
if (!
|
|
1770
|
+
if (!existsSync9(enumDir)) {
|
|
1636
1771
|
mkdirSync3(enumDir, { recursive: true });
|
|
1637
1772
|
logger.debug(`Created directory: ${enumDir}`);
|
|
1638
1773
|
}
|
|
1639
|
-
if (!
|
|
1774
|
+
if (!existsSync9(pluginEnumDir)) {
|
|
1640
1775
|
mkdirSync3(pluginEnumDir, { recursive: true });
|
|
1641
1776
|
logger.debug(`Created directory: ${pluginEnumDir}`);
|
|
1642
1777
|
}
|
|
1643
|
-
if (!
|
|
1778
|
+
if (!existsSync9(baseSchemasDir)) {
|
|
1644
1779
|
mkdirSync3(baseSchemasDir, { recursive: true });
|
|
1645
1780
|
logger.debug(`Created directory: ${baseSchemasDir}`);
|
|
1646
1781
|
}
|
|
1647
|
-
const omnifyPkgJson =
|
|
1648
|
-
if (!
|
|
1649
|
-
|
|
1782
|
+
const omnifyPkgJson = resolve9(omnifyBaseDir, "package.json");
|
|
1783
|
+
if (!existsSync9(omnifyPkgJson)) {
|
|
1784
|
+
writeFileSync5(omnifyPkgJson, JSON.stringify({
|
|
1650
1785
|
name: "@omnify-base",
|
|
1651
1786
|
version: "0.0.0",
|
|
1652
1787
|
private: true,
|
|
@@ -1683,16 +1818,16 @@ function runDirectGeneration(schemas, config, rootDir, options, changes) {
|
|
|
1683
1818
|
} else {
|
|
1684
1819
|
outputDir = schemasDir;
|
|
1685
1820
|
}
|
|
1686
|
-
const filePath =
|
|
1821
|
+
const filePath = resolve9(outputDir, outputFilePath);
|
|
1687
1822
|
const fileDir = dirname6(filePath);
|
|
1688
|
-
if (!
|
|
1823
|
+
if (!existsSync9(fileDir)) {
|
|
1689
1824
|
mkdirSync3(fileDir, { recursive: true });
|
|
1690
1825
|
}
|
|
1691
|
-
if (!file.overwrite &&
|
|
1826
|
+
if (!file.overwrite && existsSync9(filePath)) {
|
|
1692
1827
|
logger.debug(`Skipped (exists): ${file.filePath}`);
|
|
1693
1828
|
continue;
|
|
1694
1829
|
}
|
|
1695
|
-
|
|
1830
|
+
writeFileSync5(filePath, file.content);
|
|
1696
1831
|
logger.debug(`Created: ${file.filePath}`);
|
|
1697
1832
|
typesGenerated++;
|
|
1698
1833
|
}
|
|
@@ -1722,7 +1857,49 @@ async function runGenerate(options) {
|
|
|
1722
1857
|
const { config, configPath } = await loadConfig();
|
|
1723
1858
|
const rootDir = configPath ? dirname6(configPath) : process.cwd();
|
|
1724
1859
|
validateConfig(config, rootDir);
|
|
1725
|
-
|
|
1860
|
+
if (config.plugins.length > 0) {
|
|
1861
|
+
const versionLock = readVersionLock(rootDir);
|
|
1862
|
+
if (versionLock) {
|
|
1863
|
+
logger.debug("Checking plugin versions against lock file...");
|
|
1864
|
+
const versionCheck = checkPluginVersions(config.plugins, versionLock);
|
|
1865
|
+
if (!versionCheck.valid) {
|
|
1866
|
+
logger.newline();
|
|
1867
|
+
logger.error("\u{1F512} PLUGIN VERSION MISMATCH");
|
|
1868
|
+
logger.error("");
|
|
1869
|
+
logger.error("The following plugins are older than required by the version lock:");
|
|
1870
|
+
logger.newline();
|
|
1871
|
+
for (const mismatch of versionCheck.mismatches) {
|
|
1872
|
+
logger.error(` \u2022 ${mismatch.name}`);
|
|
1873
|
+
logger.error(` Required: ${mismatch.required}`);
|
|
1874
|
+
logger.error(` Installed: ${mismatch.installed}`);
|
|
1875
|
+
}
|
|
1876
|
+
logger.newline();
|
|
1877
|
+
logger.error(`Version lock file: ${VERSION_LOCK_FILE}`);
|
|
1878
|
+
logger.newline();
|
|
1879
|
+
logger.info("To fix this, upgrade the outdated plugins:");
|
|
1880
|
+
logger.info("");
|
|
1881
|
+
for (const mismatch of versionCheck.mismatches) {
|
|
1882
|
+
logger.info(` npm install ${mismatch.name}@latest`);
|
|
1883
|
+
}
|
|
1884
|
+
logger.newline();
|
|
1885
|
+
logger.info("Or if you intentionally want to use older versions, delete the lock file:");
|
|
1886
|
+
logger.info(` rm ${VERSION_LOCK_FILE}`);
|
|
1887
|
+
logger.newline();
|
|
1888
|
+
throw new OmnifyError4(
|
|
1889
|
+
"Plugin version mismatch: installed versions are older than lock file requirements",
|
|
1890
|
+
"E501",
|
|
1891
|
+
void 0,
|
|
1892
|
+
"Upgrade plugins or delete the version lock file to regenerate it."
|
|
1893
|
+
);
|
|
1894
|
+
}
|
|
1895
|
+
if (versionCheck.newPlugins.length > 0) {
|
|
1896
|
+
logger.debug(`New plugins detected: ${versionCheck.newPlugins.join(", ")}`);
|
|
1897
|
+
}
|
|
1898
|
+
} else {
|
|
1899
|
+
logger.debug(`No version lock file found (${VERSION_LOCK_FILE})`);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
const schemaPath = resolve9(rootDir, config.schemasDir);
|
|
1726
1903
|
logger.step(`Loading schemas from ${schemaPath}`);
|
|
1727
1904
|
let schemas = await loadSchemas3(schemaPath);
|
|
1728
1905
|
logger.debug(`Found ${Object.keys(schemas).length} schema(s) in main directory`);
|
|
@@ -1731,9 +1908,9 @@ async function runGenerate(options) {
|
|
|
1731
1908
|
if (additionalPaths.length > 0) {
|
|
1732
1909
|
logger.step(`Loading schemas from ${additionalPaths.length} additional path(s)`);
|
|
1733
1910
|
for (const entry of additionalPaths) {
|
|
1734
|
-
const absolutePath =
|
|
1911
|
+
const absolutePath = resolve9(rootDir, entry.path);
|
|
1735
1912
|
logger.debug(` Checking: ${entry.path} \u2192 ${absolutePath}`);
|
|
1736
|
-
if (
|
|
1913
|
+
if (existsSync9(absolutePath)) {
|
|
1737
1914
|
let packageSchemas = await loadSchemas3(absolutePath, { skipPartialResolution: true });
|
|
1738
1915
|
if (entry.output) {
|
|
1739
1916
|
const schemasWithOutput = {};
|
|
@@ -1788,12 +1965,12 @@ async function runGenerate(options) {
|
|
|
1788
1965
|
process.exit(2);
|
|
1789
1966
|
}
|
|
1790
1967
|
logger.step("Checking for changes...");
|
|
1791
|
-
const lockPath =
|
|
1968
|
+
const lockPath = resolve9(rootDir, config.lockFilePath);
|
|
1792
1969
|
const existingLock = await readLockFile(lockPath);
|
|
1793
1970
|
const currentSnapshots = await buildSchemaSnapshots(schemas);
|
|
1794
1971
|
const v2Lock = existingLock && isLockFileV2(existingLock) ? existingLock : null;
|
|
1795
1972
|
const comparison = compareSchemasDeep(currentSnapshots, v2Lock);
|
|
1796
|
-
const chainFilePath =
|
|
1973
|
+
const chainFilePath = resolve9(rootDir, VERSION_CHAIN_FILE);
|
|
1797
1974
|
const versionChain = await readVersionChain(chainFilePath);
|
|
1798
1975
|
if (versionChain && comparison.hasChanges) {
|
|
1799
1976
|
const schemaActions = [];
|
|
@@ -1830,7 +2007,7 @@ async function runGenerate(options) {
|
|
|
1830
2007
|
}
|
|
1831
2008
|
}
|
|
1832
2009
|
if (existingLock && config.output.laravel?.migrationsPath) {
|
|
1833
|
-
const migrationsDir =
|
|
2010
|
+
const migrationsDir = resolve9(rootDir, config.output.laravel.migrationsPath);
|
|
1834
2011
|
const migrationValidation = await validateMigrations(existingLock, migrationsDir);
|
|
1835
2012
|
if (!migrationValidation.valid) {
|
|
1836
2013
|
logger.newline();
|
|
@@ -1890,7 +2067,7 @@ async function runGenerate(options) {
|
|
|
1890
2067
|
const alterMigrations = toRegenerate.filter((m) => m.type === "alter" || m.type === "drop");
|
|
1891
2068
|
if (createMigrations.length > 0) {
|
|
1892
2069
|
logger.info(`Regenerating ${createMigrations.length} missing CREATE migration(s) with original timestamps...`);
|
|
1893
|
-
const migrationsDir2 =
|
|
2070
|
+
const migrationsDir2 = resolve9(rootDir, config.output.laravel.migrationsPath);
|
|
1894
2071
|
const customTypesMap2 = /* @__PURE__ */ new Map();
|
|
1895
2072
|
for (const plugin of config.plugins) {
|
|
1896
2073
|
if (plugin.types) {
|
|
@@ -1912,8 +2089,8 @@ async function runGenerate(options) {
|
|
|
1912
2089
|
customTypes: customTypesMap2
|
|
1913
2090
|
});
|
|
1914
2091
|
for (const mig of regenerated) {
|
|
1915
|
-
const filePath =
|
|
1916
|
-
|
|
2092
|
+
const filePath = resolve9(migrationsDir2, migData.fileName);
|
|
2093
|
+
writeFileSync5(filePath, mig.content);
|
|
1917
2094
|
logger.success(` Regenerated: ${migData.fileName}`);
|
|
1918
2095
|
}
|
|
1919
2096
|
}
|
|
@@ -1969,7 +2146,8 @@ async function runGenerate(options) {
|
|
|
1969
2146
|
schemas,
|
|
1970
2147
|
rootDir,
|
|
1971
2148
|
options.verbose ?? false,
|
|
1972
|
-
comparison.changes
|
|
2149
|
+
comparison.changes,
|
|
2150
|
+
config.locale
|
|
1973
2151
|
);
|
|
1974
2152
|
migrationsGenerated = counts.migrations;
|
|
1975
2153
|
typesGenerated = counts.types;
|
|
@@ -1991,32 +2169,32 @@ async function runGenerate(options) {
|
|
|
1991
2169
|
if (!options.migrationsOnly && config.output.typescript && typesGenerated === 0) {
|
|
1992
2170
|
logger.step("Generating TypeScript types...");
|
|
1993
2171
|
const tsConfig2 = config.output.typescript;
|
|
1994
|
-
const basePath2 =
|
|
1995
|
-
const schemasDir2 =
|
|
1996
|
-
const enumDir2 =
|
|
1997
|
-
const omnifyBaseDir2 =
|
|
1998
|
-
const pluginEnumDir2 =
|
|
1999
|
-
const baseSchemasDir2 =
|
|
2172
|
+
const basePath2 = resolve9(rootDir, tsConfig2.path);
|
|
2173
|
+
const schemasDir2 = resolve9(basePath2, tsConfig2.schemasDir ?? "schemas");
|
|
2174
|
+
const enumDir2 = resolve9(basePath2, tsConfig2.enumDir ?? "enum");
|
|
2175
|
+
const omnifyBaseDir2 = resolve9(rootDir, "node_modules/@omnify-base");
|
|
2176
|
+
const pluginEnumDir2 = resolve9(omnifyBaseDir2, "enum");
|
|
2177
|
+
const baseSchemasDir2 = resolve9(omnifyBaseDir2, "schemas");
|
|
2000
2178
|
const enumImportPrefix2 = relative(schemasDir2, enumDir2).replace(/\\/g, "/");
|
|
2001
|
-
if (!
|
|
2179
|
+
if (!existsSync9(schemasDir2)) {
|
|
2002
2180
|
mkdirSync3(schemasDir2, { recursive: true });
|
|
2003
2181
|
logger.debug(`Created directory: ${schemasDir2}`);
|
|
2004
2182
|
}
|
|
2005
|
-
if (!
|
|
2183
|
+
if (!existsSync9(enumDir2)) {
|
|
2006
2184
|
mkdirSync3(enumDir2, { recursive: true });
|
|
2007
2185
|
logger.debug(`Created directory: ${enumDir2}`);
|
|
2008
2186
|
}
|
|
2009
|
-
if (!
|
|
2187
|
+
if (!existsSync9(pluginEnumDir2)) {
|
|
2010
2188
|
mkdirSync3(pluginEnumDir2, { recursive: true });
|
|
2011
2189
|
logger.debug(`Created directory: ${pluginEnumDir2}`);
|
|
2012
2190
|
}
|
|
2013
|
-
if (!
|
|
2191
|
+
if (!existsSync9(baseSchemasDir2)) {
|
|
2014
2192
|
mkdirSync3(baseSchemasDir2, { recursive: true });
|
|
2015
2193
|
logger.debug(`Created directory: ${baseSchemasDir2}`);
|
|
2016
2194
|
}
|
|
2017
|
-
const omnifyPkgJson2 =
|
|
2018
|
-
if (!
|
|
2019
|
-
|
|
2195
|
+
const omnifyPkgJson2 = resolve9(omnifyBaseDir2, "package.json");
|
|
2196
|
+
if (!existsSync9(omnifyPkgJson2)) {
|
|
2197
|
+
writeFileSync5(omnifyPkgJson2, JSON.stringify({
|
|
2020
2198
|
name: "@omnify-base",
|
|
2021
2199
|
version: "0.0.0",
|
|
2022
2200
|
private: true,
|
|
@@ -2053,16 +2231,16 @@ async function runGenerate(options) {
|
|
|
2053
2231
|
} else {
|
|
2054
2232
|
outputDir2 = schemasDir2;
|
|
2055
2233
|
}
|
|
2056
|
-
const filePath =
|
|
2234
|
+
const filePath = resolve9(outputDir2, outputFilePath2);
|
|
2057
2235
|
const fileDir = dirname6(filePath);
|
|
2058
|
-
if (!
|
|
2236
|
+
if (!existsSync9(fileDir)) {
|
|
2059
2237
|
mkdirSync3(fileDir, { recursive: true });
|
|
2060
2238
|
}
|
|
2061
|
-
if (!file.overwrite &&
|
|
2239
|
+
if (!file.overwrite && existsSync9(filePath)) {
|
|
2062
2240
|
logger.debug(`Skipped (exists): ${file.filePath}`);
|
|
2063
2241
|
continue;
|
|
2064
2242
|
}
|
|
2065
|
-
|
|
2243
|
+
writeFileSync5(filePath, file.content);
|
|
2066
2244
|
logger.debug(`Created: ${file.filePath}`);
|
|
2067
2245
|
typesGenerated++;
|
|
2068
2246
|
}
|
|
@@ -2132,6 +2310,15 @@ async function runGenerate(options) {
|
|
|
2132
2310
|
} catch (guideError) {
|
|
2133
2311
|
logger.debug(`Could not generate AI guides: ${guideError.message}`);
|
|
2134
2312
|
}
|
|
2313
|
+
if (config.plugins.length > 0) {
|
|
2314
|
+
try {
|
|
2315
|
+
const cliVersion = getCliVersion();
|
|
2316
|
+
const updatedLock = updateVersionLock(rootDir, config.plugins, cliVersion);
|
|
2317
|
+
logger.debug(`Updated version lock: ${updatedLock.plugins.length} plugin(s)`);
|
|
2318
|
+
} catch (lockError) {
|
|
2319
|
+
logger.debug(`Could not update version lock: ${lockError.message}`);
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2135
2322
|
logger.newline();
|
|
2136
2323
|
logger.success("Generation complete!");
|
|
2137
2324
|
if (migrationsGenerated > 0 && config.output.laravel) {
|
|
@@ -2161,13 +2348,19 @@ function registerGenerateCommand(program) {
|
|
|
2161
2348
|
});
|
|
2162
2349
|
}
|
|
2163
2350
|
export {
|
|
2351
|
+
VERSION_LOCK_FILE,
|
|
2352
|
+
checkPluginVersions,
|
|
2164
2353
|
defineConfig,
|
|
2354
|
+
getCliVersion,
|
|
2165
2355
|
loadConfig,
|
|
2166
2356
|
logger,
|
|
2357
|
+
readVersionLock,
|
|
2167
2358
|
registerDiffCommand,
|
|
2168
2359
|
registerGenerateCommand,
|
|
2169
2360
|
registerInitCommand,
|
|
2170
2361
|
registerValidateCommand,
|
|
2171
|
-
runInit
|
|
2362
|
+
runInit,
|
|
2363
|
+
updateVersionLock,
|
|
2364
|
+
writeVersionLock
|
|
2172
2365
|
};
|
|
2173
2366
|
//# sourceMappingURL=index.js.map
|