omni-rest 0.2.7 → 0.3.0
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/README.md +2 -2
- package/dist/cli.js +180 -54
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +180 -54
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -517,8 +517,8 @@ MIT © [Omni Rest Contributors](LICENSE)
|
|
|
517
517
|
## Support
|
|
518
518
|
|
|
519
519
|
- 📖 [Documentation](docs/)
|
|
520
|
-
- 🙋 [GitHub Discussions](https://github.com/
|
|
521
|
-
- 🐛 [Report Issues](https://github.com/
|
|
520
|
+
- 🙋 [GitHub Discussions](https://github.com/Abdulllah321/omni-rest/discussions)
|
|
521
|
+
- 🐛 [Report Issues](https://github.com/Abdulllah321/omni-rest/issues)
|
|
522
522
|
- 💬 [Chat on Discord](https://discord.gg/omni-rest)
|
|
523
523
|
|
|
524
524
|
## Acknowledgments
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var fs3 = require('fs');
|
|
5
|
-
var
|
|
5
|
+
var path3 = require('path');
|
|
6
6
|
var readline = require('readline');
|
|
7
7
|
|
|
8
8
|
function _interopNamespace(e) {
|
|
@@ -24,7 +24,7 @@ function _interopNamespace(e) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
var fs3__namespace = /*#__PURE__*/_interopNamespace(fs3);
|
|
27
|
-
var
|
|
27
|
+
var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
|
|
28
28
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
29
29
|
|
|
30
30
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -479,7 +479,7 @@ function buildListParameters() {
|
|
|
479
479
|
}
|
|
480
480
|
var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "out"]);
|
|
481
481
|
function readPackageJson(dir) {
|
|
482
|
-
const pkgPath =
|
|
482
|
+
const pkgPath = path3__namespace.join(dir, "package.json");
|
|
483
483
|
try {
|
|
484
484
|
const content = fs3__namespace.readFileSync(pkgPath, "utf-8");
|
|
485
485
|
return JSON.parse(content);
|
|
@@ -490,14 +490,14 @@ function readPackageJson(dir) {
|
|
|
490
490
|
function scoreDir(dir, cwd2) {
|
|
491
491
|
let score = 0;
|
|
492
492
|
const signals = [];
|
|
493
|
-
if (fs3__namespace.existsSync(
|
|
493
|
+
if (fs3__namespace.existsSync(path3__namespace.join(dir, "next.config.js")) || fs3__namespace.existsSync(path3__namespace.join(dir, "next.config.ts"))) {
|
|
494
494
|
score += 10;
|
|
495
|
-
const file = fs3__namespace.existsSync(
|
|
495
|
+
const file = fs3__namespace.existsSync(path3__namespace.join(dir, "next.config.js")) ? "next.config.js" : "next.config.ts";
|
|
496
496
|
signals.push(`${file} found`);
|
|
497
497
|
}
|
|
498
|
-
if (fs3__namespace.existsSync(
|
|
498
|
+
if (fs3__namespace.existsSync(path3__namespace.join(dir, "vite.config.ts")) || fs3__namespace.existsSync(path3__namespace.join(dir, "vite.config.js"))) {
|
|
499
499
|
score += 10;
|
|
500
|
-
const file = fs3__namespace.existsSync(
|
|
500
|
+
const file = fs3__namespace.existsSync(path3__namespace.join(dir, "vite.config.ts")) ? "vite.config.ts" : "vite.config.js";
|
|
501
501
|
signals.push(`${file} found`);
|
|
502
502
|
}
|
|
503
503
|
const pkg = readPackageJson(dir);
|
|
@@ -512,19 +512,19 @@ function scoreDir(dir, cwd2) {
|
|
|
512
512
|
signals.push("react in devDependencies");
|
|
513
513
|
}
|
|
514
514
|
}
|
|
515
|
-
if (
|
|
515
|
+
if (path3__namespace.resolve(dir) === path3__namespace.resolve(cwd2)) {
|
|
516
516
|
score += 2;
|
|
517
517
|
signals.push("current working directory");
|
|
518
518
|
}
|
|
519
519
|
if (score === 0) return null;
|
|
520
520
|
return {
|
|
521
|
-
dir:
|
|
521
|
+
dir: path3__namespace.resolve(dir),
|
|
522
522
|
score,
|
|
523
523
|
signals
|
|
524
524
|
};
|
|
525
525
|
}
|
|
526
526
|
function walk(dir, cwd2, currentDepth, maxDepth, results) {
|
|
527
|
-
const absDir =
|
|
527
|
+
const absDir = path3__namespace.resolve(dir);
|
|
528
528
|
const candidate = scoreDir(absDir, cwd2);
|
|
529
529
|
if (candidate && !results.has(absDir)) {
|
|
530
530
|
results.set(absDir, candidate);
|
|
@@ -539,7 +539,7 @@ function walk(dir, cwd2, currentDepth, maxDepth, results) {
|
|
|
539
539
|
for (const entry of entries) {
|
|
540
540
|
if (!entry.isDirectory()) continue;
|
|
541
541
|
if (EXCLUDED_DIRS.has(entry.name)) continue;
|
|
542
|
-
walk(
|
|
542
|
+
walk(path3__namespace.join(absDir, entry.name), cwd2, currentDepth + 1, maxDepth, results);
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
545
|
function scoreCandidates(dir) {
|
|
@@ -553,7 +553,7 @@ async function scanForFrontendDir(dir) {
|
|
|
553
553
|
}
|
|
554
554
|
async function findSchema(startDir, explicitPath) {
|
|
555
555
|
if (explicitPath !== void 0) {
|
|
556
|
-
const resolved =
|
|
556
|
+
const resolved = path3__namespace.resolve(explicitPath);
|
|
557
557
|
if (!fs3__namespace.existsSync(resolved)) {
|
|
558
558
|
throw new Error(
|
|
559
559
|
`[omni-rest] Schema file not found at the specified path: "${resolved}"
|
|
@@ -562,18 +562,18 @@ Please check that the path is correct and the file is readable.`
|
|
|
562
562
|
}
|
|
563
563
|
return resolved;
|
|
564
564
|
}
|
|
565
|
-
let current =
|
|
565
|
+
let current = path3__namespace.resolve(startDir);
|
|
566
566
|
while (true) {
|
|
567
567
|
const candidates = [
|
|
568
|
-
|
|
569
|
-
|
|
568
|
+
path3__namespace.join(current, "prisma", "schema.prisma"),
|
|
569
|
+
path3__namespace.join(current, "schema.prisma")
|
|
570
570
|
];
|
|
571
571
|
for (const candidate of candidates) {
|
|
572
572
|
if (fs3__namespace.existsSync(candidate)) {
|
|
573
573
|
return candidate;
|
|
574
574
|
}
|
|
575
575
|
}
|
|
576
|
-
const parent =
|
|
576
|
+
const parent = path3__namespace.dirname(current);
|
|
577
577
|
if (parent === current) {
|
|
578
578
|
throw new Error(
|
|
579
579
|
`[omni-rest] Could not find "schema.prisma" by walking up from "${startDir}".
|
|
@@ -589,8 +589,8 @@ async function loadDMMF(frontendDir, schemaPath) {
|
|
|
589
589
|
const schemaContent = fs3__namespace.readFileSync(schemaPath, "utf-8");
|
|
590
590
|
const outputMatch = schemaContent.match(/output\s*=\s*["']([^"']+)["']/);
|
|
591
591
|
if (outputMatch) {
|
|
592
|
-
const schemaDir =
|
|
593
|
-
const customOutput =
|
|
592
|
+
const schemaDir = path3__namespace.dirname(schemaPath);
|
|
593
|
+
const customOutput = path3__namespace.resolve(schemaDir, outputMatch[1]);
|
|
594
594
|
if (fs3__namespace.existsSync(customOutput)) {
|
|
595
595
|
clientPath = customOutput;
|
|
596
596
|
}
|
|
@@ -598,7 +598,7 @@ async function loadDMMF(frontendDir, schemaPath) {
|
|
|
598
598
|
} catch {
|
|
599
599
|
}
|
|
600
600
|
if (!clientPath) {
|
|
601
|
-
clientPath =
|
|
601
|
+
clientPath = path3__namespace.join(frontendDir, "node_modules", "@prisma", "client");
|
|
602
602
|
}
|
|
603
603
|
let prismaClientModule;
|
|
604
604
|
try {
|
|
@@ -631,12 +631,35 @@ Please run "npx prisma generate" to regenerate the Prisma client, then try again
|
|
|
631
631
|
};
|
|
632
632
|
return getModels(syntheticPrisma);
|
|
633
633
|
}
|
|
634
|
+
function detectProjectStructure(frontendDir) {
|
|
635
|
+
const hasSrc = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "src"));
|
|
636
|
+
const hasApp = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "app"));
|
|
637
|
+
const hasSrcApp = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "src", "app"));
|
|
638
|
+
const hasPages = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "pages"));
|
|
639
|
+
const hasSrcPages = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "src", "pages"));
|
|
640
|
+
const usesAppRouter = hasApp || hasSrcApp;
|
|
641
|
+
const usesPagesRouter = hasPages || hasSrcPages;
|
|
642
|
+
const basePath = hasSrc ? "src" : ".";
|
|
643
|
+
let appPath = null;
|
|
644
|
+
if (hasSrcApp) {
|
|
645
|
+
appPath = path3__namespace.join(frontendDir, "src", "app");
|
|
646
|
+
} else if (hasApp) {
|
|
647
|
+
appPath = path3__namespace.join(frontendDir, "app");
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
usesSrc: hasSrc,
|
|
651
|
+
usesAppRouter,
|
|
652
|
+
usesPagesRouter,
|
|
653
|
+
basePath,
|
|
654
|
+
appPath
|
|
655
|
+
};
|
|
656
|
+
}
|
|
634
657
|
function detectFramework(frontendDir) {
|
|
635
|
-
const hasNextConfig = fs3__namespace.existsSync(
|
|
658
|
+
const hasNextConfig = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "next.config.js")) || fs3__namespace.existsSync(path3__namespace.join(frontendDir, "next.config.ts"));
|
|
636
659
|
if (hasNextConfig) return "nextjs";
|
|
637
|
-
const hasViteConfig = fs3__namespace.existsSync(
|
|
660
|
+
const hasViteConfig = fs3__namespace.existsSync(path3__namespace.join(frontendDir, "vite.config.ts")) || fs3__namespace.existsSync(path3__namespace.join(frontendDir, "vite.config.js"));
|
|
638
661
|
if (hasViteConfig) return "vite-react";
|
|
639
|
-
const pkgPath =
|
|
662
|
+
const pkgPath = path3__namespace.join(frontendDir, "package.json");
|
|
640
663
|
if (fs3__namespace.existsSync(pkgPath)) {
|
|
641
664
|
try {
|
|
642
665
|
const pkg = JSON.parse(fs3__namespace.readFileSync(pkgPath, "utf-8"));
|
|
@@ -676,11 +699,11 @@ function parseEnvFile(filePath) {
|
|
|
676
699
|
return result;
|
|
677
700
|
}
|
|
678
701
|
function resolveBaseUrl(frontendDir) {
|
|
679
|
-
const envLocal = parseEnvFile(
|
|
702
|
+
const envLocal = parseEnvFile(path3__namespace.join(frontendDir, ".env.local"));
|
|
680
703
|
if (envLocal.has("NEXT_PUBLIC_API_URL")) {
|
|
681
704
|
return envLocal.get("NEXT_PUBLIC_API_URL");
|
|
682
705
|
}
|
|
683
|
-
const env = parseEnvFile(
|
|
706
|
+
const env = parseEnvFile(path3__namespace.join(frontendDir, ".env"));
|
|
684
707
|
if (env.has("NEXT_PUBLIC_API_URL")) {
|
|
685
708
|
return env.get("NEXT_PUBLIC_API_URL");
|
|
686
709
|
}
|
|
@@ -691,16 +714,16 @@ function resolveBaseUrl(frontendDir) {
|
|
|
691
714
|
}
|
|
692
715
|
function resolveOutputDir(frontendDir, framework, outFlag) {
|
|
693
716
|
if (outFlag) {
|
|
694
|
-
return
|
|
717
|
+
return path3__namespace.resolve(frontendDir, outFlag);
|
|
695
718
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (fs3__namespace.existsSync(appDir) && !fs3__namespace.existsSync(srcDir)) {
|
|
700
|
-
return path__namespace.resolve(frontendDir, "app");
|
|
701
|
-
}
|
|
719
|
+
const structure = detectProjectStructure(frontendDir);
|
|
720
|
+
if (structure.usesSrc) {
|
|
721
|
+
return path3__namespace.resolve(frontendDir, "src");
|
|
702
722
|
}
|
|
703
|
-
|
|
723
|
+
if (framework === "nextjs" && structure.usesAppRouter) {
|
|
724
|
+
return path3__namespace.resolve(frontendDir, "app");
|
|
725
|
+
}
|
|
726
|
+
return path3__namespace.resolve(frontendDir, "src");
|
|
704
727
|
}
|
|
705
728
|
var BASE_PACKAGES = [
|
|
706
729
|
"@tanstack/react-query",
|
|
@@ -718,7 +741,7 @@ function checkDependencies(frontendDir, framework) {
|
|
|
718
741
|
...BASE_PACKAGES,
|
|
719
742
|
...FRAMEWORK_PACKAGES[framework] ?? []
|
|
720
743
|
];
|
|
721
|
-
const pkgPath =
|
|
744
|
+
const pkgPath = path3__namespace.join(frontendDir, "package.json");
|
|
722
745
|
let installed;
|
|
723
746
|
try {
|
|
724
747
|
const pkg = JSON.parse(fs3__namespace.readFileSync(pkgPath, "utf-8"));
|
|
@@ -1248,6 +1271,74 @@ function generateFormFile(config, modelConfig) {
|
|
|
1248
1271
|
lines.push(``);
|
|
1249
1272
|
return lines.join("\n");
|
|
1250
1273
|
}
|
|
1274
|
+
|
|
1275
|
+
// src/frontend/codegen/page.ts
|
|
1276
|
+
function generatePageFile(config, modelConfig) {
|
|
1277
|
+
const { model } = modelConfig;
|
|
1278
|
+
const { name } = model;
|
|
1279
|
+
const modelLower = name.charAt(0).toLowerCase() + name.slice(1);
|
|
1280
|
+
const pluralName = name + "s";
|
|
1281
|
+
const lines = [];
|
|
1282
|
+
lines.push(`'use client'`);
|
|
1283
|
+
lines.push(``);
|
|
1284
|
+
lines.push(`import { ${name}Table } from '@/components/${modelLower}/${name}Table'`);
|
|
1285
|
+
lines.push(``);
|
|
1286
|
+
lines.push(`export default function ${pluralName}Page() {`);
|
|
1287
|
+
lines.push(` return (`);
|
|
1288
|
+
lines.push(` <div className="container mx-auto py-10">`);
|
|
1289
|
+
lines.push(` <h1 className="text-3xl font-bold mb-6">${pluralName}</h1>`);
|
|
1290
|
+
lines.push(` <${name}Table />`);
|
|
1291
|
+
lines.push(` </div>`);
|
|
1292
|
+
lines.push(` )`);
|
|
1293
|
+
lines.push(`}`);
|
|
1294
|
+
lines.push(``);
|
|
1295
|
+
return lines.join("\n");
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// src/frontend/codegen/menu.ts
|
|
1299
|
+
function generateMenuData(config) {
|
|
1300
|
+
const { models } = config;
|
|
1301
|
+
const lines = [];
|
|
1302
|
+
lines.push(`/**`);
|
|
1303
|
+
lines.push(` * Auto-generated menu data for omni-rest CRUD pages`);
|
|
1304
|
+
lines.push(` * Generated by omni-rest \u2014 do not edit manually.`);
|
|
1305
|
+
lines.push(` * Re-run after schema changes.`);
|
|
1306
|
+
lines.push(` */`);
|
|
1307
|
+
lines.push(``);
|
|
1308
|
+
lines.push(`export interface MenuItem {`);
|
|
1309
|
+
lines.push(` label: string;`);
|
|
1310
|
+
lines.push(` href: string;`);
|
|
1311
|
+
lines.push(` icon?: string;`);
|
|
1312
|
+
lines.push(`}`);
|
|
1313
|
+
lines.push(``);
|
|
1314
|
+
lines.push(`export const omniRestMenuItems: MenuItem[] = [`);
|
|
1315
|
+
for (const modelConfig of models) {
|
|
1316
|
+
const { name } = modelConfig.model;
|
|
1317
|
+
const pluralName = name + "s";
|
|
1318
|
+
const route = `/${name.toLowerCase()}s`;
|
|
1319
|
+
lines.push(` {`);
|
|
1320
|
+
lines.push(` label: '${pluralName}',`);
|
|
1321
|
+
lines.push(` href: '${route}',`);
|
|
1322
|
+
lines.push(` },`);
|
|
1323
|
+
}
|
|
1324
|
+
lines.push(`];`);
|
|
1325
|
+
lines.push(``);
|
|
1326
|
+
lines.push(`/**`);
|
|
1327
|
+
lines.push(` * Get a menu item by its label`);
|
|
1328
|
+
lines.push(` */`);
|
|
1329
|
+
lines.push(`export function getMenuItemByLabel(label: string): MenuItem | undefined {`);
|
|
1330
|
+
lines.push(` return omniRestMenuItems.find(item => item.label === label);`);
|
|
1331
|
+
lines.push(`}`);
|
|
1332
|
+
lines.push(``);
|
|
1333
|
+
lines.push(`/**`);
|
|
1334
|
+
lines.push(` * Get a menu item by its href`);
|
|
1335
|
+
lines.push(` */`);
|
|
1336
|
+
lines.push(`export function getMenuItemByHref(href: string): MenuItem | undefined {`);
|
|
1337
|
+
lines.push(` return omniRestMenuItems.find(item => item.href === href);`);
|
|
1338
|
+
lines.push(`}`);
|
|
1339
|
+
lines.push(``);
|
|
1340
|
+
return lines.join("\n");
|
|
1341
|
+
}
|
|
1251
1342
|
var GREEN = "\x1B[32m";
|
|
1252
1343
|
var YELLOW = "\x1B[33m";
|
|
1253
1344
|
var BLUE = "\x1B[34m";
|
|
@@ -1257,7 +1348,7 @@ async function writeFile(destPath, content) {
|
|
|
1257
1348
|
let existed = false;
|
|
1258
1349
|
try {
|
|
1259
1350
|
existed = fs3__namespace.existsSync(destPath);
|
|
1260
|
-
fs3__namespace.mkdirSync(
|
|
1351
|
+
fs3__namespace.mkdirSync(path3__namespace.dirname(destPath), { recursive: true });
|
|
1261
1352
|
fs3__namespace.writeFileSync(destPath, content, "utf8");
|
|
1262
1353
|
return { path: destPath, status: existed ? "overwritten" : "created" };
|
|
1263
1354
|
} catch (err) {
|
|
@@ -1271,14 +1362,14 @@ var BASE_COMPONENTS = [
|
|
|
1271
1362
|
async function copyBaseComponents(outputDir, packageRoot) {
|
|
1272
1363
|
const results = [];
|
|
1273
1364
|
for (const { src, dest } of BASE_COMPONENTS) {
|
|
1274
|
-
const srcPath =
|
|
1275
|
-
const destPath =
|
|
1365
|
+
const srcPath = path3__namespace.join(packageRoot, src);
|
|
1366
|
+
const destPath = path3__namespace.join(outputDir, dest);
|
|
1276
1367
|
if (fs3__namespace.existsSync(destPath)) {
|
|
1277
1368
|
results.push({ path: destPath, status: "skipped" });
|
|
1278
1369
|
continue;
|
|
1279
1370
|
}
|
|
1280
1371
|
try {
|
|
1281
|
-
fs3__namespace.mkdirSync(
|
|
1372
|
+
fs3__namespace.mkdirSync(path3__namespace.dirname(destPath), { recursive: true });
|
|
1282
1373
|
fs3__namespace.copyFileSync(srcPath, destPath);
|
|
1283
1374
|
results.push({ path: destPath, status: "created" });
|
|
1284
1375
|
} catch (err) {
|
|
@@ -1327,27 +1418,42 @@ var COLORS = {
|
|
|
1327
1418
|
bold: (s) => `\x1B[1m${s}\x1B[0m`
|
|
1328
1419
|
};
|
|
1329
1420
|
async function generateAll(config) {
|
|
1330
|
-
const { outputDir, models } = config;
|
|
1331
|
-
const
|
|
1421
|
+
const { outputDir, models, framework, frontendDir } = config;
|
|
1422
|
+
const generatePages = config.generatePages ?? framework === "nextjs";
|
|
1423
|
+
const generateMenu = config.generateMenu ?? true;
|
|
1424
|
+
const routeGroup = config.routeGroup ?? "autogenerated-omni";
|
|
1425
|
+
const packageRoot = path3__namespace.resolve(__dirname, "..");
|
|
1332
1426
|
const results = [];
|
|
1427
|
+
const structure = detectProjectStructure(frontendDir);
|
|
1333
1428
|
for (const modelConfig of models) {
|
|
1334
1429
|
const { name } = modelConfig.model;
|
|
1335
1430
|
const modelLower = name.charAt(0).toLowerCase() + name.slice(1);
|
|
1336
1431
|
const hookContent = generateHookFile(config, modelConfig);
|
|
1337
|
-
const hookPath =
|
|
1432
|
+
const hookPath = path3__namespace.join(outputDir, "hooks", `use${name}.ts`);
|
|
1338
1433
|
results.push(await writeFile(hookPath, hookContent));
|
|
1339
1434
|
const columnsContent = generateColumnsFile(config, modelConfig);
|
|
1340
|
-
const columnsPath =
|
|
1435
|
+
const columnsPath = path3__namespace.join(outputDir, "components", modelLower, `${name}Columns.tsx`);
|
|
1341
1436
|
results.push(await writeFile(columnsPath, columnsContent));
|
|
1342
1437
|
const tableContent = generateTableFile(config, modelConfig);
|
|
1343
|
-
const tablePath =
|
|
1438
|
+
const tablePath = path3__namespace.join(outputDir, "components", modelLower, `${name}Table.tsx`);
|
|
1344
1439
|
results.push(await writeFile(tablePath, tableContent));
|
|
1345
1440
|
const formContent = generateFormFile(config, modelConfig);
|
|
1346
|
-
const formPath =
|
|
1441
|
+
const formPath = path3__namespace.join(outputDir, "components", modelLower, `${name}Form.tsx`);
|
|
1347
1442
|
results.push(await writeFile(formPath, formContent));
|
|
1443
|
+
if (generatePages && framework === "nextjs" && structure.usesAppRouter && structure.appPath) {
|
|
1444
|
+
const pageContent = generatePageFile(config, modelConfig);
|
|
1445
|
+
const pluralLower = name.toLowerCase() + "s";
|
|
1446
|
+
const pagePath = path3__namespace.join(structure.appPath, `(${routeGroup})`, pluralLower, "page.tsx");
|
|
1447
|
+
results.push(await writeFile(pagePath, pageContent));
|
|
1448
|
+
}
|
|
1348
1449
|
}
|
|
1349
1450
|
const baseResults = await copyBaseComponents(outputDir, packageRoot);
|
|
1350
1451
|
results.push(...baseResults);
|
|
1452
|
+
if (generateMenu) {
|
|
1453
|
+
const menuContent = generateMenuData(config);
|
|
1454
|
+
const menuPath = path3__namespace.join(outputDir, "lib", "menu-data.ts");
|
|
1455
|
+
results.push(await writeFile(menuPath, menuContent));
|
|
1456
|
+
}
|
|
1351
1457
|
printSummary(results);
|
|
1352
1458
|
return results;
|
|
1353
1459
|
}
|
|
@@ -1362,6 +1468,9 @@ var HELP_TEXT = `
|
|
|
1362
1468
|
--autopilot Skip all prompts, use defaults
|
|
1363
1469
|
--no-bulk Disable bulk delete hooks and wiring
|
|
1364
1470
|
--no-optimistic Disable optimistic update patterns
|
|
1471
|
+
--no-pages Disable Next.js page generation (default: enabled for Next.js)
|
|
1472
|
+
--no-menu Disable menu-data.ts generation (default: enabled)
|
|
1473
|
+
--route-group <name> Route group name for Next.js pages (default: autogenerated-omni)
|
|
1365
1474
|
--stale-time <ms> useQuery staleTime (default: 30000)
|
|
1366
1475
|
--gc-time <ms> useQuery gcTime (default: 300000)
|
|
1367
1476
|
--steps <mode> Multi-step form mode: auto | always | never (default: auto)
|
|
@@ -1384,6 +1493,9 @@ async function run(argv) {
|
|
|
1384
1493
|
let autopilot = false;
|
|
1385
1494
|
let noBulk = false;
|
|
1386
1495
|
let noOptimistic = false;
|
|
1496
|
+
let generatePages = true;
|
|
1497
|
+
let generateMenu = true;
|
|
1498
|
+
let routeGroup = "autogenerated-omni";
|
|
1387
1499
|
let staleTime = 3e4;
|
|
1388
1500
|
let gcTime = 3e5;
|
|
1389
1501
|
let stepsFlag = "auto";
|
|
@@ -1414,6 +1526,15 @@ async function run(argv) {
|
|
|
1414
1526
|
case "--no-optimistic":
|
|
1415
1527
|
noOptimistic = true;
|
|
1416
1528
|
break;
|
|
1529
|
+
case "--no-pages":
|
|
1530
|
+
generatePages = false;
|
|
1531
|
+
break;
|
|
1532
|
+
case "--no-menu":
|
|
1533
|
+
generateMenu = false;
|
|
1534
|
+
break;
|
|
1535
|
+
case "--route-group":
|
|
1536
|
+
routeGroup = argv[++i];
|
|
1537
|
+
break;
|
|
1417
1538
|
case "--stale-time":
|
|
1418
1539
|
staleTime = parseInt(argv[++i], 10) || 3e4;
|
|
1419
1540
|
break;
|
|
@@ -1538,13 +1659,18 @@ async function run(argv) {
|
|
|
1538
1659
|
};
|
|
1539
1660
|
const modelConfigs = await buildConfig(allModels, flags);
|
|
1540
1661
|
const generatorConfig = {
|
|
1662
|
+
frontendDir,
|
|
1541
1663
|
framework,
|
|
1542
1664
|
baseUrl,
|
|
1543
1665
|
outputDir,
|
|
1544
1666
|
models: modelConfigs,
|
|
1545
1667
|
staleTime,
|
|
1546
1668
|
gcTime,
|
|
1547
|
-
noOptimistic
|
|
1669
|
+
noOptimistic,
|
|
1670
|
+
generatePages,
|
|
1671
|
+
generateMenu,
|
|
1672
|
+
routeGroup
|
|
1673
|
+
};
|
|
1548
1674
|
await generateAll(generatorConfig);
|
|
1549
1675
|
console.log(COLORS.bold("\n Done!\n"));
|
|
1550
1676
|
}
|
|
@@ -1562,8 +1688,8 @@ var COLORS2 = {
|
|
|
1562
1688
|
bold: (s) => `\x1B[1m${s}\x1B[0m`
|
|
1563
1689
|
};
|
|
1564
1690
|
function write(filePath, content) {
|
|
1565
|
-
const abs =
|
|
1566
|
-
fs3__namespace.default.mkdirSync(
|
|
1691
|
+
const abs = path3__namespace.default.resolve(cwd, filePath);
|
|
1692
|
+
fs3__namespace.default.mkdirSync(path3__namespace.default.dirname(abs), { recursive: true });
|
|
1567
1693
|
fs3__namespace.default.writeFileSync(abs, content, "utf-8");
|
|
1568
1694
|
console.log(COLORS2.green(` \u2713 Written: ${filePath}`));
|
|
1569
1695
|
}
|
|
@@ -1588,8 +1714,8 @@ function createPrismaClient() {
|
|
|
1588
1714
|
}
|
|
1589
1715
|
function tryLoadFromSchemaOutput() {
|
|
1590
1716
|
const schemaPaths = [
|
|
1591
|
-
|
|
1592
|
-
|
|
1717
|
+
path3__namespace.default.resolve(cwd, "prisma/schema.prisma"),
|
|
1718
|
+
path3__namespace.default.resolve(cwd, "schema.prisma")
|
|
1593
1719
|
];
|
|
1594
1720
|
for (const schemaPath of schemaPaths) {
|
|
1595
1721
|
if (!fs3__namespace.default.existsSync(schemaPath)) continue;
|
|
@@ -1597,8 +1723,8 @@ function tryLoadFromSchemaOutput() {
|
|
|
1597
1723
|
const schema = fs3__namespace.default.readFileSync(schemaPath, "utf-8");
|
|
1598
1724
|
const match = schema.match(/output\s*=\s*["']([^"']+)["']/);
|
|
1599
1725
|
if (!match) continue;
|
|
1600
|
-
const outputDir =
|
|
1601
|
-
const indexPath =
|
|
1726
|
+
const outputDir = path3__namespace.default.resolve(path3__namespace.default.dirname(schemaPath), match[1]);
|
|
1727
|
+
const indexPath = path3__namespace.default.join(outputDir, "index.js");
|
|
1602
1728
|
const result = extractRuntimeDataModelFromFile(indexPath);
|
|
1603
1729
|
if (result) return result;
|
|
1604
1730
|
} catch {
|
|
@@ -1609,8 +1735,8 @@ function tryLoadFromSchemaOutput() {
|
|
|
1609
1735
|
}
|
|
1610
1736
|
function tryLoadFromStandardOutput() {
|
|
1611
1737
|
const candidates = [
|
|
1612
|
-
|
|
1613
|
-
|
|
1738
|
+
path3__namespace.default.resolve(cwd, "node_modules/.prisma/client/index.js"),
|
|
1739
|
+
path3__namespace.default.resolve(cwd, "node_modules/@prisma/client/index.js")
|
|
1614
1740
|
];
|
|
1615
1741
|
for (const clientPath of candidates) {
|
|
1616
1742
|
const result = extractRuntimeDataModelFromFile(clientPath);
|
|
@@ -1707,7 +1833,7 @@ async function run2() {
|
|
|
1707
1833
|
function getPackageName() {
|
|
1708
1834
|
try {
|
|
1709
1835
|
const pkg = JSON.parse(
|
|
1710
|
-
fs3__namespace.default.readFileSync(
|
|
1836
|
+
fs3__namespace.default.readFileSync(path3__namespace.default.resolve(cwd, "package.json"), "utf-8")
|
|
1711
1837
|
);
|
|
1712
1838
|
return pkg.name ?? "My API";
|
|
1713
1839
|
} catch {
|
|
@@ -1717,7 +1843,7 @@ function getPackageName() {
|
|
|
1717
1843
|
function getPackageVersion() {
|
|
1718
1844
|
try {
|
|
1719
1845
|
const pkg = JSON.parse(
|
|
1720
|
-
fs3__namespace.default.readFileSync(
|
|
1846
|
+
fs3__namespace.default.readFileSync(path3__namespace.default.resolve(cwd, "package.json"), "utf-8")
|
|
1721
1847
|
);
|
|
1722
1848
|
return pkg.version ?? "1.0.0";
|
|
1723
1849
|
} catch {
|