You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
6.8 KiB
147 lines
6.8 KiB
"use strict"; |
|
/* |
|
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. |
|
*/ |
|
var __importDefault = (this && this.__importDefault) || function (mod) { |
|
return (mod && mod.__esModule) ? mod : { "default": mod }; |
|
}; |
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
exports.validateWebpackInjectManifestOptions = exports.validateWebpackGenerateSWOptions = exports.validateInjectManifestOptions = exports.validateGetManifestOptions = exports.validateGenerateSWOptions = exports.WorkboxConfigError = void 0; |
|
const better_ajv_errors_1 = require("@apideck/better-ajv-errors"); |
|
const common_tags_1 = require("common-tags"); |
|
const ajv_1 = __importDefault(require("ajv")); |
|
const errors_1 = require("./errors"); |
|
const ajv = new ajv_1.default({ |
|
useDefaults: true, |
|
}); |
|
const DEFAULT_EXCLUDE_VALUE = [/\.map$/, /^manifest.*\.js$/]; |
|
class WorkboxConfigError extends Error { |
|
constructor(message) { |
|
super(message); |
|
Object.setPrototypeOf(this, new.target.prototype); |
|
} |
|
} |
|
exports.WorkboxConfigError = WorkboxConfigError; |
|
// Some methods need to do follow-up validation using the JSON schema, |
|
// so return both the validated options and then schema. |
|
function validate(input, methodName) { |
|
// Don't mutate input: https://github.com/GoogleChrome/workbox/issues/2158 |
|
const inputCopy = Object.assign({}, input); |
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment |
|
const jsonSchema = require(`../schema/${methodName}Options.json`); |
|
const validate = ajv.compile(jsonSchema); |
|
if (validate(inputCopy)) { |
|
// All methods support manifestTransforms, so validate it here. |
|
ensureValidManifestTransforms(inputCopy); |
|
return [inputCopy, jsonSchema]; |
|
} |
|
const betterErrors = (0, better_ajv_errors_1.betterAjvErrors)({ |
|
basePath: methodName, |
|
data: input, |
|
errors: validate.errors, |
|
// This is needed as JSONSchema6 is expected, but JSONSchemaType works. |
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment |
|
schema: jsonSchema, |
|
}); |
|
const messages = betterErrors.map((err) => (0, common_tags_1.oneLine) `[${err.path}] ${err.message}. |
|
${err.suggestion ? err.suggestion : ''}`); |
|
throw new WorkboxConfigError(messages.join('\n\n')); |
|
} |
|
function ensureValidManifestTransforms(options) { |
|
if ('manifestTransforms' in options && |
|
!(Array.isArray(options.manifestTransforms) && |
|
options.manifestTransforms.every((item) => typeof item === 'function'))) { |
|
throw new WorkboxConfigError(errors_1.errors['manifest-transforms']); |
|
} |
|
} |
|
function ensureValidNavigationPreloadConfig(options) { |
|
if (options.navigationPreload && |
|
(!Array.isArray(options.runtimeCaching) || |
|
options.runtimeCaching.length === 0)) { |
|
throw new WorkboxConfigError(errors_1.errors['nav-preload-runtime-caching']); |
|
} |
|
} |
|
function ensureValidCacheExpiration(options) { |
|
var _a, _b; |
|
for (const runtimeCaching of options.runtimeCaching || []) { |
|
if (((_a = runtimeCaching.options) === null || _a === void 0 ? void 0 : _a.expiration) && |
|
!((_b = runtimeCaching.options) === null || _b === void 0 ? void 0 : _b.cacheName)) { |
|
throw new WorkboxConfigError(errors_1.errors['cache-name-required']); |
|
} |
|
} |
|
} |
|
function ensureValidRuntimeCachingOrGlobDirectory(options) { |
|
if (!options.globDirectory && |
|
(!Array.isArray(options.runtimeCaching) || |
|
options.runtimeCaching.length === 0)) { |
|
throw new WorkboxConfigError(errors_1.errors['no-manifest-entries-or-runtime-caching']); |
|
} |
|
} |
|
// This is... messy, because we can't rely on the built-in ajv validation for |
|
// runtimeCaching.handler, as it needs to accept {} (i.e. any) due to |
|
// https://github.com/GoogleChrome/workbox/pull/2899 |
|
// So we need to perform validation when a string (not a function) is used. |
|
function ensureValidStringHandler(options, jsonSchema) { |
|
var _a, _b, _c, _d; |
|
let validHandlers = []; |
|
/* eslint-disable */ |
|
for (const handler of ((_d = (_c = (_b = (_a = jsonSchema.definitions) === null || _a === void 0 ? void 0 : _a.RuntimeCaching) === null || _b === void 0 ? void 0 : _b.properties) === null || _c === void 0 ? void 0 : _c.handler) === null || _d === void 0 ? void 0 : _d.anyOf) || []) { |
|
if ('enum' in handler) { |
|
validHandlers = handler.enum; |
|
break; |
|
} |
|
} |
|
/* eslint-enable */ |
|
for (const runtimeCaching of options.runtimeCaching || []) { |
|
if (typeof runtimeCaching.handler === 'string' && |
|
!validHandlers.includes(runtimeCaching.handler)) { |
|
throw new WorkboxConfigError(errors_1.errors['invalid-handler-string'] + runtimeCaching.handler); |
|
} |
|
} |
|
} |
|
function validateGenerateSWOptions(input) { |
|
const [validatedOptions, jsonSchema] = validate(input, 'GenerateSW'); |
|
ensureValidNavigationPreloadConfig(validatedOptions); |
|
ensureValidCacheExpiration(validatedOptions); |
|
ensureValidRuntimeCachingOrGlobDirectory(validatedOptions); |
|
ensureValidStringHandler(validatedOptions, jsonSchema); |
|
return validatedOptions; |
|
} |
|
exports.validateGenerateSWOptions = validateGenerateSWOptions; |
|
function validateGetManifestOptions(input) { |
|
const [validatedOptions] = validate(input, 'GetManifest'); |
|
return validatedOptions; |
|
} |
|
exports.validateGetManifestOptions = validateGetManifestOptions; |
|
function validateInjectManifestOptions(input) { |
|
const [validatedOptions] = validate(input, 'InjectManifest'); |
|
return validatedOptions; |
|
} |
|
exports.validateInjectManifestOptions = validateInjectManifestOptions; |
|
// The default `exclude: [/\.map$/, /^manifest.*\.js$/]` value can't be |
|
// represented in the JSON schema, so manually set it for the webpack options. |
|
function validateWebpackGenerateSWOptions(input) { |
|
const inputWithExcludeDefault = Object.assign({ |
|
// Make a copy, as exclude can be mutated when used. |
|
exclude: Array.from(DEFAULT_EXCLUDE_VALUE), |
|
}, input); |
|
const [validatedOptions, jsonSchema] = validate(inputWithExcludeDefault, 'WebpackGenerateSW'); |
|
ensureValidNavigationPreloadConfig(validatedOptions); |
|
ensureValidCacheExpiration(validatedOptions); |
|
ensureValidStringHandler(validatedOptions, jsonSchema); |
|
return validatedOptions; |
|
} |
|
exports.validateWebpackGenerateSWOptions = validateWebpackGenerateSWOptions; |
|
function validateWebpackInjectManifestOptions(input) { |
|
const inputWithExcludeDefault = Object.assign({ |
|
// Make a copy, as exclude can be mutated when used. |
|
exclude: Array.from(DEFAULT_EXCLUDE_VALUE), |
|
}, input); |
|
const [validatedOptions] = validate(inputWithExcludeDefault, 'WebpackInjectManifest'); |
|
return validatedOptions; |
|
} |
|
exports.validateWebpackInjectManifestOptions = validateWebpackInjectManifestOptions;
|
|
|