@serwist/build
Version:
A module that integrates into your build process, helping you generate a manifest of local files that should be precached.
1 lines • 51.8 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/errors.ts","../src/lib/get-composite-details.ts","../src/lib/get-string-hash.ts","../src/lib/get-file-hash.ts","../src/lib/get-file-size.ts","../src/lib/get-file-details.ts","../src/lib/get-string-details.ts","../src/lib/additional-precache-entries-transform.ts","../src/lib/maximum-size-transform.ts","../src/lib/escape-regexp.ts","../src/lib/modify-url-prefix-transform.ts","../src/lib/no-revision-for-urls-matching-transform.ts","../src/lib/transform-manifest.ts","../src/lib/get-file-manifest-entries.ts","../src/lib/validate-options.ts","../src/get-manifest.ts","../src/lib/get-source-map-url.ts","../src/lib/rebase-path.ts","../src/lib/replace-and-update-source-map.ts","../src/lib/translate-url-to-sourcemap-paths.ts","../src/inject-manifest.ts","../src/index.ts"],"sourcesContent":["/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport { oneLine as ol } from \"common-tags\";\n\nexport const errors = {\n \"unable-to-get-rootdir\": \"Unable to get the root directory of your web app.\",\n \"no-extension\": ol`Unable to detect a usable extension for a file in your web\n app directory.`,\n \"invalid-file-manifest-name\": ol`The File Manifest Name must have at least one\n character.`,\n \"unable-to-get-file-manifest-name\": \"Unable to get a file manifest name.\",\n \"invalid-sw-dest\": `The 'swDest' value must be a valid path.`,\n \"unable-to-get-sw-name\": \"Unable to get a service worker file name.\",\n \"unable-to-get-save-config\": ol`An error occurred when asking to save details\n in a config file.`,\n \"unable-to-get-file-hash\": ol`An error occurred when attempting to create a\n file hash.`,\n \"unable-to-get-file-size\": ol`An error occurred when attempting to get a file\n size.`,\n \"unable-to-glob-files\": \"An error occurred when globbing for files.\",\n \"unable-to-make-manifest-directory\": ol`Unable to make output directory for\n file manifest.`,\n \"read-manifest-template-failure\": \"Unable to read template for file manifest\",\n \"populating-manifest-tmpl-failed\": ol`An error occurred when populating the\n file manifest template.`,\n \"manifest-file-write-failure\": \"Unable to write the file manifest.\",\n \"unable-to-make-sw-directory\": ol`Unable to make the directories to output\n the service worker path.`,\n \"sw-write-failure\": \"Unable to write the service worker file.\",\n \"sw-write-failure-directory\": ol`Unable to write the service worker file;\n 'swDest' should be a full path to the file, not a path to a directory.`,\n \"unable-to-copy-serwist-libraries\": ol`One or more of the Serwist libraries\n could not be copied over to the destination directory: `,\n \"invalid-glob-directory\": ol`The supplied globDirectory must be a path as a\n string.`,\n \"invalid-dont-cache-bust\": ol`The supplied 'dontCacheBustURLsMatching'\n parameter must be a RegExp.`,\n \"invalid-exclude-files\": \"The excluded files should be an array of strings.\",\n \"invalid-get-manifest-entries-input\": ol`The input to\n 'getFileManifestEntries()' must be an object.`,\n \"invalid-manifest-path\": ol`The supplied manifest path is not a string with\n at least one character.`,\n \"invalid-manifest-entries\": ol`The manifest entries must be an array of\n strings or JavaScript objects containing a url parameter.`,\n \"invalid-manifest-format\": ol`The value of the 'format' option passed to\n generateFileManifest() must be either 'iife' (the default) or 'es'.`,\n \"invalid-static-file-globs\": ol`The 'globPatterns' value must be an array\n of strings.`,\n \"invalid-templated-urls\": ol`The 'templatedURLs' value should be an object\n that maps URLs to either a string, or to an array of glob patterns.`,\n \"templated-url-matches-glob\": ol`One of the 'templatedURLs' URLs is already\n being tracked via 'globPatterns': `,\n \"invalid-glob-ignores\": ol`The 'globIgnores' parameter must be an array of\n glob pattern strings.`,\n \"manifest-entry-bad-url\": ol`The generated manifest contains an entry without\n a URL string. This is likely an error with @serwist/build.`,\n \"modify-url-prefix-bad-prefixes\": ol`The 'modifyURLPrefix' parameter must be\n an object with string key value pairs.`,\n \"invalid-inject-manifest-arg\": ol`The input to 'injectManifest()' must be an\n object.`,\n \"injection-point-not-found\": ol`Unable to find a place to inject the manifest.\n Please ensure that your service worker file contains the following: `,\n \"multiple-injection-points\": ol`Please ensure that your 'swSrc' file contains\n only one match for the following: `,\n \"bad-template-urls-asset\": ol`There was an issue using one of the provided\n 'templatedURLs'.`,\n \"invalid-generate-file-manifest-arg\": ol`The input to generateFileManifest()\n must be an Object.`,\n \"invalid-sw-src\": `The 'swSrc' file can't be read.`,\n \"same-src-and-dest\": ol`Unable to find a place to inject the manifest. This is\n likely because swSrc and swDest are configured to the same file.\n Please ensure that your swSrc file contains the following:`,\n \"no-module-name\": ol`You must provide a moduleName parameter when calling\n getModuleURL().`,\n \"bad-manifest-transforms-return-value\": ol`The return value from a\n manifestTransform should be an object with 'manifest' and optionally\n 'warnings' properties.`,\n \"string-entry-warning\": ol`Some items were passed to additionalPrecacheEntries\n without revisioning info. This is generally NOT safe. Learn more at\n https://bit.ly/wb-precache.`,\n \"cant-find-sourcemap\": ol`The swSrc file refers to a sourcemap that can't be\n opened:`,\n \"manifest-transforms\": ol`When using manifestTransforms, you must provide\n an array of functions.`,\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport crypto from \"node:crypto\";\n\nimport type { FileDetails } from \"../types.js\";\n\nexport const getCompositeDetails = (compositeURL: string, dependencyDetails: FileDetails[]): FileDetails => {\n let totalSize = 0;\n let compositeHash = \"\";\n\n for (const fileDetails of dependencyDetails) {\n totalSize += fileDetails.size;\n compositeHash += fileDetails.hash === null ? \"\" : fileDetails.hash;\n }\n\n const md5 = crypto.createHash(\"md5\");\n md5.update(compositeHash);\n const hashOfHashes = md5.digest(\"hex\");\n\n return {\n file: compositeURL,\n hash: hashOfHashes,\n size: totalSize,\n };\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport crypto from \"node:crypto\";\n\nexport function getStringHash(input: crypto.BinaryLike): string {\n const md5 = crypto.createHash(\"md5\");\n md5.update(input);\n return md5.digest(\"hex\");\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport { readFileSync } from \"node:fs\";\n\nimport { errors } from \"./errors.js\";\nimport { getStringHash } from \"./get-string-hash.js\";\n\nexport const getFileHash = (file: string): string => {\n try {\n const buffer = readFileSync(file);\n return getStringHash(buffer);\n } catch (err) {\n throw new Error(`${errors[\"unable-to-get-file-hash\"]} '${err instanceof Error && err.message ? err.message : \"\"}'`);\n }\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport fs from \"node:fs\";\nimport { errors } from \"./errors.js\";\n\nexport const getFileSize = (file: string): number | null => {\n try {\n const stat = fs.statSync(file);\n if (!stat.isFile()) {\n return null;\n }\n return stat.size;\n } catch (err) {\n throw new Error(`${errors[\"unable-to-get-file-size\"]} '${err instanceof Error && err.message ? err.message : \"\"}'`);\n }\n};\n","/*\n Copyright 2021 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport path from \"node:path\";\nimport { globSync } from \"glob\";\nimport type { FileDetails, GlobPartial } from \"../types.js\";\nimport { errors } from \"./errors.js\";\nimport { getFileHash } from \"./get-file-hash.js\";\nimport { getFileSize } from \"./get-file-size.js\";\n\nexport const getFileDetails = ({\n globDirectory,\n globFollow,\n globIgnores,\n globPattern,\n}: Omit<GlobPartial, \"globDirectory\" | \"globPatterns\" | \"templatedURLs\"> & {\n // This will only be called when globDirectory is not undefined.\n globDirectory: string;\n globPattern: string;\n}): {\n globbedFileDetails: FileDetails[];\n warning: string;\n} => {\n let globbedFiles: string[];\n let warning = \"\";\n\n try {\n globbedFiles = globSync(globPattern, {\n cwd: globDirectory,\n follow: globFollow,\n ignore: globIgnores,\n });\n } catch (err) {\n throw new Error(`${errors[\"unable-to-glob-files\"]} '${err instanceof Error && err.message ? err.message : \"\"}'`);\n }\n\n const globbedFileDetails: FileDetails[] = [];\n for (const file of globbedFiles) {\n const fullPath = path.join(globDirectory, file);\n const fileSize = getFileSize(fullPath);\n if (fileSize !== null) {\n const fileHash = getFileHash(fullPath);\n globbedFileDetails.push({\n file: path.relative(globDirectory, fullPath),\n hash: fileHash,\n size: fileSize,\n });\n }\n }\n\n return { globbedFileDetails, warning };\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { FileDetails } from \"../types.js\";\nimport { getStringHash } from \"./get-string-hash.js\";\n\nexport const getStringDetails = (url: string, str: string): FileDetails => ({\n file: url,\n hash: getStringHash(str),\n size: str.length,\n});\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { ManifestEntry } from \"../types.js\";\nimport { errors } from \"./errors.js\";\n\ntype AdditionalManifestEntriesTransform = (manifest: (ManifestEntry & { size: number })[]) => {\n manifest: (ManifestEntry & { size: number })[];\n warnings: string[];\n};\n\nexport const additionalPrecacheEntriesTransform = (additionalPrecacheEntries: (ManifestEntry | string)[]): AdditionalManifestEntriesTransform => {\n return (manifest: (ManifestEntry & { size: number })[]) => {\n const warnings: string[] = [];\n const stringEntries = new Set<string>();\n\n for (const additionalEntry of additionalPrecacheEntries) {\n // Warn about either a string or an object that lacks a revision property.\n // (An object with a revision property set to null is okay.)\n if (typeof additionalEntry === \"string\") {\n stringEntries.add(additionalEntry);\n manifest.push({\n revision: null,\n size: 0,\n url: additionalEntry,\n });\n } else {\n if (additionalEntry && !additionalEntry.integrity && additionalEntry.revision === undefined) {\n stringEntries.add(additionalEntry.url);\n }\n manifest.push(Object.assign({ size: 0 }, additionalEntry));\n }\n }\n\n if (stringEntries.size > 0) {\n let urls = \"\\n\";\n for (const stringEntry of stringEntries) {\n urls += ` - ${stringEntry}\\n`;\n }\n\n warnings.push(errors[\"string-entry-warning\"] + urls);\n }\n\n return {\n manifest,\n warnings,\n };\n };\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport prettyBytes from \"pretty-bytes\";\n\nimport type { ManifestTransform } from \"../types.js\";\n\nexport function maximumSizeTransform(maximumFileSizeToCacheInBytes: number): ManifestTransform {\n return (originalManifest) => {\n const warnings: string[] = [];\n const manifest = originalManifest.filter((entry) => {\n if (entry.size <= maximumFileSizeToCacheInBytes) {\n return true;\n }\n\n warnings.push(\n `${entry.url} is ${prettyBytes(entry.size)}, and won't be precached. Configure maximumFileSizeToCacheInBytes to change this limit.`,\n );\n return false;\n });\n\n return { manifest, warnings };\n };\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\n// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\nexport const escapeRegExp = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { ManifestTransform } from \"../types.js\";\nimport { errors } from \"./errors.js\";\nimport { escapeRegExp } from \"./escape-regexp.js\";\n\nexport function modifyURLPrefixTransform(modifyURLPrefix: { [key: string]: string }): ManifestTransform {\n if (!modifyURLPrefix || typeof modifyURLPrefix !== \"object\" || Array.isArray(modifyURLPrefix)) {\n throw new Error(errors[\"modify-url-prefix-bad-prefixes\"]);\n }\n\n // If there are no entries in modifyURLPrefix, just return an identity\n // function as a shortcut.\n if (Object.keys(modifyURLPrefix).length === 0) {\n return (manifest) => {\n return { manifest };\n };\n }\n\n for (const key of Object.keys(modifyURLPrefix)) {\n if (typeof modifyURLPrefix[key] !== \"string\") {\n throw new Error(errors[\"modify-url-prefix-bad-prefixes\"]);\n }\n }\n\n // Escape the user input so it's safe to use in a regex.\n const safeModifyURLPrefixes = Object.keys(modifyURLPrefix).map(escapeRegExp);\n // Join all the `modifyURLPrefix` keys so a single regex can be used.\n const prefixMatchesStrings = safeModifyURLPrefixes.join(\"|\");\n // Add `^` to the front the prefix matches so it only matches the start of\n // a string.\n const modifyRegex = new RegExp(`^(${prefixMatchesStrings})`);\n\n return (originalManifest) => {\n const manifest = originalManifest.map((entry) => {\n if (typeof entry.url !== \"string\") {\n throw new Error(errors[\"manifest-entry-bad-url\"]);\n }\n\n entry.url = entry.url.replace(modifyRegex, (match) => {\n return modifyURLPrefix[match];\n });\n\n return entry;\n });\n\n return { manifest };\n };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { ManifestTransform } from \"../types.js\";\nimport { errors } from \"./errors.js\";\n\nexport function noRevisionForURLsMatchingTransform(regexp: RegExp): ManifestTransform {\n if (!(regexp instanceof RegExp)) {\n throw new Error(errors[\"invalid-dont-cache-bust\"]);\n }\n\n return (originalManifest) => {\n const manifest = originalManifest.map((entry) => {\n if (typeof entry.url !== \"string\") {\n throw new Error(errors[\"manifest-entry-bad-url\"]);\n }\n\n if (entry.url.match(regexp)) {\n entry.revision = null;\n }\n\n return entry;\n });\n\n return { manifest };\n };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { BaseResolved, FileDetails, ManifestEntry, ManifestTransform } from \"../types.js\";\nimport { additionalPrecacheEntriesTransform } from \"./additional-precache-entries-transform.js\";\nimport { errors } from \"./errors.js\";\nimport { maximumSizeTransform } from \"./maximum-size-transform.js\";\nimport { modifyURLPrefixTransform } from \"./modify-url-prefix-transform.js\";\nimport { noRevisionForURLsMatchingTransform } from \"./no-revision-for-urls-matching-transform.js\";\n\n/**\n * A `ManifestTransform` function can be used to modify the modify the `url` or\n * `revision` properties of some or all of the {@linkcode ManifestEntry} in the manifest.\n *\n * Deleting the `revision` property of an entry will cause\n * the corresponding `url` to be precached without cache-busting parameters\n * applied, which is to say, it implies that the URL itself contains\n * proper versioning info. If the `revision` property is present, it must be\n * set to a string.\n *\n * @example A transformation that prepended the origin of a CDN for any\n * URL starting with '/assets/' could be implemented as:\n *\n * const cdnTransform = async (manifestEntries) => {\n * const manifest = manifestEntries.map(entry => {\n * const cdnOrigin = 'https://example.com';\n * if (entry.url.startsWith('/assets/')) {\n * entry.url = cdnOrigin + entry.url;\n * }\n * return entry;\n * });\n * return {manifest, warnings: []};\n * };\n *\n * @example A transformation that nulls the revision field when the\n * URL contains an 8-character hash surrounded by '.', indicating that it\n * already contains revision information:\n *\n * const removeRevisionTransform = async (manifestEntries) => {\n * const manifest = manifestEntries.map(entry => {\n * const hashRegExp = /\\.\\w{8}\\./;\n * if (entry.url.match(hashRegExp)) {\n * entry.revision = null;\n * }\n * return entry;\n * });\n * return {manifest, warnings: []};\n * };\n *\n * @callback ManifestTransform\n * @param manifestEntries The full\n * array of entries, prior to the current transformation.\n * @param compilation When used in the webpack plugins, this param\n * will be set to the current `compilation`.\n * @returns The array of entries with the transformation applied,\n * and optionally, any warnings that should be reported back to the build tool.\n */\ninterface ManifestTransformResultWithWarnings {\n count: number;\n size: number;\n manifestEntries: ManifestEntry[] | undefined;\n warnings: string[];\n}\ninterface ManifestEntryWithSize extends ManifestEntry {\n size: number;\n}\ninterface TransformManifestOptions\n extends Pick<\n BaseResolved,\n | \"additionalPrecacheEntries\"\n | \"dontCacheBustURLsMatching\"\n | \"manifestTransforms\"\n | \"maximumFileSizeToCacheInBytes\"\n | \"modifyURLPrefix\"\n | \"disablePrecacheManifest\"\n > {\n fileDetails: FileDetails[];\n // When this is called by the webpack plugin, transformParam will be the\n // current webpack compilation.\n transformParam?: unknown;\n}\n\nexport async function transformManifest({\n additionalPrecacheEntries,\n dontCacheBustURLsMatching,\n fileDetails,\n manifestTransforms,\n maximumFileSizeToCacheInBytes,\n modifyURLPrefix,\n transformParam,\n disablePrecacheManifest,\n}: TransformManifestOptions): Promise<ManifestTransformResultWithWarnings> {\n if (disablePrecacheManifest) {\n return {\n count: 0,\n size: 0,\n manifestEntries: undefined,\n warnings: [],\n };\n }\n\n const allWarnings: string[] = [];\n\n // Take the array of fileDetail objects and convert it into an array of\n // {url, revision, size} objects, with \\ replaced with /.\n const normalizedManifest: ManifestEntryWithSize[] = fileDetails.map((fileDetails) => ({\n url: fileDetails.file.replace(/\\\\/g, \"/\"),\n revision: fileDetails.hash,\n size: fileDetails.size,\n }));\n\n const transformsToApply: ManifestTransform[] = [];\n\n if (maximumFileSizeToCacheInBytes) {\n transformsToApply.push(maximumSizeTransform(maximumFileSizeToCacheInBytes));\n }\n\n if (modifyURLPrefix) {\n transformsToApply.push(modifyURLPrefixTransform(modifyURLPrefix));\n }\n\n if (dontCacheBustURLsMatching) {\n transformsToApply.push(noRevisionForURLsMatchingTransform(dontCacheBustURLsMatching));\n }\n\n // Run any manifestTransforms functions second-to-last.\n if (manifestTransforms) {\n transformsToApply.push(...manifestTransforms);\n }\n\n // Run additionalPrecacheEntriesTransform last.\n if (additionalPrecacheEntries) {\n transformsToApply.push(additionalPrecacheEntriesTransform(additionalPrecacheEntries));\n }\n\n let transformedManifest: ManifestEntryWithSize[] = normalizedManifest;\n for (const transform of transformsToApply) {\n const result = await transform(transformedManifest, transformParam);\n if (!(\"manifest\" in result)) {\n throw new Error(errors[\"bad-manifest-transforms-return-value\"]);\n }\n\n transformedManifest = result.manifest;\n allWarnings.push(...(result.warnings || []));\n }\n\n // Generate some metadata about the manifest before we clear out the size\n // properties from each entry.\n const count = transformedManifest.length;\n let size = 0;\n for (const manifestEntry of transformedManifest as (ManifestEntry & { size?: number })[]) {\n size += manifestEntry.size || 0;\n delete manifestEntry.size;\n }\n\n return {\n count,\n size,\n manifestEntries: transformedManifest as ManifestEntry[],\n warnings: allWarnings,\n };\n}\n","/*\n Copyright 2021 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport assert from \"node:assert\";\n\nimport type { FileDetails, GetManifestOptionsComplete, GetManifestResult } from \"../types.js\";\nimport { errors } from \"./errors.js\";\nimport { getCompositeDetails } from \"./get-composite-details.js\";\nimport { getFileDetails } from \"./get-file-details.js\";\nimport { getStringDetails } from \"./get-string-details.js\";\nimport { transformManifest } from \"./transform-manifest.js\";\n\nexport const getFileManifestEntries = async ({\n additionalPrecacheEntries,\n dontCacheBustURLsMatching,\n globDirectory,\n globFollow,\n globIgnores,\n globPatterns = [],\n globStrict,\n manifestTransforms,\n maximumFileSizeToCacheInBytes,\n modifyURLPrefix,\n templatedURLs,\n disablePrecacheManifest,\n}: GetManifestOptionsComplete): Promise<GetManifestResult> => {\n if (disablePrecacheManifest) {\n return {\n count: 0,\n size: 0,\n manifestEntries: undefined,\n warnings: [],\n };\n }\n\n const warnings: string[] = [];\n const allFileDetails = new Map<string, FileDetails>();\n\n try {\n for (const globPattern of globPatterns) {\n const { globbedFileDetails, warning } = getFileDetails({\n globDirectory,\n globFollow,\n globIgnores,\n globPattern,\n globStrict,\n });\n\n if (warning) {\n warnings.push(warning);\n }\n\n for (const details of globbedFileDetails) {\n if (details && !allFileDetails.has(details.file)) {\n allFileDetails.set(details.file, details);\n }\n }\n }\n } catch (error) {\n // If there's an exception thrown while globbing, then report\n // it back as a warning, and don't consider it fatal.\n if (error instanceof Error && error.message) {\n warnings.push(error.message);\n }\n }\n\n if (templatedURLs) {\n for (const url of Object.keys(templatedURLs)) {\n assert(!allFileDetails.has(url), errors[\"templated-url-matches-glob\"]);\n\n const dependencies = templatedURLs[url];\n if (Array.isArray(dependencies)) {\n const details = dependencies.reduce<FileDetails[]>((previous, globPattern) => {\n try {\n const { globbedFileDetails, warning } = getFileDetails({\n globDirectory,\n globFollow,\n globIgnores,\n globPattern,\n globStrict,\n });\n\n if (warning) {\n warnings.push(warning);\n }\n\n return previous.concat(globbedFileDetails);\n } catch (error) {\n const debugObj: { [key: string]: string[] } = {};\n debugObj[url] = dependencies;\n throw new Error(\n `${errors[\"bad-template-urls-asset\"]} '${globPattern}' from '${JSON.stringify(debugObj)}':\\n${\n error instanceof Error ? error.toString() : \"\"\n }`,\n );\n }\n }, []);\n if (details.length === 0) {\n throw new Error(`${errors[\"bad-template-urls-asset\"]} The glob pattern '${dependencies.toString()}' did not match anything.`);\n }\n allFileDetails.set(url, getCompositeDetails(url, details));\n } else if (typeof dependencies === \"string\") {\n allFileDetails.set(url, getStringDetails(url, dependencies));\n }\n }\n }\n\n const transformedManifest = await transformManifest({\n additionalPrecacheEntries,\n dontCacheBustURLsMatching,\n manifestTransforms,\n maximumFileSizeToCacheInBytes,\n modifyURLPrefix,\n fileDetails: Array.from(allFileDetails.values()),\n disablePrecacheManifest,\n });\n\n transformedManifest.warnings.push(...warnings);\n\n return transformedManifest;\n};\n","import { z } from \"zod\";\n/*\n Copyright 2021 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { SerwistConfigError, validationErrorMap } from \"../schema/error.js\";\nimport type { GetManifestOptionsComplete, InjectManifestOptionsComplete } from \"../types.js\";\n\nexport const validateGetManifestOptions = async (input: unknown): Promise<GetManifestOptionsComplete> => {\n const result = await (await import(\"../schema/get-manifest.js\")).getManifestOptions.spa(input, { error: validationErrorMap });\n if (!result.success) {\n throw new SerwistConfigError({\n moduleName: \"@serwist/build\",\n message: z.prettifyError(result.error),\n });\n }\n return result.data;\n};\n\nexport const validateInjectManifestOptions = async (input: unknown): Promise<InjectManifestOptionsComplete> => {\n const result = await (await import(\"../schema/inject-manifest.js\")).injectManifestOptions.spa(input, { error: validationErrorMap });\n if (!result.success) {\n throw new SerwistConfigError({\n moduleName: \"@serwist/build\",\n message: z.prettifyError(result.error),\n });\n }\n return result.data;\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport { getFileManifestEntries } from \"./lib/get-file-manifest-entries.js\";\nimport { validateGetManifestOptions } from \"./lib/validate-options.js\";\nimport type { GetManifestOptions, GetManifestResult } from \"./types.js\";\n\n/**\n * This method returns a list of URLs to precache, referred to as a \"precache\n * manifest\", along with details about the number of entries and their size,\n * based on the options you provide.\n *\n * ```\n * // The following lists some common options; see the rest of the documentation\n * // for the full set of options and defaults.\n * const {count, manifestEntries, size, warnings} = await getManifest({\n * dontCacheBustURLsMatching: [new RegExp('...')],\n * globDirectory: '...',\n * globPatterns: ['...', '...'],\n * maximumFileSizeToCacheInBytes: ...,\n * });\n * ```\n */\nexport const getManifest = async (config: GetManifestOptions): Promise<GetManifestResult> => {\n const options = await validateGetManifestOptions(config);\n\n return await getFileManifestEntries(options);\n};\n","/*\n Copyright 2022 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\n// Adapted from https://github.com/lydell/source-map-url/blob/master/source-map-url.js\n// See https://github.com/GoogleChrome/workbox/issues/3019\nconst innerRegex = /[#@] sourceMappingURL=([^\\s'\"]*)/;\nconst regex = RegExp(`(?:/\\\\*(?:\\\\s*\\r?\\n(?://)?)?(?:${innerRegex.source})\\\\s*\\\\*/|//(?:${innerRegex.source}))\\\\s*`);\n\nexport function getSourceMapURL(srcContents: string): string | null {\n const match = srcContents.match(regex);\n return match ? match[1] || match[2] || \"\" : null;\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport path from \"node:path\";\nimport { toUnix } from \"@serwist/utils\";\n\nexport function rebasePath({ baseDirectory, file }: { baseDirectory: string; file: string }): string {\n // The initial path is relative to the current directory, so make it absolute.\n const absolutePath = path.resolve(file);\n\n // Convert the absolute path so that it's relative to the baseDirectory.\n const relativePath = path.relative(baseDirectory, absolutePath);\n\n // Remove any leading ./ as it won't work in a glob pattern.\n const normalizedPath = path.normalize(relativePath);\n\n return toUnix(normalizedPath);\n}\n","/*\n Copyright 2019 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\n\nimport type { RawSourceMap } from \"source-map\";\nimport { SourceMapConsumer, SourceMapGenerator } from \"source-map\";\n\ninterface ReplaceAndUpdateSourceMapOptions {\n /**\n * The name for the file whose contents\n * correspond to originalSource.\n */\n jsFilename: string;\n /**\n * The sourcemap for originalSource,\n * prior to any replacements.\n */\n originalMap: RawSourceMap;\n /**\n * The source code, prior to any\n * replacements.\n */\n originalSource: string;\n /**\n * A string to swap in for searchString.\n */\n replaceString: string;\n /**\n * A string in originalSource to replace.\n * Only the first occurrence will be replaced.\n */\n searchString: string;\n}\n\n/**\n * Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern\n * JavaScript updates, along with additional properties copied from originalMap.\n *\n * @param options\n * @returns An object containing both\n * originalSource with the replacement applied, and the modified originalMap.\n * @private\n */\nexport async function replaceAndUpdateSourceMap({\n jsFilename,\n originalMap,\n originalSource,\n replaceString,\n searchString,\n}: ReplaceAndUpdateSourceMapOptions): Promise<{ map: string; source: string }> {\n const generator = new SourceMapGenerator({\n file: jsFilename,\n });\n\n const consumer = await new SourceMapConsumer(originalMap);\n\n let pos: number;\n let src = originalSource;\n const replacements: { line: number; column: number }[] = [];\n let lineNum = 0;\n let filePos = 0;\n\n const lines = src.split(\"\\n\");\n for (let line of lines) {\n lineNum++;\n let searchPos = 0;\n while ((pos = line.indexOf(searchString, searchPos)) !== -1) {\n src = src.substring(0, filePos + pos) + replaceString + src.substring(filePos + pos + searchString.length);\n line = line.substring(0, pos) + replaceString + line.substring(pos + searchString.length);\n replacements.push({ line: lineNum, column: pos });\n searchPos = pos + replaceString.length;\n }\n filePos += line.length + 1;\n }\n\n replacements.reverse();\n\n consumer.eachMapping((mapping) => {\n for (const replacement of replacements) {\n if (replacement.line === mapping.generatedLine && mapping.generatedColumn > replacement.column) {\n const offset = searchString.length - replaceString.length;\n mapping.generatedColumn -= offset;\n }\n }\n\n if (mapping.source) {\n const newMapping = {\n generated: {\n line: mapping.generatedLine,\n column: mapping.generatedColumn,\n },\n original: {\n line: mapping.originalLine,\n column: mapping.originalColumn,\n },\n source: mapping.source,\n };\n return generator.addMapping(newMapping);\n }\n\n return mapping;\n });\n\n consumer.destroy();\n // JSON.parse returns any.\n const updatedSourceMap: RawSourceMap = Object.assign(JSON.parse(generator.toString()), {\n names: originalMap.names,\n sourceRoot: originalMap.sourceRoot,\n sources: originalMap.sources,\n sourcesContent: originalMap.sourcesContent,\n });\n\n return {\n map: JSON.stringify(updatedSourceMap),\n source: src,\n };\n}\n","/*\n Copyright 2021 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { toUnix } from \"@serwist/utils\";\nimport { errors } from \"./errors.js\";\n\nexport function translateURLToSourcemapPaths(\n url: string | null,\n swSrc: string,\n swDest: string,\n): {\n destPath: string | undefined;\n srcPath: string | undefined;\n warning: string | undefined;\n} {\n let destPath: string | undefined;\n let srcPath: string | undefined;\n let warning: string | undefined;\n\n if (url && !url.startsWith(\"data:\")) {\n const possibleSrcPath = path.resolve(path.dirname(swSrc), url);\n if (fs.existsSync(possibleSrcPath)) {\n srcPath = toUnix(possibleSrcPath);\n destPath = toUnix(path.resolve(path.dirname(swDest), url));\n } else {\n warning = `${errors[\"cant-find-sourcemap\"]} ${possibleSrcPath}`;\n }\n }\n\n return { destPath, srcPath, warning };\n}\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport assert from \"node:assert\";\nimport fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { toUnix } from \"@serwist/utils\";\nimport type { RawSourceMap } from \"source-map\";\nimport { errors } from \"./lib/errors.js\";\nimport { escapeRegExp } from \"./lib/escape-regexp.js\";\nimport { getFileManifestEntries } from \"./lib/get-file-manifest-entries.js\";\nimport { getSourceMapURL } from \"./lib/get-source-map-url.js\";\nimport { rebasePath } from \"./lib/rebase-path.js\";\nimport { replaceAndUpdateSourceMap } from \"./lib/replace-and-update-source-map.js\";\nimport { translateURLToSourcemapPaths } from \"./lib/translate-url-to-sourcemap-paths.js\";\nimport { validateInjectManifestOptions } from \"./lib/validate-options.js\";\nimport type { BuildResult, InjectManifestOptions } from \"./types.js\";\n\n/**\n * This method creates a list of URLs to precache, referred to as a \"precache\n * manifest\", based on the options you provide.\n *\n * The manifest is injected into the `swSrc` file, and the placeholder string\n * `injectionPoint` determines where in the file the manifest should go.\n *\n * The final service worker file, with the manifest injected, is written to\n * disk at `swDest`.\n *\n * This method will not compile or bundle your `swSrc` file; it just handles\n * injecting the manifest.\n *\n * ```\n * // The following lists some common options; see the rest of the documentation\n * // for the full set of options and defaults.\n * const {count, size, warnings} = await injectManifest({\n * dontCacheBustURLsMatching: [new RegExp('...')],\n * globDirectory: '...',\n * globPatterns: ['...', '...'],\n * maximumFileSizeToCacheInBytes: ...,\n * swDest: '...',\n * swSrc: '...',\n * });\n * ```\n */\nexport const injectManifest = async (config: InjectManifestOptions): Promise<BuildResult> => {\n const options = await validateInjectManifestOptions(config);\n\n // Make sure we leave swSrc and swDest out of the precache manifest.\n for (const file of [options.swSrc, options.swDest]) {\n options.globIgnores!.push(\n rebasePath({\n file,\n baseDirectory: options.globDirectory,\n }),\n );\n }\n\n const globalRegexp = new RegExp(escapeRegExp(options.injectionPoint!), \"g\");\n\n const { count, size, manifestEntries, warnings } = await getFileManifestEntries(options);\n let swFileContents: string;\n try {\n swFileContents = await fsp.readFile(options.swSrc, \"utf8\");\n } catch (error) {\n throw new Error(`${errors[\"invalid-sw-src\"]} ${error instanceof Error && error.message ? error.message : \"\"}`);\n }\n\n const injectionResults = swFileContents.match(globalRegexp);\n // See https://github.com/GoogleChrome/workbox/issues/2230\n const injectionPoint = options.injectionPoint ? options.injectionPoint : \"\";\n if (!injectionResults) {\n if (path.resolve(options.swSrc) === path.resolve(options.swDest)) {\n throw new Error(`${errors[\"same-src-and-dest\"]} ${injectionPoint}`);\n }\n throw new Error(`${errors[\"injection-point-not-found\"]} ${injectionPoint}`);\n }\n\n assert(injectionResults.length === 1, `${errors[\"multiple-injection-points\"]} ${injectionPoint}`);\n\n const manifestString = manifestEntries === undefined ? \"undefined\" : JSON.stringify(manifestEntries);\n\n const filesToWrite: { [key: string]: string } = {};\n\n const url = getSourceMapURL(swFileContents);\n // See https://github.com/GoogleChrome/workbox/issues/2957\n const { destPath, srcPath, warning } = translateURLToSourcemapPaths(url, options.swSrc, options.swDest);\n if (warning) {\n warnings.push(warning);\n }\n\n // If our swSrc file contains a sourcemap, we would invalidate that\n // mapping if we just replaced injectionPoint with the stringified manifest.\n // Instead, we need to update the swDest contents as well as the sourcemap\n // (assuming it's a real file, not a data: URL) at the same time.\n // See https://github.com/GoogleChrome/workbox/issues/2235\n // and https://github.com/GoogleChrome/workbox/issues/2648\n if (srcPath && destPath) {\n const originalMap = JSON.parse(await fsp.readFile(srcPath, \"utf-8\")) as RawSourceMap;\n\n const { map, source } = await replaceAndUpdateSourceMap({\n originalMap,\n jsFilename: toUnix(path.basename(options.swDest)),\n originalSource: swFileContents,\n replaceString: manifestString,\n searchString: options.injectionPoint!,\n });\n\n filesToWrite[options.swDest] = source;\n filesToWrite[destPath] = map;\n } else {\n // If there's no sourcemap associated with swSrc, a simple string\n // replacement will suffice.\n filesToWrite[options.swDest] = swFileContents.replace(globalRegexp, manifestString);\n }\n\n for (const [file, contents] of Object.entries(filesToWrite)) {\n try {\n await fsp.mkdir(path.dirname(file), { recursive: true });\n } catch (error: unknown) {\n throw new Error(`${errors[\"unable-to-make-sw-directory\"]} '${error instanceof Error && error.message ? error.message : \"\"}'`);\n }\n\n await fsp.writeFile(file, contents);\n }\n\n return {\n count,\n size,\n warnings,\n // Use path.resolve() to make all the paths absolute.\n filePaths: Object.keys(filesToWrite).map((f) => toUnix(path.resolve(f))),\n };\n};\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { getManifest } from \"./get-manifest.js\";\nimport { injectManifest } from \"./inject-manifest.js\";\nimport { DEFAULT_GLOB_PATTERNS } from \"./lib/constants.js\";\nimport { errors } from \"./lib/errors.js\";\nimport { escapeRegExp } from \"./lib/escape-regexp.js\";\nimport { getFileManifestEntries } from \"./lib/get-file-manifest-entries.js\";\nimport { getSourceMapURL } from \"./lib/get-source-map-url.js\";\nimport { rebasePath } from \"./lib/rebase-path.js\";\nimport { replaceAndUpdateSourceMap } from \"./lib/replace-and-update-source-map.js\";\nimport { transformManifest } from \"./lib/transform-manifest.js\";\nimport { translateURLToSourcemapPaths } from \"./lib/translate-url-to-sourcemap-paths.js\";\nimport { validateGetManifestOptions, validateInjectManifestOptions } from \"./lib/validate-options.js\";\n\n// TODO: remove in v10.\n/**\n * Use `JSON.stringify` instead.\n *\n * @deprecated\n */\nconst stringify = JSON.stringify;\n\nexport {\n errors,\n DEFAULT_GLOB_PATTERNS,\n escapeRegExp,\n getFileManifestEntries,\n getManifest,\n getSourceMapURL,\n injectManifest,\n rebasePath,\n replaceAndUpdateSourceMap,\n stringify,\n transformManifest,\n translateURLToSourcemapPaths,\n validateGetManifestOptions,\n validateInjectManifestOptions,\n};\n\nexport type * from \"./types.js\";\n"],"mappings":"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