mirror of
https://github.com/hanzoai/workbox.git
synced 2026-09-24 17:04:35 +00:00
Migrate workbox-build to TypeScript (#2867)
* WIP * Finished getManifest * GenerateSW migrated * Getting there * WIP * Runtime caching TS * More WIP * More WIP * Validation, type fixes * Builds! * No default exports * null support in optional strings * Accept string or buffer again * Fix JSDocs * CanIUse update * test/additional-manifest-entries-transform * lib/bundle * cdnUtils test * Switched to esModuleInterop * Still WIP * get-file-size migration * get-string-details test migration * A few more * populateSWTemplate changes * A few more * validate options * Update ts-auto-guard * Fix dependency-check * Swapped the exports * JSON Schema + ajv * TS 4.1.5 * Getting closer to validation * Some default logic * Switched default quotes * Cleanup optional types * Figuring out errors * Refactor * Update validate-options test * Started integration test migration * Remove joi schema * Fixed some swDest logic * Closer to webpack tests working * Fix transformManifest usage * Use a copy of the exclude array * More include/exclude fun * swDest default fix * Function support? * modifyURLPrefix workaround * Fix an import * Improve error messages * Fix test string * New validation unit test * getManifest working * Working through generateSW * Function massaging * Cleanup of exclude/include * Fix a few more gSW tests * RouteMatchCallback function * Expiration w/cacheName check * Optional globDirectory * InjectManifest tests * Test cleanup * Fix a test * Fix a config modification * v5 injectmanifest test * esModuleInterop support * Fixes for proxied build * Final tweaks * Linting * Automated linting fixes * Tweak linting rules * Update packages/workbox-build/src/lib/get-file-details.ts Co-authored-by: Adriana Jara <[email protected]> * Update test/workbox-build/node/generate-sw.js Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/additional-manifest-entries-transform.ts Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/additional-manifest-entries-transform.ts Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/cdn-utils.ts Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/get-file-manifest-entries.ts Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/stringify-without-comments.ts Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/validate-options.ts Co-authored-by: Adriana Jara <[email protected]> * Update packages/workbox-build/src/lib/additional-manifest-entries-transform.ts Co-authored-by: Adriana Jara <[email protected]> Co-authored-by: Adriana Jara <[email protected]>
This commit is contained in:
committed by
GitHub
co-authored by
Adriana Jara
parent
259418c754
commit
cb618332d2
+1
-1
@@ -21,7 +21,7 @@ firebase-debug.log
|
||||
# Generated TypeScript files and build data
|
||||
tsconfig.tsbuildinfo
|
||||
packages/workbox-*/**/*.d.ts
|
||||
!packages/workbox-cli/src/index.d.ts
|
||||
!packages/workbox-*/src/**/*.d.ts
|
||||
packages/workbox-*/**/*.js
|
||||
!packages/workbox-build/**/*.js
|
||||
!packages/workbox-webpack-plugin/**/*.js
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
const {parallel} = require('gulp');
|
||||
const execa = require('execa');
|
||||
const fse = require('fs-extra');
|
||||
const TJS = require('typescript-json-schema');
|
||||
const upath = require('upath');
|
||||
|
||||
const constants = require('./utils/constants');
|
||||
@@ -28,7 +30,59 @@ async function buildNodePackage(packagePath) {
|
||||
], {preferLocal: true});
|
||||
}
|
||||
|
||||
async function generateWorkboxBuildJSONSchema(packagePath) {
|
||||
const program = TJS.programFromConfig(upath.join(packagePath,
|
||||
'tsconfig.json'));
|
||||
const generator = TJS.buildGenerator(program, {
|
||||
noExtraProps: true,
|
||||
required: true,
|
||||
});
|
||||
const optionTypes = [
|
||||
'GenerateSWOptions',
|
||||
'GetManifestOptions',
|
||||
'InjectManifestOptions',
|
||||
'WebpackGenerateSWOptions',
|
||||
'WebpackInjectManifestOptions',
|
||||
];
|
||||
for (const optionType of optionTypes) {
|
||||
const schema = generator.getSchemaForSymbol(optionType);
|
||||
// Ideally, we'd set typeOfKeyword so that functions could be represented.
|
||||
// Instead, we need to hardcode a few overrides to deal with functions.
|
||||
// See https://github.com/YousefED/typescript-json-schema/issues/424
|
||||
if (schema.properties.manifestTransforms) {
|
||||
schema.properties.manifestTransforms.items = {typeof: 'function'};
|
||||
}
|
||||
if (schema.properties.exclude) {
|
||||
schema.properties.exclude.items.anyOf = [
|
||||
{'$ref': '#/definitions/RegExp'},
|
||||
{type: 'string'},
|
||||
{typeof: 'function'},
|
||||
];
|
||||
}
|
||||
if (schema.properties.include) {
|
||||
schema.properties.include.items.anyOf = [
|
||||
{'$ref': '#/definitions/RegExp'},
|
||||
{type: 'string'},
|
||||
{typeof: 'function'},
|
||||
];
|
||||
}
|
||||
if (schema.definitions.RouteMatchCallback) {
|
||||
delete schema.definitions.RouteMatchCallback.type;
|
||||
delete schema.definitions.RouteMatchCallback.additionalProperties;
|
||||
schema.definitions.RouteMatchCallback.typeof = 'function';
|
||||
}
|
||||
await fse.writeJSON(upath.join(packagePath, 'src', 'schema',
|
||||
`${optionType}.json`), schema);
|
||||
}
|
||||
}
|
||||
|
||||
async function buildNodeTSPackage(packagePath) {
|
||||
// Hardcode special logic for workbox-build, as it's the only package
|
||||
// that requires JSON schema generation.
|
||||
if (packagePath.endsWith('workbox-build')) {
|
||||
await generateWorkboxBuildJSONSchema(packagePath);
|
||||
}
|
||||
|
||||
await execa('tsc', ['-b', packagePath], {preferLocal: true});
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,11 @@ async function cleanPackage(packagePath) {
|
||||
if (await fse.pathExists(upath.join(packagePath, 'src', 'index.ts'))) {
|
||||
// Store the list of deleted files, so we can delete directories after.
|
||||
const deletedPaths = await del([
|
||||
upath.join(packagePath, '**/*.+(js|mjs|d.ts)'),
|
||||
`${packagePath}/**/*.+(js|mjs|d.ts)`,
|
||||
// Don't delete files in node_modules.
|
||||
'!**/node_modules', '!**/node_modules/**/*',
|
||||
'!**/node_modules/**/*',
|
||||
// Don't delete anything under src.
|
||||
`!${packagePath}/src/**/*`,
|
||||
]);
|
||||
|
||||
// Any directories in `deletedPaths` that are top-level directories to the
|
||||
@@ -57,12 +59,12 @@ module.exports = {
|
||||
build_packages_clean: cleanSequence(),
|
||||
build_packages: series(
|
||||
cleanSequence(),
|
||||
// This needs to be a series, not in parallel, so that there isn't a
|
||||
// race condition with the terser nameCache.
|
||||
series(build_sw_packages, build_window_packages),
|
||||
parallel(
|
||||
build_node_packages,
|
||||
build_node_ts_packages,
|
||||
// This needs to be a series, not in parallel, so that there isn't a
|
||||
// race condition with the terser nameCache.
|
||||
series(build_sw_packages, build_window_packages),
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const {getCDNOrigin} = require(
|
||||
'../../packages/workbox-build/src/lib/cdn-utils');
|
||||
const cdn = require('../../packages/workbox-build/src/cdn-details.json');
|
||||
const lernaPkg = require('../../lerna.json');
|
||||
|
||||
module.exports = () => `${getCDNOrigin()}/${lernaPkg.version}`;
|
||||
module.exports = () => `${cdn.origin}/${cdn.bucketName}/${cdn.releasesDir}` +
|
||||
`/${lernaPkg.version}`;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
function joinMessages(errorsOrWarnings) {
|
||||
if ('message' in errorsOrWarnings[0]) {
|
||||
if (errorsOrWarnings[0].message) {
|
||||
return errorsOrWarnings.map((item) => item.message).join('\n');
|
||||
} else {
|
||||
return errorsOrWarnings.join('\n');
|
||||
|
||||
Generated
+277
-9
@@ -1130,6 +1130,14 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
@@ -4176,6 +4184,59 @@
|
||||
"integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/babel__core": {
|
||||
"version": "7.1.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
|
||||
"integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.1.0",
|
||||
"@babel/types": "^7.0.0",
|
||||
"@types/babel__generator": "*",
|
||||
"@types/babel__template": "*",
|
||||
"@types/babel__traverse": "*"
|
||||
}
|
||||
},
|
||||
"@types/babel__generator": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
|
||||
"integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@types/babel__preset-env": {
|
||||
"version": "7.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__preset-env/-/babel__preset-env-7.9.1.tgz",
|
||||
"integrity": "sha512-kkCHo5fk24m3gcH7oVhRLdw6xGF2tog5rc8/CbXIyTSYSO0NhStjEYCaEmRjs5VB5Jy5Wbj+0QvuGdxuGdvAfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/babel__template": {
|
||||
"version": "7.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
|
||||
"integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.1.0",
|
||||
"@babel/types": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@types/babel__traverse": {
|
||||
"version": "7.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz",
|
||||
"integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@types/common-tags": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.0.tgz",
|
||||
"integrity": "sha512-htRqZr5qn8EzMelhX/Xmx142z218lLyGaeZ3YR8jlze4TATRU9huKKvuBmAJEW4LCC4pnY1N6JAm6p85fMHjhg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "7.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.7.tgz",
|
||||
@@ -4208,6 +4269,15 @@
|
||||
"integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "9.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.11.tgz",
|
||||
"integrity": "sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/glob": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
|
||||
@@ -4230,6 +4300,12 @@
|
||||
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.168",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
|
||||
"integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
@@ -4275,6 +4351,12 @@
|
||||
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/stringify-object": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/stringify-object/-/stringify-object-3.3.0.tgz",
|
||||
"integrity": "sha512-ryxTolaNg1l809rknW9q9T7wG8QHcjtZX6syJx7kpOLY2qev75VzC9HMVimUxlA1YzjpGsDI29yLjHBotqhUhA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/tapable": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz",
|
||||
@@ -4867,6 +4949,12 @@
|
||||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
@@ -5798,9 +5886,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001148",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001148.tgz",
|
||||
"integrity": "sha512-E66qcd0KMKZHNJQt9hiLZGE3J4zuTqE1OnU53miEVtylFbwOEmeA5OsRu90noZful+XGSQOni1aT2tiqu/9yYw==",
|
||||
"version": "1.0.30001236",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001236.tgz",
|
||||
"integrity": "sha512-o0PRQSrSCGJKCPZcgMzl5fUaj5xHe8qA2m4QRvnyY4e1lITqoNkr7q/Oh1NcpGSy0Th97UZ35yoKcINPoq7YOQ==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
@@ -5832,6 +5920,15 @@
|
||||
"type-detect": "^4.0.5"
|
||||
}
|
||||
},
|
||||
"chai-as-promised": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz",
|
||||
"integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"check-error": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"chai-match-pattern": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chai-match-pattern/-/chai-match-pattern-1.2.0.tgz",
|
||||
@@ -7070,6 +7167,12 @@
|
||||
"sha.js": "^2.4.8"
|
||||
}
|
||||
},
|
||||
"create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
@@ -8188,6 +8291,14 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ignore": {
|
||||
@@ -10554,6 +10665,14 @@
|
||||
"requires": {
|
||||
"is-stream": "^2.0.0",
|
||||
"type-fest": "^0.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"he": {
|
||||
@@ -11949,6 +12068,15 @@
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stable-stringify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
|
||||
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsonify": "~0.0.0"
|
||||
}
|
||||
},
|
||||
"json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
|
||||
@@ -11980,6 +12108,12 @@
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"jsonify": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
||||
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
|
||||
"dev": true
|
||||
},
|
||||
"jsonparse": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
|
||||
@@ -12411,6 +12545,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"make-fetch-happen": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz",
|
||||
@@ -17414,6 +17554,20 @@
|
||||
"integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=",
|
||||
"dev": true
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
|
||||
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.17",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
@@ -17472,9 +17626,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||
"dev": true
|
||||
},
|
||||
"type-is": {
|
||||
@@ -17503,11 +17657,119 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.9.7",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
|
||||
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz",
|
||||
"integrity": "sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript-json-schema": {
|
||||
"version": "0.50.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.50.1.tgz",
|
||||
"integrity": "sha512-GCof/SDoiTDl0qzPonNEV4CHyCsZEIIf+mZtlrjoD8vURCcEzEfa2deRuxYid8Znp/e27eDR7Cjg8jgGrimBCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.7",
|
||||
"@types/node": "^14.14.33",
|
||||
"glob": "^7.1.6",
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "~4.2.3",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
|
||||
"integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz",
|
||||
"integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
|
||||
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.7",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
|
||||
"integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"uc.micro": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||
@@ -19020,6 +19282,12 @@
|
||||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
||||
+10
-1
@@ -53,7 +53,13 @@
|
||||
"@rollup/plugin-multi-entry": "^4.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-replace": "^2.4.1",
|
||||
"@types/babel__core": "^7.1.12",
|
||||
"@types/babel__preset-env": "^7.9.1",
|
||||
"@types/common-tags": "^1.8.0",
|
||||
"@types/estree": "0.0.45",
|
||||
"@types/fs-extra": "^9.0.5",
|
||||
"@types/lodash": "^4.14.165",
|
||||
"@types/stringify-object": "^3.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.30.0",
|
||||
"@typescript-eslint/parser": "^2.30.0",
|
||||
"acorn": "^8.0.1",
|
||||
@@ -63,6 +69,7 @@
|
||||
"bytes": "^3.1.0",
|
||||
"camelcase": "^6.0.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chai-match-pattern": "^1.2.0",
|
||||
"chalk": "^4.1.0",
|
||||
"clear-module": "^4.1.1",
|
||||
@@ -107,7 +114,9 @@
|
||||
"service-worker-mock": "^1.9.3",
|
||||
"sinon": "^9.0.3",
|
||||
"tempy": "^0.6.0",
|
||||
"typescript": "^3.9.7",
|
||||
"type-fest": "^0.20.2",
|
||||
"typescript": "^4.1.5",
|
||||
"typescript-json-schema": "^0.50.1",
|
||||
"upath": "^1.2.0",
|
||||
"webpack-v4": "npm:webpack@^4.44.2",
|
||||
"webpack-v5": "npm:webpack@^5.9.0",
|
||||
|
||||
Generated
+187
@@ -4,6 +4,16 @@
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@apideck/better-ajv-errors": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.2.4.tgz",
|
||||
"integrity": "sha512-scZfMrs2MhqtaHgBhVif2YsrFmSUZ9BxryilZWLnafQYCLCx6l/lu+BIPlCJZ+s9JucUn7YdtnsVPb27oXKRjQ==",
|
||||
"requires": {
|
||||
"json-schema": "^0.3.0",
|
||||
"jsonpointer": "^4.1.0",
|
||||
"leven": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"@babel/code-frame": {
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
|
||||
@@ -1055,6 +1065,25 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "8.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz",
|
||||
"integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"json-schema-traverse": "^1.0.0",
|
||||
"require-from-string": "^2.0.2",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"ajv-keywords": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.0.0.tgz",
|
||||
"integrity": "sha512-ULd1QMjRoH6JDNUQIfDLrlE+OgZlFaxyYCjzt58uNuUQtKXt8/U+vK/8Ql0gyn/C5mqZzUWtKMqr/4YquvTrWA==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
@@ -1234,6 +1263,11 @@
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
@@ -1402,6 +1436,16 @@
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.3.0.tgz",
|
||||
"integrity": "sha512-TYfxx36xfl52Rf1LU9HyWSLGPdYLL+SQ8/E/0yVyKG8wCCDaSrhPap0vEdlsZWRaS6tnKKLPGiEJGiREVC8kxQ=="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
|
||||
@@ -1419,6 +1463,11 @@
|
||||
"universalify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"jsonpointer": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz",
|
||||
"integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg=="
|
||||
},
|
||||
"leven": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
||||
@@ -1602,6 +1651,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"require-from-string": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
|
||||
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
|
||||
@@ -1797,6 +1851,14 @@
|
||||
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
|
||||
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||
@@ -1812,6 +1874,131 @@
|
||||
"webidl-conversions": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"workbox-background-sync": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.1.5.tgz",
|
||||
"integrity": "sha512-VbUmPLsdz+sLzuNxHvMylzyRTiM4q+q7rwLBk3p2mtRL5NZozI8j/KgoGbno96vs84jx4b9zCZMEOIKEUTPf6w==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-broadcast-update": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.1.5.tgz",
|
||||
"integrity": "sha512-zGrTTs+n4wHpYtqYMqBg6kl/x5j1UrczGCQnODSHTxIDV8GXLb/GtA1BCZdysNxpMmdVSeLmTcgIYAAqWFamrA==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-cacheable-response": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.1.5.tgz",
|
||||
"integrity": "sha512-x8DC71lO/JCgiaJ194l9le8wc8lFPLgUpDkLhp2si7mXV6S/wZO+8Osvw1LLgYa8YYTWGbhbFhFTXIkEMknIIA==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-core": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.1.5.tgz",
|
||||
"integrity": "sha512-9SOEle7YcJzg3njC0xMSmrPIiFjfsFm9WjwGd5enXmI8Lwk8wLdy63B0nzu5LXoibEmS9k+aWF8EzaKtOWjNSA=="
|
||||
},
|
||||
"workbox-expiration": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.1.5.tgz",
|
||||
"integrity": "sha512-6cN+FVbh8fNq56LFKPMchGNKCJeyboHsDuGBqmhDUPvD4uDjsegQpDQzn52VaE0cpywbSIsDF/BSq9E9Yjh5oQ==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-google-analytics": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.1.5.tgz",
|
||||
"integrity": "sha512-LYsJ/VxTkYVLxM1uJKXZLz4cJdemidY7kPyAYtKVZ6EiDG89noASqis75/5lhqM1m3HwQfp2DtoPrelKSpSDBA==",
|
||||
"requires": {
|
||||
"workbox-background-sync": "^6.1.5",
|
||||
"workbox-core": "^6.1.5",
|
||||
"workbox-routing": "^6.1.5",
|
||||
"workbox-strategies": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-navigation-preload": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.1.5.tgz",
|
||||
"integrity": "sha512-hDbNcWlffv0uvS21jCAC/mYk7NzaGRSWOQXv1p7bj2aONAX5l699D2ZK4D27G8TO0BaLHUmW/1A5CZcsvweQdg==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-precaching": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.1.5.tgz",
|
||||
"integrity": "sha512-yhm1kb6wgi141JeM5X7z42XJxCry53tbMLB3NgrxktrZbwbrJF8JILzYy+RFKC9tHC6u2bPmL789GPLT2NCDzw==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5",
|
||||
"workbox-routing": "^6.1.5",
|
||||
"workbox-strategies": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-range-requests": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.1.5.tgz",
|
||||
"integrity": "sha512-iACChSapzB0yuIum3ascP/+cfBNuZi5DRrE+u4u5mCHigPlwfSWtlaY+y8p+a8EwcDTVTZVtnrGrRnF31SiLqQ==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-recipes": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.1.5.tgz",
|
||||
"integrity": "sha512-MD1yabHca6O/oj1hrRdfj9cRwhKA5zqIE53rWOAg/dKMMzWQsf9nyRbXRgzK3a13iQvYKuQzURU4Cx58tdnR+Q==",
|
||||
"requires": {
|
||||
"workbox-cacheable-response": "^6.1.5",
|
||||
"workbox-core": "^6.1.5",
|
||||
"workbox-expiration": "^6.1.5",
|
||||
"workbox-precaching": "^6.1.5",
|
||||
"workbox-routing": "^6.1.5",
|
||||
"workbox-strategies": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-routing": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.1.5.tgz",
|
||||
"integrity": "sha512-uC/Ctz+4GXGL42h1WxUNKxqKRik/38uS0NZ6VY/EHqL2F1ObLFqMHUZ4ZYvyQsKdyI82cxusvhJZHOrY0a2fIQ==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-strategies": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.1.5.tgz",
|
||||
"integrity": "sha512-QhiOn9KT9YGBdbfWOmJT6pXZOIAxaVrs6J6AMYzRpkUegBTEcv36+ZhE/cfHoT0u2fxVtthHnskOQ/snEzaXQw==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-streams": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.1.5.tgz",
|
||||
"integrity": "sha512-OI1kLvRHGFXV+soDvs6aEwfBwdAkvPB0mRryqdh3/K17qUj/1gRXc8QtpgU+83xqx/I/ar2bTCIj0KPzI/ChCQ==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5",
|
||||
"workbox-routing": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"workbox-sw": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.1.5.tgz",
|
||||
"integrity": "sha512-IMDiqxYbKzPorZLGMUMacLB6r76iVQbdTzYthIZoPfy+uFURJFUtqiWQJKg1L+RMyuYXwKXTahCIGkgFs4jBeg=="
|
||||
},
|
||||
"workbox-window": {
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.1.5.tgz",
|
||||
"integrity": "sha512-akL0X6mAegai2yypnq78RgfazeqvKbsllRtEI4dnbhPcRINEY1NmecFmsQk8SD+zWLK1gw5OdwAOX+zHSRVmeA==",
|
||||
"requires": {
|
||||
"workbox-core": "^6.1.5"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
|
||||
@@ -20,14 +20,16 @@
|
||||
"bugs": "https://github.com/GoogleChrome/workbox/issues",
|
||||
"homepage": "https://github.com/GoogleChrome/workbox",
|
||||
"dependencies": {
|
||||
"@apideck/better-ajv-errors": "^0.2.4",
|
||||
"@babel/core": "^7.11.1",
|
||||
"@babel/preset-env": "^7.11.0",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@hapi/joi": "^16.1.8",
|
||||
"@rollup/plugin-babel": "^5.2.0",
|
||||
"@rollup/plugin-node-resolve": "^11.2.1",
|
||||
"@rollup/plugin-replace": "^2.4.1",
|
||||
"@surma/rollup-plugin-off-main-thread": "^1.4.1",
|
||||
"ajv": "^8.6.0",
|
||||
"ajv-keywords": "^5.0.0",
|
||||
"common-tags": "^1.8.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
@@ -60,6 +62,6 @@
|
||||
},
|
||||
"main": "build/index.js",
|
||||
"workbox": {
|
||||
"packageType": "node"
|
||||
"packageType": "node_ts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +89,13 @@ import './_version.mjs';
|
||||
* property to use when creating the
|
||||
* [`ExpirationPlugin`]{@link module:workbox-expiration.ExpirationPlugin}.
|
||||
*
|
||||
* @property {number} [options.expiration.maxEntries] The `maxAgeSeconds`
|
||||
* @property {number} [options.expiration.maxEntries] The `maxEntries`
|
||||
* property to use when creating the
|
||||
* [`ExpirationPlugin`]{@link module:workbox-expiration.ExpirationPlugin}.
|
||||
*
|
||||
* @property {Object} [options.precacheFallback]
|
||||
*
|
||||
* @property {number} [options.precacheFallback.fallbackURL] The `fallbackURL`
|
||||
* @property {string} [options.precacheFallback.fallbackURL] The `fallbackURL`
|
||||
* property to use when creating the
|
||||
* [`PrecacheFallbackPlugin`]{@link module:workbox-precaching.PrecacheFallbackPlugin}.
|
||||
*
|
||||
|
||||
+30
-19
@@ -6,14 +6,13 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const upath = require('upath');
|
||||
import upath from 'upath';
|
||||
|
||||
const generateSWSchema = require('./options/schema/generate-sw');
|
||||
const getFileManifestEntries = require('./lib/get-file-manifest-entries');
|
||||
const rebasePath = require('./lib/rebase-path');
|
||||
const validate = require('./lib/validate-options');
|
||||
const writeServiceWorkerUsingDefaultTemplate =
|
||||
require('./lib/write-sw-using-default-template');
|
||||
import {BuildResult, GetManifestOptions} from './types';
|
||||
import {getFileManifestEntries} from './lib/get-file-manifest-entries';
|
||||
import {rebasePath} from './lib/rebase-path';
|
||||
import {validateGenerateSWOptions} from './lib/validate-options';
|
||||
import {writeSWUsingDefaultTemplate} from './lib/write-sw-using-default-template';
|
||||
|
||||
// eslint-disable-next-line jsdoc/newline-after-description
|
||||
/**
|
||||
@@ -194,12 +193,13 @@ const writeServiceWorkerUsingDefaultTemplate =
|
||||
*
|
||||
* @memberof module:workbox-build
|
||||
*/
|
||||
async function generateSW(config) {
|
||||
const options = validate(config, generateSWSchema);
|
||||
export async function generateSW(config: unknown): Promise<BuildResult> {
|
||||
const options = validateGenerateSWOptions(config);
|
||||
let entriesResult;
|
||||
|
||||
if (options.globDirectory) {
|
||||
// Make sure we leave swDest out of the precache manifest.
|
||||
options.globIgnores.push(rebasePath({
|
||||
options.globIgnores!.push(rebasePath({
|
||||
baseDirectory: options.globDirectory,
|
||||
file: options.swDest,
|
||||
}));
|
||||
@@ -209,21 +209,32 @@ async function generateSW(config) {
|
||||
if (!options.inlineWorkboxRuntime) {
|
||||
const swDestDir = upath.dirname(options.swDest);
|
||||
const workboxRuntimeFile = upath.join(swDestDir, 'workbox-*.js');
|
||||
options.globIgnores.push(rebasePath({
|
||||
options.globIgnores!.push(rebasePath({
|
||||
baseDirectory: options.globDirectory,
|
||||
file: workboxRuntimeFile,
|
||||
}));
|
||||
}
|
||||
|
||||
// We've previously asserted that options.globDirectory is set, so this
|
||||
// should be a safe cast.
|
||||
entriesResult = await getFileManifestEntries(options as GetManifestOptions);
|
||||
} else {
|
||||
entriesResult = {
|
||||
count: 0,
|
||||
manifestEntries: [],
|
||||
size: 0,
|
||||
warnings: [],
|
||||
};
|
||||
}
|
||||
|
||||
const {count, size, manifestEntries, warnings} =
|
||||
await getFileManifestEntries(options);
|
||||
|
||||
const filePaths = await writeServiceWorkerUsingDefaultTemplate(Object.assign({
|
||||
manifestEntries,
|
||||
const filePaths = await writeSWUsingDefaultTemplate(Object.assign({
|
||||
manifestEntries: entriesResult.manifestEntries,
|
||||
}, options));
|
||||
|
||||
return {count, filePaths, size, warnings};
|
||||
return {
|
||||
filePaths,
|
||||
count: entriesResult.count,
|
||||
size: entriesResult.size,
|
||||
warnings: entriesResult.warnings,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = generateSW;
|
||||
+6
-11
@@ -6,9 +6,9 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const getFileManifestEntries = require('./lib/get-file-manifest-entries');
|
||||
const getManifestSchema = require('./options/schema/get-manifest');
|
||||
const validate = require('./lib/validate-options');
|
||||
import {getFileManifestEntries} from './lib/get-file-manifest-entries';
|
||||
import {GetManifestResult} from './types';
|
||||
import {validateGetManifestOptions} from './lib/validate-options';
|
||||
|
||||
// eslint-disable-next-line jsdoc/newline-after-description
|
||||
/**
|
||||
@@ -88,13 +88,8 @@ const validate = require('./lib/validate-options');
|
||||
*
|
||||
* @memberof module:workbox-build
|
||||
*/
|
||||
async function getManifest(config) {
|
||||
const options = validate(config, getManifestSchema);
|
||||
export async function getManifest(config: unknown): Promise<GetManifestResult> {
|
||||
const options = validateGetManifestOptions(config);
|
||||
|
||||
const {manifestEntries, count, size, warnings} =
|
||||
await getFileManifestEntries(options);
|
||||
|
||||
return {manifestEntries, count, size, warnings};
|
||||
return await getFileManifestEntries(options);
|
||||
}
|
||||
|
||||
module.exports = getManifest;
|
||||
@@ -6,19 +6,22 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const {getModuleURL} = require('./lib/cdn-utils');
|
||||
const copyWorkboxLibraries = require('./lib/copy-workbox-libraries');
|
||||
const generateSW = require('./generate-sw');
|
||||
const getManifest = require('./get-manifest');
|
||||
const injectManifest = require('./inject-manifest');
|
||||
import {copyWorkboxLibraries} from './lib/copy-workbox-libraries';
|
||||
import {getModuleURL} from './lib/cdn-utils';
|
||||
import {generateSW} from './generate-sw';
|
||||
import {getManifest} from './get-manifest';
|
||||
import {injectManifest} from './inject-manifest';
|
||||
|
||||
|
||||
/**
|
||||
* @module workbox-build
|
||||
*/
|
||||
module.exports = {
|
||||
export default {
|
||||
copyWorkboxLibraries,
|
||||
generateSW,
|
||||
getManifest,
|
||||
getModuleURL,
|
||||
injectManifest,
|
||||
};
|
||||
|
||||
export * from './types';
|
||||
+24
-26
@@ -6,20 +6,20 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const fse = require('fs-extra');
|
||||
const sourceMapURL = require('source-map-url');
|
||||
const stringify = require('fast-json-stable-stringify');
|
||||
const upath = require('upath');
|
||||
import {RawSourceMap} from 'source-map';
|
||||
import assert from 'assert';
|
||||
import fse from 'fs-extra';
|
||||
import sourceMapURL from 'source-map-url';
|
||||
import stringify from 'fast-json-stable-stringify';
|
||||
import upath from 'upath';
|
||||
|
||||
const errors = require('./lib/errors');
|
||||
const escapeRegexp = require('./lib/escape-regexp');
|
||||
const getFileManifestEntries = require('./lib/get-file-manifest-entries');
|
||||
const injectManifestSchema = require('./options/schema/inject-manifest');
|
||||
const rebasePath = require('./lib/rebase-path');
|
||||
const replaceAndUpdateSourceMap =
|
||||
require('./lib/replace-and-update-source-map');
|
||||
const validate = require('./lib/validate-options');
|
||||
import {BuildResult} from './types';
|
||||
import {errors} from './lib/errors';
|
||||
import {escapeRegExp} from './lib/escape-regexp';
|
||||
import {getFileManifestEntries} from './lib/get-file-manifest-entries';
|
||||
import {rebasePath} from './lib/rebase-path';
|
||||
import {replaceAndUpdateSourceMap} from './lib/replace-and-update-source-map';
|
||||
import {validateInjectManifestOptions} from './lib/validate-options';
|
||||
|
||||
// eslint-disable-next-line jsdoc/newline-after-description
|
||||
/**
|
||||
@@ -116,22 +116,22 @@ const validate = require('./lib/validate-options');
|
||||
*
|
||||
* @memberof module:workbox-build
|
||||
*/
|
||||
async function injectManifest(config) {
|
||||
const options = validate(config, injectManifestSchema);
|
||||
export async function injectManifest(config: unknown): Promise<BuildResult> {
|
||||
const options = validateInjectManifestOptions(config);
|
||||
|
||||
// Make sure we leave swSrc and swDest out of the precache manifest.
|
||||
for (const file of [options.swSrc, options.swDest]) {
|
||||
options.globIgnores.push(rebasePath({
|
||||
options.globIgnores!.push(rebasePath({
|
||||
file,
|
||||
baseDirectory: options.globDirectory,
|
||||
}));
|
||||
}
|
||||
|
||||
const globalRegexp = new RegExp(escapeRegexp(options.injectionPoint), 'g');
|
||||
const globalRegexp = new RegExp(escapeRegExp(options.injectionPoint!), 'g');
|
||||
|
||||
const {count, size, manifestEntries, warnings} =
|
||||
await getFileManifestEntries(options);
|
||||
let swFileContents;
|
||||
let swFileContents: string;
|
||||
try {
|
||||
swFileContents = await fse.readFile(options.swSrc, 'utf8');
|
||||
} catch (error) {
|
||||
@@ -153,9 +153,9 @@ async function injectManifest(config) {
|
||||
options.injectionPoint);
|
||||
|
||||
const manifestString = stringify(manifestEntries);
|
||||
const filesToWrite = {};
|
||||
const filesToWrite: {[key: string]: string} = {};
|
||||
|
||||
const url = sourceMapURL.getFrom(swFileContents);
|
||||
const url: string = sourceMapURL.getFrom(swFileContents);
|
||||
// If our swSrc file contains a sourcemap, we would invalidate that
|
||||
// mapping if we just replaced injectionPoint with the stringified manifest.
|
||||
// Instead, we need to update the swDest contents as well as the sourcemap
|
||||
@@ -166,9 +166,9 @@ async function injectManifest(config) {
|
||||
const sourcemapSrcPath = upath.resolve(upath.dirname(options.swSrc), url);
|
||||
const sourcemapDestPath = upath.resolve(upath.dirname(options.swDest), url);
|
||||
|
||||
let originalMap;
|
||||
let originalMap: RawSourceMap;
|
||||
try {
|
||||
originalMap = await fse.readJSON(sourcemapSrcPath, 'utf8');
|
||||
originalMap = await fse.readJSON(sourcemapSrcPath, {encoding: 'utf8'});
|
||||
} catch (error) {
|
||||
throw new Error(`${errors['cant-find-sourcemap']} ${error.message}`);
|
||||
}
|
||||
@@ -178,7 +178,7 @@ async function injectManifest(config) {
|
||||
jsFilename: upath.basename(options.swDest),
|
||||
originalSource: swFileContents,
|
||||
replaceString: manifestString,
|
||||
searchString: options.injectionPoint,
|
||||
searchString: options.injectionPoint!,
|
||||
});
|
||||
|
||||
filesToWrite[options.swDest] = source;
|
||||
@@ -194,7 +194,7 @@ async function injectManifest(config) {
|
||||
try {
|
||||
await fse.mkdirp(upath.dirname(file));
|
||||
} catch (error) {
|
||||
throw new Error(errors['unable-to-make-injection-directory'] +
|
||||
throw new Error(errors['unable-to-make-sw-directory'] +
|
||||
` '${error.message}'`);
|
||||
}
|
||||
|
||||
@@ -209,5 +209,3 @@ async function injectManifest(config) {
|
||||
filePaths: Object.keys(filesToWrite).map((f) => upath.resolve(f)),
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = injectManifest;
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const errors = require('./errors');
|
||||
|
||||
module.exports = (additionalManifestEntries) => {
|
||||
return (manifest) => {
|
||||
const warnings = [];
|
||||
const stringEntries = new Set();
|
||||
|
||||
for (const additionalEntry of additionalManifestEntries) {
|
||||
// Warn about either a string or an object that lacks a precache property.
|
||||
// (An object with a revision property set to null is okay.)
|
||||
if (typeof additionalEntry === 'string') {
|
||||
stringEntries.add(additionalEntry);
|
||||
} else if (additionalEntry && additionalEntry.revision === undefined) {
|
||||
stringEntries.add(additionalEntry.url);
|
||||
}
|
||||
|
||||
manifest.push(additionalEntry);
|
||||
}
|
||||
|
||||
if (stringEntries.size > 0) {
|
||||
let urls = '\n';
|
||||
for (const stringEntry of stringEntries) {
|
||||
urls += ` - ${stringEntry}\n`;
|
||||
}
|
||||
|
||||
warnings.push(errors['string-entry-warning'] + urls);
|
||||
}
|
||||
|
||||
return {
|
||||
manifest,
|
||||
warnings,
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import {errors} from './errors';
|
||||
import {ManifestEntry} from '../types';
|
||||
|
||||
export function additionalManifestEntriesTransform(additionalManifestEntries: Array<ManifestEntry | string>) {
|
||||
return (manifest: Array<ManifestEntry & {size: number}>) => {
|
||||
const warnings: Array<string> = [];
|
||||
const stringEntries = new Set<string>();
|
||||
|
||||
for (const additionalEntry of additionalManifestEntries) {
|
||||
// Warn about either a string or an object that lacks a revision property.
|
||||
// (An object with a revision property set to null is okay.)
|
||||
if (typeof additionalEntry === 'string') {
|
||||
stringEntries.add(additionalEntry);
|
||||
manifest.push({
|
||||
revision: null,
|
||||
size: 0,
|
||||
url: additionalEntry,
|
||||
});
|
||||
} else {
|
||||
if (additionalEntry && additionalEntry.revision === undefined) {
|
||||
stringEntries.add(additionalEntry.url);
|
||||
}
|
||||
manifest.push(Object.assign({size: 0}, additionalEntry));
|
||||
}
|
||||
}
|
||||
|
||||
if (stringEntries.size > 0) {
|
||||
let urls = '\n';
|
||||
for (const stringEntry of stringEntries) {
|
||||
urls += ` - ${stringEntry}\n`;
|
||||
}
|
||||
|
||||
warnings.push(errors['string-entry-warning'] + urls);
|
||||
}
|
||||
|
||||
return {
|
||||
manifest,
|
||||
warnings,
|
||||
};
|
||||
};
|
||||
}
|
||||
+30
-16
@@ -6,25 +6,32 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const {babel} = require('@rollup/plugin-babel');
|
||||
const {nodeResolve} = require('@rollup/plugin-node-resolve');
|
||||
const {rollup} = require('rollup');
|
||||
const {terser} = require('rollup-plugin-terser');
|
||||
const {writeFile} = require('fs-extra');
|
||||
const omt = require('@surma/rollup-plugin-off-main-thread');
|
||||
const presetEnv = require('@babel/preset-env');
|
||||
const replace = require('@rollup/plugin-replace');
|
||||
const tempy = require('tempy');
|
||||
const upath = require('upath');
|
||||
import {babel} from '@rollup/plugin-babel';
|
||||
import {nodeResolve} from '@rollup/plugin-node-resolve';
|
||||
import {rollup, Plugin} from 'rollup';
|
||||
import {terser} from 'rollup-plugin-terser';
|
||||
import {writeFile} from 'fs-extra';
|
||||
import omt from '@surma/rollup-plugin-off-main-thread';
|
||||
import presetEnv from '@babel/preset-env';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import tempy from 'tempy';
|
||||
import upath from 'upath';
|
||||
|
||||
module.exports = async ({
|
||||
import {GeneratePartial, RequiredSWDestPartial} from '../types';
|
||||
|
||||
interface NameAndContents {
|
||||
contents: string | Uint8Array;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export async function bundle({
|
||||
babelPresetEnvTargets,
|
||||
inlineWorkboxRuntime,
|
||||
mode,
|
||||
sourcemap,
|
||||
swDest,
|
||||
unbundledCode,
|
||||
}) => {
|
||||
}: Omit<GeneratePartial, 'runtimeCaching'> & RequiredSWDestPartial & {unbundledCode: string}): Promise<Array<NameAndContents>> {
|
||||
// We need to write this to the "real" file system, as Rollup won't read from
|
||||
// a custom file system.
|
||||
const {dir, base} = upath.parse(swDest);
|
||||
@@ -65,7 +72,11 @@ module.exports = async ({
|
||||
}));
|
||||
}
|
||||
|
||||
const rollupConfig = {
|
||||
const rollupConfig: {
|
||||
input: string;
|
||||
manualChunks?: (id: string) => string | undefined;
|
||||
plugins: Array<Plugin>;
|
||||
} = {
|
||||
plugins,
|
||||
input: temporaryFile,
|
||||
};
|
||||
@@ -87,9 +98,9 @@ module.exports = async ({
|
||||
format: inlineWorkboxRuntime ? 'es' : 'amd',
|
||||
});
|
||||
|
||||
const files = [];
|
||||
const files: Array<NameAndContents>= [];
|
||||
for (const chunkOrAsset of output) {
|
||||
if (chunkOrAsset.isAsset) {
|
||||
if (chunkOrAsset.type === 'asset') {
|
||||
files.push({
|
||||
name: chunkOrAsset.fileName,
|
||||
contents: chunkOrAsset.source,
|
||||
@@ -120,7 +131,10 @@ module.exports = async ({
|
||||
file.name = upath.format({
|
||||
dir,
|
||||
base: file.name,
|
||||
ext: '',
|
||||
name: '',
|
||||
root: '',
|
||||
});
|
||||
return file;
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
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,
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2021 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import {ok} from 'assert';
|
||||
|
||||
import {BuildType, WorkboxPackageJSON} from '../types';
|
||||
import {errors} from './errors';
|
||||
import * as cdn from '../cdn-details.json';
|
||||
|
||||
function getVersionedURL(): string {
|
||||
return `${getCDNPrefix()}/${cdn.latestVersion}`;
|
||||
}
|
||||
|
||||
function getCDNPrefix() {
|
||||
return `${cdn.origin}/${cdn.bucketName}/${cdn.releasesDir}`;
|
||||
}
|
||||
|
||||
export function getModuleURL(moduleName: string, buildType: BuildType) {
|
||||
ok(moduleName, errors['no-module-name']);
|
||||
|
||||
if (buildType) {
|
||||
const pkgJson: WorkboxPackageJSON = require(`${moduleName}/package.json`);
|
||||
if (buildType === 'dev' && pkgJson.workbox && 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 `${getVersionedURL()}/${moduleName}.${buildType.slice(0, 4)}.js`;
|
||||
}
|
||||
return `${getVersionedURL()}/${moduleName}.js`;
|
||||
}
|
||||
+9
-8
@@ -6,10 +6,11 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const fse = require('fs-extra');
|
||||
const upath = require('upath');
|
||||
const errors = require('./errors');
|
||||
import fse from 'fs-extra';
|
||||
import upath from 'upath';
|
||||
|
||||
import {WorkboxPackageJSON} from '../types';
|
||||
import {errors} from './errors';
|
||||
|
||||
// Used to filter the libraries to copy based on our package.json dependencies.
|
||||
const WORKBOX_PREFIX = 'workbox-';
|
||||
@@ -36,8 +37,8 @@ const BUILD_DIR = 'build';
|
||||
*
|
||||
* @alias module:workbox-build.copyWorkboxLibraries
|
||||
*/
|
||||
module.exports = async (destDirectory) => {
|
||||
const thisPkg = require('../../package.json');
|
||||
export async function copyWorkboxLibraries(destDirectory: string): Promise<string> {
|
||||
const thisPkg: WorkboxPackageJSON = 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
|
||||
@@ -46,8 +47,8 @@ module.exports = async (destDirectory) => {
|
||||
const workboxDirectoryPath = upath.join(destDirectory, workboxDirectoryName);
|
||||
await fse.ensureDir(workboxDirectoryPath);
|
||||
|
||||
const copyPromises = [];
|
||||
const librariesToCopy = Object.keys(thisPkg.dependencies).filter(
|
||||
const copyPromises: Array<Promise<void>> = [];
|
||||
const librariesToCopy = Object.keys(thisPkg.dependencies || {}).filter(
|
||||
(dependency) => dependency.startsWith(WORKBOX_PREFIX));
|
||||
|
||||
for (const library of librariesToCopy) {
|
||||
@@ -69,4 +70,4 @@ module.exports = async (destDirectory) => {
|
||||
} catch (error) {
|
||||
throw Error(`${errors['unable-to-copy-workbox-libraries']} ${error}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -6,9 +6,9 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const ol = require('common-tags').oneLine;
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
|
||||
module.exports = {
|
||||
export const errors = {
|
||||
'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.`,
|
||||
@@ -114,4 +114,8 @@ module.exports = {
|
||||
runtimeCaching option.`,
|
||||
'cant-find-sourcemap': ol`The swSrc file refers to a sourcemap that can't be
|
||||
opened:`,
|
||||
'nav-preload-runtime-caching': ol`When using navigationPreload, you must also
|
||||
configure a runtimeCaching route that will use the preloaded response.`,
|
||||
'cache-name-required': ol`When using cache expiration, you must also
|
||||
configure a custom cacheName.`,
|
||||
};
|
||||
+3
-1
@@ -7,4 +7,6 @@
|
||||
*/
|
||||
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
|
||||
module.exports = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
export function escapeRegExp(str: string) {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
+5
-3
@@ -6,9 +6,11 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const crypto = require('crypto');
|
||||
import crypto from 'crypto';
|
||||
|
||||
module.exports = (compositeURL, dependencyDetails) => {
|
||||
import {FileDetails} from '../types';
|
||||
|
||||
export function getCompositeDetails(compositeURL: string, dependencyDetails: Array<FileDetails>): FileDetails {
|
||||
let totalSize = 0;
|
||||
let compositeHash = '';
|
||||
|
||||
@@ -26,4 +28,4 @@ module.exports = (compositeURL, dependencyDetails) => {
|
||||
hash: hashOfHashes,
|
||||
size: totalSize,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const glob = require('glob');
|
||||
const upath = require('upath');
|
||||
|
||||
const errors = require('./errors');
|
||||
const getFileSize = require('./get-file-size');
|
||||
const getFileHash = require('./get-file-hash');
|
||||
|
||||
module.exports = ({
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPattern,
|
||||
globStrict,
|
||||
}) => {
|
||||
let globbedFiles;
|
||||
let warning;
|
||||
|
||||
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) {
|
||||
warning = errors['useless-glob-pattern'] + ' ' +
|
||||
JSON.stringify({globDirectory, globPattern, globIgnores}, null, 2);
|
||||
}
|
||||
|
||||
const fileDetails = globbedFiles.map((file) => {
|
||||
const fullPath = upath.join(globDirectory, file);
|
||||
const fileSize = getFileSize(fullPath);
|
||||
if (fileSize === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const fileHash = getFileHash(fullPath);
|
||||
return {
|
||||
file: `${upath.relative(globDirectory, fullPath)}`,
|
||||
hash: fileHash,
|
||||
size: fileSize,
|
||||
};
|
||||
});
|
||||
|
||||
// If !== null, means it's a valid file.
|
||||
const globbedFileDetails = fileDetails.filter((details) => details !== null);
|
||||
|
||||
return {globbedFileDetails, warning};
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2021 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import glob from 'glob';
|
||||
import upath from 'upath';
|
||||
|
||||
import {errors} from './errors';
|
||||
import {getFileSize} from './get-file-size';
|
||||
import {getFileHash} from './get-file-hash';
|
||||
|
||||
import {GlobPartial} from '../types';
|
||||
|
||||
interface FileDetails {
|
||||
file: string;
|
||||
hash: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export function getFileDetails({
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPattern,
|
||||
globStrict,
|
||||
}: Omit<GlobPartial, 'globDirectory' | 'globPatterns' | 'templatedURLs'> & {
|
||||
// This will only be called when globDirectory is not undefined.
|
||||
globDirectory: string;
|
||||
globPattern: string;
|
||||
}): {
|
||||
globbedFileDetails: Array<FileDetails>;
|
||||
warning: string;
|
||||
} {
|
||||
let globbedFiles: Array<string>;
|
||||
let warning = '';
|
||||
|
||||
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) {
|
||||
warning = errors['useless-glob-pattern'] + ' ' +
|
||||
JSON.stringify({globDirectory, globPattern, globIgnores}, null, 2);
|
||||
}
|
||||
|
||||
const globbedFileDetails: Array<FileDetails> = [];
|
||||
for (const file of globbedFiles) {
|
||||
const fullPath = upath.join(globDirectory, file);
|
||||
const fileSize = getFileSize(fullPath);
|
||||
if (fileSize !== null) {
|
||||
const fileHash = getFileHash(fullPath);
|
||||
globbedFileDetails.push({
|
||||
file: `${upath.relative(globDirectory, fullPath)}`,
|
||||
hash: fileHash,
|
||||
size: fileSize,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {globbedFileDetails, warning};
|
||||
}
|
||||
+6
-6
@@ -6,16 +6,16 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
import fse from 'fs-extra';
|
||||
|
||||
const getStringHash = require('./get-string-hash');
|
||||
const errors = require('./errors');
|
||||
import {getStringHash} from './get-string-hash';
|
||||
import {errors} from './errors';
|
||||
|
||||
module.exports = (file) => {
|
||||
export function getFileHash(file: string): string {
|
||||
try {
|
||||
const buffer = fs.readFileSync(file);
|
||||
const buffer = fse.readFileSync(file);
|
||||
return getStringHash(buffer);
|
||||
} catch (err) {
|
||||
throw new Error(errors['unable-to-get-file-hash'] + ` '${err.message}'`);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
const errors = require('./errors');
|
||||
const transformManifest = require('./transform-manifest');
|
||||
const getCompositeDetails = require('./get-composite-details');
|
||||
const getFileDetails = require('./get-file-details');
|
||||
const getStringDetails = require('./get-string-details');
|
||||
|
||||
module.exports = async ({
|
||||
additionalManifestEntries,
|
||||
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
|
||||
// transformManifest() and get a normalized output.
|
||||
let fileDetails = [];
|
||||
const fileSet = new Set();
|
||||
|
||||
if (globDirectory) {
|
||||
try {
|
||||
fileDetails = globPatterns.reduce((accumulated, globPattern) => {
|
||||
const {globbedFileDetails, warning} = getFileDetails({
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPattern,
|
||||
globStrict,
|
||||
});
|
||||
|
||||
if (warning) {
|
||||
warnings.push(warning);
|
||||
}
|
||||
|
||||
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 (const 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, warning} = getFileDetails({
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPattern,
|
||||
globStrict,
|
||||
});
|
||||
|
||||
if (warning) {
|
||||
warnings.push(warning);
|
||||
}
|
||||
|
||||
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 transformedManifest = await transformManifest({
|
||||
additionalManifestEntries,
|
||||
dontCacheBustURLsMatching,
|
||||
fileDetails,
|
||||
manifestTransforms,
|
||||
maximumFileSizeToCacheInBytes,
|
||||
modifyURLPrefix,
|
||||
});
|
||||
|
||||
if (warnings.length > 0) {
|
||||
transformedManifest.warnings.push(...warnings);
|
||||
}
|
||||
|
||||
return transformedManifest;
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright 2021 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import assert from 'assert';
|
||||
|
||||
import {GetManifestResult, FileDetails, GetManifestOptions} from '../types';
|
||||
import {errors} from './errors';
|
||||
import {getCompositeDetails} from './get-composite-details';
|
||||
import {getFileDetails} from './get-file-details';
|
||||
import {getStringDetails} from './get-string-details';
|
||||
import {transformManifest} from './transform-manifest';
|
||||
|
||||
export async function getFileManifestEntries({
|
||||
additionalManifestEntries,
|
||||
dontCacheBustURLsMatching,
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPatterns = [],
|
||||
globStrict,
|
||||
manifestTransforms,
|
||||
maximumFileSizeToCacheInBytes,
|
||||
modifyURLPrefix,
|
||||
templatedURLs,
|
||||
}: GetManifestOptions): Promise<GetManifestResult> {
|
||||
const warnings: Array<string> = [];
|
||||
const allFileDetails = new Map<string, FileDetails>();
|
||||
|
||||
try {
|
||||
for (const globPattern of globPatterns) {
|
||||
const {globbedFileDetails, warning} = getFileDetails({
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPattern,
|
||||
globStrict,
|
||||
});
|
||||
|
||||
if (warning) {
|
||||
warnings.push(warning);
|
||||
}
|
||||
|
||||
for (const details of globbedFileDetails) {
|
||||
if (details && !allFileDetails.has(details.file)) {
|
||||
allFileDetails.set(details.file, details);
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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 (const url of Object.keys(templatedURLs)) {
|
||||
assert(!allFileDetails.has(url), errors['templated-url-matches-glob']);
|
||||
|
||||
const dependencies = templatedURLs[url];
|
||||
if (Array.isArray(dependencies)) {
|
||||
const details = dependencies.reduce<Array<FileDetails>>((previous, globPattern) => {
|
||||
try {
|
||||
const {globbedFileDetails, warning} = getFileDetails({
|
||||
globDirectory,
|
||||
globFollow,
|
||||
globIgnores,
|
||||
globPattern,
|
||||
globStrict,
|
||||
});
|
||||
|
||||
if (warning) {
|
||||
warnings.push(warning);
|
||||
}
|
||||
|
||||
return previous.concat(globbedFileDetails);
|
||||
} catch (error) {
|
||||
const debugObj: {[key: string]: Array<string>} = {};
|
||||
debugObj[url] = dependencies;
|
||||
throw new Error(`${errors['bad-template-urls-asset']} ` +
|
||||
`'${globPattern}' from '${JSON.stringify(debugObj)}':\n` +
|
||||
error);
|
||||
}
|
||||
}, []);
|
||||
if (details.length === 0) {
|
||||
throw new Error(`${errors['bad-template-urls-asset']} The glob ` +
|
||||
`pattern '${dependencies}' did not match anything.`);
|
||||
}
|
||||
allFileDetails.set(url, getCompositeDetails(url, details));
|
||||
} else if (typeof dependencies === 'string') {
|
||||
allFileDetails.set(url, getStringDetails(url, dependencies));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const transformedManifest = await transformManifest({
|
||||
additionalManifestEntries,
|
||||
dontCacheBustURLsMatching,
|
||||
manifestTransforms,
|
||||
maximumFileSizeToCacheInBytes,
|
||||
modifyURLPrefix,
|
||||
fileDetails: Array.from(allFileDetails.values()),
|
||||
});
|
||||
|
||||
transformedManifest.warnings.push(...warnings);
|
||||
|
||||
return transformedManifest;
|
||||
}
|
||||
+5
-5
@@ -6,13 +6,13 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
import fse from 'fs-extra';
|
||||
|
||||
const errors = require('./errors');
|
||||
import {errors} from './errors';
|
||||
|
||||
module.exports = (file) => {
|
||||
export function getFileSize(file: string): number | null {
|
||||
try {
|
||||
const stat = fs.statSync(file);
|
||||
const stat = fse.statSync(file);
|
||||
if (!stat.isFile()) {
|
||||
return null;
|
||||
}
|
||||
@@ -20,4 +20,4 @@ module.exports = (file) => {
|
||||
} catch (err) {
|
||||
throw new Error(errors['unable-to-get-file-size'] + ` '${err.message}'`);
|
||||
}
|
||||
};
|
||||
}
|
||||
+6
-5
@@ -6,12 +6,13 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const getStringHash = require('./get-string-hash');
|
||||
import {FileDetails} from '../types';
|
||||
import {getStringHash} from './get-string-hash';
|
||||
|
||||
module.exports = (url, string) => {
|
||||
export function getStringDetails(url: string, str: string): FileDetails {
|
||||
return {
|
||||
file: url,
|
||||
hash: getStringHash(string),
|
||||
size: string.length,
|
||||
hash: getStringHash(str),
|
||||
size: str.length,
|
||||
};
|
||||
};
|
||||
}
|
||||
+4
-4
@@ -6,10 +6,10 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const crypto = require('crypto');
|
||||
import crypto from 'crypto';
|
||||
|
||||
module.exports = (string) => {
|
||||
export function getStringHash(input: crypto.BinaryLike): string {
|
||||
const md5 = crypto.createHash('md5');
|
||||
md5.update(string);
|
||||
md5.update(input);
|
||||
return md5.digest('hex');
|
||||
};
|
||||
}
|
||||
+6
-4
@@ -6,11 +6,13 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const prettyBytes = require('pretty-bytes');
|
||||
import prettyBytes from 'pretty-bytes';
|
||||
|
||||
module.exports = (maximumFileSizeToCacheInBytes) => {
|
||||
import {ManifestTransform} from '../types';
|
||||
|
||||
export function maximumSizeTransform(maximumFileSizeToCacheInBytes: number): ManifestTransform {
|
||||
return (originalManifest) => {
|
||||
const warnings = [];
|
||||
const warnings: Array<string> = [];
|
||||
const manifest = originalManifest.filter((entry) => {
|
||||
if (entry.size <= maximumFileSizeToCacheInBytes) {
|
||||
return true;
|
||||
@@ -24,4 +26,4 @@ module.exports = (maximumFileSizeToCacheInBytes) => {
|
||||
|
||||
return {manifest, warnings};
|
||||
};
|
||||
};
|
||||
}
|
||||
+10
-7
@@ -6,10 +6,11 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const errors = require('./errors');
|
||||
const escapeRegExp = require('./escape-regexp');
|
||||
import {errors} from './errors';
|
||||
import {escapeRegExp} from './escape-regexp';
|
||||
import {ManifestTransform} from '../types';
|
||||
|
||||
module.exports = (modifyURLPrefix) => {
|
||||
export function modifyURLPrefixTransform(modifyURLPrefix: {[key: string]: string}): ManifestTransform {
|
||||
if (!modifyURLPrefix ||
|
||||
typeof modifyURLPrefix !== 'object' ||
|
||||
Array.isArray(modifyURLPrefix)) {
|
||||
@@ -19,14 +20,16 @@ module.exports = (modifyURLPrefix) => {
|
||||
// If there are no entries in modifyURLPrefix, just return an identity
|
||||
// function as a shortcut.
|
||||
if (Object.keys(modifyURLPrefix).length === 0) {
|
||||
return (entry) => entry;
|
||||
return (manifest) => {
|
||||
return {manifest};
|
||||
};
|
||||
}
|
||||
|
||||
Object.keys(modifyURLPrefix).forEach((key) => {
|
||||
for (const key of Object.keys(modifyURLPrefix)) {
|
||||
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);
|
||||
@@ -51,4 +54,4 @@ module.exports = (modifyURLPrefix) => {
|
||||
|
||||
return {manifest};
|
||||
};
|
||||
};
|
||||
}
|
||||
+11
-12
@@ -6,8 +6,8 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const ol = require('common-tags').oneLine;
|
||||
const upath = require('upath');
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
import upath from 'upath';
|
||||
|
||||
/**
|
||||
* Class for keeping track of which Workbox modules are used by the generated
|
||||
@@ -15,12 +15,13 @@ const upath = require('upath');
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
class ModuleRegistry {
|
||||
export class ModuleRegistry {
|
||||
private readonly _modulesUsed: Map<string, {moduleName: string; pkg: string}>;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
constructor() {
|
||||
this.modulesUsed = new Map();
|
||||
this._modulesUsed = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,10 +29,10 @@ class ModuleRegistry {
|
||||
* needed for the modules being used.
|
||||
* @private
|
||||
*/
|
||||
getImportStatements() {
|
||||
const workboxModuleImports = [];
|
||||
getImportStatements(): Array<string> {
|
||||
const workboxModuleImports: Array<string> = [];
|
||||
|
||||
for (const [localName, {moduleName, pkg}] of this.modulesUsed) {
|
||||
for (const [localName, {moduleName, pkg}] of this._modulesUsed) {
|
||||
// By default require.resolve returns the resolved path of the 'main'
|
||||
// field, which might be deeper than the package root. To work around
|
||||
// this, we can find the package's root by resolving its package.json and
|
||||
@@ -53,7 +54,7 @@ class ModuleRegistry {
|
||||
* @return {string} The local variable name that corresponds to that module.
|
||||
* @private
|
||||
*/
|
||||
getLocalName(pkg, moduleName) {
|
||||
getLocalName(pkg: string, moduleName: string): string {
|
||||
return `${pkg.replace(/-/g, '_')}_${moduleName}`;
|
||||
}
|
||||
|
||||
@@ -63,12 +64,10 @@ class ModuleRegistry {
|
||||
* @return {string} The local variable name that corresponds to that module.
|
||||
* @private
|
||||
*/
|
||||
use(pkg, moduleName) {
|
||||
use(pkg: string, moduleName: string): string {
|
||||
const localName = this.getLocalName(pkg, moduleName);
|
||||
this.modulesUsed.set(localName, {moduleName, pkg});
|
||||
this._modulesUsed.set(localName, {moduleName, pkg});
|
||||
|
||||
return localName;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ModuleRegistry;
|
||||
+4
-3
@@ -6,9 +6,10 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const errors = require('./errors');
|
||||
import {errors} from './errors';
|
||||
import {ManifestTransform} from '../types';
|
||||
|
||||
module.exports = (regexp) => {
|
||||
export function noRevisionForURLsMatchingTransform(regexp: RegExp): ManifestTransform {
|
||||
if (!(regexp instanceof RegExp)) {
|
||||
throw new Error(errors['invalid-dont-cache-bust']);
|
||||
}
|
||||
@@ -28,4 +29,4 @@ module.exports = (regexp) => {
|
||||
|
||||
return {manifest};
|
||||
};
|
||||
};
|
||||
}
|
||||
+12
-11
@@ -6,15 +6,16 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const template = require('lodash/template');
|
||||
const swTemplate = require('../templates/sw-template');
|
||||
import template from 'lodash/template';
|
||||
|
||||
const errors = require('./errors');
|
||||
const ModuleRegistry = require('./module-registry');
|
||||
const runtimeCachingConverter = require('./runtime-caching-converter');
|
||||
const stringifyWithoutComments = require('./stringify-without-comments');
|
||||
import {errors} from './errors';
|
||||
import {GeneratePartial, ManifestEntry} from '../types';
|
||||
import {ModuleRegistry} from './module-registry';
|
||||
import {runtimeCachingConverter} from './runtime-caching-converter';
|
||||
import {stringifyWithoutComments} from './stringify-without-comments';
|
||||
import {swTemplate} from '../templates/sw-template';
|
||||
|
||||
module.exports = ({
|
||||
export function populateSWTemplate({
|
||||
cacheId,
|
||||
cleanupOutdatedCaches,
|
||||
clientsClaim,
|
||||
@@ -30,7 +31,7 @@ module.exports = ({
|
||||
offlineGoogleAnalytics,
|
||||
runtimeCaching = [],
|
||||
skipWaiting,
|
||||
}) => {
|
||||
}: GeneratePartial & {manifestEntries: Array<ManifestEntry>}): string {
|
||||
// There needs to be at least something to precache, or else runtime caching.
|
||||
if (!(manifestEntries.length > 0 || runtimeCaching.length > 0)) {
|
||||
throw new Error(errors['no-manifest-entries-or-runtime-caching']);
|
||||
@@ -42,7 +43,7 @@ module.exports = ({
|
||||
// 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 ?
|
||||
[] :
|
||||
[] as Array<RegExp> :
|
||||
undefined,
|
||||
};
|
||||
|
||||
@@ -55,7 +56,7 @@ module.exports = ({
|
||||
);
|
||||
}
|
||||
|
||||
let offlineAnalyticsConfigString;
|
||||
let offlineAnalyticsConfigString: string | undefined = undefined;
|
||||
if (offlineGoogleAnalytics) {
|
||||
// If offlineGoogleAnalytics is a truthy value, we need to convert it to the
|
||||
// format expected by the template.
|
||||
@@ -97,4 +98,4 @@ module.exports = ({
|
||||
throw new Error(
|
||||
`${errors['populating-sw-tmpl-failed']} '${error.message}'`);
|
||||
}
|
||||
};
|
||||
}
|
||||
+6
-3
@@ -6,9 +6,12 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const upath = require('upath');
|
||||
import upath from 'upath';
|
||||
|
||||
module.exports = ({baseDirectory, file}) => {
|
||||
export function rebasePath({
|
||||
baseDirectory,
|
||||
file
|
||||
}: {baseDirectory: string; file: string}): string {
|
||||
// The initial path is relative to the current directory, so make it absolute.
|
||||
const absolutePath = upath.resolve(file);
|
||||
|
||||
@@ -19,4 +22,4 @@ module.exports = ({baseDirectory, file}) => {
|
||||
const normalizedPath = upath.normalize(relativePath);
|
||||
|
||||
return normalizedPath;
|
||||
};
|
||||
}
|
||||
+13
-9
@@ -6,7 +6,7 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const {SourceMapConsumer, SourceMapGenerator} = require('source-map');
|
||||
import {RawSourceMap, SourceMapConsumer, SourceMapGenerator} from 'source-map';
|
||||
|
||||
/**
|
||||
* Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern
|
||||
@@ -27,22 +27,28 @@ const {SourceMapConsumer, SourceMapGenerator} = require('source-map');
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
async function replaceAndUpdateSourceMap({
|
||||
export async function replaceAndUpdateSourceMap({
|
||||
jsFilename,
|
||||
originalMap,
|
||||
originalSource,
|
||||
replaceString,
|
||||
searchString,
|
||||
}) {
|
||||
}: {
|
||||
jsFilename: string;
|
||||
originalMap: RawSourceMap;
|
||||
originalSource: string;
|
||||
replaceString: string;
|
||||
searchString: string;
|
||||
}): Promise<{map: string; source: string}> {
|
||||
const generator = new SourceMapGenerator({
|
||||
file: jsFilename,
|
||||
});
|
||||
|
||||
const consumer = await new SourceMapConsumer(originalMap);
|
||||
|
||||
let pos;
|
||||
let pos: number;
|
||||
let src = originalSource;
|
||||
const replacements = [];
|
||||
const replacements: Array<{line: number; column: number}> = [];
|
||||
let lineNum = 0;
|
||||
let filePos = 0;
|
||||
|
||||
@@ -65,7 +71,7 @@ async function replaceAndUpdateSourceMap({
|
||||
|
||||
consumer.eachMapping((mapping) => {
|
||||
for (const replacement of replacements) {
|
||||
if (replacement.line == mapping.generatedLine &&
|
||||
if (replacement.line === mapping.generatedLine &&
|
||||
mapping.generatedColumn > replacement.column) {
|
||||
const offset = searchString.length - replaceString.length;
|
||||
mapping.generatedColumn -= offset;
|
||||
@@ -92,7 +98,7 @@ async function replaceAndUpdateSourceMap({
|
||||
|
||||
consumer.destroy();
|
||||
|
||||
const updatedSourceMap = Object.assign(JSON.parse(generator.toString()), {
|
||||
const updatedSourceMap: RawSourceMap = Object.assign(JSON.parse(generator.toString()), {
|
||||
names: originalMap.names,
|
||||
sourceRoot: originalMap.sourceRoot,
|
||||
sources: originalMap.sources,
|
||||
@@ -104,5 +110,3 @@ async function replaceAndUpdateSourceMap({
|
||||
source: src,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = replaceAndUpdateSourceMap;
|
||||
+47
-54
@@ -6,10 +6,12 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const ol = require('common-tags').oneLine;
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
|
||||
const errors = require('./errors');
|
||||
const stringifyWithoutComments = require('./stringify-without-comments');
|
||||
import {errors} from './errors';
|
||||
import {ModuleRegistry} from './module-registry';
|
||||
import {RuntimeCaching} from '../types';
|
||||
import {stringifyWithoutComments} from './stringify-without-comments';
|
||||
|
||||
/**
|
||||
* Given a set of options that configures runtime caching behavior, convert it
|
||||
@@ -22,61 +24,56 @@ const stringifyWithoutComments = require('./stringify-without-comments');
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function getOptionsString(moduleRegistry, options = {}) {
|
||||
let plugins = [];
|
||||
if (options.plugins) {
|
||||
// Using libs because JSON.stringify won't handle functions.
|
||||
plugins = options.plugins.map(stringifyWithoutComments);
|
||||
delete options.plugins;
|
||||
}
|
||||
function getOptionsString(moduleRegistry: ModuleRegistry, options: RuntimeCaching['options'] = {}) {
|
||||
const plugins: Array<string> = [];
|
||||
const handlerOptions: {[key in keyof typeof options]: any} = {};
|
||||
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
for (const [pluginName, pluginConfig] of Object.entries(options)) {
|
||||
// Ensure that we have some valid configuration to pass to the plugin.
|
||||
if (Object.keys(pluginConfig).length === 0) {
|
||||
for (const optionName of Object.keys(options) as Array<keyof typeof options>) {
|
||||
if (options[optionName] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let pluginCode;
|
||||
switch (pluginName) {
|
||||
switch (optionName) {
|
||||
// Using a library here because JSON.stringify won't handle functions.
|
||||
case 'plugins': {
|
||||
plugins.push(...options.plugins!.map(stringifyWithoutComments));
|
||||
break;
|
||||
}
|
||||
|
||||
// These are the option properties that we want to pull out, so that
|
||||
// they're passed to the handler constructor.
|
||||
case 'cacheName':
|
||||
case 'networkTimeoutSeconds':
|
||||
case 'fetchOptions':
|
||||
case 'matchOptions': {
|
||||
handlerOptions[optionName] = options[optionName];
|
||||
break;
|
||||
}
|
||||
|
||||
// The following cases are all shorthands for creating a plugin with a
|
||||
// given configuration.
|
||||
case 'backgroundSync': {
|
||||
const name = pluginConfig.name;
|
||||
const name = options.backgroundSync!.name;
|
||||
const plugin = moduleRegistry.use(
|
||||
'workbox-background-sync', 'BackgroundSyncPlugin');
|
||||
|
||||
pluginCode = `new ${plugin}(${JSON.stringify(name)}`;
|
||||
if ('options' in pluginConfig) {
|
||||
pluginCode += `, ${stringifyWithoutComments(pluginConfig.options)}`;
|
||||
let pluginCode = `new ${plugin}(${JSON.stringify(name)}`;
|
||||
if (options.backgroundSync!.options) {
|
||||
pluginCode += `, ${stringifyWithoutComments(options.backgroundSync!.options)}`;
|
||||
}
|
||||
pluginCode += `)`;
|
||||
|
||||
plugins.push(pluginCode);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'broadcastUpdate': {
|
||||
const channelName = pluginConfig.channelName;
|
||||
const opts = Object.assign({channelName}, pluginConfig.options);
|
||||
const channelName = options.broadcastUpdate!.channelName;
|
||||
const opts = Object.assign({channelName}, options.broadcastUpdate!.options);
|
||||
const plugin = moduleRegistry.use(
|
||||
'workbox-broadcast-update', 'BroadcastUpdatePlugin');
|
||||
|
||||
pluginCode = `new ${plugin}(${stringifyWithoutComments(opts)})`;
|
||||
|
||||
plugins.push(`new ${plugin}(${stringifyWithoutComments(opts)})`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -84,8 +81,7 @@ function getOptionsString(moduleRegistry, options = {}) {
|
||||
const plugin = moduleRegistry.use(
|
||||
'workbox-cacheable-response', 'CacheableResponsePlugin');
|
||||
|
||||
pluginCode = `new ${plugin}(${stringifyWithoutComments(pluginConfig)})`;
|
||||
|
||||
plugins.push(`new ${plugin}(${stringifyWithoutComments(options.cacheableResponse!)})`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -93,8 +89,7 @@ function getOptionsString(moduleRegistry, options = {}) {
|
||||
const plugin = moduleRegistry.use(
|
||||
'workbox-expiration', 'ExpirationPlugin');
|
||||
|
||||
pluginCode = `new ${plugin}(${stringifyWithoutComments(pluginConfig)})`;
|
||||
|
||||
plugins.push(`new ${plugin}(${stringifyWithoutComments(options.expiration!)})`);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -102,17 +97,14 @@ function getOptionsString(moduleRegistry, options = {}) {
|
||||
const plugin = moduleRegistry.use(
|
||||
'workbox-precaching', 'PrecacheFallbackPlugin');
|
||||
|
||||
pluginCode = `new ${plugin}(${stringifyWithoutComments(pluginConfig)})`;
|
||||
|
||||
plugins.push(`new ${plugin}(${stringifyWithoutComments(options.precacheFallback!)})`);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new Error(errors['bad-runtime-caching-config'] + pluginName);
|
||||
throw new Error(errors['bad-runtime-caching-config'] + optionName);
|
||||
}
|
||||
}
|
||||
|
||||
plugins.push(pluginCode);
|
||||
}
|
||||
|
||||
if (Object.keys(handlerOptions).length > 0 || plugins.length > 0) {
|
||||
@@ -126,7 +118,7 @@ function getOptionsString(moduleRegistry, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (moduleRegistry, runtimeCaching) => {
|
||||
export function runtimeCachingConverter(moduleRegistry: ModuleRegistry, runtimeCaching: Array<RuntimeCaching>): Array<string> {
|
||||
return runtimeCaching.map((entry) => {
|
||||
const method = entry.method || 'GET';
|
||||
|
||||
@@ -138,8 +130,6 @@ module.exports = (moduleRegistry, runtimeCaching) => {
|
||||
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']);
|
||||
@@ -162,5 +152,8 @@ module.exports = (moduleRegistry, runtimeCaching) => {
|
||||
} else if (typeof entry.handler === 'function') {
|
||||
return `${registerRoute}(${matcher}, ${entry.handler}, '${method}');\n`;
|
||||
}
|
||||
}).filter((entry) => Boolean(entry)); // Remove undefined map() return values.
|
||||
};
|
||||
|
||||
// '' will be filtered out.
|
||||
return '';
|
||||
}).filter((entry) => Boolean(entry));
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const objectStringify = require('stringify-object');
|
||||
const stripComments = require('strip-comments');
|
||||
|
||||
module.exports = (obj) => {
|
||||
return objectStringify(obj, {
|
||||
transform: (_obj, _prop, str) =>
|
||||
typeof _obj[_prop] === 'function' ? stripComments(str) : str,
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2021 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import objectStringify from 'stringify-object';
|
||||
import stripComments from 'strip-comments';
|
||||
|
||||
export function stringifyWithoutComments(obj: {[key: string]: any}): string {
|
||||
return objectStringify(obj, {
|
||||
// See https://github.com/yeoman/stringify-object#transformobject-property-originalresult
|
||||
transform: (_obj: {[key: string]: any}, _prop, str) => {
|
||||
if (typeof _prop !== 'symbol' && typeof _obj[_prop] === 'function') {
|
||||
return stripComments(str);
|
||||
}
|
||||
return str;
|
||||
},
|
||||
});
|
||||
}
|
||||
+20
-16
@@ -6,13 +6,12 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const errors = require('./errors');
|
||||
const additionalManifestEntriesTransform =
|
||||
require('./additional-manifest-entries-transform');
|
||||
const maximumSizeTransform = require('./maximum-size-transform');
|
||||
const modifyURLPrefixTransform = require('./modify-url-prefix-transform');
|
||||
const noRevisionForURLsMatchingTransform =
|
||||
require('./no-revision-for-urls-matching-transform');
|
||||
import {BasePartial, FileDetails, ManifestEntry, ManifestTransform} from '../types';
|
||||
import {additionalManifestEntriesTransform} from './additional-manifest-entries-transform';
|
||||
import {errors} from './errors';
|
||||
import {maximumSizeTransform} from './maximum-size-transform';
|
||||
import {modifyURLPrefixTransform} from './modify-url-prefix-transform';
|
||||
import {noRevisionForURLsMatchingTransform} from './no-revision-for-urls-matching-transform';
|
||||
|
||||
/**
|
||||
* A `ManifestTransform` function can be used to modify the modify the `url` or
|
||||
@@ -66,7 +65,7 @@ const noRevisionForURLsMatchingTransform =
|
||||
* @memberof module:workbox-build
|
||||
*/
|
||||
|
||||
module.exports = async ({
|
||||
export async function transformManifest({
|
||||
additionalManifestEntries,
|
||||
dontCacheBustURLsMatching,
|
||||
fileDetails,
|
||||
@@ -74,8 +73,13 @@ module.exports = async ({
|
||||
maximumFileSizeToCacheInBytes,
|
||||
modifyURLPrefix,
|
||||
transformParam,
|
||||
}) => {
|
||||
let allWarnings = [];
|
||||
}: BasePartial & {
|
||||
fileDetails: Array<FileDetails>;
|
||||
// When this is called by the webpack plugin, transformParam will be the
|
||||
// current webpack compilation.
|
||||
transformParam?: unknown;
|
||||
}) {
|
||||
const allWarnings: Array<string> = [];
|
||||
|
||||
// Take the array of fileDetail objects and convert it into an array of
|
||||
// {url, revision, size} objects, with \ replaced with /.
|
||||
@@ -87,7 +91,7 @@ module.exports = async ({
|
||||
};
|
||||
});
|
||||
|
||||
const transformsToApply = [];
|
||||
const transformsToApply: Array<ManifestTransform> = [];
|
||||
|
||||
if (maximumFileSizeToCacheInBytes) {
|
||||
transformsToApply.push(maximumSizeTransform(maximumFileSizeToCacheInBytes));
|
||||
@@ -113,7 +117,7 @@ module.exports = async ({
|
||||
additionalManifestEntriesTransform(additionalManifestEntries));
|
||||
}
|
||||
|
||||
let transformedManifest = normalizedManifest;
|
||||
let transformedManifest: Array<ManifestEntry & {size: number}> = normalizedManifest;
|
||||
for (const transform of transformsToApply) {
|
||||
const result = await transform(transformedManifest, transformParam);
|
||||
if (!('manifest' in result)) {
|
||||
@@ -121,14 +125,14 @@ module.exports = async ({
|
||||
}
|
||||
|
||||
transformedManifest = result.manifest;
|
||||
allWarnings = allWarnings.concat(result.warnings || []);
|
||||
allWarnings.push(...(result.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) {
|
||||
for (const manifestEntry of transformedManifest as Array<ManifestEntry & {size?: number}>) {
|
||||
size += manifestEntry.size || 0;
|
||||
delete manifestEntry.size;
|
||||
}
|
||||
@@ -136,7 +140,7 @@ module.exports = async ({
|
||||
return {
|
||||
count,
|
||||
size,
|
||||
manifestEntries: transformedManifest,
|
||||
manifestEntries: transformedManifest as Array<ManifestEntry>,
|
||||
warnings: allWarnings,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
module.exports = (options, schema) => {
|
||||
const {value, error} = schema.validate(options, {
|
||||
language: {
|
||||
object: {
|
||||
allowUnknown: 'is not a supported parameter.',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright 2021 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import {betterAjvErrors} from '@apideck/better-ajv-errors';
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
import Ajv, {JSONSchemaType} from 'ajv';
|
||||
import ajvKeywords from 'ajv-keywords';
|
||||
|
||||
import {errors} from './errors';
|
||||
|
||||
import {
|
||||
GenerateSWOptions,
|
||||
GetManifestOptions,
|
||||
InjectManifestOptions,
|
||||
WebpackGenerateSWOptions,
|
||||
WebpackInjectManifestOptions,
|
||||
} from '../types';
|
||||
|
||||
type MethodNames = 'GenerateSW' | 'GetManifest' | 'InjectManifest' |
|
||||
'WebpackGenerateSW' | 'WebpackInjectManifest';
|
||||
|
||||
const ajv = new Ajv({
|
||||
useDefaults: true,
|
||||
});
|
||||
ajvKeywords(ajv, ['typeof']);
|
||||
|
||||
const DEFAULT_EXCLUDE_VALUE= [/\.map$/, /^manifest.*\.js$/];
|
||||
|
||||
export class WorkboxConfigError extends Error {
|
||||
constructor(message?: string) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
function validate<T>(input: unknown, methodName: MethodNames): T {
|
||||
// Don't mutate input: https://github.com/GoogleChrome/workbox/issues/2158
|
||||
const inputCopy = Object.assign({}, input);
|
||||
const jsonSchema: JSONSchemaType<T> = require(`../schema/${methodName}Options.json`);
|
||||
const validate = ajv.compile(jsonSchema);
|
||||
if (validate(inputCopy)) {
|
||||
return inputCopy;
|
||||
}
|
||||
|
||||
const betterErrors = betterAjvErrors({
|
||||
basePath: methodName,
|
||||
data: input,
|
||||
errors: validate.errors,
|
||||
// This is needed as JSONSchema6 is expected, but JSONSchemaType works.
|
||||
schema: jsonSchema as any,
|
||||
});
|
||||
const messages = betterErrors.map((err) => ol`[${err.path}] ${err.message}.
|
||||
${err.suggestion ? err.suggestion : ''}`);
|
||||
|
||||
throw new WorkboxConfigError(messages.join('\n\n'));
|
||||
}
|
||||
|
||||
function ensureValidNavigationPreloadConfig(
|
||||
options: GenerateSWOptions | WebpackGenerateSWOptions,
|
||||
): void {
|
||||
if (options.navigationPreload &&
|
||||
(!Array.isArray(options.runtimeCaching) ||
|
||||
options.runtimeCaching.length === 0)) {
|
||||
throw new WorkboxConfigError(errors['nav-preload-runtime-caching']);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureValidCacheExpiration(
|
||||
options: GenerateSWOptions | WebpackGenerateSWOptions,
|
||||
): void {
|
||||
for (const runtimeCaching of options.runtimeCaching || []) {
|
||||
if (runtimeCaching.options?.expiration && !runtimeCaching.options?.cacheName) {
|
||||
throw new WorkboxConfigError(errors['cache-name-required']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ensureValidRuntimeCachingOrGlobDirectory(
|
||||
options: GenerateSWOptions,
|
||||
): void {
|
||||
if (!options.globDirectory &&
|
||||
(!Array.isArray(options.runtimeCaching) ||
|
||||
options.runtimeCaching.length === 0)) {
|
||||
throw new WorkboxConfigError(errors['no-manifest-entries-or-runtime-caching']);
|
||||
}
|
||||
}
|
||||
|
||||
export function validateGenerateSWOptions(input: unknown): GenerateSWOptions {
|
||||
const validatedOptions = validate<GenerateSWOptions>(input, 'GenerateSW');
|
||||
ensureValidNavigationPreloadConfig(validatedOptions);
|
||||
ensureValidCacheExpiration(validatedOptions);
|
||||
ensureValidRuntimeCachingOrGlobDirectory(validatedOptions);
|
||||
return validatedOptions;
|
||||
}
|
||||
|
||||
export function validateGetManifestOptions(input: unknown): GetManifestOptions {
|
||||
return validate<GetManifestOptions>(input, 'GetManifest');
|
||||
}
|
||||
|
||||
export function validateInjectManifestOptions(input: unknown): InjectManifestOptions {
|
||||
return validate<InjectManifestOptions>(input, 'InjectManifest');
|
||||
}
|
||||
|
||||
// The default `exclude: [/\.map$/, /^manifest.*\.js$/]` value can't be
|
||||
// represented in the JSON schema, so manually set it for the webpack options.
|
||||
export function validateWebpackGenerateSWOptions(input: unknown): WebpackGenerateSWOptions {
|
||||
const inputWithExcludeDefault = Object.assign({
|
||||
// Make a copy, as exclude can be mutated when used.
|
||||
exclude: Array.from(DEFAULT_EXCLUDE_VALUE),
|
||||
}, input);
|
||||
const validatedOptions = validate<WebpackGenerateSWOptions>(inputWithExcludeDefault, 'WebpackGenerateSW');
|
||||
ensureValidNavigationPreloadConfig(validatedOptions);
|
||||
ensureValidCacheExpiration(validatedOptions);
|
||||
return validatedOptions;
|
||||
}
|
||||
|
||||
export function validateWebpackInjectManifestOptions(input: unknown): WebpackInjectManifestOptions {
|
||||
const inputWithExcludeDefault = Object.assign({
|
||||
// Make a copy, as exclude can be mutated when used.
|
||||
exclude: Array.from(DEFAULT_EXCLUDE_VALUE),
|
||||
}, input);
|
||||
return validate<WebpackInjectManifestOptions>(inputWithExcludeDefault, 'WebpackInjectManifest');
|
||||
}
|
||||
+10
-9
@@ -6,14 +6,15 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const fse = require('fs-extra');
|
||||
const upath = require('upath');
|
||||
import fse from 'fs-extra';
|
||||
import upath from 'upath';
|
||||
|
||||
const bundle = require('./bundle');
|
||||
const errors = require('./errors');
|
||||
const populateSWTemplate = require('./populate-sw-template');
|
||||
import {bundle} from './bundle';
|
||||
import {errors} from './errors';
|
||||
import {GenerateSWOptions, ManifestEntry} from '../types';
|
||||
import {populateSWTemplate} from './populate-sw-template';
|
||||
|
||||
module.exports = async ({
|
||||
export async function writeSWUsingDefaultTemplate({
|
||||
babelPresetEnvTargets,
|
||||
cacheId,
|
||||
cleanupOutdatedCaches,
|
||||
@@ -34,7 +35,7 @@ module.exports = async ({
|
||||
skipWaiting,
|
||||
sourcemap,
|
||||
swDest,
|
||||
}) => {
|
||||
}: GenerateSWOptions & {manifestEntries: Array<ManifestEntry>}): Promise<Array<string>> {
|
||||
const outputDir = upath.dirname(swDest);
|
||||
try {
|
||||
await fse.mkdirp(outputDir);
|
||||
@@ -71,7 +72,7 @@ module.exports = async ({
|
||||
unbundledCode,
|
||||
});
|
||||
|
||||
const filePaths = [];
|
||||
const filePaths: Array<string> = [];
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = upath.resolve(file.name);
|
||||
@@ -87,4 +88,4 @@ module.exports = async ({
|
||||
}
|
||||
throw new Error(`${errors['sw-write-failure']} '${error.message}'`);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
babelPresetEnvTargets: ['chrome >= 56'],
|
||||
cleanupOutdatedCaches: false,
|
||||
clientsClaim: false,
|
||||
compileSrc: true,
|
||||
disableDevLogs: false,
|
||||
exclude: [
|
||||
/\.map$/,
|
||||
/^manifest.*\.js$/,
|
||||
],
|
||||
globFollow: true,
|
||||
globIgnores: ['**/node_modules/**/*'],
|
||||
globPatterns: ['**/*.{js,css,html}'],
|
||||
globStrict: true,
|
||||
injectionPoint: 'self.__WB_MANIFEST',
|
||||
inlineWorkboxRuntime: false,
|
||||
maximumFileSizeToCacheInBytes: 2 * 1024 * 1024,
|
||||
mode: 'production',
|
||||
navigateFallback: null,
|
||||
navigationPreload: false,
|
||||
offlineGoogleAnalytics: false,
|
||||
purgeOnQuotaError: true,
|
||||
skipWaiting: false,
|
||||
sourcemap: true,
|
||||
swDestFilename: 'service-worker.js',
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
module.exports = joi.object().keys({
|
||||
integrity: joi.string(),
|
||||
revision: joi.string().required().allow(null),
|
||||
url: joi.string().required(),
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
module.exports = joi.object().instance(RegExp);
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const defaults = require('../defaults');
|
||||
const manifestEntryObject = require('../objects/manifest-entry');
|
||||
const regExpObject = require('../objects/reg-exp');
|
||||
|
||||
module.exports = {
|
||||
additionalManifestEntries: joi.array()
|
||||
.items(joi.string(), manifestEntryObject),
|
||||
dontCacheBustURLsMatching: regExpObject,
|
||||
manifestTransforms: joi.array().items(joi.func().minArity(1).maxArity(2)),
|
||||
maximumFileSizeToCacheInBytes: joi.number().min(1)
|
||||
.default(defaults.maximumFileSizeToCacheInBytes),
|
||||
modifyURLPrefix: joi.object(),
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const defaults = require('../defaults');
|
||||
const regExpObject = require('../objects/reg-exp');
|
||||
|
||||
module.exports = {
|
||||
babelPresetEnvTargets: joi.array().items(joi.string())
|
||||
.default(defaults.babelPresetEnvTargets),
|
||||
cacheId: joi.string(),
|
||||
cleanupOutdatedCaches: joi.boolean().default(defaults.cleanupOutdatedCaches),
|
||||
clientsClaim: joi.boolean().default(defaults.clientsClaim),
|
||||
directoryIndex: joi.string(),
|
||||
disableDevLogs: joi.boolean().default(defaults.disableDevLogs),
|
||||
ignoreURLParametersMatching: joi.array().items(regExpObject),
|
||||
importScripts: joi.array().items(joi.string()),
|
||||
inlineWorkboxRuntime: joi.boolean().default(defaults.inlineWorkboxRuntime),
|
||||
mode: joi.string().default(process.env.NODE_ENV || defaults.mode),
|
||||
navigateFallback: joi.string().default(defaults.navigateFallback),
|
||||
navigateFallbackAllowlist: joi.array().items(regExpObject),
|
||||
navigateFallbackBlacklist: joi.forbidden().error(new Error(
|
||||
'navigateFallbackBlacklist has been renamed navigateFallbackDenylist.')),
|
||||
navigateFallbackDenylist: joi.array().items(regExpObject),
|
||||
navigateFallbackWhitelist: joi.forbidden().error(new Error(
|
||||
'navigateFallbackWhitelist has been renamed navigateFallbackAllowlist.')),
|
||||
navigationPreload: joi.boolean().default(defaults.navigationPreload),
|
||||
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(), joi.func()],
|
||||
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()),
|
||||
precacheFallback: joi.object().keys({
|
||||
fallbackURL: joi.string().required(),
|
||||
}),
|
||||
fetchOptions: joi.object(),
|
||||
matchOptions: joi.object(),
|
||||
}).with('expiration', 'cacheName'),
|
||||
})).when('navigationPreload', {
|
||||
is: true,
|
||||
then: joi.required('runtimeCaching'),
|
||||
}),
|
||||
skipWaiting: joi.boolean().default(defaults.skipWaiting),
|
||||
sourcemap: joi.boolean().default(defaults.sourcemap),
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const defaults = require('../defaults');
|
||||
|
||||
module.exports = {
|
||||
globDirectory: joi.string(),
|
||||
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),
|
||||
// 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())]),
|
||||
};
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const defaults = require('../defaults');
|
||||
|
||||
module.exports = {
|
||||
injectionPoint: joi.string().default(defaults.injectionPoint),
|
||||
swSrc: joi.string().required(),
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const defaults = require('../defaults');
|
||||
const regExpObject = require('../objects/reg-exp');
|
||||
|
||||
module.exports = {
|
||||
chunks: joi.array().items(joi.string()),
|
||||
exclude: joi.array().items(joi.string(), regExpObject, joi.func().arity(1))
|
||||
.default(defaults.exclude),
|
||||
excludeChunks: joi.array().items(joi.string()),
|
||||
include: joi.array().items(joi.string(), regExpObject, joi.func().arity(1)),
|
||||
mode: joi.string().default(process.env.NODE_ENV || defaults.mode),
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const basePartial = require('../partials/base');
|
||||
const generatePartial = require('../partials/generate');
|
||||
const globPartial = require('../partials/glob');
|
||||
|
||||
const supportedOptions = Object.assign({
|
||||
swDest: joi.string().required().regex(/\.js$/),
|
||||
}, basePartial, generatePartial, globPartial);
|
||||
|
||||
module.exports = joi.object().keys(supportedOptions);
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const basePartial = require('../partials/base');
|
||||
const globPartial = require('../partials/glob');
|
||||
|
||||
const supportedOptions = Object.assign({}, basePartial, globPartial);
|
||||
|
||||
module.exports = joi.object().keys(supportedOptions);
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const basePartial = require('../partials/base');
|
||||
const globPartial = require('../partials/glob');
|
||||
const injectPartial = require('../partials/inject');
|
||||
|
||||
const supportedOptions = Object.assign({
|
||||
swDest: joi.string().required().regex(/\.js$/),
|
||||
}, basePartial, globPartial, injectPartial);
|
||||
|
||||
module.exports = joi.object().keys(supportedOptions);
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
|
||||
const basePartial = require('../partials/base');
|
||||
const defaults = require('../defaults');
|
||||
const generatePartial = require('../partials/generate');
|
||||
const webpackPartial = require('../partials/webpack');
|
||||
|
||||
const supportedOptions = Object.assign({
|
||||
importScriptsViaChunks: joi.array().items(joi.string()),
|
||||
swDest: joi.string().default(defaults.swDestFilename),
|
||||
}, basePartial, generatePartial, webpackPartial);
|
||||
|
||||
module.exports = joi.object().keys(supportedOptions);
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 Google LLC
|
||||
|
||||
Use of this source code is governed by an MIT-style
|
||||
license that can be found in the LICENSE file or at
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const joi = require('@hapi/joi');
|
||||
const upath = require('upath');
|
||||
|
||||
const basePartial = require('../partials/base');
|
||||
const defaults = require('../defaults');
|
||||
const injectPartial = require('../partials/inject');
|
||||
const webpackPartial = require('../partials/webpack');
|
||||
|
||||
// See https://github.com/hapijs/joi/blob/v16.0.0-rc2/API.md#anydefaultvalue-description
|
||||
const swSrcBasename = (context) => {
|
||||
const {name} = upath.parse(context.swSrc);
|
||||
// Always use the .js extension when generating a default filename.
|
||||
return name + '.js';
|
||||
};
|
||||
swSrcBasename.description = 'derived from the swSrc file name';
|
||||
|
||||
const supportedOptions = Object.assign({
|
||||
compileSrc: joi.boolean().default(defaults.compileSrc),
|
||||
webpackCompilationPlugins: joi.array().items(joi.object()).when(
|
||||
'compileSrc', {is: false, then: joi.forbidden()}),
|
||||
}, basePartial, injectPartial, webpackPartial);
|
||||
|
||||
module.exports = joi.object().keys(supportedOptions).keys({
|
||||
// List this separately, so that the swSrc validation happens first.
|
||||
swDest: joi.string().default(swSrcBasename),
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
declare module '@surma/rollup-plugin-off-main-thread';
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
declare module 'source-map-url';
|
||||
@@ -0,0 +1 @@
|
||||
declare module 'strip-comments';
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
module.exports = `/**
|
||||
export const swTemplate = `/**
|
||||
* Welcome to your Workbox-powered service worker!
|
||||
*
|
||||
* You'll need to register this file in your web app.
|
||||
@@ -0,0 +1,246 @@
|
||||
import {PackageJson} from 'type-fest';
|
||||
|
||||
import {BroadcastCacheUpdateOptions} from 'workbox-broadcast-update/BroadcastCacheUpdate';
|
||||
import {GoogleAnalyticsInitializeOptions} from 'workbox-google-analytics/initialize';
|
||||
import {HTTPMethod} from 'workbox-routing/utils/constants';
|
||||
import {QueueOptions} from 'workbox-background-sync/Queue';
|
||||
import {RouteHandler, RouteMatchCallback} from 'workbox-core/types';
|
||||
import {CacheableResponseOptions} from 'workbox-cacheable-response/CacheableResponse';
|
||||
import {ExpirationPluginOptions} from 'workbox-expiration/ExpirationPlugin';
|
||||
import {WorkboxPlugin} from 'workbox-core/types';
|
||||
|
||||
export interface ManifestEntry {
|
||||
integrity?: string;
|
||||
revision: string | null;
|
||||
url: string;
|
||||
}
|
||||
|
||||
type StrategyName = 'CacheFirst' | 'CacheOnly' | 'NetworkFirst' | 'NetworkOnly' | 'StaleWhileRevalidate';
|
||||
|
||||
export interface RuntimeCaching {
|
||||
handler: RouteHandler | StrategyName;
|
||||
method?: HTTPMethod;
|
||||
options?: {
|
||||
backgroundSync?: {
|
||||
name: string;
|
||||
options?: QueueOptions;
|
||||
};
|
||||
broadcastUpdate?: {
|
||||
// TODO: This option is ignored since we switched to using postMessage().
|
||||
// Remove it in the next major release.
|
||||
channelName?: string;
|
||||
options: BroadcastCacheUpdateOptions;
|
||||
};
|
||||
cacheableResponse?: CacheableResponseOptions;
|
||||
cacheName?: string | null;
|
||||
expiration?: ExpirationPluginOptions;
|
||||
networkTimeoutSeconds?: number;
|
||||
plugins?: Array<WorkboxPlugin>;
|
||||
precacheFallback?: {
|
||||
fallbackURL: string;
|
||||
};
|
||||
fetchOptions?: RequestInit;
|
||||
matchOptions?: CacheQueryOptions;
|
||||
};
|
||||
urlPattern: RegExp | string | RouteMatchCallback;
|
||||
}
|
||||
|
||||
export interface ManifestTransformResult {
|
||||
manifest: Array<ManifestEntry & {size: number}>;
|
||||
warnings?: Array<string>;
|
||||
}
|
||||
|
||||
export type ManifestTransform = (
|
||||
manifestEntries: Array<ManifestEntry & {size: number}>,
|
||||
compilation?: unknown
|
||||
) => Promise<ManifestTransformResult> | ManifestTransformResult;
|
||||
|
||||
export interface BasePartial {
|
||||
additionalManifestEntries?: Array<string | ManifestEntry>;
|
||||
dontCacheBustURLsMatching?: RegExp;
|
||||
manifestTransforms?: Array<ManifestTransform>;
|
||||
/**
|
||||
* @default 2097152
|
||||
*/
|
||||
maximumFileSizeToCacheInBytes?: number;
|
||||
modifyURLPrefix?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GeneratePartial {
|
||||
/**
|
||||
* @default ["chrome >= 56"]
|
||||
*/
|
||||
babelPresetEnvTargets?: Array<string>;
|
||||
cacheId?: string | null;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
cleanupOutdatedCaches?: boolean;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
clientsClaim?: boolean;
|
||||
directoryIndex?: string | null;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
disableDevLogs?: boolean;
|
||||
ignoreURLParametersMatching?: Array<RegExp>;
|
||||
importScripts?: Array<string>;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
inlineWorkboxRuntime?: boolean;
|
||||
/**
|
||||
* @default "production"
|
||||
*/
|
||||
mode?: string | null;
|
||||
/**
|
||||
* @default null
|
||||
*/
|
||||
navigateFallback?: string | null;
|
||||
navigateFallbackAllowlist?: Array<RegExp>;
|
||||
navigateFallbackDenylist?: Array<RegExp>;
|
||||
/**
|
||||
* navigationPreload is only valid when runtimeCaching is configured. However,
|
||||
* this can't be expressed via TypeScript, so it's enforced via runtime logic.
|
||||
* @default false
|
||||
*/
|
||||
navigationPreload?: boolean;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
offlineGoogleAnalytics?: boolean | GoogleAnalyticsInitializeOptions;
|
||||
runtimeCaching?: Array<RuntimeCaching>;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
skipWaiting?: boolean;
|
||||
/**
|
||||
* @default true
|
||||
*/
|
||||
sourcemap?: boolean;
|
||||
}
|
||||
|
||||
// This needs to be set when using GetManifest or InjectManifest, but is
|
||||
// optional when using GenerateSW if runtimeCaching is also used. This is
|
||||
// enforced via runtime validation, and needs to be documented.
|
||||
export interface RequiredGlobDirectoryPartial {
|
||||
globDirectory: string;
|
||||
}
|
||||
|
||||
export interface OptionalGlobDirectoryPartial {
|
||||
globDirectory?: string;
|
||||
}
|
||||
|
||||
export interface GlobPartial {
|
||||
/**
|
||||
* @default true
|
||||
*/
|
||||
globFollow?: boolean;
|
||||
/**
|
||||
* @default ["**\/node_modules\/**\/*"]
|
||||
*/
|
||||
globIgnores?: Array<string>;
|
||||
/**
|
||||
* @default ["**\/*.{js,css,html}"]
|
||||
*/
|
||||
globPatterns?: Array<string>;
|
||||
/**
|
||||
* @default true
|
||||
*/
|
||||
globStrict?: boolean;
|
||||
templatedURLs?: {
|
||||
[key: string]: string | Array<string>;
|
||||
};
|
||||
}
|
||||
|
||||
interface InjectPartial {
|
||||
/**
|
||||
* @default "self.__WB_MANIFEST"
|
||||
*/
|
||||
injectionPoint?: string;
|
||||
swSrc: string;
|
||||
}
|
||||
|
||||
interface WebpackPartial {
|
||||
chunks?: Array<string>;
|
||||
// We can't use the @default annotation here to assign the value via AJV, as
|
||||
// an Array<RegExp> can't be serialized into JSON.
|
||||
// The default value of [/\.map$/, /^manifest.*\.js$/] will be assigned by
|
||||
// the validation function, and we need to reflect that in the docs.
|
||||
exclude?: Array<string | RegExp | ((arg0: string) => boolean)>;
|
||||
excludeChunks?: Array<string>;
|
||||
include?: Array<string | RegExp | ((arg0: string) => boolean)>;
|
||||
mode?: string | null;
|
||||
}
|
||||
|
||||
export interface RequiredSWDestPartial {
|
||||
swDest: string;
|
||||
}
|
||||
|
||||
interface WebpackGenerateSWPartial {
|
||||
importScriptsViaChunks?: Array<string>;
|
||||
/**
|
||||
* @default "service-worker.js"
|
||||
*/
|
||||
swDest?: string;
|
||||
}
|
||||
|
||||
interface WebpackInjectManifestPartial {
|
||||
/**
|
||||
* @default true
|
||||
*/
|
||||
compileSrc?: boolean;
|
||||
// This doesn't have a hardcoded default value; instead, the default will be
|
||||
// set at runtime to the swSrc basename, with the hardcoded extension .js.
|
||||
swDest?: string;
|
||||
// This can only be set if compileSrc is true, but that restriction can't be
|
||||
// represented in TypeScript. It's enforced via custom runtime validation
|
||||
// logic and needs to be documented.
|
||||
webpackCompilationPlugins?: Array<any>;
|
||||
}
|
||||
|
||||
export type GenerateSWOptions = BasePartial & GlobPartial & GeneratePartial &
|
||||
RequiredSWDestPartial & OptionalGlobDirectoryPartial
|
||||
|
||||
export type GetManifestOptions = BasePartial & GlobPartial &
|
||||
RequiredGlobDirectoryPartial;
|
||||
|
||||
export type InjectManifestOptions = BasePartial & GlobPartial & InjectPartial &
|
||||
RequiredSWDestPartial & RequiredGlobDirectoryPartial;
|
||||
|
||||
export type WebpackGenerateSWOptions = BasePartial & WebpackPartial &
|
||||
GeneratePartial & WebpackGenerateSWPartial;
|
||||
|
||||
export type WebpackInjectManifestOptions = BasePartial & WebpackPartial &
|
||||
InjectPartial & WebpackInjectManifestPartial;
|
||||
|
||||
export interface GetManifestResult {
|
||||
count: number;
|
||||
manifestEntries: Array<ManifestEntry>;
|
||||
size: number;
|
||||
warnings: Array<string>;
|
||||
}
|
||||
|
||||
export type BuildResult = Omit<GetManifestResult, 'manifestEntries'> & {
|
||||
filePaths: Array<string>;
|
||||
};
|
||||
|
||||
export interface FileDetails {
|
||||
file: string;
|
||||
hash: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export type BuildType = 'dev' | 'prod';
|
||||
|
||||
export interface WorkboxPackageJSON extends PackageJson {
|
||||
workbox?: {
|
||||
browserNamespace?: string;
|
||||
packageType?: string;
|
||||
prodOnly?: boolean;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"module": "CommonJS",
|
||||
"outDir": "./build",
|
||||
"resolveJsonModule": true,
|
||||
"rootDir": "./src",
|
||||
"target": "ES2018",
|
||||
"tsBuildInfoFile": "./tsconfig.tsbuildinfo"
|
||||
},
|
||||
"files": [
|
||||
"src/cdn-details.json"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/schema/*.json"
|
||||
],
|
||||
"references": [
|
||||
{"path": "../workbox-background-sync/"},
|
||||
{"path": "../workbox-broadcast-update/"},
|
||||
{"path": "../workbox-cacheable-response/"},
|
||||
{"path": "../workbox-core/"},
|
||||
{"path": "../workbox-expiration/"},
|
||||
{"path": "../workbox-google-analytics/"}
|
||||
]
|
||||
}
|
||||
@@ -7,12 +7,12 @@
|
||||
*/
|
||||
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
import * as assert from 'assert';
|
||||
import * as meow from 'meow';
|
||||
import * as prettyBytes from 'pretty-bytes';
|
||||
import * as upath from 'upath';
|
||||
import * as watch from 'glob-watcher';
|
||||
import * as workboxBuild from 'workbox-build';
|
||||
import assert from 'assert';
|
||||
import GlobWatcher from 'glob-watcher';
|
||||
import meow from 'meow';
|
||||
import prettyBytes from 'pretty-bytes';
|
||||
import upath from 'upath';
|
||||
import workboxBuild from 'workbox-build';
|
||||
|
||||
import {constants} from './lib/constants.js';
|
||||
import {errors} from './lib/errors.js';
|
||||
@@ -22,51 +22,38 @@ import {runWizard} from './lib/run-wizard.js';
|
||||
import {SupportedFlags} from './bin.js'
|
||||
|
||||
interface BuildCommand {
|
||||
command: 'generateSW'|'injectManifest';
|
||||
command: 'generateSW' | 'injectManifest';
|
||||
config: any;
|
||||
watch: boolean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs the specified build command with the provided configuration.
|
||||
*
|
||||
* @param {Object} options
|
||||
*/
|
||||
async function runBuildCommand({command, config, watch}: BuildCommand) {
|
||||
try {
|
||||
const {count, filePaths, size, warnings} =
|
||||
await workboxBuild[command](config);
|
||||
|
||||
const {count, filePaths, size, warnings} = await workboxBuild[command](config);
|
||||
|
||||
for (const warning of warnings) {
|
||||
logger.warn(warning);
|
||||
}
|
||||
for (const warning of warnings) {
|
||||
logger.warn(warning);
|
||||
}
|
||||
|
||||
if (filePaths.length === 1) {
|
||||
logger.log(`The service worker file was written to ${config.swDest}`);
|
||||
} else {
|
||||
const message = filePaths
|
||||
.sort()
|
||||
.map((filePath) => ` • ${filePath}`)
|
||||
.join(`\n`);
|
||||
logger.log(`The service worker files were written to:\n${message}`);
|
||||
}
|
||||
if (filePaths.length === 1) {
|
||||
logger.log(`The service worker file was written to ${config.swDest}`);
|
||||
} else {
|
||||
const message = filePaths
|
||||
.sort()
|
||||
.map((filePath) => ` • ${filePath}`)
|
||||
.join(`\n`);
|
||||
logger.log(`The service worker files were written to:\n${message}`);
|
||||
}
|
||||
|
||||
logger.log(`The service worker will precache ${count} URLs, ` +
|
||||
`totaling ${prettyBytes(size)}.`);
|
||||
logger.log(`The service worker will precache ${count} URLs, ` +
|
||||
`totaling ${prettyBytes(size)}.`);
|
||||
|
||||
if (watch) {
|
||||
logger.log(`\nWatching for changes...`);
|
||||
}
|
||||
} catch (error) {
|
||||
// See https://github.com/hapijs/joi/blob/v11.3.4/API.md#errors
|
||||
if (typeof error.annotate === 'function') {
|
||||
throw new Error(
|
||||
`${errors['config-validation-failed']}\n${error.annotate()}`);
|
||||
}
|
||||
logger.error(errors['workbox-build-runtime-error']);
|
||||
throw error;
|
||||
if (watch) {
|
||||
logger.log(`\nWatching for changes...`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +101,7 @@ export const app = async (params: meow.Result<SupportedFlags>) => {
|
||||
|
||||
// Determine whether we're in --watch mode, or one-off mode.
|
||||
if (params.flags && params.flags.watch) {
|
||||
const options: watch.WatchOptions = {ignoreInitial: false}
|
||||
const options: GlobWatcher.WatchOptions = {ignoreInitial: false};
|
||||
if (config.globIgnores) {
|
||||
options.ignored = config.globIgnores;
|
||||
}
|
||||
@@ -123,7 +110,7 @@ export const app = async (params: meow.Result<SupportedFlags>) => {
|
||||
}
|
||||
|
||||
if (config.globPatterns) {
|
||||
watch(config.globPatterns, options,
|
||||
GlobWatcher(config.globPatterns, options,
|
||||
() => runBuildCommand({command, config, watch: true}));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
import * as meow from 'meow'
|
||||
import * as updateNotifier from 'update-notifier';
|
||||
import meow from 'meow'
|
||||
import updateNotifier from 'update-notifier';
|
||||
|
||||
import {app} from './app';
|
||||
import {cleanupStackTrace} from './lib/cleanup-stack-trace.js';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as chalk from 'chalk';
|
||||
import chalk from 'chalk';
|
||||
|
||||
export const logger = {
|
||||
debug: (...args: string[]) => console.log(chalk.gray(...args)),
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import assert from 'assert';
|
||||
import {prompt} from 'inquirer';
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import assert from 'assert';
|
||||
import {prompt} from 'inquirer';
|
||||
import * as glob from 'glob';
|
||||
import * as ora from 'ora';
|
||||
import * as upath from 'upath';
|
||||
import glob from 'glob';
|
||||
import ora from 'ora';
|
||||
import upath from 'upath';
|
||||
|
||||
import {errors} from '../errors';
|
||||
import {constants} from '../constants';
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as fse from 'fs-extra';
|
||||
import * as glob from 'glob';
|
||||
import assert from 'assert';
|
||||
import fse from 'fs-extra';
|
||||
import glob from 'glob';
|
||||
import {prompt, Separator} from 'inquirer';
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import assert from 'assert';
|
||||
import {prompt} from 'inquirer';
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import assert from 'assert';
|
||||
import {prompt} from 'inquirer';
|
||||
import * as upath from 'upath';
|
||||
import upath from 'upath';
|
||||
|
||||
import {errors} from '../errors';
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
import * as fse from 'fs-extra';
|
||||
import fse from 'fs-extra';
|
||||
import {oneLine as ol} from 'common-tags';
|
||||
import * as stringifyObject from 'stringify-object';
|
||||
import stringifyObject from 'stringify-object';
|
||||
|
||||
import {askQuestions} from './questions/ask-questions';
|
||||
import {logger} from './logger';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"module": "CommonJS",
|
||||
"outDir": "build",
|
||||
"rootDir": "src",
|
||||
@@ -9,5 +10,8 @@
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{"path": "../workbox-build/"},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import '../_version.js';
|
||||
*/
|
||||
class Deferred<T> {
|
||||
promise: Promise<T>;
|
||||
resolve!: (value?: T) => void;
|
||||
resolve!: (value: T) => void;
|
||||
reject!: (reason?: any) => void;
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,13 @@ import {CacheExpiration} from './CacheExpiration.js';
|
||||
|
||||
import './_version.js';
|
||||
|
||||
export interface ExpirationPluginOptions {
|
||||
maxEntries?: number;
|
||||
maxAgeSeconds?: number;
|
||||
matchOptions?: CacheQueryOptions;
|
||||
purgeOnQuotaError?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* This plugin can be used in a `workbox-strategy` to regularly enforce a
|
||||
* limit on the age and / or the number of cached requests.
|
||||
@@ -58,12 +65,7 @@ class ExpirationPlugin implements WorkboxPlugin {
|
||||
* @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to
|
||||
* automatic deletion if the available storage quota has been exceeded.
|
||||
*/
|
||||
constructor(config: {
|
||||
maxEntries?: number;
|
||||
maxAgeSeconds?: number;
|
||||
matchOptions?: CacheQueryOptions;
|
||||
purgeOnQuotaError?: boolean;
|
||||
} = {}) {
|
||||
constructor(config: ExpirationPluginOptions = {}) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (!(config.maxEntries || config.maxAgeSeconds)) {
|
||||
throw new WorkboxError('max-entries-or-age-required', {
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
import './_version.js';
|
||||
|
||||
|
||||
interface GoogleAnalyticsInitializeOptions {
|
||||
export interface GoogleAnalyticsInitializeOptions {
|
||||
cacheName?: string;
|
||||
parameterOverrides?: {[paramName: string]: string};
|
||||
hitFilter?: (params: URLSearchParams) => void;
|
||||
|
||||
@@ -520,7 +520,7 @@ class StrategyHandler {
|
||||
* `waitUntil()` promises.
|
||||
*/
|
||||
destroy() {
|
||||
this._handlerDeferred.resolve();
|
||||
this._handlerDeferred.resolve(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,14 +6,13 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const bundle = require('workbox-build/build/lib/bundle');
|
||||
const populateSWTemplate =
|
||||
const {validateWebpackGenerateSWOptions} =
|
||||
require('workbox-build/build/lib/validate-options');
|
||||
const {bundle} = require('workbox-build/build/lib/bundle');
|
||||
const {populateSWTemplate} =
|
||||
require('workbox-build/build/lib/populate-sw-template');
|
||||
const prettyBytes = require('pretty-bytes');
|
||||
const validate = require('workbox-build/build/lib/validate-options');
|
||||
const webpack = require('webpack');
|
||||
const webpackGenerateSWSchema = require(
|
||||
'workbox-build/build/options/schema/webpack-generate-sw');
|
||||
|
||||
const getScriptFilesForChunks = require('./lib/get-script-files-for-chunks');
|
||||
const getManifestEntriesFromCompilation =
|
||||
@@ -272,7 +271,7 @@ class GenerateSW {
|
||||
// emit might be called multiple times; instead of modifying this.config,
|
||||
// use a validated copy.
|
||||
// See https://github.com/GoogleChrome/workbox/issues/2158
|
||||
config = validate(this.config, webpackGenerateSWSchema);
|
||||
config = validateWebpackGenerateSWOptions(this.config);
|
||||
} catch (error) {
|
||||
throw new Error(`Please check your ${this.constructor.name} plugin ` +
|
||||
`configuration:\n${error.message}`);
|
||||
|
||||
@@ -6,16 +6,15 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const escapeRegexp = require('workbox-build/build/lib/escape-regexp');
|
||||
const {escapeRegExp} = require('workbox-build/build/lib/escape-regexp');
|
||||
const {replaceAndUpdateSourceMap} =
|
||||
require('workbox-build/build/lib/replace-and-update-source-map');
|
||||
const {validateWebpackInjectManifestOptions} =
|
||||
require('workbox-build/build/lib/validate-options');
|
||||
const prettyBytes = require('pretty-bytes');
|
||||
const replaceAndUpdateSourceMap = require(
|
||||
'workbox-build/build/lib/replace-and-update-source-map');
|
||||
const stringify = require('fast-json-stable-stringify');
|
||||
const upath = require('upath');
|
||||
const validate = require('workbox-build/build/lib/validate-options');
|
||||
const webpack = require('webpack');
|
||||
const webpackInjectManifestSchema = require(
|
||||
'workbox-build/build/options/schema/webpack-inject-manifest');
|
||||
|
||||
const getManifestEntriesFromCompilation =
|
||||
require('./lib/get-manifest-entries-from-compilation');
|
||||
@@ -137,6 +136,8 @@ class InjectManifest {
|
||||
// there take precedence over derived properties from the compiler.
|
||||
this.config = Object.assign({
|
||||
mode: compiler.mode,
|
||||
// Use swSrc with a hardcoded .js extension, in case swSrc is a .ts file.
|
||||
swDest: upath.parse(this.config.swSrc).name + '.js',
|
||||
}, this.config);
|
||||
}
|
||||
|
||||
@@ -250,7 +251,7 @@ class InjectManifest {
|
||||
*/
|
||||
async handleMake(compilation, parentCompiler) {
|
||||
try {
|
||||
this.config = validate(this.config, webpackInjectManifestSchema);
|
||||
this.config = validateWebpackInjectManifestOptions(this.config);
|
||||
} catch (error) {
|
||||
throw new Error(`Please check your ${this.constructor.name} plugin ` +
|
||||
`configuration:\n${error.message}`);
|
||||
@@ -263,6 +264,13 @@ class InjectManifest {
|
||||
await this.performChildCompilation(compilation, parentCompiler);
|
||||
} else {
|
||||
this.addSrcToAssets(compilation, parentCompiler);
|
||||
// This used to be a fatal error, but just warn at runtime because we
|
||||
// can't validate it easily.
|
||||
if (Array.isArray(this.config.webpackCompilationPlugins) &&
|
||||
this.config.webpackCompilationPlugins.length > 0) {
|
||||
compilation.warnings.push(new Error('compileSrc is false, so the ' +
|
||||
'webpackCompilationPlugins option will be ignored.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +309,7 @@ class InjectManifest {
|
||||
const swAsset = compilation.getAsset(config.swDest);
|
||||
const swAssetString = swAsset.source.source();
|
||||
|
||||
const globalRegexp = new RegExp(escapeRegexp(config.injectionPoint), 'g');
|
||||
const globalRegexp = new RegExp(escapeRegExp(config.injectionPoint), 'g');
|
||||
const injectionResults = swAssetString.match(globalRegexp);
|
||||
|
||||
if (!injectionResults) {
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
*/
|
||||
|
||||
const {matchPart} = require('webpack').ModuleFilenameHelpers;
|
||||
const transformManifest = require('workbox-build/build/lib/transform-manifest');
|
||||
const {transformManifest} =
|
||||
require('workbox-build/build/lib/transform-manifest');
|
||||
|
||||
const getAssetHash = require('./get-asset-hash');
|
||||
const resolveWebpackURL = require('./resolve-webpack-url');
|
||||
|
||||
@@ -519,7 +519,7 @@ class Workbox extends WorkboxEventTarget {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
logger.log('Registered service worker now controlling this page.');
|
||||
}
|
||||
this._controllingDeferred.resolve(sw);
|
||||
this._controllingDeferred.resolve(sw!);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ describe(`[workbox-build] Test Dependencies`, function() {
|
||||
ignoreMatches: [
|
||||
'@babel/preset-env',
|
||||
'@babel/runtime',
|
||||
'type-fest',
|
||||
'workbox-background-sync',
|
||||
'workbox-broadcast-update',
|
||||
'workbox-cacheable-response',
|
||||
|
||||
@@ -6,16 +6,21 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const chai = require('chai');
|
||||
const chaiAsPromised = require('chai-as-promised');
|
||||
const fse = require('fs-extra');
|
||||
const upath = require('upath');
|
||||
const tempy = require('tempy');
|
||||
|
||||
const {errors} = require('../../../packages/workbox-build/build/lib/errors');
|
||||
const {generateSW} = require('../../../packages/workbox-build/build/generate-sw');
|
||||
const {WorkboxConfigError} = require('../../../packages/workbox-build/build/lib/validate-options');
|
||||
const confirmDirectoryContains = require('../../../infra/testing/confirm-directory-contains');
|
||||
const errors = require('../../../packages/workbox-build/src/lib/errors');
|
||||
const generateSW = require('../../../packages/workbox-build/src/generate-sw');
|
||||
const validateServiceWorkerRuntime = require('../../../infra/testing/validator/service-worker-runtime');
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
const {expect} = chai;
|
||||
|
||||
describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
const GLOB_DIR = upath.join(__dirname, '..', 'static', 'example-project-1');
|
||||
const BASE_OPTIONS = {
|
||||
@@ -64,64 +69,46 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
|
||||
describe('[workbox-build] required parameters', function() {
|
||||
for (const requiredParam of REQUIRED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${requiredParam}' is missing`, async function() {
|
||||
it(`should fail validation when '${requiredParam}' is missing`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
delete options[requiredParam];
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.key).to.eql(requiredParam);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, requiredParam);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('[workbox-build] unsupported parameters', function() {
|
||||
for (const unsupportedParam of UNSUPPORTED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${unsupportedParam}' is present`, async function() {
|
||||
it(`should fail validation when '${unsupportedParam}' is present`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
options[unsupportedParam] = unsupportedParam;
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.key).to.eql(unsupportedParam);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, unsupportedParam);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('[workbox-build] invalid parameter values', function() {
|
||||
for (const param of SUPPORTED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${param}' is null`, async function() {
|
||||
it(`should fail validation when '${param}' is an unexpected value`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
options[param] = null;
|
||||
options[param] = () => {};
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.key).to.eql(param);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, param);
|
||||
});
|
||||
}
|
||||
|
||||
it(`should reject when there are no manifest entries or runtimeCaching`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
delete options.globDirectory;
|
||||
// This temporary directory will be empty.
|
||||
options.globDirectory = tempy.directory();
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.eql(errors['no-manifest-entries-or-runtime-caching']);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
errors['no-manifest-entries-or-runtime-caching']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -362,7 +349,10 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
}, {
|
||||
url: 'webpackEntry.js',
|
||||
revision: /^[0-9a-f]{32}$/,
|
||||
}, '/one', {
|
||||
}, {
|
||||
revision: null,
|
||||
url: '/one',
|
||||
}, {
|
||||
revision: null,
|
||||
url: '/two',
|
||||
}, {
|
||||
@@ -695,12 +685,8 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
runtimeCaching: [{handler}],
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include(errors['urlPattern-is-required']);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, 'urlPattern');
|
||||
});
|
||||
|
||||
it(`should reject when 'handler' is missing from 'runtimeCaching'`, async function() {
|
||||
@@ -709,12 +695,8 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
runtimeCaching: [{urlPattern}],
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include(errors['handler-is-required']);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, 'handler');
|
||||
});
|
||||
|
||||
it(`should reject when 'handler' is not a valid strategy name`, async function() {
|
||||
@@ -726,13 +708,8 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
}],
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.key).to.eql('handler');
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, 'handler');
|
||||
});
|
||||
|
||||
// See https://github.com/GoogleChrome/workbox/issues/2078
|
||||
@@ -940,12 +917,8 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
swDest,
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include(errors['invalid-network-timeout-seconds']);
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
errors['invalid-network-timeout-seconds']);
|
||||
});
|
||||
|
||||
it(`should support 'networkTimeoutSeconds' when handler is 'NetworkFirst'`, async function() {
|
||||
@@ -1014,13 +987,8 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
}],
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.main).to.eql('expiration');
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, errors['cache-name-required']);
|
||||
});
|
||||
|
||||
it(`should ignore swDest and workbox-*.js when generating manifest entries`, async function() {
|
||||
@@ -1066,33 +1034,23 @@ describe(`[workbox-build] generate-sw.js (End to End)`, function() {
|
||||
});
|
||||
|
||||
describe(`[workbox-build] behavior with 'navigationPreload'`, function() {
|
||||
it(`should reject with a ValidationError when 'navigationPreload' is true and 'runtimeCaching' is undefined`, async function() {
|
||||
it(`should reject when 'navigationPreload' is true and 'runtimeCaching' is undefined`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS, {
|
||||
navigationPreload: true,
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.key).to.eql('runtimeCaching');
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, errors['nav-preload-runtime-caching']);
|
||||
});
|
||||
|
||||
it(`should reject with a ValidationError when 'navigationPreload' is true and 'runtimeCaching' is invalid`, async function() {
|
||||
it(`should reject when 'navigationPreload' is true and 'runtimeCaching' is undefined`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS, {
|
||||
runtimeCaching: 'invalid',
|
||||
runtimeCaching: undefined,
|
||||
navigationPreload: true,
|
||||
});
|
||||
|
||||
try {
|
||||
await generateSW(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError', error.message);
|
||||
expect(error.details[0].context.key).to.eql('runtimeCaching');
|
||||
}
|
||||
await expect(generateSW(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, errors['nav-preload-runtime-caching']);
|
||||
});
|
||||
|
||||
it(`should generate when 'navigationPreload' is true and 'runtimeCaching' is valid`, async function() {
|
||||
|
||||
@@ -7,15 +7,18 @@
|
||||
*/
|
||||
|
||||
const chai = require('chai');
|
||||
const chaiAsPromised = require('chai-as-promised');
|
||||
const chaiMatchPattern = require('chai-match-pattern');
|
||||
const fse = require('fs-extra');
|
||||
const upath = require('upath');
|
||||
const tempy = require('tempy');
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
chai.use(chaiMatchPattern);
|
||||
const {expect} = chai;
|
||||
|
||||
const getManifest = require('../../../packages/workbox-build/src/get-manifest');
|
||||
const {getManifest} = require('../../../packages/workbox-build/build/get-manifest');
|
||||
const {WorkboxConfigError} = require('../../../packages/workbox-build/build/lib/validate-options');
|
||||
|
||||
describe(`[workbox-build] get-manifest.js (End to End)`, function() {
|
||||
const SRC_DIR = upath.join(__dirname, '..', 'static', 'example-project-1');
|
||||
@@ -53,34 +56,24 @@ describe(`[workbox-build] get-manifest.js (End to End)`, function() {
|
||||
|
||||
describe('[workbox-build] unsupported parameters', function() {
|
||||
for (const unsupportedParam of UNSUPPORTED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${unsupportedParam}' is present`, async function() {
|
||||
it(`should fail validation when '${unsupportedParam}' is present`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
options[unsupportedParam] = unsupportedParam;
|
||||
|
||||
try {
|
||||
await getManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(unsupportedParam);
|
||||
}
|
||||
await expect(getManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, unsupportedParam);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('[workbox-build] invalid parameter values', function() {
|
||||
for (const param of SUPPORTED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${param}' is null`, async function() {
|
||||
it(`should fail validation when '${param}' is an unexpected value`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
options[param] = null;
|
||||
options[param] = () => {};
|
||||
|
||||
try {
|
||||
await getManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(param);
|
||||
}
|
||||
await expect(getManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, param);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -330,13 +323,8 @@ describe(`[workbox-build] get-manifest.js (End to End)`, function() {
|
||||
[option]: value,
|
||||
});
|
||||
|
||||
try {
|
||||
await getManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(option);
|
||||
}
|
||||
await expect(getManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, option);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,15 +6,20 @@
|
||||
https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const chai = require('chai');
|
||||
const chaiAsPromised = require('chai-as-promised');
|
||||
const fse = require('fs-extra');
|
||||
const upath = require('upath');
|
||||
const tempy = require('tempy');
|
||||
|
||||
const errors = require('../../../packages/workbox-build/src/lib/errors');
|
||||
const injectManifest = require('../../../packages/workbox-build/src/inject-manifest');
|
||||
const {errors} = require('../../../packages/workbox-build/build/lib/errors');
|
||||
const {injectManifest} = require('../../../packages/workbox-build/build/inject-manifest');
|
||||
const {WorkboxConfigError} = require('../../../packages/workbox-build/build/lib/validate-options');
|
||||
const validateServiceWorkerRuntime = require('../../../infra/testing/validator/service-worker-runtime');
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
const {expect} = chai;
|
||||
|
||||
describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
const GLOB_DIR = upath.join(__dirname, '..', 'static', 'example-project-1');
|
||||
const SW_SRC_DIR = upath.join(__dirname, '..', 'static', 'sw-injections');
|
||||
@@ -57,51 +62,36 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
|
||||
describe('[workbox-build] required parameters', function() {
|
||||
for (const requiredParam of REQUIRED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${requiredParam}' is missing`, async function() {
|
||||
it(`should reject when '${requiredParam}' is missing`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
delete options[requiredParam];
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(requiredParam);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, requiredParam);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('[workbox-build] unsupported parameters', function() {
|
||||
for (const unsupportedParam of UNSUPPORTED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${unsupportedParam}' is present`, async function() {
|
||||
it(`should reject when '${unsupportedParam}' is present`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
options[unsupportedParam] = unsupportedParam;
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(unsupportedParam);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, unsupportedParam);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('[workbox-build] invalid parameter values', function() {
|
||||
for (const param of SUPPORTED_PARAMS) {
|
||||
it(`should reject with a ValidationError when '${param}' is null`, async function() {
|
||||
it(`should reject when '${param}' is null`, async function() {
|
||||
const options = Object.assign({}, BASE_OPTIONS);
|
||||
options[param] = null;
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(param);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, param);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -112,12 +102,8 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
swSrc: 'DOES_NOT_EXIST',
|
||||
});
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.have.string(errors['invalid-sw-src']);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
errors['invalid-sw-src']);
|
||||
});
|
||||
|
||||
it(`should throw the expected error when there is no match for 'injectionPoint'`, async function() {
|
||||
@@ -125,12 +111,8 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
swSrc: upath.join(SW_SRC_DIR, 'bad-no-injection.js'),
|
||||
});
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.have.string(errors['injection-point-not-found']);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
errors['injection-point-not-found']);
|
||||
});
|
||||
|
||||
it(`should throw the expected error when there is no match for 'injectionPoint' and 'swSrc' and 'swDest' are the same`, async function() {
|
||||
@@ -140,12 +122,8 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
swDest: swFile,
|
||||
});
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.have.string(errors['same-src-and-dest']);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
errors['same-src-and-dest']);
|
||||
});
|
||||
|
||||
it(`should throw the expected error when there are multiple matches for 'injectionPoint'`, async function() {
|
||||
@@ -153,12 +131,8 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
swSrc: upath.join(SW_SRC_DIR, 'bad-multiple-injection.js'),
|
||||
});
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.have.string(errors['multiple-injection-points']);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
errors['multiple-injection-points']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -450,13 +424,8 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function() {
|
||||
[option]: value,
|
||||
});
|
||||
|
||||
try {
|
||||
await injectManifest(options);
|
||||
throw new Error('Unexpected success.');
|
||||
} catch (error) {
|
||||
expect(error.name).to.eql('ValidationError');
|
||||
expect(error.details[0].context.key).to.eql(option);
|
||||
}
|
||||
await expect(injectManifest(options)).to.eventually.be.rejectedWith(
|
||||
WorkboxConfigError, option);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
|
||||
const errors = require('../../../../packages/workbox-build/src/lib/errors');
|
||||
const additionalManifestEntriesTransform = require('../../../../packages/workbox-build/src/lib/additional-manifest-entries-transform');
|
||||
const {errors} = require('../../../../packages/workbox-build/build/lib/errors');
|
||||
const {additionalManifestEntriesTransform} = require('../../../../packages/workbox-build/build/lib/additional-manifest-entries-transform');
|
||||
|
||||
describe(`[workbox-build] lib/additional-manifest-entries-transform.js`, function() {
|
||||
describe(`[workbox-build] lib/additional-manifest-entries-transform`, function() {
|
||||
function getManifest() {
|
||||
return [{
|
||||
url: '/first',
|
||||
@@ -36,8 +36,8 @@ describe(`[workbox-build] lib/additional-manifest-entries-transform.js`, functio
|
||||
expect(transform(getManifest())).to.eql({
|
||||
manifest: [
|
||||
{url: '/first', revision: null},
|
||||
{url: '/second', revision: null},
|
||||
{url: '/third', revision: null},
|
||||
{url: '/second', size: 0, revision: null},
|
||||
{url: '/third', size: 0, revision: null},
|
||||
],
|
||||
warnings: [],
|
||||
});
|
||||
@@ -52,8 +52,8 @@ describe(`[workbox-build] lib/additional-manifest-entries-transform.js`, functio
|
||||
expect(transform(getManifest())).to.eql({
|
||||
manifest: [
|
||||
{url: '/first', revision: null},
|
||||
'/second',
|
||||
{url: '/third'},
|
||||
{url: '/second', size: 0, revision: null},
|
||||
{url: '/third', size: 0},
|
||||
],
|
||||
warnings: [errors['string-entry-warning'] + '\n - /second\n - /third\n'],
|
||||
});
|
||||
|
||||
@@ -10,8 +10,8 @@ const expect = require('chai').expect;
|
||||
const proxyquire = require('proxyquire');
|
||||
const sinon = require('sinon');
|
||||
|
||||
describe(`[workbox-build] lib/bundle.js`, function() {
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/src/lib/bundle';
|
||||
describe(`[workbox-build] lib/bundle`, function() {
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/build/lib/bundle';
|
||||
let bundle;
|
||||
let stubs;
|
||||
|
||||
@@ -19,16 +19,16 @@ describe(`[workbox-build] lib/bundle.js`, function() {
|
||||
const rollupStub = {
|
||||
generate: sinon.stub().resolves({output: [{
|
||||
fileName: 'asset-filename',
|
||||
isAsset: true,
|
||||
type: 'asset',
|
||||
source: 'asset-source',
|
||||
}, {
|
||||
code: 'chunk1-code',
|
||||
fileName: 'chunk1-filename',
|
||||
isAsset: false,
|
||||
type: 'chunk',
|
||||
}, {
|
||||
code: 'chunk2-code',
|
||||
fileName: 'chunk2-filename',
|
||||
isAsset: false,
|
||||
type: 'chunk',
|
||||
map: 'sourcemap-contents',
|
||||
}]}),
|
||||
};
|
||||
@@ -40,6 +40,7 @@ describe(`[workbox-build] lib/bundle.js`, function() {
|
||||
writeFile: sinon.stub().resolves(),
|
||||
},
|
||||
'upath': {
|
||||
format: sinon.stub().callsFake((args) => `${args.dir}${args.base}`),
|
||||
parse: sinon.stub().returns({base: 'sw.js', dir: ''}),
|
||||
},
|
||||
'tempy': {
|
||||
@@ -47,7 +48,9 @@ describe(`[workbox-build] lib/bundle.js`, function() {
|
||||
},
|
||||
'@rollup/plugin-node-resolve': sinon.stub(),
|
||||
'@rollup/plugin-replace': sinon.stub(),
|
||||
'@rollup/plugin-babel': {babel: sinon.stub()},
|
||||
'@rollup/plugin-babel': {
|
||||
babel: sinon.stub(),
|
||||
},
|
||||
'rollup-plugin-terser': {
|
||||
terser: sinon.stub(),
|
||||
},
|
||||
@@ -57,7 +60,7 @@ describe(`[workbox-build] lib/bundle.js`, function() {
|
||||
},
|
||||
};
|
||||
|
||||
bundle = proxyquire(MODULE_PATH, stubs);
|
||||
bundle = proxyquire(MODULE_PATH, stubs).bundle;
|
||||
});
|
||||
|
||||
it(`should pass 'babelPresetEnvTargets' to @babel/preset-env`, async function() {
|
||||
@@ -67,17 +70,9 @@ describe(`[workbox-build] lib/bundle.js`, function() {
|
||||
babelPresetEnvTargets,
|
||||
});
|
||||
|
||||
expect(stubs['@rollup/plugin-babel'].babel.args).to.eql([[{
|
||||
babelHelpers: 'bundled',
|
||||
babelrc: false,
|
||||
configFile: false,
|
||||
presets: [[stubs['@babel/preset-env'], {
|
||||
targets: {
|
||||
browsers: babelPresetEnvTargets,
|
||||
},
|
||||
loose: true,
|
||||
}]],
|
||||
}]]);
|
||||
// This is ugly, but necessary due to the way babel() is configured.
|
||||
const babelParams = stubs['@rollup/plugin-babel'].babel.args[0][0];
|
||||
expect(babelParams.presets[0][1].targets.browsers).to.eql(babelPresetEnvTargets);
|
||||
});
|
||||
|
||||
it(`should use loadz0r and configure manualChunks when 'inlineWorkboxRuntime' is false`, async function() {
|
||||
|
||||
@@ -8,17 +8,12 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
|
||||
const cdnUtils = require('../../../../packages/workbox-build/src/lib/cdn-utils');
|
||||
const errors = require('../../../../packages/workbox-build/src/lib/errors');
|
||||
const cdnUtils = require('../../../../packages/workbox-build/build/lib/cdn-utils');
|
||||
const {errors} = require('../../../../packages/workbox-build/build/lib/errors');
|
||||
|
||||
describe(`[workbox-build] lib/cdn-utils.js`, function() {
|
||||
const CDN_ORIGIN = 'https://storage.googleapis.com/workbox-cdn/releases';
|
||||
|
||||
it(`getCDNOrigin() should return the expected base URL`, function() {
|
||||
const url = cdnUtils.getCDNOrigin();
|
||||
expect(url).to.eql(CDN_ORIGIN);
|
||||
});
|
||||
|
||||
it(`getModuleURL() should throw when moduleName is undefined`, function() {
|
||||
expect(
|
||||
() => cdnUtils.getModuleURL(),
|
||||
|
||||
@@ -11,18 +11,18 @@ const upath = require('upath');
|
||||
const proxyquire = require('proxyquire');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const errors = require('../../../../packages/workbox-build/src/lib/errors');
|
||||
const {errors} = require('../../../../packages/workbox-build/build/lib/errors');
|
||||
|
||||
describe(`[workbox-build] lib/copy-workbox-libraries.js`, function() {
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/src/lib/copy-workbox-libraries';
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/build/lib/copy-workbox-libraries';
|
||||
const ABSOLUTE_DEST_DIRECTORY = upath.join('/', 'test-dir');
|
||||
const RELATIVE_DEST_DIRECTORY = upath.join('.', 'test-dir');
|
||||
|
||||
it(`should reject with an error when the copy fails`, async function() {
|
||||
const copyWorkboxLibraries = proxyquire(MODULE_PATH, {
|
||||
const {copyWorkboxLibraries} = proxyquire(MODULE_PATH, {
|
||||
'fs-extra': {
|
||||
ensureDir: sinon.stub().resolves(),
|
||||
copy: sinon.stub().rejects(),
|
||||
copy: sinon.stub().rejects('INJECTED_ERROR'),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -39,7 +39,7 @@ describe(`[workbox-build] lib/copy-workbox-libraries.js`, function() {
|
||||
const copyStub = sinon.stub().resolves();
|
||||
const ensureDirStub = sinon.stub().resolves();
|
||||
|
||||
const copyWorkboxLibraries = proxyquire(MODULE_PATH, {
|
||||
const {copyWorkboxLibraries} = proxyquire(MODULE_PATH, {
|
||||
'fs-extra': {
|
||||
copy: copyStub,
|
||||
ensureDir: ensureDirStub,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const escapeRegexp = require('../../../../packages/workbox-build/src/lib/escape-regexp');
|
||||
const {escapeRegExp} = require('../../../../packages/workbox-build/build/lib/escape-regexp');
|
||||
|
||||
describe(`[workbox-build] lib/copy-workbox-libraries.js`, function() {
|
||||
const expectedValues = new Map([
|
||||
@@ -19,7 +19,7 @@ describe(`[workbox-build] lib/copy-workbox-libraries.js`, function() {
|
||||
|
||||
for (const [original, escaped] of expectedValues) {
|
||||
it(`should perform the expected escaping: ${original} => ${escaped}`, async function() {
|
||||
expect(escapeRegexp(original)).to.eql(escaped);
|
||||
expect(escapeRegExp(original)).to.eql(escaped);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
|
||||
const getCompositeDetails = require('../../../../packages/workbox-build/src/lib/get-composite-details');
|
||||
const {getCompositeDetails} = require('../../../../packages/workbox-build/build/lib/get-composite-details');
|
||||
|
||||
describe(`[workbox-build] lib/get-composite-details.js`, function() {
|
||||
const URL = '/test';
|
||||
|
||||
@@ -10,10 +10,10 @@ const expect = require('chai').expect;
|
||||
const upath = require('upath');
|
||||
const proxyquire = require('proxyquire');
|
||||
|
||||
const errors = require('../../../../packages/workbox-build/src/lib/errors');
|
||||
const {errors} = require('../../../../packages/workbox-build/build/lib/errors');
|
||||
|
||||
describe(`[workbox-build] lib/get-file-details.js`, function() {
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/src/lib/get-file-details';
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/build/lib/get-file-details';
|
||||
const GLOB_DIRECTORY = './';
|
||||
const GLOB_PATTERN = 'file*';
|
||||
const DIRECTORY = 'directory';
|
||||
@@ -23,7 +23,7 @@ describe(`[workbox-build] lib/get-file-details.js`, function() {
|
||||
const HASH = 'example-hash';
|
||||
|
||||
it(`should throw when there's a glob.sync() error`, function() {
|
||||
const getFileDetails = proxyquire(MODULE_PATH, {
|
||||
const {getFileDetails} = proxyquire(MODULE_PATH, {
|
||||
glob: {
|
||||
sync: () => {
|
||||
throw new Error();
|
||||
@@ -43,7 +43,7 @@ describe(`[workbox-build] lib/get-file-details.js`, function() {
|
||||
});
|
||||
|
||||
it(`should return a warning when the pattern doesn't match anything`, function() {
|
||||
const getFileDetails = proxyquire(MODULE_PATH, {
|
||||
const {getFileDetails} = proxyquire(MODULE_PATH, {
|
||||
glob: {
|
||||
sync: () => [],
|
||||
},
|
||||
@@ -58,23 +58,27 @@ describe(`[workbox-build] lib/get-file-details.js`, function() {
|
||||
});
|
||||
|
||||
it(`should return array of file details, without null values`, function() {
|
||||
const getFileDetails = proxyquire(MODULE_PATH, {
|
||||
const {getFileDetails} = proxyquire(MODULE_PATH, {
|
||||
'glob': {
|
||||
sync: () => {
|
||||
return [FILE1, FILE2, DIRECTORY];
|
||||
},
|
||||
},
|
||||
'./get-file-size': (value) => {
|
||||
if (upath.normalize(value) === upath.normalize(DIRECTORY)) {
|
||||
return null;
|
||||
}
|
||||
return SIZE;
|
||||
'./get-file-size': {
|
||||
getFileSize: (value) => {
|
||||
if (upath.normalize(value) === upath.normalize(DIRECTORY)) {
|
||||
return null;
|
||||
}
|
||||
return SIZE;
|
||||
},
|
||||
},
|
||||
'./get-file-hash': (value) => {
|
||||
if (upath.normalize(value) === upath.normalize(DIRECTORY)) {
|
||||
throw new Error(`getFileHash(${DIRECTORY}) shouldn't have been called.`);
|
||||
}
|
||||
return HASH;
|
||||
'./get-file-hash': {
|
||||
getFileHash: (value) => {
|
||||
if (upath.normalize(value) === upath.normalize(DIRECTORY)) {
|
||||
throw new Error(`getFileHash(${DIRECTORY}) shouldn't have been called.`);
|
||||
}
|
||||
return HASH;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -83,7 +87,7 @@ describe(`[workbox-build] lib/get-file-details.js`, function() {
|
||||
globPattern: GLOB_PATTERN,
|
||||
});
|
||||
|
||||
expect(warning).to.be.undefined;
|
||||
expect(warning).to.eql('');
|
||||
expect(globbedFileDetails).to.deep.equal([{
|
||||
file: FILE1,
|
||||
hash: HASH,
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
const expect = require('chai').expect;
|
||||
const proxyquire = require('proxyquire');
|
||||
|
||||
const errors = require('../../../../packages/workbox-build/src/lib/errors');
|
||||
const {errors} = require('../../../../packages/workbox-build/build/lib/errors');
|
||||
|
||||
describe(`[workbox-build] lib/get-file-hash.js`, function() {
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/src/lib/get-file-hash';
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/build/lib/get-file-hash';
|
||||
const FILE = 'file.txt';
|
||||
|
||||
it(`should throw when there's a fs.readFileSync() error`, function() {
|
||||
const getFileHash = proxyquire(MODULE_PATH, {
|
||||
fs: {
|
||||
const {getFileHash} = proxyquire(MODULE_PATH, {
|
||||
'fs-extra': {
|
||||
readFileSync: () => {
|
||||
throw new Error();
|
||||
},
|
||||
@@ -36,8 +36,8 @@ describe(`[workbox-build] lib/get-file-hash.js`, function() {
|
||||
const buffer = Buffer.alloc(10);
|
||||
const hashForBuffer = 'a63c90cc3684ad8b0a2176a6a8fe9005';
|
||||
|
||||
const getFileHash = proxyquire(MODULE_PATH, {
|
||||
fs: {
|
||||
const {getFileHash} = proxyquire(MODULE_PATH, {
|
||||
'fs-extra': {
|
||||
readFileSync: (file) => {
|
||||
if (file !== FILE) {
|
||||
throw new Error(`Unexpected file name: ${file}`);
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
const expect = require('chai').expect;
|
||||
const proxyquire = require('proxyquire');
|
||||
|
||||
const errors = require('../../../../packages/workbox-build/src/lib/errors');
|
||||
const {errors} = require('../../../../packages/workbox-build/build/lib/errors');
|
||||
|
||||
describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/src/lib/get-file-manifest-entries';
|
||||
const MODULE_PATH = '../../../../packages/workbox-build/build/lib/get-file-manifest-entries';
|
||||
const GLOB_DIRECTORY = './';
|
||||
const GLOB_PATTERNS = ['invalid*'];
|
||||
const FILE = {
|
||||
@@ -22,7 +22,7 @@ describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
};
|
||||
|
||||
it(`should return empty info when neither globDirectory nor templatedURLs are provided`, async function() {
|
||||
const getFileManifestEntries = require(MODULE_PATH);
|
||||
const {getFileManifestEntries} = require(MODULE_PATH);
|
||||
|
||||
const {count, size, manifestEntries} = await getFileManifestEntries({});
|
||||
|
||||
@@ -32,12 +32,14 @@ describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
});
|
||||
|
||||
it(`should not return the same file twice`, async function() {
|
||||
const getFileManifestEntries = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': () => {
|
||||
return {
|
||||
globbedFileDetails: [FILE, FILE],
|
||||
warning: undefined,
|
||||
};
|
||||
const {getFileManifestEntries} = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': {
|
||||
getFileDetails: () => {
|
||||
return {
|
||||
globbedFileDetails: [FILE, FILE],
|
||||
warning: undefined,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -55,12 +57,14 @@ describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
});
|
||||
|
||||
it(`should throw when a templatedURL matches a globbed file`, async function() {
|
||||
const getFileManifestEntries = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': () => {
|
||||
return {
|
||||
globbedFileDetails: [FILE],
|
||||
warning: undefined,
|
||||
};
|
||||
const {getFileManifestEntries} = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': {
|
||||
getFileDetails: () => {
|
||||
return {
|
||||
globbedFileDetails: [FILE],
|
||||
warning: undefined,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -80,9 +84,11 @@ describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
|
||||
it(`should treat an exception thrown by getFileDetails() as a warning message`, async function() {
|
||||
const warningMessage = 'test warning';
|
||||
const getFileManifestEntries = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': () => {
|
||||
throw new Error(warningMessage);
|
||||
const {getFileManifestEntries} = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': {
|
||||
getFileDetails: () => {
|
||||
throw new Error(warningMessage);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -98,10 +104,11 @@ describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
});
|
||||
|
||||
it(`should throw when a templatedURL contains a pattern that doesn't match anything`, async function() {
|
||||
const getFileManifestEntries = require(MODULE_PATH);
|
||||
const {getFileManifestEntries} = require(MODULE_PATH);
|
||||
|
||||
try {
|
||||
await getFileManifestEntries({
|
||||
globDirectory: GLOB_DIRECTORY,
|
||||
templatedURLs: {
|
||||
[FILE.file]: GLOB_PATTERNS,
|
||||
},
|
||||
@@ -117,12 +124,14 @@ describe(`[workbox-build] Test getFileManifestEntries`, function() {
|
||||
const url2 = '/path/to/url2';
|
||||
const stringValue = 'string';
|
||||
|
||||
const getFileManifestEntries = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': () => {
|
||||
return {
|
||||
globbedFileDetails: [FILE],
|
||||
warning: undefined,
|
||||
};
|
||||
const {getFileManifestEntries} = proxyquire(MODULE_PATH, {
|
||||
'./get-file-details': {
|
||||
getFileDetails: () => {
|
||||
return {
|
||||
globbedFileDetails: [FILE],
|
||||
warning: undefined,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user