web-extend-plugin-vue2 0.3.5 → 0.3.7

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/dist/index.cjs CHANGED
@@ -231,21 +231,35 @@ function isScriptHostAllowed(url, hostSet) {
231
231
  }
232
232
  }
233
233
 
234
- /**
235
- * 合并用户、环境与默认配置得到运行时选项。
236
- */
237
234
  const DEF = defaultWebExtendPluginRuntime;
238
235
  const EK = webExtendPluginEnvKeys;
236
+ function asRecord$1(value) {
237
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
238
+ }
239
+ function normalizeHostBridge(userVal) {
240
+ const raw = asRecord$1(userVal);
241
+ if (!raw) {
242
+ return undefined;
243
+ }
244
+ const normalized = {};
245
+ if (raw.modules && typeof raw.modules === 'object' && !Array.isArray(raw.modules)) {
246
+ normalized.modules = { ...raw.modules };
247
+ }
248
+ if (raw.components && typeof raw.components === 'object' && !Array.isArray(raw.components)) {
249
+ normalized.components = { ...raw.components };
250
+ }
251
+ return normalized.modules || normalized.components ? normalized : undefined;
252
+ }
239
253
  function resolveManifestCredentials(userVal, envKey, fallback) {
240
254
  if (userVal !== undefined) {
241
- const s = String(userVal);
242
- if (s === 'include' || s === 'omit' || s === 'same-origin') {
243
- return s;
255
+ const normalized = String(userVal);
256
+ if (normalized === 'include' || normalized === 'omit' || normalized === 'same-origin') {
257
+ return normalized;
244
258
  }
245
259
  }
246
- const e = resolveBundledEnv(envKey, '');
247
- if (e === 'include' || e === 'omit' || e === 'same-origin') {
248
- return e;
260
+ const envValue = resolveBundledEnv(envKey, '');
261
+ if (envValue === 'include' || envValue === 'omit' || envValue === 'same-origin') {
262
+ return envValue;
249
263
  }
250
264
  return fallback;
251
265
  }
@@ -254,167 +268,184 @@ function resolvePositiveInt(userVal, envKey, fallback) {
254
268
  return Math.floor(userVal);
255
269
  }
256
270
  const raw = resolveBundledEnv(envKey, '');
257
- const n = raw ? parseInt(raw, 10) : NaN;
258
- if (Number.isFinite(n) && n > 0) {
259
- return n;
271
+ const parsed = raw ? parseInt(raw, 10) : NaN;
272
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
273
+ }
274
+ function normalizeStringList$1(value) {
275
+ if (Array.isArray(value)) {
276
+ return value.map(String).map((item) => item.trim()).filter(Boolean);
260
277
  }
261
- return fallback;
278
+ if (typeof value === 'string' && value.trim()) {
279
+ return value
280
+ .split(',')
281
+ .map((item) => item.trim())
282
+ .filter(Boolean);
283
+ }
284
+ return [];
285
+ }
286
+ function resolveAllowedScriptHosts(value) {
287
+ const raw = normalizeStringList$1(value);
288
+ return raw.length > 0 ? raw.map(normalizeHost).filter(Boolean) : [];
289
+ }
290
+ function resolvePathPrefixes(value) {
291
+ const raw = normalizeStringList$1(value);
292
+ return raw.length > 0 ? raw.map((item) => ensureLeadingPath(item)).filter(Boolean) : [];
293
+ }
294
+ function resolveBoolean(value) {
295
+ if (value === true || value === false) {
296
+ return value;
297
+ }
298
+ return undefined;
299
+ }
300
+ function resolveManifestInput(user) {
301
+ return asRecord$1(user.manifest) || {};
302
+ }
303
+ function resolveHostInput(user) {
304
+ return asRecord$1(user.host) || {};
305
+ }
306
+ function resolveDevInput(user) {
307
+ return asRecord$1(user.dev) || {};
308
+ }
309
+ function resolveHooksInput(user) {
310
+ return asRecord$1(user.hooks) || {};
311
+ }
312
+ function resolveDevPluginIds(dev) {
313
+ const explicit = normalizeStringList$1(dev.pluginIds);
314
+ if (explicit.length > 0) {
315
+ return explicit;
316
+ }
317
+ const fromEnv = normalizeStringList$1(resolveBundledEnv(EK.webPluginDevIds, ''));
318
+ if (fromEnv.length > 0) {
319
+ return fromEnv;
320
+ }
321
+ const implicit = normalizeStringList$1(resolveBundledEnv(EK.implicitDevIds, ''));
322
+ return implicit.length > 0 ? implicit : [...DEF.defaultImplicitDevPluginIds];
323
+ }
324
+ function resolveDevManifestFallback(dev, manifestMode, isDev) {
325
+ if (manifestMode === 'static') {
326
+ return false;
327
+ }
328
+ const direct = resolveBoolean(dev.manifestFallback && dev.manifestFallback.enabled);
329
+ if (direct !== undefined) {
330
+ return direct;
331
+ }
332
+ const envFlag = resolveBundledEnv(EK.devManifestFallback, '');
333
+ if (envFlag === '0' || envFlag === 'false') {
334
+ return false;
335
+ }
336
+ if (envFlag === '1' || envFlag === 'true') {
337
+ return true;
338
+ }
339
+ return isDev;
262
340
  }
263
- /** 合并用户、环境变量与 `defaultWebExtendPluginRuntime`,得到完整运行时选项(宿主可只传需要覆盖的字段)。 */
264
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
265
341
  function resolveRuntimeOptions$1(user = {}) {
266
- const manifestBaseRaw = user.manifestBase !== undefined && user.manifestBase !== ''
267
- ? String(user.manifestBase)
342
+ const manifest = resolveManifestInput(user);
343
+ const host = resolveHostInput(user);
344
+ const hostRoute = asRecord$1(host.route) || {};
345
+ const dev = resolveDevInput(user);
346
+ const devFallback = asRecord$1(dev.manifestFallback) || {};
347
+ const hooks = resolveHooksInput(user);
348
+ const normalizedHostBridge = normalizeHostBridge(host.bridge);
349
+ const manifestBaseRaw = manifest.baseUrl !== undefined && String(manifest.baseUrl).trim() !== ''
350
+ ? String(manifest.baseUrl)
268
351
  : resolveBundledEnv(EK.manifestBase, DEF.manifestBase) || DEF.manifestBase;
269
- const manifestListPath = ensureLeadingPath(user.manifestListPath !== undefined && user.manifestListPath !== ''
270
- ? user.manifestListPath
352
+ const manifestListPath = ensureLeadingPath(manifest.listPath !== undefined && String(manifest.listPath).trim() !== ''
353
+ ? manifest.listPath
271
354
  : resolveBundledEnv(EK.manifestListPath, DEF.manifestListPath));
272
- const defaultImplicitDevPluginIds = Array.isArray(user.defaultImplicitDevPluginIds)
273
- ? user.defaultImplicitDevPluginIds.map(String).filter(Boolean)
274
- : (() => {
275
- const e = resolveBundledEnv(EK.implicitDevIds, '');
276
- if (e) {
277
- return e
278
- .split(',')
279
- .map((s) => s.trim())
280
- .filter(Boolean);
281
- }
282
- return [...DEF.defaultImplicitDevPluginIds];
283
- })();
284
- const allowedScriptHosts = Array.isArray(user.allowedScriptHosts) && user.allowedScriptHosts.length > 0
285
- ? user.allowedScriptHosts.map((h) => normalizeHost(String(h))).filter(Boolean)
286
- : (() => {
287
- const e = resolveBundledEnv(EK.allowedScriptHosts, '');
288
- if (e) {
289
- return e
290
- .split(',')
291
- .map((s) => normalizeHost(s.trim()))
292
- .filter(Boolean);
293
- }
294
- return [...DEF.allowedScriptHosts];
295
- })();
296
- const bridgeAllowedPathPrefixes = Array.isArray(user.bridgeAllowedPathPrefixes) && user.bridgeAllowedPathPrefixes.length > 0
297
- ? user.bridgeAllowedPathPrefixes.map((p) => ensureLeadingPath(p)).filter(Boolean)
298
- : (() => {
299
- const e = resolveBundledEnv(EK.bridgePrefixes, '');
300
- if (e) {
301
- return e
302
- .split(',')
303
- .map((s) => ensureLeadingPath(s.trim()))
304
- .filter(Boolean);
305
- }
306
- return [...DEF.bridgeAllowedPathPrefixes];
307
- })();
308
- const manifestMode = resolveManifestModeFromInputs(user.manifestMode);
309
- const staticManifestUrl = resolveStaticManifestUrlFromInputs(user.staticManifestUrl);
310
- const isDevResolved = user.isDev !== undefined ? user.isDev : resolveBundledIsDev();
311
- const devFallbackStaticManifestUrl = (() => {
312
- if (user.devFallbackStaticManifestUrl !== undefined && String(user.devFallbackStaticManifestUrl).trim() !== '') {
313
- return String(user.devFallbackStaticManifestUrl).trim();
355
+ const allowedScriptHosts = (() => {
356
+ const explicit = resolveAllowedScriptHosts(host.scriptHosts);
357
+ if (explicit.length > 0) {
358
+ return explicit;
314
359
  }
315
- const e = resolveBundledEnv(EK.devFallbackManifestUrl, '');
316
- if (e) {
317
- return e.trim();
360
+ const fromEnv = resolveAllowedScriptHosts(resolveBundledEnv(EK.allowedScriptHosts, ''));
361
+ return fromEnv.length > 0 ? fromEnv : [...DEF.allowedScriptHosts];
362
+ })();
363
+ const bridgeAllowedPathPrefixes = (() => {
364
+ const explicit = resolvePathPrefixes(host.requestPathPrefixes);
365
+ if (explicit.length > 0) {
366
+ return explicit;
367
+ }
368
+ const fromEnv = resolvePathPrefixes(resolveBundledEnv(EK.bridgePrefixes, ''));
369
+ return fromEnv.length > 0 ? fromEnv : [...DEF.bridgeAllowedPathPrefixes];
370
+ })();
371
+ const manifestMode = resolveManifestModeFromInputs(manifest.source);
372
+ const staticManifestUrl = resolveStaticManifestUrlFromInputs(manifest.staticUrl);
373
+ const isDev = resolveBoolean(dev.enabled) !== undefined ? Boolean(dev.enabled) : resolveBundledIsDev();
374
+ const devFallbackStaticManifestUrl = (() => {
375
+ if (devFallback.staticUrl !== undefined && String(devFallback.staticUrl).trim() !== '') {
376
+ return String(devFallback.staticUrl).trim();
318
377
  }
319
- return String(DEF.devFallbackStaticManifestUrl).trim();
378
+ const envValue = resolveBundledEnv(EK.devFallbackManifestUrl, '');
379
+ return envValue ? envValue.trim() : String(DEF.devFallbackStaticManifestUrl).trim();
320
380
  })();
321
- const hostLayoutComponent = user.hostLayoutComponent;
322
- const pluginRoutesParentName = user.pluginRoutesParentName !== undefined && String(user.pluginRoutesParentName).trim() !== ''
323
- ? String(user.pluginRoutesParentName).trim()
381
+ const pluginRoutesParentName = hostRoute.parentName !== undefined && String(hostRoute.parentName).trim() !== ''
382
+ ? String(hostRoute.parentName).trim()
324
383
  : '';
325
- const pluginMountRaw = user.pluginMountPath !== undefined && String(user.pluginMountPath).trim() !== ''
326
- ? String(user.pluginMountPath).trim()
384
+ const pluginMountRaw = hostRoute.mountPath !== undefined && String(hostRoute.mountPath).trim() !== ''
385
+ ? String(hostRoute.mountPath).trim()
327
386
  : String(resolveBundledEnv(EK.mountPath, '') || DEF.pluginMountPath).trim();
328
387
  const pluginMountPath = ensureLeadingPath(pluginMountRaw || DEF.pluginMountPath);
329
- const pluginHostRouteMeta = user.pluginHostRouteMeta !== undefined && user.pluginHostRouteMeta !== null
330
- ? user.pluginHostRouteMeta
331
- : undefined;
332
- const ensurePluginHostRoute = user.ensurePluginHostRoute === true;
333
- const devManifestFallback = (() => {
334
- if (manifestMode === 'static') {
335
- return false;
336
- }
337
- if (user.devManifestFallback === false) {
338
- return false;
339
- }
340
- if (user.devManifestFallback === true) {
341
- return true;
342
- }
343
- const envFlag = resolveBundledEnv(EK.devManifestFallback, '');
344
- if (envFlag === '0' || envFlag === 'false') {
345
- return false;
346
- }
347
- if (envFlag === '1' || envFlag === 'true') {
348
- return true;
388
+ const pluginHostRouteMeta = asRecord$1(hostRoute.meta);
389
+ const ensurePluginHostRoute = resolveBoolean(hostRoute.enabled) === true;
390
+ const webPluginDevMapJson = (() => {
391
+ if (dev.pluginMap && typeof dev.pluginMap === 'object' && !Array.isArray(dev.pluginMap)) {
392
+ return JSON.stringify(dev.pluginMap);
349
393
  }
350
- return !!isDevResolved;
394
+ return dev.pluginMap !== undefined ? String(dev.pluginMap || '') : resolveBundledEnv(EK.webPluginDevMap, '');
351
395
  })();
352
396
  return {
353
397
  manifestBase: manifestBaseRaw.replace(/\/$/, '') || DEF.manifestBase.replace(/\/$/, ''),
354
398
  manifestListPath,
355
399
  manifestMode,
356
400
  staticManifestUrl,
357
- devManifestFallback,
401
+ devManifestFallback: resolveDevManifestFallback(dev, manifestMode, isDev),
358
402
  devFallbackStaticManifestUrl,
359
- manifestFetchCredentials: resolveManifestCredentials(user.manifestFetchCredentials, EK.manifestCredentials, DEF.manifestFetchCredentials),
360
- isDev: isDevResolved,
361
- webPluginDevOrigin: user.webPluginDevOrigin !== undefined
362
- ? user.webPluginDevOrigin
363
- : resolveBundledEnv(EK.webPluginDevOrigin, ''),
364
- webPluginDevIds: user.webPluginDevIds !== undefined ? user.webPluginDevIds : resolveBundledEnv(EK.webPluginDevIds, ''),
365
- webPluginDevMapJson: user.webPluginDevMapJson !== undefined
366
- ? user.webPluginDevMapJson
367
- : resolveBundledEnv(EK.webPluginDevMap, ''),
368
- webPluginDevEntryPath: ensureLeadingPath(user.webPluginDevEntryPath !== undefined && user.webPluginDevEntryPath !== ''
369
- ? user.webPluginDevEntryPath
403
+ manifestFetchCredentials: resolveManifestCredentials(manifest.credentials, EK.manifestCredentials, DEF.manifestFetchCredentials),
404
+ isDev,
405
+ webPluginDevOrigin: dev.origin !== undefined ? String(dev.origin || '').trim() : resolveBundledEnv(EK.webPluginDevOrigin, ''),
406
+ webPluginDevIds: resolveDevPluginIds(dev),
407
+ webPluginDevMapJson,
408
+ webPluginDevEntryPath: ensureLeadingPath(dev.entryPath !== undefined && String(dev.entryPath).trim() !== ''
409
+ ? String(dev.entryPath)
370
410
  : resolveBundledEnv(EK.devEntry, DEF.webPluginDevEntryPath)),
371
- devPingPath: ensureLeadingPath(user.devPingPath !== undefined && user.devPingPath !== ''
372
- ? user.devPingPath
411
+ devPingPath: ensureLeadingPath(dev.pingPath !== undefined && String(dev.pingPath).trim() !== ''
412
+ ? String(dev.pingPath)
373
413
  : resolveBundledEnv(EK.devPing, DEF.devPingPath)),
374
- devReloadSsePath: ensureLeadingPath(user.devReloadSsePath !== undefined && user.devReloadSsePath !== ''
375
- ? user.devReloadSsePath
414
+ devReloadSsePath: ensureLeadingPath(dev.reloadSsePath !== undefined && String(dev.reloadSsePath).trim() !== ''
415
+ ? String(dev.reloadSsePath)
376
416
  : resolveBundledEnv(EK.devSse, DEF.devReloadSsePath)),
377
- devPingTimeoutMs: resolvePositiveInt(user.devPingTimeoutMs, EK.devPingTimeout, DEF.devPingTimeoutMs),
378
- defaultImplicitDevPluginIds,
417
+ devPingTimeoutMs: resolvePositiveInt(dev.pingTimeoutMs, EK.devPingTimeout, DEF.devPingTimeoutMs),
418
+ defaultImplicitDevPluginIds: [...DEF.defaultImplicitDevPluginIds],
379
419
  allowedScriptHosts,
380
420
  bridgeAllowedPathPrefixes,
381
- bootstrapSummary: user.bootstrapSummary,
382
- hostLayoutComponent,
421
+ bootstrapSummary: resolveBoolean(dev.bootstrapSummary),
422
+ hostLayoutComponent: hostRoute.layout,
383
423
  pluginMountPath,
384
424
  pluginHostRouteMeta,
385
425
  ensurePluginHostRoute,
386
426
  pluginRoutesParentName,
387
- ...(typeof user.fetchManifest === 'function' ? { fetchManifest: user.fetchManifest } : {}),
388
- ...(typeof user.transformRoutes === 'function' ? { transformRoutes: user.transformRoutes } : {}),
389
- ...(typeof user.interceptRegisterRoutes === 'function'
390
- ? { interceptRegisterRoutes: user.interceptRegisterRoutes }
391
- : {}),
392
- ...(typeof user.adaptRouteDeclarations === 'function'
393
- ? { adaptRouteDeclarations: user.adaptRouteDeclarations }
427
+ ...(typeof manifest.fetch === 'function' ? { fetchManifest: manifest.fetch } : {}),
428
+ ...(typeof hooks.transformRoutes === 'function' ? { transformRoutes: hooks.transformRoutes } : {}),
429
+ ...(typeof hooks.interceptRegisterRoutes === 'function'
430
+ ? { interceptRegisterRoutes: hooks.interceptRegisterRoutes }
394
431
  : {}),
395
- ...(typeof user.onPluginRoutesContributed === 'function'
396
- ? { onPluginRoutesContributed: user.onPluginRoutesContributed }
432
+ ...(typeof hooks.adaptRouteDeclarations === 'function'
433
+ ? { adaptRouteDeclarations: hooks.adaptRouteDeclarations }
397
434
  : {}),
398
- ...(user.hostContext !== undefined &&
399
- user.hostContext !== null &&
400
- typeof user.hostContext === 'object' &&
401
- !Array.isArray(user.hostContext)
402
- ? { hostContext: user.hostContext }
435
+ ...(typeof hooks.onRoutesContributed === 'function'
436
+ ? { onPluginRoutesContributed: hooks.onRoutesContributed }
403
437
  : {}),
404
- ...(user.hostCapabilities !== undefined &&
405
- user.hostCapabilities !== null &&
406
- typeof user.hostCapabilities === 'object' &&
407
- !Array.isArray(user.hostCapabilities)
408
- ? { hostCapabilities: user.hostCapabilities }
438
+ ...(asRecord$1(host.context) ? { hostContext: asRecord$1(host.context) } : {}),
439
+ ...(asRecord$1(host.capabilities) ? { hostCapabilities: asRecord$1(host.capabilities) } : {}),
440
+ ...(normalizedHostBridge ? { hostBridge: normalizedHostBridge } : {}),
441
+ ...(typeof hooks.beforeActivate === 'function'
442
+ ? { onBeforePluginActivate: hooks.beforeActivate }
409
443
  : {}),
410
- ...(typeof user.onBeforePluginActivate === 'function'
411
- ? { onBeforePluginActivate: user.onBeforePluginActivate }
444
+ ...(typeof hooks.afterActivate === 'function'
445
+ ? { onAfterPluginActivate: hooks.afterActivate }
412
446
  : {}),
413
- ...(typeof user.onAfterPluginActivate === 'function'
414
- ? { onAfterPluginActivate: user.onAfterPluginActivate }
415
- : {}),
416
- ...(typeof user.onPluginActivateError === 'function'
417
- ? { onPluginActivateError: user.onPluginActivateError }
447
+ ...(typeof hooks.onActivateError === 'function'
448
+ ? { onPluginActivateError: hooks.onActivateError }
418
449
  : {})
419
450
  };
420
451
  }
@@ -3424,18 +3455,31 @@ function disposeWebPlugin(pluginId) {
3424
3455
  }
3425
3456
 
3426
3457
  /**
3427
- * 开发模式插件 URL 映射(显式 JSON + 隐式 dev 探测)。
3458
+ * 开发模式插件 URL 映射。
3428
3459
  */
3460
+ function normalizeStringValue(value) {
3461
+ return value == null ? '' : String(value).trim();
3462
+ }
3463
+ function normalizeStringList(value, fallback = []) {
3464
+ const raw = normalizeStringValue(value);
3465
+ if (!raw) {
3466
+ return [...fallback];
3467
+ }
3468
+ return raw
3469
+ .split(',')
3470
+ .map((item) => item.trim())
3471
+ .filter(Boolean);
3472
+ }
3429
3473
  function parseWebPluginDevMapExplicit(opts) {
3430
3474
  if (!opts.isDev) {
3431
3475
  return null;
3432
3476
  }
3433
- const raw = opts.webPluginDevMapJson;
3434
- if (raw === undefined || raw === null || String(raw).trim() === '') {
3477
+ const raw = normalizeStringValue(opts.webPluginDevMapJson);
3478
+ if (!raw) {
3435
3479
  return null;
3436
3480
  }
3437
3481
  try {
3438
- const map = JSON.parse(String(raw));
3482
+ const map = JSON.parse(raw);
3439
3483
  return map && typeof map === 'object' ? map : null;
3440
3484
  }
3441
3485
  catch (_a) {
@@ -3452,22 +3496,11 @@ async function buildImplicitWebPluginDevMap(opts, hostSet) {
3452
3496
  if (!opts.isDev) {
3453
3497
  return {};
3454
3498
  }
3455
- const origin = opts.webPluginDevOrigin === undefined || opts.webPluginDevOrigin === null
3456
- ? ''
3457
- : String(opts.webPluginDevOrigin).trim();
3458
- if (!origin) {
3459
- return {};
3460
- }
3461
- if (!isScriptHostAllowed(`${origin}/`, hostSet)) {
3499
+ const origin = normalizeStringValue(opts.webPluginDevOrigin);
3500
+ if (!origin || !isScriptHostAllowed(`${origin}/`, hostSet)) {
3462
3501
  return {};
3463
3502
  }
3464
- const idsRaw = opts.webPluginDevIds;
3465
- const ids = idsRaw !== undefined && idsRaw !== null && String(idsRaw).trim() !== ''
3466
- ? String(idsRaw)
3467
- .split(',')
3468
- .map((s) => s.trim())
3469
- .filter(Boolean)
3470
- : [...opts.defaultImplicitDevPluginIds];
3503
+ const ids = normalizeStringList(opts.webPluginDevIds, opts.defaultImplicitDevPluginIds);
3471
3504
  if (ids.length === 0) {
3472
3505
  return {};
3473
3506
  }
@@ -3476,31 +3509,28 @@ async function buildImplicitWebPluginDevMap(opts, hostSet) {
3476
3509
  try {
3477
3510
  const ctrl = new AbortController();
3478
3511
  const timer = setTimeout(() => ctrl.abort(), opts.devPingTimeoutMs);
3479
- const r = await fetch(pingUrl, {
3512
+ const response = await fetch(pingUrl, {
3480
3513
  mode: 'cors',
3481
3514
  cache: 'no-store',
3482
3515
  signal: ctrl.signal
3483
3516
  });
3484
3517
  clearTimeout(timer);
3485
- if (!r.ok) {
3518
+ if (!response.ok) {
3486
3519
  return {};
3487
3520
  }
3488
- const body = (await r.text()).trim();
3489
- if (body !== 'ok') {
3521
+ if ((await response.text()).trim() !== 'ok') {
3490
3522
  return {};
3491
3523
  }
3492
3524
  }
3493
3525
  catch (_a) {
3494
3526
  return {};
3495
3527
  }
3496
- const pathPart = opts.webPluginDevEntryPath;
3528
+ const entryUrl = `${base}${opts.webPluginDevEntryPath}`;
3497
3529
  const map = {};
3498
3530
  for (const id of ids) {
3499
- map[id] = `${base}${pathPart}`;
3500
- }
3501
- if (ids.length) {
3502
- console.info('[wep] plugin dev server', base, '→ implicit entries', pathPart, ids.join(', '));
3531
+ map[id] = entryUrl;
3503
3532
  }
3533
+ console.info('[wep] plugin dev server', base, '-> implicit entries', opts.webPluginDevEntryPath, ids.join(', '));
3504
3534
  return map;
3505
3535
  }
3506
3536
 
@@ -3634,15 +3664,14 @@ async function fetchStaticManifestViaHttp(ctx) {
3634
3664
  }
3635
3665
 
3636
3666
  /**
3637
- * 当 `ensurePluginHostRoute === true` 且提供 `pluginRoutesParentName` + `hostLayoutComponent` 时,
3638
- * 注册 `pluginMountPath` + Layout 的命名父路由,供 `router.addRoute(parentName, child)` 挂载插件页。
3667
+ * 在需要时补注册插件宿主父路由。
3639
3668
  */
3640
3669
  function routeNameExists(router, name) {
3641
3670
  if (!name) {
3642
3671
  return false;
3643
3672
  }
3644
3673
  if (typeof router.getRoutes === 'function') {
3645
- return router.getRoutes().some((r) => r.name === name);
3674
+ return router.getRoutes().some((route) => route.name === name);
3646
3675
  }
3647
3676
  return walkRouteNames(router.options && router.options.routes, name);
3648
3677
  }
@@ -3650,50 +3679,49 @@ function walkRouteNames(routes, name) {
3650
3679
  if (!Array.isArray(routes)) {
3651
3680
  return false;
3652
3681
  }
3653
- for (const r of routes) {
3654
- if (r && typeof r === 'object' && r.name === name) {
3682
+ for (const route of routes) {
3683
+ if (route && typeof route === 'object' && route.name === name) {
3655
3684
  return true;
3656
3685
  }
3657
- const ch = r && typeof r === 'object' ? r.children : null;
3658
- if (walkRouteNames(ch, name)) {
3686
+ const children = route && typeof route === 'object' ? route.children : undefined;
3687
+ if (walkRouteNames(children, name)) {
3659
3688
  return true;
3660
3689
  }
3661
3690
  }
3662
3691
  return false;
3663
3692
  }
3664
- function ensurePluginHostRoute$1(router, opts) {
3665
- if (opts.ensurePluginHostRoute !== true) {
3666
- return;
3667
- }
3668
- if (!router || typeof router.addRoute !== 'function') {
3693
+ function normalizeMountPath(value) {
3694
+ const mountDefault = defaultWebExtendPluginRuntime.pluginMountPath;
3695
+ const raw = String(value || mountDefault).trim().replace(/\/$/, '') || mountDefault;
3696
+ return raw.startsWith('/') ? raw : `/${raw}`;
3697
+ }
3698
+ function resolveRouteMeta(value) {
3699
+ return value && typeof value === 'object' && !Array.isArray(value)
3700
+ ? { ...value }
3701
+ : { requiresConfig: true, hidden: true };
3702
+ }
3703
+ function ensurePluginHostRoute$1(router, options) {
3704
+ const opts = options && typeof options === 'object' && ('manifestBase' in options || 'ensurePluginHostRoute' in options)
3705
+ ? options
3706
+ : resolveRuntimeOptions$1(options);
3707
+ if (opts.ensurePluginHostRoute !== true || !router || typeof router.addRoute !== 'function') {
3669
3708
  return;
3670
3709
  }
3671
3710
  const parentName = String(opts.pluginRoutesParentName || '').trim();
3672
- if (!parentName) {
3673
- return;
3674
- }
3675
- if (routeNameExists(router, parentName)) {
3711
+ if (!parentName || routeNameExists(router, parentName)) {
3676
3712
  return;
3677
3713
  }
3678
3714
  const Layout = opts.hostLayoutComponent;
3679
3715
  if (!Layout) {
3680
- console.warn('[wep] 缺少 hostLayoutComponent,未自动注册插件壳路由;请传入宿主 Layout,或在路由表中自行配置与 pluginRoutesParentName 一致的父路由');
3716
+ console.warn('[wep] missing hostLayoutComponent; plugin host route was not auto-registered');
3681
3717
  return;
3682
3718
  }
3683
- const mountDefault = defaultWebExtendPluginRuntime.pluginMountPath;
3684
- let pathRaw = String(opts.pluginMountPath || mountDefault).trim().replace(/\/$/, '') || mountDefault;
3685
- if (!pathRaw.startsWith('/')) {
3686
- pathRaw = `/${pathRaw}`;
3687
- }
3688
- const meta = opts.pluginHostRouteMeta && typeof opts.pluginHostRouteMeta === 'object'
3689
- ? { ...opts.pluginHostRouteMeta }
3690
- : { requiresConfig: true, hidden: true };
3691
3719
  router.addRoute({
3692
- path: pathRaw,
3720
+ path: normalizeMountPath(opts.pluginMountPath),
3693
3721
  name: parentName,
3694
3722
  component: Layout,
3695
3723
  redirect: 'noredirect',
3696
- meta,
3724
+ meta: resolveRouteMeta(opts.pluginHostRouteMeta),
3697
3725
  children: []
3698
3726
  });
3699
3727
  }
@@ -4075,6 +4103,65 @@ function sortByPriority(plugins) {
4075
4103
  })
4076
4104
  .map((decorated) => decorated.entry);
4077
4105
  }
4106
+ function logBootstrapSummary(enabled, payload) {
4107
+ if (enabled) {
4108
+ console.info('[wep] bootstrap_summary', payload);
4109
+ }
4110
+ }
4111
+ function getManifestBody(result) {
4112
+ return result.ok && result.data && typeof result.data === 'object' ? result.data : null;
4113
+ }
4114
+ function getManifestPluginCount(result) {
4115
+ const body = getManifestBody(result);
4116
+ return body && Array.isArray(body.plugins) ? body.plugins.length : 0;
4117
+ }
4118
+ async function fetchManifestSafely(fetchManifest, manifestCtx) {
4119
+ try {
4120
+ if (typeof fetchManifest === 'function') {
4121
+ return await fetchManifest(manifestCtx);
4122
+ }
4123
+ return await defaultFetchWebPluginManifest$1(manifestCtx);
4124
+ }
4125
+ catch (error) {
4126
+ return { ok: false, error, data: null };
4127
+ }
4128
+ }
4129
+ function buildHostKit(opts) {
4130
+ const frozenHostContext = freezeShallowHostContext(opts.hostContext !== undefined ? opts.hostContext : undefined, opts.hostCapabilities && typeof opts.hostCapabilities === 'object' ? opts.hostCapabilities : undefined);
4131
+ return {
4132
+ hostContext: frozenHostContext,
4133
+ bridgeAllowedPathPrefixes: opts.bridgeAllowedPathPrefixes,
4134
+ ...(opts.pluginRoutesParentName ? { pluginRoutesParentName: opts.pluginRoutesParentName } : {}),
4135
+ ...(typeof opts.transformRoutes === 'function' ? { transformRoutes: opts.transformRoutes } : {}),
4136
+ ...(typeof opts.interceptRegisterRoutes === 'function'
4137
+ ? { interceptRegisterRoutes: opts.interceptRegisterRoutes }
4138
+ : {}),
4139
+ ...(typeof opts.adaptRouteDeclarations === 'function'
4140
+ ? { adaptRouteDeclarations: opts.adaptRouteDeclarations }
4141
+ : {}),
4142
+ ...(typeof opts.onPluginRoutesContributed === 'function'
4143
+ ? { onPluginRoutesContributed: opts.onPluginRoutesContributed }
4144
+ : {})
4145
+ };
4146
+ }
4147
+ function resolveManifestRequest(opts) {
4148
+ const isStatic = opts.manifestMode === 'static';
4149
+ if (isStatic) {
4150
+ const raw = String(opts.staticManifestUrl || '').trim();
4151
+ if (!raw) {
4152
+ return null;
4153
+ }
4154
+ return {
4155
+ isStatic,
4156
+ manifestUrl: resolveStaticManifestUrlForFetch(raw, window.location.origin)
4157
+ };
4158
+ }
4159
+ const base = String(opts.manifestBase).replace(/\/$/, '');
4160
+ return {
4161
+ isStatic,
4162
+ manifestUrl: `${base}${opts.manifestListPath}`
4163
+ };
4164
+ }
4078
4165
  async function bootstrapPlugins$1(
4079
4166
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4080
4167
  router,
@@ -4086,26 +4173,17 @@ createHostApiFactory, runtimeOptions) {
4086
4173
  }
4087
4174
  printRuntimeBannerOnce();
4088
4175
  clearActivatedPluginIds();
4089
- const opts = resolveRuntimeOptions$1(runtimeOptions || {});
4176
+ const opts = resolveRuntimeOptions$1(runtimeOptions);
4177
+ const showBootstrapSummary = shouldShowBootstrapSummary(opts);
4090
4178
  setPluginBootstrapRouter(router);
4091
4179
  ensurePluginHostRoute$1(router, opts);
4092
- const base = String(opts.manifestBase).replace(/\/$/, '');
4093
- const isStatic = opts.manifestMode === 'static';
4094
- let manifestUrl;
4095
- if (isStatic) {
4096
- const raw = String(opts.staticManifestUrl || '').trim();
4097
- if (!raw) {
4098
- console.warn('[wep] manifestMode=static requires non-empty staticManifestUrl (or env VITE_WEB_PLUGIN_STATIC_MANIFEST_URL)');
4099
- if (shouldShowBootstrapSummary(opts)) {
4100
- console.info('[wep] bootstrap_summary', { ok: false, reason: 'static_manifest_url_missing' });
4101
- }
4102
- return;
4103
- }
4104
- manifestUrl = resolveStaticManifestUrlForFetch(raw, window.location.origin);
4105
- }
4106
- else {
4107
- manifestUrl = `${base}${opts.manifestListPath}`;
4180
+ const manifestRequest = resolveManifestRequest(opts);
4181
+ if (!manifestRequest) {
4182
+ console.warn('[wep] manifestMode=static requires non-empty staticManifestUrl (or env VITE_WEB_PLUGIN_STATIC_MANIFEST_URL)');
4183
+ logBootstrapSummary(showBootstrapSummary, { ok: false, reason: 'static_manifest_url_missing' });
4184
+ return;
4108
4185
  }
4186
+ const { isStatic, manifestUrl } = manifestRequest;
4109
4187
  const hostSet = buildAllowedScriptHostsSet(opts.allowedScriptHosts);
4110
4188
  const explicit = parseWebPluginDevMapExplicit(opts);
4111
4189
  const manifestCtx = {
@@ -4113,27 +4191,15 @@ createHostApiFactory, runtimeOptions) {
4113
4191
  credentials: opts.manifestFetchCredentials
4114
4192
  };
4115
4193
  const [primaryResult, implicit] = await Promise.all([
4116
- (async () => {
4117
- try {
4118
- if (typeof opts.fetchManifest === 'function') {
4119
- return await opts.fetchManifest(manifestCtx);
4120
- }
4121
- return await defaultFetchWebPluginManifest$1(manifestCtx);
4122
- }
4123
- catch (e) {
4124
- return { ok: false, error: e, data: null };
4125
- }
4126
- })(),
4194
+ fetchManifestSafely(typeof opts.fetchManifest === 'function'
4195
+ ? opts.fetchManifest
4196
+ : undefined, manifestCtx),
4127
4197
  buildImplicitWebPluginDevMap(opts, hostSet)
4128
4198
  ]);
4129
4199
  let manifestResult = primaryResult;
4130
4200
  let manifestUrlUsed = manifestUrl;
4131
4201
  if (!isStatic && opts.devManifestFallback && opts.isDev) {
4132
- const dataObj = primaryResult.ok && primaryResult.data && typeof primaryResult.data === 'object'
4133
- ? primaryResult.data
4134
- : null;
4135
- const plen = dataObj && Array.isArray(dataObj.plugins) ? dataObj.plugins.length : 0;
4136
- const needFallback = !primaryResult.ok || plen === 0;
4202
+ const needFallback = !primaryResult.ok || getManifestPluginCount(primaryResult) === 0;
4137
4203
  const fallbackRaw = String(opts.devFallbackStaticManifestUrl || '').trim();
4138
4204
  if (needFallback && fallbackRaw) {
4139
4205
  const fallbackUrl = resolveStaticManifestUrlForFetch(fallbackRaw, window.location.origin);
@@ -4142,8 +4208,7 @@ createHostApiFactory, runtimeOptions) {
4142
4208
  credentials: opts.manifestFetchCredentials
4143
4209
  };
4144
4210
  const fr = await fetchStaticManifestViaHttp(fallbackCtx);
4145
- const fdata = fr.ok && fr.data && typeof fr.data === 'object' ? fr.data : null;
4146
- const flen = fdata && Array.isArray(fdata.plugins) ? fdata.plugins.length : 0;
4211
+ const flen = getManifestPluginCount(fr);
4147
4212
  if (fr.ok && flen > 0) {
4148
4213
  manifestResult = fr;
4149
4214
  manifestUrlUsed = fallbackUrl;
@@ -4153,22 +4218,7 @@ createHostApiFactory, runtimeOptions) {
4153
4218
  }
4154
4219
  const devMap = mergeDevMaps(implicit, explicit);
4155
4220
  startPluginDevSseForMap(devMap, opts.isDev, hostSet, opts.devReloadSsePath);
4156
- const frozenHostContext = freezeShallowHostContext(opts.hostContext !== undefined ? opts.hostContext : undefined, opts.hostCapabilities && typeof opts.hostCapabilities === 'object' ? opts.hostCapabilities : undefined);
4157
- const hostKit = {
4158
- hostContext: frozenHostContext,
4159
- bridgeAllowedPathPrefixes: opts.bridgeAllowedPathPrefixes,
4160
- ...(opts.pluginRoutesParentName ? { pluginRoutesParentName: opts.pluginRoutesParentName } : {}),
4161
- ...(typeof opts.transformRoutes === 'function' ? { transformRoutes: opts.transformRoutes } : {}),
4162
- ...(typeof opts.interceptRegisterRoutes === 'function'
4163
- ? { interceptRegisterRoutes: opts.interceptRegisterRoutes }
4164
- : {}),
4165
- ...(typeof opts.adaptRouteDeclarations === 'function'
4166
- ? { adaptRouteDeclarations: opts.adaptRouteDeclarations }
4167
- : {}),
4168
- ...(typeof opts.onPluginRoutesContributed === 'function'
4169
- ? { onPluginRoutesContributed: opts.onPluginRoutesContributed }
4170
- : {})
4171
- };
4221
+ const hostKit = buildHostKit(opts);
4172
4222
  if (!manifestResult.ok) {
4173
4223
  if (manifestResult.error) {
4174
4224
  console.warn('[wep] fetch manifest failed', manifestResult.error);
@@ -4177,16 +4227,12 @@ createHostApiFactory, runtimeOptions) {
4177
4227
  const label = isStatic ? 'static manifest' : 'manifest HTTP';
4178
4228
  console.warn(`[wep] ${label}`, manifestResult.status, manifestUrlUsed);
4179
4229
  }
4180
- if (shouldShowBootstrapSummary(opts)) {
4181
- console.info('[wep] bootstrap_summary', { ok: false, reason: 'manifest_fetch' });
4182
- }
4230
+ logBootstrapSummary(showBootstrapSummary, { ok: false, reason: 'manifest_fetch' });
4183
4231
  return;
4184
4232
  }
4185
- const data = manifestResult.data;
4233
+ const data = getManifestBody(manifestResult);
4186
4234
  if (!data) {
4187
- if (shouldShowBootstrapSummary(opts)) {
4188
- console.info('[wep] bootstrap_summary', { ok: false, reason: 'manifest_empty_body' });
4189
- }
4235
+ logBootstrapSummary(showBootstrapSummary, { ok: false, reason: 'manifest_empty_body' });
4190
4236
  return;
4191
4237
  }
4192
4238
  const apiVer = data.hostPluginApiVersion;
@@ -4199,12 +4245,10 @@ createHostApiFactory, runtimeOptions) {
4199
4245
  host: HOST_PLUGIN_API_VERSION,
4200
4246
  manifest: apiVer
4201
4247
  });
4202
- if (shouldShowBootstrapSummary(opts)) {
4203
- console.info('[wep] bootstrap_summary', {
4204
- ok: false,
4205
- reason: 'manifest_host_api_version_mismatch'
4206
- });
4207
- }
4248
+ logBootstrapSummary(showBootstrapSummary, {
4249
+ ok: false,
4250
+ reason: 'manifest_host_api_version_mismatch'
4251
+ });
4208
4252
  return;
4209
4253
  }
4210
4254
  }
@@ -4304,9 +4348,7 @@ createHostApiFactory, runtimeOptions) {
4304
4348
  }
4305
4349
  }
4306
4350
  }
4307
- if (shouldShowBootstrapSummary(opts)) {
4308
- console.info('[wep] bootstrap_summary', { ok: true, ...summary });
4309
- }
4351
+ logBootstrapSummary(showBootstrapSummary, { ok: true, ...summary });
4310
4352
  }
4311
4353
 
4312
4354
  /**
@@ -4584,10 +4626,39 @@ function clearContributedRoutesForPlugin(pluginId) {
4584
4626
  }
4585
4627
 
4586
4628
  /**
4587
- * 构造插件 `activator(hostApi)` 使用的宿主 API:路由、扩展点、资源与受控请求桥。
4629
+ * 构造插件 `activator(hostApi)` 使用的宿主 API
4588
4630
  */
4589
4631
  let slotItemKeySeq = 0;
4590
4632
  let routeSynthSeq = 0;
4633
+ function getBridgePrefixes(hostKitOptions) {
4634
+ return Array.isArray(hostKitOptions.bridgeAllowedPathPrefixes) &&
4635
+ hostKitOptions.bridgeAllowedPathPrefixes.length > 0
4636
+ ? hostKitOptions.bridgeAllowedPathPrefixes
4637
+ : defaultWebExtendPluginRuntime.bridgeAllowedPathPrefixes;
4638
+ }
4639
+ function resolveHostRuntime(hostKitOptions) {
4640
+ const hostContext = hostKitOptions.hostContext != null && typeof hostKitOptions.hostContext === 'object'
4641
+ ? hostKitOptions.hostContext
4642
+ : Object.freeze({});
4643
+ const hostVue = hostContext.Vue;
4644
+ return {
4645
+ hostContext,
4646
+ VueRuntime: hostVue || Vue__default.default
4647
+ };
4648
+ }
4649
+ function normalizeParentRouteName(hostKitOptions) {
4650
+ return typeof hostKitOptions.pluginRoutesParentName === 'string'
4651
+ ? hostKitOptions.pluginRoutesParentName.trim()
4652
+ : '';
4653
+ }
4654
+ function normalizeUrls(urls) {
4655
+ return Array.isArray(urls)
4656
+ ? urls
4657
+ .filter((url) => typeof url === 'string')
4658
+ .map((url) => url.trim())
4659
+ .filter(Boolean)
4660
+ : [];
4661
+ }
4591
4662
  function decorateRouteTreeWithPluginMeta(pluginId, route) {
4592
4663
  const meta = route.meta && typeof route.meta === 'object' && !Array.isArray(route.meta)
4593
4664
  ? route.meta
@@ -4613,97 +4684,81 @@ function decorateRouteTreeWithPluginMeta(pluginId, route) {
4613
4684
  function analyzeRouteInputTree(nodes) {
4614
4685
  let hasDecl = false;
4615
4686
  let hasCfg = false;
4616
- function walk(r) {
4617
- if (!r || typeof r !== 'object') {
4687
+ function walk(node) {
4688
+ if (!node || typeof node !== 'object') {
4618
4689
  return;
4619
4690
  }
4620
- const o = r;
4621
- const cfg = o.component != null || o.components != null;
4622
- const decl = typeof o.componentRef === 'string';
4623
- if (cfg) {
4691
+ const record = node;
4692
+ const hasRouteConfig = record.component != null || record.components != null;
4693
+ const hasRouteDecl = typeof record.componentRef === 'string';
4694
+ if (hasRouteConfig) {
4624
4695
  hasCfg = true;
4625
4696
  }
4626
- else if (decl) {
4697
+ else if (hasRouteDecl) {
4627
4698
  hasDecl = true;
4628
4699
  }
4629
- const ch = o.children;
4630
- if (Array.isArray(ch)) {
4631
- for (const c of ch) {
4632
- walk(c);
4700
+ if (Array.isArray(record.children)) {
4701
+ for (const child of record.children) {
4702
+ walk(child);
4633
4703
  }
4634
4704
  }
4635
4705
  }
4636
- for (const n of nodes) {
4637
- walk(n);
4706
+ for (const node of nodes) {
4707
+ walk(node);
4638
4708
  }
4639
4709
  return { hasDecl, hasCfg };
4640
4710
  }
4641
- /**
4642
- * 单插件在宿主侧的 API 句柄。工厂请传 `(id, router, kit) => createHostApi(id, r, kit)` 以便 bridge 白名单等到位。
4643
- */
4711
+ function rollbackRegisteredTopRoutes(
4644
4712
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4645
- function createHostApi(pluginId, router, hostKitOptions = {}) {
4646
- const bridgePrefixes = Array.isArray(hostKitOptions.bridgeAllowedPathPrefixes) &&
4647
- hostKitOptions.bridgeAllowedPathPrefixes.length > 0
4648
- ? hostKitOptions.bridgeAllowedPathPrefixes
4649
- : defaultWebExtendPluginRuntime.bridgeAllowedPathPrefixes;
4650
- const bridge = createRequestBridge({ allowedPathPrefixes: bridgePrefixes });
4651
- const parentName = typeof hostKitOptions.pluginRoutesParentName === 'string'
4652
- ? hostKitOptions.pluginRoutesParentName.trim()
4653
- : '';
4654
- function rollbackRegisteredTopRoutes(routes) {
4655
- for (let i = routes.length - 1; i >= 0; i--) {
4656
- const route = routes[i];
4657
- if (typeof route.dispose === 'function') {
4658
- try {
4659
- route.dispose();
4660
- continue;
4661
- }
4662
- catch (e) {
4663
- console.warn('[wep] rollback route disposer failed', route.name, e);
4664
- }
4713
+ router, routes) {
4714
+ for (let i = routes.length - 1; i >= 0; i--) {
4715
+ const route = routes[i];
4716
+ if (typeof route.dispose === 'function') {
4717
+ try {
4718
+ route.dispose();
4719
+ continue;
4665
4720
  }
4666
- if (typeof router.removeRoute === 'function') {
4667
- try {
4668
- router.removeRoute(route.name);
4669
- }
4670
- catch (e) {
4671
- console.warn('[wep] rollback removeRoute failed', route.name, e);
4672
- }
4721
+ catch (e) {
4722
+ console.warn('[wep] rollback route disposer failed', route.name, e);
4723
+ }
4724
+ }
4725
+ if (typeof router.removeRoute === 'function') {
4726
+ try {
4727
+ router.removeRoute(route.name);
4728
+ }
4729
+ catch (e) {
4730
+ console.warn('[wep] rollback removeRoute failed', route.name, e);
4673
4731
  }
4674
4732
  }
4675
4733
  }
4676
- function applyInternalRegister(rawRouteConfigs) {
4677
- const wrapped = rawRouteConfigs.map((r) => ({
4678
- ...decorateRouteTreeWithPluginMeta(pluginId, r),
4679
- name: r.name || `${routeSynthNamePrefix}${pluginId}_${routeSynthSeq++}`
4680
- }));
4734
+ }
4735
+ function decorateTopRoutes(pluginId, rawRouteConfigs) {
4736
+ return rawRouteConfigs.map((route) => ({
4737
+ ...decorateRouteTreeWithPluginMeta(pluginId, route),
4738
+ name: route.name || `${routeSynthNamePrefix}${pluginId}_${routeSynthSeq++}`
4739
+ }));
4740
+ }
4741
+ function createRouteRegistrar({ pluginId, router, parentName, hostKitOptions }) {
4742
+ function addTopRoute(route) {
4743
+ const dispose = parentName ? router.addRoute(parentName, route) : router.addRoute(route);
4744
+ return {
4745
+ name: String(route.name),
4746
+ dispose: typeof dispose === 'function' ? dispose : undefined
4747
+ };
4748
+ }
4749
+ return function applyInternalRegister(rawRouteConfigs) {
4681
4750
  if (typeof router.addRoute !== 'function') {
4682
- throw new Error('[wep] vue-router 3.5+ 必需:请使用 router.addRoute(不再支持 addRoutes)');
4751
+ throw new Error('[wep] vue-router 3.5+ required: please use router.addRoute');
4683
4752
  }
4753
+ const wrapped = decorateTopRoutes(pluginId, rawRouteConfigs);
4684
4754
  const registeredTopRoutes = [];
4685
4755
  try {
4686
- if (parentName) {
4687
- for (const r of wrapped) {
4688
- const dispose = router.addRoute(parentName, r);
4689
- registeredTopRoutes.push({
4690
- name: String(r.name),
4691
- dispose: typeof dispose === 'function' ? dispose : undefined
4692
- });
4693
- }
4694
- }
4695
- else {
4696
- for (const r of wrapped) {
4697
- const dispose = router.addRoute(r);
4698
- registeredTopRoutes.push({
4699
- name: String(r.name),
4700
- dispose: typeof dispose === 'function' ? dispose : undefined
4701
- });
4702
- }
4756
+ for (const route of wrapped) {
4757
+ registeredTopRoutes.push(addTopRoute(route));
4703
4758
  }
4704
4759
  }
4705
4760
  catch (e) {
4706
- rollbackRegisteredTopRoutes(registeredTopRoutes);
4761
+ rollbackRegisteredTopRoutes(router, registeredTopRoutes);
4707
4762
  throw e;
4708
4763
  }
4709
4764
  recordPluginTopRoutes(pluginId, registeredTopRoutes);
@@ -4716,69 +4771,80 @@ function createHostApi(pluginId, router, hostKitOptions = {}) {
4716
4771
  contributedRoutes
4717
4772
  });
4718
4773
  }
4719
- }
4720
- function injectStylesheet(href) {
4721
- const link = document.createElement('link');
4722
- link.rel = 'stylesheet';
4723
- link.href = href;
4724
- link.setAttribute('data-plugin-asset', pluginId);
4725
- document.head.appendChild(link);
4726
- }
4727
- function injectScript(src) {
4728
- return new Promise((resolve, reject) => {
4729
- const s = document.createElement('script');
4730
- s.async = true;
4731
- s.src = src;
4732
- s.setAttribute('data-plugin-asset', pluginId);
4733
- s.onload = () => resolve();
4734
- s.onerror = () => reject(new Error('script failed: ' + src));
4735
- document.head.appendChild(s);
4774
+ };
4775
+ }
4776
+ function injectStylesheet(pluginId, href) {
4777
+ const link = document.createElement('link');
4778
+ link.rel = 'stylesheet';
4779
+ link.href = href;
4780
+ link.setAttribute('data-plugin-asset', pluginId);
4781
+ document.head.appendChild(link);
4782
+ }
4783
+ function injectScript(pluginId, src) {
4784
+ return new Promise((resolve, reject) => {
4785
+ const script = document.createElement('script');
4786
+ script.async = true;
4787
+ script.src = src;
4788
+ script.setAttribute('data-plugin-asset', pluginId);
4789
+ script.onload = () => resolve();
4790
+ script.onerror = () => reject(new Error('script failed: ' + src));
4791
+ document.head.appendChild(script);
4792
+ });
4793
+ }
4794
+ function resolveRouteConfigs(pluginId,
4795
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4796
+ router, hostKitOptions, routes) {
4797
+ const { hasDecl, hasCfg } = analyzeRouteInputTree(routes);
4798
+ if (hasDecl && hasCfg) {
4799
+ throw new Error('[wep] registerRoutes: cannot mix RouteDeclaration (componentRef) with RouteConfig (component)');
4800
+ }
4801
+ let configs;
4802
+ if (hasDecl) {
4803
+ const adapt = hostKitOptions.adaptRouteDeclarations;
4804
+ if (typeof adapt !== 'function') {
4805
+ throw new Error('[wep] registerRoutes: RouteDeclaration (componentRef) requires adaptRouteDeclarations on the host');
4806
+ }
4807
+ configs = adapt({
4808
+ pluginId,
4809
+ router,
4810
+ declarations: routes
4736
4811
  });
4737
4812
  }
4738
- const hostContext = hostKitOptions.hostContext != null && typeof hostKitOptions.hostContext === 'object'
4739
- ? hostKitOptions.hostContext
4740
- : Object.freeze({});
4741
- const hostVue = hostContext && hostContext.Vue;
4742
- const VueRuntime = hostVue || Vue__default.default;
4813
+ else {
4814
+ configs = routes;
4815
+ }
4816
+ return typeof hostKitOptions.transformRoutes === 'function'
4817
+ ? hostKitOptions.transformRoutes({
4818
+ pluginId,
4819
+ router,
4820
+ routes: configs
4821
+ })
4822
+ : configs;
4823
+ }
4824
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4825
+ function createHostApi(pluginId, router, hostKitOptions = {}) {
4826
+ const bridge = createRequestBridge({ allowedPathPrefixes: getBridgePrefixes(hostKitOptions) });
4827
+ const parentName = normalizeParentRouteName(hostKitOptions);
4828
+ const applyInternalRegister = createRouteRegistrar({
4829
+ pluginId,
4830
+ router,
4831
+ parentName,
4832
+ hostKitOptions
4833
+ });
4834
+ const { hostContext, VueRuntime } = resolveHostRuntime(hostKitOptions);
4743
4835
  ensureRegistriesReactive(VueRuntime);
4744
4836
  registerPluginTeardown(pluginId, () => {
4745
4837
  clearContributedRoutesForPlugin(pluginId);
4746
4838
  });
4747
4839
  return {
4748
4840
  hostPluginApiVersion: HOST_PLUGIN_API_VERSION,
4749
- /** 宿主注入的只读依赖(store、router、开放能力等),见 `resolveRuntimeOptions.hostContext` */
4750
4841
  hostContext,
4751
4842
  registerRoutes(routes) {
4752
4843
  const list = Array.isArray(routes) ? routes : [];
4753
4844
  if (list.length === 0) {
4754
4845
  return;
4755
4846
  }
4756
- const { hasDecl, hasCfg } = analyzeRouteInputTree(list);
4757
- if (hasDecl && hasCfg) {
4758
- throw new Error('[wep] registerRoutes: cannot mix RouteDeclaration (componentRef) with RouteConfig (component)');
4759
- }
4760
- let configs;
4761
- if (hasDecl) {
4762
- const adapt = hostKitOptions.adaptRouteDeclarations;
4763
- if (typeof adapt !== 'function') {
4764
- throw new Error('[wep] registerRoutes: RouteDeclaration (componentRef) requires adaptRouteDeclarations on the host');
4765
- }
4766
- configs = adapt({
4767
- pluginId,
4768
- router,
4769
- declarations: list
4770
- });
4771
- }
4772
- else {
4773
- configs = list;
4774
- }
4775
- if (typeof hostKitOptions.transformRoutes === 'function') {
4776
- configs = hostKitOptions.transformRoutes({
4777
- pluginId,
4778
- router,
4779
- routes: configs
4780
- });
4781
- }
4847
+ const configs = resolveRouteConfigs(pluginId, router, hostKitOptions, list);
4782
4848
  if (typeof hostKitOptions.interceptRegisterRoutes === 'function') {
4783
4849
  hostKitOptions.interceptRegisterRoutes({
4784
4850
  pluginId,
@@ -4799,11 +4865,11 @@ function createHostApi(pluginId, router, hostKitOptions = {}) {
4799
4865
  VueRuntime.set(registries.slots, pointId, []);
4800
4866
  }
4801
4867
  const list = registries.slots[pointId];
4802
- for (const c of components) {
4868
+ for (const componentEntry of components) {
4803
4869
  list.push({
4804
4870
  pluginId,
4805
- component: c.component,
4806
- priority: c.priority != null ? c.priority : 0,
4871
+ component: componentEntry.component,
4872
+ priority: componentEntry.priority != null ? componentEntry.priority : 0,
4807
4873
  key: `${pluginId}-${pointId}-${++slotItemKeySeq}`
4808
4874
  });
4809
4875
  }
@@ -4811,14 +4877,12 @@ function createHostApi(pluginId, router, hostKitOptions = {}) {
4811
4877
  registries.slotRevision++;
4812
4878
  },
4813
4879
  registerStylesheetUrls(urls) {
4814
- for (const u of urls || []) {
4815
- if (typeof u === 'string' && u) {
4816
- injectStylesheet(u);
4817
- }
4880
+ for (const url of normalizeUrls(urls)) {
4881
+ injectStylesheet(pluginId, url);
4818
4882
  }
4819
4883
  },
4820
4884
  registerScriptUrls(urls) {
4821
- const chain = (urls || []).filter((u) => typeof u === 'string' && u).reduce((p, u) => p.then(() => injectScript(u)), Promise.resolve());
4885
+ const chain = normalizeUrls(urls).reduce((promise, url) => promise.then(() => injectScript(pluginId, url)), Promise.resolve());
4822
4886
  chain.catch((e) => console.warn('[wep] registerScriptUrls', pluginId, e));
4823
4887
  },
4824
4888
  registerSanitizedHtmlSnippet() {
@@ -4891,14 +4955,54 @@ function createExtensionPointComponent(VueLike = Vue__default.default) {
4891
4955
  }
4892
4956
  var ExtensionPoint = createExtensionPointComponent();
4893
4957
 
4958
+ function isRecord(input) {
4959
+ return !!input && typeof input === 'object' && !Array.isArray(input);
4960
+ }
4961
+ function normalizeComponent(entry) {
4962
+ if (isRecord(entry) && 'component' in entry) {
4963
+ return entry.component;
4964
+ }
4965
+ return entry;
4966
+ }
4967
+ function toComponentAlias(name) {
4968
+ return name
4969
+ .trim()
4970
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
4971
+ .replace(/[^a-zA-Z0-9]+/g, '-')
4972
+ .replace(/^-+|-+$/g, '')
4973
+ .toLowerCase();
4974
+ }
4975
+ function installHostBridge(
4976
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4977
+ VueRuntime, options = {}) {
4978
+ if (!VueRuntime || typeof VueRuntime.component !== 'function' || !VueRuntime.prototype) {
4979
+ throw new Error('[wep] installHostBridge requires a Vue 2 runtime constructor');
4980
+ }
4981
+ const modules = options.modules && isRecord(options.modules) ? Object.freeze({ ...options.modules }) : Object.freeze({});
4982
+ VueRuntime.prototype.$host = modules;
4983
+ const componentEntries = options.components && isRecord(options.components) ? Object.entries(options.components) : [];
4984
+ for (const [rawName, rawEntry] of componentEntries) {
4985
+ const alias = toComponentAlias(String(rawName));
4986
+ const component = normalizeComponent(rawEntry);
4987
+ if (!alias || component == null) {
4988
+ continue;
4989
+ }
4990
+ VueRuntime.component(alias, component);
4991
+ }
4992
+ return modules;
4993
+ }
4994
+
4894
4995
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4895
4996
  function installWebExtendPluginVue2(Vue, router, options) {
4997
+ const runtime = resolveRuntimeOptions$1(options);
4896
4998
  if (Vue) {
4897
4999
  ensureRegistriesReactive(Vue);
4898
5000
  Vue.component('ExtensionPoint', createExtensionPointComponent(Vue));
5001
+ if (runtime.hostBridge && typeof runtime.hostBridge === 'object') {
5002
+ installHostBridge(Vue, runtime.hostBridge);
5003
+ }
4899
5004
  }
4900
- const runtime = resolveRuntimeOptions$1(options || {});
4901
- return bootstrapPlugins$1(router, (id, r, kit) => createHostApi(id, r, kit || {}), runtime);
5005
+ return bootstrapPlugins$1(router, createHostApi, runtime);
4902
5006
  }
4903
5007
 
4904
5008
  function resolveManifestPathUnderApiBase(manifestUrl, apiBase) {
@@ -4924,17 +5028,22 @@ function bridgePrefixesFromVueCliEnv() {
4924
5028
  const raw = [base ? `${base}/` : '', '/api/', '/dev-api/'].filter(Boolean);
4925
5029
  return [...new Set(raw)];
4926
5030
  }
5031
+ function asRecord(value) {
5032
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
5033
+ }
4927
5034
  function createVueCliAxiosInstallOptions(deps, extra = {}) {
4928
5035
  const { request } = deps;
4929
5036
  if (typeof request !== 'function') {
4930
5037
  throw new Error('[wep] createVueCliAxiosInstallOptions requires deps.request');
4931
5038
  }
4932
- const { fetchManifest: userFetchManifest, manifestMode: extraManifestMode, staticManifestUrl: extraStaticManifestUrl, ...restExtra } = extra;
5039
+ const manifest = asRecord(extra.manifest) || {};
5040
+ const host = asRecord(extra.host) || {};
5041
+ const mergedHost = { ...host };
4933
5042
  const envBase = (typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API
4934
5043
  ? String(process.env.VUE_APP_BASE_API)
4935
5044
  : '').replace(/\/$/, '');
4936
- const userBase = extra.manifestBase !== undefined && String(extra.manifestBase).trim() !== ''
4937
- ? String(extra.manifestBase).replace(/\/$/, '')
5045
+ const userBase = manifest.baseUrl !== undefined && String(manifest.baseUrl).trim() !== ''
5046
+ ? String(manifest.baseUrl).replace(/\/$/, '')
4938
5047
  : '';
4939
5048
  const stripBase = userBase || envBase;
4940
5049
  const fetchManifestApi = async (ctx) => {
@@ -4945,11 +5054,7 @@ function createVueCliAxiosInstallOptions(deps, extra = {}) {
4945
5054
  });
4946
5055
  const data = unwrapNestedManifestBody(body);
4947
5056
  if (!data || typeof data !== 'object') {
4948
- return {
4949
- ok: false,
4950
- error: new Error('[wep] invalid manifest response'),
4951
- data: null
4952
- };
5057
+ return { ok: false, error: new Error('[wep] invalid manifest response'), data: null };
4953
5058
  }
4954
5059
  return { ok: true, data };
4955
5060
  }
@@ -4957,28 +5062,33 @@ function createVueCliAxiosInstallOptions(deps, extra = {}) {
4957
5062
  return { ok: false, error, data: null };
4958
5063
  }
4959
5064
  };
4960
- const manifestMode = resolveManifestModeFromInputs(extraManifestMode);
4961
- const staticManifestUrl = resolveStaticManifestUrlFromInputs(extraStaticManifestUrl);
4962
- const fetchManifest = typeof userFetchManifest === 'function'
4963
- ? userFetchManifest
4964
- : manifestMode === 'static'
5065
+ const manifestSource = resolveManifestModeFromInputs(manifest.source);
5066
+ const staticUrl = resolveStaticManifestUrlFromInputs(manifest.staticUrl);
5067
+ const fetchManifest = typeof manifest.fetch === 'function'
5068
+ ? manifest.fetch
5069
+ : manifestSource === 'static'
4965
5070
  ? fetchStaticManifestViaHttp
4966
5071
  : fetchManifestApi;
4967
- const options = {
4968
- manifestBase: stripBase || undefined,
4969
- bridgeAllowedPathPrefixes: bridgePrefixesFromVueCliEnv(),
4970
- manifestMode,
4971
- staticManifestUrl,
4972
- ...restExtra,
4973
- fetchManifest
4974
- };
4975
5072
  const listPath = typeof process !== 'undefined' &&
4976
5073
  process.env &&
4977
- process.env[webExtendPluginEnvKeys.manifestPathAlt];
4978
- if (listPath && options.manifestListPath === undefined && extra.manifestListPath === undefined) {
4979
- options.manifestListPath = String(process.env[webExtendPluginEnvKeys.manifestPathAlt]);
5074
+ process.env[webExtendPluginEnvKeys.manifestPathAlt]
5075
+ ? String(process.env[webExtendPluginEnvKeys.manifestPathAlt])
5076
+ : undefined;
5077
+ if (mergedHost.requestPathPrefixes === undefined) {
5078
+ mergedHost.requestPathPrefixes = bridgePrefixesFromVueCliEnv();
4980
5079
  }
4981
- return options;
5080
+ return {
5081
+ ...extra,
5082
+ manifest: {
5083
+ ...manifest,
5084
+ baseUrl: stripBase || undefined,
5085
+ listPath: manifest.listPath !== undefined ? manifest.listPath : listPath,
5086
+ source: manifestSource,
5087
+ staticUrl,
5088
+ fetch: fetchManifest
5089
+ },
5090
+ host: mergedHost
5091
+ };
4982
5092
  }
4983
5093
 
4984
5094
  const { bootstrapPlugins, defaultFetchWebPluginManifest, resolveRuntimeOptions, ensurePluginHostRoute, getActivatedPluginIds } = pluginRuntime;
@@ -5007,6 +5117,7 @@ exports.getHostComponentMeta = getHostComponentMeta;
5007
5117
  exports.getHostModule = getHostModule;
5008
5118
  exports.getHostModuleMeta = getHostModuleMeta;
5009
5119
  exports.getRegisteredTopRouteNamesForPlugin = getRegisteredTopRouteNamesForPlugin;
5120
+ exports.installHostBridge = installHostBridge;
5010
5121
  exports.installWebExtendPluginVue2 = installWebExtendPluginVue2;
5011
5122
  exports.manifestFetchCacheMiddleware = manifestFetchCacheMiddleware;
5012
5123
  exports.peerMinimumVersions = peerMinimumVersions;