@serwist/build 8.4.4 → 9.0.0-preview.0

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.
Files changed (125) hide show
  1. package/dist/chunks/getManifest.js +6 -0
  2. package/dist/chunks/glob.js +60 -0
  3. package/dist/chunks/injectManifest.js +23 -0
  4. package/dist/chunks/serwist-config-error.js +57 -0
  5. package/dist/chunks/vite.js +7 -0
  6. package/dist/chunks/webpack.js +34 -0
  7. package/dist/get-manifest.d.ts +2 -1
  8. package/dist/get-manifest.d.ts.map +1 -0
  9. package/dist/index.d.ts +2 -1
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +53 -813
  12. package/dist/index.next.d.ts +3 -0
  13. package/dist/index.next.d.ts.map +1 -0
  14. package/dist/index.next.js +35 -0
  15. package/dist/inject-manifest.d.ts +2 -1
  16. package/dist/inject-manifest.d.ts.map +1 -0
  17. package/dist/lib/additional-precache-entries-transform.d.ts +6 -5
  18. package/dist/lib/additional-precache-entries-transform.d.ts.map +1 -0
  19. package/dist/lib/errors.d.ts +1 -2
  20. package/dist/lib/errors.d.ts.map +1 -0
  21. package/dist/lib/escape-regexp.d.ts +2 -1
  22. package/dist/lib/escape-regexp.d.ts.map +1 -0
  23. package/dist/lib/get-composite-details.d.ts +2 -1
  24. package/dist/lib/get-composite-details.d.ts.map +1 -0
  25. package/dist/lib/get-file-details.d.ts +2 -1
  26. package/dist/lib/get-file-details.d.ts.map +1 -0
  27. package/dist/lib/get-file-hash.d.ts +1 -0
  28. package/dist/lib/get-file-hash.d.ts.map +1 -0
  29. package/dist/lib/get-file-manifest-entries.d.ts +1 -0
  30. package/dist/lib/get-file-manifest-entries.d.ts.map +1 -0
  31. package/dist/lib/get-file-size.d.ts +1 -0
  32. package/dist/lib/get-file-size.d.ts.map +1 -0
  33. package/dist/lib/get-source-map-url.d.ts +1 -0
  34. package/dist/lib/get-source-map-url.d.ts.map +1 -0
  35. package/dist/lib/get-string-details.d.ts +1 -0
  36. package/dist/lib/get-string-details.d.ts.map +1 -0
  37. package/dist/lib/get-string-hash.d.ts +1 -0
  38. package/dist/lib/get-string-hash.d.ts.map +1 -0
  39. package/dist/lib/maximum-size-transform.d.ts +1 -0
  40. package/dist/lib/maximum-size-transform.d.ts.map +1 -0
  41. package/dist/lib/modify-url-prefix-transform.d.ts +1 -0
  42. package/dist/lib/modify-url-prefix-transform.d.ts.map +1 -0
  43. package/dist/lib/no-revision-for-urls-matching-transform.d.ts +1 -0
  44. package/dist/lib/no-revision-for-urls-matching-transform.d.ts.map +1 -0
  45. package/dist/lib/rebase-path.d.ts +1 -0
  46. package/dist/lib/rebase-path.d.ts.map +1 -0
  47. package/dist/lib/replace-and-update-source-map.d.ts +1 -0
  48. package/dist/lib/replace-and-update-source-map.d.ts.map +1 -0
  49. package/dist/lib/serwist-config-error.d.ts +7 -0
  50. package/dist/lib/serwist-config-error.d.ts.map +1 -0
  51. package/dist/lib/transform-manifest.d.ts +2 -1
  52. package/dist/lib/transform-manifest.d.ts.map +1 -0
  53. package/dist/lib/translate-url-to-sourcemap-paths.d.ts +1 -0
  54. package/dist/lib/translate-url-to-sourcemap-paths.d.ts.map +1 -0
  55. package/dist/lib/validate-next-options.d.ts +3 -0
  56. package/dist/lib/validate-next-options.d.ts.map +1 -0
  57. package/dist/lib/validate-options.d.ts +6 -8
  58. package/dist/lib/validate-options.d.ts.map +1 -0
  59. package/dist/schema/base.d.ts +169 -0
  60. package/dist/schema/base.d.ts.map +1 -0
  61. package/dist/schema/getManifest.d.ts +187 -0
  62. package/dist/schema/getManifest.d.ts.map +1 -0
  63. package/dist/schema/glob.d.ts +35 -0
  64. package/dist/schema/glob.d.ts.map +1 -0
  65. package/dist/schema/injectManifest.d.ts +206 -0
  66. package/dist/schema/injectManifest.d.ts.map +1 -0
  67. package/dist/schema/manifestEntry.d.ts +15 -0
  68. package/dist/schema/manifestEntry.d.ts.map +1 -0
  69. package/dist/schema/manifestTransform.d.ts +121 -0
  70. package/dist/schema/manifestTransform.d.ts.map +1 -0
  71. package/dist/schema/next.d.ts +243 -0
  72. package/dist/schema/next.d.ts.map +1 -0
  73. package/dist/schema/swDest.d.ts +16 -0
  74. package/dist/schema/swDest.d.ts.map +1 -0
  75. package/dist/schema/validationErrorMap.d.ts +3 -0
  76. package/dist/schema/validationErrorMap.d.ts.map +1 -0
  77. package/dist/schema/vite.d.ts +196 -0
  78. package/dist/schema/vite.d.ts.map +1 -0
  79. package/dist/schema/webpack.d.ts +231 -0
  80. package/dist/schema/webpack.d.ts.map +1 -0
  81. package/dist/types.d.ts +147 -175
  82. package/dist/types.d.ts.map +1 -0
  83. package/package.json +42 -28
  84. package/src/_types.js +112 -0
  85. package/src/get-manifest.ts +33 -0
  86. package/src/index.next.ts +3 -0
  87. package/{dist/index.d.cts → src/index.ts} +27 -2
  88. package/src/inject-manifest.ts +140 -0
  89. package/src/lib/additional-precache-entries-transform.ts +58 -0
  90. package/src/lib/errors.ts +99 -0
  91. package/src/lib/escape-regexp.ts +12 -0
  92. package/src/lib/get-composite-details.ts +31 -0
  93. package/src/lib/get-file-details.ts +68 -0
  94. package/src/lib/get-file-hash.ts +21 -0
  95. package/src/lib/get-file-manifest-entries.ts +126 -0
  96. package/src/lib/get-file-size.ts +23 -0
  97. package/src/lib/get-source-map-url.ts +17 -0
  98. package/src/lib/get-string-details.ts +18 -0
  99. package/src/lib/get-string-hash.ts +15 -0
  100. package/src/lib/maximum-size-transform.ts +29 -0
  101. package/src/lib/modify-url-prefix-transform.ts +55 -0
  102. package/src/lib/no-revision-for-urls-matching-transform.ts +32 -0
  103. package/src/lib/rebase-path.ts +22 -0
  104. package/src/lib/replace-and-update-source-map.ts +122 -0
  105. package/src/lib/serwist-config-error.ts +6 -0
  106. package/src/lib/transform-manifest.ts +158 -0
  107. package/src/lib/translate-url-to-sourcemap-paths.ts +38 -0
  108. package/src/lib/validate-next-options.ts +14 -0
  109. package/src/lib/validate-options.ts +47 -0
  110. package/src/schema/base.ts +16 -0
  111. package/src/schema/getManifest.ts +14 -0
  112. package/src/schema/glob.ts +41 -0
  113. package/src/schema/injectManifest.ts +23 -0
  114. package/src/schema/manifestEntry.ts +9 -0
  115. package/src/schema/manifestTransform.ts +15 -0
  116. package/src/schema/next.ts +35 -0
  117. package/src/schema/swDest.ts +14 -0
  118. package/src/schema/validationErrorMap.ts +36 -0
  119. package/src/schema/vite.ts +18 -0
  120. package/src/schema/webpack.ts +47 -0
  121. package/src/types.ts +407 -0
  122. package/dist/index.cjs +0 -1632
  123. package/dist/lib/cdn-utils.d.ts +0 -1
  124. package/dist/lib/copy-serwist-libraries.d.ts +0 -16
  125. package/dist/schema/index.d.ts +0 -605
package/dist/index.cjs DELETED
@@ -1,1632 +0,0 @@
1
- 'use strict';
2
-
3
- var stringify = require('fast-json-stable-stringify');
4
- var assert = require('assert');
5
- var commonTags = require('common-tags');
6
- var crypto = require('crypto');
7
- var glob = require('glob');
8
- var upath = require('upath');
9
- var fse = require('fs-extra');
10
- var betterAjvErrors = require('@apideck/better-ajv-errors');
11
- var Ajv = require('ajv');
12
- var sourceMap = require('source-map');
13
-
14
- const errors = {
15
- "unable-to-get-rootdir": "Unable to get the root directory of your web app.",
16
- "no-extension": commonTags.oneLine`Unable to detect a usable extension for a file in your web
17
- app directory.`,
18
- "invalid-file-manifest-name": commonTags.oneLine`The File Manifest Name must have at least one
19
- character.`,
20
- "unable-to-get-file-manifest-name": "Unable to get a file manifest name.",
21
- "invalid-sw-dest": `The 'swDest' value must be a valid path.`,
22
- "unable-to-get-sw-name": "Unable to get a service worker file name.",
23
- "unable-to-get-save-config": commonTags.oneLine`An error occurred when asking to save details
24
- in a config file.`,
25
- "unable-to-get-file-hash": commonTags.oneLine`An error occurred when attempting to create a
26
- file hash.`,
27
- "unable-to-get-file-size": commonTags.oneLine`An error occurred when attempting to get a file
28
- size.`,
29
- "unable-to-glob-files": "An error occurred when globbing for files.",
30
- "unable-to-make-manifest-directory": commonTags.oneLine`Unable to make output directory for
31
- file manifest.`,
32
- "read-manifest-template-failure": "Unable to read template for file manifest",
33
- "populating-manifest-tmpl-failed": commonTags.oneLine`An error occurred when populating the
34
- file manifest template.`,
35
- "manifest-file-write-failure": "Unable to write the file manifest.",
36
- "unable-to-make-sw-directory": commonTags.oneLine`Unable to make the directories to output
37
- the service worker path.`,
38
- "sw-write-failure": "Unable to write the service worker file.",
39
- "sw-write-failure-directory": commonTags.oneLine`Unable to write the service worker file;
40
- 'swDest' should be a full path to the file, not a path to a directory.`,
41
- "unable-to-copy-serwist-libraries": commonTags.oneLine`One or more of the Serwist libraries
42
- could not be copied over to the destination directory: `,
43
- "invalid-glob-directory": commonTags.oneLine`The supplied globDirectory must be a path as a
44
- string.`,
45
- "invalid-dont-cache-bust": commonTags.oneLine`The supplied 'dontCacheBustURLsMatching'
46
- parameter must be a RegExp.`,
47
- "invalid-exclude-files": "The excluded files should be an array of strings.",
48
- "invalid-get-manifest-entries-input": commonTags.oneLine`The input to
49
- 'getFileManifestEntries()' must be an object.`,
50
- "invalid-manifest-path": commonTags.oneLine`The supplied manifest path is not a string with
51
- at least one character.`,
52
- "invalid-manifest-entries": commonTags.oneLine`The manifest entries must be an array of
53
- strings or JavaScript objects containing a url parameter.`,
54
- "invalid-manifest-format": commonTags.oneLine`The value of the 'format' option passed to
55
- generateFileManifest() must be either 'iife' (the default) or 'es'.`,
56
- "invalid-static-file-globs": commonTags.oneLine`The 'globPatterns' value must be an array
57
- of strings.`,
58
- "invalid-templated-urls": commonTags.oneLine`The 'templatedURLs' value should be an object
59
- that maps URLs to either a string, or to an array of glob patterns.`,
60
- "templated-url-matches-glob": commonTags.oneLine`One of the 'templatedURLs' URLs is already
61
- being tracked via 'globPatterns': `,
62
- "invalid-glob-ignores": commonTags.oneLine`The 'globIgnores' parameter must be an array of
63
- glob pattern strings.`,
64
- "manifest-entry-bad-url": commonTags.oneLine`The generated manifest contains an entry without
65
- a URL string. This is likely an error with @serwist/build.`,
66
- "modify-url-prefix-bad-prefixes": commonTags.oneLine`The 'modifyURLPrefix' parameter must be
67
- an object with string key value pairs.`,
68
- "invalid-inject-manifest-arg": commonTags.oneLine`The input to 'injectManifest()' must be an
69
- object.`,
70
- "injection-point-not-found": commonTags.oneLine`Unable to find a place to inject the manifest.
71
- Please ensure that your service worker file contains the following: `,
72
- "multiple-injection-points": commonTags.oneLine`Please ensure that your 'swSrc' file contains
73
- only one match for the following: `,
74
- "useless-glob-pattern": commonTags.oneLine`One of the glob patterns doesn't match any files.
75
- Please remove or fix the following: `,
76
- "bad-template-urls-asset": commonTags.oneLine`There was an issue using one of the provided
77
- 'templatedURLs'.`,
78
- "invalid-runtime-caching": commonTags.oneLine`The 'runtimeCaching' parameter must an an
79
- array of objects with at least a 'urlPattern' and 'handler'.`,
80
- "static-file-globs-deprecated": commonTags.oneLine`'staticFileGlobs' is deprecated.
81
- Please use 'globPatterns' instead.`,
82
- "dynamic-url-deprecated": commonTags.oneLine`'dynamicURLToDependencies' is deprecated.
83
- Please use 'templatedURLs' instead.`,
84
- "urlPattern-is-required": commonTags.oneLine`The 'urlPattern' option is required when using
85
- 'runtimeCaching'.`,
86
- "handler-is-required": commonTags.oneLine`The 'handler' option is required when using
87
- runtimeCaching.`,
88
- "invalid-generate-file-manifest-arg": commonTags.oneLine`The input to generateFileManifest()
89
- must be an Object.`,
90
- "invalid-sw-src": `The 'swSrc' file can't be read.`,
91
- "same-src-and-dest": commonTags.oneLine`Unable to find a place to inject the manifest. This is
92
- likely because swSrc and swDest are configured to the same file.
93
- Please ensure that your swSrc file contains the following:`,
94
- "no-module-name": commonTags.oneLine`You must provide a moduleName parameter when calling
95
- getModuleURL().`,
96
- "bad-manifest-transforms-return-value": commonTags.oneLine`The return value from a
97
- manifestTransform should be an object with 'manifest' and optionally
98
- 'warnings' properties.`,
99
- "string-entry-warning": commonTags.oneLine`Some items were passed to additionalPrecacheEntries
100
- without revisioning info. This is generally NOT safe. Learn more at
101
- https://bit.ly/wb-precache.`,
102
- "cant-find-sourcemap": commonTags.oneLine`The swSrc file refers to a sourcemap that can't be
103
- opened:`,
104
- "manifest-transforms": commonTags.oneLine`When using manifestTransforms, you must provide
105
- an array of functions.`
106
- };
107
-
108
- function getCompositeDetails(compositeURL, dependencyDetails) {
109
- let totalSize = 0;
110
- let compositeHash = "";
111
- for (const fileDetails of dependencyDetails){
112
- totalSize += fileDetails.size;
113
- compositeHash += fileDetails.hash;
114
- }
115
- const md5 = crypto.createHash("md5");
116
- md5.update(compositeHash);
117
- const hashOfHashes = md5.digest("hex");
118
- return {
119
- file: compositeURL,
120
- hash: hashOfHashes,
121
- size: totalSize
122
- };
123
- }
124
-
125
- function getStringHash(input) {
126
- const md5 = crypto.createHash("md5");
127
- md5.update(input);
128
- return md5.digest("hex");
129
- }
130
-
131
- function getFileHash(file) {
132
- try {
133
- const buffer = fse.readFileSync(file);
134
- return getStringHash(buffer);
135
- } catch (err) {
136
- throw new Error(`${errors["unable-to-get-file-hash"]} '${err instanceof Error && err.message ? err.message : ""}'`);
137
- }
138
- }
139
-
140
- function getFileSize(file) {
141
- try {
142
- const stat = fse.statSync(file);
143
- if (!stat.isFile()) {
144
- return null;
145
- }
146
- return stat.size;
147
- } catch (err) {
148
- throw new Error(`${errors["unable-to-get-file-size"]} '${err instanceof Error && err.message ? err.message : ""}'`);
149
- }
150
- }
151
-
152
- function getFileDetails({ globDirectory, globFollow, globIgnores, globPattern }) {
153
- let globbedFiles;
154
- let warning = "";
155
- try {
156
- globbedFiles = glob.glob.sync(globPattern, {
157
- cwd: globDirectory,
158
- follow: globFollow,
159
- ignore: globIgnores
160
- });
161
- } catch (err) {
162
- throw new Error(`${errors["unable-to-glob-files"]} '${err instanceof Error && err.message ? err.message : ""}'`);
163
- }
164
- if (globbedFiles.length === 0) {
165
- warning = `${errors["useless-glob-pattern"]} ${JSON.stringify({
166
- globDirectory,
167
- globPattern,
168
- globIgnores
169
- }, null, 2)}`;
170
- }
171
- const globbedFileDetails = [];
172
- for (const file of globbedFiles){
173
- const fullPath = upath.join(globDirectory, file);
174
- const fileSize = getFileSize(fullPath);
175
- if (fileSize !== null) {
176
- const fileHash = getFileHash(fullPath);
177
- globbedFileDetails.push({
178
- file: `${upath.relative(globDirectory, fullPath)}`,
179
- hash: fileHash,
180
- size: fileSize
181
- });
182
- }
183
- }
184
- return {
185
- globbedFileDetails,
186
- warning
187
- };
188
- }
189
-
190
- function getStringDetails(url, str) {
191
- return {
192
- file: url,
193
- hash: getStringHash(str),
194
- size: str.length
195
- };
196
- }
197
-
198
- function additionalPrecacheEntriesTransform(additionalPrecacheEntries) {
199
- return (manifest)=>{
200
- const warnings = [];
201
- const stringEntries = new Set();
202
- for (const additionalEntry of additionalPrecacheEntries){
203
- // Warn about either a string or an object that lacks a revision property.
204
- // (An object with a revision property set to null is okay.)
205
- if (typeof additionalEntry === "string") {
206
- stringEntries.add(additionalEntry);
207
- manifest.push({
208
- revision: null,
209
- size: 0,
210
- url: additionalEntry
211
- });
212
- } else {
213
- if (additionalEntry && additionalEntry.revision === undefined) {
214
- stringEntries.add(additionalEntry.url);
215
- }
216
- manifest.push(Object.assign({
217
- size: 0
218
- }, additionalEntry));
219
- }
220
- }
221
- if (stringEntries.size > 0) {
222
- let urls = "\n";
223
- for (const stringEntry of stringEntries){
224
- urls += ` - ${stringEntry}\n`;
225
- }
226
- warnings.push(errors["string-entry-warning"] + urls);
227
- }
228
- return {
229
- manifest,
230
- warnings
231
- };
232
- };
233
- }
234
-
235
- const BYTE_UNITS = [
236
- 'B',
237
- 'kB',
238
- 'MB',
239
- 'GB',
240
- 'TB',
241
- 'PB',
242
- 'EB',
243
- 'ZB',
244
- 'YB'
245
- ];
246
- const BIBYTE_UNITS = [
247
- 'B',
248
- 'KiB',
249
- 'MiB',
250
- 'GiB',
251
- 'TiB',
252
- 'PiB',
253
- 'EiB',
254
- 'ZiB',
255
- 'YiB'
256
- ];
257
- const BIT_UNITS = [
258
- 'b',
259
- 'kbit',
260
- 'Mbit',
261
- 'Gbit',
262
- 'Tbit',
263
- 'Pbit',
264
- 'Ebit',
265
- 'Zbit',
266
- 'Ybit'
267
- ];
268
- const BIBIT_UNITS = [
269
- 'b',
270
- 'kibit',
271
- 'Mibit',
272
- 'Gibit',
273
- 'Tibit',
274
- 'Pibit',
275
- 'Eibit',
276
- 'Zibit',
277
- 'Yibit'
278
- ];
279
- /*
280
- Formats the given number using `Number#toLocaleString`.
281
- - If locale is a string, the value is expected to be a locale-key (for example: `de`).
282
- - If locale is true, the system default locale is used for translation.
283
- - If no value for locale is specified, the number is returned unmodified.
284
- */ const toLocaleString = (number, locale, options)=>{
285
- let result = number;
286
- if (typeof locale === 'string' || Array.isArray(locale)) {
287
- result = number.toLocaleString(locale, options);
288
- } else if (locale === true || options !== undefined) {
289
- result = number.toLocaleString(undefined, options);
290
- }
291
- return result;
292
- };
293
- function prettyBytes(number, options) {
294
- if (!Number.isFinite(number)) {
295
- throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
296
- }
297
- options = {
298
- bits: false,
299
- binary: false,
300
- space: true,
301
- ...options
302
- };
303
- const UNITS = options.bits ? options.binary ? BIBIT_UNITS : BIT_UNITS : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
304
- const separator = options.space ? ' ' : '';
305
- if (options.signed && number === 0) {
306
- return ` 0${separator}${UNITS[0]}`;
307
- }
308
- const isNegative = number < 0;
309
- const prefix = isNegative ? '-' : options.signed ? '+' : '';
310
- if (isNegative) {
311
- number = -number;
312
- }
313
- let localeOptions;
314
- if (options.minimumFractionDigits !== undefined) {
315
- localeOptions = {
316
- minimumFractionDigits: options.minimumFractionDigits
317
- };
318
- }
319
- if (options.maximumFractionDigits !== undefined) {
320
- localeOptions = {
321
- maximumFractionDigits: options.maximumFractionDigits,
322
- ...localeOptions
323
- };
324
- }
325
- if (number < 1) {
326
- const numberString = toLocaleString(number, options.locale, localeOptions);
327
- return prefix + numberString + separator + UNITS[0];
328
- }
329
- const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1);
330
- number /= (options.binary ? 1024 : 1000) ** exponent;
331
- if (!localeOptions) {
332
- number = number.toPrecision(3);
333
- }
334
- const numberString = toLocaleString(Number(number), options.locale, localeOptions);
335
- const unit = UNITS[exponent];
336
- return prefix + numberString + separator + unit;
337
- }
338
-
339
- function maximumSizeTransform(maximumFileSizeToCacheInBytes) {
340
- return (originalManifest)=>{
341
- const warnings = [];
342
- const manifest = originalManifest.filter((entry)=>{
343
- if (entry.size <= maximumFileSizeToCacheInBytes) {
344
- return true;
345
- }
346
- warnings.push(`${entry.url} is ${prettyBytes(entry.size)}, and won't be precached. Configure maximumFileSizeToCacheInBytes to change this limit.`);
347
- return false;
348
- });
349
- return {
350
- manifest,
351
- warnings
352
- };
353
- };
354
- }
355
-
356
- /*
357
- Copyright 2019 Google LLC
358
-
359
- Use of this source code is governed by an MIT-style
360
- license that can be found in the LICENSE file or at
361
- https://opensource.org/licenses/MIT.
362
- */ // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
363
- function escapeRegExp(str) {
364
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
365
- }
366
-
367
- function modifyURLPrefixTransform(modifyURLPrefix) {
368
- if (!modifyURLPrefix || typeof modifyURLPrefix !== "object" || Array.isArray(modifyURLPrefix)) {
369
- throw new Error(errors["modify-url-prefix-bad-prefixes"]);
370
- }
371
- // If there are no entries in modifyURLPrefix, just return an identity
372
- // function as a shortcut.
373
- if (Object.keys(modifyURLPrefix).length === 0) {
374
- return (manifest)=>{
375
- return {
376
- manifest
377
- };
378
- };
379
- }
380
- for (const key of Object.keys(modifyURLPrefix)){
381
- if (typeof modifyURLPrefix[key] !== "string") {
382
- throw new Error(errors["modify-url-prefix-bad-prefixes"]);
383
- }
384
- }
385
- // Escape the user input so it's safe to use in a regex.
386
- const safeModifyURLPrefixes = Object.keys(modifyURLPrefix).map(escapeRegExp);
387
- // Join all the `modifyURLPrefix` keys so a single regex can be used.
388
- const prefixMatchesStrings = safeModifyURLPrefixes.join("|");
389
- // Add `^` to the front the prefix matches so it only matches the start of
390
- // a string.
391
- const modifyRegex = new RegExp(`^(${prefixMatchesStrings})`);
392
- return (originalManifest)=>{
393
- const manifest = originalManifest.map((entry)=>{
394
- if (typeof entry.url !== "string") {
395
- throw new Error(errors["manifest-entry-bad-url"]);
396
- }
397
- entry.url = entry.url.replace(modifyRegex, (match)=>{
398
- return modifyURLPrefix[match];
399
- });
400
- return entry;
401
- });
402
- return {
403
- manifest
404
- };
405
- };
406
- }
407
-
408
- function noRevisionForURLsMatchingTransform(regexp) {
409
- if (!(regexp instanceof RegExp)) {
410
- throw new Error(errors["invalid-dont-cache-bust"]);
411
- }
412
- return (originalManifest)=>{
413
- const manifest = originalManifest.map((entry)=>{
414
- if (typeof entry.url !== "string") {
415
- throw new Error(errors["manifest-entry-bad-url"]);
416
- }
417
- if (entry.url.match(regexp)) {
418
- entry.revision = null;
419
- }
420
- return entry;
421
- });
422
- return {
423
- manifest
424
- };
425
- };
426
- }
427
-
428
- async function transformManifest({ additionalPrecacheEntries, dontCacheBustURLsMatching, fileDetails, manifestTransforms, maximumFileSizeToCacheInBytes, modifyURLPrefix, transformParam, disablePrecacheManifest }) {
429
- if (disablePrecacheManifest) {
430
- return {
431
- count: 0,
432
- size: 0,
433
- manifestEntries: undefined,
434
- warnings: []
435
- };
436
- }
437
- const allWarnings = [];
438
- // Take the array of fileDetail objects and convert it into an array of
439
- // {url, revision, size} objects, with \ replaced with /.
440
- const normalizedManifest = fileDetails.map((fileDetails)=>{
441
- return {
442
- url: fileDetails.file.replace(/\\/g, "/"),
443
- revision: fileDetails.hash,
444
- size: fileDetails.size
445
- };
446
- });
447
- const transformsToApply = [];
448
- if (maximumFileSizeToCacheInBytes) {
449
- transformsToApply.push(maximumSizeTransform(maximumFileSizeToCacheInBytes));
450
- }
451
- if (modifyURLPrefix) {
452
- transformsToApply.push(modifyURLPrefixTransform(modifyURLPrefix));
453
- }
454
- if (dontCacheBustURLsMatching) {
455
- transformsToApply.push(noRevisionForURLsMatchingTransform(dontCacheBustURLsMatching));
456
- }
457
- // Run any manifestTransforms functions second-to-last.
458
- if (manifestTransforms) {
459
- transformsToApply.push(...manifestTransforms);
460
- }
461
- // Run additionalPrecacheEntriesTransform last.
462
- if (additionalPrecacheEntries) {
463
- transformsToApply.push(additionalPrecacheEntriesTransform(additionalPrecacheEntries));
464
- }
465
- let transformedManifest = normalizedManifest;
466
- for (const transform of transformsToApply){
467
- const result = await transform(transformedManifest, transformParam);
468
- if (!("manifest" in result)) {
469
- throw new Error(errors["bad-manifest-transforms-return-value"]);
470
- }
471
- transformedManifest = result.manifest;
472
- allWarnings.push(...result.warnings || []);
473
- }
474
- // Generate some metadata about the manifest before we clear out the size
475
- // properties from each entry.
476
- const count = transformedManifest.length;
477
- let size = 0;
478
- for (const manifestEntry of transformedManifest){
479
- size += manifestEntry.size || 0;
480
- // biome-ignore lint/performance/noDelete: I don't understand this part yet.
481
- delete manifestEntry.size;
482
- }
483
- return {
484
- count,
485
- size,
486
- manifestEntries: transformedManifest,
487
- warnings: allWarnings
488
- };
489
- }
490
-
491
- async function getFileManifestEntries({ additionalPrecacheEntries, dontCacheBustURLsMatching, globDirectory, globFollow, globIgnores, globPatterns = [], globStrict, manifestTransforms, maximumFileSizeToCacheInBytes, modifyURLPrefix, templatedURLs, disablePrecacheManifest }) {
492
- if (disablePrecacheManifest) {
493
- return {
494
- count: 0,
495
- size: 0,
496
- manifestEntries: undefined,
497
- warnings: []
498
- };
499
- }
500
- const warnings = [];
501
- const allFileDetails = new Map();
502
- try {
503
- for (const globPattern of globPatterns){
504
- const { globbedFileDetails, warning } = getFileDetails({
505
- globDirectory,
506
- globFollow,
507
- globIgnores,
508
- globPattern,
509
- globStrict
510
- });
511
- if (warning) {
512
- warnings.push(warning);
513
- }
514
- for (const details of globbedFileDetails){
515
- if (details && !allFileDetails.has(details.file)) {
516
- allFileDetails.set(details.file, details);
517
- }
518
- }
519
- }
520
- } catch (error) {
521
- // If there's an exception thrown while globbing, then report
522
- // it back as a warning, and don't consider it fatal.
523
- if (error instanceof Error && error.message) {
524
- warnings.push(error.message);
525
- }
526
- }
527
- if (templatedURLs) {
528
- for (const url of Object.keys(templatedURLs)){
529
- assert(!allFileDetails.has(url), errors["templated-url-matches-glob"]);
530
- const dependencies = templatedURLs[url];
531
- if (Array.isArray(dependencies)) {
532
- const details = dependencies.reduce((previous, globPattern)=>{
533
- try {
534
- const { globbedFileDetails, warning } = getFileDetails({
535
- globDirectory,
536
- globFollow,
537
- globIgnores,
538
- globPattern,
539
- globStrict
540
- });
541
- if (warning) {
542
- warnings.push(warning);
543
- }
544
- return previous.concat(globbedFileDetails);
545
- } catch (error) {
546
- const debugObj = {};
547
- debugObj[url] = dependencies;
548
- throw new Error(`${errors["bad-template-urls-asset"]} ` + `'${globPattern}' from '${JSON.stringify(debugObj)}':\n` + `${error instanceof Error ? error.toString() : ""}`);
549
- }
550
- }, []);
551
- if (details.length === 0) {
552
- throw new Error(`${errors["bad-template-urls-asset"]} The glob ` + `pattern '${dependencies.toString()}' did not match anything.`);
553
- }
554
- allFileDetails.set(url, getCompositeDetails(url, details));
555
- } else if (typeof dependencies === "string") {
556
- allFileDetails.set(url, getStringDetails(url, dependencies));
557
- }
558
- }
559
- }
560
- const transformedManifest = await transformManifest({
561
- additionalPrecacheEntries,
562
- dontCacheBustURLsMatching,
563
- manifestTransforms,
564
- maximumFileSizeToCacheInBytes,
565
- modifyURLPrefix,
566
- fileDetails: Array.from(allFileDetails.values()),
567
- disablePrecacheManifest
568
- });
569
- transformedManifest.warnings.push(...warnings);
570
- return transformedManifest;
571
- }
572
-
573
- var additionalProperties$3 = false;
574
- var type$3 = "object";
575
- var properties$3 = {
576
- additionalPrecacheEntries: {
577
- description: "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.",
578
- type: "array",
579
- items: {
580
- anyOf: [
581
- {
582
- $ref: "#/definitions/ManifestEntry"
583
- },
584
- {
585
- type: "string"
586
- }
587
- ]
588
- }
589
- },
590
- dontCacheBustURLsMatching: {
591
- description: "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.",
592
- $ref: "#/definitions/RegExp"
593
- },
594
- manifestTransforms: {
595
- description: "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.",
596
- type: "array",
597
- items: {}
598
- },
599
- maximumFileSizeToCacheInBytes: {
600
- description: "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.",
601
- "default": 2097152,
602
- type: "number"
603
- },
604
- modifyURLPrefix: {
605
- description: "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```",
606
- type: "object",
607
- additionalProperties: {
608
- type: "string"
609
- }
610
- },
611
- globFollow: {
612
- description: "Determines whether or not symlinks are followed when generating the\nprecache manifest. For more information, see the definition of `follow` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).",
613
- "default": true,
614
- type: "boolean"
615
- },
616
- globIgnores: {
617
- description: "A set of patterns matching files to always exclude when generating the\nprecache manifest. For more information, see the definition of `ignore` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).",
618
- "default": [
619
- "**/node_modules/**/*"
620
- ],
621
- type: "array",
622
- items: {
623
- type: "string"
624
- }
625
- },
626
- globPatterns: {
627
- description: "Files matching any of these patterns will be included in the precache\nmanifest. For more information, see the\n[`glob` primer](https://github.com/isaacs/node-glob#glob-primer).",
628
- "default": [
629
- "**/*.{js,css,html}"
630
- ],
631
- type: "array",
632
- items: {
633
- type: "string"
634
- }
635
- },
636
- globStrict: {
637
- description: "If true, an error reading a directory when generating a precache manifest\nwill cause the build to fail. If false, the problematic directory will be\nskipped. For more information, see the definition of `strict` in the `glob`\n[documentation](https://github.com/isaacs/node-glob#options).",
638
- "default": true,
639
- type: "boolean"
640
- },
641
- templatedURLs: {
642
- description: "If a URL is rendered based on some server-side logic, its contents may\ndepend on multiple files or on some other unique string value. The keys in\nthis object are server-rendered URLs. If the values are an array of\nstrings, they will be interpreted as `glob` patterns, and the contents of\nany files matching the patterns will be used to uniquely version the URL.\nIf used with a single string, it will be interpreted as unique versioning\ninformation that you've generated for a given URL.",
643
- type: "object",
644
- additionalProperties: {
645
- anyOf: [
646
- {
647
- type: "array",
648
- items: {
649
- type: "string"
650
- }
651
- },
652
- {
653
- type: "string"
654
- }
655
- ]
656
- }
657
- },
658
- globDirectory: {
659
- description: "The local directory you wish to match `globPatterns` against. The path is\nrelative to the current directory.",
660
- type: "string"
661
- }
662
- };
663
- var required$3 = [
664
- "globDirectory"
665
- ];
666
- var definitions$3 = {
667
- ManifestEntry: {
668
- type: "object",
669
- properties: {
670
- integrity: {
671
- type: "string"
672
- },
673
- revision: {
674
- type: [
675
- "null",
676
- "string"
677
- ]
678
- },
679
- url: {
680
- type: "string"
681
- }
682
- },
683
- additionalProperties: false,
684
- required: [
685
- "revision",
686
- "url"
687
- ]
688
- },
689
- "RegExp": {
690
- type: "object",
691
- properties: {
692
- source: {
693
- type: "string"
694
- },
695
- global: {
696
- type: "boolean"
697
- },
698
- ignoreCase: {
699
- type: "boolean"
700
- },
701
- multiline: {
702
- type: "boolean"
703
- },
704
- lastIndex: {
705
- type: "number"
706
- },
707
- flags: {
708
- type: "string"
709
- },
710
- sticky: {
711
- type: "boolean"
712
- },
713
- unicode: {
714
- type: "boolean"
715
- },
716
- dotAll: {
717
- type: "boolean"
718
- }
719
- },
720
- additionalProperties: false,
721
- required: [
722
- "dotAll",
723
- "flags",
724
- "global",
725
- "ignoreCase",
726
- "lastIndex",
727
- "multiline",
728
- "source",
729
- "sticky",
730
- "unicode"
731
- ]
732
- }
733
- };
734
- var $schema$3 = "http://json-schema.org/draft-07/schema#";
735
- var getManifestOptionsSchema = {
736
- additionalProperties: additionalProperties$3,
737
- type: type$3,
738
- properties: properties$3,
739
- required: required$3,
740
- definitions: definitions$3,
741
- $schema: $schema$3
742
- };
743
-
744
- var additionalProperties$2 = false;
745
- var type$2 = "object";
746
- var properties$2 = {
747
- additionalPrecacheEntries: {
748
- description: "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.",
749
- type: "array",
750
- items: {
751
- anyOf: [
752
- {
753
- $ref: "#/definitions/ManifestEntry"
754
- },
755
- {
756
- type: "string"
757
- }
758
- ]
759
- }
760
- },
761
- dontCacheBustURLsMatching: {
762
- description: "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.",
763
- $ref: "#/definitions/RegExp"
764
- },
765
- manifestTransforms: {
766
- description: "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.",
767
- type: "array",
768
- items: {}
769
- },
770
- maximumFileSizeToCacheInBytes: {
771
- description: "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.",
772
- "default": 2097152,
773
- type: "number"
774
- },
775
- modifyURLPrefix: {
776
- description: "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```",
777
- type: "object",
778
- additionalProperties: {
779
- type: "string"
780
- }
781
- },
782
- globFollow: {
783
- description: "Determines whether or not symlinks are followed when generating the\nprecache manifest. For more information, see the definition of `follow` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).",
784
- "default": true,
785
- type: "boolean"
786
- },
787
- globIgnores: {
788
- description: "A set of patterns matching files to always exclude when generating the\nprecache manifest. For more information, see the definition of `ignore` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).",
789
- "default": [
790
- "**/node_modules/**/*"
791
- ],
792
- type: "array",
793
- items: {
794
- type: "string"
795
- }
796
- },
797
- globPatterns: {
798
- description: "Files matching any of these patterns will be included in the precache\nmanifest. For more information, see the\n[`glob` primer](https://github.com/isaacs/node-glob#glob-primer).",
799
- "default": [
800
- "**/*.{js,css,html}"
801
- ],
802
- type: "array",
803
- items: {
804
- type: "string"
805
- }
806
- },
807
- globStrict: {
808
- description: "If true, an error reading a directory when generating a precache manifest\nwill cause the build to fail. If false, the problematic directory will be\nskipped. For more information, see the definition of `strict` in the `glob`\n[documentation](https://github.com/isaacs/node-glob#options).",
809
- "default": true,
810
- type: "boolean"
811
- },
812
- templatedURLs: {
813
- description: "If a URL is rendered based on some server-side logic, its contents may\ndepend on multiple files or on some other unique string value. The keys in\nthis object are server-rendered URLs. If the values are an array of\nstrings, they will be interpreted as `glob` patterns, and the contents of\nany files matching the patterns will be used to uniquely version the URL.\nIf used with a single string, it will be interpreted as unique versioning\ninformation that you've generated for a given URL.",
814
- type: "object",
815
- additionalProperties: {
816
- anyOf: [
817
- {
818
- type: "array",
819
- items: {
820
- type: "string"
821
- }
822
- },
823
- {
824
- type: "string"
825
- }
826
- ]
827
- }
828
- },
829
- injectionPoint: {
830
- description: "The string to find inside of the `swSrc` file. Once found, it will be\nreplaced by the generated precache manifest.",
831
- "default": "self.__SW_MANIFEST",
832
- type: "string"
833
- },
834
- swSrc: {
835
- description: "The path and filename of the service worker file that will be read during\nthe build process, relative to the current working directory.",
836
- type: "string"
837
- },
838
- swDest: {
839
- description: "The path and filename of the service worker file that will be created by\nthe build process, relative to the current working directory. It must end\nin '.js'.",
840
- type: "string"
841
- },
842
- globDirectory: {
843
- description: "The local directory you wish to match `globPatterns` against. The path is\nrelative to the current directory.",
844
- type: "string"
845
- },
846
- disablePrecacheManifest: {
847
- description: "Whether the precache manifest should be set to `undefined`.",
848
- "default": false,
849
- type: "boolean"
850
- }
851
- };
852
- var required$2 = [
853
- "globDirectory",
854
- "swDest",
855
- "swSrc"
856
- ];
857
- var definitions$2 = {
858
- ManifestEntry: {
859
- type: "object",
860
- properties: {
861
- integrity: {
862
- type: "string"
863
- },
864
- revision: {
865
- type: [
866
- "null",
867
- "string"
868
- ]
869
- },
870
- url: {
871
- type: "string"
872
- }
873
- },
874
- additionalProperties: false,
875
- required: [
876
- "revision",
877
- "url"
878
- ]
879
- },
880
- "RegExp": {
881
- type: "object",
882
- properties: {
883
- source: {
884
- type: "string"
885
- },
886
- global: {
887
- type: "boolean"
888
- },
889
- ignoreCase: {
890
- type: "boolean"
891
- },
892
- multiline: {
893
- type: "boolean"
894
- },
895
- lastIndex: {
896
- type: "number"
897
- },
898
- flags: {
899
- type: "string"
900
- },
901
- sticky: {
902
- type: "boolean"
903
- },
904
- unicode: {
905
- type: "boolean"
906
- },
907
- dotAll: {
908
- type: "boolean"
909
- }
910
- },
911
- additionalProperties: false,
912
- required: [
913
- "dotAll",
914
- "flags",
915
- "global",
916
- "ignoreCase",
917
- "lastIndex",
918
- "multiline",
919
- "source",
920
- "sticky",
921
- "unicode"
922
- ]
923
- }
924
- };
925
- var $schema$2 = "http://json-schema.org/draft-07/schema#";
926
- var injectManifestOptionsSchema = {
927
- additionalProperties: additionalProperties$2,
928
- type: type$2,
929
- properties: properties$2,
930
- required: required$2,
931
- definitions: definitions$2,
932
- $schema: $schema$2
933
- };
934
-
935
- var additionalProperties$1 = false;
936
- var type$1 = "object";
937
- var properties$1 = {
938
- additionalPrecacheEntries: {
939
- description: "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.",
940
- type: "array",
941
- items: {
942
- anyOf: [
943
- {
944
- $ref: "#/definitions/ManifestEntry"
945
- },
946
- {
947
- type: "string"
948
- }
949
- ]
950
- }
951
- },
952
- dontCacheBustURLsMatching: {
953
- description: "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.",
954
- $ref: "#/definitions/RegExp"
955
- },
956
- manifestTransforms: {
957
- description: "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.",
958
- type: "array",
959
- items: {}
960
- },
961
- maximumFileSizeToCacheInBytes: {
962
- description: "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.",
963
- "default": 2097152,
964
- type: "number"
965
- },
966
- modifyURLPrefix: {
967
- description: "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```",
968
- type: "object",
969
- additionalProperties: {
970
- type: "string"
971
- }
972
- },
973
- globFollow: {
974
- description: "Determines whether or not symlinks are followed when generating the\nprecache manifest. For more information, see the definition of `follow` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).",
975
- "default": true,
976
- type: "boolean"
977
- },
978
- globIgnores: {
979
- description: "A set of patterns matching files to always exclude when generating the\nprecache manifest. For more information, see the definition of `ignore` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).",
980
- "default": [
981
- "**/node_modules/**/*"
982
- ],
983
- type: "array",
984
- items: {
985
- type: "string"
986
- }
987
- },
988
- globPatterns: {
989
- description: "Files matching any of these patterns will be included in the precache\nmanifest. For more information, see the\n[`glob` primer](https://github.com/isaacs/node-glob#glob-primer).",
990
- "default": [
991
- "**/*.{js,css,html}"
992
- ],
993
- type: "array",
994
- items: {
995
- type: "string"
996
- }
997
- },
998
- globStrict: {
999
- description: "If true, an error reading a directory when generating a precache manifest\nwill cause the build to fail. If false, the problematic directory will be\nskipped. For more information, see the definition of `strict` in the `glob`\n[documentation](https://github.com/isaacs/node-glob#options).",
1000
- "default": true,
1001
- type: "boolean"
1002
- },
1003
- templatedURLs: {
1004
- description: "If a URL is rendered based on some server-side logic, its contents may\ndepend on multiple files or on some other unique string value. The keys in\nthis object are server-rendered URLs. If the values are an array of\nstrings, they will be interpreted as `glob` patterns, and the contents of\nany files matching the patterns will be used to uniquely version the URL.\nIf used with a single string, it will be interpreted as unique versioning\ninformation that you've generated for a given URL.",
1005
- type: "object",
1006
- additionalProperties: {
1007
- anyOf: [
1008
- {
1009
- type: "array",
1010
- items: {
1011
- type: "string"
1012
- }
1013
- },
1014
- {
1015
- type: "string"
1016
- }
1017
- ]
1018
- }
1019
- },
1020
- injectionPoint: {
1021
- description: "The string to find inside of the `swSrc` file. Once found, it will be\nreplaced by the generated precache manifest.",
1022
- "default": "self.__SW_MANIFEST",
1023
- type: "string"
1024
- },
1025
- swSrc: {
1026
- description: "The path and filename of the service worker file that will be read during\nthe build process, relative to the current working directory.",
1027
- type: "string"
1028
- },
1029
- swDest: {
1030
- description: "The path and filename of the service worker file that will be created by\nthe build process, relative to the current working directory. It must end\nin '.js'.",
1031
- type: "string"
1032
- },
1033
- globDirectory: {
1034
- description: "The local directory you wish to match `globPatterns` against. The path is\nrelative to the current directory.",
1035
- type: "string"
1036
- },
1037
- disablePrecacheManifest: {
1038
- description: "Whether the precache manifest should be set to `undefined`.",
1039
- "default": false,
1040
- type: "boolean"
1041
- }
1042
- };
1043
- var required$1 = [
1044
- "globDirectory",
1045
- "swDest",
1046
- "swSrc"
1047
- ];
1048
- var definitions$1 = {
1049
- ManifestEntry: {
1050
- type: "object",
1051
- properties: {
1052
- integrity: {
1053
- type: "string"
1054
- },
1055
- revision: {
1056
- type: [
1057
- "null",
1058
- "string"
1059
- ]
1060
- },
1061
- url: {
1062
- type: "string"
1063
- }
1064
- },
1065
- additionalProperties: false,
1066
- required: [
1067
- "revision",
1068
- "url"
1069
- ]
1070
- },
1071
- "RegExp": {
1072
- type: "object",
1073
- properties: {
1074
- source: {
1075
- type: "string"
1076
- },
1077
- global: {
1078
- type: "boolean"
1079
- },
1080
- ignoreCase: {
1081
- type: "boolean"
1082
- },
1083
- multiline: {
1084
- type: "boolean"
1085
- },
1086
- lastIndex: {
1087
- type: "number"
1088
- },
1089
- flags: {
1090
- type: "string"
1091
- },
1092
- sticky: {
1093
- type: "boolean"
1094
- },
1095
- unicode: {
1096
- type: "boolean"
1097
- },
1098
- dotAll: {
1099
- type: "boolean"
1100
- }
1101
- },
1102
- additionalProperties: false,
1103
- required: [
1104
- "dotAll",
1105
- "flags",
1106
- "global",
1107
- "ignoreCase",
1108
- "lastIndex",
1109
- "multiline",
1110
- "source",
1111
- "sticky",
1112
- "unicode"
1113
- ]
1114
- }
1115
- };
1116
- var $schema$1 = "http://json-schema.org/draft-07/schema#";
1117
- var viteInjectManifestOptionsSchema = {
1118
- additionalProperties: additionalProperties$1,
1119
- type: type$1,
1120
- properties: properties$1,
1121
- required: required$1,
1122
- definitions: definitions$1,
1123
- $schema: $schema$1
1124
- };
1125
-
1126
- var additionalProperties = false;
1127
- var type = "object";
1128
- var properties = {
1129
- additionalPrecacheEntries: {
1130
- description: "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.",
1131
- type: "array",
1132
- items: {
1133
- anyOf: [
1134
- {
1135
- $ref: "#/definitions/ManifestEntry"
1136
- },
1137
- {
1138
- type: "string"
1139
- }
1140
- ]
1141
- }
1142
- },
1143
- dontCacheBustURLsMatching: {
1144
- description: "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.",
1145
- $ref: "#/definitions/RegExp"
1146
- },
1147
- manifestTransforms: {
1148
- description: "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.",
1149
- type: "array",
1150
- items: {}
1151
- },
1152
- maximumFileSizeToCacheInBytes: {
1153
- description: "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.",
1154
- "default": 2097152,
1155
- type: "number"
1156
- },
1157
- modifyURLPrefix: {
1158
- description: "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```",
1159
- type: "object",
1160
- additionalProperties: {
1161
- type: "string"
1162
- }
1163
- },
1164
- chunks: {
1165
- description: "One or more chunk names whose corresponding output files should be included\nin the precache manifest.",
1166
- type: "array",
1167
- items: {
1168
- type: "string"
1169
- }
1170
- },
1171
- exclude: {
1172
- description: "One or more specifiers used to exclude assets from the precache manifest.\nThis is interpreted following\n[the same rules](https://webpack.js.org/configuration/module/#condition)\nas `webpack`'s standard `exclude` option.\nIf not provided, the default value is `[/\\.map$/, /^manifest.*\\.js$]`.",
1173
- type: "array",
1174
- items: {}
1175
- },
1176
- excludeChunks: {
1177
- description: "One or more chunk names whose corresponding output files should be excluded\nfrom the precache manifest.",
1178
- type: "array",
1179
- items: {
1180
- type: "string"
1181
- }
1182
- },
1183
- include: {
1184
- description: "One or more specifiers used to include assets in the precache manifest.\nThis is interpreted following\n[the same rules](https://webpack.js.org/configuration/module/#condition)\nas `webpack`'s standard `include` option.",
1185
- type: "array",
1186
- items: {}
1187
- },
1188
- mode: {
1189
- description: "If set to 'production', then an optimized service worker bundle that\nexcludes debugging info will be produced. If not explicitly configured\nhere, the `mode` value configured in the current `webpack` compilation\nwill be used.",
1190
- type: [
1191
- "null",
1192
- "string"
1193
- ]
1194
- },
1195
- injectionPoint: {
1196
- description: "The string to find inside of the `swSrc` file. Once found, it will be\nreplaced by the generated precache manifest.",
1197
- "default": "self.__SW_MANIFEST",
1198
- type: "string"
1199
- },
1200
- swSrc: {
1201
- description: "The path and filename of the service worker file that will be read during\nthe build process, relative to the current working directory.",
1202
- type: "string"
1203
- },
1204
- compileSrc: {
1205
- description: "When `true` (the default), the `swSrc` file will be compiled by webpack.\nWhen `false`, compilation will not occur (and `webpackCompilationPlugins`\ncan't be used.) Set to `false` if you want to inject the manifest into,\ne.g., a JSON file.",
1206
- "default": true,
1207
- type: "boolean"
1208
- },
1209
- swDest: {
1210
- description: "The asset name of the service worker file that will be created by this\nplugin. If omitted, the name will be based on the `swSrc` name.",
1211
- type: "string"
1212
- },
1213
- webpackCompilationPlugins: {
1214
- description: "Optional `webpack` plugins that will be used when compiling the `swSrc`\ninput file. Only valid if `compileSrc` is `true`.",
1215
- type: "array",
1216
- items: {}
1217
- },
1218
- disablePrecacheManifest: {
1219
- description: "Whether the precache manifest should be set to `undefined`.",
1220
- "default": false,
1221
- type: "boolean"
1222
- }
1223
- };
1224
- var required = [
1225
- "swSrc"
1226
- ];
1227
- var definitions = {
1228
- ManifestEntry: {
1229
- type: "object",
1230
- properties: {
1231
- integrity: {
1232
- type: "string"
1233
- },
1234
- revision: {
1235
- type: [
1236
- "null",
1237
- "string"
1238
- ]
1239
- },
1240
- url: {
1241
- type: "string"
1242
- }
1243
- },
1244
- additionalProperties: false,
1245
- required: [
1246
- "revision",
1247
- "url"
1248
- ]
1249
- },
1250
- "RegExp": {
1251
- type: "object",
1252
- properties: {
1253
- source: {
1254
- type: "string"
1255
- },
1256
- global: {
1257
- type: "boolean"
1258
- },
1259
- ignoreCase: {
1260
- type: "boolean"
1261
- },
1262
- multiline: {
1263
- type: "boolean"
1264
- },
1265
- lastIndex: {
1266
- type: "number"
1267
- },
1268
- flags: {
1269
- type: "string"
1270
- },
1271
- sticky: {
1272
- type: "boolean"
1273
- },
1274
- unicode: {
1275
- type: "boolean"
1276
- },
1277
- dotAll: {
1278
- type: "boolean"
1279
- }
1280
- },
1281
- additionalProperties: false,
1282
- required: [
1283
- "dotAll",
1284
- "flags",
1285
- "global",
1286
- "ignoreCase",
1287
- "lastIndex",
1288
- "multiline",
1289
- "source",
1290
- "sticky",
1291
- "unicode"
1292
- ]
1293
- }
1294
- };
1295
- var $schema = "http://json-schema.org/draft-07/schema#";
1296
- var webpackInjectManifestOptionsSchema = {
1297
- additionalProperties: additionalProperties,
1298
- type: type,
1299
- properties: properties,
1300
- required: required,
1301
- definitions: definitions,
1302
- $schema: $schema
1303
- };
1304
-
1305
- const optionsSchemas = {
1306
- GetManifest: getManifestOptionsSchema,
1307
- InjectManifest: injectManifestOptionsSchema,
1308
- WebpackInjectManifest: webpackInjectManifestOptionsSchema,
1309
- ViteInjectManifest: viteInjectManifestOptionsSchema
1310
- };
1311
-
1312
- const ajv = new Ajv({
1313
- useDefaults: true
1314
- });
1315
- const DEFAULT_EXCLUDE_VALUE = [
1316
- /\.map$/,
1317
- /^manifest.*\.js$/
1318
- ];
1319
- class SerwistConfigError extends Error {
1320
- constructor(message){
1321
- super(message);
1322
- Object.setPrototypeOf(this, new.target.prototype);
1323
- }
1324
- }
1325
- // Some methods need to do follow-up validation using the JSON schema,
1326
- // so return both the validated options and then schema.
1327
- function validate(input, methodName) {
1328
- // Don't mutate input: https://github.com/GoogleChrome/workbox/issues/2158
1329
- const inputCopy = Object.assign({}, input);
1330
- const jsonSchema = optionsSchemas[methodName];
1331
- const validate = ajv.compile(jsonSchema);
1332
- if (validate(inputCopy)) {
1333
- // All methods support manifestTransforms, so validate it here.
1334
- ensureValidManifestTransforms(inputCopy);
1335
- return [
1336
- inputCopy,
1337
- jsonSchema
1338
- ];
1339
- }
1340
- const betterErrors = betterAjvErrors.betterAjvErrors({
1341
- basePath: methodName,
1342
- data: input,
1343
- errors: validate.errors,
1344
- // This is needed as JSONSchema6 is expected, but JSONSchemaType works.
1345
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1346
- schema: jsonSchema
1347
- });
1348
- const messages = betterErrors.map((err)=>commonTags.oneLine`[${err.path}] ${err.message}.
1349
- ${err.suggestion ? err.suggestion : ""}`);
1350
- throw new SerwistConfigError(messages.join("\n\n"));
1351
- }
1352
- function ensureValidManifestTransforms(options) {
1353
- if ("manifestTransforms" in options && !(Array.isArray(options.manifestTransforms) && options.manifestTransforms.every((item)=>typeof item === "function"))) {
1354
- throw new SerwistConfigError(errors["manifest-transforms"]);
1355
- }
1356
- }
1357
- function validateGetManifestOptions(input) {
1358
- const [validatedOptions] = validate(input, "GetManifest");
1359
- return validatedOptions;
1360
- }
1361
- function validateInjectManifestOptions(input) {
1362
- const [validatedOptions] = validate(input, "InjectManifest");
1363
- return validatedOptions;
1364
- }
1365
- function validateWebpackInjectManifestOptions(input) {
1366
- const inputWithExcludeDefault = Object.assign({
1367
- // Make a copy, as exclude can be mutated when used.
1368
- exclude: Array.from(DEFAULT_EXCLUDE_VALUE)
1369
- }, input);
1370
- const [validatedOptions] = validate(inputWithExcludeDefault, "WebpackInjectManifest");
1371
- return validatedOptions;
1372
- }
1373
- const validateViteInjectManifestOptions = (input)=>{
1374
- const [validatedOptions] = validate(input, "ViteInjectManifest");
1375
- return validatedOptions;
1376
- };
1377
-
1378
- /**
1379
- * This method returns a list of URLs to precache, referred to as a "precache
1380
- * manifest", along with details about the number of entries and their size,
1381
- * based on the options you provide.
1382
- *
1383
- * ```
1384
- * // The following lists some common options; see the rest of the documentation
1385
- * // for the full set of options and defaults.
1386
- * const {count, manifestEntries, size, warnings} = await getManifest({
1387
- * dontCacheBustURLsMatching: [new RegExp('...')],
1388
- * globDirectory: '...',
1389
- * globPatterns: ['...', '...'],
1390
- * maximumFileSizeToCacheInBytes: ...,
1391
- * });
1392
- * ```
1393
- */ async function getManifest(config) {
1394
- const options = validateGetManifestOptions(config);
1395
- return await getFileManifestEntries(options);
1396
- }
1397
-
1398
- /*
1399
- Copyright 2022 Google LLC
1400
-
1401
- Use of this source code is governed by an MIT-style
1402
- license that can be found in the LICENSE file or at
1403
- https://opensource.org/licenses/MIT.
1404
- */ // Adapted from https://github.com/lydell/source-map-url/blob/master/source-map-url.js
1405
- // See https://github.com/GoogleChrome/workbox/issues/3019
1406
- const innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/;
1407
- const regex = RegExp(`(?:/\\*(?:\\s*\r?\n(?://)?)?(?:${innerRegex.source})\\s*\\*/|//(?:${innerRegex.source}))\\s*`);
1408
- function getSourceMapURL(srcContents) {
1409
- const match = srcContents.match(regex);
1410
- return match ? match[1] || match[2] || "" : null;
1411
- }
1412
-
1413
- function rebasePath({ baseDirectory, file }) {
1414
- // The initial path is relative to the current directory, so make it absolute.
1415
- const absolutePath = upath.resolve(file);
1416
- // Convert the absolute path so that it's relative to the baseDirectory.
1417
- const relativePath = upath.relative(baseDirectory, absolutePath);
1418
- // Remove any leading ./ as it won't work in a glob pattern.
1419
- const normalizedPath = upath.normalize(relativePath);
1420
- return normalizedPath;
1421
- }
1422
-
1423
- /**
1424
- * Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern
1425
- * JavaScript updates, along with additional properties copied from originalMap.
1426
- *
1427
- * @param options
1428
- * @returns An object containing both
1429
- * originalSource with the replacement applied, and the modified originalMap.
1430
- * @private
1431
- */ async function replaceAndUpdateSourceMap({ jsFilename, originalMap, originalSource, replaceString, searchString }) {
1432
- const generator = new sourceMap.SourceMapGenerator({
1433
- file: jsFilename
1434
- });
1435
- const consumer = await new sourceMap.SourceMapConsumer(originalMap);
1436
- let pos;
1437
- let src = originalSource;
1438
- const replacements = [];
1439
- let lineNum = 0;
1440
- let filePos = 0;
1441
- const lines = src.split("\n");
1442
- for (let line of lines){
1443
- lineNum++;
1444
- let searchPos = 0;
1445
- while((pos = line.indexOf(searchString, searchPos)) !== -1){
1446
- src = src.substring(0, filePos + pos) + replaceString + src.substring(filePos + pos + searchString.length);
1447
- line = line.substring(0, pos) + replaceString + line.substring(pos + searchString.length);
1448
- replacements.push({
1449
- line: lineNum,
1450
- column: pos
1451
- });
1452
- searchPos = pos + replaceString.length;
1453
- }
1454
- filePos += line.length + 1;
1455
- }
1456
- replacements.reverse();
1457
- consumer.eachMapping((mapping)=>{
1458
- for (const replacement of replacements){
1459
- if (replacement.line === mapping.generatedLine && mapping.generatedColumn > replacement.column) {
1460
- const offset = searchString.length - replaceString.length;
1461
- mapping.generatedColumn -= offset;
1462
- }
1463
- }
1464
- if (mapping.source) {
1465
- const newMapping = {
1466
- generated: {
1467
- line: mapping.generatedLine,
1468
- column: mapping.generatedColumn
1469
- },
1470
- original: {
1471
- line: mapping.originalLine,
1472
- column: mapping.originalColumn
1473
- },
1474
- source: mapping.source
1475
- };
1476
- return generator.addMapping(newMapping);
1477
- }
1478
- return mapping;
1479
- });
1480
- consumer.destroy();
1481
- // JSON.parse returns any.
1482
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1483
- const updatedSourceMap = Object.assign(JSON.parse(generator.toString()), {
1484
- names: originalMap.names,
1485
- sourceRoot: originalMap.sourceRoot,
1486
- sources: originalMap.sources,
1487
- sourcesContent: originalMap.sourcesContent
1488
- });
1489
- return {
1490
- map: JSON.stringify(updatedSourceMap),
1491
- source: src
1492
- };
1493
- }
1494
-
1495
- function translateURLToSourcemapPaths(url, swSrc, swDest) {
1496
- let destPath = undefined;
1497
- let srcPath = undefined;
1498
- let warning = undefined;
1499
- if (url && !url.startsWith("data:")) {
1500
- const possibleSrcPath = upath.resolve(upath.dirname(swSrc), url);
1501
- if (fse.existsSync(possibleSrcPath)) {
1502
- srcPath = possibleSrcPath;
1503
- destPath = upath.resolve(upath.dirname(swDest), url);
1504
- } else {
1505
- warning = `${errors["cant-find-sourcemap"]} ${possibleSrcPath}`;
1506
- }
1507
- }
1508
- return {
1509
- destPath,
1510
- srcPath,
1511
- warning
1512
- };
1513
- }
1514
-
1515
- /**
1516
- * This method creates a list of URLs to precache, referred to as a "precache
1517
- * manifest", based on the options you provide.
1518
- *
1519
- * The manifest is injected into the `swSrc` file, and the placeholder string
1520
- * `injectionPoint` determines where in the file the manifest should go.
1521
- *
1522
- * The final service worker file, with the manifest injected, is written to
1523
- * disk at `swDest`.
1524
- *
1525
- * This method will not compile or bundle your `swSrc` file; it just handles
1526
- * injecting the manifest.
1527
- *
1528
- * ```
1529
- * // The following lists some common options; see the rest of the documentation
1530
- * // for the full set of options and defaults.
1531
- * const {count, size, warnings} = await injectManifest({
1532
- * dontCacheBustURLsMatching: [new RegExp('...')],
1533
- * globDirectory: '...',
1534
- * globPatterns: ['...', '...'],
1535
- * maximumFileSizeToCacheInBytes: ...,
1536
- * swDest: '...',
1537
- * swSrc: '...',
1538
- * });
1539
- * ```
1540
- */ async function injectManifest(config) {
1541
- const options = validateInjectManifestOptions(config);
1542
- // Make sure we leave swSrc and swDest out of the precache manifest.
1543
- for (const file of [
1544
- options.swSrc,
1545
- options.swDest
1546
- ]){
1547
- options.globIgnores.push(rebasePath({
1548
- file,
1549
- baseDirectory: options.globDirectory
1550
- }));
1551
- }
1552
- const globalRegexp = new RegExp(escapeRegExp(options.injectionPoint), "g");
1553
- const { count, size, manifestEntries, warnings } = await getFileManifestEntries(options);
1554
- let swFileContents;
1555
- try {
1556
- swFileContents = await fse.readFile(options.swSrc, "utf8");
1557
- } catch (error) {
1558
- throw new Error(`${errors["invalid-sw-src"]} ${error instanceof Error && error.message ? error.message : ""}`);
1559
- }
1560
- const injectionResults = swFileContents.match(globalRegexp);
1561
- // See https://github.com/GoogleChrome/workbox/issues/2230
1562
- const injectionPoint = options.injectionPoint ? options.injectionPoint : "";
1563
- if (!injectionResults) {
1564
- if (upath.resolve(options.swSrc) === upath.resolve(options.swDest)) {
1565
- throw new Error(`${errors["same-src-and-dest"]} ${injectionPoint}`);
1566
- }
1567
- throw new Error(`${errors["injection-point-not-found"]} ${injectionPoint}`);
1568
- }
1569
- assert(injectionResults.length === 1, `${errors["multiple-injection-points"]} ${injectionPoint}`);
1570
- const manifestString = manifestEntries === undefined ? "undefined" : stringify(manifestEntries);
1571
- const filesToWrite = {};
1572
- const url = getSourceMapURL(swFileContents);
1573
- // See https://github.com/GoogleChrome/workbox/issues/2957
1574
- const { destPath, srcPath, warning } = translateURLToSourcemapPaths(url, options.swSrc, options.swDest);
1575
- if (warning) {
1576
- warnings.push(warning);
1577
- }
1578
- // If our swSrc file contains a sourcemap, we would invalidate that
1579
- // mapping if we just replaced injectionPoint with the stringified manifest.
1580
- // Instead, we need to update the swDest contents as well as the sourcemap
1581
- // (assuming it's a real file, not a data: URL) at the same time.
1582
- // See https://github.com/GoogleChrome/workbox/issues/2235
1583
- // and https://github.com/GoogleChrome/workbox/issues/2648
1584
- if (srcPath && destPath) {
1585
- const originalMap = await fse.readJSON(srcPath, {
1586
- encoding: "utf8"
1587
- });
1588
- const { map, source } = await replaceAndUpdateSourceMap({
1589
- originalMap,
1590
- jsFilename: upath.basename(options.swDest),
1591
- originalSource: swFileContents,
1592
- replaceString: manifestString,
1593
- searchString: options.injectionPoint
1594
- });
1595
- filesToWrite[options.swDest] = source;
1596
- filesToWrite[destPath] = map;
1597
- } else {
1598
- // If there's no sourcemap associated with swSrc, a simple string
1599
- // replacement will suffice.
1600
- filesToWrite[options.swDest] = swFileContents.replace(globalRegexp, manifestString);
1601
- }
1602
- for (const [file, contents] of Object.entries(filesToWrite)){
1603
- try {
1604
- await fse.mkdirp(upath.dirname(file));
1605
- } catch (error) {
1606
- throw new Error(`${errors["unable-to-make-sw-directory"]} '${error instanceof Error && error.message ? error.message : ""}'`);
1607
- }
1608
- await fse.writeFile(file, contents);
1609
- }
1610
- return {
1611
- count,
1612
- size,
1613
- warnings,
1614
- // Use upath.resolve() to make all the paths absolute.
1615
- filePaths: Object.keys(filesToWrite).map((f)=>upath.resolve(f))
1616
- };
1617
- }
1618
-
1619
- exports.stringify = stringify;
1620
- exports.errors = errors;
1621
- exports.escapeRegExp = escapeRegExp;
1622
- exports.getFileManifestEntries = getFileManifestEntries;
1623
- exports.getManifest = getManifest;
1624
- exports.getSourceMapURL = getSourceMapURL;
1625
- exports.injectManifest = injectManifest;
1626
- exports.rebasePath = rebasePath;
1627
- exports.replaceAndUpdateSourceMap = replaceAndUpdateSourceMap;
1628
- exports.transformManifest = transformManifest;
1629
- exports.translateURLToSourcemapPaths = translateURLToSourcemapPaths;
1630
- exports.validateInjectManifestOptions = validateInjectManifestOptions;
1631
- exports.validateViteInjectManifestOptions = validateViteInjectManifestOptions;
1632
- exports.validateWebpackInjectManifestOptions = validateWebpackInjectManifestOptions;