diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/workbox-build/src | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/workbox-build/src')
36 files changed, 2032 insertions, 0 deletions
diff --git a/node_modules/workbox-build/src/_types.js b/node_modules/workbox-build/src/_types.js new file mode 100644 index 00000000..bfdb13cf --- /dev/null +++ b/node_modules/workbox-build/src/_types.js @@ -0,0 +1,34 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import './_version.mjs'; + + /** + * @typedef {Object} ManifestEntry + * @property {String} url The URL to the asset in the manifest. + * @property {String} revision The revision details for the file. This is a + * hash generated by node based on the file contents. + * + * @memberof module:workbox-build + */ + +/** + * @typedef {Object} ManifestTransformResult + * @property {Array<ManifestEntry>} manifest + * @property {Array<string>|undefined} warnings + * + * @memberof module:workbox-build + */ diff --git a/node_modules/workbox-build/src/cdn-details.json b/node_modules/workbox-build/src/cdn-details.json new file mode 100644 index 00000000..b9ae19ea --- /dev/null +++ b/node_modules/workbox-build/src/cdn-details.json @@ -0,0 +1,6 @@ +{ + "origin": "https://storage.googleapis.com", + "bucketName": "workbox-cdn", + "releasesDir": "releases", + "latestVersion": "3.6.3" +} diff --git a/node_modules/workbox-build/src/entry-points/generate-sw-string.js b/node_modules/workbox-build/src/entry-points/generate-sw-string.js new file mode 100644 index 00000000..925be51f --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/generate-sw-string.js @@ -0,0 +1,47 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const generateSWStringSchema = require('./options/generate-sw-string-schema'); +const getFileManifestEntries = require('../lib/get-file-manifest-entries'); +const populateSWTemplate = require('../lib/populate-sw-template'); +const validate = require('./options/validate'); + +/** + * This method generates a service worker based on the configuration options + * provided. + * + * @param {Object} config Please refer to the + * [configuration guide](https://developers.google.com/web/tools/workbox/modules/workbox-build#generateswstring_mode). + * @return {Promise<{swString: string, warnings: Array<string>}>} A promise that + * resolves once the service worker template is populated. The `swString` + * property contains a string representation of the full service worker code. + * Any non-fatal warning messages will be returned via `warnings`. + * + * @memberof module:workbox-build + */ +async function generateSWString(config) { + const options = validate(config, generateSWStringSchema); + + const {manifestEntries, warnings} = await getFileManifestEntries(options); + + const swString = await populateSWTemplate(Object.assign({ + manifestEntries, + }, options)); + + return {swString, warnings}; +} + +module.exports = generateSWString; diff --git a/node_modules/workbox-build/src/entry-points/generate-sw.js b/node_modules/workbox-build/src/entry-points/generate-sw.js new file mode 100644 index 00000000..7d3b7078 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/generate-sw.js @@ -0,0 +1,84 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const path = require('path'); + +const cdnUtils = require('../lib/cdn-utils'); +const copyWorkboxLibraries = require('../lib/copy-workbox-libraries'); +const generateSWSchema = require('./options/generate-sw-schema'); +const getFileManifestEntries = require('../lib/get-file-manifest-entries'); +const validate = require('./options/validate'); +const writeServiceWorkerUsingDefaultTemplate = + require('../lib/write-sw-using-default-template'); + +/** + * This method creates a list of URLs to precache, referred to as a "precache + * manifest", based on the options you provide. + * + * It also takes in additional options that configures the service worker's + * behavior, like any `runtimeCaching` rules it should use. + * + * Based on the precache manifest and the additional configuration, it writes + * a ready-to-use service worker file to disk at `swDest`. + * + * @param {Object} config Please refer to the + * [configuration guide](https://developers.google.com/web/tools/workbox/modules/workbox-build#full_generatesw_config). + * @return {Promise<{count: number, size: number, warnings: Array<string>}>} + * A promise that resolves once the service worker file has been written to + * `swDest`. The `size` property contains the aggregate size of all the + * precached entries, in bytes, and the `count` property contains the total + * number of precached entries. Any non-fatal warning messages will be returned + * via `warnings`. + * + * @memberof module:workbox-build + */ +async function generateSW(config) { + const options = validate(config, generateSWSchema); + + const destDirectory = path.dirname(options.swDest); + + // Do nothing if importWorkboxFrom is set to 'disabled'. Otherwise, check: + if (options.importWorkboxFrom === 'cdn') { + const cdnUrl = cdnUtils.getModuleUrl('workbox-sw'); + options.workboxSWImport = cdnUrl; + } else if (options.importWorkboxFrom === 'local') { + // Copy over the dev + prod version of all of the core libraries. + const workboxDirectoryName = await copyWorkboxLibraries(destDirectory); + + // The Workbox library files should not be precached, since they're cached + // automatically by virtue of being used with importScripts(). + options.globIgnores = [ + `**/${workboxDirectoryName}/*.js*`, + ].concat(options.globIgnores || []); + + const workboxSWPkg = require(`workbox-sw/package.json`); + const workboxSWFilename = path.basename(workboxSWPkg.main); + + options.workboxSWImport = `${workboxDirectoryName}/${workboxSWFilename}`; + options.modulePathPrefix = workboxDirectoryName; + } + + const {count, size, manifestEntries, warnings} = + await getFileManifestEntries(options); + + await writeServiceWorkerUsingDefaultTemplate(Object.assign({ + manifestEntries, + }, options)); + + return {count, size, warnings}; +} + +module.exports = generateSW; diff --git a/node_modules/workbox-build/src/entry-points/get-manifest.js b/node_modules/workbox-build/src/entry-points/get-manifest.js new file mode 100644 index 00000000..6eafaee5 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/get-manifest.js @@ -0,0 +1,46 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const getFileManifestEntries = require('../lib/get-file-manifest-entries'); +const getManifestSchema = require('./options/get-manifest-schema'); +const validate = require('./options/validate'); + +/** + * This method returns a list of URLs to precache, referred to as a "precache + * manifest", along with details about the number of entries and their size, + * based on the options you provide. + * + * @param {Object} config Please refer to the + * [configuration guide](https://developers.google.com/web/tools/workbox/modules/workbox-build#getmanifest_mode). + * @return {Promise<{manifestEntries: Array<ManifestEntry>, + * count: number, size: number, warnings: Array<string>}>} A promise that + * resolves once the precache manifest is determined. The `size` property + * contains the aggregate size of all the precached entries, in bytes, the + * `count` property contains the total number of precached entries, and the + * `manifestEntries` property contains all the `ManifestEntry` items. Any + * non-fatal warning messages will be returned via `warnings`. + * + * @memberof module:workbox-build + */ +async function getManifest(config) { + const options = validate(config, getManifestSchema); + + const {manifestEntries, count, size, warnings} = + await getFileManifestEntries(options); + return {manifestEntries, count, size, warnings}; +} + +module.exports = getManifest; diff --git a/node_modules/workbox-build/src/entry-points/inject-manifest.js b/node_modules/workbox-build/src/entry-points/inject-manifest.js new file mode 100644 index 00000000..eac3e820 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/inject-manifest.js @@ -0,0 +1,93 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const assert = require('assert'); +const fse = require('fs-extra'); +const path = require('path'); + +const defaults = require('./options/defaults'); +const errors = require('../lib/errors'); +const getFileManifestEntries = require('../lib/get-file-manifest-entries'); +const injectManifestSchema = require('./options/inject-manifest-schema'); +const validate = require('./options/validate'); + +/** + * This method creates a list of URLs to precache, referred to as a "precache + * manifest", based on the options you provide. + * + * The manifest is injected into the `swSrc` file, and the regular expression + * `injectionPointRegexp` determines where in the file the manifest should go. + * + * The final service worker file, with the manifest injected, is written to + * disk at `swDest`. + * + * @param {Object} config Please refer to the + * [configuration guide](https://developers.google.com/web/tools/workbox/modules/workbox-build#full_injectmanifest_config). + * @return {Promise<{count: number, size: number, warnings: Array<string>}>} + * A promise that resolves once the service worker file has been written to + * `swDest`. The `size` property contains the aggregate size of all the + * precached entries, in bytes, and the `count` property contains the total + * number of precached entries. Any non-fatal warning messages will be returned + * via `warnings`. + * + * @memberof module:workbox-build + */ +async function injectManifest(config) { + const options = validate(config, injectManifestSchema); + + if (path.normalize(config.swSrc) === path.normalize(config.swDest)) { + throw new Error(errors['same-src-and-dest']); + } + + const globalRegexp = new RegExp(options.injectionPointRegexp, 'g'); + + const {count, size, manifestEntries, warnings} = + await getFileManifestEntries(options); + let swFileContents; + try { + swFileContents = await fse.readFile(config.swSrc, 'utf8'); + } catch (error) { + throw new Error(`${errors['invalid-sw-src']} ${error.message}`); + } + + const injectionResults = swFileContents.match(globalRegexp); + assert(injectionResults, errors['injection-point-not-found'] + + // Customize the error message when this happens: + // - If the default RegExp is used, then include the expected string that + // matches as a hint to the developer. + // - If a custom RegExp is used, then just include the raw RegExp. + (options.injectionPointRegexp === defaults.injectionPointRegexp ? + 'workbox.precaching.precacheAndRoute([])' : + options.injectionPointRegexp)); + assert(injectionResults.length === 1, errors['multiple-injection-points'] + + ` ${options.injectionPointRegexp}`); + + const entriesString = JSON.stringify(manifestEntries, null, 2); + swFileContents = swFileContents.replace(globalRegexp, `$1${entriesString}$2`); + + try { + await fse.mkdirp(path.dirname(options.swDest)); + } catch (error) { + throw new Error(errors['unable-to-make-injection-directory'] + + ` '${error.message}'`); + } + + await fse.writeFile(config.swDest, swFileContents); + + return {count, size, warnings}; +} + +module.exports = injectManifest; diff --git a/node_modules/workbox-build/src/entry-points/options/base-schema.js b/node_modules/workbox-build/src/entry-points/options/base-schema.js new file mode 100644 index 00000000..12292bfa --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/base-schema.js @@ -0,0 +1,37 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +const defaults = require('./defaults'); +const regExpObject = require('./reg-exp-object'); + +// Define some common constrains used by all methods. +module.exports = joi.object().keys({ + dontCacheBustUrlsMatching: regExpObject, + globFollow: joi.boolean().default(defaults.globFollow), + globIgnores: joi.array().items(joi.string()).default(defaults.globIgnores), + globPatterns: joi.array().items(joi.string()).default(defaults.globPatterns), + globStrict: joi.boolean().default(defaults.globStrict), + manifestTransforms: joi.array().items(joi.func().arity(1)), + maximumFileSizeToCacheInBytes: joi.number().min(1) + .default(defaults.maximumFileSizeToCacheInBytes), + modifyUrlPrefix: joi.object(), + // templatedUrls is an object where any property name is valid, and the values + // can be either a string or an array of strings. + templatedUrls: joi.object().pattern(/./, + [joi.string(), joi.array().items(joi.string())]), +}); diff --git a/node_modules/workbox-build/src/entry-points/options/common-generate-schema.js b/node_modules/workbox-build/src/entry-points/options/common-generate-schema.js new file mode 100644 index 00000000..69e92843 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/common-generate-schema.js @@ -0,0 +1,77 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +const baseSchema = require('./base-schema'); +const defaults = require('./defaults'); +const regExpObject = require('./reg-exp-object'); + +// Add some constraints that apply to both generateSW and generateSWString. +module.exports = baseSchema.keys({ + cacheId: joi.string(), + clientsClaim: joi.boolean().default(defaults.clientsClaim), + directoryIndex: joi.string(), + ignoreUrlParametersMatching: joi.array().items(regExpObject), + navigateFallback: joi.string().default(defaults.navigateFallback), + navigateFallbackBlacklist: joi.array().items(regExpObject), + navigateFallbackWhitelist: joi.array().items(regExpObject), + offlineGoogleAnalytics: joi.alternatives().try(joi.boolean(), joi.object()) + .default(defaults.offlineGoogleAnalytics), + runtimeCaching: joi.array().items(joi.object().keys({ + method: joi.string().valid( + 'DELETE', + 'GET', + 'HEAD', + 'PATCH', + 'POST', + 'PUT' + ), + urlPattern: [regExpObject, joi.string()], + handler: [joi.func(), joi.string().valid( + 'cacheFirst', + 'cacheOnly', + 'networkFirst', + 'networkOnly', + 'staleWhileRevalidate' + )], + options: joi.object().keys({ + backgroundSync: joi.object().keys({ + name: joi.string().required(), + options: joi.object(), + }), + broadcastUpdate: joi.object().keys({ + channelName: joi.string().required(), + options: joi.object(), + }), + cacheableResponse: joi.object().keys({ + statuses: joi.array().items(joi.number().min(0).max(599)), + headers: joi.object(), + }).or('statuses', 'headers'), + cacheName: joi.string(), + expiration: joi.object().keys({ + maxEntries: joi.number().min(1), + maxAgeSeconds: joi.number().min(1), + purgeOnQuotaError: joi.boolean().default(defaults.purgeOnQuotaError), + }).or('maxEntries', 'maxAgeSeconds'), + networkTimeoutSeconds: joi.number().min(1), + plugins: joi.array().items(joi.object()), + fetchOptions: joi.object(), + matchOptions: joi.object(), + }).with('expiration', 'cacheName'), + }).requiredKeys('urlPattern', 'handler')), + skipWaiting: joi.boolean().default(defaults.skipWaiting), +}); diff --git a/node_modules/workbox-build/src/entry-points/options/defaults.js b/node_modules/workbox-build/src/entry-points/options/defaults.js new file mode 100644 index 00000000..7a8bbdb0 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/defaults.js @@ -0,0 +1,30 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +module.exports = { + clientsClaim: false, + globFollow: true, + globIgnores: ['**/node_modules/**/*'], + globPatterns: ['**/*.{js,css,html}'], + globStrict: true, + importWorkboxFrom: 'cdn', + injectionPointRegexp: /(\.precacheAndRoute\()\s*\[\s*\]\s*(\)|,)/, + maximumFileSizeToCacheInBytes: 2 * 1024 * 1024, + navigateFallback: undefined, + offlineGoogleAnalytics: false, + purgeOnQuotaError: false, + skipWaiting: false, +}; diff --git a/node_modules/workbox-build/src/entry-points/options/generate-sw-schema.js b/node_modules/workbox-build/src/entry-points/options/generate-sw-schema.js new file mode 100644 index 00000000..64dbaf29 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/generate-sw-schema.js @@ -0,0 +1,32 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +const commonGenerateSchema = require('./common-generate-schema'); +const defaults = require('./defaults'); + +// Define some additional constraints. +module.exports = commonGenerateSchema.keys({ + globDirectory: joi.string().required(), + importScripts: joi.array().items(joi.string()), + importWorkboxFrom: joi.string().default(defaults.importWorkboxFrom).valid( + 'cdn', + 'local', + 'disabled' + ), + swDest: joi.string().required(), +}); diff --git a/node_modules/workbox-build/src/entry-points/options/generate-sw-string-schema.js b/node_modules/workbox-build/src/entry-points/options/generate-sw-string-schema.js new file mode 100644 index 00000000..9c1f496c --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/generate-sw-string-schema.js @@ -0,0 +1,27 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +const commonGenerateSchema = require('./common-generate-schema'); + +// Define some additional constraints. +module.exports = commonGenerateSchema.keys({ + globDirectory: joi.string(), + importScripts: joi.array().items(joi.string()).required(), + modulePathPrefix: joi.string(), + workboxSWImport: joi.string(), +}); diff --git a/node_modules/workbox-build/src/entry-points/options/get-manifest-schema.js b/node_modules/workbox-build/src/entry-points/options/get-manifest-schema.js new file mode 100644 index 00000000..31704c8e --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/get-manifest-schema.js @@ -0,0 +1,24 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +const baseSchema = require('./base-schema'); + +// Define some additional constraints. +module.exports = baseSchema.keys({ + globDirectory: joi.string(), +}); diff --git a/node_modules/workbox-build/src/entry-points/options/inject-manifest-schema.js b/node_modules/workbox-build/src/entry-points/options/inject-manifest-schema.js new file mode 100644 index 00000000..6f901824 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/inject-manifest-schema.js @@ -0,0 +1,28 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +const baseSchema = require('./base-schema'); +const defaults = require('./defaults'); +const regExpObject = require('./reg-exp-object'); + +module.exports = baseSchema.keys({ + globDirectory: joi.string().required(), + injectionPointRegexp: regExpObject.default(defaults.injectionPointRegexp), + swSrc: joi.string().required(), + swDest: joi.string().required(), +}); diff --git a/node_modules/workbox-build/src/entry-points/options/reg-exp-object.js b/node_modules/workbox-build/src/entry-points/options/reg-exp-object.js new file mode 100644 index 00000000..d91fd1a1 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/reg-exp-object.js @@ -0,0 +1,20 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const joi = require('joi'); + +module.exports = joi.object().type(RegExp) + .error(() => 'the value must be a RegExp'); diff --git a/node_modules/workbox-build/src/entry-points/options/validate.js b/node_modules/workbox-build/src/entry-points/options/validate.js new file mode 100644 index 00000000..487e5446 --- /dev/null +++ b/node_modules/workbox-build/src/entry-points/options/validate.js @@ -0,0 +1,31 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +module.exports = (options, schema) => { + const {value, error} = schema.validate(options, { + language: { + object: { + allowUnknown: 'is not a supported parameter.', + }, + }, + }); + + if (error) { + throw error; + } + + return value; +}; diff --git a/node_modules/workbox-build/src/index.js b/node_modules/workbox-build/src/index.js new file mode 100644 index 00000000..c9d125f7 --- /dev/null +++ b/node_modules/workbox-build/src/index.js @@ -0,0 +1,88 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const copyWorkboxLibraries = require('./lib/copy-workbox-libraries'); +const generateSW = require('./entry-points/generate-sw'); +const generateSWString = require('./entry-points/generate-sw-string'); +const getManifest = require('./entry-points/get-manifest'); +const injectManifest = require('./entry-points/inject-manifest'); +const {getModuleUrl} = require('./lib/cdn-utils'); + +/** + * This Node module can be used to generate a list of assets that should be + * precached in a service worker, generating a hash that can be used to + * intelligently update a cache when the service worker is updated. + * + * This module will use glob patterns to find assets in a given directory + * and use the resulting URL and revision data for one of the follow uses: + * + * 1. Generate a complete service worker with precaching and some basic + * configurable options, writing the resulting service worker file to disk. See + * [generateSW()]{@link module:workbox-build.generateSW}. + * 1. Generate a complete service worker with precaching and some basic + * configurable options, without writing the results to disk. See + * [generateSWString()]{@link module:workbox-build.generateSWString}. + * 1. Inject a manifest into an existing service worker. This allows you + * to control your own service worker while still taking advantage of + * [workboxSW.precache()]{@link module:workbox-sw.WorkboxSW#precache} logic. + * See [injectManifest()]{@link module:workbox-build.injectManifest}. + * 1. Just generate a manifest, not a full service worker file. + * This is useful if you want to make use of the manifest from your own existing + * service worker file and are okay with including the manifest yourself. + * See [getManifest()]{@link module:workbox-build.getManifest}. + * + * @property {Array<RegExp>} [ignoreUrlParametersMatching=[/^utm_/]] Any + * search parameter names that match against one of the regex's in this array + * will be removed before looking for a precache match. + * + * This is useful if your users might request URLs that contain, for example, + * URL parameters used to track the source of the traffic. Those URL parameters + * would normally cause the cache lookup to fail, since the URL strings used + * as cache keys would not be expected to include them. + * + * You can use `[/./]` to ignore all URL parameters. + * + * Note: This option is only valid when used with + * {@link module:workbox-build#generateSW|generateSW()}. When using + * {@link module:workbox-build.injectManifest|injectManifest()}, you can + * explicitly pass the desired value in to the + * {@link module:workbox-sw.WorkboxSW|WorkboxSW() constructor} in your `swSrc` + * file. + * + * E.g. `[/homescreen/]` + * + * @property {Boolean} [handleFetch=true] Whether or not `workbox-sw` should + * create a `fetch` event handler that responds to network requests. This is + * useful during development if you don't want the service worker serving stale + * content. + * + * Note: This option is only valid when used with + * {@link module:workbox-build#generateSW|generateSW()}. When using + * {@link module:workbox-build.injectManifest|injectManifest()}, you can + * explicitly pass the desired value in to the + * {@link module:workbox-sw.WorkboxSW|WorkboxSW() constructor} in your `swSrc` + * file. + * + * @module workbox-build + */ +module.exports = { + copyWorkboxLibraries, + generateSW, + generateSWString, + getManifest, + getModuleUrl, + injectManifest, +}; diff --git a/node_modules/workbox-build/src/lib/cdn-utils.js b/node_modules/workbox-build/src/lib/cdn-utils.js new file mode 100644 index 00000000..4231341a --- /dev/null +++ b/node_modules/workbox-build/src/lib/cdn-utils.js @@ -0,0 +1,48 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const assert = require('assert'); + +const cdn = require('../cdn-details.json'); +const errors = require('./errors'); + +const getCDNOrigin = () => { + return `${cdn.origin}/${cdn.bucketName}/${cdn.releasesDir}`; +}; + +const getVersionedCDNUrl = () => { + return `${getCDNOrigin()}/${cdn.latestVersion}`; +}; + +const getModuleUrl = (moduleName, buildType) => { + assert(moduleName, errors['no-module-name']); + + if (buildType) { + const pkgJson = require(`${moduleName}/package.json`); + if (buildType === 'dev' && pkgJson.workbox.prodOnly) { + // This is not due to a public-facing exception, so just throw an Error(), + // without creating an entry in errors.js. + throw Error(`The 'dev' build of ${moduleName} is not available.`); + } + return `${getVersionedCDNUrl()}/${moduleName}.${buildType.slice(0, 4)}.js`; + } + return `${getVersionedCDNUrl()}/${moduleName}.js`; +}; + +module.exports = { + getCDNOrigin, + getModuleUrl, +}; diff --git a/node_modules/workbox-build/src/lib/copy-workbox-libraries.js b/node_modules/workbox-build/src/lib/copy-workbox-libraries.js new file mode 100644 index 00000000..4bc8d38b --- /dev/null +++ b/node_modules/workbox-build/src/lib/copy-workbox-libraries.js @@ -0,0 +1,89 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const fse = require('fs-extra'); +const path = require('path'); + +const errors = require('./errors'); +const useBuildType = require('./use-build-type'); + +// Used to filter the libraries to copy based on our package.json dependencies. +const WORKBOX_PREFIX = 'workbox-'; +const BUILD_TYPES = [ + 'dev', + 'prod', +]; + +/** + * This copies over a set of runtime libraries used by Workbox into a + * local directory, which should be deployed alongside your service worker file. + * + * As an alternative to deploying these local copies, you could instead use + * Workbox from its official CDN URL. + * + * This method is exposed for the benefit of developers using + * [injectManifest()]{@link module:workbox-build.injectManifest} who would + * prefer not to use the CDN copies of Workbox. Developers using + * [generateSW()]{@link module:workbox-build.generateSW} don't need to + * explicitly call this method, as it's called automatically when + * `importWorkboxFrom` is set to `local`. + * + * @param {string} destDirectory The path to the parent directory under which + * the new directory of libraries will be created. + * @return {Promise<string>} The name of the newly created directory. + * + * @alias module:workbox-build.copyWorkboxLibraries + */ +module.exports = async (destDirectory) => { + const thisPkg = require('../../package.json'); + // Use the version string from workbox-build in the name of the parent + // directory. This should be safe, because lerna will bump workbox-build's + // pkg.version whenever one of the dependent libraries gets bumped, and we + // care about versioning the dependent libraries. + const workboxDirectoryName = `workbox-v${thisPkg.version}`; + const workboxDirectoryPath = path.join(destDirectory, workboxDirectoryName); + await fse.ensureDir(workboxDirectoryPath); + + const copyPromises = []; + const librariesToCopy = Object.keys(thisPkg.dependencies).filter( + (dependency) => dependency.startsWith(WORKBOX_PREFIX)); + for (const library of librariesToCopy) { + const pkg = require(`${library}/package.json`); + const defaultPathToLibrary = require.resolve(`${library}/${pkg.main}`); + + for (const buildType of BUILD_TYPES) { + // Special-case logic for workbox-sw, which only has a single build type. + // This prevents a race condition with two identical copy promises; + // see https://github.com/GoogleChrome/workbox/issues/1180 + if (library === 'workbox-sw' && buildType === BUILD_TYPES[0]) { + continue; + } + + const srcPath = useBuildType(defaultPathToLibrary, buildType); + const destPath = path.join(workboxDirectoryPath, + path.basename(srcPath)); + copyPromises.push(fse.copy(srcPath, destPath)); + copyPromises.push(fse.copy(`${srcPath}.map`, `${destPath}.map`)); + } + } + + try { + await Promise.all(copyPromises); + return workboxDirectoryName; + } catch (error) { + throw Error(`${errors['unable-to-copy-workbox-libraries']} ${error}`); + } +}; diff --git a/node_modules/workbox-build/src/lib/errors.js b/node_modules/workbox-build/src/lib/errors.js new file mode 100644 index 00000000..603b049d --- /dev/null +++ b/node_modules/workbox-build/src/lib/errors.js @@ -0,0 +1,112 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const ol = require('common-tags').oneLine; + +module.exports = { + 'unable-to-get-rootdir': `Unable to get the root directory of your web app.`, + 'no-extension': ol`Unable to detect a usable extension for a file in your web + app directory.`, + 'invalid-file-manifest-name': ol`The File Manifest Name must have at least one + character.`, + 'unable-to-get-file-manifest-name': 'Unable to get a file manifest name.', + 'invalid-sw-dest': `The 'swDest' value must be a valid path.`, + 'unable-to-get-sw-name': 'Unable to get a service worker file name.', + 'unable-to-get-save-config': ol`An error occurred when asking to save details + in a config file.`, + 'unable-to-get-file-hash': ol`An error occurred when attempting to create a + file hash.`, + 'unable-to-get-file-size': ol`An error occurred when attempting to get a file + size.`, + 'unable-to-glob-files': 'An error occurred when globbing for files.', + 'unable-to-make-manifest-directory': ol`Unable to make output directory for + file manifest.`, + 'read-manifest-template-failure': 'Unable to read template for file manifest', + 'populating-manifest-tmpl-failed': ol`An error occurred when populating the + file manifest template.`, + 'manifest-file-write-failure': 'Unable to write the file manifest.', + 'unable-to-make-sw-directory': ol`Unable to make the directories to output + the service worker path.`, + 'read-sw-template-failure': ol`Unable to read the service worker template + file.`, + 'sw-write-failure': 'Unable to write the service worker file.', + 'sw-write-failure-directory': ol`Unable to write the service worker file; + 'swDest' should be a full path to the file, not a path to a directory.`, + 'unable-to-copy-workbox-libraries': ol`One or more of the Workbox libraries + could not be copied over to the destination directory: `, + 'invalid-generate-sw-input': ol`The input to generateSW() must be an object.`, + 'invalid-glob-directory': ol`The supplied globDirectory must be a path as a + string.`, + 'invalid-dont-cache-bust': ol`The supplied 'dontCacheBustUrlsMatching' + parameter must be a RegExp.`, + 'invalid-exclude-files': 'The excluded files should be an array of strings.', + 'invalid-get-manifest-entries-input': ol`The input to + 'getFileManifestEntries()' must be an object.`, + 'invalid-manifest-path': ol`The supplied manifest path is not a string with + at least one character.`, + 'invalid-manifest-entries': ol`The manifest entries must be an array of + strings or JavaScript objects containing a url parameter.`, + 'invalid-manifest-format': ol`The value of the 'format' option passed to + generateFileManifest() must be either 'iife' (the default) or 'es'.`, + 'invalid-static-file-globs': ol`The 'globPatterns' value must be an array + of strings.`, + 'invalid-templated-urls': ol`The 'templatedUrls' value should be an object + that maps URLs to either a string, or to an array of glob patterns.`, + 'templated-url-matches-glob': ol`One of the 'templatedUrls' URLs is already + being tracked via 'globPatterns': `, + 'invalid-glob-ignores': ol`The 'globIgnores' parameter must be an array of + glob pattern strings.`, + 'manifest-entry-bad-url': ol`The generated manifest contains an entry without + a URL string. This is likely an error with workbox-build.`, + 'modify-url-prefix-bad-prefixes': ol`The 'modifyUrlPrefix' parameter must be + an object with string key value pairs.`, + 'invalid-inject-manifest-arg': ol`The input to 'injectManifest()' must be an + object.`, + 'injection-point-not-found': ol`Unable to find a place to inject the manifest. + Please ensure that your service worker file contains the following: `, + 'multiple-injection-points': ol`Please ensure that your 'swSrc' file contains + only one match for the RegExp:`, + 'populating-sw-tmpl-failed': ol`Unable to generate service worker from + template.`, + 'useless-glob-pattern': ol`One of the glob patterns doesn't match any files. + Please remove or fix the following: `, + 'bad-template-urls-asset': ol`There was an issue using one of the provided + 'templatedUrls'.`, + 'invalid-runtime-caching': ol`The 'runtimeCaching' parameter must an an + array of objects with at least a 'urlPattern' and 'handler'.`, + 'static-file-globs-deprecated': ol`'staticFileGlobs' is deprecated. + Please use 'globPatterns' instead.`, + 'dynamic-url-deprecated': ol`'dynamicUrlToDependencies' is deprecated. + Please use 'templatedUrls' instead.`, + 'urlPattern-is-required': ol`The 'urlPattern' option is required when using + 'runtimeCaching'.`, + 'handler-is-required': ol`The 'handler' option is required when using + runtimeCaching.`, + 'invalid-generate-file-manifest-arg': ol`The input to generateFileManifest() + must be an Object.`, + 'invalid-sw-src': `The 'swSrc' file can't be read.`, + 'same-src-and-dest': ol`'swSrc' and 'swDest' should not be set to the same ` + + `file. Please use a different file path for 'swDest'.`, + 'only-regexp-routes-supported': ol`Please use a regular expression object as + the urlPattern parameter. (Express-style routes are not currently + supported.)`, + 'bad-runtime-caching-config': ol`An unknown configuration option was used + with runtimeCaching:`, + 'invalid-network-timeout-seconds': ol`When using networkTimeoutSeconds, you + must set the handler to 'networkFirst'.`, + 'no-module-name': ol`You must provide a moduleName parameter when calling + getModuleUrl().`, +}; diff --git a/node_modules/workbox-build/src/lib/filter-files.js b/node_modules/workbox-build/src/lib/filter-files.js new file mode 100644 index 00000000..979da046 --- /dev/null +++ b/node_modules/workbox-build/src/lib/filter-files.js @@ -0,0 +1,131 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const maximumSizeTransform = require('./maximum-size-transform'); +const modifyUrlPrefixTranform = require('./modify-url-prefix-transform'); +const noRevisionForUrlsMatchingTransform = + require('./no-revision-for-urls-matching-transform'); + +/** + * A `ManifestTransform` function can be used to modify the modify the `url` or + * `revision` properties of some or all of the + * {@link module:workbox-build#ManifestEntry|ManifestEntries} in the manifest. + * + * Deleting the `revision` property of an entry will cause + * the corresponding `url` to be precached without cache-busting parameters + * applied, which is to say, it implies that the URL itself contains + * proper versioning info. If the `revision` property is present, it must be + * set to a string. + * + * @example <caption>A transformation that prepended the origin of a CDN for any + * URL starting with '/assets/' could be implemented as:</caption> + * + * const cdnTransform = (manifestEntries) => { + * const manifest = manifestEntries.map(entry => { + * const cdnOrigin = 'https://example.com'; + * if (entry.url.startsWith('/assets/')) { + * entry.url = cdnOrigin + entry.url; + * } + * return entry; + * }); + * return {manifest, warnings: []}; + * }; + * + * @example <caption>A transformation that removes the revision field when the + * URL contains an 8-character hash surrounded by '.', indicating that it + * already contains revision information:</caption> + * + * const removeRevisionTransform = (manifestEntries) => { + * const manifest = manifestEntries.map(entry => { + * const hashRegExp = /\.\w{8}\./; + * if (entry.url.match(hashRegExp)) { + * delete entry.revision; + * } + * return entry; + * }); + * return {manifest, warnings: []}; + * }; + * + * @callback ManifestTransform + * @param {Array<module:workbox-build.ManifestEntry>} manifestEntries The full + * array of entries, prior to the current transformation. + * @return {module:workbox-build.ManifestTransformResult} + * The array of entries with the transformation applied, and optionally, any + * warnings that should be reported back to the build tool. + * + * @memberof module:workbox-build + */ + +module.exports = ({ + dontCacheBustUrlsMatching, + fileDetails, + manifestTransforms, + maximumFileSizeToCacheInBytes, + modifyUrlPrefix, +}) => { + let allWarnings = []; + + // Take the array of fileDetail objects and convert it into an array of + // {url, revision, size} objects, with \ replaced with /. + const normalizedManifest = fileDetails.map((fileDetails) => { + return { + url: fileDetails.file.replace(/\\/g, '/'), + revision: fileDetails.hash, + size: fileDetails.size, + }; + }); + + let transformsToApply = []; + + if (maximumFileSizeToCacheInBytes) { + transformsToApply.push(maximumSizeTransform(maximumFileSizeToCacheInBytes)); + } + + if (modifyUrlPrefix) { + transformsToApply.push(modifyUrlPrefixTranform(modifyUrlPrefix)); + } + + if (dontCacheBustUrlsMatching) { + transformsToApply.push( + noRevisionForUrlsMatchingTransform(dontCacheBustUrlsMatching)); + } + + // Any additional manifestTransforms that were passed will be applied last. + transformsToApply = transformsToApply.concat(manifestTransforms || []); + + let transformedManifest = normalizedManifest; + for (const transform of transformsToApply) { + const {manifest, warnings} = transform(transformedManifest); + transformedManifest = manifest; + allWarnings = allWarnings.concat(warnings || []); + } + + // Generate some metadata about the manifest before we clear out the size + // properties from each entry. + const count = transformedManifest.length; + let size = 0; + for (const manifestEntry of transformedManifest) { + size += manifestEntry.size; + delete manifestEntry.size; + } + + return { + count, + size, + manifestEntries: transformedManifest, + warnings: allWarnings, + }; +}; diff --git a/node_modules/workbox-build/src/lib/get-composite-details.js b/node_modules/workbox-build/src/lib/get-composite-details.js new file mode 100644 index 00000000..c59e5128 --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-composite-details.js @@ -0,0 +1,37 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const crypto = require('crypto'); + +module.exports = (compositeUrl, dependencyDetails) => { + let totalSize = 0; + let compositeHash = ''; + + for (let fileDetails of dependencyDetails) { + totalSize += fileDetails.size; + compositeHash += fileDetails.hash; + } + + const md5 = crypto.createHash('md5'); + md5.update(compositeHash); + const hashOfHashes = md5.digest('hex'); + + return { + file: compositeUrl, + hash: hashOfHashes, + size: totalSize, + }; +}; diff --git a/node_modules/workbox-build/src/lib/get-file-details.js b/node_modules/workbox-build/src/lib/get-file-details.js new file mode 100644 index 00000000..afd32628 --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-file-details.js @@ -0,0 +1,66 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const glob = require('glob'); +const path = require('path'); + +const errors = require('./errors'); +const getFileSize = require('./get-file-size'); +const getFileHash = require('./get-file-hash'); + +module.exports = (globOptions) => { + const { + globDirectory, + globFollow, + globIgnores, + globPattern, + globStrict, + } = globOptions; + let globbedFiles; + try { + globbedFiles = glob.sync(globPattern, { + cwd: globDirectory, + follow: globFollow, + ignore: globIgnores, + strict: globStrict, + }); + } catch (err) { + throw new Error(errors['unable-to-glob-files'] + ` '${err.message}'`); + } + + if (globbedFiles.length === 0) { + throw new Error(errors['useless-glob-pattern'] + ' ' + + JSON.stringify({globDirectory, globPattern, globIgnores}, null, 2)); + } + + const fileDetails = globbedFiles.map((file) => { + const fullPath = path.join(globDirectory, file); + const fileSize = getFileSize(fullPath); + if (fileSize === null) { + return null; + } + + const fileHash = getFileHash(fullPath); + return { + file: `${path.relative(globDirectory, fullPath)}`, + hash: fileHash, + size: fileSize, + }; + }); + + // If !== null, means it's a valid file. + return fileDetails.filter((details) => details !== null); +}; diff --git a/node_modules/workbox-build/src/lib/get-file-hash.js b/node_modules/workbox-build/src/lib/get-file-hash.js new file mode 100644 index 00000000..77e6f44b --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-file-hash.js @@ -0,0 +1,29 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const fs = require('fs'); + +const getStringHash = require('./get-string-hash'); +const errors = require('./errors'); + +module.exports = (file) => { + try { + const buffer = fs.readFileSync(file); + return getStringHash(buffer); + } catch (err) { + throw new Error(errors['unable-to-get-file-hash'] + ` '${err.message}'`); + } +}; diff --git a/node_modules/workbox-build/src/lib/get-file-manifest-entries.js b/node_modules/workbox-build/src/lib/get-file-manifest-entries.js new file mode 100644 index 00000000..e1c81d70 --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-file-manifest-entries.js @@ -0,0 +1,118 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const assert = require('assert'); +const path = require('path'); + +const errors = require('./errors'); +const filterFiles = require('./filter-files'); +const getCompositeDetails = require('./get-composite-details'); +const getFileDetails = require('./get-file-details'); +const getStringDetails = require('./get-string-details'); + +module.exports = async ({ + dontCacheBustUrlsMatching, + globDirectory, + globFollow, + globIgnores, + globPatterns, + globStrict, + manifestTransforms, + maximumFileSizeToCacheInBytes, + modifyUrlPrefix, + swDest, + templatedUrls, +}) => { + const warnings = []; + // Initialize to an empty array so that we can still pass something to + // filterFiles() and get a normalized output. + let fileDetails = []; + const fileSet = new Set(); + + if (globDirectory) { + if (swDest) { + // Ensure that we ignore the SW file we're eventually writing to disk. + globIgnores.push(`**/${path.basename(swDest)}`); + } + + try { + fileDetails = globPatterns.reduce((accumulated, globPattern) => { + const globbedFileDetails = getFileDetails({ + globDirectory, + globFollow, + globIgnores, + globPattern, + globStrict, + }); + + globbedFileDetails.forEach((fileDetails) => { + if (fileSet.has(fileDetails.file)) { + return; + } + + fileSet.add(fileDetails.file); + accumulated.push(fileDetails); + }); + return accumulated; + }, []); + } catch (error) { + // If there's an exception thrown while globbing, then report + // it back as a warning, and don't consider it fatal. + warnings.push(error.message); + } + } + + if (templatedUrls) { + for (let url of Object.keys(templatedUrls)) { + assert(!fileSet.has(url), errors['templated-url-matches-glob']); + + const dependencies = templatedUrls[url]; + if (Array.isArray(dependencies)) { + const details = dependencies.reduce((previous, globPattern) => { + try { + const globbedFileDetails = getFileDetails({ + globDirectory, + globFollow, + globIgnores, + globPattern, + globStrict, + }); + return previous.concat(globbedFileDetails); + } catch (error) { + const debugObj = {}; + debugObj[url] = dependencies; + throw new Error(`${errors['bad-template-urls-asset']} ` + + `'${globPattern}' from '${JSON.stringify(debugObj)}':\n` + + error); + } + }, []); + fileDetails.push(getCompositeDetails(url, details)); + } else if (typeof dependencies === 'string') { + fileDetails.push(getStringDetails(url, dependencies)); + } + } + } + + const filteredFiles = filterFiles({fileDetails, + maximumFileSizeToCacheInBytes, modifyUrlPrefix, dontCacheBustUrlsMatching, + manifestTransforms}); + + if (warnings.length > 0) { + filteredFiles.warnings.push(...warnings); + } + + return filteredFiles; +}; diff --git a/node_modules/workbox-build/src/lib/get-file-size.js b/node_modules/workbox-build/src/lib/get-file-size.js new file mode 100644 index 00000000..2b73cb09 --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-file-size.js @@ -0,0 +1,31 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const fs = require('fs'); + +const errors = require('./errors'); + +module.exports = (file) => { + try { + const stat = fs.statSync(file); + if (!stat.isFile()) { + return null; + } + return stat.size; + } catch (err) { + throw new Error(errors['unable-to-get-file-size'] + ` '${err.message}'`); + } +}; diff --git a/node_modules/workbox-build/src/lib/get-string-details.js b/node_modules/workbox-build/src/lib/get-string-details.js new file mode 100644 index 00000000..e778336d --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-string-details.js @@ -0,0 +1,25 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const getStringHash = require('./get-string-hash'); + +module.exports = (url, string) => { + return { + file: url, + hash: getStringHash(string), + size: string.length, + }; +}; diff --git a/node_modules/workbox-build/src/lib/get-string-hash.js b/node_modules/workbox-build/src/lib/get-string-hash.js new file mode 100644 index 00000000..934f5ab9 --- /dev/null +++ b/node_modules/workbox-build/src/lib/get-string-hash.js @@ -0,0 +1,23 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const crypto = require('crypto'); + +module.exports = (string) => { + const md5 = crypto.createHash('md5'); + md5.update(string); + return md5.digest('hex'); +}; diff --git a/node_modules/workbox-build/src/lib/maximum-size-transform.js b/node_modules/workbox-build/src/lib/maximum-size-transform.js new file mode 100644 index 00000000..2924ef22 --- /dev/null +++ b/node_modules/workbox-build/src/lib/maximum-size-transform.js @@ -0,0 +1,35 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const prettyBytes = require('pretty-bytes'); + +module.exports = (maximumFileSizeToCacheInBytes) => { + return (originalManifest) => { + const warnings = []; + const manifest = originalManifest.filter((entry) => { + if (entry.size <= maximumFileSizeToCacheInBytes) { + return true; + } + + warnings.push(`${entry.url} is ${prettyBytes(entry.size)}, and won't ` + + `be precached. Configure maximumFileSizeToCacheInBytes to change ` + + `this limit.`); + return false; + }); + + return {manifest, warnings}; + }; +}; diff --git a/node_modules/workbox-build/src/lib/modify-url-prefix-transform.js b/node_modules/workbox-build/src/lib/modify-url-prefix-transform.js new file mode 100644 index 00000000..bdb83b50 --- /dev/null +++ b/node_modules/workbox-build/src/lib/modify-url-prefix-transform.js @@ -0,0 +1,79 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const errors = require('./errors'); + +/** + * Escaping user input to be treated as a literal string within a regular + * expression can be accomplished by simple replacement. + * + * From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions + * + * @private + * @param {string} string The string to be used as part of a regular + * expression + * @return {string} A string that is safe to use in a regular + * expression. + * + * @private + */ +const escapeRegExp = (string) => { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +}; + +module.exports = (modifyUrlPrefix) => { + if (!modifyUrlPrefix || + typeof modifyUrlPrefix !== 'object' || + Array.isArray(modifyUrlPrefix)) { + throw new Error(errors['modify-url-prefix-bad-prefixes']); + } + + // If there are no entries in modifyUrlPrefix, just return an identity + // function as a shortcut. + if (Object.keys(modifyUrlPrefix).length === 0) { + return (entry) => entry; + } + + Object.keys(modifyUrlPrefix).forEach((key) => { + if (typeof modifyUrlPrefix[key] !== 'string') { + throw new Error(errors['modify-url-prefix-bad-prefixes']); + } + }); + + // Escape the user input so it's safe to use in a regex. + const safeModifyUrlPrefixes = Object.keys(modifyUrlPrefix).map(escapeRegExp); + // Join all the `modifyUrlPrefix` keys so a single regex can be used. + const prefixMatchesStrings = safeModifyUrlPrefixes.join('|'); + // Add `^` to the front the prefix matches so it only matches the start of + // a string. + const modifyRegex = new RegExp(`^(${prefixMatchesStrings})`); + + return (originalManifest) => { + const manifest = originalManifest.map((entry) => { + if (typeof entry.url !== 'string') { + throw new Error(errors['manifest-entry-bad-url']); + } + + entry.url = entry.url.replace(modifyRegex, (match) => { + return modifyUrlPrefix[match]; + }); + + return entry; + }); + + return {manifest}; + }; +}; diff --git a/node_modules/workbox-build/src/lib/no-revision-for-urls-matching-transform.js b/node_modules/workbox-build/src/lib/no-revision-for-urls-matching-transform.js new file mode 100644 index 00000000..e4d17c72 --- /dev/null +++ b/node_modules/workbox-build/src/lib/no-revision-for-urls-matching-transform.js @@ -0,0 +1,39 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const errors = require('./errors'); + +module.exports = (regexp) => { + if (!(regexp instanceof RegExp)) { + throw new Error(errors['invalid-dont-cache-bust']); + } + + return (originalManifest) => { + const manifest = originalManifest.map((entry) => { + if (typeof entry.url !== 'string') { + throw new Error(errors['manifest-entry-bad-url']); + } + + if (entry.url.match(regexp)) { + delete entry.revision; + } + + return entry; + }); + + return {manifest}; + }; +}; diff --git a/node_modules/workbox-build/src/lib/populate-sw-template.js b/node_modules/workbox-build/src/lib/populate-sw-template.js new file mode 100644 index 00000000..ff3baae4 --- /dev/null +++ b/node_modules/workbox-build/src/lib/populate-sw-template.js @@ -0,0 +1,94 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const template = require('lodash.template'); +const swTemplate = require('../templates/sw-template'); + +const errors = require('./errors'); +const runtimeCachingConverter = require('./runtime-caching-converter'); +const stringifyWithoutComments = require('./stringify-without-comments'); + +module.exports = ({ + cacheId, + clientsClaim, + directoryIndex, + ignoreUrlParametersMatching, + importScripts, + manifestEntries, + modulePathPrefix, + navigateFallback, + navigateFallbackBlacklist, + navigateFallbackWhitelist, + offlineGoogleAnalytics, + runtimeCaching, + skipWaiting, + workboxSWImport, +}) => { + // These are all options that can be passed to the precacheAndRoute() method. + const precacheOptions = { + directoryIndex, + // An array of RegExp objects can't be serialized by JSON.stringify()'s + // default behavior, so if it's given, convert it manually. + ignoreUrlParametersMatching: ignoreUrlParametersMatching ? + [] : + undefined, + }; + + let precacheOptionsString = JSON.stringify(precacheOptions, null, 2); + if (ignoreUrlParametersMatching) { + precacheOptionsString = precacheOptionsString.replace( + `"ignoreUrlParametersMatching": []`, + `"ignoreUrlParametersMatching": [` + + `${ignoreUrlParametersMatching.join(', ')}]` + ); + } + + let offlineAnalyticsConfigString; + if (offlineGoogleAnalytics) { + // If offlineGoogleAnalytics is a truthy value, we need to convert it to the + // format expected by the template. + offlineAnalyticsConfigString = offlineGoogleAnalytics === true ? + // If it's the literal value true, then use an empty config string. + '{}' : + // Otherwise, convert the config object into a more complex string, taking + // into account the fact that functions might need to be stringified. + stringifyWithoutComments(offlineGoogleAnalytics); + } + + try { + const populatedTemplate = template(swTemplate)({ + cacheId, + clientsClaim, + importScripts, + manifestEntries, + modulePathPrefix, + navigateFallback, + navigateFallbackBlacklist, + navigateFallbackWhitelist, + offlineAnalyticsConfigString, + precacheOptionsString, + skipWaiting, + runtimeCaching: runtimeCachingConverter(runtimeCaching), + workboxSWImport, + }); + + // Clean up multiple blank lines. + return populatedTemplate.replace(/\n{3,}/g, '\n\n').trim() + '\n'; + } catch (error) { + throw new Error( + `${errors['populating-sw-tmpl-failed']} '${error.message}'`); + } +}; diff --git a/node_modules/workbox-build/src/lib/runtime-caching-converter.js b/node_modules/workbox-build/src/lib/runtime-caching-converter.js new file mode 100644 index 00000000..7082379e --- /dev/null +++ b/node_modules/workbox-build/src/lib/runtime-caching-converter.js @@ -0,0 +1,157 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const ol = require('common-tags').oneLine; + +const errors = require('./errors'); +const stringifyWithoutComments = require('./stringify-without-comments'); + +/** + * Given a set of options that configures `sw-toolbox`'s behavior, convert it + * into a string that would configure equivalent `workbox-sw` behavior. + * + * @param {Object} options See + * https://googlechrome.github.io/sw-toolbox/api.html#options + * @return {string} A JSON string representing the equivalent options. + * + * @private + */ +function getOptionsString(options = {}) { + let plugins = []; + if (options.plugins) { + // Using libs because JSON.stringify won't handle functions. + plugins = options.plugins.map(stringifyWithoutComments); + delete options.plugins; + } + + // Pull handler-specific config from the options object, since they are + // not directly used to construct a Plugin instance. If set, need to be + // passed as options to the handler constructor instead. + const handlerOptionKeys = + ['cacheName', 'networkTimeoutSeconds', 'fetchOptions', 'matchOptions']; + const handlerOptions = {}; + for (const key of handlerOptionKeys) { + if (key in options) { + handlerOptions[key] = options[key]; + delete options[key]; + } + } + + const pluginsMapping = { + backgroundSync: 'workbox.backgroundSync.Plugin', + broadcastUpdate: 'workbox.broadcastUpdate.Plugin', + expiration: 'workbox.expiration.Plugin', + cacheableResponse: 'workbox.cacheableResponse.Plugin', + }; + + for (const [pluginName, pluginConfig] of Object.entries(options)) { + // Ensure that we have some valid configuration to pass to Plugin(). + if (Object.keys(pluginConfig).length === 0) { + continue; + } + + const pluginString = pluginsMapping[pluginName]; + if (!pluginString) { + throw new Error(`${errors['bad-runtime-caching-config']} ${pluginName}`); + } + + let pluginCode; + switch (pluginName) { + // Special case logic for plugins that have a required parameter, and then + // an additional optional config parameter. + case 'backgroundSync': { + const name = pluginConfig.name; + pluginCode = `new ${pluginString}(${JSON.stringify(name)}`; + if ('options' in pluginConfig) { + pluginCode += `, ${JSON.stringify(pluginConfig.options)}`; + } + pluginCode += `)`; + + break; + } + + case 'broadcastUpdate': { + const channelName = pluginConfig.channelName; + pluginCode = `new ${pluginString}(${JSON.stringify(channelName)}`; + if ('options' in pluginConfig) { + pluginCode += `, ${JSON.stringify(pluginConfig.options)}`; + } + pluginCode += `)`; + + break; + } + + // For plugins that just pass in an Object to the constructor, like + // expiration and cacheableResponse + default: { + pluginCode = `new ${pluginString}(${JSON.stringify(pluginConfig)})`; + } + } + + plugins.push(pluginCode); + } + + if (Object.keys(handlerOptions).length > 0 || plugins.length > 0) { + const optionsString = JSON.stringify(handlerOptions).slice(1, -1); + return ol`{ + ${optionsString ? optionsString + ',' : ''} + plugins: [${plugins.join(', ')}] + }`; + } else { + return ''; + } +} + +module.exports = (runtimeCaching = []) => { + return runtimeCaching.map((entry) => { + const method = entry.method || 'GET'; + + if (!entry.urlPattern) { + throw new Error(errors['urlPattern-is-required']); + } + + if (!entry.handler) { + throw new Error(errors['handler-is-required']); + } + + // This validation logic is a bit too gnarly for joi, so it's manually + // implemented here. + if (entry.options && entry.options.networkTimeoutSeconds && + entry.handler !== 'networkFirst') { + throw new Error(errors['invalid-network-timeout-seconds']); + } + + // urlPattern might be either a string or a RegExp object. + // If it's a string, it needs to be quoted. If it's a RegExp, it should + // be used as-is. + const matcher = typeof entry.urlPattern === 'string' ? + JSON.stringify(entry.urlPattern) : + entry.urlPattern; + + if (typeof entry.handler === 'string') { + const optionsString = getOptionsString(entry.options || {}); + + const strategyString = + `workbox.strategies.${entry.handler}(${optionsString})`; + + return `workbox.routing.registerRoute(` + + `${matcher}, ${strategyString}, '${method}');\n`; + } else if (typeof entry.handler === 'function') { + return `workbox.routing.registerRoute(` + + `${matcher}, ${entry.handler}, '${method}');\n`; + } + }).filter((entry) => Boolean(entry)); // Remove undefined map() return values. +}; diff --git a/node_modules/workbox-build/src/lib/stringify-without-comments.js b/node_modules/workbox-build/src/lib/stringify-without-comments.js new file mode 100644 index 00000000..8429ff7d --- /dev/null +++ b/node_modules/workbox-build/src/lib/stringify-without-comments.js @@ -0,0 +1,24 @@ +/* + Copyright 2018 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const objectStringify = require('stringify-object'); +const stripComments = require('strip-comments'); + +module.exports = (obj) => { + return objectStringify(obj, { + transform: (_obj, _prop, str) => stripComments(str), + }); +}; diff --git a/node_modules/workbox-build/src/lib/use-build-type.js b/node_modules/workbox-build/src/lib/use-build-type.js new file mode 100644 index 00000000..ae21b72e --- /dev/null +++ b/node_modules/workbox-build/src/lib/use-build-type.js @@ -0,0 +1,49 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// This is the build type that is expected to be present "by default". +const DEFAULT_BUILD_TYPE = 'prod'; + +/** + * Switches a string from using the "default" build type to an alternative + * build type. In practice, this is used to swap out "prod" for "dev" in the + * filename of a Workbox library. + * + * @param {string} source The path to a file, which will normally contain + * DEFAULT_BUILD_TYPE somewhere in it. + * @param {string} buildType The alternative build type value to swap in. + * @return {string} source, with the last occurrence of DEFAULT_BUILD_TYPE + * replaced with buildType. + * @private + */ +module.exports = (source, buildType) => { + // If we want the DEFAULT_BUILD_TYPE, then just return things as-is. + if (buildType === DEFAULT_BUILD_TYPE) { + return source; + } + // Otherwise, look for the last instance of DEFAULT_BUILD_TYPE, and replace it + // with the new buildType. This is easier via split/join than RegExp. + const parts = source.split(DEFAULT_BUILD_TYPE); + // Join the last two split parts with the new buildType. (If parts only has + // one item, this will be a no-op.) + const replaced = parts.slice(parts.length - 2).join(buildType); + // Take the remaining parts, if any exist, and join them with the replaced + // part using the DEFAULT_BUILD_TYPE, to restore any other matches as-is. + return [ + ...parts.slice(0, parts.length - 2), + replaced, + ].join(DEFAULT_BUILD_TYPE); +}; diff --git a/node_modules/workbox-build/src/lib/write-sw-using-default-template.js b/node_modules/workbox-build/src/lib/write-sw-using-default-template.js new file mode 100644 index 00000000..4a573775 --- /dev/null +++ b/node_modules/workbox-build/src/lib/write-sw-using-default-template.js @@ -0,0 +1,75 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +const fse = require('fs-extra'); +const path = require('path'); + +const errors = require('./errors'); +const populateSWTemplate = require('./populate-sw-template'); + +module.exports = async ({ + cacheId, + clientsClaim, + directoryIndex, + handleFetch, + ignoreUrlParametersMatching, + importScripts, + manifestEntries, + modulePathPrefix, + navigateFallback, + navigateFallbackBlacklist, + navigateFallbackWhitelist, + offlineGoogleAnalytics, + runtimeCaching, + skipWaiting, + swDest, + workboxSWImport, +}) => { + try { + await fse.mkdirp(path.dirname(swDest)); + } catch (error) { + throw new Error(`${errors['unable-to-make-sw-directory']}. ` + + `'${error.message}'`); + } + + const populatedTemplate = populateSWTemplate({ + cacheId, + clientsClaim, + directoryIndex, + handleFetch, + ignoreUrlParametersMatching, + importScripts, + manifestEntries, + modulePathPrefix, + navigateFallback, + navigateFallbackBlacklist, + navigateFallbackWhitelist, + offlineGoogleAnalytics, + runtimeCaching, + skipWaiting, + workboxSWImport, + }); + + try { + await fse.writeFile(swDest, populatedTemplate); + } catch (error) { + if (error.code === 'EISDIR') { + // See https://github.com/GoogleChrome/workbox/issues/612 + throw new Error(errors['sw-write-failure-directory']); + } + throw new Error(`${errors['sw-write-failure']}. '${error.message}'`); + } +}; diff --git a/node_modules/workbox-build/src/templates/sw-template.js b/node_modules/workbox-build/src/templates/sw-template.js new file mode 100644 index 00000000..d34dfc87 --- /dev/null +++ b/node_modules/workbox-build/src/templates/sw-template.js @@ -0,0 +1,67 @@ +/* + Copyright 2017 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +module.exports = `/** + * Welcome to your Workbox-powered service worker! + * + * You'll need to register this file in your web app and you should + * disable HTTP caching for this file too. + * See https://goo.gl/nhQhGp + * + * The rest of the code is auto-generated. Please don't update this file + * directly; instead, make changes to your Workbox build configuration + * and re-run your build process. + * See https://goo.gl/2aRDsh + */ + +<% if (workboxSWImport) { %> +importScripts(<%= JSON.stringify(workboxSWImport) %>); +<% if (modulePathPrefix) { %>workbox.setConfig({modulePathPrefix: <%= JSON.stringify(modulePathPrefix) %>});<% } %> +<% } %> +<% if (importScripts) { %> +importScripts( + <%= importScripts.map(JSON.stringify).join(',\\n ') %> +); +<% } %> + +<% if (cacheId) { %>workbox.core.setCacheNameDetails({prefix: <%= JSON.stringify(cacheId) %>});<% } %> + +<% if (skipWaiting) { %>workbox.skipWaiting();<% } %> +<% if (clientsClaim) { %>workbox.clientsClaim();<% } %> + +<% if (Array.isArray(manifestEntries)) {%> +/** + * The workboxSW.precacheAndRoute() method efficiently caches and responds to + * requests for URLs in the manifest. + * See https://goo.gl/S9QRab + */ +self.__precacheManifest = <%= JSON.stringify(manifestEntries, null, 2) %>.concat(self.__precacheManifest || []); +workbox.precaching.suppressWarnings(); +workbox.precaching.precacheAndRoute(self.__precacheManifest, <%= precacheOptionsString %>); +<% } else { %> +if (Array.isArray(self.__precacheManifest)) { + workbox.precaching.suppressWarnings(); + workbox.precaching.precacheAndRoute(self.__precacheManifest, <%= precacheOptionsString %>); +} +<% } %> +<% if (navigateFallback) { %>workbox.routing.registerNavigationRoute(<%= JSON.stringify(navigateFallback) %><% if (navigateFallbackWhitelist || navigateFallbackBlacklist) { %>, { + <% if (navigateFallbackWhitelist) { %>whitelist: [<%= navigateFallbackWhitelist %>],<% } %> + <% if (navigateFallbackBlacklist) { %>blacklist: [<%= navigateFallbackBlacklist %>],<% } %> +}<% } %>);<% } %> + +<% if (runtimeCaching) { runtimeCaching.forEach(runtimeCachingString => {%><%= runtimeCachingString %><% });} %> + +<% if (offlineAnalyticsConfigString) { %>workbox.googleAnalytics.initialize(<%= offlineAnalyticsConfigString %>);<% } %>`; |
