web-extend-plugin-vue2 0.2.5 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,64 +1,41 @@
1
- /**
2
- * 公共 API 的 TypeScript 声明;IDE 补全以本文件为准。
3
- */
4
-
5
- /** 清单侧路由声明(PRD),需配合 `adaptRouteDeclarations` */
6
1
  export type RouteDeclaration = {
7
2
  path: string
8
3
  name?: string
9
4
  title?: string
10
5
  meta?: Record<string, unknown>
11
6
  children?: RouteDeclaration[]
12
- /** 由宿主在 `adaptRouteDeclarations` 中解析为 Vue 组件 */
13
7
  componentRef: string
14
8
  }
15
9
 
16
- /** `bootstrapPlugins` 调用 `activator` 时的第二参数 */
17
- export type PluginActivateContext = {
18
- /** 清单条目的浅拷贝且已 `Object.freeze`,请勿就地修改嵌套对象 */
19
- pluginRecord: Readonly<Record<string, unknown>>
20
- }
21
-
22
- /**
23
- * 与 `vue-router` RouteConfig 兼容的宽松对象形态(未安装 vue 类型时仍可用)。
24
- * 安装 `vue` / `vue-router` 类型后可在业务代码中收窄。
25
- */
26
10
  export type VueRouteConfig = Record<string, unknown>
27
11
 
28
- /** 在合成 `name` / `meta.pluginId` 之前转换插件提交的 `RouteConfig` */
12
+ export type PluginRouteSnapshot = {
13
+ path?: string
14
+ name?: string | symbol
15
+ meta?: Record<string, unknown>
16
+ children?: PluginRouteSnapshot[]
17
+ [key: string]: unknown
18
+ }
19
+
29
20
  export type TransformRoutesFn = (ctx: {
30
21
  pluginId: string
31
22
  router: unknown
32
23
  routes: ReadonlyArray<VueRouteConfig>
33
24
  }) => VueRouteConfig[]
34
25
 
35
- /** 接管路由注册;由宿主决定是否调用 `applyInternalRegister` */
36
26
  export type InterceptRegisterRoutesFn = (ctx: {
37
27
  pluginId: string
38
28
  router: unknown
39
29
  routes: ReadonlyArray<VueRouteConfig>
40
- /** 与默认 `registerRoutes` 相同的包装 + `router.addRoute` */
41
30
  applyInternalRegister: (routes: VueRouteConfig[]) => void
42
31
  }) => void
43
32
 
44
- /** PRD → `RouteConfig` */
45
33
  export type AdaptRouteDeclarationsFn = (ctx: {
46
34
  pluginId: string
47
35
  router: unknown
48
36
  declarations: ReadonlyArray<RouteDeclaration>
49
37
  }) => VueRouteConfig[]
50
38
 
51
- /** 将插件 `registerMenuItems` 提交的数据并入宿主用于渲染侧栏/目录的 state(映射规则由宿主实现) */
52
- export type ApplyPluginMenuItemsFn = (ctx: {
53
- pluginId: string
54
- /** 已在各条上附带 `pluginId`,并按 `order` 升序 */
55
- items: Array<Record<string, unknown>>
56
- }) => void
57
-
58
- /** 卸载插件时移除该插件贡献的菜单数据 */
59
- export type RevokePluginMenuItemsFn = (pluginId: string) => void
60
-
61
- /** 宿主在 `resolveRuntimeOptions({ hostContext })` 中注入;经浅冻结后由 `hostApi.hostContext` 只读暴露 */
62
39
  export type HostContext = Readonly<Record<string, unknown>>
63
40
 
64
41
  export type OnBeforePluginActivateFn = (ctx: {
@@ -81,54 +58,35 @@ export type OnPluginActivateErrorFn = (ctx: {
81
58
  hostApi: unknown
82
59
  }) => void | Promise<void>
83
60
 
84
- /** 宿主传入 `createHostApi` `hostKit`(及 `resolveRuntimeOptions` 中同类字段) */
85
- /** {@link createVueCliAxiosQuickInstallOptions} / {@link installVueCliAxiosWebPlugins} 的宿主侧依赖 */
86
- export type VueCliAxiosQuickDeps = {
87
- request: (config: Record<string, unknown>) => Promise<unknown>
88
- hostLayoutComponent: unknown
89
- store?: unknown
90
- hostContext?: Record<string, unknown>
91
- applyPluginMenuItems?: (ctx: { pluginId: string; items: Array<Record<string, unknown>> }) => void
92
- revokePluginMenuItems?: (pluginId: string) => void
93
- }
61
+ export type OnPluginRoutesContributedFn = (ctx: {
62
+ pluginId: string
63
+ router: unknown
64
+ routes: ReadonlyArray<VueRouteConfig>
65
+ contributedRoutes: ReadonlyArray<PluginRouteSnapshot>
66
+ }) => void | Promise<void>
94
67
 
95
68
  export type HostKitOptions = {
96
- /** `getBridge().request` 允许的URL路径前缀,须以 `/` 开头 */
97
69
  bridgeAllowedPathPrefixes?: string[]
98
- /** 非空时子路由挂到该命名父路由下(需 vue-router ≥3.5 的 `addRoute`) */
99
70
  pluginRoutesParentName?: string
100
71
  transformRoutes?: TransformRoutesFn
101
72
  interceptRegisterRoutes?: InterceptRegisterRoutesFn
102
73
  adaptRouteDeclarations?: AdaptRouteDeclarationsFn
103
- /** 必填:插件调用 `registerMenuItems` 时由此写入宿主菜单/路由树等数据结构 */
104
- applyPluginMenuItems?: ApplyPluginMenuItemsFn
105
- /** 建议与 `applyPluginMenuItems` 成对配置;`disposeWebPlugin` 会调用以撤销该插件菜单 */
106
- revokePluginMenuItems?: RevokePluginMenuItemsFn
107
- /** 由引导流程浅冻结后传入各插件的 `hostApi.hostContext` */
74
+ onPluginRoutesContributed?: OnPluginRoutesContributedFn
108
75
  hostContext?: HostContext
109
76
  }
110
77
 
111
- /** `resolveRuntimeOptions` 全量运行时选项(在默认字段基础上的扩展;未列字段见 README) */
112
78
  export type WebExtendPluginRuntimeOptions = HostKitOptions &
113
79
  Record<string, unknown> & {
114
80
  manifestBase?: string
115
81
  manifestListPath?: string
116
- /** 默认 `api`;`static` 时用 `staticManifestUrl` 拉取聚合 JSON,不请求 Java 清单接口 */
117
82
  manifestMode?: 'api' | 'static'
118
- /** 静态清单 URL(绝对或站点内路径),`manifestMode: 'static'` 时必填(或配置环境变量) */
119
83
  staticManifestUrl?: string
120
- /** `manifestMode=api` 且开发环境:API 失败或 `plugins` 为空时是否尝试 `devFallbackStaticManifestUrl`(默认 true) */
121
84
  devManifestFallback?: boolean
122
- /** 开发回退静态清单路径,默认 `/web-plugins/plugins.manifest.json` */
123
85
  devFallbackStaticManifestUrl?: string
124
86
  manifestFetchCredentials?: RequestCredentials
125
- /** 宿主 Layout,传入后自动注册 `pluginMountPath` 壳路由 */
126
87
  hostLayoutComponent?: unknown
127
- /** 插件 URL 前缀,默认 `/plugin` */
128
88
  pluginMountPath?: string
129
- /** 壳路由 meta */
130
89
  pluginHostRouteMeta?: Record<string, unknown>
131
- /** 是否执行自动壳路由注册,默认 true */
132
90
  ensurePluginHostRoute?: boolean
133
91
  isDev?: boolean
134
92
  webPluginDevOrigin?: string
@@ -142,32 +100,16 @@ export type WebExtendPluginRuntimeOptions = HostKitOptions &
142
100
  allowedScriptHosts?: string[]
143
101
  bootstrapSummary?: boolean
144
102
  fetchManifest?: ManifestFetchFn
145
- /** 插件通过 `hostApi.hostContext` 只读访问(浅冻结拷贝);如 `{ store, i18n }` */
146
103
  hostContext?: Record<string, unknown>
147
- /** 调用 `activator` 之前;抛出异常将跳过该插件并计入失败 */
148
104
  onBeforePluginActivate?: OnBeforePluginActivateFn
149
- /** `activator` 成功返回后 */
150
105
  onAfterPluginActivate?: OnAfterPluginActivateFn
151
- /** `activator` 抛错后;用于埋点/降级,不应再抛错(再抛仅记录 warn) */
152
106
  onPluginActivateError?: OnPluginActivateErrorFn
153
107
  }
154
108
 
155
- /** 插件 `activator` 收到的宿主 API */
156
109
  export interface HostApi {
157
- /** 宿主实现的 Host API 协议版本,与清单 `hostPluginApiVersion` 对齐 */
158
110
  readonly hostPluginApiVersion: string
159
- /** 宿主注入上下文(`resolveRuntimeOptions.hostContext` 的浅冻结快照);无则 `{}` */
160
111
  readonly hostContext: HostContext
161
- /**
162
- * 动态注册路由。含 PRD 时使用 `componentRef` 树;否则传入 `RouteConfig` 数组。
163
- * 流水线:`adaptRouteDeclarations` → `transformRoutes` → `interceptRegisterRoutes` 或默认注册。
164
- */
165
112
  registerRoutes(routes: VueRouteConfig[] | RouteDeclaration[]): void
166
- /**
167
- * 向宿主登记侧栏/目录菜单意图;由 `applyPluginMenuItems` 写入宿主 state。
168
- * 未配置 `applyPluginMenuItems` 时调用会抛错。
169
- */
170
- registerMenuItems(items: Record<string, unknown>[]): void
171
113
  registerSlotComponents(
172
114
  pointId: string,
173
115
  components: Array<{ component: unknown; priority?: number }>
@@ -175,6 +117,7 @@ export interface HostApi {
175
117
  registerStylesheetUrls(urls?: string[]): void
176
118
  registerScriptUrls(urls?: string[]): void
177
119
  registerSanitizedHtmlSnippet(): void
120
+ getContributedRoutes(): PluginRouteSnapshot[]
178
121
  getBridge(): {
179
122
  request(path: string, init?: RequestInit): Promise<Response>
180
123
  }
@@ -202,101 +145,32 @@ export type ManifestFetchCacheOptions = {
202
145
  now?: () => number
203
146
  }
204
147
 
205
- /** 命名空间聚合对象,按领域分组 */
206
- export const WebExtendPluginVue2: Readonly<{
207
- install: (Vue: unknown, router: unknown, options?: WebExtendPluginRuntimeOptions) => Promise<void>
208
- runtime: Readonly<{
209
- /** 拉取清单并依次 `activator(hostApi, { pluginRecord })` */
210
- bootstrapPlugins: (
211
- router: unknown,
212
- createHostApiFactory: (id: string, r: unknown, kit?: HostKitOptions) => HostApi,
213
- runtimeOptions?: WebExtendPluginRuntimeOptions
214
- ) => Promise<void>
215
- resolveRuntimeOptions: (user?: WebExtendPluginRuntimeOptions) => WebExtendPluginRuntimeOptions
216
- ensurePluginHostRoute: (router: unknown, opts: WebExtendPluginRuntimeOptions) => void
217
- defaultFetchWebPluginManifest: (ctx: {
218
- manifestUrl: string
219
- credentials: RequestCredentials
220
- }) => Promise<{ ok: boolean; status?: number; data?: unknown; error?: unknown }>
221
- composeManifestFetch: (
222
- inner: ManifestFetchFn,
223
- ...middlewares: Array<(next: ManifestFetchFn) => ManifestFetchFn>
224
- ) => ManifestFetchFn
225
- manifestFetchCacheMiddleware: (options?: ManifestFetchCacheOptions) => (next: ManifestFetchFn) => ManifestFetchFn
226
- wrapManifestFetchWithCache: (inner: ManifestFetchFn, options?: ManifestFetchCacheOptions) => ManifestFetchFn
227
- }>
228
- host: Readonly<{
229
- createHostApi: (pluginId: string, router: unknown, hostKit?: HostKitOptions) => HostApi
230
- disposeWebPlugin: (pluginId: string) => void
231
- createRequestBridge: (config?: { allowedPathPrefixes?: string[] }) => {
232
- request: (path: string, init?: RequestInit) => Promise<Response>
233
- }
234
- registries: unknown
235
- }>
236
- config: Readonly<{
237
- defaultWebExtendPluginRuntime: Record<string, unknown>
238
- setWebExtendPluginEnv: (env: Record<string, unknown> | null | undefined) => void
239
- webExtendPluginEnvKeys: Readonly<Record<string, string>>
240
- defaultManifestFetchCache: Readonly<{ storageKeyPrefix: string; maxEntries: number }>
241
- defaultManifestMode: string
242
- routeSynthNamePrefix: string
243
- peerMinimumVersions: Readonly<{ vue: string; vueRouter: string }>
244
- }>
245
- constants: Readonly<{ HOST_PLUGIN_API_VERSION: string; RUNTIME_CONSOLE_LABEL: string }>
246
- components: Readonly<{ ExtensionPoint: unknown }>
247
- presets: Readonly<{
248
- vueCliAxios: Readonly<{
249
- id: string
250
- description: string
251
- createInstallOptions: (
252
- deps: { request: (config: Record<string, unknown>) => Promise<unknown> },
253
- extra?: Record<string, unknown>
254
- ) => Record<string, unknown>
255
- createQuickInstallOptions: (
256
- router: unknown,
257
- deps: VueCliAxiosQuickDeps,
258
- extra?: Record<string, unknown>
259
- ) => Record<string, unknown>
260
- defaultJavaManifestListPath: string
261
- manifestPathForApiBase: (manifestUrl: string, apiBase?: string) => string
262
- unwrapManifestBody: (body: unknown) => object | null
263
- }>
264
- }>
265
- }>
148
+ export function getRegisteredTopRouteNamesForPlugin(pluginId: string): string[]
149
+ export function getContributedRoutesForPlugin(pluginId: string): PluginRouteSnapshot[]
266
150
 
267
151
  export const defaultWebExtendPluginRuntime: Record<string, unknown>
268
-
269
- /** 与 `resolveRuntimeOptions` / `build-env` 读取逻辑一致的环境变量键(文档与宿主检索用) */
270
152
  export const webExtendPluginEnvKeys: Readonly<Record<string, string>>
271
-
272
153
  export const defaultManifestFetchCache: Readonly<{ storageKeyPrefix: string; maxEntries: number }>
273
-
274
154
  export const defaultManifestMode: 'api'
275
-
276
- /** 无 name 的路由由 `createHostApi` 合成的名称前缀 */
277
155
  export const routeSynthNamePrefix: string
278
-
279
- /** 与 package.json peer 下限一致,供 CI / `test:peer-min` 对齐 */
280
156
  export const peerMinimumVersions: Readonly<{ vue: string; vueRouter: string }>
281
157
 
282
- /** 拉取清单并依次激活插件;浏览器环境执行 */
283
158
  export function bootstrapPlugins(
284
159
  router: unknown,
285
160
  createHostApiFactory: (id: string, r: unknown, kit?: HostKitOptions) => HostApi,
286
161
  runtimeOptions?: WebExtendPluginRuntimeOptions
287
162
  ): Promise<void>
288
163
 
289
- /** 合并默认配置、环境变量与显式传入字段 */
290
164
  export function resolveRuntimeOptions(user?: WebExtendPluginRuntimeOptions): WebExtendPluginRuntimeOptions
291
165
 
292
166
  export function ensurePluginHostRoute(router: unknown, opts: WebExtendPluginRuntimeOptions): void
167
+ export function getActivatedPluginIds(): string[]
293
168
 
294
169
  export function defaultFetchWebPluginManifest(ctx: {
295
170
  manifestUrl: string
296
171
  credentials: RequestCredentials
297
172
  }): Promise<{ ok: boolean; status?: number; data?: unknown; error?: unknown }>
298
173
 
299
- /** 构造单个插件在宿主侧的 `hostApi`,供 `activator(hostApi, context)` 使用 */
300
174
  export function createHostApi(pluginId: string, router: unknown, hostKit?: HostKitOptions): HostApi
301
175
 
302
176
  export function disposeWebPlugin(pluginId: string): void
@@ -307,53 +181,21 @@ export function createRequestBridge(config?: {
307
181
  }): { request: (path: string, init?: RequestInit) => Promise<Response> }
308
182
 
309
183
  export const HOST_PLUGIN_API_VERSION: string
310
- /** 控制台日志前缀用的短名称 */
311
184
  export const RUNTIME_CONSOLE_LABEL: string
312
185
  export function setWebExtendPluginEnv(env: Record<string, unknown> | null | undefined): void
313
186
 
314
- /** 注册全局 `ExtensionPoint` 并异步 `bootstrapPlugins` */
315
187
  export function installWebExtendPluginVue2(
316
188
  Vue: unknown,
317
189
  router: unknown,
318
190
  options?: WebExtendPluginRuntimeOptions
319
191
  ): Promise<void>
320
192
 
321
- /** Vue CLI + axios 一键安装;默认 `exposeGlobalVue: true` 写入 `window.Vue` */
322
- export function installVueCliAxiosWebPlugins(
323
- Vue: unknown,
324
- router: unknown,
325
- deps: VueCliAxiosQuickDeps,
326
- extra?: WebExtendPluginRuntimeOptions & { exposeGlobalVue?: boolean }
327
- ): Promise<void>
328
-
329
193
  export const ExtensionPoint: unknown
330
194
 
331
- /** 常见 Java 清单路径段,与 `manifestBase` 拼接 */
332
- export const defaultVueCliJavaManifestListPath: string
333
-
334
- export function createVueCliAxiosQuickInstallOptions(
335
- router: unknown,
336
- deps: VueCliAxiosQuickDeps,
337
- extra?: Record<string, unknown>
338
- ): Record<string, unknown>
339
-
340
195
  export function createVueCliAxiosInstallOptions(
341
196
  deps: { request: (config: Record<string, unknown>) => Promise<unknown> },
342
197
  extra?: Record<string, unknown>
343
198
  ): Record<string, unknown>
344
- /** 将完整 manifest URL 转为相对 axios `baseURL` 的请求路径 */
345
- export function resolveManifestPathUnderApiBase(manifestUrl: string, apiBase?: string): string
346
- /** 解包裸清单或与 `{ data: { plugins } }` 包装的响应体 */
347
- export function unwrapNestedManifestBody(body: unknown): object | null
348
- export const presetVueCliAxios: Readonly<{
349
- id: string
350
- description: string
351
- createInstallOptions: typeof createVueCliAxiosInstallOptions
352
- createQuickInstallOptions: typeof createVueCliAxiosQuickInstallOptions
353
- defaultJavaManifestListPath: typeof defaultVueCliJavaManifestListPath
354
- manifestPathForApiBase: typeof resolveManifestPathUnderApiBase
355
- unwrapManifestBody: typeof unwrapNestedManifestBody
356
- }>
357
199
 
358
200
  export function composeManifestFetch(
359
201
  inner: ManifestFetchFn,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-extend-plugin-vue2",
3
- "version": "0.2.5",
3
+ "version": "0.3.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -21,7 +21,7 @@
21
21
  "index.d.ts"
22
22
  ],
23
23
  "peerDependencies": {
24
- "vue": ">=2.6.14 <3.0.0",
24
+ "vue": ">=2.6.0 <3.0.0",
25
25
  "vue-router": ">=3.5.0 <4.0.0"
26
26
  },
27
27
  "dependencies": {
@@ -35,15 +35,12 @@
35
35
  "rollup": "^4.28.0",
36
36
  "tslib": "^2.8.1",
37
37
  "typescript": "^5.7.2",
38
- "vitest": "^2.1.9",
39
38
  "vue": "^2.7.16",
40
39
  "vue-router": "^3.6.5"
41
40
  },
42
41
  "scripts": {
43
42
  "build": "rollup -c rollup.config.mjs",
44
- "test": "vitest run",
45
- "test:peer-min": "npm install --no-save vue@2.6.14 vue-router@3.5.4 && npm run build && npm test && npm install",
46
- "prepublishOnly": "npm run build && npm run test"
43
+ "prepublishOnly": "npm run build"
47
44
  },
48
45
  "license": "Apache-2.0",
49
46
  "repository": {