vite-add-cdn-script 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -1,22 +1,23 @@
1
- var D = Object.defineProperty;
2
- var F = (n, t, e) => t in n ? D(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
3
- var f = (n, t, e) => (F(n, typeof t != "symbol" ? t + "" : t, e), e);
4
- import J from "node:path";
5
- import j from "node:fs";
6
- import E from "node:https";
7
- class L {
1
+ var G = Object.defineProperty;
2
+ var B = (r, t, e) => t in r ? G(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var m = (r, t, e) => (B(r, typeof t != "symbol" ? t + "" : t, e), e);
4
+ import O from "node:path";
5
+ import U from "node:fs";
6
+ import V from "node-fetch";
7
+ import J from "semver";
8
+ class z {
8
9
  constructor() {
9
- f(this, "cdnCache", {});
10
- f(this, "cdnCachePath", "");
11
- this.cdnCachePath = J.resolve(process.cwd(), "./.cdn-cache.json");
10
+ m(this, "cdnCache", {});
11
+ m(this, "cdnCachePath", "");
12
+ this.cdnCachePath = O.resolve(process.cwd(), "./.cdn-cache.json");
12
13
  }
13
14
  // 初始化cdn缓存
14
15
  async init() {
15
16
  try {
16
- const t = await j.readFileSync(this.cdnCachePath, "utf-8");
17
+ const t = await U.readFileSync(this.cdnCachePath, "utf-8");
17
18
  this.cdnCache = JSON.parse(t);
18
19
  } catch {
19
- console.log("cdn缓存文件不存在,创建缓存文件"), this.cdnCache = {}, await j.writeFileSync(this.cdnCachePath, "", "utf-8");
20
+ console.log("cdn缓存文件不存在,创建缓存文件"), this.cdnCache = {}, await U.writeFileSync(this.cdnCachePath, "", "utf-8");
20
21
  }
21
22
  }
22
23
  /**
@@ -25,8 +26,8 @@ class L {
25
26
  * @param version 版本
26
27
  */
27
28
  getCdnCache(t, e) {
28
- var r;
29
- return (r = this.cdnCache[t]) == null ? void 0 : r[e];
29
+ var s;
30
+ return (s = this.cdnCache[t]) == null ? void 0 : s[e];
30
31
  }
31
32
  /**
32
33
  * 设置cdn缓存
@@ -34,25 +35,45 @@ class L {
34
35
  * @param version 版本
35
36
  * @param urls 地址列表
36
37
  */
37
- setCdnCache(t, e, r) {
38
- this.cdnCache[t] ? this.cdnCache[t][e] = r : this.cdnCache[t] = {
39
- [e]: r
38
+ setCdnCache(t, e, s) {
39
+ this.cdnCache[t] ? this.cdnCache[t][e] = s : this.cdnCache[t] = {
40
+ [e]: s
40
41
  };
41
42
  }
42
43
  /**
43
44
  * 更新cdn缓存
44
45
  */
45
46
  async save() {
46
- await j.writeFileSync(this.cdnCachePath, JSON.stringify(this.cdnCache), "utf-8");
47
+ await U.writeFileSync(this.cdnCachePath, JSON.stringify(this.cdnCache), "utf-8");
47
48
  }
48
49
  }
49
- let y;
50
- const I = async () => (y || (y = new L(), await y.init()), y);
51
- class N {
50
+ let b;
51
+ const K = async () => (b || (b = new z(), await b.init()), b);
52
+ class u extends Error {
52
53
  constructor(t) {
53
- f(this, "_max");
54
- f(this, "_count");
55
- f(this, "_taskQueue");
54
+ super(t), this.name = "NetworkError";
55
+ }
56
+ }
57
+ class C extends u {
58
+ constructor({ packageName: t, version: e, cdn: s }) {
59
+ super(`${s} ${t}@${e} 网络请求失败`), this.name = "PackageNetworkError";
60
+ }
61
+ }
62
+ class $ extends Error {
63
+ constructor({ packageName: t, version: e, cdn: s }) {
64
+ super(`${s}上没有${t}@${e}的版本`), this.name = "NoVersionError";
65
+ }
66
+ }
67
+ class W extends Error {
68
+ constructor({ packageName: t, version: e, cdn: s }) {
69
+ super(`在 ${s} 中找不到 ${t}@${e} 文件,请检查包名或版本号`), this.name = "GetFileListError";
70
+ }
71
+ }
72
+ class X {
73
+ constructor(t) {
74
+ m(this, "_max");
75
+ m(this, "_count");
76
+ m(this, "_taskQueue");
56
77
  this._max = t || 5, this._count = 0, this._taskQueue = [];
57
78
  }
58
79
  /**
@@ -62,9 +83,9 @@ class N {
62
83
  * @returns {Promise<any>} 返回一个promise
63
84
  */
64
85
  call(t, ...e) {
65
- return new Promise((r, s) => {
66
- const c = this._createTask(t, e, r, s);
67
- this._count >= this._max ? this._taskQueue.push(c) : c();
86
+ return new Promise((s, n) => {
87
+ const o = this._createTask(t, e, s, n);
88
+ this._count >= this._max ? this._taskQueue.push(o) : o();
68
89
  });
69
90
  }
70
91
  /**
@@ -76,138 +97,217 @@ class N {
76
97
  * @returns {Function} 返回一个任务函数
77
98
  * @private
78
99
  */
79
- _createTask(t, e, r, s) {
100
+ _createTask(t, e, s, n) {
80
101
  return () => {
81
- t(...e).then(r).catch(s).finally(() => {
102
+ t(...e).then(s).catch(n).finally(() => {
82
103
  this._count--, this._taskQueue.length && this._taskQueue.shift()();
83
104
  }), this._count++;
84
105
  };
85
106
  }
86
107
  }
87
- const U = new N(5), R = {
108
+ const D = new X(5), M = async (r) => {
109
+ try {
110
+ const t = await V(r, { method: "HEAD", redirect: "manual" });
111
+ return t.status >= 300 && t.status < 400 ? await M(t.headers.get("location") || "") : r;
112
+ } catch (t) {
113
+ throw Promise.reject(new u(t.message));
114
+ }
115
+ }, Y = {
88
116
  //get请求封装
89
- get: (n, t, e) => new Promise((r, s) => {
117
+ get: async (r) => {
90
118
  try {
91
- E.get(n, (c) => {
92
- let i = "";
93
- c.on("data", (o) => {
94
- i += o;
95
- }), c.on("end", () => {
96
- t == null || t(i), r(i);
97
- });
98
- }).on("error", function(c) {
99
- e == null || e(c), s(c);
119
+ const t = await V(r);
120
+ if (t.ok) {
121
+ const e = t.headers.get("content-type"), s = await t.text();
122
+ return e && e.includes("application/json") ? JSON.parse(s) : s;
123
+ } else
124
+ throw new u(`请求失败,状态码:${t.status}`);
125
+ } catch (t) {
126
+ throw new u(t.message);
127
+ }
128
+ }
129
+ }, y = {
130
+ get: D.call.bind(D, Y.get)
131
+ }, Z = async (r, t) => {
132
+ try {
133
+ const e = await y.get(`https://api.bootcdn.cn/libraries/${r}`);
134
+ if (e.length === 0)
135
+ throw new $({
136
+ packageName: r,
137
+ version: t,
138
+ cdn: "bootcdn"
139
+ });
140
+ const s = e[0], o = s.assets.reverse().find((c) => {
141
+ if (J.satisfies(c.version, t))
142
+ return !0;
143
+ });
144
+ if (!o)
145
+ throw new $({
146
+ packageName: r,
147
+ version: t,
148
+ cdn: "bootcdn"
149
+ });
150
+ return { fileList: o.files.map((c) => ({
151
+ name: "/" + c
152
+ })), recommendFileName: s.filename, version: o.version };
153
+ } catch (e) {
154
+ throw e instanceof u ? new C({
155
+ packageName: r,
156
+ version: t,
157
+ cdn: "unpkg"
158
+ }) : e;
159
+ }
160
+ }, N = (r, t, e) => `https://cdn.bootcdn.net/ajax/libs/${r}/${t}${e}`, tt = {
161
+ getFileList: Z,
162
+ getUrl: N
163
+ };
164
+ async function I(r, t, e = !1) {
165
+ try {
166
+ if (!e && t.match(/^\D/)) {
167
+ const n = await rt(r, t);
168
+ for (let o of n)
169
+ if (J.satisfies(o, t))
170
+ return I(r, o, !0);
171
+ throw new $({
172
+ packageName: r,
173
+ version: t,
174
+ cdn: "cdnjs"
100
175
  });
101
- } catch (c) {
102
- e == null || e(c), s(c);
103
176
  }
104
- })
105
- }, w = {
106
- get: U.call.bind(U, R.get)
107
- }, A = {
108
- getFileList: (n, t) => new Promise((e, r) => {
109
- w.get(
110
- `https://api.bootcdn.cn/libraries/${n}`,
111
- (s) => {
112
- const c = JSON.parse(s);
113
- if (c.length === 0) {
114
- r(new Error(`${n} not found in bootcdn`));
115
- return;
116
- }
117
- const i = c[0], a = i.assets.find((d) => d.version === t);
118
- if (!a) {
119
- r(new Error(`${n}@${t} not found in ${i.name}`));
120
- return;
121
- }
122
- const l = a.files.map((d) => ({
123
- name: "/" + d
124
- }));
125
- e({ fileList: l, recommendFileName: i.filename });
126
- },
127
- (s) => {
128
- r(s);
129
- }
130
- );
131
- }),
132
- getUrl: (n, t, e) => `https://cdn.bootcdn.net/ajax/libs/${n}/${t}${e}`
133
- }, M = {
134
- getFileList: (n, t) => new Promise((e, r) => {
135
- w.get(
136
- `https://api.cdnjs.com/libraries/${n}/${t}`,
137
- (s) => {
138
- const c = JSON.parse(s);
139
- if (c.error) {
140
- r(new Error(`cdnjs: ${n}@${t} not found`));
141
- return;
142
- }
143
- e({
144
- fileList: c.rawFiles.map((i) => ({
145
- name: "/" + i
146
- }))
147
- });
148
- },
149
- (s) => {
150
- r(s);
151
- }
152
- );
153
- }),
154
- getUrl: (n, t, e) => `https://cdnjs.cloudflare.com/ajax/libs/${n}/${t}${e}`
155
- }, V = {
156
- getFileList: (n, t) => new Promise((e, r) => {
157
- w.get(
158
- `https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${t}/files`,
159
- (s) => {
160
- const c = JSON.parse(s);
161
- if (c.length === 0) {
162
- r(new Error(`${n}@${t} not found`));
163
- return;
164
- }
165
- e({ fileList: c });
166
- },
167
- (s) => {
168
- r(s);
169
- }
170
- );
171
- }),
177
+ const s = await y.get(`https://api.cdnjs.com/libraries/${r}/${t}`);
178
+ if (s.error)
179
+ throw new $({
180
+ packageName: r,
181
+ version: t,
182
+ cdn: "cdnjs"
183
+ });
184
+ return {
185
+ fileList: s.rawFiles.map((n) => ({
186
+ name: "/" + n
187
+ })),
188
+ version: t
189
+ };
190
+ } catch (s) {
191
+ throw s instanceof u ? new C({
192
+ packageName: r,
193
+ version: t,
194
+ cdn: "unpkg"
195
+ }) : s;
196
+ }
197
+ }
198
+ const et = (r, t, e) => `https://cdnjs.cloudflare.com/ajax/libs/${r}/${t}${e}`, rt = async (r, t) => {
199
+ try {
200
+ return (await y.get(`https://api.cdnjs.com/libraries/${r}?fields=versions`)).versions;
201
+ } catch (e) {
202
+ throw e instanceof u ? new C({
203
+ packageName: r,
204
+ version: t,
205
+ cdn: "unpkg"
206
+ }) : e;
207
+ }
208
+ }, st = {
209
+ getFileList: I,
210
+ getUrl: et
211
+ }, T = (r, t = "") => r.reduce((e, s) => (s.type === "file" ? e.push({ name: `${t}/${s.name}` }) : s.files && e.push(...T(s.files, `${t}/${s.name}`)), e), []);
212
+ async function Q(r, t, e = !1) {
213
+ try {
214
+ if (!e && t.match(/^\D/)) {
215
+ const n = await ot(r, t);
216
+ if (typeof n == "string")
217
+ return Q(r, n, !0);
218
+ throw new $({
219
+ packageName: r,
220
+ version: t,
221
+ cdn: "jsdelivr"
222
+ });
223
+ }
224
+ const s = await y.get(`https://data.jsdelivr.com/v1/packages/npm/${r}@${t}`);
225
+ if (s.status)
226
+ throw new $({
227
+ packageName: r,
228
+ version: t,
229
+ cdn: "jsdelivr"
230
+ });
231
+ return { fileList: T(s.files), version: t };
232
+ } catch (s) {
233
+ throw s instanceof u ? new C({
234
+ packageName: r,
235
+ version: t,
236
+ cdn: "unpkg"
237
+ }) : s;
238
+ }
239
+ }
240
+ const nt = (r, t, e) => `https://cdn.jsdelivr.net/npm/${r}@${t}${e}`, ot = async (r, t) => {
241
+ try {
242
+ return (await y.get(
243
+ `https://data.jsdelivr.com/v1/packages/npm/${r}/resolved?specifier=${t}`
244
+ )).version;
245
+ } catch (e) {
246
+ throw e instanceof u ? new C({
247
+ packageName: r,
248
+ version: t,
249
+ cdn: "unpkg"
250
+ }) : e;
251
+ }
252
+ }, ct = {
253
+ getFileList: Q,
172
254
  // 拼接url
173
- getUrl: (n, t, e) => `https://cdn.jsdelivr.net/npm/${n}@${t}${e}`
174
- }, b = (n) => n.reduce((t, e) => (e.type === "file" ? t.push({ name: e.path }) : e.files && t.push(...b(e.files)), t), []), T = {
175
- getFileList: (n, t) => new Promise((e, r) => {
176
- w.get(
177
- `https://unpkg.com/${n}@${t}/?meta`,
178
- (s) => {
179
- const c = JSON.parse(s);
180
- e({ fileList: b(c.files || []) });
181
- },
182
- (s) => {
183
- r(s);
184
- }
185
- );
186
- }),
187
- getUrl: (n, t, e) => `https://unpkg.com/${n}@${t}${e}`
188
- }, Q = async (n) => {
189
- const t = /^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;
190
- if (t.test(n)) {
191
- const e = n.replace(t, (r, s) => `${s}package.json`);
192
- return JSON.parse(await w.get(e));
193
- } else
194
- throw new Error(`${n} 不是正确的url`);
195
- }, q = (n, t) => {
196
- var e, r;
197
- return ((e = n.dependencies) == null ? void 0 : e[t]) || ((r = n.devDependencies) == null ? void 0 : r[t]);
198
- }, H = async (n, t, e) => {
199
- var i;
200
- const r = (i = t.match(/\d+(.\d+)?(.\d+)?/)) == null ? void 0 : i[0];
201
- if (!r)
202
- throw new Error(`${n} version ${t} is not valid`);
203
- const s = await v[e].getFileList(n, r).catch((o) => {
204
- throw console.log(o), new Error(`${n} ${t} ${e} API 请求失败`);
205
- }), c = B(s, n);
206
- if (!c)
207
- throw new Error(`在 ${e} 中找不到 ${n}@${r} 文件,请检查包名或版本号`);
208
- return v[e].getUrl(n, r, c);
209
- }, B = ({ fileList: n }, t) => {
210
- var c, i;
255
+ getUrl: nt
256
+ }, H = (r) => r.reduce((t, e) => (e.type === "file" ? t.push({ name: e.path }) : e.files && t.push(...H(e.files)), t), []);
257
+ async function it(r, t) {
258
+ var e;
259
+ try {
260
+ const n = (e = (await M(`https://unpkg.com/${r}@${t}/?meta`)).match(new RegExp("(?<=@)\\d+\\.\\d+\\.\\d+(?=\\/\\?meta)"))) == null ? void 0 : e[0];
261
+ if (n) {
262
+ const o = await y.get(`https://unpkg.com/${r}@${n}/?meta`);
263
+ return { fileList: H(o.files || []), version: n };
264
+ } else
265
+ throw new $({
266
+ packageName: r,
267
+ version: t,
268
+ cdn: "unpkg"
269
+ });
270
+ } catch (s) {
271
+ throw s instanceof u ? new C({
272
+ packageName: r,
273
+ version: t,
274
+ cdn: "unpkg"
275
+ }) : s;
276
+ }
277
+ }
278
+ function at(r, t, e) {
279
+ return `https://unpkg.com/${r}@${t}${e}`;
280
+ }
281
+ const lt = {
282
+ getFileList: it,
283
+ getUrl: at
284
+ }, ut = async (r) => {
285
+ try {
286
+ const t = /^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;
287
+ if (t.test(r)) {
288
+ const e = r.replace(t, (s, n) => `${n}package.json`);
289
+ return await y.get(e);
290
+ } else
291
+ throw new Error(`${r} 不是正确的url`);
292
+ } catch (t) {
293
+ throw t;
294
+ }
295
+ }, dt = (r, t) => {
296
+ var e, s;
297
+ return ((e = r.dependencies) == null ? void 0 : e[t]) || ((s = r.devDependencies) == null ? void 0 : s[t]);
298
+ }, ht = async (r, t, e) => {
299
+ if (!t.match(/\d+(.\d+)?(.\d+)?/))
300
+ throw new Error(`${r} version ${t} is not valid`);
301
+ const n = await R[e].getFileList(r, t), o = ft(n, r);
302
+ if (!o)
303
+ throw new W({
304
+ packageName: r,
305
+ version: t,
306
+ cdn: e
307
+ });
308
+ return R[e].getUrl(r, n.version, o);
309
+ }, ft = ({ fileList: r }, t) => {
310
+ var o, a;
211
311
  let e = [
212
312
  `umd/${t}.production.min.js`,
213
313
  /umd\/.+?\.production\.min\.js$/,
@@ -225,146 +325,211 @@ const U = new N(5), R = {
225
325
  /\.min\.js$/,
226
326
  /\.js$/
227
327
  ];
228
- const r = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((o) => !t.includes(o));
229
- let s = "";
230
- for (let o of e)
231
- if (o instanceof RegExp ? s = ((c = n.find((a) => o.test(a.name) && !r.some((l) => a.name.includes(l)))) == null ? void 0 : c.name) || "" : s = ((i = n.find((a) => a.name.includes(o) && !r.some((l) => a.name.includes(l)))) == null ? void 0 : i.name) || "", s)
328
+ const s = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((c) => !t.includes(c));
329
+ let n = "";
330
+ for (let c of e)
331
+ if (c instanceof RegExp ? n = ((o = r.find((i) => c.test(i.name) && !s.some((l) => i.name.includes(l)))) == null ? void 0 : o.name) || "" : n = ((a = r.find((i) => i.name.includes(c) && !s.some((l) => i.name.includes(l)))) == null ? void 0 : a.name) || "", n)
232
332
  break;
233
- return s;
234
- }, v = {
235
- jsdelivr: V,
236
- bootcdn: A,
237
- cdnjs: M,
238
- unpkg: T
333
+ return n;
334
+ }, R = {
335
+ jsdelivr: ct,
336
+ bootcdn: tt,
337
+ cdnjs: st,
338
+ unpkg: lt
239
339
  };
240
- function G(n, t) {
241
- const e = n.replace(/^\D/, "").split("."), r = t.replace(/^\D/, "").split("."), s = Math.max(e.length, r.length);
242
- for (; e.length < s; )
340
+ function pt(r, t) {
341
+ const e = r.replace(/^\D/, "").split("."), s = t.replace(/^\D/, "").split("."), n = Math.max(e.length, s.length);
342
+ for (; e.length < n; )
243
343
  e.push("0");
244
- for (; r.length < s; )
245
- r.push("0");
246
- for (let c = 0; c < s; c++) {
247
- const i = parseInt(e[c], 10), o = parseInt(r[c], 10);
248
- if (i > o)
344
+ for (; s.length < n; )
345
+ s.push("0");
346
+ for (let o = 0; o < n; o++) {
347
+ const a = parseInt(e[o], 10), c = parseInt(s[o], 10);
348
+ if (a > c)
249
349
  return 1;
250
- if (i < o)
350
+ if (a < c)
251
351
  return -1;
252
352
  }
253
353
  return 0;
254
354
  }
255
- function z(n, t) {
355
+ function wt(r, t) {
256
356
  for (let e in t)
257
- Object.prototype.hasOwnProperty.call(t, e) && (n[e] ? G(n[e], t[e]) === -1 && (n[e] = t[e]) : n[e] = t[e]);
258
- return n;
357
+ Object.prototype.hasOwnProperty.call(t, e) && (r[e] ? pt(r[e], t[e]) === -1 && (r[e] = t[e]) : r[e] = t[e]);
358
+ return r;
359
+ }
360
+ class gt {
361
+ constructor() {
362
+ // 打印记录
363
+ m(this, "logList", []);
364
+ }
365
+ // 打印方法
366
+ log(t) {
367
+ this.logList.push({
368
+ type: "log",
369
+ message: t
370
+ });
371
+ }
372
+ warn(t) {
373
+ this.logList.push({
374
+ type: "warn",
375
+ message: t
376
+ });
377
+ }
378
+ error(t) {
379
+ this.logList.push({
380
+ type: "error",
381
+ message: t
382
+ });
383
+ }
384
+ info(t) {
385
+ this.logList.push({
386
+ type: "info",
387
+ message: t
388
+ });
389
+ }
390
+ // 打印全部
391
+ consoleAll() {
392
+ this.logList.forEach((t) => {
393
+ console[t.type](`${q} ${t.message}`);
394
+ });
395
+ }
396
+ // 清除打印记录
397
+ clear() {
398
+ this.logList = [];
399
+ }
259
400
  }
260
- async function O({ external: n, packageData: t, customScript: e, defaultCdns: r }) {
261
- let s = [], c = !1;
262
- const i = await I();
401
+ const q = "vite-add-cdn-script", S = new gt();
402
+ async function A({
403
+ external: r,
404
+ packageData: t,
405
+ customScript: e,
406
+ defaultCdns: s
407
+ }) {
408
+ let n = [], o = !1;
409
+ const a = await K();
263
410
  return await Promise.all(
264
- n.map(async (o) => {
265
- const a = q(t, o);
266
- if (e[o])
411
+ r.map(async (c) => {
412
+ const i = dt(t, c);
413
+ if (e[c])
267
414
  return {
268
415
  urls: [],
269
- key: o
416
+ key: c
270
417
  };
271
- const l = i.getCdnCache(o, a);
272
- if (!a && !l)
273
- return s.push(o), {
418
+ if (!i)
419
+ return n.push(c), {
274
420
  urls: [],
275
- key: o
421
+ key: c
276
422
  };
423
+ const l = a.getCdnCache(c, i);
277
424
  if (l)
278
425
  return {
279
426
  urls: l,
280
- key: o
427
+ key: c
281
428
  };
282
429
  {
283
- c = !0, console.log(`从网络获取${o}${a}的cdn地址`);
430
+ o = !0, console.log(`从网络获取${c}${i}的cdn地址`);
431
+ const L = await Promise.allSettled(
432
+ s.map(async (w) => await ht(c, i, w))
433
+ ).then((w) => w.filter((f) => {
434
+ if (f.status === "fulfilled")
435
+ return f.value, !0;
436
+ S.warn(f.reason.toString());
437
+ }).map((f) => f.value));
438
+ if (L.length === 0)
439
+ throw new Error(`获取${c} ${i}的cdn地址失败`);
284
440
  const d = {
285
- urls: await Promise.all(
286
- r.map(async (C) => await H(o, a, C))
287
- ),
288
- key: o
441
+ urls: L,
442
+ key: c
289
443
  };
290
- return i.setCdnCache(o, a, d.urls), d;
444
+ return a.setCdnCache(c, i, d.urls), d;
291
445
  }
292
446
  })
293
- ).then((o) => (c && i.save(), {
294
- urls: o,
295
- noVersionPackages: s
447
+ ).then((c) => (o && a.save(), {
448
+ urls: c,
449
+ noVersionPackages: n
296
450
  }));
297
451
  }
298
- function tt(n) {
299
- const { customScript: t = {}, retryTimes: e, defaultCdns: r = ["jsdelivr", "unpkg", "cdnjs"] } = n;
300
- let s = e;
301
- s || (s = r.length - 1);
302
- let c;
452
+ function Pt(r) {
453
+ const { customScript: t = {}, retryTimes: e = 1, defaultCdns: s = ["jsdelivr", "unpkg"] } = r;
454
+ let n;
303
455
  return {
304
- name: "vite-add-cdn-script",
456
+ name: q,
305
457
  enforce: "pre",
306
458
  apply: "build",
307
- config(i) {
308
- c = i;
459
+ config(o) {
460
+ n = o;
309
461
  },
310
- async transformIndexHtml(i) {
311
- if (!r || r.length === 0)
462
+ async transformIndexHtml(o) {
463
+ var c, i;
464
+ if (!s || s.length === 0)
312
465
  throw new Error("defaultCdns不能为空");
313
- const o = J.resolve(process.cwd(), "package.json");
466
+ const a = O.resolve(process.cwd(), "package.json");
314
467
  try {
315
- const a = j.readFileSync(o, "utf-8"), l = JSON.parse(a), d = c.build.rollupOptions.external, C = {};
316
- let p = "";
317
- const { urls: k, noVersionPackages: S } = await O({
318
- external: d,
319
- packageData: l,
468
+ const l = U.readFileSync(a, "utf-8"), L = JSON.parse(l), d = (i = (c = n.build) == null ? void 0 : c.rollupOptions) == null ? void 0 : i.external;
469
+ if (!d)
470
+ return o;
471
+ let w = [];
472
+ if (typeof d == "string")
473
+ w = [d];
474
+ else if (Array.isArray(d))
475
+ w = d.filter((g) => typeof g == "string");
476
+ else if (typeof d == "object")
477
+ return o;
478
+ const f = {};
479
+ let k = "";
480
+ const { urls: v, noVersionPackages: _ } = await A({
481
+ external: w,
482
+ packageData: L,
320
483
  customScript: t,
321
- defaultCdns: r
484
+ defaultCdns: s
322
485
  });
323
- if (S.length > 0) {
324
- const m = { dependencies: {} };
325
- await Promise.all(
326
- k.map(async (u) => {
327
- if (!u)
486
+ if (_.length > 0) {
487
+ const g = { dependencies: {} };
488
+ await Promise.allSettled(
489
+ v.map(async (h) => {
490
+ if (!h)
328
491
  return;
329
- const { key: x, urls: _ } = u, g = t[x] || _[0];
330
- if (!g)
492
+ const { key: j, urls: F } = h, P = t[j] || F[0];
493
+ if (!P)
331
494
  return;
332
- const $ = await Q(g);
333
- z(m.dependencies, $.dependencies);
495
+ const x = await ut(P);
496
+ wt(g.dependencies, x.dependencies);
334
497
  })
335
- ).catch((u) => {
336
- console.log("err", u);
498
+ ).then((h) => {
499
+ h.forEach((j) => {
500
+ j.status === "rejected" && S.warn(j.reason.toString());
501
+ });
337
502
  });
338
- const { urls: P, noVersionPackages: h } = await O({
339
- external: S,
340
- packageData: m,
503
+ const { urls: E, noVersionPackages: p } = await A({
504
+ external: _,
505
+ packageData: g,
341
506
  customScript: t,
342
- defaultCdns: r
507
+ defaultCdns: s
343
508
  });
344
- if (P.map((u) => {
345
- var g;
346
- if (!u)
509
+ if (E.map((h) => {
510
+ var P;
511
+ if (!h)
347
512
  return;
348
- const { urls: x, key: _ } = u;
349
- (g = k.find(($) => ($ == null ? void 0 : $.key) === _)) == null || g.urls.push(...x);
350
- }), h.length > 0)
351
- throw console.error(`找不到${h.join(",")}的版本`), new Error(`找不到${h.join(",")}的版本`);
513
+ const { urls: j, key: F } = h;
514
+ (P = v.find((x) => (x == null ? void 0 : x.key) === F)) == null || P.urls.push(...j);
515
+ }), p.length > 0)
516
+ throw console.error(`找不到${p.join(",")}的版本`), new Error(`找不到${p.join(",")}的版本`);
352
517
  }
353
- return k.forEach((m) => {
354
- if (!m)
518
+ return S.consoleAll(), v.forEach((g) => {
519
+ if (!g)
355
520
  return;
356
- const { urls: P, key: h } = m;
357
- if (t[h])
358
- p += t[h];
521
+ const { urls: E, key: p } = g;
522
+ if (t[p])
523
+ k += t[p];
359
524
  else {
360
- C[h] = P;
361
- const u = P[0];
362
- p += `<script src="${u}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${h}"><\/script>
525
+ f[p] = E;
526
+ const h = E[0];
527
+ k += `<script src="${h}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${p}"><\/script>
363
528
  `;
364
529
  }
365
- }), p = `<script>
530
+ }), k = `<script>
366
531
  function errorCDN(e) {
367
- const packNameUrl = JSON.parse('${JSON.stringify(C)}');
532
+ const packNameUrl = JSON.parse('${JSON.stringify(f)}');
368
533
  const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
369
534
  if(nextCur>${e}){return;}
370
535
 
@@ -384,13 +549,14 @@ function tt(n) {
384
549
  document.head.appendChild(cdnDOM);
385
550
  e.remove();
386
551
  }
387
- <\/script>` + p, i = i.replace("</head>", `${p}</head>`), i;
388
- } catch (a) {
389
- console.error("获取dependencies出错:", a);
552
+ <\/script>` + k, o = o.replace("</head>", `${k}</head>`), o;
553
+ } catch (l) {
554
+ S.consoleAll(), console.error("vite-add-cdn-script error:", l.message), process.exit(1);
390
555
  }
391
556
  }
392
557
  };
393
558
  }
394
559
  export {
395
- tt as default
560
+ Pt as default,
561
+ q as libName
396
562
  };
@@ -1,9 +1,9 @@
1
- (function(d,u){typeof exports=="object"&&typeof module<"u"?module.exports=u(require("node:path"),require("node:fs"),require("node:https")):typeof define=="function"&&define.amd?define(["node:path","node:fs","node:https"],u):(d=typeof globalThis<"u"?globalThis:d||self,d.index=u(d.path,d.fs,d.https))})(this,function(d,u,m){"use strict";var z=Object.defineProperty;var K=(d,u,m)=>u in d?z(d,u,{enumerable:!0,configurable:!0,writable:!0,value:m}):d[u]=m;var $=(d,u,m)=>(K(d,typeof u!="symbol"?u+"":u,m),m);class E{constructor(){$(this,"cdnCache",{});$(this,"cdnCachePath","");this.cdnCachePath=d.resolve(process.cwd(),"./.cdn-cache.json")}async init(){try{const e=await u.readFileSync(this.cdnCachePath,"utf-8");this.cdnCache=JSON.parse(e)}catch{console.log("cdn缓存文件不存在,创建缓存文件"),this.cdnCache={},await u.writeFileSync(this.cdnCachePath,"","utf-8")}}getCdnCache(e,t){var r;return(r=this.cdnCache[e])==null?void 0:r[t]}setCdnCache(e,t,r){this.cdnCache[e]?this.cdnCache[e][t]=r:this.cdnCache[e]={[t]:r}}async save(){await u.writeFileSync(this.cdnCachePath,JSON.stringify(this.cdnCache),"utf-8")}}let j;const L=async()=>(j||(j=new E,await j.init()),j);class b{constructor(e){$(this,"_max");$(this,"_count");$(this,"_taskQueue");this._max=e||5,this._count=0,this._taskQueue=[]}call(e,...t){return new Promise((r,s)=>{const c=this._createTask(e,t,r,s);this._count>=this._max?this._taskQueue.push(c):c()})}_createTask(e,t,r,s){return()=>{e(...t).then(r).catch(s).finally(()=>{this._count--,this._taskQueue.length&&this._taskQueue.shift()()}),this._count++}}}const v=new b(5),I={get:(n,e,t)=>new Promise((r,s)=>{try{m.get(n,c=>{let i="";c.on("data",o=>{i+=o}),c.on("end",()=>{e==null||e(i),r(i)})}).on("error",function(c){t==null||t(c),s(c)})}catch(c){t==null||t(c),s(c)}})},w={get:v.call.bind(v,I.get)},N={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://api.bootcdn.cn/libraries/${n}`,s=>{const c=JSON.parse(s);if(c.length===0){r(new Error(`${n} not found in bootcdn`));return}const i=c[0],a=i.assets.find(p=>p.version===e);if(!a){r(new Error(`${n}@${e} not found in ${i.name}`));return}const l=a.files.map(p=>({name:"/"+p}));t({fileList:l,recommendFileName:i.filename})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdn.bootcdn.net/ajax/libs/${n}/${e}${t}`},R={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://api.cdnjs.com/libraries/${n}/${e}`,s=>{const c=JSON.parse(s);if(c.error){r(new Error(`cdnjs: ${n}@${e} not found`));return}t({fileList:c.rawFiles.map(i=>({name:"/"+i}))})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdnjs.cloudflare.com/ajax/libs/${n}/${e}${t}`},A={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://data.jsdelivr.com/v1/stats/packages/npm/${n}@${e}/files`,s=>{const c=JSON.parse(s);if(c.length===0){r(new Error(`${n}@${e} not found`));return}t({fileList:c})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://cdn.jsdelivr.net/npm/${n}@${e}${t}`},O=n=>n.reduce((e,t)=>(t.type==="file"?e.push({name:t.path}):t.files&&e.push(...O(t.files)),e),[]),T={getFileList:(n,e)=>new Promise((t,r)=>{w.get(`https://unpkg.com/${n}@${e}/?meta`,s=>{const c=JSON.parse(s);t({fileList:O(c.files||[])})},s=>{r(s)})}),getUrl:(n,e,t)=>`https://unpkg.com/${n}@${e}${t}`},M=async n=>{const e=/^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;if(e.test(n)){const t=n.replace(e,(r,s)=>`${s}package.json`);return JSON.parse(await w.get(t))}else throw new Error(`${n} 不是正确的url`)},V=(n,e)=>{var t,r;return((t=n.dependencies)==null?void 0:t[e])||((r=n.devDependencies)==null?void 0:r[e])},q=async(n,e,t)=>{var i;const r=(i=e.match(/\d+(.\d+)?(.\d+)?/))==null?void 0:i[0];if(!r)throw new Error(`${n} version ${e} is not valid`);const s=await J[t].getFileList(n,r).catch(o=>{throw console.log(o),new Error(`${n} ${e} ${t} API 请求失败`)}),c=Q(s,n);if(!c)throw new Error(`在 ${t} 中找不到 ${n}@${r} 文件,请检查包名或版本号`);return J[t].getUrl(n,r,c)},Q=({fileList:n},e)=>{var c,i;let t=[`umd/${e}.production.min.js`,/umd\/.+?\.production\.min\.js$/,/dist\/.+?\.production\.min\.js$/,/dist\/.+?\.umd\.min\.js$/,`dist/${e}.prod.min.js`,/dist\/.+?\.global.prod.min.js/,`dist/${e}.min.js`,/.+?\.global.prod.min.js/,/.+?.global.prod.js/,/lib\/.+?\.min\.js$/,/dist\/.+?\.min\.js$/,/index\.min\.js$/,/index\.js$/,/\.min\.js$/,/\.js$/];const r=["runtime","compiler",".esm",".cjs","development"].filter(o=>!e.includes(o));let s="";for(let o of t)if(o instanceof RegExp?s=((c=n.find(a=>o.test(a.name)&&!r.some(l=>a.name.includes(l))))==null?void 0:c.name)||"":s=((i=n.find(a=>a.name.includes(o)&&!r.some(l=>a.name.includes(l))))==null?void 0:i.name)||"",s)break;return s},J={jsdelivr:A,bootcdn:N,cdnjs:R,unpkg:T};function H(n,e){const t=n.replace(/^\D/,"").split("."),r=e.replace(/^\D/,"").split("."),s=Math.max(t.length,r.length);for(;t.length<s;)t.push("0");for(;r.length<s;)r.push("0");for(let c=0;c<s;c++){const i=parseInt(t[c],10),o=parseInt(r[c],10);if(i>o)return 1;if(i<o)return-1}return 0}function B(n,e){for(let t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]?H(n[t],e[t])===-1&&(n[t]=e[t]):n[t]=e[t]);return n}async function D({external:n,packageData:e,customScript:t,defaultCdns:r}){let s=[],c=!1;const i=await L();return await Promise.all(n.map(async o=>{const a=V(e,o);if(t[o])return{urls:[],key:o};const l=i.getCdnCache(o,a);if(!a&&!l)return s.push(o),{urls:[],key:o};if(l)return{urls:l,key:o};{c=!0,console.log(`从网络获取${o}${a}的cdn地址`);const p={urls:await Promise.all(r.map(async k=>await q(o,a,k))),key:o};return i.setCdnCache(o,a,p.urls),p}})).then(o=>(c&&i.save(),{urls:o,noVersionPackages:s}))}function G(n){const{customScript:e={},retryTimes:t,defaultCdns:r=["jsdelivr","unpkg","cdnjs"]}=n;let s=t;s||(s=r.length-1);let c;return{name:"vite-add-cdn-script",enforce:"pre",apply:"build",config(i){c=i},async transformIndexHtml(i){if(!r||r.length===0)throw new Error("defaultCdns不能为空");const o=d.resolve(process.cwd(),"package.json");try{const a=u.readFileSync(o,"utf-8"),l=JSON.parse(a),p=c.build.rollupOptions.external,k={};let g="";const{urls:_,noVersionPackages:F}=await D({external:p,packageData:l,customScript:e,defaultCdns:r});if(F.length>0){const C={dependencies:{}};await Promise.all(_.map(async h=>{if(!h)return;const{key:S,urls:U}=h,P=e[S]||U[0];if(!P)return;const y=await M(P);B(C.dependencies,y.dependencies)})).catch(h=>{console.log("err",h)});const{urls:x,noVersionPackages:f}=await D({external:F,packageData:C,customScript:e,defaultCdns:r});if(x.map(h=>{var P;if(!h)return;const{urls:S,key:U}=h;(P=_.find(y=>(y==null?void 0:y.key)===U))==null||P.urls.push(...S)}),f.length>0)throw console.error(`找不到${f.join(",")}的版本`),new Error(`找不到${f.join(",")}的版本`)}return _.forEach(C=>{if(!C)return;const{urls:x,key:f}=C;if(e[f])g+=e[f];else{k[f]=x;const h=x[0];g+=`<script src="${h}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${f}"><\/script>
2
- `}}),g=`<script>
1
+ (function(c,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("node:path"),require("node:fs"),require("node-fetch"),require("semver")):typeof define=="function"&&define.amd?define(["exports","node:path","node:fs","node-fetch","semver"],l):(c=typeof globalThis<"u"?globalThis:c||self,l(c.index={},c.path,c.fs,c.fetch,c.semver))})(this,function(c,l,d,R,A){"use strict";var wt=Object.defineProperty;var gt=(c,l,d)=>l in c?wt(c,l,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[l]=d;var k=(c,l,d)=>(gt(c,typeof l!="symbol"?l+"":l,d),d);class B{constructor(){k(this,"cdnCache",{});k(this,"cdnCachePath","");this.cdnCachePath=l.resolve(process.cwd(),"./.cdn-cache.json")}async init(){try{const t=await d.readFileSync(this.cdnCachePath,"utf-8");this.cdnCache=JSON.parse(t)}catch{console.log("cdn缓存文件不存在,创建缓存文件"),this.cdnCache={},await d.writeFileSync(this.cdnCachePath,"","utf-8")}}getCdnCache(t,e){var n;return(n=this.cdnCache[t])==null?void 0:n[e]}setCdnCache(t,e,n){this.cdnCache[t]?this.cdnCache[t][e]=n:this.cdnCache[t]={[e]:n}}async save(){await d.writeFileSync(this.cdnCachePath,JSON.stringify(this.cdnCache),"utf-8")}}let b;const z=async()=>(b||(b=new B,await b.init()),b);class h extends Error{constructor(t){super(t),this.name="NetworkError"}}class P extends h{constructor({packageName:t,version:e,cdn:n}){super(`${n} ${t}@${e} 网络请求失败`),this.name="PackageNetworkError"}}class $ extends Error{constructor({packageName:t,version:e,cdn:n}){super(`${n}上没有${t}@${e}的版本`),this.name="NoVersionError"}}class K extends Error{constructor({packageName:t,version:e,cdn:n}){super(`在 ${n} 中找不到 ${t}@${e} 文件,请检查包名或版本号`),this.name="GetFileListError"}}class W{constructor(t){k(this,"_max");k(this,"_count");k(this,"_taskQueue");this._max=t||5,this._count=0,this._taskQueue=[]}call(t,...e){return new Promise((n,s)=>{const i=this._createTask(t,e,n,s);this._count>=this._max?this._taskQueue.push(i):i()})}_createTask(t,e,n,s){return()=>{t(...e).then(n).catch(s).finally(()=>{this._count--,this._taskQueue.length&&this._taskQueue.shift()()}),this._count++}}}const V=new W(5),J=async r=>{try{const t=await R(r,{method:"HEAD",redirect:"manual"});return t.status>=300&&t.status<400?await J(t.headers.get("location")||""):r}catch(t){throw Promise.reject(new h(t.message))}},X={get:async r=>{try{const t=await R(r);if(t.ok){const e=t.headers.get("content-type"),n=await t.text();return e&&e.includes("application/json")?JSON.parse(n):n}else throw new h(`请求失败,状态码:${t.status}`)}catch(t){throw new h(t.message)}}},y={get:V.call.bind(V,X.get)},Y={getFileList:async(r,t)=>{try{const e=await y.get(`https://api.bootcdn.cn/libraries/${r}`);if(e.length===0)throw new $({packageName:r,version:t,cdn:"bootcdn"});const n=e[0],i=n.assets.reverse().find(o=>{if(A.satisfies(o.version,t))return!0});if(!i)throw new $({packageName:r,version:t,cdn:"bootcdn"});return{fileList:i.files.map(o=>({name:"/"+o})),recommendFileName:n.filename,version:i.version}}catch(e){throw e instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):e}},getUrl:(r,t,e)=>`https://cdn.bootcdn.net/ajax/libs/${r}/${t}${e}`};async function M(r,t,e=!1){try{if(!e&&t.match(/^\D/)){const s=await N(r,t);for(let i of s)if(A.satisfies(i,t))return M(r,i,!0);throw new $({packageName:r,version:t,cdn:"cdnjs"})}const n=await y.get(`https://api.cdnjs.com/libraries/${r}/${t}`);if(n.error)throw new $({packageName:r,version:t,cdn:"cdnjs"});return{fileList:n.rawFiles.map(s=>({name:"/"+s})),version:t}}catch(n){throw n instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):n}}const Z=(r,t,e)=>`https://cdnjs.cloudflare.com/ajax/libs/${r}/${t}${e}`,N=async(r,t)=>{try{return(await y.get(`https://api.cdnjs.com/libraries/${r}?fields=versions`)).versions}catch(e){throw e instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):e}},tt={getFileList:M,getUrl:Z},T=(r,t="")=>r.reduce((e,n)=>(n.type==="file"?e.push({name:`${t}/${n.name}`}):n.files&&e.push(...T(n.files,`${t}/${n.name}`)),e),[]);async function I(r,t,e=!1){try{if(!e&&t.match(/^\D/)){const s=await rt(r,t);if(typeof s=="string")return I(r,s,!0);throw new $({packageName:r,version:t,cdn:"jsdelivr"})}const n=await y.get(`https://data.jsdelivr.com/v1/packages/npm/${r}@${t}`);if(n.status)throw new $({packageName:r,version:t,cdn:"jsdelivr"});return{fileList:T(n.files),version:t}}catch(n){throw n instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):n}}const et=(r,t,e)=>`https://cdn.jsdelivr.net/npm/${r}@${t}${e}`,rt=async(r,t)=>{try{return(await y.get(`https://data.jsdelivr.com/v1/packages/npm/${r}/resolved?specifier=${t}`)).version}catch(e){throw e instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):e}},nt={getFileList:I,getUrl:et},q=r=>r.reduce((t,e)=>(e.type==="file"?t.push({name:e.path}):e.files&&t.push(...q(e.files)),t),[]);async function st(r,t){var e;try{const s=(e=(await J(`https://unpkg.com/${r}@${t}/?meta`)).match(new RegExp("(?<=@)\\d+\\.\\d+\\.\\d+(?=\\/\\?meta)")))==null?void 0:e[0];if(s){const i=await y.get(`https://unpkg.com/${r}@${s}/?meta`);return{fileList:q(i.files||[]),version:s}}else throw new $({packageName:r,version:t,cdn:"unpkg"})}catch(n){throw n instanceof h?new P({packageName:r,version:t,cdn:"unpkg"}):n}}function it(r,t,e){return`https://unpkg.com/${r}@${t}${e}`}const ot={getFileList:st,getUrl:it},ct=async r=>{try{const t=/^(https?:\/\/.*\d+\.\d+\.\d+\/).+?\.js$/;if(t.test(r)){const e=r.replace(t,(n,s)=>`${s}package.json`);return await y.get(e)}else throw new Error(`${r} 不是正确的url`)}catch(t){throw t}},at=(r,t)=>{var e,n;return((e=r.dependencies)==null?void 0:e[t])||((n=r.devDependencies)==null?void 0:n[t])},lt=async(r,t,e)=>{if(!t.match(/\d+(.\d+)?(.\d+)?/))throw new Error(`${r} version ${t} is not valid`);const s=await Q[e].getFileList(r,t),i=ut(s,r);if(!i)throw new K({packageName:r,version:t,cdn:e});return Q[e].getUrl(r,s.version,i)},ut=({fileList:r},t)=>{var i,u;let e=[`umd/${t}.production.min.js`,/umd\/.+?\.production\.min\.js$/,/dist\/.+?\.production\.min\.js$/,/dist\/.+?\.umd\.min\.js$/,`dist/${t}.prod.min.js`,/dist\/.+?\.global.prod.min.js/,`dist/${t}.min.js`,/.+?\.global.prod.min.js/,/.+?.global.prod.js/,/lib\/.+?\.min\.js$/,/dist\/.+?\.min\.js$/,/index\.min\.js$/,/index\.js$/,/\.min\.js$/,/\.js$/];const n=["runtime","compiler",".esm",".cjs","development"].filter(o=>!t.includes(o));let s="";for(let o of e)if(o instanceof RegExp?s=((i=r.find(a=>o.test(a.name)&&!n.some(f=>a.name.includes(f))))==null?void 0:i.name)||"":s=((u=r.find(a=>a.name.includes(o)&&!n.some(f=>a.name.includes(f))))==null?void 0:u.name)||"",s)break;return s},Q={jsdelivr:nt,bootcdn:Y,cdnjs:tt,unpkg:ot};function dt(r,t){const e=r.replace(/^\D/,"").split("."),n=t.replace(/^\D/,"").split("."),s=Math.max(e.length,n.length);for(;e.length<s;)e.push("0");for(;n.length<s;)n.push("0");for(let i=0;i<s;i++){const u=parseInt(e[i],10),o=parseInt(n[i],10);if(u>o)return 1;if(u<o)return-1}return 0}function ht(r,t){for(let e in t)Object.prototype.hasOwnProperty.call(t,e)&&(r[e]?dt(r[e],t[e])===-1&&(r[e]=t[e]):r[e]=t[e]);return r}class ft{constructor(){k(this,"logList",[])}log(t){this.logList.push({type:"log",message:t})}warn(t){this.logList.push({type:"warn",message:t})}error(t){this.logList.push({type:"error",message:t})}info(t){this.logList.push({type:"info",message:t})}consoleAll(){this.logList.forEach(t=>{console[t.type](`${F} ${t.message}`)})}clear(){this.logList=[]}}const F="vite-add-cdn-script",v=new ft;async function H({external:r,packageData:t,customScript:e,defaultCdns:n}){let s=[],i=!1;const u=await z();return await Promise.all(r.map(async o=>{const a=at(t,o);if(e[o])return{urls:[],key:o};if(!a)return s.push(o),{urls:[],key:o};const f=u.getCdnCache(o,a);if(f)return{urls:f,key:o};{i=!0,console.log(`从网络获取${o}${a}的cdn地址`);const S=await Promise.allSettled(n.map(async j=>await lt(o,a,j))).then(j=>j.filter(g=>{if(g.status==="fulfilled")return g.value,!0;v.warn(g.reason.toString())}).map(g=>g.value));if(S.length===0)throw new Error(`获取${o} ${a}的cdn地址失败`);const p={urls:S,key:o};return u.setCdnCache(o,a,p.urls),p}})).then(o=>(i&&u.save(),{urls:o,noVersionPackages:s}))}function pt(r){const{customScript:t={},retryTimes:e=1,defaultCdns:n=["jsdelivr","unpkg"]}=r;let s;return{name:F,enforce:"pre",apply:"build",config(i){s=i},async transformIndexHtml(i){var o,a;if(!n||n.length===0)throw new Error("defaultCdns不能为空");const u=l.resolve(process.cwd(),"package.json");try{const f=d.readFileSync(u,"utf-8"),S=JSON.parse(f),p=(a=(o=s.build)==null?void 0:o.rollupOptions)==null?void 0:a.external;if(!p)return i;let j=[];if(typeof p=="string")j=[p];else if(Array.isArray(p))j=p.filter(C=>typeof C=="string");else if(typeof p=="object")return i;const g={};let L="";const{urls:D,noVersionPackages:G}=await H({external:j,packageData:S,customScript:t,defaultCdns:n});if(G.length>0){const C={dependencies:{}};await Promise.allSettled(D.map(async w=>{if(!w)return;const{key:x,urls:O}=w,E=t[x]||O[0];if(!E)return;const U=await ct(E);ht(C.dependencies,U.dependencies)})).then(w=>{w.forEach(x=>{x.status==="rejected"&&v.warn(x.reason.toString())})});const{urls:_,noVersionPackages:m}=await H({external:G,packageData:C,customScript:t,defaultCdns:n});if(_.map(w=>{var E;if(!w)return;const{urls:x,key:O}=w;(E=D.find(U=>(U==null?void 0:U.key)===O))==null||E.urls.push(...x)}),m.length>0)throw console.error(`找不到${m.join(",")}的版本`),new Error(`找不到${m.join(",")}的版本`)}return v.consoleAll(),D.forEach(C=>{if(!C)return;const{urls:_,key:m}=C;if(t[m])L+=t[m];else{g[m]=_;const w=_[0];L+=`<script src="${w}" type="text/javascript" crossorigin="anonymous" onerror="errorCDN(this)" data-cur="0" data-key="${m}"><\/script>
2
+ `}}),L=`<script>
3
3
  function errorCDN(e) {
4
- const packNameUrl = JSON.parse('${JSON.stringify(k)}');
4
+ const packNameUrl = JSON.parse('${JSON.stringify(g)}');
5
5
  const nextCur = parseInt(e.getAttribute("data-cur")) + 1;
6
- if(nextCur>${t}){return;}
6
+ if(nextCur>${e}){return;}
7
7
 
8
8
  const key = e.getAttribute("data-key");
9
9
  if(nextCur>=packNameUrl[key].length){return;}
@@ -21,4 +21,4 @@
21
21
  document.head.appendChild(cdnDOM);
22
22
  e.remove();
23
23
  }
24
- <\/script>`+g,i=i.replace("</head>",`${g}</head>`),i}catch(a){console.error("获取dependencies出错:",a)}}}}return G});
24
+ <\/script>`+L,i=i.replace("</head>",`${L}</head>`),i}catch(f){v.consoleAll(),console.error("vite-add-cdn-script error:",f.message),process.exit(1)}}}}c.default=pt,c.libName=F,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-add-cdn-script",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "keywords": [
5
5
  "vite",
6
6
  "cdn",
@@ -37,8 +37,10 @@
37
37
  "devDependencies": {
38
38
  "@jest/globals": "^29.7.0",
39
39
  "@types/node": "^20.12.11",
40
+ "@types/node-fetch": "2",
40
41
  "@types/react": "^18.3.2",
41
42
  "@types/react-dom": "^18.3.0",
43
+ "@types/semver": "^7.5.8",
42
44
  "@vitejs/plugin-react": "^4.2.1",
43
45
  "cross-env": "^7.0.3",
44
46
  "jest": "^29.7.0",
@@ -55,5 +57,8 @@
55
57
  "publishConfig": {
56
58
  "registry": "https://registry.npmjs.org/"
57
59
  },
58
- "dependencies": {}
60
+ "dependencies": {
61
+ "node-fetch": "2",
62
+ "semver": "^7.6.2"
63
+ }
59
64
  }