@squadbase/vantage 0.2.2 → 0.2.3
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/{chunk-UHZ7XSAN.js → chunk-3QKPNWKJ.js} +3 -3
- package/dist/{chunk-UHZ7XSAN.js.map → chunk-3QKPNWKJ.js.map} +1 -1
- package/dist/cli.js +306 -28
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/vite/index.js +1 -1
- package/docs/en/changelog.md +24 -0
- package/docs/en/cli-reference.md +52 -1
- package/docs/ja/changelog.md +22 -0
- package/docs/ja/cli-reference.md +52 -1
- package/package.json +1 -1
- package/skills/vantage-add-feature/SKILL.md +12 -2
- package/templates/AGENTS.md +4 -2
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { PAGE_EXTENSIONS, scanProject, vantagePlugin, generateArtifacts, VANTAGE_DIR, MANIFEST_SCHEMA_VERSION, FORBIDDEN_FILES, API_METHODS, PUBLIC_ENV_PREFIX } from './chunk-
|
|
2
|
+
import { PAGE_EXTENSIONS, scanProject, vantagePlugin, generateArtifacts, VANTAGE_DIR, MANIFEST_SCHEMA_VERSION, FORBIDDEN_FILES, API_METHODS, PUBLIC_ENV_PREFIX, extractPageMeta } from './chunk-3QKPNWKJ.js';
|
|
3
3
|
import './chunk-46QI6GFC.js';
|
|
4
4
|
import './chunk-B7LLBNLV.js';
|
|
5
5
|
import path2 from 'path';
|
|
@@ -12,7 +12,21 @@ import { fileURLToPath } from 'url';
|
|
|
12
12
|
import { spawn } from 'child_process';
|
|
13
13
|
|
|
14
14
|
// @squadbase/vantage — generated build. Do not edit.
|
|
15
|
-
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
15
|
+
var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
16
|
+
"json",
|
|
17
|
+
"help",
|
|
18
|
+
"force",
|
|
19
|
+
"verbose",
|
|
20
|
+
"version",
|
|
21
|
+
"all",
|
|
22
|
+
"list",
|
|
23
|
+
"regex",
|
|
24
|
+
"pages",
|
|
25
|
+
"apis",
|
|
26
|
+
"detail",
|
|
27
|
+
"h",
|
|
28
|
+
"v"
|
|
29
|
+
]);
|
|
16
30
|
function parseArgs(argv) {
|
|
17
31
|
const positionals = [];
|
|
18
32
|
const flags = {};
|
|
@@ -358,10 +372,202 @@ async function add(root, args) {
|
|
|
358
372
|
log.error(`Unknown add target "${kind}". Use one of: page, api, ui, block, skill, agents.`);
|
|
359
373
|
return 1;
|
|
360
374
|
}
|
|
361
|
-
|
|
375
|
+
|
|
376
|
+
// src/core/source.ts
|
|
362
377
|
function stripComments(src) {
|
|
363
378
|
return src.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'`\\])\/\/[^\n]*/g, "$1");
|
|
364
379
|
}
|
|
380
|
+
var OPENERS = { "(": ")", "[": "]", "{": "}" };
|
|
381
|
+
function readBracketBody(src, openIndex) {
|
|
382
|
+
const open = src[openIndex];
|
|
383
|
+
if (!open || !OPENERS[open]) return null;
|
|
384
|
+
let depth = 0;
|
|
385
|
+
let quote = null;
|
|
386
|
+
for (let i = openIndex; i < src.length; i++) {
|
|
387
|
+
const c = src[i];
|
|
388
|
+
if (quote) {
|
|
389
|
+
if (c === "\\") i++;
|
|
390
|
+
else if (c === quote) quote = null;
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
394
|
+
quote = c;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (OPENERS[c]) depth++;
|
|
398
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
399
|
+
if (--depth === 0) return src.slice(openIndex + 1, i);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
function splitTopLevel(body) {
|
|
405
|
+
const parts = [];
|
|
406
|
+
let depth = 0;
|
|
407
|
+
let quote = null;
|
|
408
|
+
let start = 0;
|
|
409
|
+
for (let i = 0; i < body.length; i++) {
|
|
410
|
+
const c = body[i];
|
|
411
|
+
if (quote) {
|
|
412
|
+
if (c === "\\") i++;
|
|
413
|
+
else if (c === quote) quote = null;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
417
|
+
quote = c;
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
if (OPENERS[c]) depth++;
|
|
421
|
+
else if (c === ")" || c === "]" || c === "}") depth--;
|
|
422
|
+
else if (c === "," && depth === 0) {
|
|
423
|
+
parts.push(body.slice(start, i));
|
|
424
|
+
start = i + 1;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
parts.push(body.slice(start));
|
|
428
|
+
return parts.map((p) => p.trim()).filter(Boolean);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// src/core/route-spec.ts
|
|
432
|
+
function detectApiMethods(src) {
|
|
433
|
+
return API_METHODS.filter(
|
|
434
|
+
(m) => new RegExp(`export\\s+(async\\s+)?(function|const|let|var)\\s+${m}\\b`).test(src) || new RegExp(`export\\s*\\{[^}]*\\b${m}\\b[^}]*\\}`).test(src)
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
function methodRegions(src) {
|
|
438
|
+
const re = new RegExp(
|
|
439
|
+
`export\\s+(?:async\\s+)?(?:function|const|let|var)\\s+(${API_METHODS.join("|")})\\b`,
|
|
440
|
+
"g"
|
|
441
|
+
);
|
|
442
|
+
const decls = [];
|
|
443
|
+
let m;
|
|
444
|
+
while (m = re.exec(src)) decls.push({ method: m[1], index: m.index });
|
|
445
|
+
const regions = /* @__PURE__ */ new Map();
|
|
446
|
+
decls.forEach((d, i) => {
|
|
447
|
+
regions.set(d.method, src.slice(d.index, decls[i + 1]?.index ?? src.length));
|
|
448
|
+
});
|
|
449
|
+
for (const method of detectApiMethods(src)) {
|
|
450
|
+
if (!regions.has(method)) regions.set(method, src);
|
|
451
|
+
}
|
|
452
|
+
return regions;
|
|
453
|
+
}
|
|
454
|
+
function objectKeys(expr) {
|
|
455
|
+
const trimmed = expr.trim();
|
|
456
|
+
if (!trimmed.startsWith("{")) return void 0;
|
|
457
|
+
const body = readBracketBody(trimmed, 0);
|
|
458
|
+
if (body == null) return void 0;
|
|
459
|
+
const keys = [];
|
|
460
|
+
for (const part of splitTopLevel(body)) {
|
|
461
|
+
if (part.startsWith("...")) {
|
|
462
|
+
keys.push("\u2026");
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
const name = part.match(/^["'`]?([A-Za-z0-9_$]+)/);
|
|
466
|
+
if (name) keys.push(name[1]);
|
|
467
|
+
}
|
|
468
|
+
return keys.length ? keys : void 0;
|
|
469
|
+
}
|
|
470
|
+
function initStatus(init) {
|
|
471
|
+
const m = init?.match(/\bstatus\s*:\s*(\d{3})\b/);
|
|
472
|
+
return m ? Number(m[1]) : void 0;
|
|
473
|
+
}
|
|
474
|
+
function initContentType(init) {
|
|
475
|
+
const m = init?.match(/["']?content-type["']?\s*:\s*["']([^"';]+)/i);
|
|
476
|
+
return m ? m[1].trim() : void 0;
|
|
477
|
+
}
|
|
478
|
+
function extractResponses(region) {
|
|
479
|
+
const re = /\bnew\s+Response\s*\(|\bResponse\s*\.\s*json\s*\(|(?<![.\w$])json\s*\(/g;
|
|
480
|
+
const out = [];
|
|
481
|
+
const seen = /* @__PURE__ */ new Set();
|
|
482
|
+
let m;
|
|
483
|
+
while (m = re.exec(region)) {
|
|
484
|
+
const isJson = !m[0].startsWith("new");
|
|
485
|
+
const args = readBracketBody(region, m.index + m[0].length - 1);
|
|
486
|
+
if (args == null) continue;
|
|
487
|
+
const [payload, init] = splitTopLevel(args);
|
|
488
|
+
const contentType = isJson ? "application/json" : initContentType(init) ?? (payload?.startsWith("JSON.stringify") ? "application/json" : void 0);
|
|
489
|
+
const keys = isJson && payload ? objectKeys(payload) : void 0;
|
|
490
|
+
const spec = {
|
|
491
|
+
status: initStatus(init) ?? 200,
|
|
492
|
+
...contentType ? { contentType } : {},
|
|
493
|
+
...keys ? { keys } : {}
|
|
494
|
+
};
|
|
495
|
+
const key = JSON.stringify(spec);
|
|
496
|
+
if (seen.has(key)) continue;
|
|
497
|
+
seen.add(key);
|
|
498
|
+
out.push(spec);
|
|
499
|
+
}
|
|
500
|
+
return out;
|
|
501
|
+
}
|
|
502
|
+
function extractErrors(region) {
|
|
503
|
+
const re = /\bHttpError\s*\(\s*(\d{3})\s*(?:,\s*(?:(["'`])((?:\\.|(?!\2)[\s\S])*)\2))?/g;
|
|
504
|
+
const out = [];
|
|
505
|
+
const seen = /* @__PURE__ */ new Set();
|
|
506
|
+
let m;
|
|
507
|
+
while (m = re.exec(region)) {
|
|
508
|
+
const message = m[3]?.replace(/\\(.)/g, "$1");
|
|
509
|
+
const spec = { status: Number(m[1]), ...message ? { message } : {} };
|
|
510
|
+
const key = JSON.stringify(spec);
|
|
511
|
+
if (seen.has(key)) continue;
|
|
512
|
+
seen.add(key);
|
|
513
|
+
out.push(spec);
|
|
514
|
+
}
|
|
515
|
+
return out;
|
|
516
|
+
}
|
|
517
|
+
function extractQuery(region) {
|
|
518
|
+
const re = /searchParams\s*\.\s*(?:get|getAll|has)\s*\(\s*["'`]([^"'`]+)["'`]/g;
|
|
519
|
+
const out = /* @__PURE__ */ new Set();
|
|
520
|
+
let m;
|
|
521
|
+
while (m = re.exec(region)) out.add(m[1]);
|
|
522
|
+
return [...out];
|
|
523
|
+
}
|
|
524
|
+
function extractBody(region) {
|
|
525
|
+
const read = region.match(/\b(?:request|req)\s*\.\s*(json|formData|text|arrayBuffer|blob)\s*\(/);
|
|
526
|
+
if (!read) return void 0;
|
|
527
|
+
const method = read[1];
|
|
528
|
+
const format = method === "json" || method === "formData" || method === "text" ? method : "binary";
|
|
529
|
+
const destructured = region.match(
|
|
530
|
+
/(?:const|let|var)\s*(\{[\s\S]*?\})\s*=\s*(?:await\s+)?[\w.]*\.json\s*\(/
|
|
531
|
+
);
|
|
532
|
+
const keys = format === "json" && destructured ? objectKeys(destructured[1]) : void 0;
|
|
533
|
+
return { format, ...keys ? { keys } : {} };
|
|
534
|
+
}
|
|
535
|
+
function toParams(segments) {
|
|
536
|
+
const out = [];
|
|
537
|
+
for (const s of segments) {
|
|
538
|
+
if (s.kind === "static") continue;
|
|
539
|
+
out.push({ name: s.name, kind: s.kind });
|
|
540
|
+
}
|
|
541
|
+
return out;
|
|
542
|
+
}
|
|
543
|
+
function extractPageSpec(page) {
|
|
544
|
+
return { params: toParams(page.segments), ...extractPageMeta(page.absFile) };
|
|
545
|
+
}
|
|
546
|
+
function extractApiSpec(api) {
|
|
547
|
+
const params = toParams(api.segments);
|
|
548
|
+
let src;
|
|
549
|
+
try {
|
|
550
|
+
src = stripComments(fs2.readFileSync(api.absFile, "utf8"));
|
|
551
|
+
} catch {
|
|
552
|
+
return { params, methods: [] };
|
|
553
|
+
}
|
|
554
|
+
const regions = methodRegions(src);
|
|
555
|
+
const methods = API_METHODS.filter((m) => regions.has(m)).map((method) => {
|
|
556
|
+
const region = regions.get(method);
|
|
557
|
+
const body = extractBody(region);
|
|
558
|
+
return {
|
|
559
|
+
method,
|
|
560
|
+
query: extractQuery(region),
|
|
561
|
+
...body ? { body } : {},
|
|
562
|
+
responses: extractResponses(region),
|
|
563
|
+
errors: extractErrors(region)
|
|
564
|
+
};
|
|
565
|
+
});
|
|
566
|
+
return { params, methods };
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// src/core/diagnostics.ts
|
|
570
|
+
var ALLOWED_ENV_KEYS = /* @__PURE__ */ new Set(["MODE", "DEV", "PROD", "SSR", "BASE_URL", "PUBLIC_"]);
|
|
365
571
|
function hasDefaultExport(src) {
|
|
366
572
|
return /\bexport\s+default\b/.test(src) || /\bexport\s*\{[^}]*\bas\s+default\b[^}]*\}/.test(src) || /\bexport\s*\{[^}]*\bdefault\b[^}]*\}\s*from\b/.test(src);
|
|
367
573
|
}
|
|
@@ -472,9 +678,7 @@ function checkApiExports(root, model) {
|
|
|
472
678
|
} catch {
|
|
473
679
|
continue;
|
|
474
680
|
}
|
|
475
|
-
const exported =
|
|
476
|
-
(m) => new RegExp(`export\\s+(async\\s+)?(function|const|let|var)\\s+${m}\\b`).test(src) || new RegExp(`export\\s*\\{[^}]*\\b${m}\\b[^}]*\\}`).test(src)
|
|
477
|
-
);
|
|
681
|
+
const exported = detectApiMethods(src);
|
|
478
682
|
if (exported.length === 0) {
|
|
479
683
|
const lower = ["get", "post", "put", "patch", "delete", "options"].filter(
|
|
480
684
|
(m) => new RegExp(`export\\s+(async\\s+)?function\\s+${m}\\b`).test(src)
|
|
@@ -941,39 +1145,110 @@ async function preview(root, args) {
|
|
|
941
1145
|
return new Promise(() => {
|
|
942
1146
|
});
|
|
943
1147
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
1148
|
+
var ROUTE_COLUMN = 28;
|
|
1149
|
+
var LABEL_COLUMN = 9;
|
|
1150
|
+
function detailLine(indent, label, value) {
|
|
1151
|
+
console.log(`${indent}${pc3.dim(label.padEnd(LABEL_COLUMN))}${value}`);
|
|
1152
|
+
}
|
|
1153
|
+
function formatParams(params) {
|
|
1154
|
+
return params.map((p) => p.kind === "catchall" ? `*${p.name}` : `:${p.name}`).join(", ");
|
|
1155
|
+
}
|
|
1156
|
+
function formatKeys(keys) {
|
|
1157
|
+
return keys?.length ? ` { ${keys.join(", ")} }` : "";
|
|
1158
|
+
}
|
|
1159
|
+
function printPageSpec(spec) {
|
|
1160
|
+
const indent = " ";
|
|
1161
|
+
if (spec.title) detailLine(indent, "title", spec.title);
|
|
1162
|
+
if (spec.navLabel) detailLine(indent, "nav", spec.navLabel);
|
|
1163
|
+
if (spec.description) detailLine(indent, "desc", spec.description);
|
|
1164
|
+
if (spec.params.length) detailLine(indent, "params", formatParams(spec.params));
|
|
1165
|
+
}
|
|
1166
|
+
function printApiMethodSpec(method, params) {
|
|
1167
|
+
const indent = " ";
|
|
1168
|
+
console.log(` ${pc3.bold(method.method)}`);
|
|
1169
|
+
if (params.length) detailLine(indent, "path", formatParams(params));
|
|
1170
|
+
if (method.query.length) detailLine(indent, "query", method.query.join(", "));
|
|
1171
|
+
if (method.body) detailLine(indent, "body", method.body.format + formatKeys(method.body.keys));
|
|
1172
|
+
for (const res of method.responses) {
|
|
1173
|
+
const parts = [String(res.status), res.contentType].filter(Boolean).join(" ");
|
|
1174
|
+
detailLine(indent, "response", parts + formatKeys(res.keys));
|
|
1175
|
+
}
|
|
1176
|
+
for (const err of method.errors) {
|
|
1177
|
+
detailLine(indent, "error", `${err.status}${err.message ? ` "${err.message}"` : ""}`);
|
|
956
1178
|
}
|
|
1179
|
+
}
|
|
1180
|
+
function printPages(model, detail) {
|
|
957
1181
|
console.log(pc3.bold("\nPages"));
|
|
958
1182
|
if (model.pages.length === 0) console.log(pc3.dim(" (none)"));
|
|
959
1183
|
for (const p of model.pages) {
|
|
960
|
-
console.log(` ${pc3.green(p.routePath.padEnd(
|
|
1184
|
+
console.log(` ${pc3.green(p.routePath.padEnd(ROUTE_COLUMN))} ${pc3.dim(p.file)}`);
|
|
1185
|
+
if (detail) printPageSpec(extractPageSpec(p));
|
|
961
1186
|
}
|
|
962
1187
|
if (model.layouts.length || model.notFound || model.error) {
|
|
963
1188
|
console.log(pc3.bold("\nSpecial"));
|
|
964
1189
|
for (const l of model.layouts) {
|
|
965
|
-
|
|
1190
|
+
const label = "layout " + (l.dir === "" ? "/" : "/" + l.dir);
|
|
1191
|
+
console.log(` ${pc3.cyan(label.padEnd(ROUTE_COLUMN))} ${pc3.dim(l.file)}`);
|
|
966
1192
|
}
|
|
967
|
-
if (model.notFound) console.log(` ${pc3.cyan("404".padEnd(
|
|
968
|
-
if (model.error) console.log(` ${pc3.cyan("error".padEnd(
|
|
1193
|
+
if (model.notFound) console.log(` ${pc3.cyan("404".padEnd(ROUTE_COLUMN))} ${pc3.dim(model.notFound)}`);
|
|
1194
|
+
if (model.error) console.log(` ${pc3.cyan("error".padEnd(ROUTE_COLUMN))} ${pc3.dim(model.error)}`);
|
|
969
1195
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1196
|
+
}
|
|
1197
|
+
function printApis(model, detail) {
|
|
1198
|
+
console.log(pc3.bold("\nAPI"));
|
|
1199
|
+
if (!model.hasServer) {
|
|
1200
|
+
console.log(pc3.dim(" (none \u2014 this project has no server/ directory)"));
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
if (model.apis.length === 0) console.log(pc3.dim(" (none)"));
|
|
1204
|
+
for (const a of model.apis) {
|
|
1205
|
+
console.log(` ${pc3.yellow(a.routePath.padEnd(ROUTE_COLUMN))} ${pc3.dim(a.file)}`);
|
|
1206
|
+
if (!detail) continue;
|
|
1207
|
+
const spec = extractApiSpec(a);
|
|
1208
|
+
if (spec.methods.length === 0) console.log(` ${pc3.dim("(no HTTP method handler exported)")}`);
|
|
1209
|
+
for (const method of spec.methods) printApiMethodSpec(method, spec.params);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
function pageJson(p, detail) {
|
|
1213
|
+
return {
|
|
1214
|
+
route: p.routePath,
|
|
1215
|
+
file: p.file,
|
|
1216
|
+
dynamic: p.dynamic,
|
|
1217
|
+
...detail ? { spec: extractPageSpec(p) } : {}
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
function apiJson(a, detail) {
|
|
1221
|
+
return {
|
|
1222
|
+
route: a.routePath,
|
|
1223
|
+
file: a.file,
|
|
1224
|
+
params: a.params,
|
|
1225
|
+
...detail ? { spec: extractApiSpec(a) } : {}
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
async function routes(root, args) {
|
|
1229
|
+
const model = scanProject(root);
|
|
1230
|
+
const onlyPages = Boolean(args.flags.pages);
|
|
1231
|
+
const onlyApis = Boolean(args.flags.apis);
|
|
1232
|
+
const showPages = onlyPages || !onlyApis;
|
|
1233
|
+
const showApis = onlyApis || !onlyPages;
|
|
1234
|
+
const detail = Boolean(args.flags.detail);
|
|
1235
|
+
if (args.flags.json) {
|
|
1236
|
+
const payload = {};
|
|
1237
|
+
if (showPages) {
|
|
1238
|
+
payload.pages = model.pages.map((p) => pageJson(p, detail));
|
|
1239
|
+
payload.layouts = model.layouts.map((l) => ({ dir: l.dir === "" ? "/" : l.dir, file: l.file }));
|
|
1240
|
+
payload.notFound = model.notFound;
|
|
1241
|
+
payload.error = model.error;
|
|
975
1242
|
}
|
|
1243
|
+
if (showApis) {
|
|
1244
|
+
payload.apis = model.apis.map((a) => apiJson(a, detail));
|
|
1245
|
+
payload.hasServer = model.hasServer;
|
|
1246
|
+
}
|
|
1247
|
+
printJson(payload);
|
|
1248
|
+
return 0;
|
|
976
1249
|
}
|
|
1250
|
+
if (showPages) printPages(model, detail);
|
|
1251
|
+
if (showApis && (model.hasServer || onlyApis)) printApis(model, detail);
|
|
977
1252
|
console.log("");
|
|
978
1253
|
return 0;
|
|
979
1254
|
}
|
|
@@ -1322,7 +1597,7 @@ ${pc3.bold("Commands")}
|
|
|
1322
1597
|
build Build client and optional server into dist/
|
|
1323
1598
|
preview Run the production build locally
|
|
1324
1599
|
check Static verification (routes, boundaries, forbidden files)
|
|
1325
|
-
routes Show page and API URL map
|
|
1600
|
+
routes Show page and API URL map (--pages | --apis | --detail)
|
|
1326
1601
|
add <kind> <name> Scaffold a page | api | ui | block | skill | agents
|
|
1327
1602
|
(add skill with no name lists the skills and where they sit)
|
|
1328
1603
|
docs [name] Show the bundled guide and component reference
|
|
@@ -1335,6 +1610,9 @@ ${pc3.bold("Options")}
|
|
|
1335
1610
|
--port <n> Port for dev/preview
|
|
1336
1611
|
--root <dir> Project root (default: cwd)
|
|
1337
1612
|
--force Overwrite when scaffolding
|
|
1613
|
+
--pages Show only page routes (routes)
|
|
1614
|
+
--apis Show only API routes (routes)
|
|
1615
|
+
--detail Add each route's static spec (routes)
|
|
1338
1616
|
--list List pages without showing one (docs)
|
|
1339
1617
|
--lang <ja|en> Documentation language (docs, search, default: ja)
|
|
1340
1618
|
--regex Treat the query as a regular expression (search)
|