@ubean/build 0.7.1 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -165,9 +165,10 @@ interface I18nTypesOptions {
165
165
  /** Convert a JSON message tree into a TypeScript object type body. */
166
166
  export declare function messagesToTsType(value: unknown, indent?: number): string;
167
167
  /**
168
- * Generate `.ubean/i18n.d.ts` augmenting vue-i18n `DefineLocaleMessage`
169
- * from the default locale JSON. Users can also hand-write the same
170
- * module augmentation if they prefer.
168
+ * Generate `.ubean/i18n.d.ts` augmenting vue-i18n `DefineLocaleMessage` from
169
+ * the default locale JSON, plus `GeneratedTypeConfig['locale']` from the
170
+ * scanned locale codes. The two halves are independent: message keys need a
171
+ * JSON source, the locale union only needs the locale files to exist.
171
172
  */
172
173
  export declare function generateI18nTypes(result: ScanResult, options: I18nTypesOptions): Promise<string | null>;
173
174
  //#endregion
@@ -1 +1 @@
1
- export { d as BUILTIN_PRESETS, t as CODEGEN_CONTRACT_VERSION, n as CODEGEN_FILES, r as CODEGEN_NON_CONTRACT_FILES, p as HONO_OPENAPI_PRESET, m as UBEAN_CLIENT_PRESET, h as UBEAN_SERVER_PRESET, g as VUE_I18N_PRESET, _ as VUE_MACROS_PRESET, v as VUE_PRESET, y as VUE_ROUTER_PRESET, b as generateAutoImports, l as generateI18nTypes, x as generateImportsTransform, a as generateOpenApiTypes, o as generateOpenApiTypesFromServer, s as generatePageTypes, c as generateRouteTypes, i as generateTypes, S as getAutoImportPresets, C as getBuiltinComposables, w as getUbeanAutoImportConfig, T as getUbeanComponentsConfig, u as messagesToTsType, E as resolveAutoImportsConfig, D as resolveComponentsConfig, O as toArray } from "../codegen-Dw-uws16.js";
1
+ export { d as BUILTIN_PRESETS, t as CODEGEN_CONTRACT_VERSION, n as CODEGEN_FILES, r as CODEGEN_NON_CONTRACT_FILES, p as HONO_OPENAPI_PRESET, m as UBEAN_CLIENT_PRESET, h as UBEAN_SERVER_PRESET, g as VUE_I18N_PRESET, _ as VUE_MACROS_PRESET, v as VUE_PRESET, y as VUE_ROUTER_PRESET, b as generateAutoImports, l as generateI18nTypes, x as generateImportsTransform, a as generateOpenApiTypes, o as generateOpenApiTypesFromServer, s as generatePageTypes, c as generateRouteTypes, i as generateTypes, S as getAutoImportPresets, C as getBuiltinComposables, w as getUbeanAutoImportConfig, T as getUbeanComponentsConfig, u as messagesToTsType, E as resolveAutoImportsConfig, D as resolveComponentsConfig, O as toArray } from "../codegen-DUQT79IR.js";
@@ -753,34 +753,55 @@ function pickDefaultLocaleFile(locales, defaultLocale) {
753
753
  return jsonFiles.find((l) => l.isDefault) || jsonFiles[0];
754
754
  }
755
755
  /**
756
- * Generate `.ubean/i18n.d.ts` augmenting vue-i18n `DefineLocaleMessage`
757
- * from the default locale JSON. Users can also hand-write the same
758
- * module augmentation if they prefer.
756
+ * Locale codes scanned from `src/locales/` → vue-i18n `GeneratedTypeConfig`.
757
+ *
758
+ * `@intlify/core-base` derives `Locale = GeneratedLocale` from this interface
759
+ * (`core-base.d.ts`: `Locale = IsNever<GeneratedLocale> extends true ? string : GeneratedLocale`),
760
+ * so every `Composer.locale` / `createI18n({ locale })` surface narrows to the
761
+ * union. Requires the leading `export {}` in the emitted file — without it the
762
+ * `declare module` is not a module augmentation and silently does nothing.
763
+ */
764
+ function localeUnionType(locales) {
765
+ const codes = [...new Set(locales.map((l) => l.code))];
766
+ if (codes.length === 0) return null;
767
+ return codes.map((c) => JSON.stringify(c)).join(" | ");
768
+ }
769
+ /**
770
+ * Generate `.ubean/i18n.d.ts` augmenting vue-i18n `DefineLocaleMessage` from
771
+ * the default locale JSON, plus `GeneratedTypeConfig['locale']` from the
772
+ * scanned locale codes. The two halves are independent: message keys need a
773
+ * JSON source, the locale union only needs the locale files to exist.
759
774
  */
760
775
  async function generateI18nTypes(result, options) {
761
776
  const { outDir, fileName = "i18n.d.ts", defaultLocale } = options;
762
- const source = pickDefaultLocaleFile(result.locales || [], defaultLocale);
763
- if (!source) return null;
764
- let raw;
765
- try {
777
+ const locales = result.locales || [];
778
+ const localeUnion = localeUnionType(locales);
779
+ const source = pickDefaultLocaleFile(locales, defaultLocale);
780
+ let messages = null;
781
+ if (source) try {
766
782
  const text = await readFile(source.fullPath, "utf8");
767
- raw = JSON.parse(text);
783
+ messages = unwrapMessages(JSON.parse(text));
768
784
  } catch {
769
- return null;
785
+ messages = null;
770
786
  }
771
- const messages = unwrapMessages(raw);
772
- if (!messages) return null;
773
- const typeBody = messagesToTsType(messages, 2);
774
- const contents = `// Auto-generated by ubean from ${source.relativePath} — do not edit manually
775
- // Typed \`t('key')\` via vue-i18n \`DefineLocaleMessage\`.
776
- // Override by adding your own \`declare module 'vue-i18n'\` in src/.
787
+ if (!messages && !localeUnion) return null;
788
+ const contents = `${`// Auto-generated by ubean ${source ? `from ${source.relativePath}` : "from scanned locale codes"} — do not edit manually
789
+ // Typed \`t('key')\` via vue-i18n \`DefineLocaleMessage\` and \`Locale\` via
790
+ // \`@intlify/core-base\` \`GeneratedTypeConfig\`.
791
+ // Override by adding your own \`declare module\` in src/.
777
792
  /* eslint-disable */
778
793
  export {};
779
-
794
+ `}${messages ? `
780
795
  declare module 'vue-i18n' {
781
- export interface DefineLocaleMessage ${typeBody}
796
+ export interface DefineLocaleMessage ${messagesToTsType(messages, 2)}
797
+ }
798
+ ` : ""}${localeUnion ? `
799
+ declare module '@intlify/core-base' {
800
+ export interface GeneratedTypeConfig {
801
+ locale: ${localeUnion};
802
+ }
782
803
  }
783
- `;
804
+ ` : ""}`;
784
805
  await mkdir(outDir, { recursive: true });
785
806
  const outPath = join(outDir, fileName);
786
807
  await writeFile(outPath, contents, "utf8");
@@ -882,6 +903,10 @@ async function generatePageTypes(result, options) {
882
903
  " pageMeta?: unknown;",
883
904
  " /** `definePage({ redirect })`。 */",
884
905
  " redirect?: string | null;",
906
+ " /** 是否为框架内置路由(Root / NotFound)。宿主生成菜单时应过滤。 */",
907
+ " isBuiltin?: boolean;",
908
+ " /** 是否为全局捕获路由(`pages/404.vue`)。 */",
909
+ " isGlobalCatchAll?: boolean;",
885
910
  " }",
886
911
  "",
887
912
  " export interface LayoutInfo {",
@@ -984,7 +1009,7 @@ const CODEGEN_FILES = [
984
1009
  name: "i18n.d.ts",
985
1010
  module: "vue-i18n",
986
1011
  required: false,
987
- types: ["DefineLocaleMessage"]
1012
+ types: ["DefineLocaleMessage", "GeneratedTypeConfig"]
988
1013
  },
989
1014
  {
990
1015
  name: "auto-imports.d.ts",
@@ -1025,7 +1050,10 @@ async function generateTypes(result, options) {
1025
1050
  generated.push(routeTypesPath);
1026
1051
  const pageTypesPath = await generatePageTypes(result, { outDir });
1027
1052
  generated.push(pageTypesPath);
1028
- const i18nTypesPath = await generateI18nTypes(result, { outDir });
1053
+ const i18nTypesPath = await generateI18nTypes(result, {
1054
+ outDir,
1055
+ defaultLocale: result.defaultLocale
1056
+ });
1029
1057
  if (i18nTypesPath) generated.push(i18nTypesPath);
1030
1058
  const envTypesPath = await generateEnvTypes({
1031
1059
  outDir,
package/dist/index.d.ts CHANGED
@@ -116,6 +116,8 @@ interface PagesModulePage extends CompiledPage {
116
116
  pageKind?: 'component' | 'reuse' | 'meta';
117
117
  pageMeta?: unknown;
118
118
  redirect?: string;
119
+ isBuiltin?: boolean;
120
+ isGlobalCatchAll?: boolean;
119
121
  }
120
122
  export declare function createRoutingVirtualModule(routes: CompiledRoute[], middlewares: CompiledMiddleware[], cwd: string): VirtualModule;
121
123
  export declare function createPagesVirtualModule(pages: PagesModulePage[], layouts: CompiledLayout[], cwd: string): VirtualModule;
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { _ as defineVirtualModule, a as ssrSingletonProdOptimizeExclude, b as useVirtualRegistry, c as getComponentResolvers, d as registerComponentResolver, f as registerCssImport, g as createVirtualRegistry, h as VirtualModuleRegistry, i as ssrSingletonDevPolicy, l as getCssImports, m as resetModuleRegistry, n as SSR_SINGLETON_OPTIMIZE_EXCLUDE, o as ssrSingletonProdSsr, p as registerHeadScript, r as SSR_SINGLETON_PACKAGES, t as SSR_SINGLETON_DEDUPE, u as getHeadScripts, v as defineVirtualModulePrefix, y as resetVirtualRegistry } from "./ssr-singleton-CUHZLgiO.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-DXIIB-zM.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-AXf0lNb0.js";
3
3
  export { SSR_SINGLETON_DEDUPE, SSR_SINGLETON_OPTIMIZE_EXCLUDE, SSR_SINGLETON_PACKAGES, VirtualModuleRegistry, createAppVirtualModule, createLocalesVirtualModule, createMetaVirtualModule, createPagesVirtualModule, createRoutingVirtualModule, createVirtualRegistry, defineVirtualModule, defineVirtualModulePrefix, getComponentResolvers, getCssImports, getHeadScripts, registerComponentResolver, registerCssImport, registerHeadScript, resetModuleRegistry, resetVirtualRegistry, ssrSingletonDevPolicy, ssrSingletonProdOptimizeExclude, ssrSingletonProdSsr, stripMacros, transformMacros, useVirtualRegistry };
package/dist/prerender.js CHANGED
@@ -77,6 +77,7 @@ function collectPrerenderRoutes(pages, options = {}) {
77
77
  const allPageRoutes = [];
78
78
  for (const page of pages) {
79
79
  if (page.routable === false) continue;
80
+ if (page.isGlobalCatchAll) continue;
80
81
  if (isRedirectPage(page)) {
81
82
  redirectPaths.add(normalizePagePath(page.path));
82
83
  continue;
@@ -1 +1 @@
1
- export { T as buildWithEnvironments, v as createIslandsSsrStubPlugin, y as generateCloudflareWorkerEntry, b as generateNodeServerEntry, x as generateStandardHandlerEntry, S as generateVirtualModulesToDisk, C as getPresetBuildConfig, w as serializePagesForEntry } from "./vite-CGvlml0h.js";
1
+ export { T as buildWithEnvironments, v as createIslandsSsrStubPlugin, y as generateCloudflareWorkerEntry, b as generateNodeServerEntry, x as generateStandardHandlerEntry, S as generateVirtualModulesToDisk, C as getPresetBuildConfig, w as serializePagesForEntry } from "./vite-Cwx2gAN6.js";
@@ -203,7 +203,7 @@ async function createStaticSsgRenderer(cwd, manifest, init) {
203
203
  return;
204
204
  }
205
205
  const renderStaticPage = mod.renderStaticPage;
206
- const compiled = init.pages.map(compilePageRoute);
206
+ const compiled = init.pages.filter((p) => !p.isGlobalCatchAll).map(compilePageRoute);
207
207
  const i18nEnabled = init.i18n != null && init.i18n.enabled !== false;
208
208
  const localeCodes = i18nEnabled ? (init.i18n?.locales || []).map((l) => typeof l === "string" ? l : l.code) : [];
209
209
  const strategy = i18nEnabled ? init.i18n?.strategy || "prefix_except_default" : "no_prefix";
@@ -150,7 +150,7 @@ function createRoutingVirtualModule(routes, middlewares, cwd) {
150
150
  }
151
151
  function createPagesVirtualModule(pages, layouts, cwd) {
152
152
  return defineVirtualModule("ubean:pages", () => {
153
- return `export const pages = {\n${pages.map((p) => ` ${JSON.stringify(p.name)}: { name: ${JSON.stringify(p.name)}, path: ${JSON.stringify(p.path)}, filePath: ${JSON.stringify(toPortableFilePath(p.filePath, cwd))}, layout: ${JSON.stringify(p.layout)}, pageKind: ${JSON.stringify(resolvePageKind(p))}, routable: ${p.routable !== false}, reuseTarget: ${JSON.stringify(p.reuseTarget)}, pageMeta: ${JSON.stringify(p.pageMeta ?? null)}, redirect: ${JSON.stringify(p.redirect ?? null)} }`).join(",\n")}\n};\nexport const pageEntries = pages;\nexport const layouts = {\n${layouts.map((l) => ` ${JSON.stringify(l.name)}: { name: ${JSON.stringify(l.name)}, filePath: ${JSON.stringify(toPortableFilePath(l.filePath, cwd))}, isDefault: ${l.isDefault} }`).join(",\n")}\n};\nexport default { pages, layouts, pageEntries };`;
153
+ return `export const pages = {\n${pages.map((p) => ` ${JSON.stringify(p.name)}: { name: ${JSON.stringify(p.name)}, path: ${JSON.stringify(p.path)}, filePath: ${JSON.stringify(toPortableFilePath(p.filePath, cwd))}, layout: ${JSON.stringify(p.layout)}, pageKind: ${JSON.stringify(resolvePageKind(p))}, routable: ${p.routable !== false}, reuseTarget: ${JSON.stringify(p.reuseTarget)}, pageMeta: ${JSON.stringify(p.pageMeta ?? null)}, redirect: ${JSON.stringify(p.redirect ?? null)}, isBuiltin: ${p.isBuiltin === true}, isGlobalCatchAll: ${p.isGlobalCatchAll === true} }`).join(",\n")}\n};\nexport const pageEntries = pages;\nexport const layouts = {\n${layouts.map((l) => ` ${JSON.stringify(l.name)}: { name: ${JSON.stringify(l.name)}, filePath: ${JSON.stringify(toPortableFilePath(l.filePath, cwd))}, isDefault: ${l.isDefault} }`).join(",\n")}\n};\nexport default { pages, layouts, pageEntries };`;
154
154
  });
155
155
  }
156
156
  function createMetaVirtualModule() {
@@ -1,7 +1,7 @@
1
1
  import { a as ssrSingletonProdOptimizeExclude, g as createVirtualRegistry, o as ssrSingletonProdSsr, x as __exportAll } from "./ssr-singleton-CUHZLgiO.js";
2
- import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-DXIIB-zM.js";
3
- import { a as generateOpenApiTypes, i as generateTypes } from "./codegen-Dw-uws16.js";
4
- import { _ as sendWebResponse, a as createServerEntryVirtualModule, d as ensureDevApp, i as createClientEntryVirtualModule, n as ubeanVite, o as createVueAppEntryVirtualModule, r as composeHeadScripts, s as createVuePagesVirtualModule, v as toWebRequest, x as getDevScanCoordinator } from "./vue-DLig_WHk.js";
2
+ import { a as createRoutingVirtualModule, i as createPagesVirtualModule, n as createLocalesVirtualModule, r as createMetaVirtualModule, s as transformMacros, t as createAppVirtualModule } from "./virtual-modules-AXf0lNb0.js";
3
+ import { a as generateOpenApiTypes, i as generateTypes } from "./codegen-DUQT79IR.js";
4
+ import { _ as sendWebResponse, a as createServerEntryVirtualModule, d as ensureDevApp, i as createClientEntryVirtualModule, n as ubeanVite, o as createVueAppEntryVirtualModule, r as composeHeadScripts, s as createVuePagesVirtualModule, v as toWebRequest, x as getDevScanCoordinator } from "./vue-Cr9byirH.js";
5
5
  import { createStaticSsgRenderer } from "./static-render.js";
6
6
  import { prerender, resolvePrerenderStaticDir } from "./prerender.js";
7
7
  import { resolvePageKind } from "@ubean/vue";
@@ -134,6 +134,10 @@ const _routeGroups = new Map();
134
134
  for (const _p of _pages) {
135
135
  // routable: false 的页面不建路由(与客户端 virtual:ubean-pages 同形)。
136
136
  if (_p.routable === false) continue;
137
+ // 内置全局捕获路由不在这里注册 —— 它的 URL 形态是 vue-router 的 repeatable 参数(客户端),
138
+ // 而 SSG 靠下面的静态 /404 路由渲染产物(静态段优先于 repeatable 参数,
139
+ // 不会被用户的 [...slug].vue 抢走)。两条都注册会得到重复的 'NotFound' 路由名。
140
+ if (_p.isGlobalCatchAll) continue;
137
141
  const _key = _p.route;
138
142
  const _group = _routeGroups.get(_key) || { slots: [] };
139
143
  if (_p.slot) _group.slots.push(_p);
@@ -1503,7 +1507,9 @@ function serializePagesForEntry(pages) {
1503
1507
  pageMeta: p.pageMeta,
1504
1508
  matchers: p.matchers,
1505
1509
  slot: p.slot,
1506
- redirect: p.redirect
1510
+ redirect: p.redirect,
1511
+ isBuiltin: p.isBuiltin,
1512
+ isGlobalCatchAll: p.isGlobalCatchAll
1507
1513
  })));
1508
1514
  }
1509
1515
  async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir, preset, registry, contentSnapshot) {
@@ -1538,7 +1544,9 @@ async function generateVirtualModulesToDisk(cwd, config, scanResult, virtualDir,
1538
1544
  routable: p.routable,
1539
1545
  pageKind: p.pageKind,
1540
1546
  pageMeta: p.pageMeta,
1541
- redirect: p.redirect
1547
+ redirect: p.redirect,
1548
+ isBuiltin: p.isBuiltin,
1549
+ isGlobalCatchAll: p.isGlobalCatchAll
1542
1550
  })), scanResult.layouts.map((l) => ({
1543
1551
  name: l.name,
1544
1552
  filePath: l.fullPath,
@@ -2911,7 +2919,9 @@ function ubeanPlugin(options) {
2911
2919
  routable: p.routable,
2912
2920
  pageKind: p.pageKind,
2913
2921
  pageMeta: p.pageMeta,
2914
- redirect: p.redirect
2922
+ redirect: p.redirect,
2923
+ isBuiltin: p.isBuiltin,
2924
+ isGlobalCatchAll: p.isGlobalCatchAll
2915
2925
  })), result.layouts.map((l) => ({
2916
2926
  name: l.name,
2917
2927
  filePath: l.fullPath,
package/dist/vite.d.ts CHANGED
@@ -432,16 +432,14 @@ interface DevSsrRoutesOptions {
432
432
  loadComponent: (fullPath: string) => Promise<unknown>;
433
433
  /** 与客户端 `virtual:ubean-pages` 相同的 locale param(如 `:locale(zh)?`)。 */
434
434
  localeVueParam?: string;
435
- /** `pages/404.vue` 经扫描得到的条目;缺省则不注册 catch-all。 */
436
- notFoundPage?: ScannedPageRoute;
437
435
  }
438
436
  /**
439
437
  * 构建 SSR 路由表。
440
438
  *
441
439
  * 顺序与形状刻意对齐客户端:页面按扫描顺序、reuse 路由复用目标页面的组件、
442
- * 最后是 404 catch-all。catch-all 用 `/:locale?/:pathMatch(.*)*` —— SSR 渲染的是
443
- * **请求 URL 本身**(不像 SSG 渲染静态产物、可以用 `/404`),必须与客户端同形才能
444
- * 让两侧 `useRoute()` 解析出同一份 matched 结构。
440
+ * 全局捕获路由(`pages/404.vue` / `pages/not-found.vue`)排最后。catch-all 用
441
+ * `/:locale?/:pathMatch(.*)*` —— SSR 渲染的是**请求 URL 本身**(不像 SSG 渲染静态产物、
442
+ * 可以用 `/404`),必须与客户端同形才能让两侧 `useRoute()` 解析出同一份 matched 结构。
445
443
  */
446
444
  export declare function buildDevSsrRoutes(options: DevSsrRoutesOptions): DevSsrRoute[];
447
445
  //#endregion
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { g as createVirtualRegistry } from "./ssr-singleton-CUHZLgiO.js";
2
- import { A as buildDevSsrRoutes, C as peekDevScanCoordinator, D as resolveDevSecurityHeaders, E as createDevAppReady, O as resolveLocaleVueParam, S as onDevScan, T as createDevApp, _ as sendWebResponse, b as createDevScanCoordinator, c as DEVTOOLS_PASS_THROUGH_PREFIXES, d as ensureDevApp, f as getDevApp, g as ubeanDevRequestPlugin, h as isViteResourceRequest, j as toVueRouterPagePath, k as enhanceDevApp, l as collectDevCssLinks, m as isFrameworkHtmlPage, p as injectStylesheetLinks, u as createUbeanRequestHandlers, v as toWebRequest, w as bootstrapDevApp, x as getDevScanCoordinator, y as DEV_SCAN_DIRS } from "./vue-DLig_WHk.js";
3
- import { D as createCloudflarePreviewRunner, E as MINIFLARE_INSTALL_HINT, O as defaultLoadMiniflare, _ as ubeanPreviewPlugin, a as createEnvRunnerTransport, c as getDevWorkerEntrySource, d as attachPreviewMiddleware, f as createPreviewMiddleware, g as sendPreviewStatus, h as sendPreviewFile, i as bridgeEnvRunnerInvokes, k as readCompatibilityDate, l as invalidateDevWorkerModules, m as resolvePreviewFile, n as UBEAN_DEV_ENV_NAME, o as createUbeanDevEnvironmentFactory, p as previewMimeType, r as UbeanDevEnvironment, s as DEV_WORKER_FILE, t as ubeanPlugin, u as writeDevWorkerEntry } from "./vite-CGvlml0h.js";
2
+ import { A as buildDevSsrRoutes, C as peekDevScanCoordinator, D as resolveDevSecurityHeaders, E as createDevAppReady, O as resolveLocaleVueParam, S as onDevScan, T as createDevApp, _ as sendWebResponse, b as createDevScanCoordinator, c as DEVTOOLS_PASS_THROUGH_PREFIXES, d as ensureDevApp, f as getDevApp, g as ubeanDevRequestPlugin, h as isViteResourceRequest, j as toVueRouterPagePath, k as enhanceDevApp, l as collectDevCssLinks, m as isFrameworkHtmlPage, p as injectStylesheetLinks, u as createUbeanRequestHandlers, v as toWebRequest, w as bootstrapDevApp, x as getDevScanCoordinator, y as DEV_SCAN_DIRS } from "./vue-Cr9byirH.js";
3
+ import { D as createCloudflarePreviewRunner, E as MINIFLARE_INSTALL_HINT, O as defaultLoadMiniflare, _ as ubeanPreviewPlugin, a as createEnvRunnerTransport, c as getDevWorkerEntrySource, d as attachPreviewMiddleware, f as createPreviewMiddleware, g as sendPreviewStatus, h as sendPreviewFile, i as bridgeEnvRunnerInvokes, k as readCompatibilityDate, l as invalidateDevWorkerModules, m as resolvePreviewFile, n as UBEAN_DEV_ENV_NAME, o as createUbeanDevEnvironmentFactory, p as previewMimeType, r as UbeanDevEnvironment, s as DEV_WORKER_FILE, t as ubeanPlugin, u as writeDevWorkerEntry } from "./vite-Cwx2gAN6.js";
4
4
  export { DEVTOOLS_PASS_THROUGH_PREFIXES, DEV_SCAN_DIRS, DEV_WORKER_FILE, MINIFLARE_INSTALL_HINT, UBEAN_DEV_ENV_NAME, UbeanDevEnvironment, attachPreviewMiddleware, bootstrapDevApp, bridgeEnvRunnerInvokes, buildDevSsrRoutes, collectDevCssLinks, createCloudflarePreviewRunner, createDevApp, createDevAppReady, createDevScanCoordinator, createEnvRunnerTransport, createPreviewMiddleware, createUbeanDevEnvironmentFactory, createUbeanRequestHandlers, createVirtualRegistry, defaultLoadMiniflare, enhanceDevApp, ensureDevApp, getDevApp, getDevScanCoordinator, getDevWorkerEntrySource, injectStylesheetLinks, invalidateDevWorkerModules, isFrameworkHtmlPage, isViteResourceRequest, onDevScan, peekDevScanCoordinator, previewMimeType, readCompatibilityDate, resolveDevSecurityHeaders, resolveLocaleVueParam, resolvePreviewFile, sendPreviewFile, sendPreviewStatus, sendWebResponse, toVueRouterPagePath, toWebRequest, ubeanDevRequestPlugin, ubeanPlugin, ubeanPreviewPlugin, writeDevWorkerEntry };
@@ -1,8 +1,8 @@
1
1
  import { _ as defineVirtualModule, c as getComponentResolvers, g as createVirtualRegistry, i as ssrSingletonDevPolicy, l as getCssImports, u as getHeadScripts } from "./ssr-singleton-CUHZLgiO.js";
2
- import { D as resolveComponentsConfig, E as resolveAutoImportsConfig, O as toArray, S as getAutoImportPresets, f as COMPONENT_HALF_GLOBS } from "./codegen-Dw-uws16.js";
2
+ import { D as resolveComponentsConfig, E as resolveAutoImportsConfig, O as toArray, S as getAutoImportPresets, f as COMPONENT_HALF_GLOBS } from "./codegen-DUQT79IR.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { generatePagesModuleSource } from "@ubean/vue/vite";
5
- import { resolvePageKind } from "@ubean/vue";
5
+ import { NOT_FOUND_ROUTE_PATH, resolvePageKind, sortPagesForRouting } from "@ubean/vue";
6
6
  import { isAbsolute, join, normalize, relative, resolve } from "pathe";
7
7
  import { existsSync } from "node:fs";
8
8
  import { loadUbeanConfig, localePathsOf, resolvePageCompilers } from "@ubean/config";
@@ -56,14 +56,14 @@ function redirectTarget(target, localeVueParam) {
56
56
  * 构建 SSR 路由表。
57
57
  *
58
58
  * 顺序与形状刻意对齐客户端:页面按扫描顺序、reuse 路由复用目标页面的组件、
59
- * 最后是 404 catch-all。catch-all 用 `/:locale?/:pathMatch(.*)*` —— SSR 渲染的是
60
- * **请求 URL 本身**(不像 SSG 渲染静态产物、可以用 `/404`),必须与客户端同形才能
61
- * 让两侧 `useRoute()` 解析出同一份 matched 结构。
59
+ * 全局捕获路由(`pages/404.vue` / `pages/not-found.vue`)排最后。catch-all 用
60
+ * `/:locale?/:pathMatch(.*)*` —— SSR 渲染的是**请求 URL 本身**(不像 SSG 渲染静态产物、
61
+ * 可以用 `/404`),必须与客户端同形才能让两侧 `useRoute()` 解析出同一份 matched 结构。
62
62
  */
63
63
  function buildDevSsrRoutes(options) {
64
- const { pages, layouts, loadComponent, localeVueParam, notFoundPage } = options;
64
+ const { pages, layouts, loadComponent, localeVueParam } = options;
65
65
  const defaultLayout = layouts.find((l) => l.isDefault)?.name ?? null;
66
- const routablePages = pages.filter((p) => p.routable !== false);
66
+ const routablePages = sortPagesForRouting(pages.filter((p) => p.routable !== false));
67
67
  const withLocale = (path) => localeVueParam ? toVueRouterLocalePath(path, localeVueParam) : path;
68
68
  const pageByName = /* @__PURE__ */ new Map();
69
69
  for (const page of routablePages) pageByName.set(page.name, page);
@@ -72,7 +72,7 @@ function buildDevSsrRoutes(options) {
72
72
  return async () => await loadComponent(fullPath);
73
73
  };
74
74
  const routeFor = (page) => ({
75
- path: withLocale(toVueRouterPagePath(page.route)),
75
+ path: withLocale(page.isGlobalCatchAll ? NOT_FOUND_ROUTE_PATH : toVueRouterPagePath(page.route)),
76
76
  name: page.name,
77
77
  ...page.redirect ? { redirect: redirectTarget(page.redirect, localeVueParam) } : { component: componentFor(page) },
78
78
  meta: {
@@ -103,15 +103,6 @@ function buildDevSsrRoutes(options) {
103
103
  }
104
104
  routes.push(route);
105
105
  }
106
- if (notFoundPage) routes.push({
107
- path: withLocale("/:pathMatch(.*)*"),
108
- name: "NotFound",
109
- component: async () => await loadComponent(notFoundPage.fullPath),
110
- meta: {
111
- layout: notFoundPage.layout === false ? false : notFoundPage.layout || defaultLayout,
112
- pageName: "NotFound"
113
- }
114
- });
115
106
  return routes;
116
107
  }
117
108
  //#endregion
@@ -161,8 +152,7 @@ function enhanceDevApp(options) {
161
152
  pages: app.options.pages || [],
162
153
  layouts,
163
154
  localeVueParam,
164
- loadComponent: loadModule,
165
- notFoundPage: app.options.notFoundPage
155
+ loadComponent: loadModule
166
156
  });
167
157
  let appConfigModule = null;
168
158
  const getAppConfigModule = () => {
package/dist/vue.js CHANGED
@@ -1 +1 @@
1
- export { t as VUE_PLUGIN_INCLUDE, r as composeHeadScripts, i as createClientEntryVirtualModule, a as createServerEntryVirtualModule, o as createVueAppEntryVirtualModule, s as createVuePagesVirtualModule, n as default, n as ubeanVite } from "./vue-DLig_WHk.js";
1
+ export { t as VUE_PLUGIN_INCLUDE, r as composeHeadScripts, i as createClientEntryVirtualModule, a as createServerEntryVirtualModule, o as createVueAppEntryVirtualModule, s as createVuePagesVirtualModule, n as default, n as ubeanVite } from "./vue-Cr9byirH.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ubean/build",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "Vite plugins, production build, SSG prerender, type codegen, and Server Actions plugin for ubean",
5
5
  "files": [
6
6
  "dist"
@@ -49,19 +49,19 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@intlify/unplugin-vue-i18n": "11.2.7",
52
- "@ubean/app": "0.7.1",
53
- "@ubean/client": "0.7.1",
54
- "@ubean/config": "0.7.1",
55
- "@ubean/i18n": "0.7.1",
56
- "@ubean/islands": "0.7.1",
57
- "@ubean/markdown": "0.7.1",
58
- "@ubean/pages": "0.7.1",
59
- "@ubean/preset": "0.7.1",
60
- "@ubean/routes": "0.7.1",
61
- "@ubean/scan": "0.7.1",
62
- "@ubean/server": "0.7.1",
63
- "@ubean/shared": "0.7.1",
64
- "@ubean/vue": "0.7.1",
52
+ "@ubean/app": "0.7.3",
53
+ "@ubean/client": "0.7.3",
54
+ "@ubean/config": "0.7.3",
55
+ "@ubean/i18n": "0.7.3",
56
+ "@ubean/islands": "0.7.3",
57
+ "@ubean/markdown": "0.7.3",
58
+ "@ubean/pages": "0.7.3",
59
+ "@ubean/preset": "0.7.3",
60
+ "@ubean/routes": "0.7.3",
61
+ "@ubean/scan": "0.7.3",
62
+ "@ubean/server": "0.7.3",
63
+ "@ubean/shared": "0.7.3",
64
+ "@ubean/vue": "0.7.3",
65
65
  "@vitejs/plugin-vue": "^6.0.10",
66
66
  "@vitejs/plugin-vue-jsx": "^5.1.6",
67
67
  "openapi-typescript": "^7.13.0",