@ubean/vue 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +493 -0
- package/README.zh-CN.md +500 -0
- package/dist/generator/index.d.ts +125 -0
- package/dist/generator/index.js +369 -0
- package/dist/index.d.ts +782 -0
- package/dist/index.js +1073 -0
- package/dist/types-VHF1RJu2.d.ts +132 -0
- package/dist/vite.d.ts +164 -0
- package/dist/vite.js +1189 -0
- package/package.json +67 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { RouteMeta } from "vue-router";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* `@ubean/vue` 页面路由共享类型(运行时 + 构建期 `/vite` 共用)。
|
|
5
|
+
*
|
|
6
|
+
* 本包是页面路由的唯一所有者:`@ubean/scan` 聚合层通过
|
|
7
|
+
* `import type { ... } from '@ubean/vue'` re-export 这些类型保持向后兼容。
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Page-level head configuration (SEO title, meta, link, etc.).
|
|
11
|
+
*
|
|
12
|
+
* 提取自 Markdown frontmatter 与 `definePage({ head })` 宏(构建期);
|
|
13
|
+
* SSR 链路经 `pageObj.head` 应用,SPA 链路经 `setupPageHeadGuard` 读取
|
|
14
|
+
* `route.meta.head` 后 push 进 head 实例。动态/响应式 head 用 `useHead()`。
|
|
15
|
+
*/
|
|
16
|
+
interface PageHead {
|
|
17
|
+
title?: string;
|
|
18
|
+
meta?: Array<Record<string, string>>;
|
|
19
|
+
link?: Array<Record<string, string>>;
|
|
20
|
+
script?: Array<Record<string, string>>;
|
|
21
|
+
htmlAttrs?: Record<string, string>;
|
|
22
|
+
bodyAttrs?: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Page-level route metadata extracted from `definePage()` macro calls.
|
|
26
|
+
*
|
|
27
|
+
* 注意:无 `middleware` 字段 —— 此前该字段从未被任何运行时消费
|
|
28
|
+
* (服务端中间件走 `middleware/` 目录挂载,客户端守卫读 `meta`)。
|
|
29
|
+
* 需要按路由声明守卫时,用 `meta: { middleware: [...] }` 透传到
|
|
30
|
+
* `route.meta` 由用户导航守卫消费。
|
|
31
|
+
*/
|
|
32
|
+
interface PageMeta {
|
|
33
|
+
name?: string;
|
|
34
|
+
path?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Layout name, array of layout names (outer → inner, applied left-to-right),
|
|
37
|
+
* or `false` to disable layout.
|
|
38
|
+
*/
|
|
39
|
+
layout?: string | string[] | false;
|
|
40
|
+
/** Reuse route target page name(元数据文件 `.reuse.ts` / `.reuse.js`)。 */
|
|
41
|
+
reuse?: string;
|
|
42
|
+
/** 任意扩展 meta,浅合并进 `route.meta`。 */
|
|
43
|
+
meta?: RouteMeta;
|
|
44
|
+
/** 鉴权标记,写入 `route.meta.requiresAuth`,由用户导航守卫消费。 */
|
|
45
|
+
requiresAuth?: boolean;
|
|
46
|
+
/** keep-alive 页面缓存声明。reuse 路由未显式声明时继承目标页。 */
|
|
47
|
+
cache?: boolean;
|
|
48
|
+
/** 页面级过渡名,`<PageView>` 消费;空串禁用本页过渡。 */
|
|
49
|
+
transition?: string;
|
|
50
|
+
/**
|
|
51
|
+
* 页面级静态 head(SEO)。构建期提取;仅当 `/vite` 插件
|
|
52
|
+
* `head: true` 时写入 `route.meta.head` 并参与扫描输出。
|
|
53
|
+
*/
|
|
54
|
+
head?: PageHead;
|
|
55
|
+
}
|
|
56
|
+
/** 扫描得到的单个页面(字段与旧 `ScannedPageRoute` 完全兼容)。 */
|
|
57
|
+
interface ScannedPage {
|
|
58
|
+
fullPath: string;
|
|
59
|
+
relativePath: string;
|
|
60
|
+
dirname: string;
|
|
61
|
+
basename: string;
|
|
62
|
+
name: string;
|
|
63
|
+
route: string;
|
|
64
|
+
path: string;
|
|
65
|
+
layout?: string | string[] | false;
|
|
66
|
+
cache?: boolean;
|
|
67
|
+
isReuse: boolean;
|
|
68
|
+
isMarkdown: boolean;
|
|
69
|
+
reuseTarget?: string;
|
|
70
|
+
pageMeta?: PageMeta;
|
|
71
|
+
frontmatter?: Record<string, unknown>;
|
|
72
|
+
/** Parallel route slot name(`@slotName/` 目录约定)。 */
|
|
73
|
+
slot?: string;
|
|
74
|
+
/** Intercepting route:从 `interceptFrom` 导航到 `interceptTarget` 时拦截。 */
|
|
75
|
+
interceptFrom?: string;
|
|
76
|
+
interceptTarget?: string;
|
|
77
|
+
/** 路由参数 → matcher 名称映射(`[param=matcher]` 语法)。 */
|
|
78
|
+
matchers?: Record<string, string>;
|
|
79
|
+
}
|
|
80
|
+
/** 扫描得到的布局(`layouts/` 下 `xx.vue` 或 `xx/index.vue`)。 */
|
|
81
|
+
interface ScannedLayout {
|
|
82
|
+
fullPath: string;
|
|
83
|
+
relativePath: string;
|
|
84
|
+
dirname: string;
|
|
85
|
+
basename: string;
|
|
86
|
+
name: string;
|
|
87
|
+
path: string;
|
|
88
|
+
isDefault: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* `scanPages` 入参。`pagesDir` / `layoutsDir` 支持多目录
|
|
92
|
+
* (先到先得去重,可分层叠加目录)。
|
|
93
|
+
*/
|
|
94
|
+
interface ScanPagesOptions {
|
|
95
|
+
/** 项目根目录(绝对)。 */
|
|
96
|
+
cwd: string;
|
|
97
|
+
/** 源码目录(绝对或相对 `cwd`)。 */
|
|
98
|
+
srcDir: string;
|
|
99
|
+
/** 页面目录,相对 `srcDir` 或绝对。默认 `['pages']`。 */
|
|
100
|
+
pagesDir?: string | string[];
|
|
101
|
+
/** 布局目录,相对 `srcDir` 或绝对。默认 `['layouts']`。 */
|
|
102
|
+
layoutsDir?: string | string[];
|
|
103
|
+
/**
|
|
104
|
+
* 页面文件扩展名。默认 `['vue', 'tsx', 'jsx']`;markdown 开启后自动追加
|
|
105
|
+
* 对应的 `.md` / `.mdx`。`.reuse.ts` 元数据文件为独立约定,始终参与扫描。
|
|
106
|
+
*/
|
|
107
|
+
extensions?: string[];
|
|
108
|
+
/** 额外 glob ignore。 */
|
|
109
|
+
ignore?: string[];
|
|
110
|
+
/**
|
|
111
|
+
* Markdown 页面支持,默认 `false`(零成本)。
|
|
112
|
+
* - `true`:扫描 `.md` + `.mdx`
|
|
113
|
+
* - `'md'`:仅 `.md`
|
|
114
|
+
* - `'mdx'`:仅 `.mdx`
|
|
115
|
+
* 需安装 `@ubean/markdown`(构建期按需加载,未安装时降级为无 frontmatter)。
|
|
116
|
+
*/
|
|
117
|
+
markdown?: boolean | 'mdx' | 'md';
|
|
118
|
+
/**
|
|
119
|
+
* 页面级 head 支持,默认 `false`。开启后 `definePage({ head })` 与
|
|
120
|
+
* markdown frontmatter `head` 写入 `pageMeta.head` / `route.meta.head`。
|
|
121
|
+
*/
|
|
122
|
+
head?: boolean;
|
|
123
|
+
}
|
|
124
|
+
interface ScanPagesResult {
|
|
125
|
+
pages: ScannedPage[];
|
|
126
|
+
layouts: ScannedLayout[];
|
|
127
|
+
notFoundPage?: ScannedPage;
|
|
128
|
+
loadingPage?: ScannedPage;
|
|
129
|
+
errorPage?: ScannedPage;
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
export { ScannedLayout as a, ScanPagesResult as i, PageMeta as n, ScannedPage as o, ScanPagesOptions as r, PageHead as t };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { i as ScanPagesResult, n as PageMeta, r as ScanPagesOptions, t as PageHead } from "./types-VHF1RJu2.js";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
//#region src/scan-pages.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extract parallel route slot name and intercept info from a relative file path.
|
|
6
|
+
*
|
|
7
|
+
* Parallel routes: `@slotName/page.vue` → slot = 'slotName'
|
|
8
|
+
* Intercepting routes:
|
|
9
|
+
* `(..)target/page.vue` → intercept from parent, target = 'target'
|
|
10
|
+
* `(.)target/page.vue` → intercept from same level, target = 'target'
|
|
11
|
+
* `(...)target/page.vue` → intercept from root, target = 'target'
|
|
12
|
+
*/
|
|
13
|
+
declare function extractSlotAndIntercept(fileBase: string): {
|
|
14
|
+
cleanedBase: string;
|
|
15
|
+
slot?: string;
|
|
16
|
+
interceptFrom?: string;
|
|
17
|
+
interceptTarget?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function scanPages(options: ScanPagesOptions): Promise<ScanPagesResult>;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/virtual-pages.d.ts
|
|
22
|
+
type PagesModuleInput = Pick<ScanPagesResult, 'pages' | 'layouts' | 'notFoundPage' | 'loadingPage' | 'errorPage'>;
|
|
23
|
+
/** Generate the virtual module source(plain JS — no TS syntax, SSR-safe)。 */
|
|
24
|
+
declare function generatePagesModuleSource(input: PagesModuleInput): string;
|
|
25
|
+
/**
|
|
26
|
+
* Generate the ambient module declaration d.ts for the virtual module.
|
|
27
|
+
*
|
|
28
|
+
* 产物必须是 **script 文件**(无顶层 import/export)—— `declare module` 在
|
|
29
|
+
* script 上下文中才注册「环境模块声明」;在 module 文件中会被当作模块增强,
|
|
30
|
+
* 对不存在的模块无法生效。由 `/vite` 插件写入 `<root>/ubean-vue-routes.d.ts`。
|
|
31
|
+
*/
|
|
32
|
+
declare function generateVirtualModuleDts(input: PagesModuleInput, moduleId?: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Generate `typed-router.d.ts` content for the virtual module.
|
|
35
|
+
*
|
|
36
|
+
* 包含 `vue-router/auto-routes` 的 `RouteNamedMap` 增强,让 vue-router 的
|
|
37
|
+
* `useRoute<Name>(name)` / `RouterLink` 能推断 `route.params` 类型。
|
|
38
|
+
*
|
|
39
|
+
* 产物是 **module 文件**(顶层 `export {}`)—— `declare module` 块按「模块
|
|
40
|
+
* 增强」语义合并进真实的 'vue-router' / 'vue-router/auto-routes' 模块;
|
|
41
|
+
* 若以 script 形式输出,同名环境模块声明会整体遮蔽真实包的类型。
|
|
42
|
+
* 虚拟模块自身的环境声明见 `generateVirtualModuleDts`。
|
|
43
|
+
*/
|
|
44
|
+
declare function generateTypedRouter(input: PagesModuleInput, _moduleId?: string): string;
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/route-path.d.ts
|
|
47
|
+
declare function stripRouteGroups(path: string): string;
|
|
48
|
+
interface ParsedRoutePath {
|
|
49
|
+
route: string;
|
|
50
|
+
method?: string;
|
|
51
|
+
env?: string;
|
|
52
|
+
/**
|
|
53
|
+
* matcher 后缀剥离后、语法转换前的文件路由路径(保留 `[id]` / `[...slug]`
|
|
54
|
+
* 方括号语法)。`generateRouteName` 消费文件语法而非转换后的 `:id` 语法。
|
|
55
|
+
*/
|
|
56
|
+
cleaned?: string;
|
|
57
|
+
/**
|
|
58
|
+
* 路由参数 → matcher 名称的映射。
|
|
59
|
+
*
|
|
60
|
+
* 由 `[paramName=matcherName]` 语法解析得到,例如 `[id=numeric].vue` →
|
|
61
|
+
* `{ id: 'numeric' }`。无 matcher 语法的路由此项为 `undefined`。
|
|
62
|
+
*/
|
|
63
|
+
matchers?: Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 解析 `[param=matcher]` 语法,从原始路径中提取 matcher 名称映射,并把
|
|
67
|
+
* `=matcher` 后缀剥离,以便后续正则能正确识别为普通动态参数。
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* parseMatchers('users/[id=numeric]') → { cleaned: 'users/[id]', matchers: { id: 'numeric' } }
|
|
71
|
+
* parseMatchers('blog/[...slug=any]') → { cleaned: 'blog/[...slug]', matchers: { slug: 'any' } }
|
|
72
|
+
* parseMatchers('users/[id]') → { cleaned: 'users/[id]', matchers: undefined }
|
|
73
|
+
*/
|
|
74
|
+
declare function parseMatchers(filePath: string): {
|
|
75
|
+
cleaned: string;
|
|
76
|
+
matchers?: Record<string, string>;
|
|
77
|
+
};
|
|
78
|
+
declare function filePathToRoute(filePath: string, prefix?: string): ParsedRoutePath;
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/route-name.d.ts
|
|
81
|
+
/**
|
|
82
|
+
* 路由名生成器(页面路由所有权归属 `@ubean/vue`)。
|
|
83
|
+
* `@ubean/scan` 聚合层 re-export 保持向后兼容;服务端专用的
|
|
84
|
+
* `generateApiRouteId` 保留在 `@ubean/scan`。
|
|
85
|
+
*/
|
|
86
|
+
declare function generateRouteName(routePath: string): string;
|
|
87
|
+
declare function generateLayoutName(layoutPath: string): string;
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/extract-page.d.ts
|
|
90
|
+
/**
|
|
91
|
+
* 通用宏调用提取:在代码中查找 `funcName({...})` 形式的调用并解析其
|
|
92
|
+
* 对象字面量参数。供本包的 `definePage` 提取与 `@ubean/scan` 的
|
|
93
|
+
* `defineHandlerMeta` 提取共用(单一解析器实现)。
|
|
94
|
+
*/
|
|
95
|
+
declare function extractCallObject(code: string, funcName: string): Record<string, unknown> | null;
|
|
96
|
+
/**
|
|
97
|
+
* Normalize a parsed `head` value into a `PageHead` object。
|
|
98
|
+
*
|
|
99
|
+
* Mirrors the markdown frontmatter head validation so Vue pages (via
|
|
100
|
+
* `definePage`) and Markdown pages (via frontmatter) share the same rules.
|
|
101
|
+
*/
|
|
102
|
+
declare function normalizePageHead(raw: unknown): PageHead | undefined;
|
|
103
|
+
declare function extractDefinePageFromCode(code: string): PageMeta | null;
|
|
104
|
+
declare function extractDefinePage(filePath: string): Promise<PageMeta | null>;
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/vite.d.ts
|
|
107
|
+
/**
|
|
108
|
+
* `@ubean/vue/vite` —— 精简客户端路由 Vite 插件(页面路由唯一所有者)。
|
|
109
|
+
*
|
|
110
|
+
* 能力:
|
|
111
|
+
* - 多 `pagesDir` / `layoutsDir` 扫描(先到先得去重)
|
|
112
|
+
* - reuse 路由、特殊页(404/loading/error)、并行路由 `@slot/`、拦截路由
|
|
113
|
+
* - `[param=matcher]` 语法(matchers 注入 `route.meta`)
|
|
114
|
+
* - markdown 页面(opt-in,默认 false,`@ubean/markdown` 按需加载)
|
|
115
|
+
* - 页面级 head(opt-in,默认 false,写入 `route.meta.head`)
|
|
116
|
+
* - `typed-router.d.ts` 生成(RouteNamedMap 完整类型推断,产物在 `dtsDir`,默认 `.ubean`)
|
|
117
|
+
*
|
|
118
|
+
* 框架层(`@ubean/vite`)通过 `generatePagesModuleSource` /
|
|
119
|
+
* `scanPages` / `generateTypedRouter` 复用同一套生成器。
|
|
120
|
+
*/
|
|
121
|
+
declare const VUE_ROUTES_MODULE_ID = "virtual:ubean-vue-routes";
|
|
122
|
+
interface UbeanVueViteOptions {
|
|
123
|
+
/** 页面目录(相对项目根或绝对),支持多目录。默认 `'src/pages'`。 */
|
|
124
|
+
pagesDir?: string | string[];
|
|
125
|
+
/** 布局目录(相对项目根或绝对),支持多目录。默认 `'src/layouts'`。 */
|
|
126
|
+
layoutsDir?: string | string[];
|
|
127
|
+
/**
|
|
128
|
+
* 页面文件扩展名。默认 `['vue', 'tsx', 'jsx']`;markdown 开启后自动追加
|
|
129
|
+
* 对应的 `.md` / `.mdx`。`.reuse.ts` 元数据文件为独立约定,始终参与扫描。
|
|
130
|
+
*/
|
|
131
|
+
extensions?: string[];
|
|
132
|
+
/** 额外 glob ignore。 */
|
|
133
|
+
ignore?: string[];
|
|
134
|
+
/** 是否生成 `typed-router.d.ts`。默认 `true`。 */
|
|
135
|
+
generateTypes?: boolean;
|
|
136
|
+
/**
|
|
137
|
+
* 类型声明产物目录(相对项目根或绝对路径)。默认 `'.ubean'` ——
|
|
138
|
+
* `ubean-vue-routes.d.ts` 与 `typed-router.d.ts` 都生成在该目录下,
|
|
139
|
+
* 与框架层(`@ubean/vite` 的 auto-imports dts)保持同一约定。
|
|
140
|
+
*/
|
|
141
|
+
dtsDir?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Markdown 页面支持,默认 `false`(零成本)。
|
|
144
|
+
* - `true`:扫描并渲染 `.md` + `.mdx`
|
|
145
|
+
* - `'md'`:仅 `.md`
|
|
146
|
+
* - `'mdx'`:仅 `.mdx`
|
|
147
|
+
* 需安装 `@ubean/markdown`(构建期按需加载)。
|
|
148
|
+
*/
|
|
149
|
+
markdown?: boolean | 'mdx' | 'md';
|
|
150
|
+
/**
|
|
151
|
+
* 页面级 head 支持,默认 `false`。开启后 `definePage({ head })` 与
|
|
152
|
+
* frontmatter `head` 写入 `route.meta.head`(配合 `setupPageHeadGuard`)。
|
|
153
|
+
*/
|
|
154
|
+
head?: boolean;
|
|
155
|
+
}
|
|
156
|
+
/** 剥离 `definePage({...})` 宏调用(构建期,扫描后源码中不再需要)。 */
|
|
157
|
+
declare function stripDefinePageCalls(code: string): string;
|
|
158
|
+
/**
|
|
159
|
+
* 扫描客户端页面/布局(对外工具函数,`root` 为项目根)。
|
|
160
|
+
*/
|
|
161
|
+
declare function scanClientPages(root: string, options?: UbeanVueViteOptions): Promise<ScanPagesResult>;
|
|
162
|
+
declare function ubeanVueVite(options?: UbeanVueViteOptions): Plugin;
|
|
163
|
+
//#endregion
|
|
164
|
+
export { type ParsedRoutePath, UbeanVueViteOptions, VUE_ROUTES_MODULE_ID, ubeanVueVite as default, ubeanVueVite, extractCallObject, extractDefinePage, extractDefinePageFromCode, extractSlotAndIntercept, filePathToRoute, generateLayoutName, generatePagesModuleSource, generateRouteName, generateTypedRouter, generateVirtualModuleDts, normalizePageHead, parseMatchers, scanClientPages, scanPages, stripDefinePageCalls, stripRouteGroups };
|