web-extend-plugin-vue2 0.3.6 → 0.3.8

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
@@ -45,8 +45,8 @@ const defaultManifestFetchCache = {
45
45
  };
46
46
  const routeSynthNamePrefix = '__wep_';
47
47
  const defaultWebExtendPluginRuntime = {
48
- manifestBase: '/fp-api',
49
- manifestListPath: '/api/frontend-plugins',
48
+ manifestBase: '/dev-api',
49
+ manifestListPath: '/web-plugin',
50
50
  manifestFetchCredentials: 'include',
51
51
  devPingPath: '/__web_plugin_dev_ping',
52
52
  devReloadSsePath: '/__web_plugin_reload_stream',
@@ -56,7 +56,7 @@ const defaultWebExtendPluginRuntime = {
56
56
  allowedScriptHosts: ['localhost', '127.0.0.1', '::1'],
57
57
  bridgeAllowedPathPrefixes: ['/api/'],
58
58
  pluginMountPath: '/plugin',
59
- devFallbackStaticManifestUrl: '/web-plugins/plugins.manifest.json'
59
+ devFallbackStaticManifestUrl: ''
60
60
  };
61
61
 
62
62
  /**
@@ -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 false;
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;
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);
336
393
  }
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;
349
- }
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),
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) {
3499
+ const origin = normalizeStringValue(opts.webPluginDevOrigin);
3500
+ if (!origin || !isScriptHostAllowed(`${origin}/`, hostSet)) {
3459
3501
  return {};
3460
3502
  }
3461
- if (!isScriptHostAllowed(`${origin}/`, hostSet)) {
3462
- return {};
3463
- }
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,73 @@ 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
+ }
4165
+ function isResolvedRuntimeOptions(input) {
4166
+ return !!(input &&
4167
+ typeof input === 'object' &&
4168
+ !Array.isArray(input) &&
4169
+ ('manifestBase' in input ||
4170
+ 'manifestListPath' in input ||
4171
+ 'fetchManifest' in input));
4172
+ }
4078
4173
  async function bootstrapPlugins$1(
4079
4174
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4080
4175
  router,
@@ -4086,26 +4181,17 @@ createHostApiFactory, runtimeOptions) {
4086
4181
  }
4087
4182
  printRuntimeBannerOnce();
4088
4183
  clearActivatedPluginIds();
4089
- const opts = resolveRuntimeOptions$1(runtimeOptions || {});
4184
+ const opts = isResolvedRuntimeOptions(runtimeOptions) ? runtimeOptions : resolveRuntimeOptions$1(runtimeOptions);
4185
+ const showBootstrapSummary = shouldShowBootstrapSummary(opts);
4090
4186
  setPluginBootstrapRouter(router);
4091
4187
  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}`;
4188
+ const manifestRequest = resolveManifestRequest(opts);
4189
+ if (!manifestRequest) {
4190
+ console.warn('[wep] manifestMode=static requires non-empty staticManifestUrl (or env VITE_WEB_PLUGIN_STATIC_MANIFEST_URL)');
4191
+ logBootstrapSummary(showBootstrapSummary, { ok: false, reason: 'static_manifest_url_missing' });
4192
+ return;
4108
4193
  }
4194
+ const { isStatic, manifestUrl } = manifestRequest;
4109
4195
  const hostSet = buildAllowedScriptHostsSet(opts.allowedScriptHosts);
4110
4196
  const explicit = parseWebPluginDevMapExplicit(opts);
4111
4197
  const manifestCtx = {
@@ -4113,27 +4199,15 @@ createHostApiFactory, runtimeOptions) {
4113
4199
  credentials: opts.manifestFetchCredentials
4114
4200
  };
4115
4201
  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
- })(),
4202
+ fetchManifestSafely(typeof opts.fetchManifest === 'function'
4203
+ ? opts.fetchManifest
4204
+ : undefined, manifestCtx),
4127
4205
  buildImplicitWebPluginDevMap(opts, hostSet)
4128
4206
  ]);
4129
4207
  let manifestResult = primaryResult;
4130
4208
  let manifestUrlUsed = manifestUrl;
4131
4209
  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;
4210
+ const needFallback = !primaryResult.ok || getManifestPluginCount(primaryResult) === 0;
4137
4211
  const fallbackRaw = String(opts.devFallbackStaticManifestUrl || '').trim();
4138
4212
  if (needFallback && fallbackRaw) {
4139
4213
  const fallbackUrl = resolveStaticManifestUrlForFetch(fallbackRaw, window.location.origin);
@@ -4142,8 +4216,7 @@ createHostApiFactory, runtimeOptions) {
4142
4216
  credentials: opts.manifestFetchCredentials
4143
4217
  };
4144
4218
  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;
4219
+ const flen = getManifestPluginCount(fr);
4147
4220
  if (fr.ok && flen > 0) {
4148
4221
  manifestResult = fr;
4149
4222
  manifestUrlUsed = fallbackUrl;
@@ -4153,22 +4226,7 @@ createHostApiFactory, runtimeOptions) {
4153
4226
  }
4154
4227
  const devMap = mergeDevMaps(implicit, explicit);
4155
4228
  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
- };
4229
+ const hostKit = buildHostKit(opts);
4172
4230
  if (!manifestResult.ok) {
4173
4231
  if (manifestResult.error) {
4174
4232
  console.warn('[wep] fetch manifest failed', manifestResult.error);
@@ -4177,16 +4235,12 @@ createHostApiFactory, runtimeOptions) {
4177
4235
  const label = isStatic ? 'static manifest' : 'manifest HTTP';
4178
4236
  console.warn(`[wep] ${label}`, manifestResult.status, manifestUrlUsed);
4179
4237
  }
4180
- if (shouldShowBootstrapSummary(opts)) {
4181
- console.info('[wep] bootstrap_summary', { ok: false, reason: 'manifest_fetch' });
4182
- }
4238
+ logBootstrapSummary(showBootstrapSummary, { ok: false, reason: 'manifest_fetch' });
4183
4239
  return;
4184
4240
  }
4185
- const data = manifestResult.data;
4241
+ const data = getManifestBody(manifestResult);
4186
4242
  if (!data) {
4187
- if (shouldShowBootstrapSummary(opts)) {
4188
- console.info('[wep] bootstrap_summary', { ok: false, reason: 'manifest_empty_body' });
4189
- }
4243
+ logBootstrapSummary(showBootstrapSummary, { ok: false, reason: 'manifest_empty_body' });
4190
4244
  return;
4191
4245
  }
4192
4246
  const apiVer = data.hostPluginApiVersion;
@@ -4199,12 +4253,10 @@ createHostApiFactory, runtimeOptions) {
4199
4253
  host: HOST_PLUGIN_API_VERSION,
4200
4254
  manifest: apiVer
4201
4255
  });
4202
- if (shouldShowBootstrapSummary(opts)) {
4203
- console.info('[wep] bootstrap_summary', {
4204
- ok: false,
4205
- reason: 'manifest_host_api_version_mismatch'
4206
- });
4207
- }
4256
+ logBootstrapSummary(showBootstrapSummary, {
4257
+ ok: false,
4258
+ reason: 'manifest_host_api_version_mismatch'
4259
+ });
4208
4260
  return;
4209
4261
  }
4210
4262
  }
@@ -4304,9 +4356,7 @@ createHostApiFactory, runtimeOptions) {
4304
4356
  }
4305
4357
  }
4306
4358
  }
4307
- if (shouldShowBootstrapSummary(opts)) {
4308
- console.info('[wep] bootstrap_summary', { ok: true, ...summary });
4309
- }
4359
+ logBootstrapSummary(showBootstrapSummary, { ok: true, ...summary });
4310
4360
  }
4311
4361
 
4312
4362
  /**
@@ -4584,10 +4634,39 @@ function clearContributedRoutesForPlugin(pluginId) {
4584
4634
  }
4585
4635
 
4586
4636
  /**
4587
- * 构造插件 `activator(hostApi)` 使用的宿主 API:路由、扩展点、资源与受控请求桥。
4637
+ * 构造插件 `activator(hostApi)` 使用的宿主 API
4588
4638
  */
4589
4639
  let slotItemKeySeq = 0;
4590
4640
  let routeSynthSeq = 0;
4641
+ function getBridgePrefixes(hostKitOptions) {
4642
+ return Array.isArray(hostKitOptions.bridgeAllowedPathPrefixes) &&
4643
+ hostKitOptions.bridgeAllowedPathPrefixes.length > 0
4644
+ ? hostKitOptions.bridgeAllowedPathPrefixes
4645
+ : defaultWebExtendPluginRuntime.bridgeAllowedPathPrefixes;
4646
+ }
4647
+ function resolveHostRuntime(hostKitOptions) {
4648
+ const hostContext = hostKitOptions.hostContext != null && typeof hostKitOptions.hostContext === 'object'
4649
+ ? hostKitOptions.hostContext
4650
+ : Object.freeze({});
4651
+ const hostVue = hostContext.Vue;
4652
+ return {
4653
+ hostContext,
4654
+ VueRuntime: hostVue || Vue__default.default
4655
+ };
4656
+ }
4657
+ function normalizeParentRouteName(hostKitOptions) {
4658
+ return typeof hostKitOptions.pluginRoutesParentName === 'string'
4659
+ ? hostKitOptions.pluginRoutesParentName.trim()
4660
+ : '';
4661
+ }
4662
+ function normalizeUrls(urls) {
4663
+ return Array.isArray(urls)
4664
+ ? urls
4665
+ .filter((url) => typeof url === 'string')
4666
+ .map((url) => url.trim())
4667
+ .filter(Boolean)
4668
+ : [];
4669
+ }
4591
4670
  function decorateRouteTreeWithPluginMeta(pluginId, route) {
4592
4671
  const meta = route.meta && typeof route.meta === 'object' && !Array.isArray(route.meta)
4593
4672
  ? route.meta
@@ -4613,97 +4692,81 @@ function decorateRouteTreeWithPluginMeta(pluginId, route) {
4613
4692
  function analyzeRouteInputTree(nodes) {
4614
4693
  let hasDecl = false;
4615
4694
  let hasCfg = false;
4616
- function walk(r) {
4617
- if (!r || typeof r !== 'object') {
4695
+ function walk(node) {
4696
+ if (!node || typeof node !== 'object') {
4618
4697
  return;
4619
4698
  }
4620
- const o = r;
4621
- const cfg = o.component != null || o.components != null;
4622
- const decl = typeof o.componentRef === 'string';
4623
- if (cfg) {
4699
+ const record = node;
4700
+ const hasRouteConfig = record.component != null || record.components != null;
4701
+ const hasRouteDecl = typeof record.componentRef === 'string';
4702
+ if (hasRouteConfig) {
4624
4703
  hasCfg = true;
4625
4704
  }
4626
- else if (decl) {
4705
+ else if (hasRouteDecl) {
4627
4706
  hasDecl = true;
4628
4707
  }
4629
- const ch = o.children;
4630
- if (Array.isArray(ch)) {
4631
- for (const c of ch) {
4632
- walk(c);
4708
+ if (Array.isArray(record.children)) {
4709
+ for (const child of record.children) {
4710
+ walk(child);
4633
4711
  }
4634
4712
  }
4635
4713
  }
4636
- for (const n of nodes) {
4637
- walk(n);
4714
+ for (const node of nodes) {
4715
+ walk(node);
4638
4716
  }
4639
4717
  return { hasDecl, hasCfg };
4640
4718
  }
4641
- /**
4642
- * 单插件在宿主侧的 API 句柄。工厂请传 `(id, router, kit) => createHostApi(id, r, kit)` 以便 bridge 白名单等到位。
4643
- */
4719
+ function rollbackRegisteredTopRoutes(
4644
4720
  // 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
- }
4721
+ router, routes) {
4722
+ for (let i = routes.length - 1; i >= 0; i--) {
4723
+ const route = routes[i];
4724
+ if (typeof route.dispose === 'function') {
4725
+ try {
4726
+ route.dispose();
4727
+ continue;
4665
4728
  }
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
- }
4729
+ catch (e) {
4730
+ console.warn('[wep] rollback route disposer failed', route.name, e);
4731
+ }
4732
+ }
4733
+ if (typeof router.removeRoute === 'function') {
4734
+ try {
4735
+ router.removeRoute(route.name);
4736
+ }
4737
+ catch (e) {
4738
+ console.warn('[wep] rollback removeRoute failed', route.name, e);
4673
4739
  }
4674
4740
  }
4675
4741
  }
4676
- function applyInternalRegister(rawRouteConfigs) {
4677
- const wrapped = rawRouteConfigs.map((r) => ({
4678
- ...decorateRouteTreeWithPluginMeta(pluginId, r),
4679
- name: r.name || `${routeSynthNamePrefix}${pluginId}_${routeSynthSeq++}`
4680
- }));
4742
+ }
4743
+ function decorateTopRoutes(pluginId, rawRouteConfigs) {
4744
+ return rawRouteConfigs.map((route) => ({
4745
+ ...decorateRouteTreeWithPluginMeta(pluginId, route),
4746
+ name: route.name || `${routeSynthNamePrefix}${pluginId}_${routeSynthSeq++}`
4747
+ }));
4748
+ }
4749
+ function createRouteRegistrar({ pluginId, router, parentName, hostKitOptions }) {
4750
+ function addTopRoute(route) {
4751
+ const dispose = parentName ? router.addRoute(parentName, route) : router.addRoute(route);
4752
+ return {
4753
+ name: String(route.name),
4754
+ dispose: typeof dispose === 'function' ? dispose : undefined
4755
+ };
4756
+ }
4757
+ return function applyInternalRegister(rawRouteConfigs) {
4681
4758
  if (typeof router.addRoute !== 'function') {
4682
- throw new Error('[wep] vue-router 3.5+ 必需:请使用 router.addRoute(不再支持 addRoutes)');
4759
+ throw new Error('[wep] vue-router 3.5+ required: please use router.addRoute');
4683
4760
  }
4761
+ const wrapped = decorateTopRoutes(pluginId, rawRouteConfigs);
4684
4762
  const registeredTopRoutes = [];
4685
4763
  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
- }
4764
+ for (const route of wrapped) {
4765
+ registeredTopRoutes.push(addTopRoute(route));
4703
4766
  }
4704
4767
  }
4705
4768
  catch (e) {
4706
- rollbackRegisteredTopRoutes(registeredTopRoutes);
4769
+ rollbackRegisteredTopRoutes(router, registeredTopRoutes);
4707
4770
  throw e;
4708
4771
  }
4709
4772
  recordPluginTopRoutes(pluginId, registeredTopRoutes);
@@ -4716,69 +4779,80 @@ function createHostApi(pluginId, router, hostKitOptions = {}) {
4716
4779
  contributedRoutes
4717
4780
  });
4718
4781
  }
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);
4782
+ };
4783
+ }
4784
+ function injectStylesheet(pluginId, href) {
4785
+ const link = document.createElement('link');
4786
+ link.rel = 'stylesheet';
4787
+ link.href = href;
4788
+ link.setAttribute('data-plugin-asset', pluginId);
4789
+ document.head.appendChild(link);
4790
+ }
4791
+ function injectScript(pluginId, src) {
4792
+ return new Promise((resolve, reject) => {
4793
+ const script = document.createElement('script');
4794
+ script.async = true;
4795
+ script.src = src;
4796
+ script.setAttribute('data-plugin-asset', pluginId);
4797
+ script.onload = () => resolve();
4798
+ script.onerror = () => reject(new Error('script failed: ' + src));
4799
+ document.head.appendChild(script);
4800
+ });
4801
+ }
4802
+ function resolveRouteConfigs(pluginId,
4803
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4804
+ router, hostKitOptions, routes) {
4805
+ const { hasDecl, hasCfg } = analyzeRouteInputTree(routes);
4806
+ if (hasDecl && hasCfg) {
4807
+ throw new Error('[wep] registerRoutes: cannot mix RouteDeclaration (componentRef) with RouteConfig (component)');
4808
+ }
4809
+ let configs;
4810
+ if (hasDecl) {
4811
+ const adapt = hostKitOptions.adaptRouteDeclarations;
4812
+ if (typeof adapt !== 'function') {
4813
+ throw new Error('[wep] registerRoutes: RouteDeclaration (componentRef) requires adaptRouteDeclarations on the host');
4814
+ }
4815
+ configs = adapt({
4816
+ pluginId,
4817
+ router,
4818
+ declarations: routes
4736
4819
  });
4737
4820
  }
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;
4821
+ else {
4822
+ configs = routes;
4823
+ }
4824
+ return typeof hostKitOptions.transformRoutes === 'function'
4825
+ ? hostKitOptions.transformRoutes({
4826
+ pluginId,
4827
+ router,
4828
+ routes: configs
4829
+ })
4830
+ : configs;
4831
+ }
4832
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4833
+ function createHostApi(pluginId, router, hostKitOptions = {}) {
4834
+ const bridge = createRequestBridge({ allowedPathPrefixes: getBridgePrefixes(hostKitOptions) });
4835
+ const parentName = normalizeParentRouteName(hostKitOptions);
4836
+ const applyInternalRegister = createRouteRegistrar({
4837
+ pluginId,
4838
+ router,
4839
+ parentName,
4840
+ hostKitOptions
4841
+ });
4842
+ const { hostContext, VueRuntime } = resolveHostRuntime(hostKitOptions);
4743
4843
  ensureRegistriesReactive(VueRuntime);
4744
4844
  registerPluginTeardown(pluginId, () => {
4745
4845
  clearContributedRoutesForPlugin(pluginId);
4746
4846
  });
4747
4847
  return {
4748
4848
  hostPluginApiVersion: HOST_PLUGIN_API_VERSION,
4749
- /** 宿主注入的只读依赖(store、router、开放能力等),见 `resolveRuntimeOptions.hostContext` */
4750
4849
  hostContext,
4751
4850
  registerRoutes(routes) {
4752
4851
  const list = Array.isArray(routes) ? routes : [];
4753
4852
  if (list.length === 0) {
4754
4853
  return;
4755
4854
  }
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
- }
4855
+ const configs = resolveRouteConfigs(pluginId, router, hostKitOptions, list);
4782
4856
  if (typeof hostKitOptions.interceptRegisterRoutes === 'function') {
4783
4857
  hostKitOptions.interceptRegisterRoutes({
4784
4858
  pluginId,
@@ -4799,11 +4873,11 @@ function createHostApi(pluginId, router, hostKitOptions = {}) {
4799
4873
  VueRuntime.set(registries.slots, pointId, []);
4800
4874
  }
4801
4875
  const list = registries.slots[pointId];
4802
- for (const c of components) {
4876
+ for (const componentEntry of components) {
4803
4877
  list.push({
4804
4878
  pluginId,
4805
- component: c.component,
4806
- priority: c.priority != null ? c.priority : 0,
4879
+ component: componentEntry.component,
4880
+ priority: componentEntry.priority != null ? componentEntry.priority : 0,
4807
4881
  key: `${pluginId}-${pointId}-${++slotItemKeySeq}`
4808
4882
  });
4809
4883
  }
@@ -4811,14 +4885,12 @@ function createHostApi(pluginId, router, hostKitOptions = {}) {
4811
4885
  registries.slotRevision++;
4812
4886
  },
4813
4887
  registerStylesheetUrls(urls) {
4814
- for (const u of urls || []) {
4815
- if (typeof u === 'string' && u) {
4816
- injectStylesheet(u);
4817
- }
4888
+ for (const url of normalizeUrls(urls)) {
4889
+ injectStylesheet(pluginId, url);
4818
4890
  }
4819
4891
  },
4820
4892
  registerScriptUrls(urls) {
4821
- const chain = (urls || []).filter((u) => typeof u === 'string' && u).reduce((p, u) => p.then(() => injectScript(u)), Promise.resolve());
4893
+ const chain = normalizeUrls(urls).reduce((promise, url) => promise.then(() => injectScript(pluginId, url)), Promise.resolve());
4822
4894
  chain.catch((e) => console.warn('[wep] registerScriptUrls', pluginId, e));
4823
4895
  },
4824
4896
  registerSanitizedHtmlSnippet() {
@@ -4891,16 +4963,6 @@ function createExtensionPointComponent(VueLike = Vue__default.default) {
4891
4963
  }
4892
4964
  var ExtensionPoint = createExtensionPointComponent();
4893
4965
 
4894
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4895
- function installWebExtendPluginVue2(Vue, router, options) {
4896
- if (Vue) {
4897
- ensureRegistriesReactive(Vue);
4898
- Vue.component('ExtensionPoint', createExtensionPointComponent(Vue));
4899
- }
4900
- const runtime = resolveRuntimeOptions$1(options || {});
4901
- return bootstrapPlugins$1(router, (id, r, kit) => createHostApi(id, r, kit || {}), runtime);
4902
- }
4903
-
4904
4966
  function isRecord(input) {
4905
4967
  return !!input && typeof input === 'object' && !Array.isArray(input);
4906
4968
  }
@@ -4938,22 +5000,19 @@ VueRuntime, options = {}) {
4938
5000
  return modules;
4939
5001
  }
4940
5002
 
4941
- function resolveManifestPathUnderApiBase(manifestUrl, apiBase) {
4942
- const base = String(apiBase !== undefined
4943
- ? apiBase
4944
- : typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API
4945
- ? String(process.env.VUE_APP_BASE_API)
4946
- : '').replace(/\/$/, '');
4947
- if (typeof window === 'undefined') {
4948
- return '/api/frontend-plugins';
4949
- }
4950
- const url = new URL(manifestUrl, window.location.origin);
4951
- let path = url.pathname + url.search;
4952
- if (base && path.startsWith(base)) {
4953
- path = path.slice(base.length) || '/';
5003
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5004
+ function installWebExtendPluginVue2(Vue, router, options) {
5005
+ const runtime = resolveRuntimeOptions$1(options);
5006
+ if (Vue) {
5007
+ ensureRegistriesReactive(Vue);
5008
+ Vue.component('ExtensionPoint', createExtensionPointComponent(Vue));
5009
+ if (runtime.hostBridge && typeof runtime.hostBridge === 'object') {
5010
+ installHostBridge(Vue, runtime.hostBridge);
5011
+ }
4954
5012
  }
4955
- return path;
5013
+ return bootstrapPlugins$1(router, createHostApi, runtime);
4956
5014
  }
5015
+
4957
5016
  function bridgePrefixesFromVueCliEnv() {
4958
5017
  const base = (typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API
4959
5018
  ? String(process.env.VUE_APP_BASE_API)
@@ -4961,32 +5020,29 @@ function bridgePrefixesFromVueCliEnv() {
4961
5020
  const raw = [base ? `${base}/` : '', '/api/', '/dev-api/'].filter(Boolean);
4962
5021
  return [...new Set(raw)];
4963
5022
  }
5023
+ function asRecord(value) {
5024
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
5025
+ }
4964
5026
  function createVueCliAxiosInstallOptions(deps, extra = {}) {
4965
5027
  const { request } = deps;
4966
5028
  if (typeof request !== 'function') {
4967
5029
  throw new Error('[wep] createVueCliAxiosInstallOptions requires deps.request');
4968
5030
  }
4969
- const { fetchManifest: userFetchManifest, manifestMode: extraManifestMode, staticManifestUrl: extraStaticManifestUrl, ...restExtra } = extra;
4970
- const envBase = (typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API
4971
- ? String(process.env.VUE_APP_BASE_API)
4972
- : '').replace(/\/$/, '');
4973
- const userBase = extra.manifestBase !== undefined && String(extra.manifestBase).trim() !== ''
4974
- ? String(extra.manifestBase).replace(/\/$/, '')
4975
- : '';
4976
- const stripBase = userBase || envBase;
5031
+ const manifest = asRecord(extra.manifest) || {};
5032
+ const host = asRecord(extra.host) || {};
5033
+ const mergedHost = { ...host };
4977
5034
  const fetchManifestApi = async (ctx) => {
4978
5035
  try {
5036
+ const manifestRequestUrl = typeof window !== 'undefined'
5037
+ ? new URL(String(ctx.manifestUrl), window.location.origin).toString()
5038
+ : String(ctx.manifestUrl);
4979
5039
  const body = await request({
4980
- url: resolveManifestPathUnderApiBase(ctx.manifestUrl, stripBase),
5040
+ url: manifestRequestUrl,
4981
5041
  method: 'get'
4982
5042
  });
4983
5043
  const data = unwrapNestedManifestBody(body);
4984
5044
  if (!data || typeof data !== 'object') {
4985
- return {
4986
- ok: false,
4987
- error: new Error('[wep] invalid manifest response'),
4988
- data: null
4989
- };
5045
+ return { ok: false, error: new Error('[wep] invalid manifest response'), data: null };
4990
5046
  }
4991
5047
  return { ok: true, data };
4992
5048
  }
@@ -4994,28 +5050,35 @@ function createVueCliAxiosInstallOptions(deps, extra = {}) {
4994
5050
  return { ok: false, error, data: null };
4995
5051
  }
4996
5052
  };
4997
- const manifestMode = resolveManifestModeFromInputs(extraManifestMode);
4998
- const staticManifestUrl = resolveStaticManifestUrlFromInputs(extraStaticManifestUrl);
4999
- const fetchManifest = typeof userFetchManifest === 'function'
5000
- ? userFetchManifest
5001
- : manifestMode === 'static'
5053
+ const manifestSource = resolveManifestModeFromInputs(manifest.source);
5054
+ const staticUrl = resolveStaticManifestUrlFromInputs(manifest.staticUrl);
5055
+ const fetchManifest = typeof manifest.fetch === 'function'
5056
+ ? manifest.fetch
5057
+ : manifestSource === 'static'
5002
5058
  ? fetchStaticManifestViaHttp
5003
5059
  : fetchManifestApi;
5004
- const options = {
5005
- manifestBase: stripBase || undefined,
5006
- bridgeAllowedPathPrefixes: bridgePrefixesFromVueCliEnv(),
5007
- manifestMode,
5008
- staticManifestUrl,
5009
- ...restExtra,
5010
- fetchManifest
5011
- };
5012
5060
  const listPath = typeof process !== 'undefined' &&
5013
5061
  process.env &&
5014
- process.env[webExtendPluginEnvKeys.manifestPathAlt];
5015
- if (listPath && options.manifestListPath === undefined && extra.manifestListPath === undefined) {
5016
- options.manifestListPath = String(process.env[webExtendPluginEnvKeys.manifestPathAlt]);
5062
+ process.env[webExtendPluginEnvKeys.manifestPathAlt]
5063
+ ? String(process.env[webExtendPluginEnvKeys.manifestPathAlt])
5064
+ : undefined;
5065
+ if (mergedHost.requestPathPrefixes === undefined) {
5066
+ mergedHost.requestPathPrefixes = bridgePrefixesFromVueCliEnv();
5017
5067
  }
5018
- return options;
5068
+ return {
5069
+ ...extra,
5070
+ manifest: {
5071
+ ...manifest,
5072
+ baseUrl: manifest.baseUrl !== undefined && String(manifest.baseUrl).trim() !== ''
5073
+ ? String(manifest.baseUrl).replace(/\/$/, '')
5074
+ : undefined,
5075
+ listPath: manifest.listPath !== undefined ? manifest.listPath : listPath,
5076
+ source: manifestSource,
5077
+ staticUrl,
5078
+ fetch: fetchManifest
5079
+ },
5080
+ host: mergedHost
5081
+ };
5019
5082
  }
5020
5083
 
5021
5084
  const { bootstrapPlugins, defaultFetchWebPluginManifest, resolveRuntimeOptions, ensurePluginHostRoute, getActivatedPluginIds } = pluginRuntime;