@ubean/cli 0.4.5 → 0.4.7

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 CHANGED
@@ -1,11 +1,11 @@
1
- import { A as summarizeBundle, D as compareBundleBaseline, E as createFsOps, O as findClientManifest, S as renderTemplate, a as scaffold, c as scaffoldStarterTemplate, i as recoverScaffold, j as writeBundleBaseline, k as readViteManifest, l as scaffoldUnifyTemplate, n as listScaffoldableFiles, o as scaffoldBlogTemplate, r as pageCommand, s as scaffoldMinimalTemplate, t as deleteScaffold } from "./page-pkDKNCLT.js";
1
+ import { A as summarizeBundle, D as compareBundleBaseline, E as createFsOps, O as findClientManifest, S as renderTemplate, a as scaffold, c as scaffoldStarterTemplate, i as recoverScaffold, j as writeBundleBaseline, k as readViteManifest, l as scaffoldUnifyTemplate, n as listScaffoldableFiles, o as scaffoldBlogTemplate, r as pageCommand, s as scaffoldMinimalTemplate, t as deleteScaffold } from "./page-Um0fHKa9.js";
2
2
  import { existsSync, mkdirSync, readFileSync, watch } from "node:fs";
3
3
  import { basename, join, relative, resolve } from "pathe";
4
4
  import { extname, normalize, sep } from "node:path";
5
5
  import { getLogger, setDebugLogging } from "@ubean/shared/logger";
6
6
  import { defineCommand, runMain } from "citty";
7
7
  import { BUILTIN_MODULES, isBuiltinDisabled, loadUbeanConfig, resolveModules, resolvePrerenderConfig, resolveSsrConfig } from "@ubean/config";
8
- import { readFile, rm, stat } from "node:fs/promises";
8
+ import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
9
9
  import { pathToFileURL } from "node:url";
10
10
  import { generateOpenApiTypesFromServer, generateTypes } from "@ubean/build/codegen";
11
11
  import { prerender } from "@ubean/build/prerender";
@@ -430,6 +430,33 @@ const buildCommand = {
430
430
  notFoundRoute,
431
431
  expandRoutes
432
432
  });
433
+ if (contentSnapshot) try {
434
+ const contentMod = await import("@ubean/content");
435
+ const searchConfig = contentMod.resolveContentSearchConfig(config.content, { ssg: config.mode === "ssg" });
436
+ const staticDir = resolve(cwd, resolvePrerenderConfig(config.prerender).staticDir);
437
+ if (searchConfig.sections) {
438
+ const payload = contentMod.generateSearchSectionsSnapshot(contentSnapshot);
439
+ await mkdir(staticDir, { recursive: true });
440
+ await writeFile(join(staticDir, "__search.json"), JSON.stringify(payload), "utf-8");
441
+ const sectionCount = Object.values(payload).reduce((sum, sections) => sum + sections.length, 0);
442
+ logger$9.info(`Search: wrote __search.json (${sectionCount} sections)`);
443
+ }
444
+ if (searchConfig.pagefind) {
445
+ const res = await contentMod.runPagefindIndex({
446
+ siteDir: staticDir,
447
+ createIndexOptions: searchConfig.pagefindOptions,
448
+ logger: {
449
+ info: (msg) => logger$9.info(msg),
450
+ warn: (msg) => logger$9.warn(msg)
451
+ }
452
+ });
453
+ if (res.indexed) logger$9.info("Search: pagefind index generated");
454
+ else if (res.reason === "pagefind-not-installed") logger$9.info("Search: pagefind is not installed — skipping index. Run `pnpm add -D pagefind` to enable.");
455
+ else logger$9.warn(`Search: pagefind indexing failed — ${res.error ?? res.reason}`);
456
+ }
457
+ } catch (err) {
458
+ logger$9.warn(`Search index generation skipped: ${err instanceof Error ? err.message : String(err)}`);
459
+ }
433
460
  }
434
461
  if (config.mode === "ssg" && !process.env.UBEAN_KEEP_SSR) {
435
462
  const serverDir = join(cwd, config.build.outputDir, "server");
@@ -1092,6 +1119,20 @@ import("@ubean/devtools").then((mod) => {
1092
1119
  function getCustomTabs() {
1093
1120
  return _customTabsGetter();
1094
1121
  }
1122
+ /**
1123
+ * dev 环境 SecurityHeaders 解析(ADR-0011)。
1124
+ *
1125
+ * ssg 模式默认关闭:静态产物不携带框架注入的安全头(响应头由托管平台
1126
+ * 控制),dev 默认关闭以对齐生产行为,消除「dev 有 CSP / 线上没有」的
1127
+ * 偏差。显式配置(`headers: true` 或对象)仍会被尊重,作为 CSP 调试
1128
+ * 入口。其余模式默认开启不变。
1129
+ */
1130
+ function resolveDevSecurityHeaders(config) {
1131
+ if (config.security === false) return false;
1132
+ if (config.security?.headers === false) return false;
1133
+ if (config.security?.headers !== void 0) return config.security.headers;
1134
+ return config.mode !== "ssg";
1135
+ }
1095
1136
  const devCommand = {
1096
1137
  meta: {
1097
1138
  name: "dev",
@@ -1285,7 +1326,7 @@ async function buildApp(cwd, config) {
1285
1326
  streaming: config.ssr.streaming,
1286
1327
  notFoundPage: result.notFoundPage,
1287
1328
  csrf: config.security === false ? false : config.security?.csrf ?? true,
1288
- securityHeaders: config.security === false ? false : config.security?.headers === false ? false : config.security?.headers ?? true,
1329
+ securityHeaders: resolveDevSecurityHeaders(config),
1289
1330
  dataCache: config.dataCache,
1290
1331
  cache: config.cache,
1291
1332
  seoConventions: { srcDir: resolve(cwd, config.srcDir) }
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ interface BackupOptions {
7
7
  backupSuffix?: string;
8
8
  removeOriginal?: boolean;
9
9
  }
10
- declare function createFsOps(cwd: string): {
10
+ export declare function createFsOps(cwd: string): {
11
11
  cwd: string;
12
12
  resolve: (...paths: string[]) => string;
13
13
  exists: (path: string) => Promise<boolean>;
@@ -53,9 +53,9 @@ interface BundleBaseline {
53
53
  totalGzip: number;
54
54
  entryGzip: number;
55
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?: {
56
+ export declare function readViteManifest(manifestPath: string): Record<string, ManifestChunk>;
57
+ export declare function summarizeBundle(outDir: string, manifest: Record<string, ManifestChunk>): BundleBaseline;
58
+ export declare function compareBundleBaseline(current: Pick<BundleBaseline, 'totalGzip' | 'entryGzip'>, committed: Pick<BundleBaseline, 'totalGzip' | 'entryGzip'>, options?: {
59
59
  maxIncrease?: number;
60
60
  }): {
61
61
  ok: boolean;
@@ -64,8 +64,8 @@ declare function compareBundleBaseline(current: Pick<BundleBaseline, 'totalGzip'
64
64
  entryRatio: number;
65
65
  messages: string[];
66
66
  };
67
- declare function writeBundleBaseline(filePath: string, baseline: BundleBaseline): void;
68
- declare function findClientManifest(cwd: string): {
67
+ export declare function writeBundleBaseline(filePath: string, baseline: BundleBaseline): void;
68
+ export declare function findClientManifest(cwd: string): {
69
69
  outDir: string;
70
70
  manifestPath: string;
71
71
  } | undefined;
@@ -78,7 +78,7 @@ interface TemplateOptions {
78
78
  variables?: Record<string, unknown>;
79
79
  delimiters?: [string, string];
80
80
  }
81
- declare function renderTemplate(template: string, options?: TemplateOptions): string;
81
+ export declare function renderTemplate(template: string, options?: TemplateOptions): string;
82
82
  interface PageTemplateData {
83
83
  name: string;
84
84
  path: string;
@@ -112,21 +112,21 @@ interface PluginTemplateData {
112
112
  kebabName: string;
113
113
  pascalName: string;
114
114
  }
115
- declare function toKebabCase(str: string): string;
116
- declare function toPascalCase(str: string): string;
117
- declare function toCamelCase(str: string): string;
118
- declare const PAGE_TEMPLATE = "<script setup lang=\"ts\">\ndefinePage({\n meta: {\n title: '{{name}}'\n }\n});\n</script>\n\n<template>\n <div class=\"{{kebabName}}-page\">\n <div>{{name}}</div>\n </div>\n</template>\n\n";
119
- declare const API_TEMPLATE = "import { defineHandler } from 'ubean/server';\n\nexport default defineHandler(async c => {\n return c.json({ message: '{{name}} endpoint' });\n});\n";
120
- declare const MIDDLEWARE_TEMPLATE = "import { defineMiddleware } from 'ubean/server';\n\nexport default defineMiddleware(async (c, next) => {\n console.log('{{name}} middleware');\n await next();\n});\n";
121
- declare const LAYOUT_TEMPLATE = "<script setup lang=\"ts\">\ndefinePage({\n meta: {\n title: '{{name}}'\n }\n});\n</script>\n\n<template>\n <div class=\"{{kebabName}}\">\n <slot />\n </div>\n</template>\n";
122
- declare const CRON_TEMPLATE = "import { defineScheduled } from 'ubean/server';\n\nexport default defineScheduled({\n name: '{{name}}',\n schedule: '{{schedule}}'\n}, async () => {\n console.log('Running {{name}} cron task');\n});\n";
123
- declare const PLUGIN_TEMPLATE = "import { definePlugin } from 'ubean';\n\nexport default definePlugin({\n name: '{{kebabName}}',\n setup() {\n console.log('{{name}} plugin setup');\n }\n});\n";
124
- declare function renderPageTemplate(data: PageTemplateData): string;
125
- declare function renderApiTemplate(data: ApiTemplateData): string;
126
- declare function renderMiddlewareTemplate(data: MiddlewareTemplateData): string;
127
- declare function renderLayoutTemplate(data: LayoutTemplateData): string;
128
- declare function renderCronTemplate(data: CronTemplateData): string;
129
- declare function renderPluginTemplate(data: PluginTemplateData): string;
115
+ export declare function toKebabCase(str: string): string;
116
+ export declare function toPascalCase(str: string): string;
117
+ export declare function toCamelCase(str: string): string;
118
+ export declare const PAGE_TEMPLATE = "<script setup lang=\"ts\">\ndefinePage({\n meta: {\n title: '{{name}}'\n }\n});\n</script>\n\n<template>\n <div class=\"{{kebabName}}-page\">\n <div>{{name}}</div>\n </div>\n</template>\n\n";
119
+ export declare const API_TEMPLATE = "import { defineHandler } from 'ubean/server';\n\nexport default defineHandler(async c => {\n return c.json({ message: '{{name}} endpoint' });\n});\n";
120
+ export declare const MIDDLEWARE_TEMPLATE = "import { defineMiddleware } from 'ubean/server';\n\nexport default defineMiddleware(async (c, next) => {\n console.log('{{name}} middleware');\n await next();\n});\n";
121
+ export declare const LAYOUT_TEMPLATE = "<script setup lang=\"ts\">\ndefinePage({\n meta: {\n title: '{{name}}'\n }\n});\n</script>\n\n<template>\n <div class=\"{{kebabName}}\">\n <slot />\n </div>\n</template>\n";
122
+ export declare const CRON_TEMPLATE = "import { defineScheduled } from 'ubean/server';\n\nexport default defineScheduled({\n name: '{{name}}',\n schedule: '{{schedule}}'\n}, async () => {\n console.log('Running {{name}} cron task');\n});\n";
123
+ export declare const PLUGIN_TEMPLATE = "import { definePlugin } from 'ubean';\n\nexport default definePlugin({\n name: '{{kebabName}}',\n setup() {\n console.log('{{name}} plugin setup');\n }\n});\n";
124
+ export declare function renderPageTemplate(data: PageTemplateData): string;
125
+ export declare function renderApiTemplate(data: ApiTemplateData): string;
126
+ export declare function renderMiddlewareTemplate(data: MiddlewareTemplateData): string;
127
+ export declare function renderLayoutTemplate(data: LayoutTemplateData): string;
128
+ export declare function renderCronTemplate(data: CronTemplateData): string;
129
+ export declare function renderPluginTemplate(data: PluginTemplateData): string;
130
130
  //#endregion
131
131
  //#region src/page.d.ts
132
132
  type ScaffoldType = 'page' | 'api' | 'layout' | 'middleware' | 'reuse' | 'cron' | 'plugin';
@@ -148,8 +148,8 @@ interface ScaffoldResult {
148
148
  skipped: string[];
149
149
  errors: string[];
150
150
  }
151
- declare function scaffold(options: ScaffoldOptions): Promise<ScaffoldResult>;
152
- declare function deleteScaffold(options: {
151
+ export declare function scaffold(options: ScaffoldOptions): Promise<ScaffoldResult>;
152
+ export declare function deleteScaffold(options: {
153
153
  cwd?: string;
154
154
  type: ScaffoldType;
155
155
  path: string;
@@ -157,17 +157,17 @@ declare function deleteScaffold(options: {
157
157
  dry?: boolean;
158
158
  baseDir?: string;
159
159
  }): Promise<ScaffoldResult>;
160
- declare function recoverScaffold(options: {
160
+ export declare function recoverScaffold(options: {
161
161
  cwd?: string;
162
162
  type: ScaffoldType;
163
163
  path: string;
164
164
  dry?: boolean;
165
165
  baseDir?: string;
166
166
  }): Promise<ScaffoldResult>;
167
- declare function listScaffoldableFiles(cwd: string, type: ScaffoldType, baseDir?: string): Promise<string[]>;
167
+ export declare function listScaffoldableFiles(cwd: string, type: ScaffoldType, baseDir?: string): Promise<string[]>;
168
168
  //#endregion
169
169
  //#region src/scaffold-manifest.d.ts
170
- declare const SCAFFOLD_CONTRACT_VERSION: 1;
170
+ export declare const SCAFFOLD_CONTRACT_VERSION: 1;
171
171
  interface ScaffoldArgManifest {
172
172
  name: string;
173
173
  required: boolean;
@@ -188,9 +188,9 @@ interface ScaffoldManifest {
188
188
  types: ScaffoldTypeManifest[];
189
189
  }
190
190
  /** Machine-readable scaffold catalog for studio / IDE plugins (RM-S01). */
191
- declare function getScaffoldManifest(): ScaffoldManifest;
191
+ export declare function getScaffoldManifest(): ScaffoldManifest;
192
192
  //#endregion
193
193
  //#region src/index.d.ts
194
- type FsOps = ReturnType<typeof createFsOps>;
194
+ export type FsOps = ReturnType<typeof createFsOps>;
195
195
  //#endregion
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 };
196
+ export type { ApiTemplateData, BackupOptions, BundleBaseline, BundleBudgetEntry, CronTemplateData, FsOpOptions as FsOpsOptions, LayoutTemplateData, ManifestChunk, MiddlewareTemplateData, PageTemplateData, PluginTemplateData, ScaffoldArgManifest, ScaffoldManifest, ScaffoldOptions, ScaffoldResult, ScaffoldType, ScaffoldTypeManifest, TemplateOptions, TemplateVariables };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
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-pkDKNCLT.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-Um0fHKa9.js";
3
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 };
@@ -338,7 +338,7 @@ const PACKAGE_JSON = `{
338
338
  "@soybeanjs/eslint-config-vue": "^0.1.1",
339
339
  "@soybeanjs/oxc-config": "^0.2.3",
340
340
  "eslint": "^10.8.0",
341
- "typescript": "^5.6.0",
341
+ "typescript": "^6.0.3",
342
342
  "vite-plus": "^0.2.6",
343
343
  "vue-tsc": "^2.1.0"
344
344
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/cli",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
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"
@@ -24,15 +24,15 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@ubean/app": "0.4.5",
28
- "@ubean/build": "0.4.5",
29
- "@ubean/client": "0.4.5",
30
- "@ubean/config": "0.4.5",
31
- "@ubean/i18n": "0.4.5",
32
- "@ubean/islands": "0.4.5",
33
- "@ubean/preset": "0.4.5",
34
- "@ubean/scan": "0.4.5",
35
- "@ubean/shared": "0.4.5",
27
+ "@ubean/app": "0.4.7",
28
+ "@ubean/build": "0.4.7",
29
+ "@ubean/client": "0.4.7",
30
+ "@ubean/config": "0.4.7",
31
+ "@ubean/i18n": "0.4.7",
32
+ "@ubean/islands": "0.4.7",
33
+ "@ubean/preset": "0.4.7",
34
+ "@ubean/scan": "0.4.7",
35
+ "@ubean/shared": "0.4.7",
36
36
  "citty": "^0.2.2",
37
37
  "kolorist": "^1.8.0",
38
38
  "pathe": "^2.0.3"
@@ -40,15 +40,15 @@
40
40
  "devDependencies": {
41
41
  "@types/node": "^26.5.0",
42
42
  "@vitejs/plugin-vue": "^6.0.8",
43
- "typescript": "7.0.2",
44
- "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
45
- "vite-plus": "0.3.0"
43
+ "typescript": "npm:typescript-native-bridge@latest",
44
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.3.1",
45
+ "vite-plus": "0.3.1"
46
46
  },
47
47
  "peerDependencies": {
48
- "@ubean/content": "0.4.5",
49
- "@ubean/devtools": "0.4.5",
48
+ "@ubean/content": "0.4.7",
49
+ "@ubean/devtools": "0.4.7",
50
50
  "@vitejs/plugin-vue": "^6.0.8",
51
- "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0"
51
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.3.1"
52
52
  },
53
53
  "peerDependenciesMeta": {
54
54
  "@ubean/content": {