/** * @license Angular v9.0.7 * (c) 2010-2020 Google LLC. https://angular.io/ * License: MIT */ import { __awaiter } from 'tslib'; /** * @fileoverview added by tsickle * Generated from: packages/service-worker/config/src/duration.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @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 */ /** @type {?} */ const PARSE_TO_PAIRS = /([0-9]+[^0-9]+)/g; /** @type {?} */ const PAIR_SPLIT = /^([0-9]+)([dhmsu]+)$/; /** * @param {?} duration * @return {?} */ function parseDurationToMs(duration) { /** @type {?} */ const matches = []; /** @type {?} */ let array; while ((array = PARSE_TO_PAIRS.exec(duration)) !== null) { matches.push(array[0]); } return matches .map((/** * @param {?} match * @return {?} */ match => { /** @type {?} */ const res = PAIR_SPLIT.exec(match); if (res === null) { throw new Error(`Not a valid duration: ${match}`); } /** @type {?} */ let 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((/** * @param {?} total * @param {?} value * @return {?} */ (total, value) => total + value), 0); } /** * @fileoverview added by tsickle * Generated from: packages/service-worker/config/src/glob.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @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 */ /** @type {?} */ const QUESTION_MARK = '[^/]'; /** @type {?} */ const WILD_SINGLE = '[^/]*'; /** @type {?} */ const WILD_OPEN = '(?:.+\\/)?'; /** @type {?} */ const TO_ESCAPE_BASE = [ { replace: /\./g, with: '\\.' }, { replace: /\+/g, with: '\\+' }, { replace: /\*/g, with: WILD_SINGLE }, ]; /** @type {?} */ const TO_ESCAPE_WILDCARD_QM = [ ...TO_ESCAPE_BASE, { replace: /\?/g, with: QUESTION_MARK }, ]; /** @type {?} */ const TO_ESCAPE_LITERAL_QM = [ ...TO_ESCAPE_BASE, { replace: /\?/g, with: '\\?' }, ]; /** * @param {?} glob * @param {?=} literalQuestionMark * @return {?} */ function globToRegex(glob, literalQuestionMark = false) { /** @type {?} */ const toEscape = literalQuestionMark ? TO_ESCAPE_LITERAL_QM : TO_ESCAPE_WILDCARD_QM; /** @type {?} */ const segments = glob.split('/').reverse(); /** @type {?} */ let regex = ''; while (segments.length > 0) { /** @type {?} */ const segment = (/** @type {?} */ (segments.pop())); if (segment === '**') { if (segments.length > 0) { regex += WILD_OPEN; } else { regex += '.*'; } } else { /** @type {?} */ const processed = toEscape.reduce((/** * @param {?} segment * @param {?} escape * @return {?} */ (segment, escape) => segment.replace(escape.replace, escape.with)), segment); regex += processed; if (segments.length > 0) { regex += '\\/'; } } } return regex; } /** * @fileoverview added by tsickle * Generated from: packages/service-worker/config/src/generator.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const DEFAULT_NAVIGATION_URLS = [ '/**', '!/**/*.*', '!/**/*__*', '!/**/*__*/**', ]; /** * Consumes service worker configuration files and processes them into control files. * * \@publicApi */ class Generator { /** * @param {?} fs * @param {?} baseHref */ constructor(fs, baseHref) { this.fs = fs; this.baseHref = baseHref; } /** * @param {?} config * @return {?} */ process(config) { return __awaiter(this, void 0, void 0, function* () { /** @type {?} */ const unorderedHashTable = {}; /** @type {?} */ const assetGroups = yield this.processAssetGroups(config, unorderedHashTable); return { configVersion: 1, timestamp: Date.now(), appData: config.appData, index: joinUrls(this.baseHref, config.index), assetGroups, dataGroups: this.processDataGroups(config), hashTable: withOrderedKeys(unorderedHashTable), navigationUrls: processNavigationUrls(this.baseHref, config.navigationUrls), }; }); } /** * @private * @param {?} config * @param {?} hashTable * @return {?} */ processAssetGroups(config, hashTable) { return __awaiter(this, void 0, void 0, function* () { /** @type {?} */ const seenMap = new Set(); return Promise.all((config.assetGroups || []).map((/** * @param {?} group * @return {?} */ (group) => __awaiter(this, void 0, void 0, function* () { if (((/** @type {?} */ (group.resources))).versionedFiles) { throw new Error(`Asset-group '${group.name}' in 'ngsw-config.json' uses the 'versionedFiles' option, ` + 'which is no longer supported. Use \'files\' instead.'); } /** @type {?} */ const fileMatcher = globListToMatcher(group.resources.files || []); /** @type {?} */ const allFiles = yield this.fs.list('/'); /** @type {?} */ const matchedFiles = allFiles.filter(fileMatcher).filter((/** * @param {?} file * @return {?} */ file => !seenMap.has(file))).sort(); matchedFiles.forEach((/** * @param {?} file * @return {?} */ file => seenMap.add(file))); // Add the hashes. yield matchedFiles.reduce((/** * @param {?} previous * @param {?} file * @return {?} */ (previous, file) => __awaiter(this, void 0, void 0, function* () { yield previous; /** @type {?} */ const hash = yield this.fs.hash(file); hashTable[joinUrls(this.baseHref, file)] = hash; })), Promise.resolve()); return { name: group.name, installMode: group.installMode || 'prefetch', updateMode: group.updateMode || group.installMode || 'prefetch', urls: matchedFiles.map((/** * @param {?} url * @return {?} */ url => joinUrls(this.baseHref, url))), patterns: (group.resources.urls || []).map((/** * @param {?} url * @return {?} */ url => urlToRegex(url, this.baseHref, true))), }; })))); }); } /** * @private * @param {?} config * @return {?} */ processDataGroups(config) { return (config.dataGroups || []).map((/** * @param {?} group * @return {?} */ group => { return { name: group.name, patterns: group.urls.map((/** * @param {?} url * @return {?} */ url => 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, }; })); } } if (false) { /** @type {?} */ Generator.prototype.fs; /** * @type {?} * @private */ Generator.prototype.baseHref; } /** * @param {?} baseHref * @param {?=} urls * @return {?} */ function processNavigationUrls(baseHref, urls = DEFAULT_NAVIGATION_URLS) { return urls.map((/** * @param {?} url * @return {?} */ url => { /** @type {?} */ const positive = !url.startsWith('!'); url = positive ? url : url.substr(1); return { positive, regex: `^${urlToRegex(url, baseHref)}$` }; })); } /** * @param {?} globs * @return {?} */ function globListToMatcher(globs) { /** @type {?} */ const patterns = globs.map((/** * @param {?} pattern * @return {?} */ pattern => { if (pattern.startsWith('!')) { return { positive: false, regex: new RegExp('^' + globToRegex(pattern.substr(1)) + '$'), }; } else { return { positive: true, regex: new RegExp('^' + globToRegex(pattern) + '$'), }; } })); return (/** * @param {?} file * @return {?} */ (file) => matches(file, patterns)); } /** * @param {?} file * @param {?} patterns * @return {?} */ function matches(file, patterns) { /** @type {?} */ const res = patterns.reduce((/** * @param {?} isMatch * @param {?} pattern * @return {?} */ (isMatch, pattern) => { if (pattern.positive) { return isMatch || pattern.regex.test(file); } else { return isMatch && !pattern.regex.test(file); } }), false); return res; } /** * @param {?} url * @param {?} baseHref * @param {?=} literalQuestionMark * @return {?} */ function urlToRegex(url, baseHref, literalQuestionMark) { if (!url.startsWith('/') && url.indexOf('://') === -1) { url = joinUrls(baseHref, url); } return globToRegex(url, literalQuestionMark); } /** * @param {?} a * @param {?} b * @return {?} */ 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; } /** * @template T * @param {?} unorderedObj * @return {?} */ function withOrderedKeys(unorderedObj) { /** @type {?} */ const orderedObj = (/** @type {?} */ ({})); Object.keys(unorderedObj).sort().forEach((/** * @param {?} key * @return {?} */ key => orderedObj[key] = unorderedObj[key])); return (/** @type {?} */ (orderedObj)); } /** * @fileoverview added by tsickle * Generated from: packages/service-worker/config/public_api.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * Generated from: packages/service-worker/config/index.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Generated bundle index. Do not edit. */ export { Generator }; //# sourceMappingURL=config.js.map