vite-add-cdn-script 0.0.9 → 0.0.10

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.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
  }