web-extend-plugin-vue2 0.2.1 → 0.2.2

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.mjs CHANGED
@@ -59,115 +59,490 @@ const defaultWebExtendPluginRuntime = {
59
59
  bridgeAllowedPathPrefixes: ['/api/']
60
60
  };
61
61
 
62
- function getDefaultExportFromCjs (x) {
63
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
64
- }
65
-
66
- var re = {exports: {}};
62
+ /**
63
+ * 不依赖 `import.meta`,兼容 Webpack 4/5、Vue CLI、Vite、Rspack 等宿主。
64
+ * - Webpack / Vue CLI:依赖构建时注入的 `process.env`(如 `VUE_APP_*`、`DefinePlugin` 注入的 `VITE_*`)。
65
+ * - Vite:在入口调用 `setWebExtendPluginEnv(import.meta.env)`,或 `installWebExtendPluginVue2(..., { env: import.meta.env })`。
66
+ * - 也可在入口前设置 `globalThis.__WEP_ENV__ = import.meta.env`(与 setWebExtendPluginEnv 二选一即可)。
67
+ *
68
+ * @module bundled-env
69
+ */
67
70
 
68
- var constants;
69
- var hasRequiredConstants;
71
+ /** @type {Record<string, unknown> | null} */
72
+ let _explicitEnv = null;
70
73
 
71
- function requireConstants () {
72
- if (hasRequiredConstants) return constants;
73
- hasRequiredConstants = 1;
74
+ /**
75
+ * 显式注入与 `import.meta.env` 同形态的对象(推荐 Vite 宿主在入口调用一次)。
76
+ * @param {Record<string, unknown> | null | undefined} env
77
+ */
78
+ function setWebExtendPluginEnv(env) {
79
+ _explicitEnv = env && typeof env === 'object' ? env : null;
80
+ }
74
81
 
75
- // Note: this is the semver.org version of the spec that it implements
76
- // Not necessarily the package version of this code.
77
- const SEMVER_SPEC_VERSION = '2.0.0';
82
+ /**
83
+ * @returns {Record<string, unknown> | null}
84
+ */
85
+ function getInjectedEnvObject() {
86
+ if (_explicitEnv) {
87
+ return _explicitEnv
88
+ }
89
+ try {
90
+ const g = typeof globalThis !== 'undefined' ? globalThis : undefined;
91
+ if (g && g.__WEP_ENV__ && typeof g.__WEP_ENV__ === 'object') {
92
+ return g.__WEP_ENV__
93
+ }
94
+ } catch (_) {}
95
+ return null
96
+ }
78
97
 
79
- const MAX_LENGTH = 256;
80
- const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
81
- /* istanbul ignore next */ 9007199254740991;
98
+ /**
99
+ * 从注入环境读取字符串配置键(`VITE_*` / `PLUGIN_*` 等)。
100
+ * @param {string} key
101
+ * @returns {string|undefined}
102
+ */
103
+ function readInjectedEnvKey(key) {
104
+ const o = getInjectedEnvObject();
105
+ if (!o || !(key in o)) {
106
+ return undefined
107
+ }
108
+ const v = o[key];
109
+ if (v === undefined || v === '') {
110
+ return undefined
111
+ }
112
+ return String(v)
113
+ }
82
114
 
83
- // Max safe segment length for coercion.
84
- const MAX_SAFE_COMPONENT_LENGTH = 16;
115
+ /**
116
+ * @returns {boolean}
117
+ */
118
+ function readInjectedEnvDev() {
119
+ const o = getInjectedEnvObject();
120
+ return !!(o && o.DEV === true)
121
+ }
85
122
 
86
- // Max safe length for a build identifier. The max length minus 6 characters for
87
- // the shortest version with a build 0.0.0+BUILD.
88
- const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6;
123
+ /**
124
+ * 从注入环境与 `process.env` 解析 VITE_/PLUGIN_ 键。
125
+ * @module runtime/env-resolve
126
+ */
89
127
 
90
- const RELEASE_TYPES = [
91
- 'major',
92
- 'premajor',
93
- 'minor',
94
- 'preminor',
95
- 'patch',
96
- 'prepatch',
97
- 'prerelease',
98
- ];
128
+ /**
129
+ * @param {string} key
130
+ * @returns {string|undefined}
131
+ */
132
+ function readProcessEnv(key) {
133
+ try {
134
+ if (typeof process !== 'undefined' && process.env && key in process.env) {
135
+ const v = process.env[key];
136
+ if (v !== undefined && v !== '') {
137
+ return String(v)
138
+ }
139
+ }
140
+ } catch (_) {}
141
+ return undefined
142
+ }
99
143
 
100
- constants = {
101
- MAX_LENGTH,
102
- MAX_SAFE_COMPONENT_LENGTH,
103
- MAX_SAFE_BUILD_LENGTH,
104
- MAX_SAFE_INTEGER,
105
- RELEASE_TYPES,
106
- SEMVER_SPEC_VERSION,
107
- FLAG_INCLUDE_PRERELEASE: 0b001,
108
- FLAG_LOOSE: 0b010,
109
- };
110
- return constants;
144
+ /**
145
+ * @param {string} viteStyleKey
146
+ * @returns {string|null}
147
+ */
148
+ function viteKeyToPluginAlternate(viteStyleKey) {
149
+ if (typeof viteStyleKey !== 'string' || !viteStyleKey.startsWith('VITE_')) {
150
+ return null
151
+ }
152
+ return `PLUGIN_${viteStyleKey.slice(5)}`
111
153
  }
112
154
 
113
- var debug_1;
114
- var hasRequiredDebug;
155
+ /**
156
+ * @param {string} key
157
+ * @param {string} [fallback='']
158
+ */
159
+ function resolveBundledEnv(key, fallback = '') {
160
+ const alt = viteKeyToPluginAlternate(key);
161
+ const inj = readInjectedEnvKey(key);
162
+ const fromInjected =
163
+ inj === undefined || inj === null ? (alt ? readInjectedEnvKey(alt) : undefined) : inj;
164
+ const proc = readProcessEnv(key);
165
+ const fromProcess =
166
+ proc === undefined || proc === null ? (alt ? readProcessEnv(alt) : undefined) : proc;
167
+ const first = fromInjected === undefined || fromInjected === null ? fromProcess : fromInjected;
168
+ return first === undefined || first === null ? fallback : first
169
+ }
115
170
 
116
- function requireDebug () {
117
- if (hasRequiredDebug) return debug_1;
118
- hasRequiredDebug = 1;
171
+ /**
172
+ * @returns {boolean}
173
+ */
174
+ function resolveBundledIsDev() {
175
+ try {
176
+ if (readInjectedEnvDev()) {
177
+ return true
178
+ }
179
+ } catch (_) {}
180
+ try {
181
+ if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'development') {
182
+ return true
183
+ }
184
+ } catch (_) {}
185
+ return false
186
+ }
119
187
 
120
- const debug = (
121
- typeof process === 'object' &&
122
- process.env &&
123
- process.env.NODE_DEBUG &&
124
- /\bsemver\b/i.test(process.env.NODE_DEBUG)
125
- ) ? (...args) => console.error('SEMVER', ...args)
126
- : () => {};
188
+ /**
189
+ * 路径与脚本主机名校验工具。
190
+ * @module runtime/path-host-utils
191
+ */
127
192
 
128
- debug_1 = debug;
129
- return debug_1;
193
+ /**
194
+ * @param {string} p
195
+ */
196
+ function ensureLeadingPath(p) {
197
+ const t = String(p || '').trim();
198
+ if (!t) {
199
+ return '/'
200
+ }
201
+ return t.startsWith('/') ? t : `/${t}`
130
202
  }
131
203
 
132
- var hasRequiredRe;
204
+ /**
205
+ * @param {string} hostname
206
+ */
207
+ function normalizeHost(hostname) {
208
+ if (!hostname) {
209
+ return ''
210
+ }
211
+ const h = hostname.toLowerCase();
212
+ if (h.startsWith('[') && h.endsWith(']')) {
213
+ return h.slice(1, -1)
214
+ }
215
+ return h
216
+ }
133
217
 
134
- function requireRe () {
135
- if (hasRequiredRe) return re.exports;
136
- hasRequiredRe = 1;
137
- (function (module, exports$1) {
218
+ /**
219
+ * @param {string[]} hostnames
220
+ * @returns {Set<string>}
221
+ */
222
+ function buildAllowedScriptHostsSet(hostnames) {
223
+ const s = new Set();
224
+ for (const h of hostnames) {
225
+ const n = normalizeHost(h);
226
+ if (n) {
227
+ s.add(n);
228
+ }
229
+ }
230
+ return s
231
+ }
138
232
 
139
- const {
140
- MAX_SAFE_COMPONENT_LENGTH,
141
- MAX_SAFE_BUILD_LENGTH,
142
- MAX_LENGTH,
143
- } = requireConstants();
144
- const debug = requireDebug();
145
- exports$1 = module.exports = {};
233
+ /**
234
+ * @param {string} url
235
+ * @param {Set<string>} hostSet
236
+ */
237
+ function isScriptHostAllowed(url, hostSet) {
238
+ if (typeof window === 'undefined') {
239
+ return false
240
+ }
241
+ try {
242
+ const u = new URL(url, window.location.origin);
243
+ const h = normalizeHost(u.hostname);
244
+ return hostSet.has(h)
245
+ } catch {
246
+ return false
247
+ }
248
+ }
146
249
 
147
- // The actual regexps go on exports.re
148
- const re = exports$1.re = [];
149
- const safeRe = exports$1.safeRe = [];
150
- const src = exports$1.src = [];
151
- const safeSrc = exports$1.safeSrc = [];
152
- const t = exports$1.t = {};
153
- let R = 0;
250
+ /**
251
+ * 合并用户、环境与默认配置得到运行时选项。
252
+ * @module runtime/resolve-runtime-options
253
+ */
154
254
 
155
- const LETTERDASHNUMBER = '[a-zA-Z0-9-]';
156
255
 
157
- // Replace some greedy regex tokens to prevent regex dos issues. These regex are
158
- // used internally via the safeRe object since all inputs in this library get
159
- // normalized first to trim and collapse all extra whitespace. The original
160
- // regexes are exported for userland consumption and lower level usage. A
161
- // future breaking change could export the safer regex only with a note that
162
- // all input should have extra whitespace removed.
163
- const safeRegexReplacements = [
164
- ['\\s', 1],
165
- ['\\d', MAX_LENGTH],
166
- [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
167
- ];
256
+ const DEF = defaultWebExtendPluginRuntime;
168
257
 
169
- const makeSafeRegex = (value) => {
170
- for (const [token, max] of safeRegexReplacements) {
258
+ /**
259
+ * @param {string|undefined} userVal
260
+ * @param {string} envKey
261
+ * @param {RequestCredentials} fallback
262
+ */
263
+ function resolveManifestCredentials(userVal, envKey, fallback) {
264
+ if (userVal !== undefined && userVal !== '') {
265
+ const s = String(userVal);
266
+ if (s === 'include' || s === 'omit' || s === 'same-origin') {
267
+ return s
268
+ }
269
+ }
270
+ const e = resolveBundledEnv(envKey, '');
271
+ if (e === 'include' || e === 'omit' || e === 'same-origin') {
272
+ return e
273
+ }
274
+ return fallback
275
+ }
276
+
277
+ /**
278
+ * @param {number|undefined} userVal
279
+ * @param {string} envKey
280
+ * @param {number} fallback
281
+ */
282
+ function resolvePositiveInt(userVal, envKey, fallback) {
283
+ if (typeof userVal === 'number' && Number.isFinite(userVal) && userVal > 0) {
284
+ return Math.floor(userVal)
285
+ }
286
+ const raw = resolveBundledEnv(envKey, '');
287
+ const n = raw ? parseInt(raw, 10) : NaN;
288
+ if (Number.isFinite(n) && n > 0) {
289
+ return n
290
+ }
291
+ return fallback
292
+ }
293
+
294
+ /**
295
+ * 合并用户、环境变量与 `defaultWebExtendPluginRuntime`,得到完整运行时选项(宿主可只传需要覆盖的字段)。
296
+ * @param {WebExtendPluginRuntimeOptions} [user]
297
+ * @returns {object}
298
+ */
299
+ function resolveRuntimeOptions$1(user = {}) {
300
+ const manifestBaseRaw =
301
+ user.manifestBase !== undefined && user.manifestBase !== ''
302
+ ? String(user.manifestBase)
303
+ : resolveBundledEnv('VITE_FRONTEND_PLUGIN_BASE', DEF.manifestBase) || DEF.manifestBase;
304
+
305
+ const manifestListPath = ensureLeadingPath(
306
+ user.manifestListPath !== undefined && user.manifestListPath !== ''
307
+ ? user.manifestListPath
308
+ : resolveBundledEnv('VITE_WEB_PLUGIN_MANIFEST_PATH', DEF.manifestListPath)
309
+ );
310
+
311
+ const defaultImplicitDevPluginIds = Array.isArray(user.defaultImplicitDevPluginIds)
312
+ ? user.defaultImplicitDevPluginIds.map(String).filter(Boolean)
313
+ : (() => {
314
+ const e = resolveBundledEnv('VITE_WEB_PLUGIN_IMPLICIT_DEV_IDS', '');
315
+ if (e) {
316
+ return e
317
+ .split(',')
318
+ .map((s) => s.trim())
319
+ .filter(Boolean)
320
+ }
321
+ return [...DEF.defaultImplicitDevPluginIds]
322
+ })();
323
+
324
+ const allowedScriptHosts =
325
+ Array.isArray(user.allowedScriptHosts) && user.allowedScriptHosts.length > 0
326
+ ? user.allowedScriptHosts.map((h) => normalizeHost(String(h))).filter(Boolean)
327
+ : (() => {
328
+ const e = resolveBundledEnv('VITE_WEB_PLUGIN_ALLOWED_SCRIPT_HOSTS', '');
329
+ if (e) {
330
+ return e
331
+ .split(',')
332
+ .map((s) => normalizeHost(s.trim()))
333
+ .filter(Boolean)
334
+ }
335
+ return [...DEF.allowedScriptHosts]
336
+ })();
337
+
338
+ const bridgeAllowedPathPrefixes =
339
+ Array.isArray(user.bridgeAllowedPathPrefixes) && user.bridgeAllowedPathPrefixes.length > 0
340
+ ? user.bridgeAllowedPathPrefixes.map((p) => ensureLeadingPath(p)).filter(Boolean)
341
+ : (() => {
342
+ const e = resolveBundledEnv('VITE_WEB_PLUGIN_BRIDGE_PREFIXES', '');
343
+ if (e) {
344
+ return e
345
+ .split(',')
346
+ .map((s) => ensureLeadingPath(s.trim()))
347
+ .filter(Boolean)
348
+ }
349
+ return [...DEF.bridgeAllowedPathPrefixes]
350
+ })();
351
+
352
+ return {
353
+ manifestBase: manifestBaseRaw.replace(/\/$/, '') || DEF.manifestBase.replace(/\/$/, ''),
354
+ manifestListPath,
355
+ manifestFetchCredentials: resolveManifestCredentials(
356
+ user.manifestFetchCredentials,
357
+ 'VITE_WEB_PLUGIN_MANIFEST_CREDENTIALS',
358
+ DEF.manifestFetchCredentials
359
+ ),
360
+ isDev: user.isDev !== undefined ? user.isDev : resolveBundledIsDev(),
361
+ webPluginDevOrigin:
362
+ user.webPluginDevOrigin !== undefined ? user.webPluginDevOrigin : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_ORIGIN', ''),
363
+ webPluginDevIds:
364
+ user.webPluginDevIds !== undefined ? user.webPluginDevIds : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_IDS', ''),
365
+ webPluginDevMapJson:
366
+ user.webPluginDevMapJson !== undefined
367
+ ? user.webPluginDevMapJson
368
+ : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_MAP', ''),
369
+ webPluginDevEntryPath: ensureLeadingPath(
370
+ user.webPluginDevEntryPath !== undefined && user.webPluginDevEntryPath !== ''
371
+ ? user.webPluginDevEntryPath
372
+ : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_ENTRY', DEF.webPluginDevEntryPath)
373
+ ),
374
+ devPingPath: ensureLeadingPath(
375
+ user.devPingPath !== undefined && user.devPingPath !== ''
376
+ ? user.devPingPath
377
+ : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_PING_PATH', DEF.devPingPath)
378
+ ),
379
+ devReloadSsePath: ensureLeadingPath(
380
+ user.devReloadSsePath !== undefined && user.devReloadSsePath !== ''
381
+ ? user.devReloadSsePath
382
+ : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_SSE_PATH', DEF.devReloadSsePath)
383
+ ),
384
+ devPingTimeoutMs: resolvePositiveInt(user.devPingTimeoutMs, 'VITE_WEB_PLUGIN_DEV_PING_TIMEOUT_MS', DEF.devPingTimeoutMs),
385
+ defaultImplicitDevPluginIds,
386
+ allowedScriptHosts,
387
+ bridgeAllowedPathPrefixes,
388
+ bootstrapSummary: user.bootstrapSummary,
389
+ ...(typeof user.fetchManifest === 'function' ? { fetchManifest: user.fetchManifest } : {})
390
+ }
391
+ }
392
+
393
+ /**
394
+ * 默认清单 HTTP 拉取(未配置 `fetchManifest` 时)。
395
+ * @module runtime/default-fetch-manifest
396
+ */
397
+
398
+ /**
399
+ * @typedef {object} FetchWebPluginManifestContext
400
+ * @property {string} manifestUrl
401
+ * @property {RequestCredentials} credentials
402
+ */
403
+
404
+ /**
405
+ * @typedef {object} FetchWebPluginManifestResult
406
+ * @property {boolean} ok
407
+ * @property {number} [status]
408
+ * @property {{ hostPluginApiVersion?: string, plugins?: object[] }|null} [data]
409
+ * @property {unknown} [error]
410
+ */
411
+
412
+ /**
413
+ * @callback FetchWebPluginManifestFn
414
+ * @param {FetchWebPluginManifestContext} ctx
415
+ * @returns {Promise<FetchWebPluginManifestResult>}
416
+ */
417
+
418
+ /**
419
+ * 默认清单请求(未配置 `fetchManifest` 时)。
420
+ * @param {FetchWebPluginManifestContext} ctx
421
+ * @returns {Promise<FetchWebPluginManifestResult>}
422
+ */
423
+ async function defaultFetchWebPluginManifest$1(ctx) {
424
+ const { manifestUrl, credentials } = ctx;
425
+ try {
426
+ const res = await fetch(manifestUrl, { credentials });
427
+ if (!res.ok) {
428
+ return { ok: false, status: res.status, data: null }
429
+ }
430
+ const data = await res.json();
431
+ return { ok: true, data }
432
+ } catch (e) {
433
+ return { ok: false, error: e, data: null }
434
+ }
435
+ }
436
+
437
+ function getDefaultExportFromCjs (x) {
438
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
439
+ }
440
+
441
+ var re = {exports: {}};
442
+
443
+ var constants;
444
+ var hasRequiredConstants;
445
+
446
+ function requireConstants () {
447
+ if (hasRequiredConstants) return constants;
448
+ hasRequiredConstants = 1;
449
+
450
+ // Note: this is the semver.org version of the spec that it implements
451
+ // Not necessarily the package version of this code.
452
+ const SEMVER_SPEC_VERSION = '2.0.0';
453
+
454
+ const MAX_LENGTH = 256;
455
+ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
456
+ /* istanbul ignore next */ 9007199254740991;
457
+
458
+ // Max safe segment length for coercion.
459
+ const MAX_SAFE_COMPONENT_LENGTH = 16;
460
+
461
+ // Max safe length for a build identifier. The max length minus 6 characters for
462
+ // the shortest version with a build 0.0.0+BUILD.
463
+ const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6;
464
+
465
+ const RELEASE_TYPES = [
466
+ 'major',
467
+ 'premajor',
468
+ 'minor',
469
+ 'preminor',
470
+ 'patch',
471
+ 'prepatch',
472
+ 'prerelease',
473
+ ];
474
+
475
+ constants = {
476
+ MAX_LENGTH,
477
+ MAX_SAFE_COMPONENT_LENGTH,
478
+ MAX_SAFE_BUILD_LENGTH,
479
+ MAX_SAFE_INTEGER,
480
+ RELEASE_TYPES,
481
+ SEMVER_SPEC_VERSION,
482
+ FLAG_INCLUDE_PRERELEASE: 0b001,
483
+ FLAG_LOOSE: 0b010,
484
+ };
485
+ return constants;
486
+ }
487
+
488
+ var debug_1;
489
+ var hasRequiredDebug;
490
+
491
+ function requireDebug () {
492
+ if (hasRequiredDebug) return debug_1;
493
+ hasRequiredDebug = 1;
494
+
495
+ const debug = (
496
+ typeof process === 'object' &&
497
+ process.env &&
498
+ process.env.NODE_DEBUG &&
499
+ /\bsemver\b/i.test(process.env.NODE_DEBUG)
500
+ ) ? (...args) => console.error('SEMVER', ...args)
501
+ : () => {};
502
+
503
+ debug_1 = debug;
504
+ return debug_1;
505
+ }
506
+
507
+ var hasRequiredRe;
508
+
509
+ function requireRe () {
510
+ if (hasRequiredRe) return re.exports;
511
+ hasRequiredRe = 1;
512
+ (function (module, exports$1) {
513
+
514
+ const {
515
+ MAX_SAFE_COMPONENT_LENGTH,
516
+ MAX_SAFE_BUILD_LENGTH,
517
+ MAX_LENGTH,
518
+ } = requireConstants();
519
+ const debug = requireDebug();
520
+ exports$1 = module.exports = {};
521
+
522
+ // The actual regexps go on exports.re
523
+ const re = exports$1.re = [];
524
+ const safeRe = exports$1.safeRe = [];
525
+ const src = exports$1.src = [];
526
+ const safeSrc = exports$1.safeSrc = [];
527
+ const t = exports$1.t = {};
528
+ let R = 0;
529
+
530
+ const LETTERDASHNUMBER = '[a-zA-Z0-9-]';
531
+
532
+ // Replace some greedy regex tokens to prevent regex dos issues. These regex are
533
+ // used internally via the safeRe object since all inputs in this library get
534
+ // normalized first to trim and collapse all extra whitespace. The original
535
+ // regexes are exported for userland consumption and lower level usage. A
536
+ // future breaking change could export the safer regex only with a note that
537
+ // all input should have extra whitespace removed.
538
+ const safeRegexReplacements = [
539
+ ['\\s', 1],
540
+ ['\\d', MAX_LENGTH],
541
+ [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
542
+ ];
543
+
544
+ const makeSafeRegex = (value) => {
545
+ for (const [token, max] of safeRegexReplacements) {
171
546
  value = value
172
547
  .split(`${token}*`).join(`${token}{0,${max}}`)
173
548
  .split(`${token}+`).join(`${token}{1,${max}}`);
@@ -2772,395 +3147,31 @@ function requireSemver () {
2772
3147
  SemVer,
2773
3148
  re: internalRe.re,
2774
3149
  src: internalRe.src,
2775
- tokens: internalRe.t,
2776
- SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION,
2777
- RELEASE_TYPES: constants.RELEASE_TYPES,
2778
- compareIdentifiers: identifiers.compareIdentifiers,
2779
- rcompareIdentifiers: identifiers.rcompareIdentifiers,
2780
- };
2781
- return semver$1;
2782
- }
2783
-
2784
- var semverExports = requireSemver();
2785
- var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
2786
-
2787
- /**
2788
- * 不依赖 `import.meta`,兼容 Webpack 4/5、Vue CLI、Vite、Rspack 等宿主。
2789
- * - Webpack / Vue CLI:依赖构建时注入的 `process.env`(如 `VUE_APP_*`、`DefinePlugin` 注入的 `VITE_*`)。
2790
- * - Vite:在入口调用 `setWebExtendPluginEnv(import.meta.env)`,或 `installWebExtendPluginVue2(..., { env: import.meta.env })`。
2791
- * - 也可在入口前设置 `globalThis.__WEP_ENV__ = import.meta.env`(与 setWebExtendPluginEnv 二选一即可)。
2792
- *
2793
- * @module bundled-env
2794
- */
2795
-
2796
- /** @type {Record<string, unknown> | null} */
2797
- let _explicitEnv = null;
2798
-
2799
- /**
2800
- * 显式注入与 `import.meta.env` 同形态的对象(推荐 Vite 宿主在入口调用一次)。
2801
- * @param {Record<string, unknown> | null | undefined} env
2802
- */
2803
- function setWebExtendPluginEnv(env) {
2804
- _explicitEnv = env && typeof env === 'object' ? env : null;
2805
- }
2806
-
2807
- /**
2808
- * @returns {Record<string, unknown> | null}
2809
- */
2810
- function getInjectedEnvObject() {
2811
- if (_explicitEnv) {
2812
- return _explicitEnv
2813
- }
2814
- try {
2815
- const g = typeof globalThis !== 'undefined' ? globalThis : undefined;
2816
- if (g && g.__WEP_ENV__ && typeof g.__WEP_ENV__ === 'object') {
2817
- return g.__WEP_ENV__
2818
- }
2819
- } catch (_) {}
2820
- return null
2821
- }
2822
-
2823
- /**
2824
- * 从注入环境读取字符串配置键(`VITE_*` / `PLUGIN_*` 等)。
2825
- * @param {string} key
2826
- * @returns {string|undefined}
2827
- */
2828
- function readInjectedEnvKey(key) {
2829
- const o = getInjectedEnvObject();
2830
- if (!o || !(key in o)) {
2831
- return undefined
2832
- }
2833
- const v = o[key];
2834
- if (v === undefined || v === '') {
2835
- return undefined
2836
- }
2837
- return String(v)
2838
- }
2839
-
2840
- /**
2841
- * @returns {boolean}
2842
- */
2843
- function readInjectedEnvDev() {
2844
- const o = getInjectedEnvObject();
2845
- return !!(o && o.DEV === true)
2846
- }
2847
-
2848
- /**
2849
- * 与 `plugin-web-starter`(WebPluginsResponse)返回的 `hostPluginApiVersion` 保持一致,用于契约校验。
2850
- * @type {string}
2851
- */
2852
- const HOST_PLUGIN_API_VERSION = '1.0.0';
2853
-
2854
- /**
2855
- * 宿主侧插件引导:拉取清单、dev 映射、加载入口脚本、调用 activator。
2856
- * 路径与白名单等默认值见 `defaultWebExtendPluginRuntime`,可通过 `resolveRuntimeOptions` / 环境变量覆盖。
2857
- *
2858
- * **Webpack 宿主**:用 `DefinePlugin` 注入 `process.env.VITE_*` 或 **`PLUGIN_*`**(等价键),或 `resolveRuntimeOptions` 显式传参。
2859
- * **Vite 宿主**:入口调用 `setWebExtendPluginEnv(import.meta.env)`,或 `installWebExtendPluginVue2(..., { env: import.meta.env })`。
2860
- *
2861
- * @module PluginRuntime
2862
- */
2863
-
2864
- const DEF = defaultWebExtendPluginRuntime;
2865
-
2866
- /**
2867
- * @typedef {object} WebExtendPluginRuntimeOptions
2868
- * @property {string} [manifestBase] 清单服务 URL 前缀
2869
- * @property {string} [manifestListPath] 清单接口路径(以 `/` 开头),拼在 manifestBase 后
2870
- * @property {RequestCredentials} [manifestFetchCredentials] 清单 fetch 的 credentials
2871
- * @property {boolean} [isDev] 开发模式
2872
- * @property {string} [webPluginDevOrigin] 插件 dev origin
2873
- * @property {string} [webPluginDevIds] 逗号分隔 id,隐式 dev 映射
2874
- * @property {string} [webPluginDevMapJson] 显式 dev 映射 JSON
2875
- * @property {string} [webPluginDevEntryPath] 隐式 dev 入口路径(相对插件 dev origin)
2876
- * @property {string} [devPingPath] dev 存活探测路径
2877
- * @property {string} [devReloadSsePath] dev 热更新 SSE 路径
2878
- * @property {number} [devPingTimeoutMs] 探测超时
2879
- * @property {string[]} [defaultImplicitDevPluginIds] 无 `webPluginDevIds`/env 时用于隐式 dev 的 id;包内默认 `[]`
2880
- * @property {string[]} [allowedScriptHosts] 允许加载脚本的主机名
2881
- * @property {string[]} [bridgeAllowedPathPrefixes] bridge.request 白名单前缀
2882
- * @property {boolean} [bootstrapSummary] bootstrap 结束是否打印摘要
2883
- */
2884
-
2885
- /**
2886
- * 从 Webpack `DefinePlugin` 等注入的 `process.env` 读取。
2887
- * @param {string} key
2888
- * @returns {string|undefined}
2889
- */
2890
- function readProcessEnv(key) {
2891
- try {
2892
- if (typeof process !== 'undefined' && process.env && key in process.env) {
2893
- const v = process.env[key];
2894
- if (v !== undefined && v !== '') {
2895
- return String(v)
2896
- }
2897
- }
2898
- } catch (_) {}
2899
- return undefined
2900
- }
2901
-
2902
- /**
2903
- * `VITE_*` 的并列命名:同值可读 `PLUGIN_*`(`VITE_WEB_PLUGIN_X` → `PLUGIN_WEB_PLUGIN_X`)。
2904
- * Vite 需在 `defineConfig({ envPrefix: ['VITE_', 'PLUGIN_'] })` 中暴露 `PLUGIN_`;Webpack 用 DefinePlugin 注入即可。
2905
- * @param {string} viteStyleKey 以 `VITE_` 开头的键名
2906
- * @returns {string|null}
2907
- */
2908
- function viteKeyToPluginAlternate(viteStyleKey) {
2909
- if (typeof viteStyleKey !== 'string' || !viteStyleKey.startsWith('VITE_')) {
2910
- return null
2911
- }
2912
- return `PLUGIN_${viteStyleKey.slice(5)}`
2913
- }
2914
-
2915
- /**
2916
- * 先读注入环境(`setWebExtendPluginEnv` / `__WEP_ENV__`)中的 `VITE_*` 与并列 `PLUGIN_*`,再读 `process.env`,最后 `fallback`。
2917
- * @param {string} key 仍以 `VITE_*` 为逻辑名(与文档一致)
2918
- * @param {string} [fallback='']
2919
- */
2920
- function resolveBundledEnv(key, fallback = '') {
2921
- const alt = viteKeyToPluginAlternate(key);
2922
- const inj = readInjectedEnvKey(key);
2923
- const fromInjected =
2924
- inj === undefined || inj === null ? (alt ? readInjectedEnvKey(alt) : undefined) : inj;
2925
- const proc = readProcessEnv(key);
2926
- const fromProcess =
2927
- proc === undefined || proc === null ? (alt ? readProcessEnv(alt) : undefined) : proc;
2928
- const first = fromInjected === undefined || fromInjected === null ? fromProcess : fromInjected;
2929
- return first === undefined || first === null ? fallback : first
2930
- }
2931
-
2932
- /**
2933
- * @returns {boolean}
2934
- */
2935
- function resolveBundledIsDev() {
2936
- try {
2937
- if (readInjectedEnvDev()) {
2938
- return true
2939
- }
2940
- } catch (_) {}
2941
- try {
2942
- if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'development') {
2943
- return true
2944
- }
2945
- } catch (_) {}
2946
- return false
2947
- }
2948
-
2949
- /**
2950
- * @param {string} p
2951
- */
2952
- function ensureLeadingPath(p) {
2953
- const t = String(p || '').trim();
2954
- if (!t) {
2955
- return '/'
2956
- }
2957
- return t.startsWith('/') ? t : `/${t}`
2958
- }
2959
-
2960
- /**
2961
- * 解析 `include` | `omit` | `same-origin`,非法时回退默认值。
2962
- * @param {string|undefined} userVal
2963
- * @param {string} envKey
2964
- * @param {RequestCredentials} fallback
2965
- */
2966
- function resolveManifestCredentials(userVal, envKey, fallback) {
2967
- if (userVal !== undefined && userVal !== '') {
2968
- const s = String(userVal);
2969
- if (s === 'include' || s === 'omit' || s === 'same-origin') {
2970
- return s
2971
- }
2972
- }
2973
- const e = resolveBundledEnv(envKey, '');
2974
- if (e === 'include' || e === 'omit' || e === 'same-origin') {
2975
- return e
2976
- }
2977
- return fallback
2978
- }
2979
-
2980
- /**
2981
- * @param {number|undefined} userVal
2982
- * @param {string} envKey
2983
- * @param {number} fallback
2984
- */
2985
- function resolvePositiveInt(userVal, envKey, fallback) {
2986
- if (typeof userVal === 'number' && Number.isFinite(userVal) && userVal > 0) {
2987
- return Math.floor(userVal)
2988
- }
2989
- const raw = resolveBundledEnv(envKey, '');
2990
- const n = raw ? parseInt(raw, 10) : NaN;
2991
- if (Number.isFinite(n) && n > 0) {
2992
- return n
2993
- }
2994
- return fallback
2995
- }
2996
-
2997
- /**
2998
- * 合并用户、环境变量与 `defaultWebExtendPluginRuntime`,得到完整运行时选项(宿主可只传需要覆盖的字段)。
2999
- * @param {WebExtendPluginRuntimeOptions} [user]
3000
- * @returns {object}
3001
- */
3002
- function resolveRuntimeOptions(user = {}) {
3003
- const manifestBaseRaw =
3004
- user.manifestBase !== undefined && user.manifestBase !== ''
3005
- ? String(user.manifestBase)
3006
- : resolveBundledEnv('VITE_FRONTEND_PLUGIN_BASE', DEF.manifestBase) || DEF.manifestBase;
3007
-
3008
- const manifestListPath = ensureLeadingPath(
3009
- user.manifestListPath !== undefined && user.manifestListPath !== ''
3010
- ? user.manifestListPath
3011
- : resolveBundledEnv('VITE_WEB_PLUGIN_MANIFEST_PATH', DEF.manifestListPath)
3012
- );
3013
-
3014
- const defaultImplicitDevPluginIds =
3015
- Array.isArray(user.defaultImplicitDevPluginIds)
3016
- ? user.defaultImplicitDevPluginIds.map(String).filter(Boolean)
3017
- : (() => {
3018
- const e = resolveBundledEnv('VITE_WEB_PLUGIN_IMPLICIT_DEV_IDS', '');
3019
- if (e) {
3020
- return e
3021
- .split(',')
3022
- .map((s) => s.trim())
3023
- .filter(Boolean)
3024
- }
3025
- return [...DEF.defaultImplicitDevPluginIds]
3026
- })();
3027
-
3028
- const allowedScriptHosts =
3029
- Array.isArray(user.allowedScriptHosts) && user.allowedScriptHosts.length > 0
3030
- ? user.allowedScriptHosts.map((h) => normalizeHost(String(h))).filter(Boolean)
3031
- : (() => {
3032
- const e = resolveBundledEnv('VITE_WEB_PLUGIN_ALLOWED_SCRIPT_HOSTS', '');
3033
- if (e) {
3034
- return e
3035
- .split(',')
3036
- .map((s) => normalizeHost(s.trim()))
3037
- .filter(Boolean)
3038
- }
3039
- return [...DEF.allowedScriptHosts]
3040
- })();
3041
-
3042
- const bridgeAllowedPathPrefixes =
3043
- Array.isArray(user.bridgeAllowedPathPrefixes) && user.bridgeAllowedPathPrefixes.length > 0
3044
- ? user.bridgeAllowedPathPrefixes.map((p) => ensureLeadingPath(p)).filter(Boolean)
3045
- : (() => {
3046
- const e = resolveBundledEnv('VITE_WEB_PLUGIN_BRIDGE_PREFIXES', '');
3047
- if (e) {
3048
- return e
3049
- .split(',')
3050
- .map((s) => ensureLeadingPath(s.trim()))
3051
- .filter(Boolean)
3052
- }
3053
- return [...DEF.bridgeAllowedPathPrefixes]
3054
- })();
3055
-
3056
- return {
3057
- manifestBase: manifestBaseRaw.replace(/\/$/, '') || DEF.manifestBase.replace(/\/$/, ''),
3058
- manifestListPath,
3059
- manifestFetchCredentials: resolveManifestCredentials(
3060
- user.manifestFetchCredentials,
3061
- 'VITE_WEB_PLUGIN_MANIFEST_CREDENTIALS',
3062
- DEF.manifestFetchCredentials
3063
- ),
3064
- isDev: user.isDev !== undefined ? user.isDev : resolveBundledIsDev(),
3065
- webPluginDevOrigin:
3066
- user.webPluginDevOrigin !== undefined ? user.webPluginDevOrigin : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_ORIGIN', ''),
3067
- webPluginDevIds:
3068
- user.webPluginDevIds !== undefined ? user.webPluginDevIds : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_IDS', ''),
3069
- webPluginDevMapJson:
3070
- user.webPluginDevMapJson !== undefined
3071
- ? user.webPluginDevMapJson
3072
- : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_MAP', ''),
3073
- webPluginDevEntryPath: ensureLeadingPath(
3074
- user.webPluginDevEntryPath !== undefined && user.webPluginDevEntryPath !== ''
3075
- ? user.webPluginDevEntryPath
3076
- : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_ENTRY', DEF.webPluginDevEntryPath)
3077
- ),
3078
- devPingPath: ensureLeadingPath(
3079
- user.devPingPath !== undefined && user.devPingPath !== ''
3080
- ? user.devPingPath
3081
- : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_PING_PATH', DEF.devPingPath)
3082
- ),
3083
- devReloadSsePath: ensureLeadingPath(
3084
- user.devReloadSsePath !== undefined && user.devReloadSsePath !== ''
3085
- ? user.devReloadSsePath
3086
- : resolveBundledEnv('VITE_WEB_PLUGIN_DEV_SSE_PATH', DEF.devReloadSsePath)
3087
- ),
3088
- devPingTimeoutMs: resolvePositiveInt(user.devPingTimeoutMs, 'VITE_WEB_PLUGIN_DEV_PING_TIMEOUT_MS', DEF.devPingTimeoutMs),
3089
- defaultImplicitDevPluginIds,
3090
- allowedScriptHosts,
3091
- bridgeAllowedPathPrefixes,
3092
- bootstrapSummary: user.bootstrapSummary
3093
- }
3094
- }
3095
-
3096
- /**
3097
- * @param {ReturnType<typeof resolveRuntimeOptions>} opts
3098
- */
3099
- function shouldShowBootstrapSummary(opts) {
3100
- if (opts.bootstrapSummary === true) {
3101
- return true
3102
- }
3103
- if (opts.bootstrapSummary === false) {
3104
- return false
3105
- }
3106
- const env = resolveBundledEnv('VITE_PLUGINS_BOOTSTRAP_SUMMARY', '');
3107
- if (env === '0' || env === 'false') {
3108
- return false
3109
- }
3110
- if (env === '1' || env === 'true') {
3111
- return true
3112
- }
3113
- return resolveBundledIsDev()
3150
+ tokens: internalRe.t,
3151
+ SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION,
3152
+ RELEASE_TYPES: constants.RELEASE_TYPES,
3153
+ compareIdentifiers: identifiers.compareIdentifiers,
3154
+ rcompareIdentifiers: identifiers.rcompareIdentifiers,
3155
+ };
3156
+ return semver$1;
3114
3157
  }
3115
3158
 
3116
- /**
3117
- * @param {string} hostname
3118
- */
3119
- function normalizeHost(hostname) {
3120
- if (!hostname) {
3121
- return ''
3122
- }
3123
- const h = hostname.toLowerCase();
3124
- if (h.startsWith('[') && h.endsWith(']')) {
3125
- return h.slice(1, -1)
3126
- }
3127
- return h
3128
- }
3159
+ var semverExports = requireSemver();
3160
+ var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
3129
3161
 
3130
- /**
3131
- * @param {string[]} hostnames
3132
- * @returns {Set<string>}
3133
- */
3134
- function buildAllowedScriptHostsSet(hostnames) {
3135
- const s = new Set();
3136
- for (const h of hostnames) {
3137
- const n = normalizeHost(h);
3138
- if (n) {
3139
- s.add(n);
3140
- }
3141
- }
3142
- return s
3143
- }
3162
+ /**
3163
+ * `plugin-web-starter`(WebPluginsResponse)返回的 `hostPluginApiVersion` 保持一致,用于契约校验。
3164
+ * @type {string}
3165
+ */
3166
+ const HOST_PLUGIN_API_VERSION = '1.0.0';
3144
3167
 
3145
3168
  /**
3146
- * @param {string} url
3147
- * @param {Set<string>} hostSet
3169
+ * 开发模式插件 URL 映射(显式 JSON + 隐式 dev 探测)。
3170
+ * @module runtime/dev-map
3148
3171
  */
3149
- function isScriptHostAllowed(url, hostSet) {
3150
- if (typeof window === 'undefined') {
3151
- return false
3152
- }
3153
- try {
3154
- const u = new URL(url, window.location.origin);
3155
- const h = normalizeHost(u.hostname);
3156
- return hostSet.has(h)
3157
- } catch {
3158
- return false
3159
- }
3160
- }
3161
3172
 
3162
3173
  /**
3163
- * @param {ReturnType<typeof resolveRuntimeOptions>} opts
3174
+ * @param {{ isDev: boolean, webPluginDevMapJson?: string|null }} opts
3164
3175
  */
3165
3176
  function parseWebPluginDevMapExplicit(opts) {
3166
3177
  if (!opts.isDev) {
@@ -3180,7 +3191,24 @@ function parseWebPluginDevMapExplicit(opts) {
3180
3191
  }
3181
3192
 
3182
3193
  /**
3183
- * @param {ReturnType<typeof resolveRuntimeOptions>} opts
3194
+ * @param {Record<string, string>} implicit
3195
+ * @param {Record<string, string>|null} explicit
3196
+ */
3197
+ function mergeDevMaps(implicit, explicit) {
3198
+ const i = implicit && typeof implicit === 'object' ? implicit : {};
3199
+ const e = explicit && typeof explicit === 'object' ? explicit : {};
3200
+ return { ...i, ...e }
3201
+ }
3202
+
3203
+ /**
3204
+ * @param {object} opts
3205
+ * @param {boolean} opts.isDev
3206
+ * @param {string|undefined|null} opts.webPluginDevOrigin
3207
+ * @param {string|undefined|null} opts.webPluginDevIds
3208
+ * @param {string[]} opts.defaultImplicitDevPluginIds
3209
+ * @param {string} opts.devPingPath
3210
+ * @param {number} opts.devPingTimeoutMs
3211
+ * @param {string} opts.webPluginDevEntryPath
3184
3212
  * @param {Set<string>} hostSet
3185
3213
  */
3186
3214
  async function buildImplicitWebPluginDevMap(opts, hostSet) {
@@ -3252,14 +3280,9 @@ async function buildImplicitWebPluginDevMap(opts, hostSet) {
3252
3280
  }
3253
3281
 
3254
3282
  /**
3255
- * @param {Record<string, string>} implicit
3256
- * @param {Record<string, string>|null} explicit
3283
+ * 开发模式下插件热更新 SSE(按 dev 映射中的 origin 连接)。
3284
+ * @module runtime/dev-reload-sse
3257
3285
  */
3258
- function mergeDevMaps(implicit, explicit) {
3259
- const i = implicit && typeof implicit === 'object' ? implicit : {};
3260
- const e = explicit && typeof explicit === 'object' ? explicit : {};
3261
- return { ...i, ...e }
3262
- }
3263
3286
 
3264
3287
  /** @type {Map<string, EventSource>} */
3265
3288
  const pluginDevEventSources = new Map();
@@ -3356,8 +3379,17 @@ function startPluginDevSseForMap(devMap, isDev, hostSet, ssePath) {
3356
3379
  }
3357
3380
  }
3358
3381
 
3382
+ /**
3383
+ * 动态加载脚本(去重与并发合并)。
3384
+ * @module runtime/load-script
3385
+ */
3386
+
3359
3387
  const loadScriptMemo = new Map();
3360
3388
 
3389
+ /**
3390
+ * @param {string} src
3391
+ * @returns {Promise<void>}
3392
+ */
3361
3393
  function loadScript(src) {
3362
3394
  if (typeof document === 'undefined') {
3363
3395
  return Promise.reject(new Error('loadScript: no document'))
@@ -3401,6 +3433,31 @@ function loadScript(src) {
3401
3433
  return p
3402
3434
  }
3403
3435
 
3436
+ /**
3437
+ * 拉取清单、合并 dev 映射、加载入口并执行 activator。
3438
+ * @module runtime/bootstrap-plugins
3439
+ */
3440
+
3441
+ /**
3442
+ * @param {import('./resolve-runtime-options.js').WebExtendPluginRuntimeOptions|object} opts
3443
+ */
3444
+ function shouldShowBootstrapSummary(opts) {
3445
+ if (opts.bootstrapSummary === true) {
3446
+ return true
3447
+ }
3448
+ if (opts.bootstrapSummary === false) {
3449
+ return false
3450
+ }
3451
+ const env = resolveBundledEnv('VITE_PLUGINS_BOOTSTRAP_SUMMARY', '');
3452
+ if (env === '0' || env === 'false') {
3453
+ return false
3454
+ }
3455
+ if (env === '1' || env === 'true') {
3456
+ return true
3457
+ }
3458
+ return resolveBundledIsDev()
3459
+ }
3460
+
3404
3461
  /**
3405
3462
  * @param {{ id: string }} p
3406
3463
  * @param {string} [entryUrl]
@@ -3439,29 +3496,30 @@ async function loadPluginEntry(p, entryUrl, devMap, hostSet) {
3439
3496
  /**
3440
3497
  * @param {import('vue-router').default} router
3441
3498
  * @param {(pluginId: string, router: import('vue-router').default, hostKit?: { bridgeAllowedPathPrefixes: string[] }) => object} createHostApiFactory
3442
- * 始终传入三个参数;单参工厂 `(id) => createHostApi(id, router)` 仍可用,后两个实参被忽略。
3443
- * @param {WebExtendPluginRuntimeOptions} [runtimeOptions]
3499
+ * @param {import('./resolve-runtime-options.js').WebExtendPluginRuntimeOptions} [runtimeOptions]
3444
3500
  */
3445
- async function bootstrapPlugins(router, createHostApiFactory, runtimeOptions) {
3501
+ async function bootstrapPlugins$1(router, createHostApiFactory, runtimeOptions) {
3446
3502
  if (typeof window === 'undefined') {
3447
3503
  console.warn('[plugins] bootstrapPlugins skipped: requires browser (window)');
3448
3504
  return
3449
3505
  }
3450
- const opts = resolveRuntimeOptions(runtimeOptions || {});
3506
+ const opts = resolveRuntimeOptions$1(runtimeOptions || {});
3451
3507
  const base = String(opts.manifestBase).replace(/\/$/, '');
3452
3508
  const manifestUrl = `${base}${opts.manifestListPath}`;
3453
3509
  const hostSet = buildAllowedScriptHostsSet(opts.allowedScriptHosts);
3454
3510
  const explicit = parseWebPluginDevMapExplicit(opts);
3455
3511
 
3512
+ const manifestCtx = {
3513
+ manifestUrl,
3514
+ credentials: opts.manifestFetchCredentials
3515
+ };
3456
3516
  const [manifestResult, implicit] = await Promise.all([
3457
3517
  (async () => {
3458
3518
  try {
3459
- const res = await fetch(manifestUrl, { credentials: opts.manifestFetchCredentials });
3460
- if (!res.ok) {
3461
- return { ok: false, status: res.status, data: null }
3519
+ if (typeof opts.fetchManifest === 'function') {
3520
+ return await opts.fetchManifest(manifestCtx)
3462
3521
  }
3463
- const data = await res.json();
3464
- return { ok: true, data }
3522
+ return await defaultFetchWebPluginManifest$1(manifestCtx)
3465
3523
  } catch (e) {
3466
3524
  return { ok: false, error: e, data: null }
3467
3525
  }
@@ -3565,6 +3623,240 @@ async function bootstrapPlugins(router, createHostApiFactory, runtimeOptions) {
3565
3623
  }
3566
3624
  }
3567
3625
 
3626
+ /**
3627
+ * 宿主侧插件引导:拉取清单、dev 映射、加载入口脚本、调用 activator。
3628
+ * 实现已拆至 `src/runtime/` 下各模块;本文件保留模块说明与对外类型约定,并 re-export 稳定 API。
3629
+ *
3630
+ * **Webpack 宿主**:用 `DefinePlugin` 注入 `process.env.VITE_*` 或 **`PLUGIN_*`**(等价键),或 `resolveRuntimeOptions` 显式传参。
3631
+ * **Vite 宿主**:入口调用 `setWebExtendPluginEnv(import.meta.env)`,或 `installWebExtendPluginVue2(..., { env: import.meta.env })`。
3632
+ *
3633
+ * @module PluginRuntime
3634
+ */
3635
+
3636
+ var pluginRuntime = /*#__PURE__*/Object.freeze({
3637
+ __proto__: null,
3638
+ bootstrapPlugins: bootstrapPlugins$1,
3639
+ defaultFetchWebPluginManifest: defaultFetchWebPluginManifest$1,
3640
+ resolveRuntimeOptions: resolveRuntimeOptions$1
3641
+ });
3642
+
3643
+ /**
3644
+ * 清单拉取函数的组合工具:缓存、埋点等以**中间件**形式扩展,不侵入 `bootstrapPlugins` 核心逻辑,
3645
+ * 符合第三方依赖「可组合、可替换」约定。契约与 `PluginRuntime` 中 `fetchManifest` 一致。
3646
+ *
3647
+ * @module runtime/manifest-fetch-composer
3648
+ */
3649
+
3650
+ /**
3651
+ * @typedef {object} FetchWebPluginManifestContext
3652
+ * @property {string} manifestUrl
3653
+ * @property {RequestCredentials} credentials
3654
+ */
3655
+
3656
+ /**
3657
+ * @typedef {object} FetchWebPluginManifestResult
3658
+ * @property {boolean} ok
3659
+ * @property {number} [status]
3660
+ * @property {{ hostPluginApiVersion?: string, plugins?: object[] }|null} [data]
3661
+ * @property {unknown} [error]
3662
+ */
3663
+
3664
+ /**
3665
+ * @callback FetchWebPluginManifestFn
3666
+ * @param {FetchWebPluginManifestContext} ctx
3667
+ * @returns {Promise<FetchWebPluginManifestResult>}
3668
+ */
3669
+
3670
+ /**
3671
+ * 将内层 `fetchManifest` 包装为带缓存的版本。等价于
3672
+ * `composeManifestFetch(inner, manifestFetchCacheMiddleware(options))`。
3673
+ *
3674
+ * @param {FetchWebPluginManifestFn} inner 内层实现(如预设生成的 `fetchManifest` 或 `defaultFetchWebPluginManifest`)
3675
+ * @param {ManifestFetchCacheOptions} [options]
3676
+ * @returns {FetchWebPluginManifestFn}
3677
+ */
3678
+ function wrapManifestFetchWithCache$1(inner, options = {}) {
3679
+ return composeManifestFetch$1(inner, manifestFetchCacheMiddleware$1(options))
3680
+ }
3681
+
3682
+ /**
3683
+ * @typedef {object} ManifestFetchCacheOptions
3684
+ * @property {number} [ttlMs] 缓存时长(毫秒)。`<= 0` 或未传时**不缓存**(直接透传 `inner`)。
3685
+ * @property {'memory'|'session'|'local'} [storage='memory'] `session`/`local` 依赖 `JSON.stringify`,仅适合可序列化的 `data`。
3686
+ * @property {string} [storageKeyPrefix='wep.manifestFetch.v1'] Web Storage 键前缀(仅 storage 非 memory 时生效)。
3687
+ * @property {(ctx: FetchWebPluginManifestContext) => string} [cacheKey] 默认 `manifestUrl + '\0' + credentials`。
3688
+ * @property {(result: FetchWebPluginManifestResult) => boolean} [shouldCache] 默认:`ok === true` 且 `data` 非空。
3689
+ * @property {number} [maxEntries=50] 仅 `memory`:超过条数时淘汰最久未读条目。
3690
+ * @property {() => number} [now] 测试注入时间戳。
3691
+ */
3692
+
3693
+ /**
3694
+ * 清单拉取**中间件工厂**:`next` 为内层 `fetchManifest`。
3695
+ *
3696
+ * @param {ManifestFetchCacheOptions} options
3697
+ * @returns {(next: FetchWebPluginManifestFn) => FetchWebPluginManifestFn}
3698
+ */
3699
+ function manifestFetchCacheMiddleware$1(options = {}) {
3700
+ const ttlMs = typeof options.ttlMs === 'number' && Number.isFinite(options.ttlMs) ? options.ttlMs : 0;
3701
+ if (ttlMs <= 0) {
3702
+ return (next) => next
3703
+ }
3704
+
3705
+ const storage = options.storage || 'memory';
3706
+ const prefix = options.storageKeyPrefix || 'wep.manifestFetch.v1';
3707
+ const maxEntries = typeof options.maxEntries === 'number' && options.maxEntries > 0 ? options.maxEntries : 50;
3708
+ const getNow = typeof options.now === 'function' ? options.now : () => Date.now();
3709
+ const cacheKeyFn =
3710
+ typeof options.cacheKey === 'function'
3711
+ ? options.cacheKey
3712
+ : (ctx) => `${String(ctx.manifestUrl)}\0${String(ctx.credentials)}`;
3713
+
3714
+ const shouldCache =
3715
+ typeof options.shouldCache === 'function'
3716
+ ? options.shouldCache
3717
+ : (r) => !!(r && r.ok === true && r.data != null);
3718
+
3719
+ /** @type {Map<string, { expiresAt: number, result: FetchWebPluginManifestResult, lastRead: number }>} */
3720
+ const memory = new Map();
3721
+
3722
+ function cloneResult(r) {
3723
+ try {
3724
+ if (typeof structuredClone === 'function') {
3725
+ return structuredClone(r)
3726
+ }
3727
+ } catch (_) {}
3728
+ try {
3729
+ return JSON.parse(JSON.stringify(r))
3730
+ } catch (_) {
3731
+ return { ...r, data: r.data }
3732
+ }
3733
+ }
3734
+
3735
+ function touchMemory(key) {
3736
+ const e = memory.get(key);
3737
+ if (e) {
3738
+ e.lastRead = getNow();
3739
+ }
3740
+ }
3741
+
3742
+ function pruneMemory() {
3743
+ if (memory.size <= maxEntries) {
3744
+ return
3745
+ }
3746
+ const entries = [...memory.entries()].sort((a, b) => a[1].lastRead - b[1].lastRead);
3747
+ const drop = memory.size - maxEntries;
3748
+ for (let i = 0; i < drop; i++) {
3749
+ memory.delete(entries[i][0]);
3750
+ }
3751
+ }
3752
+
3753
+ function readWebStorage(store, key) {
3754
+ try {
3755
+ const raw = store.getItem(key);
3756
+ if (!raw) {
3757
+ return null
3758
+ }
3759
+ const o = JSON.parse(raw);
3760
+ if (!o || typeof o !== 'object') {
3761
+ return null
3762
+ }
3763
+ const exp = o.expiresAt;
3764
+ const res = o.result;
3765
+ if (typeof exp !== 'number' || getNow() > exp) {
3766
+ store.removeItem(key);
3767
+ return null
3768
+ }
3769
+ return /** @type {FetchWebPluginManifestResult} */ (res)
3770
+ } catch (_) {
3771
+ return null
3772
+ }
3773
+ }
3774
+
3775
+ function writeWebStorage(store, key, result, expiresAt) {
3776
+ try {
3777
+ store.setItem(key, JSON.stringify({ expiresAt, result }));
3778
+ } catch (_) {
3779
+ /* Quota / 不可序列化 */
3780
+ }
3781
+ }
3782
+
3783
+ return (next) => {
3784
+ return async (ctx) => {
3785
+ const key = cacheKeyFn(ctx);
3786
+ const now = getNow();
3787
+
3788
+ if (storage === 'memory') {
3789
+ const hit = memory.get(key);
3790
+ if (hit && hit.expiresAt > now) {
3791
+ touchMemory(key);
3792
+ return cloneResult(hit.result)
3793
+ }
3794
+ } else if (storage === 'session' && typeof sessionStorage !== 'undefined') {
3795
+ const sk = `${prefix}:${key}`;
3796
+ const hit = readWebStorage(sessionStorage, sk);
3797
+ if (hit) {
3798
+ return cloneResult(hit)
3799
+ }
3800
+ } else if (storage === 'local' && typeof localStorage !== 'undefined') {
3801
+ const sk = `${prefix}:${key}`;
3802
+ const hit = readWebStorage(localStorage, sk);
3803
+ if (hit) {
3804
+ return cloneResult(hit)
3805
+ }
3806
+ }
3807
+
3808
+ const result = await next(ctx);
3809
+
3810
+ if (!shouldCache(result)) {
3811
+ return result
3812
+ }
3813
+
3814
+ const expiresAt = now + ttlMs;
3815
+ const frozen = cloneResult(result);
3816
+
3817
+ if (storage === 'memory') {
3818
+ memory.set(key, { expiresAt, result: frozen, lastRead: now });
3819
+ pruneMemory();
3820
+ } else if (storage === 'session' && typeof sessionStorage !== 'undefined') {
3821
+ writeWebStorage(sessionStorage, `${prefix}:${key}`, frozen, expiresAt);
3822
+ } else if (storage === 'local' && typeof localStorage !== 'undefined') {
3823
+ writeWebStorage(localStorage, `${prefix}:${key}`, frozen, expiresAt);
3824
+ }
3825
+
3826
+ return result
3827
+ }
3828
+ }
3829
+ }
3830
+
3831
+ /**
3832
+ * 自右向左组合中间件(与 Koa/Redux 习惯一致:`compose(f,g,h)(inner)` = f(g(h(inner))))。
3833
+ *
3834
+ * @param {FetchWebPluginManifestFn} inner 最内层拉取实现
3835
+ * @param {...function(FetchWebPluginManifestFn): FetchWebPluginManifestFn} middlewares 每个元素签名 `(next) => async (ctx) => result`
3836
+ * @returns {FetchWebPluginManifestFn}
3837
+ */
3838
+ function composeManifestFetch$1(inner, ...middlewares) {
3839
+ if (typeof inner !== 'function') {
3840
+ throw new Error('[web-extend-plugin-vue2] composeManifestFetch 需要 inner 为函数')
3841
+ }
3842
+ let f = inner;
3843
+ for (let i = middlewares.length - 1; i >= 0; i--) {
3844
+ const mw = middlewares[i];
3845
+ if (typeof mw !== 'function') {
3846
+ throw new Error('[web-extend-plugin-vue2] composeManifestFetch 中间件须为函数')
3847
+ }
3848
+ f = mw(f);
3849
+ }
3850
+ return f
3851
+ }
3852
+
3853
+ var manifestComposer = /*#__PURE__*/Object.freeze({
3854
+ __proto__: null,
3855
+ composeManifestFetch: composeManifestFetch$1,
3856
+ manifestFetchCacheMiddleware: manifestFetchCacheMiddleware$1,
3857
+ wrapManifestFetchWithCache: wrapManifestFetchWithCache$1
3858
+ });
3859
+
3568
3860
  /**
3569
3861
  * 插件通过宿主访问后端的受控通道:仅允许配置的前缀路径,默认 `/api/`;强制默认 `same-origin` 携带 Cookie。
3570
3862
  * 前缀列表由 `createRequestBridge({ allowedPathPrefixes })` 传入,与 `defaultWebExtendPluginRuntime.bridgeAllowedPathPrefixes` 对齐。
@@ -3572,17 +3864,6 @@ async function bootstrapPlugins(router, createHostApiFactory, runtimeOptions) {
3572
3864
  * @module bridge
3573
3865
  */
3574
3866
 
3575
- /**
3576
- * @param {string} p
3577
- */
3578
- function ensureLeadingSlash(p) {
3579
- const t = String(p || '').trim();
3580
- if (!t) {
3581
- return '/'
3582
- }
3583
- return t.startsWith('/') ? t : `/${t}`
3584
- }
3585
-
3586
3867
  /**
3587
3868
  * @param {{ allowedPathPrefixes?: string[] }} [config]
3588
3869
  */
@@ -3591,7 +3872,7 @@ function createRequestBridge(config = {}) {
3591
3872
  Array.isArray(config.allowedPathPrefixes) && config.allowedPathPrefixes.length > 0
3592
3873
  ? config.allowedPathPrefixes
3593
3874
  : defaultWebExtendPluginRuntime.bridgeAllowedPathPrefixes;
3594
- const allowedPathPrefixes = raw.map((p) => ensureLeadingSlash(p));
3875
+ const allowedPathPrefixes = raw.map((p) => ensureLeadingPath(p));
3595
3876
 
3596
3877
  return {
3597
3878
  /**
@@ -4012,9 +4293,215 @@ function installWebExtendPluginVue2(Vue, router, options) {
4012
4293
  if (Vue && ExtensionPoint) {
4013
4294
  Vue.component('ExtensionPoint', ExtensionPoint);
4014
4295
  }
4015
- const runtime = resolveRuntimeOptions(runtimeUser);
4016
- return bootstrapPlugins(router, (id, r, kit) => createHostApi(id, r, kit), runtime)
4296
+ const runtime = resolveRuntimeOptions$1(runtimeUser);
4297
+ return bootstrapPlugins$1(router, (id, r, kit) => createHostApi(id, r, kit), runtime)
4298
+ }
4299
+
4300
+ /**
4301
+ * 预设:Vue CLI + 统一 axios(如若依 `utils/request`)。
4302
+ * 对外以 {@link presetVueCliAxios} 聚合;亦保留具名函数便于 tree-shaking。
4303
+ *
4304
+ * @module presets/vue-cli-axios
4305
+ */
4306
+
4307
+ /**
4308
+ * @typedef {object} VueCliAxiosInstallPresetDeps
4309
+ * @property {(config: { url: string, method?: string, [key: string]: unknown }) => Promise<unknown>} request 宿主 axios 封装(已含 baseURL、Token 等)
4310
+ */
4311
+
4312
+ /**
4313
+ * 将 `manifestBase + manifestListPath` 转为相对 `VUE_APP_BASE_API` 的路径(供 axios baseURL 拼接)。
4314
+ * @param {string} manifestUrl
4315
+ * @param {string} [apiBase]
4316
+ */
4317
+ function manifestPathForVueCliApiBase(manifestUrl, apiBase) {
4318
+ const base = String(
4319
+ apiBase !== undefined
4320
+ ? apiBase
4321
+ : (typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API) || ''
4322
+ ).replace(/\/$/, '');
4323
+ if (typeof window === 'undefined') {
4324
+ return '/api/frontend-plugins'
4325
+ }
4326
+ const u = new URL(manifestUrl, window.location.origin);
4327
+ let path = u.pathname + u.search;
4328
+ if (base && path.startsWith(base)) {
4329
+ path = path.slice(base.length) || '/';
4330
+ }
4331
+ return path
4332
+ }
4333
+
4334
+ /**
4335
+ * 兼容裸清单 JSON 与常见 `{ code, data: { plugins } }` 包装。
4336
+ * @param {unknown} body
4337
+ * @returns {object|null}
4338
+ */
4339
+ function unwrapTableStyleManifestBody(body) {
4340
+ if (!body || typeof body !== 'object') {
4341
+ return null
4342
+ }
4343
+ const o = /** @type {Record<string, unknown>} */ (body);
4344
+ if (Array.isArray(o.plugins)) {
4345
+ return o
4346
+ }
4347
+ const d = o.data;
4348
+ if (d && typeof d === 'object') {
4349
+ const inner = /** @type {Record<string, unknown>} */ (d);
4350
+ if (Array.isArray(inner.plugins)) {
4351
+ return inner
4352
+ }
4353
+ if ('plugins' in inner) {
4354
+ return inner
4355
+ }
4356
+ }
4357
+ return d !== undefined && d !== null && typeof d === 'object' ? /** @type {object} */ (d) : o
4358
+ }
4359
+
4360
+ function bridgePrefixesFromVueCliEnv() {
4361
+ const base = (
4362
+ typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API
4363
+ ? String(process.env.VUE_APP_BASE_API)
4364
+ : ''
4365
+ ).replace(/\/$/, '');
4366
+ const raw = [base ? `${base}/` : '', '/api/', '/dev-api/'].filter(Boolean);
4367
+ return [...new Set(raw)]
4368
+ }
4369
+
4370
+ /**
4371
+ * 生成可直接传给 `installWebExtendPluginVue2` 的 options(含 fetchManifest、manifestBase、bridge 前缀)。
4372
+ * @param {VueCliAxiosInstallPresetDeps} deps
4373
+ * @param {Record<string, unknown>} [extra] 合并覆盖,如 `manifestListPath`、`env` 等
4374
+ * @returns {Record<string, unknown>}
4375
+ */
4376
+ function createVueCliAxiosInstallOptions(deps, extra = {}) {
4377
+ const { request } = deps;
4378
+ if (typeof request !== 'function') {
4379
+ throw new Error('[web-extend-plugin-vue2] createVueCliAxiosInstallOptions({ request }) 需要宿主 request 函数')
4380
+ }
4381
+ const envBase = (
4382
+ typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API
4383
+ ? String(process.env.VUE_APP_BASE_API)
4384
+ : ''
4385
+ ).replace(/\/$/, '');
4386
+ const userBase =
4387
+ extra.manifestBase !== undefined && String(extra.manifestBase).trim() !== ''
4388
+ ? String(extra.manifestBase).replace(/\/$/, '')
4389
+ : '';
4390
+ const stripBase = userBase || envBase;
4391
+
4392
+ const fetchManifest = async (ctx) => {
4393
+ try {
4394
+ const url = manifestPathForVueCliApiBase(ctx.manifestUrl, stripBase);
4395
+ const body = await request({
4396
+ url,
4397
+ method: 'get'
4398
+ });
4399
+ const data = unwrapTableStyleManifestBody(body);
4400
+ if (!data || typeof data !== 'object') {
4401
+ return {
4402
+ ok: false,
4403
+ error: new Error('[web-plugin] 清单响应格式无效'),
4404
+ data: null
4405
+ }
4406
+ }
4407
+ return { ok: true, data }
4408
+ } catch (e) {
4409
+ return { ok: false, error: e, data: null }
4410
+ }
4411
+ };
4412
+
4413
+ const opts = {
4414
+ manifestBase: stripBase || undefined,
4415
+ bridgeAllowedPathPrefixes: bridgePrefixesFromVueCliEnv(),
4416
+ fetchManifest,
4417
+ ...extra
4418
+ };
4419
+
4420
+ const listPath =
4421
+ typeof process !== 'undefined' && process.env && process.env.VUE_APP_WEB_PLUGIN_MANIFEST_PATH;
4422
+ if (listPath && opts.manifestListPath === undefined && extra.manifestListPath === undefined) {
4423
+ opts.manifestListPath = String(listPath);
4424
+ }
4425
+
4426
+ return opts
4017
4427
  }
4018
4428
 
4019
- export { ExtensionPoint, HOST_PLUGIN_API_VERSION, bootstrapPlugins, createHostApi, createRequestBridge, defaultWebExtendPluginRuntime, disposeWebPlugin, installWebExtendPluginVue2, registries, resolveRuntimeOptions, setWebExtendPluginEnv };
4429
+ /**
4430
+ * Vue CLI + axios 预设的**对外聚合入口**(与具名导出函数等价,便于按需查阅与扩展多预设)。
4431
+ * @type {Readonly<{ id: string, description: string, createInstallOptions: typeof createVueCliAxiosInstallOptions, manifestPathForApiBase: typeof manifestPathForVueCliApiBase, unwrapManifestBody: typeof unwrapTableStyleManifestBody }>}
4432
+ */
4433
+ const presetVueCliAxios = Object.freeze({
4434
+ id: 'vue-cli-axios',
4435
+ description: 'Vue CLI + 统一 axios 实例(如若依 utils/request),清单走宿主 request',
4436
+ createInstallOptions: createVueCliAxiosInstallOptions,
4437
+ manifestPathForApiBase: manifestPathForVueCliApiBase,
4438
+ unwrapManifestBody: unwrapTableStyleManifestBody
4439
+ });
4440
+
4441
+ /**
4442
+ * 稳定对外 API:具名导出 + {@link WebExtendPluginVue2} 聚合对象。
4443
+ * 语义化版本内保持本文件导出的符号与聚合结构兼容。
4444
+ *
4445
+ * `PluginRuntime` 与 `manifest-fetch-composer` 通过 namespace 绑定到 `WebExtendPluginVue2.runtime`,避免具名导出与聚合对象重复列举。
4446
+ *
4447
+ * @module public
4448
+ */
4449
+
4450
+
4451
+ const {
4452
+ bootstrapPlugins,
4453
+ defaultFetchWebPluginManifest,
4454
+ resolveRuntimeOptions
4455
+ } = pluginRuntime;
4456
+
4457
+ const {
4458
+ composeManifestFetch,
4459
+ manifestFetchCacheMiddleware,
4460
+ wrapManifestFetchWithCache
4461
+ } = manifestComposer;
4462
+
4463
+ /**
4464
+ * 根命名空间:宿主可通过 `WebExtendPluginVue2.presets.vueCliAxios` 等路径发现能力,避免仅依赖散落的具名导出。
4465
+ * @type {Readonly<{
4466
+ * install: typeof installWebExtendPluginVue2,
4467
+ * runtime: Readonly<{ bootstrapPlugins: typeof pluginRuntime.bootstrapPlugins, resolveRuntimeOptions: typeof pluginRuntime.resolveRuntimeOptions, defaultFetchWebPluginManifest: typeof pluginRuntime.defaultFetchWebPluginManifest, composeManifestFetch: typeof manifestComposer.composeManifestFetch, manifestFetchCacheMiddleware: typeof manifestComposer.manifestFetchCacheMiddleware, wrapManifestFetchWithCache: typeof manifestComposer.wrapManifestFetchWithCache }>,
4468
+ * host: Readonly<{ createHostApi: typeof createHostApi, disposeWebPlugin: typeof disposeWebPlugin, createRequestBridge: typeof createRequestBridge, registries: typeof registries }>,
4469
+ * config: Readonly<{ defaultWebExtendPluginRuntime: typeof defaultWebExtendPluginRuntime, setWebExtendPluginEnv: typeof setWebExtendPluginEnv }>,
4470
+ * constants: Readonly<{ HOST_PLUGIN_API_VERSION: typeof HOST_PLUGIN_API_VERSION }>,
4471
+ * components: Readonly<{ ExtensionPoint: typeof ExtensionPoint }>,
4472
+ * presets: Readonly<{ vueCliAxios: typeof presetVueCliAxios }>
4473
+ * }>}
4474
+ */
4475
+ const WebExtendPluginVue2 = Object.freeze({
4476
+ install: installWebExtendPluginVue2,
4477
+ runtime: Object.freeze({
4478
+ bootstrapPlugins: bootstrapPlugins$1,
4479
+ resolveRuntimeOptions: resolveRuntimeOptions$1,
4480
+ defaultFetchWebPluginManifest: defaultFetchWebPluginManifest$1,
4481
+ composeManifestFetch: composeManifestFetch$1,
4482
+ manifestFetchCacheMiddleware: manifestFetchCacheMiddleware$1,
4483
+ wrapManifestFetchWithCache: wrapManifestFetchWithCache$1
4484
+ }),
4485
+ host: Object.freeze({
4486
+ createHostApi,
4487
+ disposeWebPlugin,
4488
+ createRequestBridge,
4489
+ registries
4490
+ }),
4491
+ config: Object.freeze({
4492
+ defaultWebExtendPluginRuntime,
4493
+ setWebExtendPluginEnv
4494
+ }),
4495
+ constants: Object.freeze({
4496
+ HOST_PLUGIN_API_VERSION
4497
+ }),
4498
+ components: Object.freeze({
4499
+ ExtensionPoint
4500
+ }),
4501
+ presets: Object.freeze({
4502
+ vueCliAxios: presetVueCliAxios
4503
+ })
4504
+ });
4505
+
4506
+ export { ExtensionPoint, HOST_PLUGIN_API_VERSION, WebExtendPluginVue2, bootstrapPlugins, composeManifestFetch, createHostApi, createRequestBridge, createVueCliAxiosInstallOptions, defaultFetchWebPluginManifest, defaultWebExtendPluginRuntime, disposeWebPlugin, installWebExtendPluginVue2, manifestFetchCacheMiddleware, manifestPathForVueCliApiBase, presetVueCliAxios, registries, resolveRuntimeOptions, setWebExtendPluginEnv, unwrapTableStyleManifestBody, wrapManifestFetchWithCache };
4020
4507
  //# sourceMappingURL=index.mjs.map