UNPKG

2.18 kBJavaScriptView Raw
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
9const errors = require('./errors');
10
11/**
12 * Escaping user input to be treated as a literal string within a regular
13 * expression can be accomplished by simple replacement.
14 *
15 * From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
16 *
17 * @private
18 * @param {string} string The string to be used as part of a regular
19 * expression
20 * @return {string} A string that is safe to use in a regular
21 * expression.
22 *
23 * @private
24 */
25const escapeRegExp = (string) => {
26 return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
27};
28
29module.exports = (modifyURLPrefix) => {
30 if (!modifyURLPrefix ||
31 typeof modifyURLPrefix !== 'object' ||
32 Array.isArray(modifyURLPrefix)) {
33 throw new Error(errors['modify-url-prefix-bad-prefixes']);
34 }
35
36 // If there are no entries in modifyURLPrefix, just return an identity
37 // function as a shortcut.
38 if (Object.keys(modifyURLPrefix).length === 0) {
39 return (entry) => entry;
40 }
41
42 Object.keys(modifyURLPrefix).forEach((key) => {
43 if (typeof modifyURLPrefix[key] !== 'string') {
44 throw new Error(errors['modify-url-prefix-bad-prefixes']);
45 }
46 });
47
48 // Escape the user input so it's safe to use in a regex.
49 const safeModifyURLPrefixes = Object.keys(modifyURLPrefix).map(escapeRegExp);
50 // Join all the `modifyURLPrefix` keys so a single regex can be used.
51 const prefixMatchesStrings = safeModifyURLPrefixes.join('|');
52 // Add `^` to the front the prefix matches so it only matches the start of
53 // a string.
54 const modifyRegex = new RegExp(`^(${prefixMatchesStrings})`);
55
56 return (originalManifest) => {
57 const manifest = originalManifest.map((entry) => {
58 if (typeof entry.url !== 'string') {
59 throw new Error(errors['manifest-entry-bad-url']);
60 }
61
62 entry.url = entry.url.replace(modifyRegex, (match) => {
63 return modifyURLPrefix[match];
64 });
65
66 return entry;
67 });
68
69 return {manifest};
70 };
71};