UNPKG

7.6 kBJavaScriptView Raw
1'use strict';
2
3var _entries = require('babel-runtime/core-js/object/entries');
4
5var _entries2 = _interopRequireDefault(_entries);
6
7var _getIterator2 = require('babel-runtime/core-js/get-iterator');
8
9var _getIterator3 = _interopRequireDefault(_getIterator2);
10
11var _stringify = require('babel-runtime/core-js/json/stringify');
12
13var _stringify2 = _interopRequireDefault(_stringify);
14
15var _keys = require('babel-runtime/core-js/object/keys');
16
17var _keys2 = _interopRequireDefault(_keys);
18
19var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
20
21var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
22
23function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
25/*
26 Copyright 2017 Google Inc.
27
28 Licensed under the Apache License, Version 2.0 (the "License");
29 you may not use this file except in compliance with the License.
30 You may obtain a copy of the License at
31
32 https://www.apache.org/licenses/LICENSE-2.0
33
34 Unless required by applicable law or agreed to in writing, software
35 distributed under the License is distributed on an "AS IS" BASIS,
36 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37 See the License for the specific language governing permissions and
38 limitations under the License.
39*/
40
41var ol = require('common-tags').oneLine;
42
43var errors = require('./errors');
44var stringifyWithoutComments = require('./stringify-without-comments');
45
46/**
47 * Given a set of options that configures `sw-toolbox`'s behavior, convert it
48 * into a string that would configure equivalent `workbox-sw` behavior.
49 *
50 * @param {Object} options See
51 * https://googlechrome.github.io/sw-toolbox/api.html#options
52 * @return {string} A JSON string representing the equivalent options.
53 *
54 * @private
55 */
56function getOptionsString() {
57 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
58
59 var plugins = [];
60 if (options.plugins) {
61 // Using libs because JSON.stringify won't handle functions.
62 plugins = options.plugins.map(stringifyWithoutComments);
63 delete options.plugins;
64 }
65
66 // Pull handler-specific config from the options object, since they are
67 // not directly used to construct a Plugin instance. If set, need to be
68 // passed as options to the handler constructor instead.
69 var handlerOptionKeys = ['cacheName', 'networkTimeoutSeconds', 'fetchOptions', 'matchOptions'];
70 var handlerOptions = {};
71 var _iteratorNormalCompletion = true;
72 var _didIteratorError = false;
73 var _iteratorError = undefined;
74
75 try {
76 for (var _iterator = (0, _getIterator3.default)(handlerOptionKeys), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
77 var key = _step.value;
78
79 if (key in options) {
80 handlerOptions[key] = options[key];
81 delete options[key];
82 }
83 }
84 } catch (err) {
85 _didIteratorError = true;
86 _iteratorError = err;
87 } finally {
88 try {
89 if (!_iteratorNormalCompletion && _iterator.return) {
90 _iterator.return();
91 }
92 } finally {
93 if (_didIteratorError) {
94 throw _iteratorError;
95 }
96 }
97 }
98
99 var pluginsMapping = {
100 backgroundSync: 'workbox.backgroundSync.Plugin',
101 broadcastUpdate: 'workbox.broadcastUpdate.Plugin',
102 expiration: 'workbox.expiration.Plugin',
103 cacheableResponse: 'workbox.cacheableResponse.Plugin'
104 };
105
106 var _iteratorNormalCompletion2 = true;
107 var _didIteratorError2 = false;
108 var _iteratorError2 = undefined;
109
110 try {
111 for (var _iterator2 = (0, _getIterator3.default)((0, _entries2.default)(options)), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
112 var _ref = _step2.value;
113
114 var _ref2 = (0, _slicedToArray3.default)(_ref, 2);
115
116 var pluginName = _ref2[0];
117 var pluginConfig = _ref2[1];
118
119 // Ensure that we have some valid configuration to pass to Plugin().
120 if ((0, _keys2.default)(pluginConfig).length === 0) {
121 continue;
122 }
123
124 var pluginString = pluginsMapping[pluginName];
125 if (!pluginString) {
126 throw new Error(`${errors['bad-runtime-caching-config']} ${pluginName}`);
127 }
128
129 var pluginCode = void 0;
130 switch (pluginName) {
131 // Special case logic for plugins that have a required parameter, and then
132 // an additional optional config parameter.
133 case 'backgroundSync':
134 {
135 var name = pluginConfig.name;
136 pluginCode = `new ${pluginString}(${(0, _stringify2.default)(name)}`;
137 if ('options' in pluginConfig) {
138 pluginCode += `, ${(0, _stringify2.default)(pluginConfig.options)}`;
139 }
140 pluginCode += `)`;
141
142 break;
143 }
144
145 case 'broadcastUpdate':
146 {
147 var channelName = pluginConfig.channelName;
148 pluginCode = `new ${pluginString}(${(0, _stringify2.default)(channelName)}`;
149 if ('options' in pluginConfig) {
150 pluginCode += `, ${(0, _stringify2.default)(pluginConfig.options)}`;
151 }
152 pluginCode += `)`;
153
154 break;
155 }
156
157 // For plugins that just pass in an Object to the constructor, like
158 // expiration and cacheableResponse
159 default:
160 {
161 pluginCode = `new ${pluginString}(${(0, _stringify2.default)(pluginConfig)})`;
162 }
163 }
164
165 plugins.push(pluginCode);
166 }
167 } catch (err) {
168 _didIteratorError2 = true;
169 _iteratorError2 = err;
170 } finally {
171 try {
172 if (!_iteratorNormalCompletion2 && _iterator2.return) {
173 _iterator2.return();
174 }
175 } finally {
176 if (_didIteratorError2) {
177 throw _iteratorError2;
178 }
179 }
180 }
181
182 if ((0, _keys2.default)(handlerOptions).length > 0 || plugins.length > 0) {
183 var optionsString = (0, _stringify2.default)(handlerOptions).slice(1, -1);
184 return ol`{
185 ${optionsString ? optionsString + ',' : ''}
186 plugins: [${plugins.join(', ')}]
187 }`;
188 } else {
189 return '';
190 }
191}
192
193module.exports = function () {
194 var runtimeCaching = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
195
196 return runtimeCaching.map(function (entry) {
197 var method = entry.method || 'GET';
198
199 if (!entry.urlPattern) {
200 throw new Error(errors['urlPattern-is-required']);
201 }
202
203 if (!entry.handler) {
204 throw new Error(errors['handler-is-required']);
205 }
206
207 // This validation logic is a bit too gnarly for joi, so it's manually
208 // implemented here.
209 if (entry.options && entry.options.networkTimeoutSeconds && entry.handler !== 'networkFirst') {
210 throw new Error(errors['invalid-network-timeout-seconds']);
211 }
212
213 // urlPattern might be either a string or a RegExp object.
214 // If it's a string, it needs to be quoted. If it's a RegExp, it should
215 // be used as-is.
216 var matcher = typeof entry.urlPattern === 'string' ? (0, _stringify2.default)(entry.urlPattern) : entry.urlPattern;
217
218 if (typeof entry.handler === 'string') {
219 var optionsString = getOptionsString(entry.options || {});
220
221 var strategyString = `workbox.strategies.${entry.handler}(${optionsString})`;
222
223 return `workbox.routing.registerRoute(` + `${matcher}, ${strategyString}, '${method}');\n`;
224 } else if (typeof entry.handler === 'function') {
225 return `workbox.routing.registerRoute(` + `${matcher}, ${entry.handler}, '${method}');\n`;
226 }
227 }).filter(function (entry) {
228 return Boolean(entry);
229 }); // Remove undefined map() return values.
230};
\No newline at end of file