1 | /*
|
2 | Copyright 2018 Google LLC
|
3 |
|
4 | Use of this source code is governed by an MIT-style
|
5 | license that can be found in the LICENSE file or at
|
6 | https://opensource.org/licenses/MIT.
|
7 | */
|
8 |
|
9 | const maximumSizeTransform = require('./maximum-size-transform');
|
10 | const modifyURLPrefixTranform = require('./modify-url-prefix-transform');
|
11 | const noRevisionForURLsMatchingTransform =
|
12 | require('./no-revision-for-urls-matching-transform');
|
13 |
|
14 | /**
|
15 | * A `ManifestTransform` function can be used to modify the modify the `url` or
|
16 | * `revision` properties of some or all of the
|
17 | * {@link module:workbox-build#ManifestEntry|ManifestEntries} in the manifest.
|
18 | *
|
19 | * Deleting the `revision` property of an entry will cause
|
20 | * the corresponding `url` to be precached without cache-busting parameters
|
21 | * applied, which is to say, it implies that the URL itself contains
|
22 | * proper versioning info. If the `revision` property is present, it must be
|
23 | * set to a string.
|
24 | *
|
25 | * @example <caption>A transformation that prepended the origin of a CDN for any
|
26 | * URL starting with '/assets/' could be implemented as:</caption>
|
27 | *
|
28 | * const cdnTransform = (manifestEntries) => {
|
29 | * const manifest = manifestEntries.map(entry => {
|
30 | * const cdnOrigin = 'https://example.com';
|
31 | * if (entry.url.startsWith('/assets/')) {
|
32 | * entry.url = cdnOrigin + entry.url;
|
33 | * }
|
34 | * return entry;
|
35 | * });
|
36 | * return {manifest, warnings: []};
|
37 | * };
|
38 | *
|
39 | * @example <caption>A transformation that removes the revision field when the
|
40 | * URL contains an 8-character hash surrounded by '.', indicating that it
|
41 | * already contains revision information:</caption>
|
42 | *
|
43 | * const removeRevisionTransform = (manifestEntries) => {
|
44 | * const manifest = manifestEntries.map(entry => {
|
45 | * const hashRegExp = /\.\w{8}\./;
|
46 | * if (entry.url.match(hashRegExp)) {
|
47 | * delete entry.revision;
|
48 | * }
|
49 | * return entry;
|
50 | * });
|
51 | * return {manifest, warnings: []};
|
52 | * };
|
53 | *
|
54 | * @callback ManifestTransform
|
55 | * @param {Array<module:workbox-build.ManifestEntry>} manifestEntries The full
|
56 | * array of entries, prior to the current transformation.
|
57 | * @return {module:workbox-build.ManifestTransformResult}
|
58 | * The array of entries with the transformation applied, and optionally, any
|
59 | * warnings that should be reported back to the build tool.
|
60 | *
|
61 | * @memberof module:workbox-build
|
62 | */
|
63 |
|
64 | module.exports = ({
|
65 | dontCacheBustURLsMatching,
|
66 | fileDetails,
|
67 | manifestTransforms,
|
68 | maximumFileSizeToCacheInBytes,
|
69 | modifyURLPrefix,
|
70 | }) => {
|
71 | let allWarnings = [];
|
72 |
|
73 | // Take the array of fileDetail objects and convert it into an array of
|
74 | // {url, revision, size} objects, with \ replaced with /.
|
75 | const normalizedManifest = fileDetails.map((fileDetails) => {
|
76 | return {
|
77 | url: fileDetails.file.replace(/\\/g, '/'),
|
78 | revision: fileDetails.hash,
|
79 | size: fileDetails.size,
|
80 | };
|
81 | });
|
82 |
|
83 | let transformsToApply = [];
|
84 |
|
85 | if (maximumFileSizeToCacheInBytes) {
|
86 | transformsToApply.push(maximumSizeTransform(maximumFileSizeToCacheInBytes));
|
87 | }
|
88 |
|
89 | if (modifyURLPrefix) {
|
90 | transformsToApply.push(modifyURLPrefixTranform(modifyURLPrefix));
|
91 | }
|
92 |
|
93 | if (dontCacheBustURLsMatching) {
|
94 | transformsToApply.push(
|
95 | noRevisionForURLsMatchingTransform(dontCacheBustURLsMatching));
|
96 | }
|
97 |
|
98 | // Any additional manifestTransforms that were passed will be applied last.
|
99 | transformsToApply = transformsToApply.concat(manifestTransforms || []);
|
100 |
|
101 | let transformedManifest = normalizedManifest;
|
102 | for (const transform of transformsToApply) {
|
103 | const {manifest, warnings} = transform(transformedManifest);
|
104 | transformedManifest = manifest;
|
105 | allWarnings = allWarnings.concat(warnings || []);
|
106 | }
|
107 |
|
108 | // Generate some metadata about the manifest before we clear out the size
|
109 | // properties from each entry.
|
110 | const count = transformedManifest.length;
|
111 | let size = 0;
|
112 | for (const manifestEntry of transformedManifest) {
|
113 | size += manifestEntry.size;
|
114 | delete manifestEntry.size;
|
115 | }
|
116 |
|
117 | return {
|
118 | count,
|
119 | size,
|
120 | manifestEntries: transformedManifest,
|
121 | warnings: allWarnings,
|
122 | };
|
123 | };
|