From 97fc6468c2b45b3b000224565f5be6f908db9067 Mon Sep 17 00:00:00 2001 From: Jeffrey Posnick Date: Wed, 13 Oct 2021 13:36:31 -0400 Subject: [PATCH] Treat a missing sourcemap as a warning (#2959) * Missing sourcemap warning * Linting --- packages/workbox-build/src/inject-manifest.ts | 40 ++++----- .../lib/translate-url-to-sourcemap-paths.ts | 38 ++++++++ test/workbox-build/node/inject-manifest.js | 22 +++++ .../lib/translate-url-to-sourcemap-paths.js | 87 +++++++++++++++++++ .../basic-with-invalid-sourcemap.js.nolint | 2 + 5 files changed, 168 insertions(+), 21 deletions(-) create mode 100644 packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts create mode 100644 test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js create mode 100644 test/workbox-build/static/sw-injections/basic-with-invalid-sourcemap.js.nolint diff --git a/packages/workbox-build/src/inject-manifest.ts b/packages/workbox-build/src/inject-manifest.ts index 45d5af249..081f77869 100644 --- a/packages/workbox-build/src/inject-manifest.ts +++ b/packages/workbox-build/src/inject-manifest.ts @@ -19,6 +19,7 @@ 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 {translateURLToSourcemapPaths} from './lib/translate-url-to-sourcemap-paths'; import {validateInjectManifestOptions} from './lib/validate-options'; // eslint-disable-next-line jsdoc/newline-after-description @@ -162,31 +163,28 @@ export async function injectManifest(config: unknown): Promise { const manifestString = stringify(manifestEntries); const filesToWrite: {[key: string]: string} = {}; - // sourceMapURL returns value type any and could be null. - // url is checked before it is used later. - const url: string = sourceMapURL.getFrom(swFileContents); // eslint-disable-line + + const url = sourceMapURL.getFrom(swFileContents) as string; // eslint-disable-line + // See https://github.com/GoogleChrome/workbox/issues/2957 + const {destPath, srcPath, warning} = translateURLToSourcemapPaths( + url, + options.swSrc, + options.swDest, + ); + if (warning) { + warnings.push(warning); + } + // 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 // (assuming it's a real file, not a data: URL) at the same time. // See https://github.com/GoogleChrome/workbox/issues/2235 // and https://github.com/GoogleChrome/workbox/issues/2648 - if (url && !url.startsWith('data:')) { - const sourcemapSrcPath = upath.resolve(upath.dirname(options.swSrc), url); - const sourcemapDestPath = upath.resolve(upath.dirname(options.swDest), url); - - let originalMap: RawSourceMap; - try { - // readJSON returns Promise. - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - originalMap = await fse.readJSON(sourcemapSrcPath, {encoding: 'utf8'}); - } catch (error) { - throw new Error( - `${errors['cant-find-sourcemap']} ${ - error instanceof Error && error.message ? error.message : '' - }`, - ); - } + if (srcPath && destPath) { + const originalMap = (await fse.readJSON(srcPath, { + encoding: 'utf8', + })) as RawSourceMap; const {map, source} = await replaceAndUpdateSourceMap({ originalMap, @@ -197,7 +195,7 @@ export async function injectManifest(config: unknown): Promise { }); filesToWrite[options.swDest] = source; - filesToWrite[sourcemapDestPath] = map; + filesToWrite[destPath] = map; } else { // If there's no sourcemap associated with swSrc, a simple string // replacement will suffice. @@ -210,7 +208,7 @@ export async function injectManifest(config: unknown): Promise { for (const [file, contents] of Object.entries(filesToWrite)) { try { await fse.mkdirp(upath.dirname(file)); - } catch (error) { + } catch (error: unknown) { throw new Error( errors['unable-to-make-sw-directory'] + ` '${error instanceof Error && error.message ? error.message : ''}'`, diff --git a/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts b/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts new file mode 100644 index 000000000..ec5d37945 --- /dev/null +++ b/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts @@ -0,0 +1,38 @@ +/* + 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 fse from 'fs-extra'; +import upath from 'upath'; + +import {errors} from './errors'; + +export function translateURLToSourcemapPaths( + url: string, + swSrc: string, + swDest: string, +): { + destPath: string | undefined; + srcPath: string | undefined; + warning: string | undefined; +} { + let destPath: string | undefined = undefined; + let srcPath: string | undefined = undefined; + let warning: string | undefined = undefined; + + if (url && !url.startsWith('data:')) { + const possibleSrcPath = upath.resolve(upath.dirname(swSrc), url); + if (fse.existsSync(possibleSrcPath)) { + srcPath = possibleSrcPath; + destPath = upath.resolve(upath.dirname(swDest), url); + } else { + warning = `${errors['cant-find-sourcemap']} ${possibleSrcPath}`; + } + } + + return {destPath, srcPath, warning}; +} diff --git a/test/workbox-build/node/inject-manifest.js b/test/workbox-build/node/inject-manifest.js index aa3479ce7..907e5c4ff 100644 --- a/test/workbox-build/node/inject-manifest.js +++ b/test/workbox-build/node/inject-manifest.js @@ -482,6 +482,28 @@ describe(`[workbox-build] inject-manifest.js (End to End)`, function () { // We can't validate the SW file contents. }); + + it(`should perform injection, but report a warning if the sourcemap file can't be found`, async function () { + const outputDir = tempy.directory(); + const swSrc = upath.join( + SW_SRC_DIR, + 'basic-with-invalid-sourcemap.js.nolint', + ); + const swDest = upath.join(outputDir, 'basic-with-sourcemap.js'); + const options = Object.assign({}, BASE_OPTIONS, { + swDest, + swSrc, + }); + + const {count, size, warnings} = await injectManifest(options); + expect(warnings.length).to.eql(1); + expect(warnings[0]).to.include(errors['cant-find-sourcemap']); + expect(count).to.eql(6); + // Line ending differences lead to different sizes on Windows. + expect(size).to.be.oneOf([2782, 2698]); + + // We can't validate the SW file contents. + }); }); describe(`[workbox-build] removed options`, function () { diff --git a/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js b/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js new file mode 100644 index 000000000..dc0f60701 --- /dev/null +++ b/test/workbox-build/node/lib/translate-url-to-sourcemap-paths.js @@ -0,0 +1,87 @@ +/* + 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 expect = require('chai').expect; +const proxyquire = require('proxyquire'); + +const {errors} = require('../../../../packages/workbox-build/build/lib/errors'); + +describe(`[workbox-build] lib/translate-url-to-sourcemap-paths.ts`, function () { + const MODULE_PATH = + '../../../../packages/workbox-build/build/lib/translate-url-to-sourcemap-paths'; + const URL = 'sw.js.map'; + const SWSRC = 'src/sw.js'; + const SWDEST = 'dist/sw.js'; + + it(`should return undefined paths when url is undefined`, function () { + const {translateURLToSourcemapPaths} = require(MODULE_PATH); + + const {destPath, srcPath, warning} = translateURLToSourcemapPaths( + undefined, + SWSRC, + SWDEST, + ); + + expect(destPath).to.be.undefined; + expect(srcPath).to.be.undefined; + expect(warning).to.be.undefined; + }); + + it(`should return undefined paths when url starts with data:`, function () { + const {translateURLToSourcemapPaths} = require(MODULE_PATH); + + const {destPath, srcPath, warning} = translateURLToSourcemapPaths( + `data:${URL}`, + SWSRC, + SWDEST, + ); + + expect(destPath).to.be.undefined; + expect(srcPath).to.be.undefined; + expect(warning).to.be.undefined; + }); + + it(`should return undefined paths and a warning when the resolved URL path doesn't exist`, function () { + const {translateURLToSourcemapPaths} = proxyquire(MODULE_PATH, { + 'fs-extra': { + existsSync: () => false, + }, + }); + + const {destPath, srcPath, warning} = translateURLToSourcemapPaths( + URL, + SWSRC, + SWDEST, + ); + + expect(destPath).to.be.undefined; + expect(srcPath).to.be.undefined; + expect(warning).to.include(errors['cant-find-sourcemap']); + }); + + it(`should return valid paths and no warning when the resolved URL path exists`, function () { + const {translateURLToSourcemapPaths} = proxyquire(MODULE_PATH, { + 'fs-extra': { + existsSync: () => true, + }, + 'upath': { + resolve: (...args) => args.join('/'), + }, + }); + + const {destPath, srcPath, warning} = translateURLToSourcemapPaths( + URL, + SWSRC, + SWDEST, + ); + + expect(destPath).to.eql('dist/sw.js.map'); + expect(srcPath).to.eq('src/sw.js.map'); + expect(warning).to.be.undefined; + }); +}); diff --git a/test/workbox-build/static/sw-injections/basic-with-invalid-sourcemap.js.nolint b/test/workbox-build/static/sw-injections/basic-with-invalid-sourcemap.js.nolint new file mode 100644 index 000000000..e2040d606 --- /dev/null +++ b/test/workbox-build/static/sw-injections/basic-with-invalid-sourcemap.js.nolint @@ -0,0 +1,2 @@ +!function(){"use strict";try{self["workbox:core:5.0.0-beta.0"]&&_()}catch(e){}const e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n};class t extends Error{constructor(t,n){super(e(t,n)),this.name=t,this.details=n}}const n={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:registration.scope},s=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join("-"),a={updateDetails:e=>{(e=>{for(const t of Object.keys(n))e(t)})(t=>{"string"==typeof e[t]&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||s(n.googleAnalytics),getPrecacheName:e=>e||s(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||s(n.runtime),getSuffix:()=>n.suffix},r=e=>{const t=new URL(String(e),location.href);return t.origin===location.origin?t.pathname:t.href},o=new Set;const i=(e,t)=>e.filter(e=>t in e),c=async({cacheName:e,request:t,event:n,matchOptions:s,plugins:a=[]})=>{const r=await caches.open(e),o=await l({plugins:a,request:t,mode:"read"});let i=await r.match(o,s);for(const t of a)if("cachedResponseWillBeUsed"in t){const a=t.cachedResponseWillBeUsed;i=await a.call(t,{cacheName:e,event:n,matchOptions:s,cachedResponse:i,request:o})}return i},h=async({request:e,response:t,event:n,plugins:s=[]})=>{let a=t,r=!1;for(let t of s)if("cacheWillUpdate"in t){r=!0;const s=t.cacheWillUpdate;if(!(a=await s.call(t,{request:e,response:a,event:n})))break}return r||(a=a&&200===a.status?a:void 0),a||null},l=async({request:e,mode:t,plugins:n=[]})=>{const s=i(n,"cacheKeyWillBeUsed");let a=e;for(const e of s)"string"==typeof(a=await e.cacheKeyWillBeUsed.call(e,{mode:t,request:a}))&&(a=new Request(a));return a},u={put:async({cacheName:e,request:n,response:s,event:a,plugins:u=[],matchOptions:d})=>{const f=await l({plugins:u,request:n,mode:"write"});if(!s)throw new t("cache-put-with-no-response",{url:r(f.url)});let p=await h({event:a,plugins:u,response:s,request:f});if(!p)return;const g=await caches.open(e),w=i(u,"cacheDidUpdate");let y=w.length>0?await c({cacheName:e,matchOptions:d,request:f}):null;try{await g.put(f,p)}catch(e){throw"QuotaExceededError"===e.name&&await async function(){for(const e of o)await e()}(),e}for(let t of w)await t.cacheDidUpdate.call(t,{cacheName:e,event:a,oldResponse:y,newResponse:p,request:f})},match:c},d={fetch:async({request:e,fetchOptions:n,event:s,plugins:a=[]})=>{if("string"==typeof e&&(e=new Request(e)),s instanceof FetchEvent&&s.preloadResponse){const e=await s.preloadResponse;if(e)return e}const r=i(a,"fetchDidFail"),o=r.length>0?e.clone():null;try{for(let t of a)if("requestWillFetch"in t){const n=t.requestWillFetch,a=e.clone();e=await n.call(t,{request:a,event:s})}}catch(e){throw new t("plugin-error-request-will-fetch",{thrownError:e})}let c=e.clone();try{let t;t="navigate"===e.mode?await fetch(e):await fetch(e,n);for(const e of a)"fetchDidSucceed"in e&&(t=await e.fetchDidSucceed.call(e,{event:s,request:c,response:t}));return t}catch(e){for(const t of r)await t.fetchDidFail.call(t,{error:e,event:s,originalRequest:o.clone(),request:c.clone()});throw e}}};try{self["workbox:strategies:5.0.0-beta.0"]&&_()}catch(e){}let f;class p{constructor(e,t,{onupgradeneeded:n,onversionchange:s}={}){this._db=null,this._name=e,this._version=t,this._onupgradeneeded=n,this._onversionchange=s||(()=>this.close())}get db(){return this._db}async open(){if(!this._db)return this._db=await new Promise((e,t)=>{let n=!1;setTimeout(()=>{n=!0,t(new Error("The open request was blocked and timed out"))},this.OPEN_TIMEOUT);const s=indexedDB.open(this._name,this._version);s.onerror=()=>t(s.error),s.onupgradeneeded=e=>{n?(s.transaction.abort(),s.result.close()):"function"==typeof this._onupgradeneeded&&this._onupgradeneeded(e)},s.onsuccess=()=>{const t=s.result;n?t.close():(t.onversionchange=this._onversionchange.bind(this),e(t))}}),this}async getKey(e,t){return(await this.getAllKeys(e,t,1))[0]}async getAll(e,t,n){return await this.getAllMatching(e,{query:t,count:n})}async getAllKeys(e,t,n){return(await this.getAllMatching(e,{query:t,count:n,includeKeys:!0})).map(e=>e.key)}async getAllMatching(e,{index:t,query:n=null,direction:s="next",count:a,includeKeys:r=!1}={}){return await this.transaction([e],"readonly",(o,i)=>{const c=o.objectStore(e),h=t?c.index(t):c,l=[],u=h.openCursor(n,s);u.onsuccess=()=>{const e=u.result;e?(l.push(r?e:e.value),a&&l.length>=a?i(l):e.continue()):i(l)}})}async transaction(e,t,n){return await this.open(),await new Promise((s,a)=>{const r=this._db.transaction(e,t);r.onabort=()=>a(r.error),r.oncomplete=()=>s(),n(r,e=>s(e))})}async _call(e,t,n,...s){return await this.transaction([t],n,(n,a)=>{const r=n.objectStore(t),o=r[e].apply(r,s);o.onsuccess=()=>a(o.result)})}close(){this._db&&(this._db.close(),this._db=null)}}p.prototype.OPEN_TIMEOUT=2e3;const g={readonly:["get","count","getKey","getAll","getAllKeys"],readwrite:["add","put","clear","delete"]};for(const[e,t]of Object.entries(g))for(const n of t)n in IDBObjectStore.prototype&&(p.prototype[n]=async function(t,...s){return await this._call(n,t,e,...s)});async function w(e,t){const n=e.clone(),s={headers:new Headers(n.headers),status:n.status,statusText:n.statusText},a=t?t(s):s,r=function(){if(void 0===f){const e=new Response("");if("body"in e)try{new Response(e.body),f=!0}catch(e){f=!1}f=!1}return f}()?n.body:await n.blob();return new Response(r,a)}try{self["workbox:precaching:5.0.0-beta.0"]&&_()}catch(e){}const y=[],m={get:()=>y,add(e){y.push(...e)}},v="__WB_REVISION__";function R(e){if(!e)throw new t("add-to-cache-list-unexpected-type",{entry:e});if("string"==typeof e){const t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}const{revision:n,url:s}=e;if(!s)throw new t("add-to-cache-list-unexpected-type",{entry:e});if(!n){const e=new URL(s,location.href);return{cacheKey:e.href,url:e.href}}const a=new URL(s,location.href),r=new URL(s,location.href);return a.searchParams.set(v,n),{cacheKey:a.href,url:r.href}}class b{constructor(e){this._cacheName=a.getPrecacheName(e),this._urlsToCacheKeys=new Map,this._cacheKeysToIntegrities=new Map}addToCacheList(e){for(const n of e){const{cacheKey:e,url:s}=R(n);if(this._urlsToCacheKeys.has(s)&&this._urlsToCacheKeys.get(s)!==e)throw new t("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(s),secondEntry:e});if("string"!=typeof n&&n.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==n.integrity)throw new t("add-to-cache-list-conflicting-integrities",{url:s});this._cacheKeysToIntegrities.set(e,n.integrity)}this._urlsToCacheKeys.set(s,e)}}async install({event:e,plugins:t}={}){const n=[],s=[],a=await caches.open(this._cacheName),r=await a.keys(),o=new Set(r.map(e=>e.url));for(const[e,t]of this._urlsToCacheKeys)o.has(t)?s.push(e):n.push({cacheKey:t,url:e});const i=n.map(({cacheKey:n,url:s})=>{const a=this._cacheKeysToIntegrities.get(n);return this._addURLToCache({cacheKey:n,event:e,plugins:t,url:s,integrity:a})});return await Promise.all(i),{updatedURLs:n.map(e=>e.url),notUpdatedURLs:s}}async activate(){const e=await caches.open(this._cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),s=[];for(const a of t)n.has(a.url)||(await e.delete(a),s.push(a.url));return{deletedURLs:s}}async _addURLToCache({cacheKey:e,url:n,event:s,plugins:a,integrity:r}){const o=new Request(n,{integrity:r,cache:"reload",credentials:"same-origin"});let i,c=await d.fetch({event:s,plugins:a,request:o});for(const e of a||[])"cacheWillUpdate"in e&&(i=e);if(!(i?i.cacheWillUpdate({event:s,request:o,response:c}):c.status<400))throw new t("bad-precaching-response",{url:n,status:c.status});c.redirected&&(c=await w(c)),await u.put({event:s,plugins:a,response:c,request:e===n?o:new Request(e),cacheName:this._cacheName,matchOptions:{ignoreSearch:!0}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}createHandlerForURL(e){const n=this.getCacheKeyForURL(e);if(!n)throw new t("non-precached-url",{url:e});return async()=>{try{const e=await caches.open(this._cacheName),t=await e.match(n);if(t)return t;throw new Error(`The cache ${this._cacheName} did not have an entry `+`for ${n}.`)}catch(e){return fetch(n)}}}}let q;const U=()=>(q||(q=new b),q);const L=(e,t)=>{const n=U().getURLsToCacheKeys();for(const s of function*(e,{ignoreURLParametersMatching:t,directoryIndex:n,cleanURLs:s,urlManipulation:a}={}){const r=new URL(e,location.href);r.hash="",yield r.href;const o=function(e,t=[]){for(const n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}(r,t);if(yield o.href,n&&o.pathname.endsWith("/")){const e=new URL(o.href);e.pathname+=n,yield e.href}if(s){const e=new URL(o.href);e.pathname+=".html",yield e.href}if(a){const e=a({url:r});for(const t of e)yield t.href}}(e,t)){const e=n.get(s);if(e)return e}};let x=!1;const T=e=>{x||((({ignoreURLParametersMatching:e=[/^utm_/],directoryIndex:t="index.html",cleanURLs:n=!0,urlManipulation:s}={})=>{const r=a.getPrecacheName();addEventListener("fetch",a=>{const o=L(a.request.url,{cleanURLs:n,directoryIndex:t,ignoreURLParametersMatching:e,urlManipulation:s});if(!o)return;let i=caches.open(r).then(e=>e.match(o)).then(e=>e||fetch(o));a.respondWith(i)})})(e),x=!0)},K=e=>{const t=U(),n=m.get();e.waitUntil(t.install({event:e,plugins:n}).catch(e=>{throw e}))},N=e=>{const t=U();e.waitUntil(t.activate())};try{self["workbox:range-requests:5.0.0-beta.0"]&&_()}catch(e){}async function C(e,n){try{if(206===n.status)return n;const s=e.headers.get("range");if(!s)throw new t("no-range-header");const a=function(e){const n=e.trim().toLowerCase();if(!n.startsWith("bytes="))throw new t("unit-must-be-bytes",{normalizedRangeHeader:n});if(n.includes(","))throw new t("single-range-only",{normalizedRangeHeader:n});const s=/(\d*)-(\d*)/.exec(n);if(!s||!s[1]&&!s[2])throw new t("invalid-range-values",{normalizedRangeHeader:n});return{start:""===s[1]?void 0:Number(s[1]),end:""===s[2]?void 0:Number(s[2])}}(s),r=await n.blob(),o=function(e,n,s){const a=e.size;if(s&&s>a||n&&n<0)throw new t("range-not-satisfiable",{size:a,end:s,start:n});let r,o;return void 0!==n&&void 0!==s?(r=n,o=s+1):void 0!==n&&void 0===s?(r=n,o=a):void 0!==s&&void 0===n&&(r=a-s,o=a),{start:r,end:o}}(r,a.start,a.end),i=r.slice(o.start,o.end),c=i.size,h=new Response(i,{status:206,statusText:"Partial Content",headers:n.headers});return h.headers.set("Content-Length",String(c)),h.headers.set("Content-Range",`bytes ${o.start}-${o.end-1}/`+r.size),h}catch(e){return new Response("",{status:416,statusText:"Range Not Satisfiable"})}}try{self["workbox:routing:5.0.0-beta.0"]&&_()}catch(e){}const E="GET",P=e=>e&&"object"==typeof e?e:{handle:e};class O{constructor(e,t,n=E){this.handler=P(t),this.match=e,this.method=n}}class M extends O{constructor(e,t,n){super(({url:t})=>{const n=e.exec(t.href);if(n&&(t.origin===location.origin||0===n.index))return n.slice(1)},t,n)}}class S{constructor(){this._routes=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",e=>{const{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)})}addCacheListener(){self.addEventListener("message",async e=>{if(e.data&&"CACHE_URLS"===e.data.type){const{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const t=new Request(...e);return this.handleRequest({request:t})}));e.waitUntil(n),e.ports&&e.ports[0]&&(await n,e.ports[0].postMessage(!0))}})}handleRequest({request:e,event:t}){const n=new URL(e.url,location.href);if(!n.protocol.startsWith("http"))return;let s,{params:a,route:r}=this.findMatchingRoute({url:n,request:e,event:t}),o=r&&r.handler;if(!o&&this._defaultHandler&&(o=this._defaultHandler),o){try{s=o.handle({url:n,request:e,event:t,params:a})}catch(e){s=Promise.reject(e)}return s&&this._catchHandler&&(s=s.catch(s=>this._catchHandler.handle({url:n,request:e,event:t}))),s}}findMatchingRoute({url:e,request:t,event:n}){const s=this._routes.get(t.method)||[];for(const a of s){let s,r=a.match({url:e,request:t,event:n});if(r)return s=r,Array.isArray(r)&&0===r.length?s=void 0:r.constructor===Object&&0===Object.keys(r).length?s=void 0:"boolean"==typeof r&&(s=void 0),{route:a,params:s}}return{}}setDefaultHandler(e){this._defaultHandler=P(e)}setCatchHandler(e){this._catchHandler=P(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t("unregister-route-but-not-found-with-method",{method:e.method});const n=this._routes.get(e.method).indexOf(e);if(!(n>-1))throw new t("unregister-route-route-not-registered");this._routes.get(e.method).splice(n,1)}}let W;const k=()=>(W||((W=new S).addFetchListener(),W.addCacheListener()),W),A=(e,n,s)=>{let a;if("string"==typeof e){const t=new URL(e,location.href);a=new O(({url:e})=>e.href===t.href,n,s)}else if(e instanceof RegExp)a=new M(e,n,s);else if("function"==typeof e)a=new O(e,n,s);else{if(!(e instanceof O))throw new t("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});a=e}return k().registerRoute(a),a},H="media";!async function(){const e=await caches.open(H),t=await e.keys();Promise.all(t.reverse().map(async t=>{return{contentType:(await e.match(t)).headers.get("content-type"),src:t.url}}))}();const I={href:"/audio",mimePrefix:"audio/"},D={href:"/images",mimePrefix:"image/"},B={href:"/videos",mimePrefix:"video/"},F=BroadcastChannel?new BroadcastChannel("messages"):null,j=new class{constructor(e={}){this._cacheName=a.getRuntimeName(e.cacheName),this._plugins=e.plugins||[],this._matchOptions=e.matchOptions}async handle({event:e,request:n}){const s=await u.match({cacheName:this._cacheName,request:n,event:e,matchOptions:this._matchOptions,plugins:this._plugins});if(!s)throw new t("no-response",{url:n.url});return s}}({cacheName:H,plugins:[new class{constructor(){this.cachedResponseWillBeUsed=async({request:e,cachedResponse:t})=>t&&e.headers.has("range")?await C(e,t):t}}]});var z;addEventListener("install",()=>self.skipWaiting()),addEventListener("activate",()=>self.clients.claim()),(e=>{U().addToCacheList(e),e.length>0&&(addEventListener("install",K),addEventListener("activate",N))})(self.__WB_MANIFEST),T(z),A("/_share-target",async({event:e})=>{F&&F.postMessage("Saving media locally...");const t=(await e.request.formData()).getAll("media"),n=await caches.open(H);for(const e of t)e.name?await n.put(`/_media/${Date.now()}-${e.name}`,new Response(e,{headers:{"content-length":e.size,"content-type":e.type}})):F&&F.postMessage("Sorry! No name found on incoming media.");const s=[I,D,B].find(e=>t[0].type.startsWith(e.mimePrefix)),a=s?`/#${s.href}`:"/";return Response.redirect(a,303)},"POST"),A(new RegExp("/_media/"),j)}(); +//# sourceMappingURL=does-not-exist.js.map