vite-add-cdn-script 0.0.11 → 1.0.0

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