@ubean/build 0.3.6 → 0.4.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.
@@ -1,39 +1,82 @@
1
+ import { AutoImportOptions, ComponentsOptions } from "@ubean/config";
1
2
  import { ScanResult } from "@ubean/scan";
2
3
  import { Import, InlinePreset } from "unimport";
4
+ import { Options } from "unplugin-vue-components/types";
5
+ import { Options as Options$1 } from "unplugin-auto-import/types";
3
6
  //#region src/codegen/auto-imports.d.ts
4
- interface AutoImportOptions {
7
+ interface GenerateAutoImportsOptions {
5
8
  cwd: string;
6
9
  srcDir: string;
7
10
  buildDir: string;
8
- composablesDirs?: string[];
9
- componentsDirs?: string[];
11
+ /** `srcDir` 内扫描目录名(默认 `composables` / `components`)。 */
10
12
  dirs?: {
11
13
  composables?: string;
12
14
  components?: string;
13
15
  };
14
- imports?: {
15
- autoImport?: boolean;
16
- global?: boolean;
17
- };
18
- components?: {
19
- autoImport?: boolean;
20
- directoryAsNamespace?: boolean;
21
- };
16
+ /** `ubean.config.ts` 的 `autoImports` 配置(`boolean | AutoImportOptions`)。 */
17
+ autoImports?: boolean | AutoImportOptions;
18
+ /** `ubean.config.ts` 的 `components` 配置(`boolean | ComponentsOptions`)。 */
19
+ components?: boolean | ComponentsOptions;
22
20
  }
21
+ interface ResolvedAutoImports {
22
+ /** 总开关(`autoImports: false` 时为 `false`)。 */
23
+ enabled: boolean;
24
+ /** ubean 内置 API(client + server 预设),默认 `true`。 */
25
+ ubean: boolean;
26
+ /** vue composables + reactivity macros,默认 `false`。 */
27
+ vue: boolean;
28
+ /** vue-router `useRouter`,默认 `false`。 */
29
+ vueRouter: boolean;
30
+ /** vue-i18n `useI18n`,默认 `false`。 */
31
+ vueI18n: boolean;
32
+ /** hono-openapi `validator`/`describeRoute`,默认 `false`。 */
33
+ honoOpenapi: boolean;
34
+ /** 用户对象形态配置(boolean/undefined 时为 `{}`)。 */
35
+ options: AutoImportOptions;
36
+ }
37
+ /** 将 `boolean | AutoImportOptions` 归一化为分库开关 + 透传选项。 */
38
+ declare function resolveAutoImportsConfig(input: boolean | AutoImportOptions | undefined): ResolvedAutoImports;
39
+ /** 按分库开关组装内置预设(顺序稳定:ubean client/server → vue → vue-router → vue-i18n → hono-openapi)。 */
40
+ declare function getAutoImportPresets(resolved: ResolvedAutoImports): InlinePreset[];
41
+ interface ResolvedComponentsAutoImport {
42
+ /** 目录扫描 + dts 总开关(`components: false` 时为 `false`;resolver 仍然生效)。 */
43
+ enabled: boolean;
44
+ /** ubean 内置组件(`Link`/`Head`/`PageView`)resolver,默认 `true`。 */
45
+ ubean: boolean;
46
+ /** 用户对象形态配置(boolean/undefined 时为 `{}`)。 */
47
+ options: ComponentsOptions;
48
+ }
49
+ /** 将 `boolean | ComponentsOptions` 归一化。 */
50
+ declare function resolveComponentsConfig(input: boolean | ComponentsOptions | undefined): ResolvedComponentsAutoImport;
51
+ /** unplugin 系选项普遍使用 `Arrayable<T>`,合并进数组前先归一化。 */
52
+ declare function toArray<T>(value: T | T[] | undefined): T[];
23
53
  declare const VUE_PRESET: InlinePreset;
24
54
  declare const VUE_MACROS_PRESET: InlinePreset;
25
55
  /**
26
56
  * Client-safe symbols sourced from the first-class `ubean/client` entry.
27
57
  * These are safe to auto-import in Vue components (browser-side) because
28
58
  * `@ubean/client` has zero build-time dependencies and no `node:*` imports.
29
- * (`ubean/runtime/vue` still works — it re-exports the same kernel — but
30
- * new code should prefer `ubean/client`.)
31
59
  */
32
60
  declare const UBEAN_CLIENT_PRESET: InlinePreset;
33
61
  /**
34
- * Server-only symbols that come from the main `ubean` package.
35
- * These import the full ubean entry (which includes build tools like `vite`),
36
- * so they must only be used in server-side files (API routes, middleware, etc.).
62
+ * vue-router composables, sourced directly from `vue-router` (not re-exported
63
+ * through `ubean/client` third-party APIs are imported from their own packages).
64
+ */
65
+ declare const VUE_ROUTER_PRESET: InlinePreset;
66
+ /**
67
+ * vue-i18n Composition API, sourced directly from `vue-i18n` (ubean no longer
68
+ * wraps `useI18n` — same instance is exposed by the framework-installed
69
+ * vue-i18n plugin; `t` is destructured from the returned composer).
70
+ */
71
+ declare const VUE_I18N_PRESET: InlinePreset;
72
+ /**
73
+ * Server-only symbols sourced from the `ubean/server` aggregation entry
74
+ * (`@ubean/app` + `@ubean/routes` + `@ubean/server` + `@ubean/shared/node`).
75
+ * Sourcing from `ubean/server` (instead of the full `ubean` barrel) keeps
76
+ * build-time tooling (scan / build / cli, oxc-parser WASM…) out of the import
77
+ * closure, so these must still only be used in server-side files
78
+ * (API routes, middleware, etc.) — the closure still contains Hono and
79
+ * `node:*` builtins.
37
80
  *
38
81
  * Note: the isomorphic data composables (`useData` / `useAsyncData` /
39
82
  * `useFetch`) are intentionally NOT listed here — they are exported from
@@ -57,35 +100,41 @@ interface AutoImportResult {
57
100
  autoImportsDtsPath: string;
58
101
  componentsDtsPath: string;
59
102
  }
60
- declare function generateAutoImports(_scanResult: ScanResult, options: AutoImportOptions): Promise<AutoImportResult>;
103
+ declare function generateAutoImports(_scanResult: ScanResult, options: GenerateAutoImportsOptions): Promise<AutoImportResult>;
61
104
  declare function getBuiltinComposables(): Import[];
105
+ /** unplugin-auto-import 的组装结果(透传字段类型直接引用 unplugin 类型,避免跨包类型命名问题)。 */
106
+ interface UbeanAutoImportConfig {
107
+ imports: Options$1['imports'];
108
+ dirs: string[];
109
+ dts: Options$1['dts'];
110
+ vueTemplate: boolean;
111
+ eslintrc: Options$1['eslintrc'];
112
+ }
62
113
  declare function getUbeanAutoImportConfig(options?: {
63
114
  cwd?: string;
64
115
  srcDir?: string;
65
116
  buildDir?: string;
66
117
  composablesDirs?: string[];
67
- }): {
68
- imports: InlinePreset[];
118
+ /** `ubean.config.ts` 的 `autoImports` 配置(默认最小:仅 ubean 内置 API)。 */
119
+ autoImports?: boolean | AutoImportOptions;
120
+ }): UbeanAutoImportConfig;
121
+ /** unplugin-vue-components 的组装结果(类型直接引用 unplugin,理由同上)。 */
122
+ interface UbeanComponentsConfig {
69
123
  dirs: string[];
70
- dts: string;
71
- vueTemplate: boolean;
72
- eslintrc: {
73
- enabled: boolean;
74
- };
75
- };
124
+ extensions: string[];
125
+ directoryAsNamespace: boolean;
126
+ dts: Options['dts'];
127
+ deep: boolean;
128
+ }
76
129
  declare function getUbeanComponentsConfig(options?: {
77
130
  cwd?: string;
78
131
  srcDir?: string;
79
132
  buildDir?: string;
80
133
  componentsDirs?: string[];
81
134
  directoryAsNamespace?: boolean;
82
- }): {
83
- dirs: string[];
84
- extensions: string[];
85
- directoryAsNamespace: boolean;
86
- dts: string;
87
- deep: boolean;
88
- };
135
+ /** `ubean.config.ts` 的 `components` 配置。 */
136
+ components?: boolean | ComponentsOptions;
137
+ }): UbeanComponentsConfig;
89
138
  declare function generateImportsTransform(imports: Import[]): {
90
139
  code: string;
91
140
  map?: null;
@@ -168,7 +217,7 @@ interface CodegenManifest {
168
217
  generated: boolean;
169
218
  }>;
170
219
  }
171
- interface CodegenOptions extends Omit<AutoImportOptions, 'cwd' | 'srcDir' | 'buildDir'> {
220
+ interface CodegenOptions extends Omit<GenerateAutoImportsOptions, 'cwd' | 'srcDir' | 'buildDir'> {
172
221
  cwd: string;
173
222
  srcDir: string;
174
223
  buildDir: string;
@@ -183,4 +232,4 @@ interface CodegenResult {
183
232
  }
184
233
  declare function generateTypes(result: ScanResult, options: CodegenOptions): Promise<CodegenResult>;
185
234
  //#endregion
186
- export { type AutoImportOptions, type AutoImportResult, BUILTIN_PRESETS, CODEGEN_CONTRACT_VERSION, CODEGEN_FILES, CodegenFileContract, CodegenManifest, CodegenOptions, CodegenResult, type ComponentInfo, type GenerateOpenApiTypesOptions, HONO_OPENAPI_PRESET, type I18nTypesOptions, type Import, type InlinePreset, type PageTypesOptions, type RouteTypesOptions, UBEAN_CLIENT_PRESET, UBEAN_SERVER_PRESET, VUE_MACROS_PRESET, VUE_PRESET, generateAutoImports, generateI18nTypes, generateImportsTransform, generateOpenApiTypes, generateOpenApiTypesFromServer, generatePageTypes, generateRouteTypes, generateTypes, getBuiltinComposables, getUbeanAutoImportConfig, getUbeanComponentsConfig, messagesToTsType };
235
+ export { type AutoImportResult, BUILTIN_PRESETS, CODEGEN_CONTRACT_VERSION, CODEGEN_FILES, CodegenFileContract, CodegenManifest, CodegenOptions, CodegenResult, type ComponentInfo, type GenerateAutoImportsOptions, type GenerateOpenApiTypesOptions, HONO_OPENAPI_PRESET, type I18nTypesOptions, type Import, type InlinePreset, type PageTypesOptions, type ResolvedAutoImports, type ResolvedComponentsAutoImport, type RouteTypesOptions, UBEAN_CLIENT_PRESET, UBEAN_SERVER_PRESET, VUE_I18N_PRESET, VUE_MACROS_PRESET, VUE_PRESET, VUE_ROUTER_PRESET, generateAutoImports, generateI18nTypes, generateImportsTransform, generateOpenApiTypes, generateOpenApiTypesFromServer, generatePageTypes, generateRouteTypes, generateTypes, getAutoImportPresets, getBuiltinComposables, getUbeanAutoImportConfig, getUbeanComponentsConfig, messagesToTsType, resolveAutoImportsConfig, resolveComponentsConfig, toArray };
@@ -1,2 +1,2 @@
1
- import { _ as generateImportsTransform, a as generateOpenApiTypesFromServer, b as getUbeanComponentsConfig, c as generateI18nTypes, d as HONO_OPENAPI_PRESET, f as UBEAN_CLIENT_PRESET, g as generateAutoImports, h as VUE_PRESET, i as generateOpenApiTypes, l as messagesToTsType, m as VUE_MACROS_PRESET, n as CODEGEN_FILES, o as generatePageTypes, p as UBEAN_SERVER_PRESET, r as generateTypes, s as generateRouteTypes, t as CODEGEN_CONTRACT_VERSION, u as BUILTIN_PRESETS, v as getBuiltinComposables, y as getUbeanAutoImportConfig } from "../codegen-DX7zMgPZ.js";
2
- export { BUILTIN_PRESETS, CODEGEN_CONTRACT_VERSION, CODEGEN_FILES, HONO_OPENAPI_PRESET, UBEAN_CLIENT_PRESET, UBEAN_SERVER_PRESET, VUE_MACROS_PRESET, VUE_PRESET, generateAutoImports, generateI18nTypes, generateImportsTransform, generateOpenApiTypes, generateOpenApiTypesFromServer, generatePageTypes, generateRouteTypes, generateTypes, getBuiltinComposables, getUbeanAutoImportConfig, getUbeanComponentsConfig, messagesToTsType };
1
+ import { C as getUbeanComponentsConfig, E as toArray, S as getUbeanAutoImportConfig, T as resolveComponentsConfig, _ as VUE_ROUTER_PRESET, a as generateOpenApiTypesFromServer, b as getAutoImportPresets, c as generateI18nTypes, d as HONO_OPENAPI_PRESET, f as UBEAN_CLIENT_PRESET, g as VUE_PRESET, h as VUE_MACROS_PRESET, i as generateOpenApiTypes, l as messagesToTsType, m as VUE_I18N_PRESET, n as CODEGEN_FILES, o as generatePageTypes, p as UBEAN_SERVER_PRESET, r as generateTypes, s as generateRouteTypes, t as CODEGEN_CONTRACT_VERSION, u as BUILTIN_PRESETS, v as generateAutoImports, w as resolveAutoImportsConfig, x as getBuiltinComposables, y as generateImportsTransform } from "../codegen-BqqGw4Dv.js";
2
+ export { BUILTIN_PRESETS, CODEGEN_CONTRACT_VERSION, CODEGEN_FILES, HONO_OPENAPI_PRESET, UBEAN_CLIENT_PRESET, UBEAN_SERVER_PRESET, VUE_I18N_PRESET, VUE_MACROS_PRESET, VUE_PRESET, VUE_ROUTER_PRESET, generateAutoImports, generateI18nTypes, generateImportsTransform, generateOpenApiTypes, generateOpenApiTypesFromServer, generatePageTypes, generateRouteTypes, generateTypes, getAutoImportPresets, getBuiltinComposables, getUbeanAutoImportConfig, getUbeanComponentsConfig, messagesToTsType, resolveAutoImportsConfig, resolveComponentsConfig, toArray };
@@ -4,6 +4,42 @@ import { glob } from "tinyglobby";
4
4
  import { createUnimport, toTypeDeclarationFile } from "unimport";
5
5
  import openapiTS, { astToString } from "openapi-typescript";
6
6
  //#region src/codegen/auto-imports.ts
7
+ /** 将 `boolean | AutoImportOptions` 归一化为分库开关 + 透传选项。 */
8
+ function resolveAutoImportsConfig(input) {
9
+ const options = typeof input === "object" && input !== null ? input : {};
10
+ return {
11
+ enabled: input !== false,
12
+ ubean: options.ubean ?? true,
13
+ vue: options.vue ?? false,
14
+ vueRouter: options.vueRouter ?? false,
15
+ vueI18n: options.vueI18n ?? false,
16
+ honoOpenapi: options.honoOpenapi ?? false,
17
+ options
18
+ };
19
+ }
20
+ /** 按分库开关组装内置预设(顺序稳定:ubean client/server → vue → vue-router → vue-i18n → hono-openapi)。 */
21
+ function getAutoImportPresets(resolved) {
22
+ const presets = [];
23
+ if (resolved.ubean) presets.push(UBEAN_CLIENT_PRESET, UBEAN_SERVER_PRESET);
24
+ if (resolved.vue) presets.push(VUE_PRESET, VUE_MACROS_PRESET);
25
+ if (resolved.vueRouter) presets.push(VUE_ROUTER_PRESET);
26
+ if (resolved.vueI18n) presets.push(VUE_I18N_PRESET);
27
+ if (resolved.honoOpenapi) presets.push(HONO_OPENAPI_PRESET);
28
+ return presets;
29
+ }
30
+ /** 将 `boolean | ComponentsOptions` 归一化。 */
31
+ function resolveComponentsConfig(input) {
32
+ const options = typeof input === "object" && input !== null ? input : {};
33
+ return {
34
+ enabled: input !== false,
35
+ ubean: options.ubean ?? true,
36
+ options
37
+ };
38
+ }
39
+ /** unplugin 系选项普遍使用 `Arrayable<T>`,合并进数组前先归一化。 */
40
+ function toArray(value) {
41
+ return value === void 0 ? [] : Array.isArray(value) ? value : [value];
42
+ }
7
43
  const VUE_PRESET = {
8
44
  from: "vue",
9
45
  imports: [
@@ -81,8 +117,6 @@ const VUE_MACROS_PRESET = {
81
117
  * Client-safe symbols sourced from the first-class `ubean/client` entry.
82
118
  * These are safe to auto-import in Vue components (browser-side) because
83
119
  * `@ubean/client` has zero build-time dependencies and no `node:*` imports.
84
- * (`ubean/runtime/vue` still works — it re-exports the same kernel — but
85
- * new code should prefer `ubean/client`.)
86
120
  */
87
121
  const UBEAN_CLIENT_PRESET = {
88
122
  from: "ubean/client",
@@ -92,8 +126,6 @@ const UBEAN_CLIENT_PRESET = {
92
126
  "defineApp",
93
127
  "applyAppConfig",
94
128
  "createDefaultAppConfig",
95
- "t",
96
- "useI18n",
97
129
  "setLocale",
98
130
  "useLocalePath",
99
131
  "useSwitchLocalePath",
@@ -104,7 +136,6 @@ const UBEAN_CLIENT_PRESET = {
104
136
  "useSearch",
105
137
  "useSeoMeta",
106
138
  "usePage",
107
- "useRouter",
108
139
  "useHead",
109
140
  "useViewTransition",
110
141
  "useData",
@@ -128,9 +159,30 @@ const UBEAN_CLIENT_PRESET = {
128
159
  ]
129
160
  };
130
161
  /**
131
- * Server-only symbols that come from the main `ubean` package.
132
- * These import the full ubean entry (which includes build tools like `vite`),
133
- * so they must only be used in server-side files (API routes, middleware, etc.).
162
+ * vue-router composables, sourced directly from `vue-router` (not re-exported
163
+ * through `ubean/client` third-party APIs are imported from their own packages).
164
+ */
165
+ const VUE_ROUTER_PRESET = {
166
+ from: "vue-router",
167
+ imports: ["useRouter"]
168
+ };
169
+ /**
170
+ * vue-i18n Composition API, sourced directly from `vue-i18n` (ubean no longer
171
+ * wraps `useI18n` — same instance is exposed by the framework-installed
172
+ * vue-i18n plugin; `t` is destructured from the returned composer).
173
+ */
174
+ const VUE_I18N_PRESET = {
175
+ from: "vue-i18n",
176
+ imports: ["useI18n"]
177
+ };
178
+ /**
179
+ * Server-only symbols sourced from the `ubean/server` aggregation entry
180
+ * (`@ubean/app` + `@ubean/routes` + `@ubean/server` + `@ubean/shared/node`).
181
+ * Sourcing from `ubean/server` (instead of the full `ubean` barrel) keeps
182
+ * build-time tooling (scan / build / cli, oxc-parser WASM…) out of the import
183
+ * closure, so these must still only be used in server-side files
184
+ * (API routes, middleware, etc.) — the closure still contains Hono and
185
+ * `node:*` builtins.
134
186
  *
135
187
  * Note: the isomorphic data composables (`useData` / `useAsyncData` /
136
188
  * `useFetch`) are intentionally NOT listed here — they are exported from
@@ -140,7 +192,7 @@ const UBEAN_CLIENT_PRESET = {
140
192
  * the client preset only.
141
193
  */
142
194
  const UBEAN_SERVER_PRESET = {
143
- from: "ubean",
195
+ from: "ubean/server",
144
196
  imports: [
145
197
  "defineHandlerMeta",
146
198
  "defineAction",
@@ -165,6 +217,8 @@ const HONO_OPENAPI_PRESET = {
165
217
  };
166
218
  const BUILTIN_PRESETS = [
167
219
  UBEAN_CLIENT_PRESET,
220
+ VUE_ROUTER_PRESET,
221
+ VUE_I18N_PRESET,
168
222
  UBEAN_SERVER_PRESET,
169
223
  HONO_OPENAPI_PRESET
170
224
  ];
@@ -198,6 +252,14 @@ function transformImportPath(filePath, srcDir) {
198
252
  const posixSrcDir = toPosixPath(normalize(srcDir));
199
253
  return `~/${toPosixPath(relative(posixSrcDir, posixPath)).replace(/\.(ts|js|mts|mjs|cts|cjs|tsx|jsx)$/, "")}`;
200
254
  }
255
+ /**
256
+ * Bare package specifiers (`vue`, `vue-router`, `hono-openapi`, `ubean/client`…)
257
+ * keep their source in the generated dts; only project-relative files are
258
+ * rewritten to `~/` paths.
259
+ */
260
+ function isPackageSource(from) {
261
+ return !from.startsWith(".") && !from.startsWith("/") && !from.startsWith("~");
262
+ }
201
263
  async function scanComponentsDir(dir, srcDir, directoryAsNamespace, ignore = [
202
264
  "**/*.test.*",
203
265
  "**/*.spec.*",
@@ -232,27 +294,27 @@ async function scanComponentsDir(dir, srcDir, directoryAsNamespace, ignore = [
232
294
  return components;
233
295
  }
234
296
  async function generateAutoImports(_scanResult, options) {
235
- const { cwd, srcDir, buildDir, composablesDirs = [], componentsDirs = [], dirs = {}, imports: importsConfig, components: componentsConfig } = options;
297
+ const { cwd, srcDir, buildDir, dirs = {}, autoImports: autoImportsInput, components: componentsInput } = options;
236
298
  const outDir = join(cwd, buildDir);
237
299
  await mkdir(outDir, { recursive: true });
238
- const autoImportEnabled = importsConfig?.autoImport !== false;
239
- const componentAutoImportEnabled = componentsConfig?.autoImport !== false;
240
- const directoryAsNamespace = componentsConfig?.directoryAsNamespace ?? false;
300
+ const resolvedAutoImports = resolveAutoImportsConfig(autoImportsInput);
301
+ const resolvedComponents = resolveComponentsConfig(componentsInput);
302
+ const directoryAsNamespace = resolvedComponents.options.directoryAsNamespace ?? false;
241
303
  const composablesDir = dirs.composables || "composables";
242
304
  const componentsDir = dirs.components || "components";
243
305
  let composablesImports = [];
244
306
  let components = [];
245
307
  const autoImportsDtsPath = join(outDir, "auto-imports.d.ts");
246
308
  const componentsDtsPath = join(outDir, "components.d.ts");
247
- if (autoImportEnabled) {
248
- const allComposablesDirs = [join(srcDir, composablesDir), ...composablesDirs];
309
+ if (resolvedAutoImports.enabled) {
310
+ const allComposablesDirs = [join(srcDir, composablesDir), ...resolvedAutoImports.options.dirs ?? []];
249
311
  const existingDirs = [];
250
312
  for (const dir of allComposablesDirs) try {
251
313
  const { statSync } = await import("node:fs");
252
314
  if (statSync(dir).isDirectory()) existingDirs.push(dir);
253
315
  } catch {}
254
316
  const unimport = createUnimport({
255
- presets: BUILTIN_PRESETS,
317
+ presets: getAutoImportPresets(resolvedAutoImports),
256
318
  dirs: existingDirs,
257
319
  dirsScanOptions: {
258
320
  cwd: srcDir,
@@ -262,20 +324,20 @@ async function generateAutoImports(_scanResult, options) {
262
324
  });
263
325
  await unimport.init();
264
326
  composablesImports = (await unimport.getImports()).map((imp) => {
265
- if (imp.from === "vue" || imp.from === "vue/macros" || imp.from === "ubean" || imp.from.startsWith("ubean/")) return imp;
327
+ if (isPackageSource(imp.from)) return imp;
266
328
  return {
267
329
  ...imp,
268
330
  from: transformImportPath(imp.from, srcDir)
269
331
  };
270
332
  });
271
333
  const dtsContent = toTypeDeclarationFile(composablesImports, { resolvePath: (imp) => {
272
- if (imp.from === "vue" || imp.from === "vue/macros" || imp.from === "ubean" || imp.from.startsWith("ubean/")) return imp.from;
334
+ if (isPackageSource(imp.from)) return imp.from;
273
335
  return transformImportPath(imp.from, srcDir);
274
336
  } });
275
337
  await writeFile(autoImportsDtsPath, dtsContent, "utf-8");
276
338
  } else await writeFile(autoImportsDtsPath, "// Auto-generated by ubean - auto-imports disabled\n/* eslint-disable */\n// @ts-nocheck\nexport {}\n", "utf-8");
277
- if (componentAutoImportEnabled) {
278
- const allComponentsDirs = [join(srcDir, componentsDir), ...componentsDirs];
339
+ if (resolvedComponents.enabled) {
340
+ const allComponentsDirs = [join(srcDir, componentsDir), ...resolvedComponents.options.dirs ?? []];
279
341
  for (const dir of allComponentsDirs) {
280
342
  const scanned = await scanComponentsDir(dir, srcDir, directoryAsNamespace);
281
343
  components.push(...scanned);
@@ -350,29 +412,37 @@ function getUbeanAutoImportConfig(options = {}) {
350
412
  const cwd = options.cwd || process.cwd();
351
413
  const srcDir = options.srcDir || join(cwd, "src");
352
414
  const buildDir = options.buildDir || ".ubean";
353
- const composablesDirs = [join(srcDir, "composables"), ...options.composablesDirs || []];
415
+ const composablesDirName = "composables";
416
+ const resolved = resolveAutoImportsConfig(options.autoImports);
417
+ const composablesDirs = [
418
+ join(srcDir, composablesDirName),
419
+ ...resolved.options.dirs ?? [],
420
+ ...options.composablesDirs || []
421
+ ];
354
422
  return {
355
- imports: [
356
- UBEAN_CLIENT_PRESET,
357
- UBEAN_SERVER_PRESET,
358
- HONO_OPENAPI_PRESET
359
- ],
423
+ imports: [...getAutoImportPresets(resolved), ...toArray(resolved.options.imports)],
360
424
  dirs: composablesDirs,
361
- dts: join(cwd, buildDir, "auto-imports.d.ts"),
362
- vueTemplate: true,
363
- eslintrc: { enabled: false }
425
+ dts: resolved.options.dts === void 0 ? join(cwd, buildDir, "auto-imports.d.ts") : resolved.options.dts,
426
+ vueTemplate: resolved.options.vueTemplate ?? true,
427
+ eslintrc: resolved.options.eslintrc ?? { enabled: false }
364
428
  };
365
429
  }
366
430
  function getUbeanComponentsConfig(options = {}) {
367
431
  const cwd = options.cwd || process.cwd();
368
432
  const srcDir = options.srcDir || join(cwd, "src");
369
433
  const buildDir = options.buildDir || ".ubean";
434
+ const componentsDirName = "components";
435
+ const resolved = resolveComponentsConfig(options.components);
370
436
  return {
371
- dirs: [join(srcDir, "components"), ...options.componentsDirs || []],
437
+ dirs: [
438
+ join(srcDir, componentsDirName),
439
+ ...resolved.options.dirs ?? [],
440
+ ...options.componentsDirs || []
441
+ ],
372
442
  extensions: ["vue"],
373
- directoryAsNamespace: options.directoryAsNamespace ?? false,
374
- dts: join(cwd, buildDir, "components.d.ts"),
375
- deep: true
443
+ directoryAsNamespace: resolved.options.directoryAsNamespace ?? options.directoryAsNamespace ?? false,
444
+ dts: resolved.options.dts === void 0 ? join(cwd, buildDir, "components.d.ts") : resolved.options.dts,
445
+ deep: resolved.options.deep ?? true
376
446
  };
377
447
  }
378
448
  function generateImportsTransform(imports) {
@@ -698,4 +768,4 @@ async function generateTypes(result, options) {
698
768
  };
699
769
  }
700
770
  //#endregion
701
- export { generateImportsTransform as _, generateOpenApiTypesFromServer as a, getUbeanComponentsConfig as b, generateI18nTypes as c, HONO_OPENAPI_PRESET as d, UBEAN_CLIENT_PRESET as f, generateAutoImports as g, VUE_PRESET as h, generateOpenApiTypes as i, messagesToTsType as l, VUE_MACROS_PRESET as m, CODEGEN_FILES as n, generatePageTypes as o, UBEAN_SERVER_PRESET as p, generateTypes as r, generateRouteTypes as s, CODEGEN_CONTRACT_VERSION as t, BUILTIN_PRESETS as u, getBuiltinComposables as v, getUbeanAutoImportConfig as y };
771
+ export { getUbeanComponentsConfig as C, toArray as E, getUbeanAutoImportConfig as S, resolveComponentsConfig as T, VUE_ROUTER_PRESET as _, generateOpenApiTypesFromServer as a, getAutoImportPresets as b, generateI18nTypes as c, HONO_OPENAPI_PRESET as d, UBEAN_CLIENT_PRESET as f, VUE_PRESET as g, VUE_MACROS_PRESET as h, generateOpenApiTypes as i, messagesToTsType as l, VUE_I18N_PRESET as m, CODEGEN_FILES as n, generatePageTypes as o, UBEAN_SERVER_PRESET as p, generateTypes as r, generateRouteTypes as s, CODEGEN_CONTRACT_VERSION as t, BUILTIN_PRESETS as u, generateAutoImports as v, resolveAutoImportsConfig as w, getBuiltinComposables as x, generateImportsTransform as y };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { a as useVirtualRegistry, i as resetVirtualRegistry, n as defineVirtualModule, r as defineVirtualModulePrefix, t as VirtualModuleRegistry } from "./virtual-registry-BWkaQHXN.js";
2
- import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, o as stripMacros, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-D5WBA3u7.js";
2
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, o as stripMacros, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-vLkLkAfT.js";
3
3
  import { a as ssrSingletonProdOptimizeExclude, c as getCssImports, d as resetModuleRegistry, i as ssrSingletonDevPolicy, l as registerComponentResolver, n as SSR_SINGLETON_OPTIMIZE_EXCLUDE, o as ssrSingletonProdSsr, r as SSR_SINGLETON_PACKAGES, s as getComponentResolvers, t as SSR_SINGLETON_DEDUPE, u as registerCssImport } from "./ssr-singleton-CEQi_H6-.js";
4
4
  export { SSR_SINGLETON_DEDUPE, SSR_SINGLETON_OPTIMIZE_EXCLUDE, SSR_SINGLETON_PACKAGES, VirtualModuleRegistry, createAppVirtualModule, createLocalesVirtualModule, createMetaVirtualModule, createPagesVirtualModule, createRoutingVirtualModule, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, registerComponentResolver, registerCssImport, resetModuleRegistry, resetVirtualRegistry, ssrSingletonDevPolicy, ssrSingletonProdOptimizeExclude, ssrSingletonProdSsr, stripMacros, transformMacros, useVirtualRegistry };
@@ -1,8 +1,8 @@
1
1
  import { a as useVirtualRegistry } from "./virtual-registry-BWkaQHXN.js";
2
- import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, t as createAppVirtualModule } from "./virtual-modules-D5WBA3u7.js";
2
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, t as createAppVirtualModule } from "./virtual-modules-vLkLkAfT.js";
3
3
  import { a as ssrSingletonProdOptimizeExclude, o as ssrSingletonProdSsr } from "./ssr-singleton-CEQi_H6-.js";
4
- import { n as localeVueParamFromI18n, r as serializeI18nConfig, t as ubeanPlugin } from "./vite-B3y8Qoan.js";
5
- import { a as createVueAppEntryVirtualModule, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, t as VUE_PLUGIN_INCLUDE } from "./vue-JEYc4beF.js";
4
+ import { n as localeVueParamFromI18n, r as serializeI18nConfig, t as ubeanPlugin } from "./vite-D2EZl_6P.js";
5
+ import { a as createVueAppEntryVirtualModule, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, t as VUE_PLUGIN_INCLUDE } from "./vue-I5nC0ldj.js";
6
6
  import { join, relative, resolve } from "pathe";
7
7
  import { resolveModules } from "@ubean/config";
8
8
  import { build } from "vite";
@@ -132,7 +132,7 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir,
132
132
  pageMeta: scanResult.notFoundPage.pageMeta
133
133
  } : null);
134
134
  const colorModeScript = config.colorMode !== false ? getColorModeScript(resolveColorModeConfig(config.colorMode)) : "";
135
- const rendererImport = ssrEnabled ? `import { createVueRenderer } from 'ubean/vue-ssr';` : "";
135
+ const rendererImport = ssrEnabled ? `import { createVueRenderer } from 'ubean/ssr';` : "";
136
136
  const prodLocaleVueParam = localeVueParamFromI18n(config.i18n) || "";
137
137
  const rendererSetup = ssrEnabled ? `
138
138
  // --- SSR renderer setup ---
@@ -202,7 +202,7 @@ ${contentEntries.map(([name, docs]) => `registerContent(${JSON.stringify(name)},
202
202
  ` : "";
203
203
  if (hasServer) {
204
204
  const serverEntry = `// Auto-generated server entry
205
- import { createUbeanApp, applyServerConfig } from 'ubean/runtime/app';
205
+ import { createUbeanApp, applyServerConfig } from 'ubean/server';
206
206
  import { toVueRouterLocalePath } from '@ubean/i18n';
207
207
  import 'ubean:locales';
208
208
  ${rendererImport}
@@ -262,7 +262,7 @@ const defaultCode = ${defaultCode};
262
262
 
263
263
  let i18nRuntime = null;
264
264
  if (import.meta.env.SSR) {
265
- i18nRuntime = await import('ubean/runtime/i18n');
265
+ i18nRuntime = await import('ubean/i18n');
266
266
  if (i18nConfig && i18nConfig.fallbackLocale) {
267
267
  i18nRuntime.setFallbackLocale(i18nConfig.fallbackLocale);
268
268
  } else if (defaultCode) {
@@ -1,5 +1,5 @@
1
1
  import { a as useVirtualRegistry } from "./virtual-registry-BWkaQHXN.js";
2
- import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-D5WBA3u7.js";
2
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-vLkLkAfT.js";
3
3
  import { join, relative, resolve } from "pathe";
4
4
  import { loadUbeanConfig, tryGetConfig } from "@ubean/config";
5
5
  import { createServerRouter } from "@ubean/routes";
package/dist/vite.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as ubeanPlugin } from "./vite-B3y8Qoan.js";
1
+ import { t as ubeanPlugin } from "./vite-D2EZl_6P.js";
2
2
  export { ubeanPlugin };
@@ -1,6 +1,6 @@
1
1
  import { a as useVirtualRegistry, n as defineVirtualModule } from "./virtual-registry-BWkaQHXN.js";
2
2
  import { c as getCssImports, i as ssrSingletonDevPolicy, s as getComponentResolvers } from "./ssr-singleton-CEQi_H6-.js";
3
- import { f as UBEAN_CLIENT_PRESET, p as UBEAN_SERVER_PRESET } from "./codegen-DX7zMgPZ.js";
3
+ import { E as toArray, T as resolveComponentsConfig, b as getAutoImportPresets, w as resolveAutoImportsConfig } from "./codegen-BqqGw4Dv.js";
4
4
  import { createRequire } from "node:module";
5
5
  import { join, resolve } from "pathe";
6
6
  import { scanProject } from "@ubean/scan";
@@ -44,18 +44,19 @@ function createVueAppEntryVirtualModule(appEntry = EMPTY_APP_ENTRY) {
44
44
  const hasSharedApp = appEntry.shared.exists;
45
45
  const hasServerApp = appEntry.server.exists;
46
46
  const hasClientApp = appEntry.client.exists;
47
+ const hasRootApp = appEntry.root?.exists;
47
48
  return `${`
48
49
  // Auto-generated by ubean - do not edit
49
50
  /* eslint-disable */
50
51
  ${hasSharedApp ? `import _sharedApp from ${JSON.stringify(appEntry.shared.fullPath)};` : "const _sharedApp = null;"}
51
52
  ${hasServerApp ? `import _serverApp from ${JSON.stringify(appEntry.server.fullPath)};` : "const _serverApp = null;"}
52
53
  ${hasClientApp ? `import _clientApp from ${JSON.stringify(appEntry.client.fullPath)};` : "const _clientApp = null;"}
54
+ ${hasRootApp ? `import _rootApp from ${JSON.stringify(appEntry.root.fullPath)};` : "const _rootApp = null;"}
53
55
 
54
56
  import {
55
57
  createUbeanClientApp,
56
58
  createUbeanSSRApp,
57
59
  usePage,
58
- useRouter,
59
60
  useHead,
60
61
  useSeoMeta,
61
62
  Link,
@@ -72,6 +73,8 @@ import {
72
73
  scheduleIslandHydration,
73
74
  configureI18nRuntime
74
75
  } from 'ubean/client';
76
+ // useRouter 由 vue-router 直源(ubean 不再透传第三方 API)
77
+ import { useRouter } from 'vue-router';
75
78
 
76
79
  import { i18nConfig as _i18nConfig, loadLocale as _loadLocale } from 'ubean:locales';
77
80
 
@@ -147,6 +150,7 @@ function _mergeAppConfig(base, ...configs) {
147
150
  if (cfg.onClientReady) result.onClientReady = cfg.onClientReady;
148
151
  if (cfg.errorComponent) result.errorComponent = cfg.errorComponent;
149
152
  if (cfg.loadingComponent) result.loadingComponent = cfg.loadingComponent;
153
+ if (cfg.appRoot) result.appRoot = cfg.appRoot;
150
154
  if (cfg.viewTransitions !== undefined) result.viewTransitions = cfg.viewTransitions;
151
155
  if (cfg.serializeState) result.serializeState = cfg.serializeState;
152
156
  if (cfg.hydrateState) result.hydrateState = cfg.hydrateState;
@@ -172,6 +176,12 @@ function _mergeAppConfig(base, ...configs) {
172
176
 
173
177
  export function resolveAppConfig(mode) {
174
178
  const base = createDefaultAppConfig();
179
+ // src/app.vue / src/App.vue 自动检测(小写优先)作为默认 appRoot;
180
+ // 显式 defineApp({ appRoot }) 在下方 merge 时按"后者覆盖"盖过它。
181
+ // 注入 base 而非在消费点 || _rootApp,保证走 resolveAppConfig('server')
182
+ // 的 dev/prod SSR(经 @ubean/client/ssr 的 createVueRenderer)与客户端
183
+ // resolveAppConfig('client') 读到一致的 appRoot → 水合结构不 mismatch。
184
+ if (_rootApp) base.appRoot = _rootApp;
175
185
  if (!_sharedApp && !_serverApp && !_clientApp) return base;
176
186
 
177
187
  const sharedCfg = typeof _sharedApp === 'function' ? _sharedApp() : _sharedApp;
@@ -225,7 +235,9 @@ export async function createApp() {
225
235
  hydrate: !!initialPage,
226
236
  routerSetup: config.router?.setup,
227
237
  loadingComponent,
228
- errorComponent
238
+ errorComponent,
239
+ // appRoot 已在 resolveAppConfig 中合并(src/App.vue 默认 + defineApp 显式覆盖)
240
+ appRoot: config.appRoot
229
241
  });
230
242
 
231
243
  applyAppConfig(instance.app, config, 'client');
@@ -308,7 +320,10 @@ export async function createSSRApp(initialPage) {
308
320
  head,
309
321
  routerSetup: config.router?.setup,
310
322
  loadingComponent,
311
- errorComponent
323
+ errorComponent,
324
+ // appRoot 已在 resolveAppConfig 中合并(src/App.vue 默认 + defineApp 显式覆盖),
325
+ // 客户端水合同理会从 resolveAppConfig('client') 读到一致的值。
326
+ appRoot: config.appRoot
312
327
  });
313
328
 
314
329
  applyAppConfig(app, config, 'server');
@@ -355,7 +370,7 @@ import {
355
370
  defineServer,
356
371
  createDefaultServerConfig,
357
372
  mergeServerConfigs
358
- } from 'ubean/runtime/app';
373
+ } from 'ubean/server';
359
374
 
360
375
  export {
361
376
  defineServer,
@@ -437,14 +452,13 @@ function ubeanVite(options) {
437
452
  const dtsDir = join(ubeanConfig.rootDir, ".ubean");
438
453
  const markdownEnabled = ubeanConfig.markdown?.enabled !== false;
439
454
  const mdxEnabled = ubeanConfig.markdown?.mdx === true;
440
- const autoImportEnabled = ubeanConfig.imports.autoImport !== false;
441
- const componentAutoImportEnabled = ubeanConfig.components.autoImport !== false;
455
+ const autoImports = resolveAutoImportsConfig(ubeanConfig.autoImports);
456
+ const componentsAutoImport = resolveComponentsConfig(ubeanConfig.components);
442
457
  const markdownComponentsAutoImport = ubeanConfig.markdown?.components?.autoImport !== false;
443
- const directoryAsNamespace = ubeanConfig.components.directoryAsNamespace ?? false;
444
458
  const composablesDirName = ubeanConfig.dir.composables || "composables";
445
459
  const componentsDirName = ubeanConfig.dir.components || "components";
446
- const composablesDirs = [join(srcDir, composablesDirName), ...ubeanConfig.imports.dirs || []];
447
- const componentsDirs = [join(srcDir, componentsDirName), ...ubeanConfig.components.dirs || []];
460
+ const composablesDirs = [join(srcDir, composablesDirName), ...autoImports.options.dirs ?? []];
461
+ const componentsDirs = [join(srcDir, componentsDirName), ...componentsAutoImport.options.dirs ?? []];
448
462
  const mdExtensions = mdxEnabled ? ["md", "mdx"] : ["md"];
449
463
  function getVirtualModule(virtualId) {
450
464
  return virtualRegistry.getModules().find((m) => m.id === virtualId);
@@ -561,7 +575,7 @@ function ubeanVite(options) {
561
575
  for (const dir of watchDirs) server.watcher.add(join(srcDir, dir));
562
576
  async function handleFileChange(file) {
563
577
  const rel = file.replace(`${srcDir}/`, "");
564
- const isAppFile = /^app(\.(server|client))?\.(ts|js|mjs|mts)$/.test(rel);
578
+ const isAppFile = /^(app(\.(server|client))?|App)\.(ts|js|mjs|mts|vue)$/.test(rel);
565
579
  const isServerFile = /^server(\.(dev|prod))?\.(ts|js|mjs|mts)$/.test(rel);
566
580
  const isMarkdownFile = new RegExp(`\\.(${mdExtensions.join("|")})$`).test(rel);
567
581
  if (isAppFile || isServerFile || watchDirs.some((d) => rel.startsWith(`${d}/`)) || isMarkdownFile) {
@@ -600,13 +614,17 @@ function ubeanVite(options) {
600
614
  remarkPlugins: ubeanConfig.markdown?.remarkPlugins || [],
601
615
  rehypePlugins: ubeanConfig.markdown?.rehypePlugins || []
602
616
  }));
603
- if (autoImportEnabled) plugins.push(AutoImport({
604
- imports: [UBEAN_CLIENT_PRESET, UBEAN_SERVER_PRESET],
605
- dirs: composablesDirs,
606
- dts: join(dtsDir, "auto-imports.d.ts"),
607
- vueTemplate: true,
608
- eslintrc: { enabled: false }
609
- }));
617
+ if (autoImports.enabled) {
618
+ const userAutoImports = autoImports.options;
619
+ plugins.push(AutoImport({
620
+ vueTemplate: true,
621
+ eslintrc: { enabled: false },
622
+ ...userAutoImports,
623
+ imports: [...getAutoImportPresets(autoImports), ...toArray(userAutoImports.imports)],
624
+ dirs: composablesDirs,
625
+ dts: userAutoImports.dts === void 0 ? join(dtsDir, "auto-imports.d.ts") : userAutoImports.dts
626
+ }));
627
+ }
610
628
  const UBEAN_BUILTIN_COMPONENTS = [
611
629
  "Link",
612
630
  "Head",
@@ -618,13 +636,14 @@ function ubeanVite(options) {
618
636
  from: "ubean/client"
619
637
  };
620
638
  }
621
- const dynamicResolvers = [ubeanComponentsResolver, (name) => {
639
+ const dynamicResolvers = [...componentsAutoImport.ubean ? [ubeanComponentsResolver] : [], (name) => {
622
640
  for (const resolver of getComponentResolvers()) {
623
641
  const result = typeof resolver === "function" ? resolver(name) : resolver.resolve(name);
624
642
  if (result) return result;
625
643
  }
626
644
  }];
627
- if (componentAutoImportEnabled) {
645
+ if (componentsAutoImport.enabled) {
646
+ const userComponents = componentsAutoImport.options;
628
647
  const extensions = ["vue"];
629
648
  const includePatterns = [/\.vue$/, /\.vue\?vue/];
630
649
  if (markdownEnabled && markdownComponentsAutoImport) {
@@ -633,13 +652,13 @@ function ubeanVite(options) {
633
652
  if (mdxEnabled) includePatterns.push(/\.mdx$/);
634
653
  }
635
654
  plugins.push(Components({
655
+ deep: true,
656
+ ...userComponents,
636
657
  dirs: componentsDirs,
637
658
  extensions,
638
659
  include: includePatterns,
639
- directoryAsNamespace,
640
- dts: join(dtsDir, "components.d.ts"),
641
- deep: true,
642
- resolvers: dynamicResolvers
660
+ dts: userComponents.dts === void 0 ? join(dtsDir, "components.d.ts") : userComponents.dts,
661
+ resolvers: [...dynamicResolvers, ...toArray(userComponents.resolvers)]
643
662
  }));
644
663
  } else plugins.push(Components({
645
664
  dts: true,
package/dist/vue.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as createVueAppEntryVirtualModule, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, t as VUE_PLUGIN_INCLUDE } from "./vue-JEYc4beF.js";
1
+ import { a as createVueAppEntryVirtualModule, i as createServerEntryVirtualModule, n as ubeanVite, o as createVuePagesVirtualModule, r as createClientEntryVirtualModule, t as VUE_PLUGIN_INCLUDE } from "./vue-I5nC0ldj.js";
2
2
  export { VUE_PLUGIN_INCLUDE, createClientEntryVirtualModule, createServerEntryVirtualModule, createVueAppEntryVirtualModule, createVuePagesVirtualModule, ubeanVite as default, ubeanVite };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/build",
3
- "version": "0.3.6",
3
+ "version": "0.4.0",
4
4
  "description": "Vite plugins, production build, SSG prerender, type codegen, and Server Actions plugin for ubean",
5
5
  "files": [
6
6
  "dist"
@@ -41,17 +41,17 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@intlify/unplugin-vue-i18n": "11.2.5",
44
- "@ubean/client": "0.3.6",
45
- "@ubean/config": "0.3.6",
46
- "@ubean/i18n": "0.3.6",
47
- "@ubean/islands": "0.3.6",
48
- "@ubean/markdown": "0.3.6",
49
- "@ubean/pages": "0.3.6",
50
- "@ubean/preset": "0.3.6",
51
- "@ubean/routes": "0.3.6",
52
- "@ubean/scan": "0.3.6",
53
- "@ubean/shared": "0.3.6",
54
- "@ubean/vue": "0.3.6",
44
+ "@ubean/client": "0.4.0",
45
+ "@ubean/config": "0.4.0",
46
+ "@ubean/i18n": "0.4.0",
47
+ "@ubean/islands": "0.4.0",
48
+ "@ubean/markdown": "0.4.0",
49
+ "@ubean/pages": "0.4.0",
50
+ "@ubean/preset": "0.4.0",
51
+ "@ubean/routes": "0.4.0",
52
+ "@ubean/scan": "0.4.0",
53
+ "@ubean/shared": "0.4.0",
54
+ "@ubean/vue": "0.4.0",
55
55
  "@vitejs/plugin-vue": "^6.0.8",
56
56
  "openapi-typescript": "^7.13.0",
57
57
  "oxc-transform": "^0.147.0",