mirror of
https://github.com/Sevichecc/Urara-Blog.git
synced 2025-05-20 18:49:13 +08:00
215 lines
6.1 KiB
Text
215 lines
6.1 KiB
Text
/*
|
|
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.
|
|
*/
|
|
|
|
import {oneLine as ol} from 'common-tags';
|
|
|
|
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
|
|
* to the equivalent Workbox method calls.
|
|
*
|
|
* @param {ModuleRegistry} moduleRegistry
|
|
* @param {Object} options See
|
|
* https://developers.google.com/web/tools/workbox/modules/workbox-build#generateSW-runtimeCaching
|
|
* @return {string} A JSON string representing the equivalent options.
|
|
*
|
|
* @private
|
|
*/
|
|
function getOptionsString(
|
|
moduleRegistry: ModuleRegistry,
|
|
options: RuntimeCaching['options'] = {},
|
|
) {
|
|
const plugins: Array<string> = [];
|
|
const handlerOptions: {[key in keyof typeof options]: any} = {};
|
|
|
|
for (const optionName of Object.keys(options) as Array<
|
|
keyof typeof options
|
|
>) {
|
|
if (options[optionName] === undefined) {
|
|
continue;
|
|
}
|
|
|
|
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 = options.backgroundSync!.name;
|
|
const plugin = moduleRegistry.use(
|
|
'workbox-background-sync',
|
|
'BackgroundSyncPlugin',
|
|
);
|
|
|
|
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 = options.broadcastUpdate!.channelName;
|
|
const opts = Object.assign(
|
|
{channelName},
|
|
options.broadcastUpdate!.options,
|
|
);
|
|
const plugin = moduleRegistry.use(
|
|
'workbox-broadcast-update',
|
|
'BroadcastUpdatePlugin',
|
|
);
|
|
|
|
plugins.push(`new ${plugin}(${stringifyWithoutComments(opts)})`);
|
|
break;
|
|
}
|
|
|
|
case 'cacheableResponse': {
|
|
const plugin = moduleRegistry.use(
|
|
'workbox-cacheable-response',
|
|
'CacheableResponsePlugin',
|
|
);
|
|
|
|
plugins.push(
|
|
`new ${plugin}(${stringifyWithoutComments(
|
|
options.cacheableResponse!,
|
|
)})`,
|
|
);
|
|
break;
|
|
}
|
|
|
|
case 'expiration': {
|
|
const plugin = moduleRegistry.use(
|
|
'workbox-expiration',
|
|
'ExpirationPlugin',
|
|
);
|
|
|
|
plugins.push(
|
|
`new ${plugin}(${stringifyWithoutComments(options.expiration!)})`,
|
|
);
|
|
break;
|
|
}
|
|
|
|
case 'precacheFallback': {
|
|
const plugin = moduleRegistry.use(
|
|
'workbox-precaching',
|
|
'PrecacheFallbackPlugin',
|
|
);
|
|
|
|
plugins.push(
|
|
`new ${plugin}(${stringifyWithoutComments(
|
|
options.precacheFallback!,
|
|
)})`,
|
|
);
|
|
break;
|
|
}
|
|
|
|
case 'rangeRequests': {
|
|
const plugin = moduleRegistry.use(
|
|
'workbox-range-requests',
|
|
'RangeRequestsPlugin',
|
|
);
|
|
|
|
// There are no configuration options for the constructor.
|
|
plugins.push(`new ${plugin}()`);
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
throw new Error(
|
|
// In the default case optionName is typed as 'never'.
|
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
`${errors['bad-runtime-caching-config']} ${optionName}`,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Object.keys(handlerOptions).length > 0 || plugins.length > 0) {
|
|
const optionsString = JSON.stringify(handlerOptions).slice(1, -1);
|
|
return ol`{
|
|
${optionsString ? optionsString + ',' : ''}
|
|
plugins: [${plugins.join(', ')}]
|
|
}`;
|
|
} else {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
export function runtimeCachingConverter(
|
|
moduleRegistry: ModuleRegistry,
|
|
runtimeCaching: Array<RuntimeCaching>,
|
|
): Array<string> {
|
|
return runtimeCaching
|
|
.map((entry) => {
|
|
const method = entry.method || 'GET';
|
|
|
|
if (!entry.urlPattern) {
|
|
throw new Error(errors['urlPattern-is-required']);
|
|
}
|
|
|
|
if (!entry.handler) {
|
|
throw new Error(errors['handler-is-required']);
|
|
}
|
|
|
|
if (
|
|
entry.options &&
|
|
entry.options.networkTimeoutSeconds &&
|
|
entry.handler !== 'NetworkFirst'
|
|
) {
|
|
throw new Error(errors['invalid-network-timeout-seconds']);
|
|
}
|
|
|
|
// urlPattern might be a string, a RegExp object, or a function.
|
|
// If it's a string, it needs to be quoted.
|
|
const matcher =
|
|
typeof entry.urlPattern === 'string'
|
|
? JSON.stringify(entry.urlPattern)
|
|
: entry.urlPattern;
|
|
|
|
const registerRoute = moduleRegistry.use(
|
|
'workbox-routing',
|
|
'registerRoute',
|
|
);
|
|
if (typeof entry.handler === 'string') {
|
|
const optionsString = getOptionsString(moduleRegistry, entry.options);
|
|
const handler = moduleRegistry.use('workbox-strategies', entry.handler);
|
|
const strategyString = `new ${handler}(${optionsString})`;
|
|
|
|
return `${registerRoute}(${matcher.toString()}, ${strategyString}, '${method}');\n`;
|
|
} else if (typeof entry.handler === 'function') {
|
|
return `${registerRoute}(${matcher.toString()}, ${entry.handler.toString()}, '${method}');\n`;
|
|
}
|
|
|
|
// '' will be filtered out.
|
|
return '';
|
|
})
|
|
.filter((entry) => Boolean(entry));
|
|
}
|