UNPKG

@angular/service-worker

Version:

Angular - service worker tooling!

299 lines (290 loc) • 11.9 kB
/** * @license Angular v7.0.2 * (c) 2010-2018 Google, Inc. https://angular.io/ * License: MIT */ import { __awaiter, __generator, __spread } from 'tslib'; /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var PARSE_TO_PAIRS = /([0-9]+[^0-9]+)/g; var PAIR_SPLIT = /^([0-9]+)([dhmsu]+)$/; function parseDurationToMs(duration) { var matches = []; var array; while ((array = PARSE_TO_PAIRS.exec(duration)) !== null) { matches.push(array[0]); } return matches .map(function (match) { var res = PAIR_SPLIT.exec(match); if (res === null) { throw new Error("Not a valid duration: " + match); } var factor = 0; switch (res[2]) { case 'd': factor = 86400000; break; case 'h': factor = 3600000; break; case 'm': factor = 60000; break; case 's': factor = 1000; break; case 'u': factor = 1; break; default: throw new Error("Not a valid duration unit: " + res[2]); } return parseInt(res[1]) * factor; }) .reduce(function (total, value) { return total + value; }, 0); } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var QUESTION_MARK = '[^/]'; var WILD_SINGLE = '[^/]*'; var WILD_OPEN = '(?:.+\\/)?'; var TO_ESCAPE_BASE = [ { replace: /\./g, with: '\\.' }, { replace: /\+/g, with: '\\+' }, { replace: /\*/g, with: WILD_SINGLE }, ]; var TO_ESCAPE_WILDCARD_QM = __spread(TO_ESCAPE_BASE, [ { replace: /\?/g, with: QUESTION_MARK }, ]); var TO_ESCAPE_LITERAL_QM = __spread(TO_ESCAPE_BASE, [ { replace: /\?/g, with: '\\?' }, ]); function globToRegex(glob, literalQuestionMark) { if (literalQuestionMark === void 0) { literalQuestionMark = false; } var toEscape = literalQuestionMark ? TO_ESCAPE_LITERAL_QM : TO_ESCAPE_WILDCARD_QM; var segments = glob.split('/').reverse(); var regex = ''; while (segments.length > 0) { var segment = segments.pop(); if (segment === '**') { if (segments.length > 0) { regex += WILD_OPEN; } else { regex += '.*'; } } else { var processed = toEscape.reduce(function (segment, escape) { return segment.replace(escape.replace, escape.with); }, segment); regex += processed; if (segments.length > 0) { regex += '\\/'; } } } return regex; } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var DEFAULT_NAVIGATION_URLS = [ '/**', '!/**/*.*', '!/**/*__*', '!/**/*__*/**', ]; /** * Consumes service worker configuration files and processes them into control files. * * @publicApi */ var Generator = /** @class */ (function () { function Generator(fs, baseHref) { this.fs = fs; this.baseHref = baseHref; } Generator.prototype.process = function (config) { return __awaiter(this, void 0, void 0, function () { var unorderedHashTable, assetGroups; return __generator(this, function (_a) { switch (_a.label) { case 0: unorderedHashTable = {}; return [4 /*yield*/, this.processAssetGroups(config, unorderedHashTable)]; case 1: assetGroups = _a.sent(); return [2 /*return*/, { configVersion: 1, appData: config.appData, index: joinUrls(this.baseHref, config.index), assetGroups: assetGroups, dataGroups: this.processDataGroups(config), hashTable: withOrderedKeys(unorderedHashTable), navigationUrls: processNavigationUrls(this.baseHref, config.navigationUrls), }]; } }); }); }; Generator.prototype.processAssetGroups = function (config, hashTable) { return __awaiter(this, void 0, void 0, function () { var seenMap; var _this = this; return __generator(this, function (_a) { seenMap = new Set(); return [2 /*return*/, Promise.all((config.assetGroups || []).map(function (group) { return __awaiter(_this, void 0, void 0, function () { var fileMatcher, versionedMatcher, allFiles, plainFiles, versionedFiles, matchedFiles; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (group.resources.versionedFiles) { console.warn("Asset-group '" + group.name + "' in 'ngsw-config.json' uses the 'versionedFiles' option.\n" + 'As of v6 \'versionedFiles\' and \'files\' options have the same behavior. ' + 'Use \'files\' instead.'); } fileMatcher = globListToMatcher(group.resources.files || []); versionedMatcher = globListToMatcher(group.resources.versionedFiles || []); return [4 /*yield*/, this.fs.list('/')]; case 1: allFiles = _a.sent(); plainFiles = allFiles.filter(fileMatcher).filter(function (file) { return !seenMap.has(file); }); plainFiles.forEach(function (file) { return seenMap.add(file); }); versionedFiles = allFiles.filter(versionedMatcher).filter(function (file) { return !seenMap.has(file); }); versionedFiles.forEach(function (file) { return seenMap.add(file); }); matchedFiles = __spread(plainFiles, versionedFiles).sort(); return [4 /*yield*/, matchedFiles.reduce(function (previous, file) { return __awaiter(_this, void 0, void 0, function () { var hash; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, previous]; case 1: _a.sent(); return [4 /*yield*/, this.fs.hash(file)]; case 2: hash = _a.sent(); hashTable[joinUrls(this.baseHref, file)] = hash; return [2 /*return*/]; } }); }); }, Promise.resolve())]; case 2: _a.sent(); return [2 /*return*/, { name: group.name, installMode: group.installMode || 'prefetch', updateMode: group.updateMode || group.installMode || 'prefetch', urls: matchedFiles.map(function (url) { return joinUrls(_this.baseHref, url); }), patterns: (group.resources.urls || []).map(function (url) { return urlToRegex(url, _this.baseHref, true); }), }]; } }); }); }))]; }); }); }; Generator.prototype.processDataGroups = function (config) { var _this = this; return (config.dataGroups || []).map(function (group) { return { name: group.name, patterns: group.urls.map(function (url) { return urlToRegex(url, _this.baseHref, true); }), strategy: group.cacheConfig.strategy || 'performance', maxSize: group.cacheConfig.maxSize, maxAge: parseDurationToMs(group.cacheConfig.maxAge), timeoutMs: group.cacheConfig.timeout && parseDurationToMs(group.cacheConfig.timeout), version: group.version !== undefined ? group.version : 1, }; }); }; return Generator; }()); function processNavigationUrls(baseHref, urls) { if (urls === void 0) { urls = DEFAULT_NAVIGATION_URLS; } return urls.map(function (url) { var positive = !url.startsWith('!'); url = positive ? url : url.substr(1); return { positive: positive, regex: "^" + urlToRegex(url, baseHref) + "$" }; }); } function globListToMatcher(globs) { var patterns = globs.map(function (pattern) { if (pattern.startsWith('!')) { return { positive: false, regex: new RegExp('^' + globToRegex(pattern.substr(1)) + '$'), }; } else { return { positive: true, regex: new RegExp('^' + globToRegex(pattern) + '$'), }; } }); return function (file) { return matches(file, patterns); }; } function matches(file, patterns) { var res = patterns.reduce(function (isMatch, pattern) { if (pattern.positive) { return isMatch || pattern.regex.test(file); } else { return isMatch && !pattern.regex.test(file); } }, false); return res; } function urlToRegex(url, baseHref, literalQuestionMark) { if (!url.startsWith('/') && url.indexOf('://') === -1) { url = joinUrls(baseHref, url); } return globToRegex(url, literalQuestionMark); } function joinUrls(a, b) { if (a.endsWith('/') && b.startsWith('/')) { return a + b.substr(1); } else if (!a.endsWith('/') && !b.startsWith('/')) { return a + '/' + b; } return a + b; } function withOrderedKeys(unorderedObj) { var orderedObj = {}; Object.keys(unorderedObj).sort().forEach(function (key) { return orderedObj[key] = unorderedObj[key]; }); return orderedObj; } /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ /** * Generated bundle index. Do not edit. */ export { Generator }; //# sourceMappingURL=config.js.map