@ubean/cli 0.2.2 → 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/dist/cli.js +738 -65
- package/dist/index.d.ts +64 -1
- package/dist/index.js +3 -2
- package/dist/{page-DU64g_Lv.js → page-BRUWKaig.js} +96 -57
- package/dist/scaffold-manifest-TrH6OCX8.js +116 -0
- package/package.json +25 -14
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,45 @@ declare function createFsOps(cwd: string): {
|
|
|
31
31
|
relative: (to: string) => string;
|
|
32
32
|
};
|
|
33
33
|
//#endregion
|
|
34
|
+
//#region src/analyze-lib.d.ts
|
|
35
|
+
interface ManifestChunk {
|
|
36
|
+
file: string;
|
|
37
|
+
isEntry?: boolean;
|
|
38
|
+
isDynamicEntry?: boolean;
|
|
39
|
+
name?: string;
|
|
40
|
+
src?: string;
|
|
41
|
+
}
|
|
42
|
+
interface BundleBudgetEntry {
|
|
43
|
+
file: string;
|
|
44
|
+
bytes: number;
|
|
45
|
+
gzip: number;
|
|
46
|
+
isEntry?: boolean;
|
|
47
|
+
}
|
|
48
|
+
interface BundleBaseline {
|
|
49
|
+
generatedAt: string;
|
|
50
|
+
outDir: string;
|
|
51
|
+
entries: BundleBudgetEntry[];
|
|
52
|
+
totalBytes: number;
|
|
53
|
+
totalGzip: number;
|
|
54
|
+
entryGzip: number;
|
|
55
|
+
}
|
|
56
|
+
declare function readViteManifest(manifestPath: string): Record<string, ManifestChunk>;
|
|
57
|
+
declare function summarizeBundle(outDir: string, manifest: Record<string, ManifestChunk>): BundleBaseline;
|
|
58
|
+
declare function compareBundleBaseline(current: Pick<BundleBaseline, 'totalGzip' | 'entryGzip'>, committed: Pick<BundleBaseline, 'totalGzip' | 'entryGzip'>, options?: {
|
|
59
|
+
maxIncrease?: number;
|
|
60
|
+
}): {
|
|
61
|
+
ok: boolean;
|
|
62
|
+
maxIncrease: number;
|
|
63
|
+
totalRatio: number;
|
|
64
|
+
entryRatio: number;
|
|
65
|
+
messages: string[];
|
|
66
|
+
};
|
|
67
|
+
declare function writeBundleBaseline(filePath: string, baseline: BundleBaseline): void;
|
|
68
|
+
declare function findClientManifest(cwd: string): {
|
|
69
|
+
outDir: string;
|
|
70
|
+
manifestPath: string;
|
|
71
|
+
} | undefined;
|
|
72
|
+
//#endregion
|
|
34
73
|
//#region src/shared/templates.d.ts
|
|
35
74
|
interface TemplateVariables {
|
|
36
75
|
[key: string]: unknown;
|
|
@@ -127,7 +166,31 @@ declare function recoverScaffold(options: {
|
|
|
127
166
|
}): Promise<ScaffoldResult>;
|
|
128
167
|
declare function listScaffoldableFiles(cwd: string, type: ScaffoldType, baseDir?: string): Promise<string[]>;
|
|
129
168
|
//#endregion
|
|
169
|
+
//#region src/scaffold-manifest.d.ts
|
|
170
|
+
declare const SCAFFOLD_CONTRACT_VERSION: 1;
|
|
171
|
+
interface ScaffoldArgManifest {
|
|
172
|
+
name: string;
|
|
173
|
+
required: boolean;
|
|
174
|
+
description: string;
|
|
175
|
+
default?: string;
|
|
176
|
+
}
|
|
177
|
+
interface ScaffoldTypeManifest {
|
|
178
|
+
type: ScaffoldType;
|
|
179
|
+
/** Dedicated CLI command (`ubean api add`, …) or `ubean page add --type`. */
|
|
180
|
+
cli: boolean;
|
|
181
|
+
/** Directory relative to `src/`. */
|
|
182
|
+
baseDir: string;
|
|
183
|
+
extensions: string[];
|
|
184
|
+
args: ScaffoldArgManifest[];
|
|
185
|
+
}
|
|
186
|
+
interface ScaffoldManifest {
|
|
187
|
+
contractVersion: typeof SCAFFOLD_CONTRACT_VERSION;
|
|
188
|
+
types: ScaffoldTypeManifest[];
|
|
189
|
+
}
|
|
190
|
+
/** Machine-readable scaffold catalog for studio / IDE plugins (RM-S01). */
|
|
191
|
+
declare function getScaffoldManifest(): ScaffoldManifest;
|
|
192
|
+
//#endregion
|
|
130
193
|
//#region src/index.d.ts
|
|
131
194
|
type FsOps = ReturnType<typeof createFsOps>;
|
|
132
195
|
//#endregion
|
|
133
|
-
export { API_TEMPLATE, type ApiTemplateData, type BackupOptions, CRON_TEMPLATE, type CronTemplateData, FsOps, type FsOpOptions as FsOpsOptions, LAYOUT_TEMPLATE, type LayoutTemplateData, MIDDLEWARE_TEMPLATE, type MiddlewareTemplateData, PAGE_TEMPLATE, PLUGIN_TEMPLATE, type PageTemplateData, type PluginTemplateData, type ScaffoldOptions, type ScaffoldResult, type ScaffoldType, type TemplateOptions, type TemplateVariables, createFsOps, deleteScaffold, listScaffoldableFiles, recoverScaffold, renderApiTemplate, renderCronTemplate, renderLayoutTemplate, renderMiddlewareTemplate, renderPageTemplate, renderPluginTemplate, renderTemplate, scaffold, toCamelCase, toKebabCase, toPascalCase };
|
|
196
|
+
export { API_TEMPLATE, type ApiTemplateData, type BackupOptions, type BundleBaseline, type BundleBudgetEntry, CRON_TEMPLATE, type CronTemplateData, FsOps, type FsOpOptions as FsOpsOptions, LAYOUT_TEMPLATE, type LayoutTemplateData, MIDDLEWARE_TEMPLATE, type ManifestChunk, type MiddlewareTemplateData, PAGE_TEMPLATE, PLUGIN_TEMPLATE, type PageTemplateData, type PluginTemplateData, SCAFFOLD_CONTRACT_VERSION, type ScaffoldArgManifest, type ScaffoldManifest, type ScaffoldOptions, type ScaffoldResult, type ScaffoldType, type ScaffoldTypeManifest, type TemplateOptions, type TemplateVariables, compareBundleBaseline, createFsOps, deleteScaffold, findClientManifest, getScaffoldManifest, listScaffoldableFiles, readViteManifest, recoverScaffold, renderApiTemplate, renderCronTemplate, renderLayoutTemplate, renderMiddlewareTemplate, renderPageTemplate, renderPluginTemplate, renderTemplate, scaffold, summarizeBundle, toCamelCase, toKebabCase, toPascalCase, writeBundleBaseline };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { n as getScaffoldManifest, t as SCAFFOLD_CONTRACT_VERSION } from "./scaffold-manifest-TrH6OCX8.js";
|
|
2
|
+
import { A as summarizeBundle, C as toCamelCase, D as compareBundleBaseline, E as createFsOps, O as findClientManifest, S as renderTemplate, T as toPascalCase, _ as renderCronTemplate, a as scaffold, b as renderPageTemplate, d as CRON_TEMPLATE, f as LAYOUT_TEMPLATE, g as renderApiTemplate, h as PLUGIN_TEMPLATE, i as recoverScaffold, j as writeBundleBaseline, k as readViteManifest, m as PAGE_TEMPLATE, n as listScaffoldableFiles, p as MIDDLEWARE_TEMPLATE, t as deleteScaffold, u as API_TEMPLATE, v as renderLayoutTemplate, w as toKebabCase, x as renderPluginTemplate, y as renderMiddlewareTemplate } from "./page-BRUWKaig.js";
|
|
3
|
+
export { API_TEMPLATE, CRON_TEMPLATE, LAYOUT_TEMPLATE, MIDDLEWARE_TEMPLATE, PAGE_TEMPLATE, PLUGIN_TEMPLATE, SCAFFOLD_CONTRACT_VERSION, compareBundleBaseline, createFsOps, deleteScaffold, findClientManifest, getScaffoldManifest, listScaffoldableFiles, readViteManifest, recoverScaffold, renderApiTemplate, renderCronTemplate, renderLayoutTemplate, renderMiddlewareTemplate, renderPageTemplate, renderPluginTemplate, renderTemplate, scaffold, summarizeBundle, toCamelCase, toKebabCase, toPascalCase, writeBundleBaseline };
|
|
@@ -1,9 +1,75 @@
|
|
|
1
|
-
import { existsSync, promises } from "node:fs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, promises, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { gzipSync } from "node:zlib";
|
|
3
|
+
import { dirname, join, resolve } from "pathe";
|
|
4
|
+
import { dirname as dirname$1, extname, join as join$1, relative as relative$1, resolve as resolve$1 } from "node:path";
|
|
5
|
+
import { getLogger } from "@ubean/shared/logger";
|
|
6
|
+
//#region src/analyze-lib.ts
|
|
7
|
+
function readViteManifest(manifestPath) {
|
|
8
|
+
return JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
9
|
+
}
|
|
10
|
+
function summarizeBundle(outDir, manifest) {
|
|
11
|
+
const entries = [];
|
|
12
|
+
for (const chunk of Object.values(manifest)) {
|
|
13
|
+
if (!chunk.file || chunk.file.endsWith(".css")) continue;
|
|
14
|
+
const abs = join(outDir, chunk.file);
|
|
15
|
+
if (!existsSync(abs)) continue;
|
|
16
|
+
const bytes = statSync(abs).size;
|
|
17
|
+
const gzip = gzipSync(readFileSync(abs)).length;
|
|
18
|
+
entries.push({
|
|
19
|
+
file: chunk.file,
|
|
20
|
+
bytes,
|
|
21
|
+
gzip,
|
|
22
|
+
isEntry: chunk.isEntry
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
entries.sort((a, b) => b.gzip - a.gzip);
|
|
26
|
+
const totalBytes = entries.reduce((sum, e) => sum + e.bytes, 0);
|
|
27
|
+
const totalGzip = entries.reduce((sum, e) => sum + e.gzip, 0);
|
|
28
|
+
const entryGzip = entries.filter((e) => e.isEntry).reduce((sum, e) => sum + e.gzip, 0);
|
|
29
|
+
return {
|
|
30
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31
|
+
outDir,
|
|
32
|
+
entries,
|
|
33
|
+
totalBytes,
|
|
34
|
+
totalGzip,
|
|
35
|
+
entryGzip
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function compareBundleBaseline(current, committed, options = {}) {
|
|
39
|
+
const maxIncrease = options.maxIncrease ?? .05;
|
|
40
|
+
const totalRatio = committed.totalGzip === 0 ? current.totalGzip === 0 ? 0 : Infinity : current.totalGzip / committed.totalGzip - 1;
|
|
41
|
+
const entryRatio = committed.entryGzip === 0 ? current.entryGzip === 0 ? 0 : Infinity : current.entryGzip / committed.entryGzip - 1;
|
|
42
|
+
const messages = [];
|
|
43
|
+
if (totalRatio > maxIncrease) messages.push(`total gzip ${(current.totalGzip / 1024).toFixed(1)} kB exceeds baseline ${(committed.totalGzip / 1024).toFixed(1)} kB by ${(totalRatio * 100).toFixed(1)}% (max ${(maxIncrease * 100).toFixed(0)}%)`);
|
|
44
|
+
if (entryRatio > maxIncrease) messages.push(`entry gzip ${(current.entryGzip / 1024).toFixed(1)} kB exceeds baseline ${(committed.entryGzip / 1024).toFixed(1)} kB by ${(entryRatio * 100).toFixed(1)}% (max ${(maxIncrease * 100).toFixed(0)}%)`);
|
|
45
|
+
return {
|
|
46
|
+
ok: messages.length === 0,
|
|
47
|
+
maxIncrease,
|
|
48
|
+
totalRatio,
|
|
49
|
+
entryRatio,
|
|
50
|
+
messages
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function writeBundleBaseline(filePath, baseline) {
|
|
54
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
55
|
+
writeFileSync(filePath, `${JSON.stringify(baseline, null, 2)}\n`, "utf8");
|
|
56
|
+
}
|
|
57
|
+
function findClientManifest(cwd) {
|
|
58
|
+
const candidates = [
|
|
59
|
+
join(cwd, "dist/client/.vite/manifest.json"),
|
|
60
|
+
join(cwd, "dist/public/.vite/manifest.json"),
|
|
61
|
+
join(cwd, "dist/.vite/manifest.json"),
|
|
62
|
+
join(cwd, ".output/public/.vite/manifest.json")
|
|
63
|
+
];
|
|
64
|
+
for (const manifestPath of candidates) if (existsSync(manifestPath)) return {
|
|
65
|
+
outDir: resolve(dirname(manifestPath), ".."),
|
|
66
|
+
manifestPath
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
4
70
|
//#region src/shared/fs-ops.ts
|
|
5
71
|
function resolvePath(cwd, ...paths) {
|
|
6
|
-
return resolve(cwd, ...paths);
|
|
72
|
+
return resolve$1(cwd, ...paths);
|
|
7
73
|
}
|
|
8
74
|
async function ensureDir(dir) {
|
|
9
75
|
await promises.mkdir(dir, { recursive: true });
|
|
@@ -23,7 +89,7 @@ async function readFile(path, encoding = "utf-8") {
|
|
|
23
89
|
return promises.readFile(path, encoding);
|
|
24
90
|
}
|
|
25
91
|
async function writeFile(path, content, encoding = "utf-8") {
|
|
26
|
-
await ensureDir(dirname(path));
|
|
92
|
+
await ensureDir(dirname$1(path));
|
|
27
93
|
await promises.writeFile(path, content, encoding);
|
|
28
94
|
}
|
|
29
95
|
async function appendFile(path, content, encoding = "utf-8") {
|
|
@@ -36,15 +102,15 @@ async function remove(path) {
|
|
|
36
102
|
});
|
|
37
103
|
}
|
|
38
104
|
async function copyFile(src, dest) {
|
|
39
|
-
await ensureDir(dirname(dest));
|
|
105
|
+
await ensureDir(dirname$1(dest));
|
|
40
106
|
await promises.copyFile(src, dest);
|
|
41
107
|
}
|
|
42
108
|
async function copyDir(src, dest, options) {
|
|
43
109
|
await ensureDir(dest);
|
|
44
110
|
const entries = await promises.readdir(src, { withFileTypes: true });
|
|
45
111
|
for (const entry of entries) {
|
|
46
|
-
const srcPath = join(src, entry.name);
|
|
47
|
-
const destPath = join(dest, entry.name);
|
|
112
|
+
const srcPath = join$1(src, entry.name);
|
|
113
|
+
const destPath = join$1(dest, entry.name);
|
|
48
114
|
if (options?.filter && !options.filter(srcPath)) continue;
|
|
49
115
|
if (entry.isDirectory()) await copyDir(srcPath, destPath, options);
|
|
50
116
|
else await copyFile(srcPath, destPath);
|
|
@@ -81,7 +147,7 @@ async function listFiles(dir, pattern) {
|
|
|
81
147
|
async function walk(current) {
|
|
82
148
|
const entries = await promises.readdir(current, { withFileTypes: true });
|
|
83
149
|
for (const entry of entries) {
|
|
84
|
-
const fullPath = join(current, entry.name);
|
|
150
|
+
const fullPath = join$1(current, entry.name);
|
|
85
151
|
if (entry.isDirectory()) {
|
|
86
152
|
if (entry.name === "node_modules" || entry.name.startsWith(".") && entry.name !== ".ubean") continue;
|
|
87
153
|
await walk(fullPath);
|
|
@@ -111,7 +177,7 @@ function createFsOps(cwd) {
|
|
|
111
177
|
restoreBackup: (path, opts) => restoreBackup(resolvePath(cwd, path), opts),
|
|
112
178
|
removeBackup: (path, opts) => removeBackup(resolvePath(cwd, path), opts),
|
|
113
179
|
listFiles: (dir, pattern) => listFiles(resolvePath(cwd, dir || "."), pattern),
|
|
114
|
-
relative: (to) => relative(cwd, resolve(cwd, to))
|
|
180
|
+
relative: (to) => relative$1(cwd, resolve$1(cwd, to))
|
|
115
181
|
};
|
|
116
182
|
}
|
|
117
183
|
//#endregion
|
|
@@ -583,32 +649,6 @@ const GLOBAL_MIDDLEWARE = [
|
|
|
583
649
|
"});",
|
|
584
650
|
""
|
|
585
651
|
].join("\n");
|
|
586
|
-
const I18N_MIDDLEWARE = [
|
|
587
|
-
"import { defineMiddleware, createI18nMiddleware, setI18nConfig } from 'ubean';",
|
|
588
|
-
"",
|
|
589
|
-
"// Set global i18n config (used by localizePath, switchLocalePath, etc.)",
|
|
590
|
-
"// Locale messages are auto-loaded by ubean:locales virtual module.",
|
|
591
|
-
"setI18nConfig({",
|
|
592
|
-
" defaultLocale: 'en',",
|
|
593
|
-
" strategy: 'prefix_except_default',",
|
|
594
|
-
" locales: ['en', 'zh']",
|
|
595
|
-
"});",
|
|
596
|
-
"",
|
|
597
|
-
"// Create i18n middleware instance once.",
|
|
598
|
-
"const i18nHandler = createI18nMiddleware({",
|
|
599
|
-
" strategy: 'prefix_except_default',",
|
|
600
|
-
" defaultLocale: 'en',",
|
|
601
|
-
" locales: ['en', 'zh'],",
|
|
602
|
-
" detectFromHeader: true,",
|
|
603
|
-
" detectFromCookie: true,",
|
|
604
|
-
" redirectOnLocaleMismatch: false",
|
|
605
|
-
"});",
|
|
606
|
-
"",
|
|
607
|
-
"export default defineMiddleware(async (c, next) => {",
|
|
608
|
-
" return i18nHandler(c, next);",
|
|
609
|
-
"});",
|
|
610
|
-
""
|
|
611
|
-
].join("\n");
|
|
612
652
|
const HELLO_API = `import { pipe, description, object, string, number } from 'valibot';
|
|
613
653
|
import { defineHandler, describeRoute, resolver } from 'ubean';
|
|
614
654
|
|
|
@@ -1221,7 +1261,6 @@ async function scaffoldUnifyTemplate(fs, options) {
|
|
|
1221
1261
|
await fs.writeFile("src/pages/about2.reuse.ts", ABOUT_REUSE);
|
|
1222
1262
|
await fs.writeFile("src/pages/(admin)/dashboard.vue", DASHBOARD_PAGE);
|
|
1223
1263
|
await fs.writeFile("src/middleware/01.global.ts", GLOBAL_MIDDLEWARE);
|
|
1224
|
-
await fs.writeFile("src/middleware/02.i18n.ts", I18N_MIDDLEWARE);
|
|
1225
1264
|
await fs.writeFile("src/routes/api/hello-world.ts", HELLO_API);
|
|
1226
1265
|
await fs.writeFile("src/components/IslandCounter.vue", ISLAND_COUNTER);
|
|
1227
1266
|
await fs.writeFile("src/components/IslandClock.vue", ISLAND_CLOCK);
|
|
@@ -1280,46 +1319,46 @@ async function scaffoldBlogTemplate(fs, options) {
|
|
|
1280
1319
|
//#region src/page.ts
|
|
1281
1320
|
const logger = getLogger("cli");
|
|
1282
1321
|
function getSrcDir(cwd) {
|
|
1283
|
-
return join(cwd, "src");
|
|
1322
|
+
return join$1(cwd, "src");
|
|
1284
1323
|
}
|
|
1285
1324
|
function getDirForType(cwd, type) {
|
|
1286
1325
|
const srcDir = getSrcDir(cwd);
|
|
1287
1326
|
switch (type) {
|
|
1288
1327
|
case "page":
|
|
1289
|
-
case "reuse": return join(srcDir, "pages");
|
|
1290
|
-
case "api": return join(srcDir, "routes");
|
|
1291
|
-
case "layout": return join(srcDir, "layouts");
|
|
1292
|
-
case "middleware": return join(srcDir, "middleware");
|
|
1293
|
-
case "cron": return join(srcDir, "server", "crons");
|
|
1294
|
-
case "plugin": return join(srcDir, "plugins");
|
|
1328
|
+
case "reuse": return join$1(srcDir, "pages");
|
|
1329
|
+
case "api": return join$1(srcDir, "routes");
|
|
1330
|
+
case "layout": return join$1(srcDir, "layouts");
|
|
1331
|
+
case "middleware": return join$1(srcDir, "middleware");
|
|
1332
|
+
case "cron": return join$1(srcDir, "server", "crons");
|
|
1333
|
+
case "plugin": return join$1(srcDir, "plugins");
|
|
1295
1334
|
default: return srcDir;
|
|
1296
1335
|
}
|
|
1297
1336
|
}
|
|
1298
1337
|
/** Resolve a baseDir that may be relative or absolute into an absolute path. */
|
|
1299
1338
|
function resolveBaseDir(cwd, baseDir) {
|
|
1300
|
-
return baseDir.startsWith("/") ? baseDir : join(cwd, baseDir);
|
|
1339
|
+
return baseDir.startsWith("/") ? baseDir : join$1(cwd, baseDir);
|
|
1301
1340
|
}
|
|
1302
1341
|
function resolveTargetPath(baseDir, path, type) {
|
|
1303
1342
|
let normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
1304
1343
|
if (normalizedPath === "" || normalizedPath === "/") normalizedPath = type === "page" || type === "reuse" ? "index" : "index";
|
|
1305
1344
|
if (type === "page" || type === "layout" || type === "reuse") {
|
|
1306
1345
|
if (type === "page" || type === "layout") {
|
|
1307
|
-
if (normalizedPath.endsWith(".vue")) return join(baseDir, normalizedPath);
|
|
1346
|
+
if (normalizedPath.endsWith(".vue")) return join$1(baseDir, normalizedPath);
|
|
1308
1347
|
const ext = ".vue";
|
|
1309
|
-
if (normalizedPath.endsWith("/") || normalizedPath === "") return join(baseDir, normalizedPath, `index${ext}`);
|
|
1310
|
-
return join(baseDir, `${normalizedPath}${ext}`);
|
|
1348
|
+
if (normalizedPath.endsWith("/") || normalizedPath === "") return join$1(baseDir, normalizedPath, `index${ext}`);
|
|
1349
|
+
return join$1(baseDir, `${normalizedPath}${ext}`);
|
|
1311
1350
|
}
|
|
1312
|
-
if (normalizedPath.endsWith(".reuse.ts")) return join(baseDir, normalizedPath);
|
|
1313
|
-
if (normalizedPath.endsWith(".ts")) return join(baseDir, normalizedPath.replace(/\.ts$/, ".reuse.ts"));
|
|
1351
|
+
if (normalizedPath.endsWith(".reuse.ts")) return join$1(baseDir, normalizedPath);
|
|
1352
|
+
if (normalizedPath.endsWith(".ts")) return join$1(baseDir, normalizedPath.replace(/\.ts$/, ".reuse.ts"));
|
|
1314
1353
|
const ext = ".reuse.ts";
|
|
1315
|
-
if (normalizedPath.endsWith("/") || normalizedPath === "") return join(baseDir, normalizedPath, `index${ext}`);
|
|
1316
|
-
return join(baseDir, `${normalizedPath}${ext}`);
|
|
1354
|
+
if (normalizedPath.endsWith("/") || normalizedPath === "") return join$1(baseDir, normalizedPath, `index${ext}`);
|
|
1355
|
+
return join$1(baseDir, `${normalizedPath}${ext}`);
|
|
1317
1356
|
}
|
|
1318
|
-
if (normalizedPath.endsWith(".ts") || normalizedPath.endsWith(".js")) return join(baseDir, normalizedPath);
|
|
1357
|
+
if (normalizedPath.endsWith(".ts") || normalizedPath.endsWith(".js")) return join$1(baseDir, normalizedPath);
|
|
1319
1358
|
const ext = ".ts";
|
|
1320
|
-
if (normalizedPath.endsWith("/") || normalizedPath === "") return join(baseDir, normalizedPath, `index${ext}`);
|
|
1321
|
-
if ((type === "api" || type === "middleware" || type === "cron" || type === "plugin") && !normalizedPath.includes(".")) return join(baseDir, `${normalizedPath}${ext}`);
|
|
1322
|
-
return join(baseDir, normalizedPath);
|
|
1359
|
+
if (normalizedPath.endsWith("/") || normalizedPath === "") return join$1(baseDir, normalizedPath, `index${ext}`);
|
|
1360
|
+
if ((type === "api" || type === "middleware" || type === "cron" || type === "plugin") && !normalizedPath.includes(".")) return join$1(baseDir, `${normalizedPath}${ext}`);
|
|
1361
|
+
return join$1(baseDir, normalizedPath);
|
|
1323
1362
|
}
|
|
1324
1363
|
function sanitizeNameSegment(seg) {
|
|
1325
1364
|
return seg.replace(/^\[\.\.\.(.+)\]$/, "All$1").replace(/^\[\[(.+)\]\]$/, "$1Optional").replace(/^\[(.+)\]$/, "$1").replace(/[^a-zA-Z0-9$_]/g, "");
|
|
@@ -1700,4 +1739,4 @@ const pageCommand = {
|
|
|
1700
1739
|
}
|
|
1701
1740
|
};
|
|
1702
1741
|
//#endregion
|
|
1703
|
-
export { toCamelCase as C, createFsOps as E, renderTemplate as S, toPascalCase as T, renderCronTemplate as _, scaffold as a, renderPageTemplate as b, scaffoldStarterTemplate as c, CRON_TEMPLATE as d, LAYOUT_TEMPLATE as f, renderApiTemplate as g, PLUGIN_TEMPLATE as h, recoverScaffold as i, scaffoldUnifyTemplate as l, PAGE_TEMPLATE as m, listScaffoldableFiles as n, scaffoldBlogTemplate as o, MIDDLEWARE_TEMPLATE as p, pageCommand as r, scaffoldMinimalTemplate as s, deleteScaffold as t, API_TEMPLATE as u, renderLayoutTemplate as v, toKebabCase as w, renderPluginTemplate as x, renderMiddlewareTemplate as y };
|
|
1742
|
+
export { summarizeBundle as A, toCamelCase as C, compareBundleBaseline as D, createFsOps as E, findClientManifest as O, renderTemplate as S, toPascalCase as T, renderCronTemplate as _, scaffold as a, renderPageTemplate as b, scaffoldStarterTemplate as c, CRON_TEMPLATE as d, LAYOUT_TEMPLATE as f, renderApiTemplate as g, PLUGIN_TEMPLATE as h, recoverScaffold as i, writeBundleBaseline as j, readViteManifest as k, scaffoldUnifyTemplate as l, PAGE_TEMPLATE as m, listScaffoldableFiles as n, scaffoldBlogTemplate as o, MIDDLEWARE_TEMPLATE as p, pageCommand as r, scaffoldMinimalTemplate as s, deleteScaffold as t, API_TEMPLATE as u, renderLayoutTemplate as v, toKebabCase as w, renderPluginTemplate as x, renderMiddlewareTemplate as y };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/scaffold-manifest.ts
|
|
14
|
+
var scaffold_manifest_exports = /* @__PURE__ */ __exportAll({
|
|
15
|
+
SCAFFOLD_CONTRACT_VERSION: () => 1,
|
|
16
|
+
getScaffoldManifest: () => getScaffoldManifest
|
|
17
|
+
});
|
|
18
|
+
const SCAFFOLD_CONTRACT_VERSION = 1;
|
|
19
|
+
const TYPES = [
|
|
20
|
+
{
|
|
21
|
+
type: "page",
|
|
22
|
+
cli: true,
|
|
23
|
+
baseDir: "pages",
|
|
24
|
+
extensions: [".vue"],
|
|
25
|
+
args: [{
|
|
26
|
+
name: "path",
|
|
27
|
+
required: true,
|
|
28
|
+
description: "Route path (e.g. users/[id])"
|
|
29
|
+
}]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: "api",
|
|
33
|
+
cli: true,
|
|
34
|
+
baseDir: "routes",
|
|
35
|
+
extensions: [".ts"],
|
|
36
|
+
args: [{
|
|
37
|
+
name: "path",
|
|
38
|
+
required: true,
|
|
39
|
+
description: "API route path (e.g. users/[id])"
|
|
40
|
+
}, {
|
|
41
|
+
name: "method",
|
|
42
|
+
required: false,
|
|
43
|
+
description: "HTTP method",
|
|
44
|
+
default: "GET"
|
|
45
|
+
}]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: "layout",
|
|
49
|
+
cli: true,
|
|
50
|
+
baseDir: "layouts",
|
|
51
|
+
extensions: [".vue"],
|
|
52
|
+
args: [{
|
|
53
|
+
name: "path",
|
|
54
|
+
required: true,
|
|
55
|
+
description: "Layout name (e.g. admin)"
|
|
56
|
+
}]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: "middleware",
|
|
60
|
+
cli: true,
|
|
61
|
+
baseDir: "middleware",
|
|
62
|
+
extensions: [".ts"],
|
|
63
|
+
args: [{
|
|
64
|
+
name: "path",
|
|
65
|
+
required: true,
|
|
66
|
+
description: "Middleware path (e.g. auth)"
|
|
67
|
+
}]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: "cron",
|
|
71
|
+
cli: true,
|
|
72
|
+
baseDir: "server/crons",
|
|
73
|
+
extensions: [".ts"],
|
|
74
|
+
args: [{
|
|
75
|
+
name: "path",
|
|
76
|
+
required: true,
|
|
77
|
+
description: "Cron task path (e.g. daily-cleanup)"
|
|
78
|
+
}, {
|
|
79
|
+
name: "schedule",
|
|
80
|
+
required: false,
|
|
81
|
+
description: "Cron expression",
|
|
82
|
+
default: "* * * * *"
|
|
83
|
+
}]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: "plugin",
|
|
87
|
+
cli: true,
|
|
88
|
+
baseDir: "plugins",
|
|
89
|
+
extensions: [".ts"],
|
|
90
|
+
args: [{
|
|
91
|
+
name: "path",
|
|
92
|
+
required: true,
|
|
93
|
+
description: "Plugin path (e.g. analytics)"
|
|
94
|
+
}]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
type: "reuse",
|
|
98
|
+
cli: false,
|
|
99
|
+
baseDir: "pages",
|
|
100
|
+
extensions: [".reuse.ts", ".reuse.vue"],
|
|
101
|
+
args: [{
|
|
102
|
+
name: "path",
|
|
103
|
+
required: true,
|
|
104
|
+
description: "Reuse route path; library API only (`scaffold({ type: \"reuse\" })`)"
|
|
105
|
+
}]
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
/** Machine-readable scaffold catalog for studio / IDE plugins (RM-S01). */
|
|
109
|
+
function getScaffoldManifest() {
|
|
110
|
+
return {
|
|
111
|
+
contractVersion: 1,
|
|
112
|
+
types: TYPES
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { getScaffoldManifest as n, scaffold_manifest_exports as r, SCAFFOLD_CONTRACT_VERSION as t };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubean/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "CLI for ubean (ubean-next binary: dev, build, prepare, init, preview, page, env, config, devtools, api/layout/middleware/cron/plugin scaffolds)",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "CLI for ubean (ubean-next binary: dev, build, prepare, init, preview, page, env, config, devtools, api/layout/middleware/cron/plugin scaffolds) plus the Vite dev server runner",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ubean-next": "./bin/ubean-next.mjs"
|
|
7
7
|
},
|
|
@@ -27,29 +27,40 @@
|
|
|
27
27
|
"citty": "^0.2.2",
|
|
28
28
|
"kolorist": "^1.8.0",
|
|
29
29
|
"pathe": "^2.0.3",
|
|
30
|
-
"@ubean/
|
|
31
|
-
"@ubean/
|
|
32
|
-
"@ubean/
|
|
33
|
-
"@ubean/
|
|
34
|
-
"@ubean/
|
|
35
|
-
"@ubean/
|
|
36
|
-
"@ubean/
|
|
37
|
-
"@ubean/
|
|
38
|
-
"@ubean/prerender": "0.2.2",
|
|
39
|
-
"@ubean/shared": "0.2.2",
|
|
40
|
-
"@ubean/scan": "0.2.2"
|
|
30
|
+
"@ubean/app": "0.3.0",
|
|
31
|
+
"@ubean/build": "0.3.0",
|
|
32
|
+
"@ubean/client": "0.3.0",
|
|
33
|
+
"@ubean/preset": "0.3.0",
|
|
34
|
+
"@ubean/islands": "0.3.0",
|
|
35
|
+
"@ubean/scan": "0.3.0",
|
|
36
|
+
"@ubean/shared": "0.3.0",
|
|
37
|
+
"@ubean/config": "0.3.0"
|
|
41
38
|
},
|
|
42
39
|
"devDependencies": {
|
|
43
40
|
"@types/node": "^26.2.0",
|
|
41
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
44
42
|
"typescript": "7.0.2",
|
|
43
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.9",
|
|
45
44
|
"vite-plus": "0.2.9"
|
|
46
45
|
},
|
|
47
46
|
"peerDependencies": {
|
|
48
|
-
"@
|
|
47
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
48
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.9",
|
|
49
|
+
"@ubean/content": "0.3.0",
|
|
50
|
+
"@ubean/devtools": "0.3.0"
|
|
49
51
|
},
|
|
50
52
|
"peerDependenciesMeta": {
|
|
53
|
+
"@ubean/content": {
|
|
54
|
+
"optional": true
|
|
55
|
+
},
|
|
51
56
|
"@ubean/devtools": {
|
|
52
57
|
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"@vitejs/plugin-vue": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"vite": {
|
|
63
|
+
"optional": true
|
|
53
64
|
}
|
|
54
65
|
},
|
|
55
66
|
"scripts": {
|