@angular/service-worker
Version:
Angular - service worker tooling!
379 lines (368 loc) • 13 kB
JavaScript
import {createRequire as __cjsCompatRequire} from 'module';
const require = __cjsCompatRequire(import.meta.url);
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/config/src/duration.mjs
var PARSE_TO_PAIRS = /([0-9]+[^0-9]+)/g;
var PAIR_SPLIT = /^([0-9]+)([dhmsu]+)$/;
function parseDurationToMs(duration) {
const matches2 = [];
let array;
while ((array = PARSE_TO_PAIRS.exec(duration)) !== null) {
matches2.push(array[0]);
}
return matches2.map((match) => {
const res = PAIR_SPLIT.exec(match);
if (res === null) {
throw new Error(`Not a valid duration: ${match}`);
}
let factor = 0;
switch (res[2]) {
case "d":
factor = 864e5;
break;
case "h":
factor = 36e5;
break;
case "m":
factor = 6e4;
break;
case "s":
factor = 1e3;
break;
case "u":
factor = 1;
break;
default:
throw new Error(`Not a valid duration unit: ${res[2]}`);
}
return parseInt(res[1]) * factor;
}).reduce((total, value) => total + value, 0);
}
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/config/src/glob.mjs
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 = [...TO_ESCAPE_BASE, { replace: /\?/g, with: QUESTION_MARK }];
var TO_ESCAPE_LITERAL_QM = [...TO_ESCAPE_BASE, { replace: /\?/g, with: "\\?" }];
function globToRegex(glob, literalQuestionMark = false) {
const toEscape = literalQuestionMark ? TO_ESCAPE_LITERAL_QM : TO_ESCAPE_WILDCARD_QM;
const segments = glob.split("/").reverse();
let regex = "";
while (segments.length > 0) {
const segment = segments.pop();
if (segment === "**") {
if (segments.length > 0) {
regex += WILD_OPEN;
} else {
regex += ".*";
}
} else {
const processed = toEscape.reduce((segment2, escape) => segment2.replace(escape.replace, escape.with), segment);
regex += processed;
if (segments.length > 0) {
regex += "\\/";
}
}
}
return regex;
}
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/config/src/generator.mjs
var DEFAULT_NAVIGATION_URLS = [
"/**",
"!/**/*.*",
"!/**/*__*",
"!/**/*__*/**"
];
var Generator = class {
fs;
baseHref;
constructor(fs3, baseHref2) {
this.fs = fs3;
this.baseHref = baseHref2;
}
async process(config2) {
var _a;
const unorderedHashTable = {};
const assetGroups = await this.processAssetGroups(config2, unorderedHashTable);
return {
configVersion: 1,
timestamp: Date.now(),
appData: config2.appData,
index: joinUrls(this.baseHref, config2.index),
assetGroups,
dataGroups: this.processDataGroups(config2),
hashTable: withOrderedKeys(unorderedHashTable),
navigationUrls: processNavigationUrls(this.baseHref, config2.navigationUrls),
navigationRequestStrategy: (_a = config2.navigationRequestStrategy) != null ? _a : "performance",
applicationMaxAge: config2.applicationMaxAge ? parseDurationToMs(config2.applicationMaxAge) : void 0
};
}
async processAssetGroups(config2, hashTable) {
const allFiles = await this.fs.list("/");
const seenMap = /* @__PURE__ */ new Set();
const filesPerGroup = /* @__PURE__ */ new Map();
for (const group of config2.assetGroups || []) {
if (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.`);
}
const fileMatcher = globListToMatcher(group.resources.files || []);
const matchedFiles = allFiles.filter(fileMatcher).filter((file) => !seenMap.has(file)).sort();
matchedFiles.forEach((file) => seenMap.add(file));
filesPerGroup.set(group, matchedFiles);
}
const allMatchedFiles = [].concat(...Array.from(filesPerGroup.values())).sort();
const allMatchedHashes = await processInBatches(allMatchedFiles, 500, (file) => this.fs.hash(file));
allMatchedFiles.forEach((file, idx) => {
hashTable[joinUrls(this.baseHref, file)] = allMatchedHashes[idx];
});
return Array.from(filesPerGroup.entries()).map(([group, matchedFiles]) => ({
name: group.name,
installMode: group.installMode || "prefetch",
updateMode: group.updateMode || group.installMode || "prefetch",
cacheQueryOptions: buildCacheQueryOptions(group.cacheQueryOptions),
urls: matchedFiles.map((url) => joinUrls(this.baseHref, url)),
patterns: (group.resources.urls || []).map((url) => urlToRegex(url, this.baseHref, true))
}));
}
processDataGroups(config2) {
return (config2.dataGroups || []).map((group) => {
return {
name: group.name,
patterns: group.urls.map((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),
refreshAheadMs: group.cacheConfig.refreshAhead && parseDurationToMs(group.cacheConfig.refreshAhead),
cacheOpaqueResponses: group.cacheConfig.cacheOpaqueResponses,
cacheQueryOptions: buildCacheQueryOptions(group.cacheQueryOptions),
version: group.version !== void 0 ? group.version : 1
};
});
}
};
function processNavigationUrls(baseHref2, urls = DEFAULT_NAVIGATION_URLS) {
return urls.map((url) => {
const positive = !url.startsWith("!");
url = positive ? url : url.slice(1);
return { positive, regex: `^${urlToRegex(url, baseHref2)}$` };
});
}
async function processInBatches(items, batchSize, processFn) {
const batches = [];
for (let i = 0; i < items.length; i += batchSize) {
batches.push(items.slice(i, i + batchSize));
}
return batches.reduce(async (prev, batch) => (await prev).concat(await Promise.all(batch.map((item) => processFn(item)))), Promise.resolve([]));
}
function globListToMatcher(globs) {
const patterns = globs.map((pattern) => {
if (pattern.startsWith("!")) {
return {
positive: false,
regex: new RegExp("^" + globToRegex(pattern.slice(1)) + "$")
};
} else {
return {
positive: true,
regex: new RegExp("^" + globToRegex(pattern) + "$")
};
}
});
return (file) => matches(file, patterns);
}
function matches(file, patterns) {
return patterns.reduce((isMatch, pattern) => {
if (pattern.positive) {
return isMatch || pattern.regex.test(file);
} else {
return isMatch && !pattern.regex.test(file);
}
}, false);
}
function urlToRegex(url, baseHref2, literalQuestionMark) {
if (!url.startsWith("/") && url.indexOf("://") === -1) {
url = joinUrls(baseHref2.replace(/^\.(?=\/)/, ""), url);
}
return globToRegex(url, literalQuestionMark);
}
function joinUrls(a, b) {
if (a.endsWith("/") && b.startsWith("/")) {
return a + b.slice(1);
} else if (!a.endsWith("/") && !b.startsWith("/")) {
return a + "/" + b;
}
return a + b;
}
function withOrderedKeys(unorderedObj) {
const orderedObj = {};
Object.keys(unorderedObj).sort().forEach((key) => orderedObj[key] = unorderedObj[key]);
return orderedObj;
}
function buildCacheQueryOptions(inOptions) {
return {
ignoreVary: true,
...inOptions
};
}
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/cli/main.mjs
import * as fs2 from "fs";
import * as path2 from "path";
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/cli/filesystem.mjs
import * as fs from "fs";
import * as path from "path";
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/cli/sha1.mjs
function sha1Binary(buffer) {
const words32 = arrayBufferToWords32(buffer, Endian.Big);
return _sha1(words32, buffer.byteLength * 8);
}
function _sha1(words32, len) {
const w = [];
let [a, b, c, d, e] = [1732584193, 4023233417, 2562383102, 271733878, 3285377520];
words32[len >> 5] |= 128 << 24 - len % 32;
words32[(len + 64 >> 9 << 4) + 15] = len;
for (let i = 0; i < words32.length; i += 16) {
const [h0, h1, h2, h3, h4] = [a, b, c, d, e];
for (let j = 0; j < 80; j++) {
if (j < 16) {
w[j] = words32[i + j];
} else {
w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
}
const [f, k] = fk(j, b, c, d);
const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
[e, d, c, b, a] = [d, c, rol32(b, 30), a, temp];
}
[a, b, c, d, e] = [add32(a, h0), add32(b, h1), add32(c, h2), add32(d, h3), add32(e, h4)];
}
return byteStringToHexString(words32ToByteString([a, b, c, d, e]));
}
function add32(a, b) {
return add32to64(a, b)[1];
}
function add32to64(a, b) {
const low = (a & 65535) + (b & 65535);
const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
return [high >>> 16, high << 16 | low & 65535];
}
function rol32(a, count) {
return a << count | a >>> 32 - count;
}
var Endian;
(function(Endian2) {
Endian2[Endian2["Little"] = 0] = "Little";
Endian2[Endian2["Big"] = 1] = "Big";
})(Endian || (Endian = {}));
function fk(index, b, c, d) {
if (index < 20) {
return [b & c | ~b & d, 1518500249];
}
if (index < 40) {
return [b ^ c ^ d, 1859775393];
}
if (index < 60) {
return [b & c | b & d | c & d, 2400959708];
}
return [b ^ c ^ d, 3395469782];
}
function arrayBufferToWords32(buffer, endian) {
const size = buffer.byteLength + 3 >>> 2;
const words32 = [];
const view = new Uint8Array(buffer);
for (let i = 0; i < size; i++) {
words32[i] = wordAt(view, i * 4, endian);
}
return words32;
}
function byteAt(str, index) {
if (typeof str === "string") {
return index >= str.length ? 0 : str.charCodeAt(index) & 255;
} else {
return index >= str.byteLength ? 0 : str[index] & 255;
}
}
function wordAt(str, index, endian) {
let word = 0;
if (endian === Endian.Big) {
for (let i = 0; i < 4; i++) {
word += byteAt(str, index + i) << 24 - 8 * i;
}
} else {
for (let i = 0; i < 4; i++) {
word += byteAt(str, index + i) << 8 * i;
}
}
return word;
}
function words32ToByteString(words32) {
return words32.reduce((str, word) => str + word32ToByteString(word), "");
}
function word32ToByteString(word) {
let str = "";
for (let i = 0; i < 4; i++) {
str += String.fromCharCode(word >>> 8 * (3 - i) & 255);
}
return str;
}
function byteStringToHexString(str) {
let hex = "";
for (let i = 0; i < str.length; i++) {
const b = byteAt(str, i);
hex += (b >>> 4).toString(16) + (b & 15).toString(16);
}
return hex.toLowerCase();
}
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/cli/filesystem.mjs
var NodeFilesystem = class {
base;
constructor(base) {
this.base = base;
}
async list(_path) {
const dir = this.canonical(_path);
const entries = fs.readdirSync(dir).map((entry) => ({ entry, stats: fs.statSync(path.join(dir, entry)) }));
const files = entries.filter((entry) => !entry.stats.isDirectory()).map((entry) => path.posix.join(_path, entry.entry));
return entries.filter((entry) => entry.stats.isDirectory()).map((entry) => path.posix.join(_path, entry.entry)).reduce(async (list, subdir) => (await list).concat(await this.list(subdir)), Promise.resolve(files));
}
async read(_path) {
const file = this.canonical(_path);
return fs.readFileSync(file).toString();
}
async hash(_path) {
const file = this.canonical(_path);
const contents = fs.readFileSync(file);
return sha1Binary(contents);
}
async write(_path, contents) {
const file = this.canonical(_path);
fs.writeFileSync(file, contents);
}
canonical(_path) {
return path.posix.join(this.base, _path);
}
};
// bazel-out/darwin_arm64-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/cli/main.mjs
var cwd = process.cwd();
var distDir = path2.join(cwd, process.argv[2]);
var config = path2.join(cwd, process.argv[3]);
var baseHref = process.argv[4] || "/";
var configParsed = JSON.parse(fs2.readFileSync(config).toString());
var filesystem = new NodeFilesystem(distDir);
var gen = new Generator(filesystem, baseHref);
(async () => {
const control = await gen.process(configParsed);
await filesystem.write("/ngsw.json", JSON.stringify(control, null, 2));
})();
/**
* @license
* Copyright Google LLC 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.dev/license
*/
//# sourceMappingURL=ngsw_config.js.map