@ubean/cli 0.2.2 → 0.3.1

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/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 { C as toCamelCase, E as createFsOps, 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, 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-DU64g_Lv.js";
2
- export { API_TEMPLATE, CRON_TEMPLATE, LAYOUT_TEMPLATE, MIDDLEWARE_TEMPLATE, PAGE_TEMPLATE, PLUGIN_TEMPLATE, createFsOps, deleteScaffold, listScaffoldableFiles, recoverScaffold, renderApiTemplate, renderCronTemplate, renderLayoutTemplate, renderMiddlewareTemplate, renderPageTemplate, renderPluginTemplate, renderTemplate, scaffold, toCamelCase, toKebabCase, toPascalCase };
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 { dirname, extname, join, relative, resolve } from "node:path";
3
- import { getLogger } from "@ubean/logger";
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.2.2",
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.1",
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
  },
@@ -24,32 +24,43 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
+ "@ubean/app": "0.3.1",
28
+ "@ubean/build": "0.3.1",
29
+ "@ubean/client": "0.3.1",
30
+ "@ubean/config": "0.3.1",
31
+ "@ubean/islands": "0.3.1",
32
+ "@ubean/preset": "0.3.1",
33
+ "@ubean/scan": "0.3.1",
34
+ "@ubean/shared": "0.3.1",
27
35
  "citty": "^0.2.2",
28
36
  "kolorist": "^1.8.0",
29
- "pathe": "^2.0.3",
30
- "@ubean/build": "0.2.2",
31
- "@ubean/app": "0.2.2",
32
- "@ubean/codegen": "0.2.2",
33
- "@ubean/config": "0.2.2",
34
- "@ubean/dev-server": "0.2.2",
35
- "@ubean/logger": "0.2.2",
36
- "@ubean/modules": "0.2.2",
37
- "@ubean/preset": "0.2.2",
38
- "@ubean/prerender": "0.2.2",
39
- "@ubean/shared": "0.2.2",
40
- "@ubean/scan": "0.2.2"
37
+ "pathe": "^2.0.3"
41
38
  },
42
39
  "devDependencies": {
43
- "@types/node": "^26.2.0",
40
+ "@types/node": "^26.4.0",
41
+ "@vitejs/plugin-vue": "^6.0.8",
44
42
  "typescript": "7.0.2",
45
- "vite-plus": "0.2.9"
43
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
44
+ "vite-plus": "0.3.0"
46
45
  },
47
46
  "peerDependencies": {
48
- "@ubean/devtools": "0.2.2"
47
+ "@ubean/content": "0.3.1",
48
+ "@ubean/devtools": "0.3.1",
49
+ "@vitejs/plugin-vue": "^6.0.8",
50
+ "vite": "npm:@voidzero-dev/vite-plus-core@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": {