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 +489 -370
- package/dist/index.umd.cjs +25 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
@@ -1,23 +1,30 @@
|
|
1
|
-
var
|
2
|
-
var
|
3
|
-
var
|
4
|
-
import
|
5
|
-
import
|
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
|
-
|
8
|
+
var L = /* @__PURE__ */ ((s) => (s.noFound = "noFound", s.NetworkError = "networkError", s))(L || {});
|
9
|
+
class Z {
|
9
10
|
constructor() {
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
18
|
-
this.cdnCache = JSON.parse(
|
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 = {
|
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(
|
29
|
-
var
|
30
|
-
return (
|
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(
|
39
|
-
this.cdnCache[
|
40
|
-
[
|
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
|
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
|
51
|
-
const
|
52
|
-
class
|
53
|
-
constructor(
|
54
|
-
super(
|
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
|
58
|
-
constructor({ packageName: t, version:
|
59
|
-
super(`${
|
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
|
63
|
-
constructor({ packageName: t, version:
|
64
|
-
super(`${
|
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
|
68
|
-
constructor({ packageName:
|
69
|
-
super(`在 ${
|
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
|
73
|
-
constructor(
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
this._max =
|
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(
|
86
|
-
return new Promise((
|
87
|
-
const
|
88
|
-
this._count >= this._max ? this._taskQueue.push(
|
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(
|
149
|
+
_createTask(e, t, r, n) {
|
101
150
|
return () => {
|
102
|
-
|
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
|
157
|
+
const b = new te(5), J = async (s) => {
|
109
158
|
try {
|
110
|
-
const
|
111
|
-
return
|
112
|
-
} catch (
|
113
|
-
throw
|
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
|
-
},
|
164
|
+
}, se = {
|
116
165
|
//get请求封装
|
117
|
-
get: async (
|
166
|
+
get: async (s) => {
|
118
167
|
try {
|
119
|
-
const
|
120
|
-
if (
|
121
|
-
const
|
122
|
-
return
|
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
|
125
|
-
} catch (
|
126
|
-
throw new
|
173
|
+
throw new g(`请求失败,状态码:${e.status}`);
|
174
|
+
} catch (e) {
|
175
|
+
throw new g(e.message);
|
127
176
|
}
|
128
177
|
}
|
129
|
-
},
|
130
|
-
get:
|
131
|
-
},
|
178
|
+
}, j = {
|
179
|
+
get: b.call.bind(b, se.get)
|
180
|
+
}, re = async (s, e) => {
|
132
181
|
try {
|
133
|
-
const
|
134
|
-
if (
|
135
|
-
throw new
|
136
|
-
packageName:
|
137
|
-
version:
|
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
|
141
|
-
if (V.satisfies(
|
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 (!
|
145
|
-
throw new
|
146
|
-
packageName:
|
147
|
-
version:
|
193
|
+
if (!c)
|
194
|
+
throw new k({
|
195
|
+
packageName: s,
|
196
|
+
version: e,
|
148
197
|
cdn: "bootcdn"
|
149
198
|
});
|
150
|
-
return { fileList:
|
151
|
-
name: "/" +
|
152
|
-
})), recommendFileName:
|
153
|
-
} catch (
|
154
|
-
throw
|
155
|
-
packageName:
|
156
|
-
version:
|
157
|
-
cdn: "
|
158
|
-
}) :
|
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
|
-
},
|
161
|
-
getFileList:
|
162
|
-
getUrl:
|
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
|
213
|
+
async function I(s, e, t = !1) {
|
165
214
|
try {
|
166
|
-
if (!
|
167
|
-
const n = await
|
168
|
-
for (let
|
169
|
-
if (V.satisfies(
|
170
|
-
return
|
171
|
-
throw new
|
172
|
-
packageName:
|
173
|
-
version:
|
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
|
178
|
-
if (
|
179
|
-
throw new
|
180
|
-
packageName:
|
181
|
-
version:
|
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:
|
234
|
+
fileList: r.rawFiles.map((n) => ({
|
186
235
|
name: "/" + n
|
187
236
|
})),
|
188
|
-
version:
|
237
|
+
version: e
|
189
238
|
};
|
190
|
-
} catch (
|
191
|
-
throw
|
192
|
-
packageName:
|
193
|
-
version:
|
194
|
-
cdn: "
|
195
|
-
}) :
|
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
|
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
|
201
|
-
} catch (
|
202
|
-
throw
|
203
|
-
packageName:
|
204
|
-
version:
|
205
|
-
cdn: "
|
206
|
-
}) :
|
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
|
-
},
|
209
|
-
getFileList:
|
210
|
-
getUrl:
|
211
|
-
},
|
212
|
-
async function Q(
|
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 (!
|
215
|
-
const n = await
|
263
|
+
if (!t && e.match(/^\D/)) {
|
264
|
+
const n = await de(s, e);
|
216
265
|
if (typeof n == "string")
|
217
|
-
return Q(
|
218
|
-
throw new
|
219
|
-
packageName:
|
220
|
-
version:
|
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
|
225
|
-
if (
|
226
|
-
throw new
|
227
|
-
packageName:
|
228
|
-
version:
|
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:
|
232
|
-
} catch (
|
233
|
-
throw
|
234
|
-
packageName:
|
235
|
-
version:
|
236
|
-
cdn: "
|
237
|
-
}) :
|
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
|
289
|
+
const le = (s, e, t) => `https://cdn.jsdelivr.net/npm/${s}@${e}${t}`, de = async (s, e) => {
|
241
290
|
try {
|
242
|
-
return (await
|
243
|
-
`https://data.jsdelivr.com/v1/packages/npm/${
|
291
|
+
return (await j.get(
|
292
|
+
`https://data.jsdelivr.com/v1/packages/npm/${s}/resolved?specifier=${e}`
|
244
293
|
)).version;
|
245
|
-
} catch (
|
246
|
-
throw
|
247
|
-
packageName:
|
248
|
-
version:
|
249
|
-
cdn: "
|
250
|
-
}) :
|
294
|
+
} catch (t) {
|
295
|
+
throw t instanceof g ? new y({
|
296
|
+
packageName: s,
|
297
|
+
version: e,
|
298
|
+
cdn: "jsdelivr"
|
299
|
+
}) : t;
|
251
300
|
}
|
252
|
-
},
|
301
|
+
}, ue = {
|
253
302
|
getFileList: Q,
|
254
303
|
// 拼接url
|
255
|
-
getUrl:
|
256
|
-
}, T = (
|
257
|
-
async function
|
258
|
-
var
|
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 = (
|
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
|
263
|
-
return { fileList: T(
|
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
|
266
|
-
packageName:
|
267
|
-
version:
|
314
|
+
throw new k({
|
315
|
+
packageName: s,
|
316
|
+
version: e,
|
268
317
|
cdn: "unpkg"
|
269
318
|
});
|
270
|
-
} catch (
|
271
|
-
throw
|
272
|
-
packageName:
|
273
|
-
version:
|
319
|
+
} catch (r) {
|
320
|
+
throw r instanceof g ? new y({
|
321
|
+
packageName: s,
|
322
|
+
version: e,
|
274
323
|
cdn: "unpkg"
|
275
|
-
}) :
|
324
|
+
}) : r;
|
276
325
|
}
|
277
326
|
}
|
278
|
-
function
|
279
|
-
return `https://unpkg.com/${
|
327
|
+
function fe(s, e, t) {
|
328
|
+
return `https://unpkg.com/${s}@${e}${t}`;
|
280
329
|
}
|
281
|
-
const
|
282
|
-
getFileList:
|
283
|
-
getUrl:
|
284
|
-
},
|
330
|
+
const pe = {
|
331
|
+
getFileList: he,
|
332
|
+
getUrl: fe
|
333
|
+
}, ge = async (s) => {
|
285
334
|
try {
|
286
|
-
const
|
287
|
-
if (
|
288
|
-
const
|
289
|
-
return await
|
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(`${
|
292
|
-
} catch (
|
293
|
-
throw
|
294
|
-
}
|
295
|
-
},
|
296
|
-
var
|
297
|
-
return ((
|
298
|
-
},
|
299
|
-
if (!
|
300
|
-
throw new Error(`${
|
301
|
-
const n = await
|
302
|
-
if (!
|
303
|
-
throw new
|
304
|
-
packageName:
|
305
|
-
version:
|
306
|
-
cdn:
|
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
|
309
|
-
},
|
310
|
-
var
|
311
|
-
let
|
312
|
-
`umd/${
|
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/${
|
365
|
+
`dist/${e}.prod.min.js`,
|
317
366
|
/dist\/.+?\.global.prod.min.js/,
|
318
|
-
`dist/${
|
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
|
377
|
+
const r = ["runtime", "compiler", ".esm", ".cjs", "development"].filter((i) => !e.includes(i));
|
329
378
|
let n = "";
|
330
|
-
for (let
|
331
|
-
if (
|
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
|
-
},
|
335
|
-
jsdelivr:
|
336
|
-
bootcdn:
|
337
|
-
cdnjs:
|
338
|
-
unpkg:
|
383
|
+
}, S = {
|
384
|
+
jsdelivr: ue,
|
385
|
+
bootcdn: ce,
|
386
|
+
cdnjs: ae,
|
387
|
+
unpkg: pe
|
339
388
|
};
|
340
|
-
function
|
341
|
-
const
|
342
|
-
for (;
|
343
|
-
|
344
|
-
for (;
|
345
|
-
|
346
|
-
for (let
|
347
|
-
const
|
348
|
-
if (
|
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 (
|
399
|
+
if (d < i)
|
351
400
|
return -1;
|
352
401
|
}
|
353
402
|
return 0;
|
354
403
|
}
|
355
|
-
function
|
356
|
-
for (let
|
357
|
-
Object.prototype.hasOwnProperty.call(
|
358
|
-
return
|
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
|
-
|
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
|
-
|
528
|
+
f(this, "logList", []);
|
364
529
|
}
|
365
530
|
// 打印方法
|
366
|
-
log(
|
531
|
+
log(e) {
|
367
532
|
this.logList.push({
|
368
533
|
type: "log",
|
369
|
-
message:
|
534
|
+
message: e
|
370
535
|
});
|
371
536
|
}
|
372
|
-
warn(
|
537
|
+
warn(e) {
|
373
538
|
this.logList.push({
|
374
539
|
type: "warn",
|
375
|
-
message:
|
540
|
+
message: e
|
376
541
|
});
|
377
542
|
}
|
378
|
-
error(
|
543
|
+
error(e) {
|
379
544
|
this.logList.push({
|
380
545
|
type: "error",
|
381
|
-
message:
|
546
|
+
message: e
|
382
547
|
});
|
383
548
|
}
|
384
|
-
info(
|
549
|
+
info(e) {
|
385
550
|
this.logList.push({
|
386
551
|
type: "info",
|
387
|
-
message:
|
552
|
+
message: e
|
388
553
|
});
|
389
554
|
}
|
390
555
|
// 打印全部
|
391
556
|
consoleAll() {
|
392
|
-
this.logList.forEach((
|
393
|
-
console[
|
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
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
const
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
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
|
453
|
-
const { customScript:
|
454
|
-
let
|
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:
|
614
|
+
enforce: q.PRE,
|
458
615
|
apply: "build",
|
459
616
|
config(n) {
|
460
|
-
|
617
|
+
r = n;
|
461
618
|
},
|
462
619
|
async transformIndexHtml(n) {
|
463
|
-
var
|
464
|
-
if (!
|
620
|
+
var i, o;
|
621
|
+
if (!t || t.length === 0)
|
465
622
|
throw new Error("defaultCdns不能为空");
|
466
|
-
|
623
|
+
let c = new ke();
|
624
|
+
const d = M.resolve(process.cwd(), "package.json");
|
467
625
|
try {
|
468
|
-
const
|
469
|
-
if (!
|
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
|
472
|
-
if (typeof
|
473
|
-
|
474
|
-
else if (Array.isArray(
|
475
|
-
|
476
|
-
else if (typeof
|
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
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
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 (
|
487
|
-
const
|
488
|
-
|
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
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
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 (
|
510
|
-
var
|
511
|
-
if (!
|
661
|
+
if (c.addMessageList("warn", B), z.map((x) => {
|
662
|
+
var E;
|
663
|
+
if (!x)
|
512
664
|
return;
|
513
|
-
const { urls:
|
514
|
-
(
|
515
|
-
}),
|
516
|
-
throw console.error(`找不到${
|
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
|
-
|
553
|
-
|
554
|
-
|
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
|
-
|
561
|
-
H as libName
|
680
|
+
De as default
|
562
681
|
};
|
package/dist/index.umd.cjs
CHANGED
@@ -1,24 +1,25 @@
|
|
1
|
-
(function(
|
2
|
-
`
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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});
|