swpp-backends 0.0.1-alpha.0 → 0.0.2-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SwppConfig.js +2 -0
- package/dist/UpdateJsonBuilder.js +281 -0
- package/dist/VersionAnalyzer.js +62 -0
- package/dist/fileAnalyzer.js +325 -76
- package/dist/index.js +32 -25
- package/dist/resources/sw-template.js +15 -23
- package/dist/serviceWorkerBuilder.js +18 -10
- package/dist/swppRules.js +34 -16
- package/dist/utils.js +42 -14
- package/package.json +36 -21
- package/{src/SwppConfig.ts → types/SwppConfig.d.ts} +125 -125
- package/types/UpdateJsonBuilder.d.ts +50 -0
- package/types/VersionAnalyzer.d.ts +29 -0
- package/types/fileAnalyzer.d.ts +149 -0
- package/types/index.d.ts +55 -0
- package/types/serviceWorkerBuilder.d.ts +7 -0
- package/types/swppRules.d.ts +101 -0
- package/types/utils.d.ts +41 -0
- package/gulpfile.js +0 -3
- package/src/FileAnalyzer.ts +0 -417
- package/src/ServiceWorkerBuilder.ts +0 -156
- package/src/SwppRules.ts +0 -200
- package/src/UpdateJsonBuilder.ts +0 -279
- package/src/Utils.ts +0 -195
- package/src/VersionAnalyzer.ts +0 -77
- package/src/index.ts +0 -64
- package/src/resources/sw-dom.js +0 -51
- package/src/resources/sw-template.js +0 -257
- package/tsconfig.json +0 -109
package/dist/fileAnalyzer.js
CHANGED
|
@@ -26,20 +26,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.replaceRequest = exports.findCache = exports.eachAllLinkInJavaScript = exports.eachAllLinkInCss = exports.eachAllLinkInHtml = exports.eachAllLinkInUrl = exports.
|
|
29
|
+
exports.replaceRequest = exports.findCache = exports.eachAllLinkInJavaScript = exports.eachAllLinkInCss = exports.eachAllLinkInHtml = exports.eachAllLinkInUrl = exports.buildVersionJson = exports.readMergeVersionMap = exports.readNewVersionJson = exports.readOldVersionJson = exports.submitCacheInfo = exports.loadVersionJson = exports.isStable = exports.isExclude = void 0;
|
|
30
30
|
const fs_1 = __importDefault(require("fs"));
|
|
31
31
|
const path_1 = __importDefault(require("path"));
|
|
32
32
|
const node_fetch_1 = require("node-fetch");
|
|
33
|
-
const
|
|
33
|
+
const SwppRules_1 = require("./SwppRules");
|
|
34
34
|
const crypto = __importStar(require("crypto"));
|
|
35
35
|
const buffer_1 = require("buffer");
|
|
36
36
|
const fast_html_parser_1 = __importDefault(require("fast-html-parser"));
|
|
37
37
|
const css_1 = __importDefault(require("css"));
|
|
38
|
-
const
|
|
38
|
+
const Utils_1 = require("./Utils");
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* 遍历指定目录及其子目录中包含的所有文件(不遍历文件夹)
|
|
41
41
|
* @param root 根目录
|
|
42
|
-
* @param cb
|
|
42
|
+
* @param cb 回调函数(接收的参数是文件的相对路径)
|
|
43
43
|
*/
|
|
44
44
|
function eachAllFile(root, cb) {
|
|
45
45
|
const stats = fs_1.default.statSync(root);
|
|
@@ -50,81 +50,255 @@ function eachAllFile(root, cb) {
|
|
|
50
50
|
files.forEach(it => eachAllFile(path_1.default.join(root, it), cb));
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
/**
|
|
54
|
+
* 判断指定 URL 是否排除
|
|
55
|
+
*
|
|
56
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
57
|
+
*
|
|
58
|
+
* @param domain 网站域名
|
|
59
|
+
* @param url 要判断的 URL
|
|
60
|
+
*/
|
|
61
|
+
function isExclude(domain, url) {
|
|
62
|
+
const exclude = (0, SwppRules_1.readRules)().config?.json?.exclude;
|
|
63
|
+
if (!exclude)
|
|
64
|
+
throw 'exclude 为空';
|
|
65
|
+
const list = isExternalLink(domain, url) ? exclude.other : exclude.localhost;
|
|
66
|
+
for (let reg of list) {
|
|
67
|
+
if (url.match(reg))
|
|
58
68
|
return true;
|
|
59
69
|
}
|
|
60
70
|
return false;
|
|
61
71
|
}
|
|
72
|
+
exports.isExclude = isExclude;
|
|
62
73
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
* 判断指定 URL 是否是 stable 的
|
|
75
|
+
*
|
|
76
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
77
|
+
*/
|
|
78
|
+
function isStable(url) {
|
|
79
|
+
const stable = (0, SwppRules_1.readRules)().config?.external?.stable;
|
|
80
|
+
if (!stable)
|
|
81
|
+
throw 'stable 为空';
|
|
82
|
+
for (let reg of stable) {
|
|
83
|
+
if (url.match(reg))
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
exports.isStable = isStable;
|
|
89
|
+
/**
|
|
90
|
+
* 从指定 URL 加载 cache json
|
|
91
|
+
*
|
|
92
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
93
|
+
*/
|
|
94
|
+
async function loadVersionJson(url) {
|
|
95
|
+
const response = await (0, Utils_1.fetchFile)(url);
|
|
96
|
+
return _oldVersionJson = (await response.json());
|
|
97
|
+
}
|
|
98
|
+
exports.loadVersionJson = loadVersionJson;
|
|
99
|
+
let _oldVersionJson;
|
|
100
|
+
let _newVersionJson;
|
|
101
|
+
let _mergeVersionMap;
|
|
102
|
+
const event = [];
|
|
103
|
+
/** 提交要存储到 version json 的值 */
|
|
104
|
+
function submitCacheInfo(value) {
|
|
105
|
+
event.push(value);
|
|
106
|
+
}
|
|
107
|
+
exports.submitCacheInfo = submitCacheInfo;
|
|
108
|
+
/**
|
|
109
|
+
* 读取最后一次加载的 version json
|
|
110
|
+
*
|
|
111
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
112
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
68
113
|
*/
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
|
|
114
|
+
function readOldVersionJson() {
|
|
115
|
+
if (!_oldVersionJson)
|
|
116
|
+
throw 'cache json 尚未初始化';
|
|
117
|
+
return _oldVersionJson;
|
|
118
|
+
}
|
|
119
|
+
exports.readOldVersionJson = readOldVersionJson;
|
|
120
|
+
/**
|
|
121
|
+
* 读取最后一次构建的 VersionJson
|
|
122
|
+
*
|
|
123
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
124
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
125
|
+
* + **执行该函数前必须调用过 [buildVersionJson]**
|
|
126
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
127
|
+
*/
|
|
128
|
+
function readNewVersionJson() {
|
|
129
|
+
if (!_newVersionJson)
|
|
130
|
+
throw 'cache json 尚未初始化';
|
|
131
|
+
return _newVersionJson;
|
|
132
|
+
}
|
|
133
|
+
exports.readNewVersionJson = readNewVersionJson;
|
|
134
|
+
/**
|
|
135
|
+
* 读取新旧版本文件合并后的版本地图
|
|
136
|
+
*
|
|
137
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
138
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
139
|
+
* + **执行该函数前必须调用过 [buildVersionJson]**
|
|
140
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
141
|
+
*/
|
|
142
|
+
function readMergeVersionMap() {
|
|
143
|
+
if (_mergeVersionMap)
|
|
144
|
+
return _mergeVersionMap;
|
|
145
|
+
const map = {};
|
|
146
|
+
Object.assign(map, readOldVersionJson().list);
|
|
147
|
+
Object.assign(map, readNewVersionJson().list);
|
|
148
|
+
return _mergeVersionMap = map;
|
|
149
|
+
}
|
|
150
|
+
exports.readMergeVersionMap = readMergeVersionMap;
|
|
151
|
+
/**
|
|
152
|
+
* 构建一个 version json
|
|
153
|
+
*
|
|
154
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
155
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
156
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
157
|
+
*
|
|
158
|
+
* @param protocol 网站的网络协议
|
|
159
|
+
* @param domain 网站域名(包括二级域名)
|
|
160
|
+
* @param root 网页根目录(首页 index.html 所在目录)
|
|
161
|
+
*/
|
|
162
|
+
async function buildVersionJson(protocol, domain, root) {
|
|
163
|
+
const list = {};
|
|
164
|
+
eachAllFile(root, async (path) => {
|
|
72
165
|
const endIndex = path.length - (path.endsWith('/index.html') ? 10 : 0);
|
|
73
|
-
const url = new URL(protocol + path_1.default.join(
|
|
74
|
-
|
|
166
|
+
const url = new URL(protocol + path_1.default.join(domain, path.substring(root.length, endIndex)));
|
|
167
|
+
const pathname = url.pathname;
|
|
168
|
+
if (isExclude(domain, pathname))
|
|
75
169
|
return;
|
|
76
170
|
let content = null;
|
|
77
|
-
if (findCache(url
|
|
171
|
+
if (findCache(url)) {
|
|
78
172
|
content = fs_1.default.readFileSync(path, 'utf-8');
|
|
79
173
|
const key = decodeURIComponent(url.pathname);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
174
|
+
list[key] = crypto.createHash('md5').update(content).digest('hex');
|
|
175
|
+
}
|
|
176
|
+
if (pathname.endsWith('/') || pathname.endsWith('.html')) {
|
|
177
|
+
if (!content)
|
|
178
|
+
content = fs_1.default.readFileSync(path, 'utf-8');
|
|
179
|
+
await eachAllLinkInHtml(domain, content, list);
|
|
180
|
+
}
|
|
181
|
+
else if (pathname.endsWith('.css')) {
|
|
182
|
+
if (!content)
|
|
183
|
+
content = fs_1.default.readFileSync(path, 'utf-8');
|
|
184
|
+
await eachAllLinkInCss(domain, content, list);
|
|
185
|
+
}
|
|
186
|
+
else if (pathname.endsWith('.js')) {
|
|
187
|
+
if (!content)
|
|
188
|
+
content = fs_1.default.readFileSync(path, 'utf-8');
|
|
189
|
+
await eachAllLinkInJavaScript(domain, content, list);
|
|
84
190
|
}
|
|
85
191
|
});
|
|
192
|
+
return _newVersionJson = {
|
|
193
|
+
version: 3, list
|
|
194
|
+
};
|
|
86
195
|
}
|
|
87
|
-
exports.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
196
|
+
exports.buildVersionJson = buildVersionJson;
|
|
197
|
+
/**
|
|
198
|
+
* 检索一个 URL 指向的文件中所有地外部链接
|
|
199
|
+
*
|
|
200
|
+
* 该函数会处理该 URL 指向的文件和文件中直接或间接包含的所有 URL
|
|
201
|
+
*
|
|
202
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
203
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
204
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
205
|
+
*
|
|
206
|
+
* @param domain 网站域名
|
|
207
|
+
* @param url 要检索的 URL
|
|
208
|
+
* @param result 存放结果的对象
|
|
209
|
+
* @param event 检索到一个 URL 时触发的事件
|
|
210
|
+
*/
|
|
211
|
+
async function eachAllLinkInUrl(domain, url, result, event) {
|
|
212
|
+
if (url.startsWith('//'))
|
|
213
|
+
url = 'http' + url;
|
|
214
|
+
if (url in result)
|
|
215
|
+
return event?.(url);
|
|
216
|
+
if (!url.startsWith('http') || isExclude(domain, url))
|
|
217
|
+
return;
|
|
218
|
+
if (!(isExternalLink(domain, url) && findCache(new URL(url))))
|
|
219
|
+
return;
|
|
220
|
+
event?.(url);
|
|
221
|
+
const stable = isStable(url);
|
|
222
|
+
if (stable) {
|
|
223
|
+
const old = readOldVersionJson().list;
|
|
224
|
+
if (url in old) {
|
|
225
|
+
const copyTree = (key) => {
|
|
226
|
+
const value = old[key];
|
|
227
|
+
if (!value)
|
|
228
|
+
return;
|
|
229
|
+
result[key] = value;
|
|
230
|
+
if (Array.isArray(value)) {
|
|
231
|
+
result[key] = value;
|
|
232
|
+
for (let url of value) {
|
|
233
|
+
copyTree(url);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
event?.(value);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
copyTree(url);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const response = await (0, Utils_1.fetchFile)(url);
|
|
245
|
+
if (![200, 301, 302, 307, 308].includes(response.status))
|
|
93
246
|
throw response;
|
|
94
|
-
const result = [];
|
|
95
247
|
const pathname = new URL(url).pathname;
|
|
96
|
-
let content
|
|
248
|
+
let content;
|
|
249
|
+
const relay = [];
|
|
250
|
+
const nextEvent = (it) => {
|
|
251
|
+
relay.push(it);
|
|
252
|
+
event?.(it);
|
|
253
|
+
};
|
|
97
254
|
switch (true) {
|
|
98
255
|
case pathname.endsWith('.html'):
|
|
99
256
|
case pathname.endsWith('/'):
|
|
100
257
|
content = await response.text();
|
|
101
|
-
|
|
258
|
+
await eachAllLinkInHtml(domain, content, result, nextEvent);
|
|
102
259
|
break;
|
|
103
260
|
case pathname.endsWith('.css'):
|
|
104
261
|
content = await response.text();
|
|
105
|
-
|
|
262
|
+
await eachAllLinkInCss(domain, content, result, nextEvent);
|
|
106
263
|
break;
|
|
107
264
|
case pathname.endsWith('.js'):
|
|
108
265
|
content = await response.text();
|
|
109
|
-
|
|
266
|
+
await eachAllLinkInJavaScript(domain, content, result, nextEvent);
|
|
110
267
|
break;
|
|
111
268
|
default:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
269
|
+
if (stable) {
|
|
270
|
+
result[url] = [];
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
const buffer = buffer_1.Buffer.from(await response.arrayBuffer());
|
|
274
|
+
result[url] = crypto.createHash('md5').update(buffer).digest('hex');
|
|
275
|
+
}
|
|
116
276
|
break;
|
|
117
277
|
}
|
|
118
|
-
if (content)
|
|
119
|
-
|
|
120
|
-
url
|
|
121
|
-
}
|
|
122
|
-
|
|
278
|
+
if (content) {
|
|
279
|
+
if (stable) {
|
|
280
|
+
result[url] = relay;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
result[url] = crypto.createHash('md5').update(content).digest('hex');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
123
286
|
}
|
|
124
287
|
exports.eachAllLinkInUrl = eachAllLinkInUrl;
|
|
125
|
-
/**
|
|
126
|
-
|
|
127
|
-
|
|
288
|
+
/**
|
|
289
|
+
* 检索 HTML 文件中的所有外部链接
|
|
290
|
+
*
|
|
291
|
+
* 该函数仅处理 HTML 当中直接或间接包含的 URL,不处理文件本身
|
|
292
|
+
*
|
|
293
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
294
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
295
|
+
*
|
|
296
|
+
* @param domain 网站域名
|
|
297
|
+
* @param content HTML 文件内容
|
|
298
|
+
* @param result 存放结果的对象
|
|
299
|
+
* @param event 检索到 URL 时触发的事件
|
|
300
|
+
*/
|
|
301
|
+
async function eachAllLinkInHtml(domain, content, result, event) {
|
|
128
302
|
const each = async (node) => {
|
|
129
303
|
let url = undefined;
|
|
130
304
|
switch (node.tagName) {
|
|
@@ -143,63 +317,138 @@ async function eachAllLinkInHtml(webRoot, content, rules) {
|
|
|
143
317
|
break;
|
|
144
318
|
}
|
|
145
319
|
if (url) {
|
|
146
|
-
|
|
147
|
-
result.push(...await eachAllLinkInUrl(webRoot, url, rules));
|
|
320
|
+
await eachAllLinkInUrl(domain, url, result, event);
|
|
148
321
|
}
|
|
149
322
|
else if (node.tagName === 'script') {
|
|
150
|
-
|
|
323
|
+
await eachAllLinkInJavaScript(domain, node.rawText, result, event);
|
|
151
324
|
}
|
|
152
325
|
else if (node.tagName === 'style') {
|
|
153
|
-
|
|
326
|
+
await eachAllLinkInCss(domain, node.rawText, result, event);
|
|
154
327
|
}
|
|
155
328
|
for (let childNode of node.childNodes) {
|
|
156
329
|
await each(childNode);
|
|
157
330
|
}
|
|
158
331
|
};
|
|
159
332
|
await each(fast_html_parser_1.default.parse(content, { style: true, script: true }));
|
|
160
|
-
return result;
|
|
161
333
|
}
|
|
162
334
|
exports.eachAllLinkInHtml = eachAllLinkInHtml;
|
|
163
|
-
/**
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
335
|
+
/**
|
|
336
|
+
* 检索 CSS 文件中的所有外部链
|
|
337
|
+
*
|
|
338
|
+
* 该函数仅处理 CSS 当中直接或间接包含的 URL,不处理文件本身
|
|
339
|
+
*
|
|
340
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
341
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
342
|
+
*
|
|
343
|
+
* @param domain 网站域名
|
|
344
|
+
* @param content CSS 文件内容
|
|
345
|
+
* @param result 存放结果的对象
|
|
346
|
+
* @param event 当检索到一个 URL 后触发的事件
|
|
347
|
+
*/
|
|
348
|
+
async function eachAllLinkInCss(domain, content, result, event) {
|
|
349
|
+
const each = async (any) => {
|
|
350
|
+
if (!any)
|
|
168
351
|
return;
|
|
169
|
-
for (let rule of
|
|
352
|
+
for (let rule of any) {
|
|
353
|
+
switch (rule.type) {
|
|
354
|
+
case 'rule':
|
|
355
|
+
await each(rule.declarations);
|
|
356
|
+
break;
|
|
357
|
+
case 'declaration':
|
|
358
|
+
const value = rule.value;
|
|
359
|
+
const list = value.match(/url\(['"]?([^'")]+)['"]?\)/g)
|
|
360
|
+
?.map(it => it.replace(/(^url\(['"])|(['"]\)$)/g, ''));
|
|
361
|
+
if (list) {
|
|
362
|
+
for (let url of list) {
|
|
363
|
+
await eachAllLinkInUrl(domain, url, result, event);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
break;
|
|
367
|
+
case 'import':
|
|
368
|
+
const url = rule.import.trim().replace(/^["']|["']$/g, '');
|
|
369
|
+
await eachAllLinkInUrl(domain, url, result, event);
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
170
372
|
}
|
|
171
373
|
};
|
|
172
|
-
each(css_1.default.parse(content).stylesheet?.rules);
|
|
173
|
-
return result;
|
|
374
|
+
await each(css_1.default.parse(content).stylesheet?.rules);
|
|
174
375
|
}
|
|
175
376
|
exports.eachAllLinkInCss = eachAllLinkInCss;
|
|
176
|
-
/**
|
|
177
|
-
|
|
377
|
+
/**
|
|
378
|
+
* 遍历 JS 文件中地所有外部链接
|
|
379
|
+
*
|
|
380
|
+
* 该函数仅处理 JS 当中直接或间接包含的 URL,不处理文件本身
|
|
381
|
+
*
|
|
382
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
383
|
+
* + **调用该函数前必须调用过 [loadCacheJson]**
|
|
384
|
+
*
|
|
385
|
+
* @param domain 网站域名
|
|
386
|
+
* @param content JS 文件内容
|
|
387
|
+
* @param result 存放结果的对象
|
|
388
|
+
* @param event 当检索到一个 URL 后触发的事件
|
|
389
|
+
*/
|
|
390
|
+
async function eachAllLinkInJavaScript(domain, content, result, event) {
|
|
391
|
+
const ruleList = (0, SwppRules_1.readRules)().config?.external?.js;
|
|
392
|
+
if (!ruleList)
|
|
393
|
+
throw 'ruleList 为空';
|
|
394
|
+
for (let value of ruleList) {
|
|
395
|
+
if (typeof value === 'function') {
|
|
396
|
+
const urls = value(content);
|
|
397
|
+
for (let url of urls) {
|
|
398
|
+
await eachAllLinkInUrl(domain, url, result, event);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
const { head, tail } = value;
|
|
403
|
+
const reg = new RegExp(`${head}(['"\`])(.*?)(['"\`])${tail}`, 'mg');
|
|
404
|
+
const list = content.match(reg)
|
|
405
|
+
?.map(it => it.substring(head.length, it.length - tail.length).trim())
|
|
406
|
+
?.map(it => it.replace(/^['"`]|['"`]$/g, ''));
|
|
407
|
+
if (list) {
|
|
408
|
+
for (let url of list) {
|
|
409
|
+
await eachAllLinkInUrl(domain, url, result, event);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
178
414
|
}
|
|
179
415
|
exports.eachAllLinkInJavaScript = eachAllLinkInJavaScript;
|
|
180
416
|
/** 判断一个 URL 是否是外部链接 */
|
|
181
|
-
function isExternalLink(
|
|
182
|
-
return
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
417
|
+
function isExternalLink(domain, url) {
|
|
418
|
+
return new RegExp(`^(https?:)?\\/\\/${domain}`).test(url);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* 查询指定 URL 对应的缓存规则
|
|
422
|
+
*
|
|
423
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
424
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
425
|
+
*/
|
|
426
|
+
function findCache(url) {
|
|
427
|
+
const { cacheRules } = (0, SwppRules_1.readRules)();
|
|
428
|
+
const eject = (0, Utils_1.readEjectData)();
|
|
429
|
+
if (typeof url === 'string')
|
|
430
|
+
url = new URL(url);
|
|
431
|
+
url = new URL(replaceRequest(url.href));
|
|
432
|
+
for (let key in cacheRules) {
|
|
433
|
+
const value = cacheRules[key];
|
|
191
434
|
if (value.match(url, eject.nodeEject))
|
|
192
435
|
return value;
|
|
193
436
|
}
|
|
194
437
|
return null;
|
|
195
438
|
}
|
|
196
439
|
exports.findCache = findCache;
|
|
197
|
-
/**
|
|
198
|
-
|
|
440
|
+
/**
|
|
441
|
+
* 替换请求
|
|
442
|
+
*
|
|
443
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
444
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
445
|
+
*/
|
|
446
|
+
function replaceRequest(url) {
|
|
447
|
+
const rules = (0, SwppRules_1.readRules)();
|
|
199
448
|
if (!('modifyRequest' in rules))
|
|
200
449
|
return url;
|
|
201
450
|
const { modifyRequest } = rules;
|
|
202
451
|
const request = new node_fetch_1.Request(url);
|
|
203
|
-
return modifyRequest(request, (0,
|
|
452
|
+
return modifyRequest?.(request, (0, Utils_1.readEjectData)().nodeEject)?.url ?? url;
|
|
204
453
|
}
|
|
205
454
|
exports.replaceRequest = replaceRequest;
|
package/dist/index.js
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Utils_1 = require("./Utils");
|
|
4
|
+
const FileAnalyzer_1 = require("./FileAnalyzer");
|
|
5
|
+
const ServiceWorkerBuilder_1 = require("./ServiceWorkerBuilder");
|
|
6
|
+
const SwppRules_1 = require("./SwppRules");
|
|
7
|
+
const UpdateJsonBuilder_1 = require("./UpdateJsonBuilder");
|
|
8
|
+
const VersionAnalyzer_1 = require("./VersionAnalyzer");
|
|
9
|
+
// noinspection JSUnusedGlobalSymbols
|
|
10
|
+
exports.default = {
|
|
11
|
+
cache: {
|
|
12
|
+
readEjectData: Utils_1.readEjectData, readUpdateJson: UpdateJsonBuilder_1.readUpdateJson,
|
|
13
|
+
readRules: SwppRules_1.readRules, readMergeVersionMap: FileAnalyzer_1.readMergeVersionMap,
|
|
14
|
+
readOldVersionJson: FileAnalyzer_1.readOldVersionJson, readNewVersionJson: FileAnalyzer_1.readNewVersionJson
|
|
15
|
+
},
|
|
16
|
+
builder: {
|
|
17
|
+
buildServiceWorker: ServiceWorkerBuilder_1.buildServiceWorker,
|
|
18
|
+
buildVersionJson: FileAnalyzer_1.buildVersionJson,
|
|
19
|
+
buildNewInfo: UpdateJsonBuilder_1.buildNewInfo,
|
|
20
|
+
calcEjectValues: Utils_1.calcEjectValues,
|
|
21
|
+
analyzer: VersionAnalyzer_1.analyzer
|
|
22
|
+
},
|
|
23
|
+
loader: {
|
|
24
|
+
loadRules: SwppRules_1.loadRules, loadUpdateJson: UpdateJsonBuilder_1.loadUpdateJson, loadVersionJson: FileAnalyzer_1.loadVersionJson
|
|
25
|
+
},
|
|
26
|
+
event: {
|
|
27
|
+
addRulesMapEvent: SwppRules_1.addRulesMapEvent, refreshUrl: VersionAnalyzer_1.refreshUrl, submitChange: UpdateJsonBuilder_1.submitChange, submitCacheInfo: FileAnalyzer_1.submitCacheInfo
|
|
28
|
+
},
|
|
29
|
+
utils: {
|
|
30
|
+
getSource: Utils_1.getSource, getShorthand: UpdateJsonBuilder_1.getShorthand, findCache: FileAnalyzer_1.findCache,
|
|
31
|
+
fetchFile: Utils_1.fetchFile, replaceDevRequest: Utils_1.replaceDevRequest, replaceRequest: FileAnalyzer_1.replaceRequest,
|
|
32
|
+
isStable: FileAnalyzer_1.isStable, isExclude: FileAnalyzer_1.isExclude,
|
|
33
|
+
eachAllLinkInUrl: FileAnalyzer_1.eachAllLinkInUrl, eachAllLinkInHtml: FileAnalyzer_1.eachAllLinkInHtml, eachAllLinkInCss: FileAnalyzer_1.eachAllLinkInCss, eachAllLinkInJavaScript: FileAnalyzer_1.eachAllLinkInJavaScript
|
|
7
34
|
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
35
|
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
const CSSParser = __importStar(require("css"));
|
|
27
|
-
const tmp = CSSParser.parse('.name0 .name1 { color: red; }');
|
|
28
|
-
console.log(tmp);
|
|
@@ -237,29 +237,21 @@
|
|
|
237
237
|
return false
|
|
238
238
|
} else return action(value)
|
|
239
239
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
this.match = url => forEachValues(value => url.endsWith(value))
|
|
255
|
-
break
|
|
256
|
-
case 'str':
|
|
257
|
-
this.match = url => forEachValues(value => url.includes(value))
|
|
258
|
-
break
|
|
259
|
-
case 'reg':
|
|
260
|
-
this.match = url => forEachValues(value => url.match(new RegExp(value, 'i')))
|
|
261
|
-
break
|
|
262
|
-
default: throw `未知表达式:${JSON.stringify(json)}`
|
|
240
|
+
const getMatch = () => {
|
|
241
|
+
switch (json['flag']) {
|
|
242
|
+
case 'html':
|
|
243
|
+
return url => url.match(/(\/|\.html)$/)
|
|
244
|
+
case 'end':
|
|
245
|
+
return url => forEachValues(value => url.endsWith(value))
|
|
246
|
+
case 'begin':
|
|
247
|
+
return url => forEachValues(value => url.startsWith(value))
|
|
248
|
+
case 'str':
|
|
249
|
+
return url => forEachValues(value => url.includes(value))
|
|
250
|
+
case 'reg':
|
|
251
|
+
return url => forEachValues(value => url.match(new RegExp(value, 'i')))
|
|
252
|
+
default: throw `未知表达式:${JSON.stringify(json)}`
|
|
253
|
+
}
|
|
263
254
|
}
|
|
255
|
+
this.match = getMatch()
|
|
264
256
|
}
|
|
265
257
|
})()
|
|
@@ -4,21 +4,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.buildServiceWorker = void 0;
|
|
7
|
-
const
|
|
7
|
+
const SwppRules_1 = require("./SwppRules");
|
|
8
|
+
const Utils_1 = require("./Utils");
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
9
10
|
const path_1 = __importDefault(require("path"));
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* 构建 sw
|
|
13
|
+
*
|
|
14
|
+
* + **执行该函数前必须调用过 [loadRules]**
|
|
15
|
+
* + **执行该函数前必须调用过 [calcEjectValues]**
|
|
16
|
+
*/
|
|
17
|
+
function buildServiceWorker() {
|
|
18
|
+
const rules = (0, SwppRules_1.readRules)();
|
|
19
|
+
const eject = (0, Utils_1.readEjectData)();
|
|
20
|
+
const { modifyRequest, fetchFile, getRaceUrls, getSpareUrls, blockRequest, config } = rules;
|
|
13
21
|
const serviceWorkerConfig = config.serviceWorker;
|
|
14
22
|
const templatePath = path_1.default.resolve('./', module.path, 'sw-template.js');
|
|
15
23
|
// 获取拓展文件
|
|
16
|
-
let cache = (0,
|
|
17
|
-
'cacheList', 'modifyRequest', 'getCdnList', 'getSpareUrls', 'blockRequest',
|
|
24
|
+
let cache = (0, Utils_1.getSource)(rules, undefined, [
|
|
25
|
+
'cacheList', 'modifyRequest', 'getCdnList', 'getSpareUrls', 'blockRequest', 'fetchFile',
|
|
18
26
|
...('external' in rules && Array.isArray(rules.external) ? rules.external : [])
|
|
19
27
|
], true) + '\n';
|
|
20
|
-
if (!
|
|
21
|
-
if (
|
|
28
|
+
if (!fetchFile) {
|
|
29
|
+
if (getRaceUrls)
|
|
22
30
|
cache += JS_CODE_GET_CDN_LIST;
|
|
23
31
|
else if (getSpareUrls)
|
|
24
32
|
cache += JS_CODE_GET_SPARE_URLS;
|
|
@@ -28,9 +36,9 @@ function buildServiceWorker(rules, eject) {
|
|
|
28
36
|
if (!getSpareUrls)
|
|
29
37
|
cache += `\nconst getSpareUrls = _ => {}`;
|
|
30
38
|
if ('afterJoin' in rules)
|
|
31
|
-
cache += `(${(0,
|
|
39
|
+
cache += `(${(0, Utils_1.getSource)(rules['afterJoin'])})()\n`;
|
|
32
40
|
if ('afterTheme' in rules)
|
|
33
|
-
cache += `(${(0,
|
|
41
|
+
cache += `(${(0, Utils_1.getSource)(rules['afterTheme'])})()\n`;
|
|
34
42
|
const keyword = "const { cacheList, fetchFile, getSpareUrls } = require('../sw-rules')";
|
|
35
43
|
// noinspection JSUnresolvedVariable
|
|
36
44
|
let content = fs_1.default.readFileSync(templatePath, 'utf8')
|