web-extend-plugin-vue2 0.2.2 → 0.2.5

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,7 +1,186 @@
1
1
  /**
2
- * 稳定对外 API 的 TypeScript 声明(宿主需自行安装 vue / vue-router 类型时可再收紧 any)。
2
+ * 公共 API 的 TypeScript 声明;IDE 补全以本文件为准。
3
3
  */
4
4
 
5
+ /** 清单侧路由声明(PRD),需配合 `adaptRouteDeclarations` */
6
+ export type RouteDeclaration = {
7
+ path: string
8
+ name?: string
9
+ title?: string
10
+ meta?: Record<string, unknown>
11
+ children?: RouteDeclaration[]
12
+ /** 由宿主在 `adaptRouteDeclarations` 中解析为 Vue 组件 */
13
+ componentRef: string
14
+ }
15
+
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
+ export type VueRouteConfig = Record<string, unknown>
27
+
28
+ /** 在合成 `name` / `meta.pluginId` 之前转换插件提交的 `RouteConfig` */
29
+ export type TransformRoutesFn = (ctx: {
30
+ pluginId: string
31
+ router: unknown
32
+ routes: ReadonlyArray<VueRouteConfig>
33
+ }) => VueRouteConfig[]
34
+
35
+ /** 接管路由注册;由宿主决定是否调用 `applyInternalRegister` */
36
+ export type InterceptRegisterRoutesFn = (ctx: {
37
+ pluginId: string
38
+ router: unknown
39
+ routes: ReadonlyArray<VueRouteConfig>
40
+ /** 与默认 `registerRoutes` 相同的包装 + `router.addRoute` */
41
+ applyInternalRegister: (routes: VueRouteConfig[]) => void
42
+ }) => void
43
+
44
+ /** PRD → `RouteConfig` */
45
+ export type AdaptRouteDeclarationsFn = (ctx: {
46
+ pluginId: string
47
+ router: unknown
48
+ declarations: ReadonlyArray<RouteDeclaration>
49
+ }) => VueRouteConfig[]
50
+
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
+ export type HostContext = Readonly<Record<string, unknown>>
63
+
64
+ export type OnBeforePluginActivateFn = (ctx: {
65
+ pluginId: string
66
+ router: unknown
67
+ pluginRecord: Readonly<Record<string, unknown>>
68
+ }) => void | Promise<void>
69
+
70
+ export type OnAfterPluginActivateFn = (ctx: {
71
+ pluginId: string
72
+ router: unknown
73
+ pluginRecord: Readonly<Record<string, unknown>>
74
+ hostApi: unknown
75
+ }) => void | Promise<void>
76
+
77
+ export type OnPluginActivateErrorFn = (ctx: {
78
+ pluginId: string
79
+ error: unknown
80
+ pluginRecord: Readonly<Record<string, unknown>>
81
+ hostApi: unknown
82
+ }) => void | Promise<void>
83
+
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
+ }
94
+
95
+ export type HostKitOptions = {
96
+ /** `getBridge().request` 允许的URL路径前缀,须以 `/` 开头 */
97
+ bridgeAllowedPathPrefixes?: string[]
98
+ /** 非空时子路由挂到该命名父路由下(需 vue-router ≥3.5 的 `addRoute`) */
99
+ pluginRoutesParentName?: string
100
+ transformRoutes?: TransformRoutesFn
101
+ interceptRegisterRoutes?: InterceptRegisterRoutesFn
102
+ adaptRouteDeclarations?: AdaptRouteDeclarationsFn
103
+ /** 必填:插件调用 `registerMenuItems` 时由此写入宿主菜单/路由树等数据结构 */
104
+ applyPluginMenuItems?: ApplyPluginMenuItemsFn
105
+ /** 建议与 `applyPluginMenuItems` 成对配置;`disposeWebPlugin` 会调用以撤销该插件菜单 */
106
+ revokePluginMenuItems?: RevokePluginMenuItemsFn
107
+ /** 由引导流程浅冻结后传入各插件的 `hostApi.hostContext` */
108
+ hostContext?: HostContext
109
+ }
110
+
111
+ /** `resolveRuntimeOptions` 全量运行时选项(在默认字段基础上的扩展;未列字段见 README) */
112
+ export type WebExtendPluginRuntimeOptions = HostKitOptions &
113
+ Record<string, unknown> & {
114
+ manifestBase?: string
115
+ manifestListPath?: string
116
+ /** 默认 `api`;`static` 时用 `staticManifestUrl` 拉取聚合 JSON,不请求 Java 清单接口 */
117
+ manifestMode?: 'api' | 'static'
118
+ /** 静态清单 URL(绝对或站点内路径),`manifestMode: 'static'` 时必填(或配置环境变量) */
119
+ staticManifestUrl?: string
120
+ /** `manifestMode=api` 且开发环境:API 失败或 `plugins` 为空时是否尝试 `devFallbackStaticManifestUrl`(默认 true) */
121
+ devManifestFallback?: boolean
122
+ /** 开发回退静态清单路径,默认 `/web-plugins/plugins.manifest.json` */
123
+ devFallbackStaticManifestUrl?: string
124
+ manifestFetchCredentials?: RequestCredentials
125
+ /** 宿主 Layout,传入后自动注册 `pluginMountPath` 壳路由 */
126
+ hostLayoutComponent?: unknown
127
+ /** 插件 URL 前缀,默认 `/plugin` */
128
+ pluginMountPath?: string
129
+ /** 壳路由 meta */
130
+ pluginHostRouteMeta?: Record<string, unknown>
131
+ /** 是否执行自动壳路由注册,默认 true */
132
+ ensurePluginHostRoute?: boolean
133
+ isDev?: boolean
134
+ webPluginDevOrigin?: string
135
+ webPluginDevIds?: string
136
+ webPluginDevMapJson?: string
137
+ webPluginDevEntryPath?: string
138
+ devPingPath?: string
139
+ devReloadSsePath?: string
140
+ devPingTimeoutMs?: number
141
+ defaultImplicitDevPluginIds?: string[]
142
+ allowedScriptHosts?: string[]
143
+ bootstrapSummary?: boolean
144
+ fetchManifest?: ManifestFetchFn
145
+ /** 插件通过 `hostApi.hostContext` 只读访问(浅冻结拷贝);如 `{ store, i18n }` */
146
+ hostContext?: Record<string, unknown>
147
+ /** 调用 `activator` 之前;抛出异常将跳过该插件并计入失败 */
148
+ onBeforePluginActivate?: OnBeforePluginActivateFn
149
+ /** `activator` 成功返回后 */
150
+ onAfterPluginActivate?: OnAfterPluginActivateFn
151
+ /** `activator` 抛错后;用于埋点/降级,不应再抛错(再抛仅记录 warn) */
152
+ onPluginActivateError?: OnPluginActivateErrorFn
153
+ }
154
+
155
+ /** 插件 `activator` 收到的宿主 API */
156
+ export interface HostApi {
157
+ /** 宿主实现的 Host API 协议版本,与清单 `hostPluginApiVersion` 对齐 */
158
+ readonly hostPluginApiVersion: string
159
+ /** 宿主注入上下文(`resolveRuntimeOptions.hostContext` 的浅冻结快照);无则 `{}` */
160
+ readonly hostContext: HostContext
161
+ /**
162
+ * 动态注册路由。含 PRD 时使用 `componentRef` 树;否则传入 `RouteConfig` 数组。
163
+ * 流水线:`adaptRouteDeclarations` → `transformRoutes` → `interceptRegisterRoutes` 或默认注册。
164
+ */
165
+ registerRoutes(routes: VueRouteConfig[] | RouteDeclaration[]): void
166
+ /**
167
+ * 向宿主登记侧栏/目录菜单意图;由 `applyPluginMenuItems` 写入宿主 state。
168
+ * 未配置 `applyPluginMenuItems` 时调用会抛错。
169
+ */
170
+ registerMenuItems(items: Record<string, unknown>[]): void
171
+ registerSlotComponents(
172
+ pointId: string,
173
+ components: Array<{ component: unknown; priority?: number }>
174
+ ): void
175
+ registerStylesheetUrls(urls?: string[]): void
176
+ registerScriptUrls(urls?: string[]): void
177
+ registerSanitizedHtmlSnippet(): void
178
+ getBridge(): {
179
+ request(path: string, init?: RequestInit): Promise<Response>
180
+ }
181
+ onTeardown(_pluginId: string, fn: () => void): void
182
+ }
183
+
5
184
  export type ManifestFetchContext = { manifestUrl: string; credentials: RequestCredentials }
6
185
 
7
186
  export type ManifestFetchResult = {
@@ -23,15 +202,18 @@ export type ManifestFetchCacheOptions = {
23
202
  now?: () => number
24
203
  }
25
204
 
205
+ /** 命名空间聚合对象,按领域分组 */
26
206
  export const WebExtendPluginVue2: Readonly<{
27
- install: (Vue: unknown, router: unknown, options?: Record<string, unknown>) => Promise<void>
207
+ install: (Vue: unknown, router: unknown, options?: WebExtendPluginRuntimeOptions) => Promise<void>
28
208
  runtime: Readonly<{
209
+ /** 拉取清单并依次 `activator(hostApi, { pluginRecord })` */
29
210
  bootstrapPlugins: (
30
211
  router: unknown,
31
- createHostApiFactory: (id: string, r: unknown, kit?: unknown) => unknown,
32
- runtimeOptions?: Record<string, unknown>
212
+ createHostApiFactory: (id: string, r: unknown, kit?: HostKitOptions) => HostApi,
213
+ runtimeOptions?: WebExtendPluginRuntimeOptions
33
214
  ) => Promise<void>
34
- resolveRuntimeOptions: (user?: Record<string, unknown>) => Record<string, unknown>
215
+ resolveRuntimeOptions: (user?: WebExtendPluginRuntimeOptions) => WebExtendPluginRuntimeOptions
216
+ ensurePluginHostRoute: (router: unknown, opts: WebExtendPluginRuntimeOptions) => void
35
217
  defaultFetchWebPluginManifest: (ctx: {
36
218
  manifestUrl: string
37
219
  credentials: RequestCredentials
@@ -44,7 +226,7 @@ export const WebExtendPluginVue2: Readonly<{
44
226
  wrapManifestFetchWithCache: (inner: ManifestFetchFn, options?: ManifestFetchCacheOptions) => ManifestFetchFn
45
227
  }>
46
228
  host: Readonly<{
47
- createHostApi: (pluginId: string, router: unknown, hostKit?: unknown) => unknown
229
+ createHostApi: (pluginId: string, router: unknown, hostKit?: HostKitOptions) => HostApi
48
230
  disposeWebPlugin: (pluginId: string) => void
49
231
  createRequestBridge: (config?: { allowedPathPrefixes?: string[] }) => {
50
232
  request: (path: string, init?: RequestInit) => Promise<Response>
@@ -54,8 +236,13 @@ export const WebExtendPluginVue2: Readonly<{
54
236
  config: Readonly<{
55
237
  defaultWebExtendPluginRuntime: Record<string, unknown>
56
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 }>
57
244
  }>
58
- constants: Readonly<{ HOST_PLUGIN_API_VERSION: string }>
245
+ constants: Readonly<{ HOST_PLUGIN_API_VERSION: string; RUNTIME_CONSOLE_LABEL: string }>
59
246
  components: Readonly<{ ExtensionPoint: unknown }>
60
247
  presets: Readonly<{
61
248
  vueCliAxios: Readonly<{
@@ -65,6 +252,12 @@ export const WebExtendPluginVue2: Readonly<{
65
252
  deps: { request: (config: Record<string, unknown>) => Promise<unknown> },
66
253
  extra?: Record<string, unknown>
67
254
  ) => Record<string, unknown>
255
+ createQuickInstallOptions: (
256
+ router: unknown,
257
+ deps: VueCliAxiosQuickDeps,
258
+ extra?: Record<string, unknown>
259
+ ) => Record<string, unknown>
260
+ defaultJavaManifestListPath: string
68
261
  manifestPathForApiBase: (manifestUrl: string, apiBase?: string) => string
69
262
  unwrapManifestBody: (body: unknown) => object | null
70
263
  }>
@@ -72,43 +265,94 @@ export const WebExtendPluginVue2: Readonly<{
72
265
  }>
73
266
 
74
267
  export const defaultWebExtendPluginRuntime: Record<string, unknown>
268
+
269
+ /** 与 `resolveRuntimeOptions` / `build-env` 读取逻辑一致的环境变量键(文档与宿主检索用) */
270
+ export const webExtendPluginEnvKeys: Readonly<Record<string, string>>
271
+
272
+ export const defaultManifestFetchCache: Readonly<{ storageKeyPrefix: string; maxEntries: number }>
273
+
274
+ export const defaultManifestMode: 'api'
275
+
276
+ /** 无 name 的路由由 `createHostApi` 合成的名称前缀 */
277
+ export const routeSynthNamePrefix: string
278
+
279
+ /** 与 package.json peer 下限一致,供 CI / `test:peer-min` 对齐 */
280
+ export const peerMinimumVersions: Readonly<{ vue: string; vueRouter: string }>
281
+
282
+ /** 拉取清单并依次激活插件;浏览器环境执行 */
75
283
  export function bootstrapPlugins(
76
284
  router: unknown,
77
- createHostApiFactory: (id: string, r: unknown, kit?: unknown) => unknown,
78
- runtimeOptions?: Record<string, unknown>
285
+ createHostApiFactory: (id: string, r: unknown, kit?: HostKitOptions) => HostApi,
286
+ runtimeOptions?: WebExtendPluginRuntimeOptions
79
287
  ): Promise<void>
80
- export function resolveRuntimeOptions(user?: Record<string, unknown>): Record<string, unknown>
288
+
289
+ /** 合并默认配置、环境变量与显式传入字段 */
290
+ export function resolveRuntimeOptions(user?: WebExtendPluginRuntimeOptions): WebExtendPluginRuntimeOptions
291
+
292
+ export function ensurePluginHostRoute(router: unknown, opts: WebExtendPluginRuntimeOptions): void
293
+
81
294
  export function defaultFetchWebPluginManifest(ctx: {
82
295
  manifestUrl: string
83
296
  credentials: RequestCredentials
84
297
  }): Promise<{ ok: boolean; status?: number; data?: unknown; error?: unknown }>
85
- export function createHostApi(pluginId: string, router: unknown, hostKit?: unknown): unknown
298
+
299
+ /** 构造单个插件在宿主侧的 `hostApi`,供 `activator(hostApi, context)` 使用 */
300
+ export function createHostApi(pluginId: string, router: unknown, hostKit?: HostKitOptions): HostApi
301
+
86
302
  export function disposeWebPlugin(pluginId: string): void
87
303
  export const registries: unknown
304
+
88
305
  export function createRequestBridge(config?: {
89
306
  allowedPathPrefixes?: string[]
90
307
  }): { request: (path: string, init?: RequestInit) => Promise<Response> }
308
+
91
309
  export const HOST_PLUGIN_API_VERSION: string
310
+ /** 控制台日志前缀用的短名称 */
311
+ export const RUNTIME_CONSOLE_LABEL: string
92
312
  export function setWebExtendPluginEnv(env: Record<string, unknown> | null | undefined): void
313
+
314
+ /** 注册全局 `ExtensionPoint` 并异步 `bootstrapPlugins` */
93
315
  export function installWebExtendPluginVue2(
94
316
  Vue: unknown,
95
317
  router: unknown,
96
- options?: Record<string, unknown>
318
+ options?: WebExtendPluginRuntimeOptions
319
+ ): Promise<void>
320
+
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 }
97
327
  ): Promise<void>
328
+
98
329
  export const ExtensionPoint: unknown
99
330
 
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
+
100
340
  export function createVueCliAxiosInstallOptions(
101
341
  deps: { request: (config: Record<string, unknown>) => Promise<unknown> },
102
342
  extra?: Record<string, unknown>
103
343
  ): Record<string, unknown>
104
- export function manifestPathForVueCliApiBase(manifestUrl: string, apiBase?: string): string
105
- export function unwrapTableStyleManifestBody(body: unknown): object | null
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
106
348
  export const presetVueCliAxios: Readonly<{
107
349
  id: string
108
350
  description: string
109
351
  createInstallOptions: typeof createVueCliAxiosInstallOptions
110
- manifestPathForApiBase: typeof manifestPathForVueCliApiBase
111
- unwrapManifestBody: typeof unwrapTableStyleManifestBody
352
+ createQuickInstallOptions: typeof createVueCliAxiosQuickInstallOptions
353
+ defaultJavaManifestListPath: typeof defaultVueCliJavaManifestListPath
354
+ manifestPathForApiBase: typeof resolveManifestPathUnderApiBase
355
+ unwrapManifestBody: typeof unwrapNestedManifestBody
112
356
  }>
113
357
 
114
358
  export function composeManifestFetch(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "web-extend-plugin-vue2",
3
- "version": "0.2.2",
3
+ "version": "0.2.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "peerDependencies": {
24
24
  "vue": ">=2.6.14 <3.0.0",
25
- "vue-router": ">=3.2.0 <4.0.0"
25
+ "vue-router": ">=3.5.0 <4.0.0"
26
26
  },
27
27
  "dependencies": {
28
28
  "semver": "^7.6.3"
@@ -30,12 +30,19 @@
30
30
  "devDependencies": {
31
31
  "@rollup/plugin-commonjs": "^29.0.2",
32
32
  "@rollup/plugin-node-resolve": "^15.3.0",
33
+ "@rollup/plugin-typescript": "^12.1.2",
34
+ "@types/node": "^22.10.2",
33
35
  "rollup": "^4.28.0",
34
- "vitest": "^2.1.9"
36
+ "tslib": "^2.8.1",
37
+ "typescript": "^5.7.2",
38
+ "vitest": "^2.1.9",
39
+ "vue": "^2.7.16",
40
+ "vue-router": "^3.6.5"
35
41
  },
36
42
  "scripts": {
37
43
  "build": "rollup -c rollup.config.mjs",
38
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",
39
46
  "prepublishOnly": "npm run build && npm run test"
40
47
  },
41
48
  "license": "Apache-2.0",