From ac743ee40ac4831426c94e4525c812d35558b080 Mon Sep 17 00:00:00 2001 From: DuCanhGH <75556609+DuCanhGH@users.noreply.github.com> Date: Wed, 18 Oct 2023 18:00:20 +0700 Subject: [PATCH 1/9] fork --- docs/package.json | 16 +- examples/basic/package.json | 4 +- examples/custom-server/package.json | 8 +- examples/custom-worker/package.json | 4 +- examples/lifecycle/package.json | 4 +- examples/next-i18next/package.json | 6 +- examples/next-image/package.json | 4 +- examples/offline-fallback-v2/package.json | 4 +- examples/web-push/package.json | 4 +- examples/workboxless/package.json | 4 +- package.json | 16 +- packages/constants/package.json | 2 +- packages/next-pwa/__tests__/package.json | 2 +- packages/next-pwa/package.json | 10 +- packages/next-sw/package.json | 10 +- packages/test-utils/package.json | 2 +- packages/utils/package.json | 4 +- packages/workbox-background-sync/README.md | 1 + packages/workbox-background-sync/package.json | 30 + .../src/BackgroundSyncPlugin.ts | 43 + packages/workbox-background-sync/src/Queue.ts | 487 +++ .../workbox-background-sync/src/QueueStore.ts | 14 + .../src/StorableRequest.ts | 14 + .../workbox-background-sync/src/_version.ts | 4 + packages/workbox-background-sync/src/index.ts | 46 + .../src/lib/QueueDb.ts | 200 + .../src/lib/QueueStore.ts | 179 + .../src/lib/StorableRequest.ts | 156 + .../workbox-background-sync/tsconfig.json | 9 + packages/workbox-broadcast-update/README.md | 1 + .../workbox-broadcast-update/package.json | 27 + .../src/BroadcastCacheUpdate.ts | 215 ++ .../src/BroadcastUpdatePlugin.ts | 63 + .../workbox-broadcast-update/src/_version.ts | 4 + .../workbox-broadcast-update/src/index.ts | 27 + .../src/responsesAreSame.ts | 72 + .../src/utils/constants.ts | 18 + .../workbox-broadcast-update/tsconfig.json | 9 + packages/workbox-build/README.md | 1 + packages/workbox-build/package.json | 69 + packages/workbox-build/src/_types.js | 120 + packages/workbox-build/src/cdn-details.json | 6 + packages/workbox-build/src/generate-sw.ts | 117 + packages/workbox-build/src/get-manifest.ts | 37 + packages/workbox-build/src/index.ts | 26 + packages/workbox-build/src/inject-manifest.ts | 162 + .../additional-manifest-entries-transform.ts | 58 + packages/workbox-build/src/lib/bundle.ts | 153 + packages/workbox-build/src/lib/cdn-utils.ts | 37 + .../src/lib/copy-workbox-libraries.ts | 84 + packages/workbox-build/src/lib/errors.ts | 124 + .../workbox-build/src/lib/escape-regexp.ts | 12 + .../src/lib/get-composite-details.ts | 34 + .../workbox-build/src/lib/get-file-details.ts | 76 + .../workbox-build/src/lib/get-file-hash.ts | 24 + .../src/lib/get-file-manifest-entries.ts | 121 + .../workbox-build/src/lib/get-file-size.ts | 26 + .../src/lib/get-source-map-url.ts | 32 + .../src/lib/get-string-details.ts | 18 + .../workbox-build/src/lib/get-string-hash.ts | 15 + .../src/lib/maximum-size-transform.ts | 33 + .../src/lib/modify-url-prefix-transform.ts | 61 + .../workbox-build/src/lib/module-registry.ts | 76 + ...no-revision-for-urls-matching-transform.ts | 34 + .../src/lib/populate-sw-template.ts | 105 + packages/workbox-build/src/lib/rebase-path.ts | 28 + .../src/lib/replace-and-update-source-map.ts | 127 + .../src/lib/runtime-caching-converter.ts | 215 ++ .../src/lib/stringify-without-comments.ts | 23 + .../src/lib/transform-manifest.ts | 162 + .../lib/translate-url-to-sourcemap-paths.ts | 38 + .../workbox-build/src/lib/validate-options.ts | 237 ++ .../lib/write-sw-using-default-template.ts | 96 + .../src/rollup-plugin-off-main-thread.d.ts | 1 + .../src/schema/GenerateSWOptions.json | 872 +++++ .../src/schema/GetManifestOptions.json | 164 + .../src/schema/InjectManifestOptions.json | 179 + .../src/schema/WebpackGenerateSWOptions.json | 850 +++++ .../schema/WebpackInjectManifestOptions.json | 167 + .../workbox-build/src/strip-comments.d.ts | 1 + .../src/templates/sw-template.ts | 60 + packages/workbox-build/src/types.ts | 590 +++ packages/workbox-build/tsconfig.json | 14 + packages/workbox-cacheable-response/README.md | 1 + .../workbox-cacheable-response/package.json | 27 + .../src/CacheableResponse.ts | 150 + .../src/CacheableResponsePlugin.ts | 58 + .../src/_version.ts | 4 + .../workbox-cacheable-response/src/index.ts | 21 + .../workbox-cacheable-response/tsconfig.json | 10 + packages/workbox-cli/README.md | 1 + packages/workbox-cli/package.json | 53 + packages/workbox-cli/src/app.ts | 156 + packages/workbox-cli/src/bin.ts | 46 + .../src/lib/cleanup-stack-trace.ts | 30 + packages/workbox-cli/src/lib/constants.ts | 14 + packages/workbox-cli/src/lib/errors.ts | 35 + packages/workbox-cli/src/lib/help-text.ts | 57 + packages/workbox-cli/src/lib/logger.ts | 16 + .../src/lib/questions/ask-config-location.ts | 42 + .../lib/questions/ask-extensions-to-cache.ts | 109 + .../src/lib/questions/ask-questions.ts | 56 + .../src/lib/questions/ask-root-of-web-app.ts | 100 + .../questions/ask-start_url-query-params.ts | 84 + .../src/lib/questions/ask-sw-dest.ts | 43 + .../src/lib/questions/ask-sw-src.ts | 35 + packages/workbox-cli/src/lib/read-config.ts | 17 + packages/workbox-cli/src/lib/run-wizard.ts | 37 + packages/workbox-cli/tsconfig.json | 13 + packages/workbox-core/README.md | 1 + packages/workbox-core/package.json | 23 + packages/workbox-core/src/_private.ts | 42 + .../workbox-core/src/_private/Deferred.ts | 35 + .../workbox-core/src/_private/WorkboxError.ts | 43 + packages/workbox-core/src/_private/assert.ts | 100 + .../src/_private/cacheMatchIgnoreParams.ts | 56 + .../workbox-core/src/_private/cacheNames.ts | 75 + .../_private/canConstructReadableStream.ts | 37 + .../canConstructResponseFromBodyStream.ts | 40 + .../workbox-core/src/_private/dontWaitFor.ts | 18 + .../_private/executeQuotaErrorCallbacks.ts | 40 + .../src/_private/getFriendlyURL.ts | 18 + packages/workbox-core/src/_private/logger.ts | 100 + .../src/_private/resultingClientExists.ts | 62 + packages/workbox-core/src/_private/timeout.ts | 21 + .../workbox-core/src/_private/waitUntil.ts | 28 + packages/workbox-core/src/_version.ts | 4 + packages/workbox-core/src/cacheNames.ts | 45 + packages/workbox-core/src/clientsClaim.ts | 24 + packages/workbox-core/src/copyResponse.ts | 70 + packages/workbox-core/src/index.ts | 35 + .../src/models/messages/messageGenerator.ts | 30 + .../src/models/messages/messages.ts | 387 ++ .../workbox-core/src/models/pluginEvents.ts | 19 + .../src/models/quotaErrorCallbacks.ts | 16 + .../src/registerQuotaErrorCallback.ts | 39 + .../workbox-core/src/setCacheNameDetails.ts | 69 + packages/workbox-core/src/skipWaiting.ts | 37 + packages/workbox-core/src/types.ts | 282 ++ .../workbox-core/src/utils/pluginUtils.ts | 16 + packages/workbox-core/src/utils/welcome.ts | 35 + packages/workbox-core/tsconfig.json | 9 + packages/workbox-expiration/README.md | 1 + packages/workbox-expiration/package.json | 28 + .../workbox-expiration/src/CacheExpiration.ts | 205 + .../src/ExpirationPlugin.ts | 302 ++ packages/workbox-expiration/src/_version.ts | 4 + packages/workbox-expiration/src/index.ts | 21 + .../src/models/CacheTimestampsModel.ts | 226 ++ packages/workbox-expiration/tsconfig.json | 10 + packages/workbox-google-analytics/README.md | 1 + .../workbox-google-analytics/package.json | 33 + .../workbox-google-analytics/src/_version.ts | 4 + .../workbox-google-analytics/src/index.ts | 17 + .../src/initialize.ts | 233 ++ .../src/utils/constants.ts | 24 + .../workbox-google-analytics/tsconfig.json | 15 + packages/workbox-navigation-preload/README.md | 1 + .../workbox-navigation-preload/package.json | 27 + .../src/_version.ts | 4 + .../workbox-navigation-preload/src/disable.ts | 39 + .../workbox-navigation-preload/src/enable.ts | 51 + .../workbox-navigation-preload/src/index.ts | 37 + .../src/isSupported.ts | 24 + .../workbox-navigation-preload/tsconfig.json | 10 + packages/workbox-precaching/README.md | 1 + packages/workbox-precaching/package.json | 28 + .../src/PrecacheController.ts | 366 ++ .../src/PrecacheFallbackPlugin.ts | 65 + .../workbox-precaching/src/PrecacheRoute.ts | 77 + .../src/PrecacheStrategy.ts | 287 ++ packages/workbox-precaching/src/_types.ts | 85 + packages/workbox-precaching/src/_version.ts | 4 + packages/workbox-precaching/src/addPlugins.ts | 25 + packages/workbox-precaching/src/addRoute.ts | 38 + .../src/cleanupOutdatedCaches.ts | 41 + .../src/createHandlerBoundToURL.ts | 35 + .../src/getCacheKeyForURL.ts | 36 + packages/workbox-precaching/src/index.ts | 52 + .../workbox-precaching/src/matchPrecache.ts | 35 + packages/workbox-precaching/src/precache.ts | 37 + .../src/precacheAndRoute.ts | 36 + .../src/utils/PrecacheCacheKeyPlugin.ts | 52 + .../src/utils/PrecacheInstallReportPlugin.ts | 61 + .../src/utils/createCacheKey.ts | 69 + .../src/utils/deleteOutdatedCaches.ts | 55 + .../src/utils/generateURLVariations.ts | 60 + .../src/utils/getCacheKeyForURL.ts | 38 + .../utils/getOrCreatePrecacheController.ts | 23 + .../src/utils/printCleanupDetails.ts | 45 + .../src/utils/printInstallDetails.ts | 63 + .../src/utils/removeIgnoredSearchParams.ts | 36 + packages/workbox-precaching/tsconfig.json | 14 + packages/workbox-range-requests/README.md | 1 + packages/workbox-range-requests/package.json | 31 + .../src/RangeRequestsPlugin.ts | 50 + .../workbox-range-requests/src/_version.ts | 4 + .../src/createPartialResponse.ts | 115 + packages/workbox-range-requests/src/index.ts | 17 + .../src/utils/calculateEffectiveBoundaries.ts | 67 + .../src/utils/parseRangeHeader.ts | 57 + packages/workbox-range-requests/tsconfig.json | 10 + packages/workbox-recipes/README.md | 1 + packages/workbox-recipes/package.json | 33 + packages/workbox-recipes/src/_version.ts | 4 + .../workbox-recipes/src/googleFontsCache.ts | 64 + packages/workbox-recipes/src/imageCache.ts | 77 + packages/workbox-recipes/src/index.ts | 41 + .../workbox-recipes/src/offlineFallback.ts | 90 + packages/workbox-recipes/src/pageCache.ts | 69 + .../src/staticResourceCache.ts | 66 + .../workbox-recipes/src/warmStrategyCache.ts | 34 + packages/workbox-recipes/tsconfig.json | 17 + packages/workbox-routing/README.md | 1 + packages/workbox-routing/package.json | 28 + .../workbox-routing/src/NavigationRoute.ts | 143 + packages/workbox-routing/src/RegExpRoute.ts | 92 + packages/workbox-routing/src/Route.ts | 80 + packages/workbox-routing/src/Router.ts | 487 +++ packages/workbox-routing/src/_types.ts | 66 + packages/workbox-routing/src/_version.ts | 4 + packages/workbox-routing/src/index.ts | 35 + packages/workbox-routing/src/registerRoute.ts | 115 + .../workbox-routing/src/setCatchHandler.ts | 29 + .../workbox-routing/src/setDefaultHandler.ts | 32 + .../workbox-routing/src/utils/constants.ts | 37 + .../src/utils/getOrCreateDefaultRouter.ts | 30 + .../src/utils/normalizeHandler.ts | 43 + packages/workbox-routing/tsconfig.json | 10 + packages/workbox-strategies/README.md | 1 + packages/workbox-strategies/package.json | 28 + packages/workbox-strategies/src/CacheFirst.ts | 101 + packages/workbox-strategies/src/CacheOnly.ts | 72 + .../workbox-strategies/src/NetworkFirst.ts | 263 ++ .../workbox-strategies/src/NetworkOnly.ts | 122 + .../src/StaleWhileRevalidate.ts | 135 + packages/workbox-strategies/src/Strategy.ts | 289 ++ .../workbox-strategies/src/StrategyHandler.ts | 636 ++++ packages/workbox-strategies/src/_version.ts | 4 + packages/workbox-strategies/src/index.ts | 44 + .../src/plugins/cacheOkAndOpaquePlugin.ts | 29 + .../workbox-strategies/src/utils/messages.ts | 23 + packages/workbox-strategies/tsconfig.json | 10 + packages/workbox-streams/README.md | 1 + packages/workbox-streams/package.json | 29 + packages/workbox-streams/src/_types.ts | 23 + packages/workbox-streams/src/_version.ts | 4 + packages/workbox-streams/src/concatenate.ts | 146 + .../src/concatenateToResponse.ts | 43 + packages/workbox-streams/src/index.ts | 28 + packages/workbox-streams/src/isSupported.ts | 27 + packages/workbox-streams/src/strategy.ts | 102 + .../src/utils/createHeaders.ts | 34 + packages/workbox-streams/tsconfig.json | 10 + packages/workbox-sw/README.md | 1 + packages/workbox-sw/_types.mjs | 24 + packages/workbox-sw/_version.mjs | 3 + packages/workbox-sw/controllers/WorkboxSW.mjs | 221 ++ packages/workbox-sw/index.mjs | 17 + packages/workbox-sw/package.json | 23 + packages/workbox-webpack-plugin/README.md | 1 + packages/workbox-webpack-plugin/package.json | 42 + .../workbox-webpack-plugin/src/generate-sw.ts | 244 ++ packages/workbox-webpack-plugin/src/index.ts | 19 + .../src/inject-manifest.ts | 371 ++ .../src/lib/get-asset-hash.ts | 30 + .../get-manifest-entries-from-compilation.ts | 253 ++ .../src/lib/get-script-files-for-chunks.ts | 51 + .../src/lib/get-sourcemap-asset-name.ts | 54 + .../src/lib/relative-to-output-path.ts | 32 + .../src/lib/resolve-webpack-url.ts | 33 + packages/workbox-webpack-plugin/tsconfig.json | 14 + packages/workbox-window/README.md | 1 + packages/workbox-window/package.json | 30 + packages/workbox-window/src/Workbox.ts | 743 ++++ packages/workbox-window/src/_version.ts | 4 + packages/workbox-window/src/index.ts | 20 + packages/workbox-window/src/messageSW.ts | 37 + .../workbox-window/src/utils/WorkboxEvent.ts | 59 + .../src/utils/WorkboxEventTarget.ts | 77 + .../workbox-window/src/utils/urlsMatch.ts | 23 + packages/workbox-window/tsconfig.json | 15 + pnpm-lock.yaml | 3372 +++++++++++++---- 283 files changed, 22660 insertions(+), 798 deletions(-) create mode 100644 packages/workbox-background-sync/README.md create mode 100644 packages/workbox-background-sync/package.json create mode 100644 packages/workbox-background-sync/src/BackgroundSyncPlugin.ts create mode 100644 packages/workbox-background-sync/src/Queue.ts create mode 100644 packages/workbox-background-sync/src/QueueStore.ts create mode 100644 packages/workbox-background-sync/src/StorableRequest.ts create mode 100644 packages/workbox-background-sync/src/_version.ts create mode 100644 packages/workbox-background-sync/src/index.ts create mode 100644 packages/workbox-background-sync/src/lib/QueueDb.ts create mode 100644 packages/workbox-background-sync/src/lib/QueueStore.ts create mode 100644 packages/workbox-background-sync/src/lib/StorableRequest.ts create mode 100644 packages/workbox-background-sync/tsconfig.json create mode 100644 packages/workbox-broadcast-update/README.md create mode 100644 packages/workbox-broadcast-update/package.json create mode 100644 packages/workbox-broadcast-update/src/BroadcastCacheUpdate.ts create mode 100644 packages/workbox-broadcast-update/src/BroadcastUpdatePlugin.ts create mode 100644 packages/workbox-broadcast-update/src/_version.ts create mode 100644 packages/workbox-broadcast-update/src/index.ts create mode 100644 packages/workbox-broadcast-update/src/responsesAreSame.ts create mode 100644 packages/workbox-broadcast-update/src/utils/constants.ts create mode 100644 packages/workbox-broadcast-update/tsconfig.json create mode 100644 packages/workbox-build/README.md create mode 100644 packages/workbox-build/package.json create mode 100644 packages/workbox-build/src/_types.js create mode 100644 packages/workbox-build/src/cdn-details.json create mode 100644 packages/workbox-build/src/generate-sw.ts create mode 100644 packages/workbox-build/src/get-manifest.ts create mode 100644 packages/workbox-build/src/index.ts create mode 100644 packages/workbox-build/src/inject-manifest.ts create mode 100644 packages/workbox-build/src/lib/additional-manifest-entries-transform.ts create mode 100644 packages/workbox-build/src/lib/bundle.ts create mode 100644 packages/workbox-build/src/lib/cdn-utils.ts create mode 100644 packages/workbox-build/src/lib/copy-workbox-libraries.ts create mode 100644 packages/workbox-build/src/lib/errors.ts create mode 100644 packages/workbox-build/src/lib/escape-regexp.ts create mode 100644 packages/workbox-build/src/lib/get-composite-details.ts create mode 100644 packages/workbox-build/src/lib/get-file-details.ts create mode 100644 packages/workbox-build/src/lib/get-file-hash.ts create mode 100644 packages/workbox-build/src/lib/get-file-manifest-entries.ts create mode 100644 packages/workbox-build/src/lib/get-file-size.ts create mode 100644 packages/workbox-build/src/lib/get-source-map-url.ts create mode 100644 packages/workbox-build/src/lib/get-string-details.ts create mode 100644 packages/workbox-build/src/lib/get-string-hash.ts create mode 100644 packages/workbox-build/src/lib/maximum-size-transform.ts create mode 100644 packages/workbox-build/src/lib/modify-url-prefix-transform.ts create mode 100644 packages/workbox-build/src/lib/module-registry.ts create mode 100644 packages/workbox-build/src/lib/no-revision-for-urls-matching-transform.ts create mode 100644 packages/workbox-build/src/lib/populate-sw-template.ts create mode 100644 packages/workbox-build/src/lib/rebase-path.ts create mode 100644 packages/workbox-build/src/lib/replace-and-update-source-map.ts create mode 100644 packages/workbox-build/src/lib/runtime-caching-converter.ts create mode 100644 packages/workbox-build/src/lib/stringify-without-comments.ts create mode 100644 packages/workbox-build/src/lib/transform-manifest.ts create mode 100644 packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts create mode 100644 packages/workbox-build/src/lib/validate-options.ts create mode 100644 packages/workbox-build/src/lib/write-sw-using-default-template.ts create mode 100644 packages/workbox-build/src/rollup-plugin-off-main-thread.d.ts create mode 100644 packages/workbox-build/src/schema/GenerateSWOptions.json create mode 100644 packages/workbox-build/src/schema/GetManifestOptions.json create mode 100644 packages/workbox-build/src/schema/InjectManifestOptions.json create mode 100644 packages/workbox-build/src/schema/WebpackGenerateSWOptions.json create mode 100644 packages/workbox-build/src/schema/WebpackInjectManifestOptions.json create mode 100644 packages/workbox-build/src/strip-comments.d.ts create mode 100644 packages/workbox-build/src/templates/sw-template.ts create mode 100644 packages/workbox-build/src/types.ts create mode 100644 packages/workbox-build/tsconfig.json create mode 100644 packages/workbox-cacheable-response/README.md create mode 100755 packages/workbox-cacheable-response/package.json create mode 100644 packages/workbox-cacheable-response/src/CacheableResponse.ts create mode 100644 packages/workbox-cacheable-response/src/CacheableResponsePlugin.ts create mode 100644 packages/workbox-cacheable-response/src/_version.ts create mode 100644 packages/workbox-cacheable-response/src/index.ts create mode 100644 packages/workbox-cacheable-response/tsconfig.json create mode 100644 packages/workbox-cli/README.md create mode 100644 packages/workbox-cli/package.json create mode 100644 packages/workbox-cli/src/app.ts create mode 100755 packages/workbox-cli/src/bin.ts create mode 100644 packages/workbox-cli/src/lib/cleanup-stack-trace.ts create mode 100644 packages/workbox-cli/src/lib/constants.ts create mode 100644 packages/workbox-cli/src/lib/errors.ts create mode 100644 packages/workbox-cli/src/lib/help-text.ts create mode 100644 packages/workbox-cli/src/lib/logger.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-config-location.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-extensions-to-cache.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-questions.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-start_url-query-params.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-sw-dest.ts create mode 100644 packages/workbox-cli/src/lib/questions/ask-sw-src.ts create mode 100644 packages/workbox-cli/src/lib/read-config.ts create mode 100644 packages/workbox-cli/src/lib/run-wizard.ts create mode 100644 packages/workbox-cli/tsconfig.json create mode 100644 packages/workbox-core/README.md create mode 100644 packages/workbox-core/package.json create mode 100644 packages/workbox-core/src/_private.ts create mode 100644 packages/workbox-core/src/_private/Deferred.ts create mode 100644 packages/workbox-core/src/_private/WorkboxError.ts create mode 100644 packages/workbox-core/src/_private/assert.ts create mode 100644 packages/workbox-core/src/_private/cacheMatchIgnoreParams.ts create mode 100644 packages/workbox-core/src/_private/cacheNames.ts create mode 100644 packages/workbox-core/src/_private/canConstructReadableStream.ts create mode 100644 packages/workbox-core/src/_private/canConstructResponseFromBodyStream.ts create mode 100644 packages/workbox-core/src/_private/dontWaitFor.ts create mode 100644 packages/workbox-core/src/_private/executeQuotaErrorCallbacks.ts create mode 100644 packages/workbox-core/src/_private/getFriendlyURL.ts create mode 100644 packages/workbox-core/src/_private/logger.ts create mode 100644 packages/workbox-core/src/_private/resultingClientExists.ts create mode 100644 packages/workbox-core/src/_private/timeout.ts create mode 100644 packages/workbox-core/src/_private/waitUntil.ts create mode 100644 packages/workbox-core/src/_version.ts create mode 100644 packages/workbox-core/src/cacheNames.ts create mode 100644 packages/workbox-core/src/clientsClaim.ts create mode 100644 packages/workbox-core/src/copyResponse.ts create mode 100644 packages/workbox-core/src/index.ts create mode 100644 packages/workbox-core/src/models/messages/messageGenerator.ts create mode 100644 packages/workbox-core/src/models/messages/messages.ts create mode 100644 packages/workbox-core/src/models/pluginEvents.ts create mode 100644 packages/workbox-core/src/models/quotaErrorCallbacks.ts create mode 100644 packages/workbox-core/src/registerQuotaErrorCallback.ts create mode 100644 packages/workbox-core/src/setCacheNameDetails.ts create mode 100644 packages/workbox-core/src/skipWaiting.ts create mode 100644 packages/workbox-core/src/types.ts create mode 100644 packages/workbox-core/src/utils/pluginUtils.ts create mode 100644 packages/workbox-core/src/utils/welcome.ts create mode 100644 packages/workbox-core/tsconfig.json create mode 100644 packages/workbox-expiration/README.md create mode 100644 packages/workbox-expiration/package.json create mode 100644 packages/workbox-expiration/src/CacheExpiration.ts create mode 100644 packages/workbox-expiration/src/ExpirationPlugin.ts create mode 100644 packages/workbox-expiration/src/_version.ts create mode 100644 packages/workbox-expiration/src/index.ts create mode 100644 packages/workbox-expiration/src/models/CacheTimestampsModel.ts create mode 100644 packages/workbox-expiration/tsconfig.json create mode 100644 packages/workbox-google-analytics/README.md create mode 100644 packages/workbox-google-analytics/package.json create mode 100644 packages/workbox-google-analytics/src/_version.ts create mode 100644 packages/workbox-google-analytics/src/index.ts create mode 100644 packages/workbox-google-analytics/src/initialize.ts create mode 100644 packages/workbox-google-analytics/src/utils/constants.ts create mode 100644 packages/workbox-google-analytics/tsconfig.json create mode 100644 packages/workbox-navigation-preload/README.md create mode 100755 packages/workbox-navigation-preload/package.json create mode 100644 packages/workbox-navigation-preload/src/_version.ts create mode 100644 packages/workbox-navigation-preload/src/disable.ts create mode 100644 packages/workbox-navigation-preload/src/enable.ts create mode 100644 packages/workbox-navigation-preload/src/index.ts create mode 100644 packages/workbox-navigation-preload/src/isSupported.ts create mode 100644 packages/workbox-navigation-preload/tsconfig.json create mode 100644 packages/workbox-precaching/README.md create mode 100644 packages/workbox-precaching/package.json create mode 100644 packages/workbox-precaching/src/PrecacheController.ts create mode 100644 packages/workbox-precaching/src/PrecacheFallbackPlugin.ts create mode 100644 packages/workbox-precaching/src/PrecacheRoute.ts create mode 100644 packages/workbox-precaching/src/PrecacheStrategy.ts create mode 100644 packages/workbox-precaching/src/_types.ts create mode 100644 packages/workbox-precaching/src/_version.ts create mode 100644 packages/workbox-precaching/src/addPlugins.ts create mode 100644 packages/workbox-precaching/src/addRoute.ts create mode 100644 packages/workbox-precaching/src/cleanupOutdatedCaches.ts create mode 100644 packages/workbox-precaching/src/createHandlerBoundToURL.ts create mode 100644 packages/workbox-precaching/src/getCacheKeyForURL.ts create mode 100644 packages/workbox-precaching/src/index.ts create mode 100644 packages/workbox-precaching/src/matchPrecache.ts create mode 100644 packages/workbox-precaching/src/precache.ts create mode 100644 packages/workbox-precaching/src/precacheAndRoute.ts create mode 100644 packages/workbox-precaching/src/utils/PrecacheCacheKeyPlugin.ts create mode 100644 packages/workbox-precaching/src/utils/PrecacheInstallReportPlugin.ts create mode 100644 packages/workbox-precaching/src/utils/createCacheKey.ts create mode 100644 packages/workbox-precaching/src/utils/deleteOutdatedCaches.ts create mode 100644 packages/workbox-precaching/src/utils/generateURLVariations.ts create mode 100644 packages/workbox-precaching/src/utils/getCacheKeyForURL.ts create mode 100644 packages/workbox-precaching/src/utils/getOrCreatePrecacheController.ts create mode 100644 packages/workbox-precaching/src/utils/printCleanupDetails.ts create mode 100644 packages/workbox-precaching/src/utils/printInstallDetails.ts create mode 100644 packages/workbox-precaching/src/utils/removeIgnoredSearchParams.ts create mode 100644 packages/workbox-precaching/tsconfig.json create mode 100644 packages/workbox-range-requests/README.md create mode 100755 packages/workbox-range-requests/package.json create mode 100644 packages/workbox-range-requests/src/RangeRequestsPlugin.ts create mode 100644 packages/workbox-range-requests/src/_version.ts create mode 100644 packages/workbox-range-requests/src/createPartialResponse.ts create mode 100644 packages/workbox-range-requests/src/index.ts create mode 100644 packages/workbox-range-requests/src/utils/calculateEffectiveBoundaries.ts create mode 100644 packages/workbox-range-requests/src/utils/parseRangeHeader.ts create mode 100644 packages/workbox-range-requests/tsconfig.json create mode 100644 packages/workbox-recipes/README.md create mode 100644 packages/workbox-recipes/package.json create mode 100644 packages/workbox-recipes/src/_version.ts create mode 100644 packages/workbox-recipes/src/googleFontsCache.ts create mode 100644 packages/workbox-recipes/src/imageCache.ts create mode 100644 packages/workbox-recipes/src/index.ts create mode 100644 packages/workbox-recipes/src/offlineFallback.ts create mode 100644 packages/workbox-recipes/src/pageCache.ts create mode 100644 packages/workbox-recipes/src/staticResourceCache.ts create mode 100644 packages/workbox-recipes/src/warmStrategyCache.ts create mode 100644 packages/workbox-recipes/tsconfig.json create mode 100644 packages/workbox-routing/README.md create mode 100644 packages/workbox-routing/package.json create mode 100644 packages/workbox-routing/src/NavigationRoute.ts create mode 100644 packages/workbox-routing/src/RegExpRoute.ts create mode 100644 packages/workbox-routing/src/Route.ts create mode 100644 packages/workbox-routing/src/Router.ts create mode 100644 packages/workbox-routing/src/_types.ts create mode 100644 packages/workbox-routing/src/_version.ts create mode 100644 packages/workbox-routing/src/index.ts create mode 100644 packages/workbox-routing/src/registerRoute.ts create mode 100644 packages/workbox-routing/src/setCatchHandler.ts create mode 100644 packages/workbox-routing/src/setDefaultHandler.ts create mode 100644 packages/workbox-routing/src/utils/constants.ts create mode 100644 packages/workbox-routing/src/utils/getOrCreateDefaultRouter.ts create mode 100644 packages/workbox-routing/src/utils/normalizeHandler.ts create mode 100644 packages/workbox-routing/tsconfig.json create mode 100644 packages/workbox-strategies/README.md create mode 100644 packages/workbox-strategies/package.json create mode 100644 packages/workbox-strategies/src/CacheFirst.ts create mode 100644 packages/workbox-strategies/src/CacheOnly.ts create mode 100644 packages/workbox-strategies/src/NetworkFirst.ts create mode 100644 packages/workbox-strategies/src/NetworkOnly.ts create mode 100644 packages/workbox-strategies/src/StaleWhileRevalidate.ts create mode 100644 packages/workbox-strategies/src/Strategy.ts create mode 100644 packages/workbox-strategies/src/StrategyHandler.ts create mode 100644 packages/workbox-strategies/src/_version.ts create mode 100644 packages/workbox-strategies/src/index.ts create mode 100644 packages/workbox-strategies/src/plugins/cacheOkAndOpaquePlugin.ts create mode 100644 packages/workbox-strategies/src/utils/messages.ts create mode 100644 packages/workbox-strategies/tsconfig.json create mode 100644 packages/workbox-streams/README.md create mode 100644 packages/workbox-streams/package.json create mode 100644 packages/workbox-streams/src/_types.ts create mode 100644 packages/workbox-streams/src/_version.ts create mode 100644 packages/workbox-streams/src/concatenate.ts create mode 100644 packages/workbox-streams/src/concatenateToResponse.ts create mode 100644 packages/workbox-streams/src/index.ts create mode 100644 packages/workbox-streams/src/isSupported.ts create mode 100644 packages/workbox-streams/src/strategy.ts create mode 100644 packages/workbox-streams/src/utils/createHeaders.ts create mode 100644 packages/workbox-streams/tsconfig.json create mode 100644 packages/workbox-sw/README.md create mode 100644 packages/workbox-sw/_types.mjs create mode 100644 packages/workbox-sw/_version.mjs create mode 100644 packages/workbox-sw/controllers/WorkboxSW.mjs create mode 100644 packages/workbox-sw/index.mjs create mode 100644 packages/workbox-sw/package.json create mode 100644 packages/workbox-webpack-plugin/README.md create mode 100644 packages/workbox-webpack-plugin/package.json create mode 100644 packages/workbox-webpack-plugin/src/generate-sw.ts create mode 100644 packages/workbox-webpack-plugin/src/index.ts create mode 100644 packages/workbox-webpack-plugin/src/inject-manifest.ts create mode 100644 packages/workbox-webpack-plugin/src/lib/get-asset-hash.ts create mode 100644 packages/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts create mode 100644 packages/workbox-webpack-plugin/src/lib/get-script-files-for-chunks.ts create mode 100644 packages/workbox-webpack-plugin/src/lib/get-sourcemap-asset-name.ts create mode 100644 packages/workbox-webpack-plugin/src/lib/relative-to-output-path.ts create mode 100644 packages/workbox-webpack-plugin/src/lib/resolve-webpack-url.ts create mode 100644 packages/workbox-webpack-plugin/tsconfig.json create mode 100644 packages/workbox-window/README.md create mode 100644 packages/workbox-window/package.json create mode 100644 packages/workbox-window/src/Workbox.ts create mode 100644 packages/workbox-window/src/_version.ts create mode 100644 packages/workbox-window/src/index.ts create mode 100644 packages/workbox-window/src/messageSW.ts create mode 100644 packages/workbox-window/src/utils/WorkboxEvent.ts create mode 100644 packages/workbox-window/src/utils/WorkboxEventTarget.ts create mode 100644 packages/workbox-window/src/utils/urlsMatch.ts create mode 100644 packages/workbox-window/tsconfig.json diff --git a/docs/package.json b/docs/package.json index 70e3ffb9..cc902af2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,13 +10,13 @@ }, "dependencies": { "@ducanh2912/next-pwa": "workspace:*", - "@mantine/hooks": "7.1.2", + "@mantine/hooks": "7.1.3", "@tabler/icons-react": "2.39.0", "bright": "0.8.4", "client-only": "0.0.1", "contentlayer": "0.3.4", "highlight.js": "11.9.0", - "next": "13.5.4", + "next": "13.5.5", "next-contentlayer": "0.3.4", "react": "18.2.0", "react-dom": "18.2.0", @@ -27,11 +27,11 @@ "zustand": "4.4.3" }, "devDependencies": { - "@types/extend": "3.0.2", - "@types/hast": "3.0.1", - "@types/mdast": "4.0.1", + "@types/extend": "3.0.3", + "@types/hast": "3.0.2", + "@types/mdast": "4.0.2", "@types/mdx": "2.0.8", - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "@types/uuid": "9.0.5", @@ -49,8 +49,8 @@ "rehype-highlight": "7.0.0", "rehype-sanitize": "6.0.0", "tailwindcss": "3.3.3", - "typescript": "5.3.0-dev.20231011", - "unified": "10.1.2", + "typescript": "5.3.0-dev.20231018", + "unified": "11.0.3", "unist-util-is": "6.0.0", "unist-util-visit": "5.0.0" } diff --git a/examples/basic/package.json b/examples/basic/package.json index 9914a2b6..79fb7e42 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@ducanh2912/next-pwa": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/examples/custom-server/package.json b/examples/custom-server/package.json index 1938b2ea..ac25edf8 100644 --- a/examples/custom-server/package.json +++ b/examples/custom-server/package.json @@ -13,14 +13,14 @@ "@ducanh2912/next-pwa": "latest", "@fastify/compress": "6.4.0", "cross-env": "7.0.3", - "fastify": "4.24.0", - "next": "13.5.4", + "fastify": "4.24.2", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@swc/core": "1.3.92", - "@types/node": "20.8.4", + "@swc/core": "1.3.93", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "nodemon": "3.0.1", diff --git a/examples/custom-worker/package.json b/examples/custom-worker/package.json index c3900eb5..b81306d6 100644 --- a/examples/custom-worker/package.json +++ b/examples/custom-worker/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@ducanh2912/next-pwa": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/examples/lifecycle/package.json b/examples/lifecycle/package.json index 3f9887c9..3d937caf 100644 --- a/examples/lifecycle/package.json +++ b/examples/lifecycle/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@ducanh2912/next-pwa": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/examples/next-i18next/package.json b/examples/next-i18next/package.json index eed6fac6..ad72ec41 100644 --- a/examples/next-i18next/package.json +++ b/examples/next-i18next/package.json @@ -15,14 +15,14 @@ "express": "4.18.2", "fastify-compress": "4.1.0", "i18next": "23.5.1", - "next": "13.5.4", + "next": "13.5.5", "next-i18next": "14.0.3", "react": "18.2.0", "react-dom": "18.2.0", - "react-i18next": "13.2.2" + "react-i18next": "13.3.0" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/examples/next-image/package.json b/examples/next-image/package.json index 6d5b9ec3..6e6407d0 100644 --- a/examples/next-image/package.json +++ b/examples/next-image/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@ducanh2912/next-pwa": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/examples/offline-fallback-v2/package.json b/examples/offline-fallback-v2/package.json index 0d094dc7..b6292501 100644 --- a/examples/offline-fallback-v2/package.json +++ b/examples/offline-fallback-v2/package.json @@ -11,13 +11,13 @@ }, "dependencies": { "@ducanh2912/next-pwa": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0", "sharp": "0.32.6" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/examples/web-push/package.json b/examples/web-push/package.json index a8826e35..b2d179ad 100644 --- a/examples/web-push/package.json +++ b/examples/web-push/package.json @@ -12,13 +12,13 @@ }, "dependencies": { "@ducanh2912/next-pwa": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0", "web-push": "3.6.6" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "@types/web-push": "3.6.1", diff --git a/examples/workboxless/package.json b/examples/workboxless/package.json index 98995525..c86fe065 100644 --- a/examples/workboxless/package.json +++ b/examples/workboxless/package.json @@ -10,12 +10,12 @@ }, "dependencies": { "@ducanh2912/next-sw": "latest", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "typescript": "5.2.2" diff --git a/package.json b/package.json index 49001454..bac732be 100644 --- a/package.json +++ b/package.json @@ -34,13 +34,13 @@ "@changesets/cli": "2.26.2", "@ducanh2912/next-pwa": "workspace:*", "@ducanh2912/next-sw": "workspace:*", - "@types/node": "20.8.4", + "@types/node": "20.8.7", "@types/shell-quote": "1.7.2", - "@typescript-eslint/eslint-plugin": "6.7.5", - "@typescript-eslint/parser": "6.7.5", + "@typescript-eslint/eslint-plugin": "6.8.0", + "@typescript-eslint/parser": "6.8.0", "cross-env": "7.0.3", "eslint": "8.51.0", - "eslint-config-next": "13.5.4", + "eslint-config-next": "13.5.5", "eslint-config-prettier": "9.0.0", "eslint-config-turbo": "1.10.15", "eslint-plugin-import": "2.28.1", @@ -48,15 +48,15 @@ "fast-glob": "3.3.1", "husky": "8.0.3", "jest": "29.7.0", - "lint-staged": "14.0.1", - "npm-check-updates": "16.14.5", + "lint-staged": "15.0.1", + "npm-check-updates": "16.14.6", "prettier": "3.0.3", - "prettier-plugin-tailwindcss": "0.5.5", + "prettier-plugin-tailwindcss": "0.5.6", "rimraf": "5.0.5", "shell-quote": "1.8.1", "tslib": "2.6.2", "turbo": "1.10.15", - "typescript": "5.3.0-dev.20231011" + "typescript": "5.3.0-dev.20231018" }, "packageManager": "pnpm@8.7.5" } diff --git a/packages/constants/package.json b/packages/constants/package.json index c8e573e1..29206185 100644 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -19,6 +19,6 @@ } }, "devDependencies": { - "@swc/core": "1.3.92" + "@swc/core": "1.3.93" } } diff --git a/packages/next-pwa/__tests__/package.json b/packages/next-pwa/__tests__/package.json index 51776f8d..36367edb 100644 --- a/packages/next-pwa/__tests__/package.json +++ b/packages/next-pwa/__tests__/package.json @@ -5,7 +5,7 @@ "type": "module", "devDependencies": { "@jest/globals": "29.7.0", - "@types/jest": "29.5.5", + "@types/jest": "29.5.6", "@types/react": "18.2.28", "@types/react-dom": "18.2.13", "tests-utils": "workspace:*" diff --git a/packages/next-pwa/package.json b/packages/next-pwa/package.json index 3f7eba16..b67a2fa5 100644 --- a/packages/next-pwa/package.json +++ b/packages/next-pwa/package.json @@ -74,18 +74,18 @@ "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-swc": "0.2.1", "@rollup/plugin-typescript": "11.1.5", - "@swc/core": "1.3.92", - "@types/node": "20.8.4", + "@swc/core": "1.3.93", + "@types/node": "20.8.7", "@types/semver": "7.5.3", "chalk": "5.3.0", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0", "rollup": "3.28.1", "rollup-plugin-dts": "6.0.2", "type-fest": "4.4.0", - "typescript": "5.3.0-dev.20231011", - "webpack": "5.88.2" + "typescript": "5.3.0-dev.20231018", + "webpack": "5.89.0" }, "peerDependencies": { "next": ">=11.0.0", diff --git a/packages/next-sw/package.json b/packages/next-sw/package.json index 1a454016..2f5d0fb1 100644 --- a/packages/next-sw/package.json +++ b/packages/next-sw/package.json @@ -49,16 +49,16 @@ "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-swc": "0.2.1", "@rollup/plugin-typescript": "11.1.5", - "@swc/core": "1.3.92", - "@types/node": "20.8.4", + "@swc/core": "1.3.93", + "@types/node": "20.8.7", "chalk": "5.3.0", - "next": "13.5.4", + "next": "13.5.5", "react": "18.2.0", "react-dom": "18.2.0", "rollup": "3.28.1", "rollup-plugin-dts": "6.0.2", - "typescript": "5.3.0-dev.20231011", - "webpack": "5.88.2" + "typescript": "5.3.0-dev.20231018", + "webpack": "5.89.0" }, "peerDependencies": { "next": ">=9.1.0" diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index f21a1904..8966d180 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -15,6 +15,6 @@ }, "devDependencies": { "@types/fs-extra": "11.0.2", - "@types/jest": "29.5.5" + "@types/jest": "29.5.6" } } diff --git a/packages/utils/package.json b/packages/utils/package.json index 559c6342..73dcd96b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -36,11 +36,11 @@ "@ducanh2912/constants": "workspace:*", "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-swc": "0.2.1", - "@swc/core": "1.3.92", + "@swc/core": "1.3.93", "@types/semver": "7.5.3", "rollup": "3.28.1", "terser-webpack-plugin": "5.3.9", "type-fest": "4.4.0", - "typescript": "5.3.0-dev.20231011" + "typescript": "5.3.0-dev.20231018" } } diff --git a/packages/workbox-background-sync/README.md b/packages/workbox-background-sync/README.md new file mode 100644 index 00000000..af63198d --- /dev/null +++ b/packages/workbox-background-sync/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-background-sync diff --git a/packages/workbox-background-sync/package.json b/packages/workbox-background-sync/package.json new file mode 100644 index 00000000..dc54c4bc --- /dev/null +++ b/packages/workbox-background-sync/package.json @@ -0,0 +1,30 @@ +{ + "name": "@ducanh2912/workbox-background-sync", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team, DuCanhGH", + "description": "Queues failed requests and uses the Background Sync API to replay them when the network is available", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "background", + "sync", + "workbox-plugin" + ], + "workbox": { + "browserNamespace": "workbox.backgroundSync", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*", + "idb": "7.1.1" + } +} diff --git a/packages/workbox-background-sync/src/BackgroundSyncPlugin.ts b/packages/workbox-background-sync/src/BackgroundSyncPlugin.ts new file mode 100644 index 00000000..085c5cdf --- /dev/null +++ b/packages/workbox-background-sync/src/BackgroundSyncPlugin.ts @@ -0,0 +1,43 @@ +/* + 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 { WorkboxPlugin } from "workbox-core/types.js"; +import { Queue, QueueOptions } from "./Queue.js"; +import "./_version.js"; + +/** + * A class implementing the `fetchDidFail` lifecycle callback. This makes it + * easier to add failed requests to a background sync Queue. + * + * @memberof workbox-background-sync + */ +class BackgroundSyncPlugin implements WorkboxPlugin { + private readonly _queue: Queue; + + /** + * @param {string} name See the {@link workbox-background-sync.Queue} + * documentation for parameter details. + * @param {Object} [options] See the + * {@link workbox-background-sync.Queue} documentation for + * parameter details. + */ + constructor(name: string, options?: QueueOptions) { + this._queue = new Queue(name, options); + } + + /** + * @param {Object} options + * @param {Request} options.request + * @private + */ + fetchDidFail: WorkboxPlugin["fetchDidFail"] = async ({ request }) => { + await this._queue.pushRequest({ request }); + }; +} + +export { BackgroundSyncPlugin }; diff --git a/packages/workbox-background-sync/src/Queue.ts b/packages/workbox-background-sync/src/Queue.ts new file mode 100644 index 00000000..aed9f298 --- /dev/null +++ b/packages/workbox-background-sync/src/Queue.ts @@ -0,0 +1,487 @@ +/* + 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 { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { assert } from "workbox-core/_private/assert.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { QueueStore } from "./lib/QueueStore.js"; +import { QueueStoreEntry, UnidentifiedQueueStoreEntry } from "./lib/QueueDb.js"; +import { StorableRequest } from "./lib/StorableRequest.js"; +import "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +interface OnSyncCallbackOptions { + queue: Queue; +} + +interface OnSyncCallback { + (options: OnSyncCallbackOptions): void | Promise; +} + +export interface QueueOptions { + forceSyncFallback?: boolean; + maxRetentionTime?: number; + onSync?: OnSyncCallback; +} + +interface QueueEntry { + request: Request; + timestamp?: number; + // We could use Record as a type but that would be a breaking + // change, better do it in next major release. + // eslint-disable-next-line @typescript-eslint/ban-types + metadata?: object; +} + +const TAG_PREFIX = "workbox-background-sync"; +const MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes + +const queueNames = new Set(); + +/** + * Converts a QueueStore entry into the format exposed by Queue. This entails + * converting the request data into a real request and omitting the `id` and + * `queueName` properties. + * + * @param {UnidentifiedQueueStoreEntry} queueStoreEntry + * @return {Queue} + * @private + */ +const convertEntry = ( + queueStoreEntry: UnidentifiedQueueStoreEntry +): QueueEntry => { + const queueEntry: QueueEntry = { + request: new StorableRequest(queueStoreEntry.requestData).toRequest(), + timestamp: queueStoreEntry.timestamp, + }; + if (queueStoreEntry.metadata) { + queueEntry.metadata = queueStoreEntry.metadata; + } + return queueEntry; +}; + +/** + * A class to manage storing failed requests in IndexedDB and retrying them + * later. All parts of the storing and replaying process are observable via + * callbacks. + * + * @memberof workbox-background-sync + */ +class Queue { + private readonly _name: string; + private readonly _onSync: OnSyncCallback; + private readonly _maxRetentionTime: number; + private readonly _queueStore: QueueStore; + private readonly _forceSyncFallback: boolean; + private _syncInProgress = false; + private _requestsAddedDuringSync = false; + + /** + * Creates an instance of Queue with the given options + * + * @param {string} name The unique name for this queue. This name must be + * unique as it's used to register sync events and store requests + * in IndexedDB specific to this instance. An error will be thrown if + * a duplicate name is detected. + * @param {Object} [options] + * @param {Function} [options.onSync] A function that gets invoked whenever + * the 'sync' event fires. The function is invoked with an object + * containing the `queue` property (referencing this instance), and you + * can use the callback to customize the replay behavior of the queue. + * When not set the `replayRequests()` method is called. + * Note: if the replay fails after a sync event, make sure you throw an + * error, so the browser knows to retry the sync event later. + * @param {number} [options.maxRetentionTime=7 days] The amount of time (in + * minutes) a request may be retried. After this amount of time has + * passed, the request will be deleted from the queue. + * @param {boolean} [options.forceSyncFallback=false] If `true`, instead + * of attempting to use background sync events, always attempt to replay + * queued request at service worker startup. Most folks will not need + * this, unless you explicitly target a runtime like Electron that + * exposes the interfaces for background sync, but does not have a working + * implementation. + */ + constructor( + name: string, + { forceSyncFallback, onSync, maxRetentionTime }: QueueOptions = {} + ) { + // Ensure the store name is not already being used + if (queueNames.has(name)) { + throw new WorkboxError("duplicate-queue-name", { name }); + } else { + queueNames.add(name); + } + + this._name = name; + this._onSync = onSync || this.replayRequests; + this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME; + this._forceSyncFallback = Boolean(forceSyncFallback); + this._queueStore = new QueueStore(this._name); + + this._addSyncListener(); + } + + /** + * @return {string} + */ + get name(): string { + return this._name; + } + + /** + * Stores the passed request in IndexedDB (with its timestamp and any + * metadata) at the end of the queue. + * + * @param {QueueEntry} entry + * @param {Request} entry.request The request to store in the queue. + * @param {Object} [entry.metadata] Any metadata you want associated with the + * stored request. When requests are replayed you'll have access to this + * metadata object in case you need to modify the request beforehand. + * @param {number} [entry.timestamp] The timestamp (Epoch time in + * milliseconds) when the request was first added to the queue. This is + * used along with `maxRetentionTime` to remove outdated requests. In + * general you don't need to set this value, as it's automatically set + * for you (defaulting to `Date.now()`), but you can update it if you + * don't want particular requests to expire. + */ + async pushRequest(entry: QueueEntry): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isType(entry, "object", { + moduleName: "workbox-background-sync", + className: "Queue", + funcName: "pushRequest", + paramName: "entry", + }); + assert!.isInstance(entry.request, Request, { + moduleName: "workbox-background-sync", + className: "Queue", + funcName: "pushRequest", + paramName: "entry.request", + }); + } + + await this._addRequest(entry, "push"); + } + + /** + * Stores the passed request in IndexedDB (with its timestamp and any + * metadata) at the beginning of the queue. + * + * @param {QueueEntry} entry + * @param {Request} entry.request The request to store in the queue. + * @param {Object} [entry.metadata] Any metadata you want associated with the + * stored request. When requests are replayed you'll have access to this + * metadata object in case you need to modify the request beforehand. + * @param {number} [entry.timestamp] The timestamp (Epoch time in + * milliseconds) when the request was first added to the queue. This is + * used along with `maxRetentionTime` to remove outdated requests. In + * general you don't need to set this value, as it's automatically set + * for you (defaulting to `Date.now()`), but you can update it if you + * don't want particular requests to expire. + */ + async unshiftRequest(entry: QueueEntry): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isType(entry, "object", { + moduleName: "workbox-background-sync", + className: "Queue", + funcName: "unshiftRequest", + paramName: "entry", + }); + assert!.isInstance(entry.request, Request, { + moduleName: "workbox-background-sync", + className: "Queue", + funcName: "unshiftRequest", + paramName: "entry.request", + }); + } + + await this._addRequest(entry, "unshift"); + } + + /** + * Removes and returns the last request in the queue (along with its + * timestamp and any metadata). The returned object takes the form: + * `{request, timestamp, metadata}`. + * + * @return {Promise} + */ + async popRequest(): Promise { + return this._removeRequest("pop"); + } + + /** + * Removes and returns the first request in the queue (along with its + * timestamp and any metadata). The returned object takes the form: + * `{request, timestamp, metadata}`. + * + * @return {Promise} + */ + async shiftRequest(): Promise { + return this._removeRequest("shift"); + } + + /** + * Returns all the entries that have not expired (per `maxRetentionTime`). + * Any expired entries are removed from the queue. + * + * @return {Promise>} + */ + async getAll(): Promise> { + const allEntries = await this._queueStore.getAll(); + const now = Date.now(); + + const unexpiredEntries = []; + for (const entry of allEntries) { + // Ignore requests older than maxRetentionTime. Call this function + // recursively until an unexpired request is found. + const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000; + if (now - entry.timestamp > maxRetentionTimeInMs) { + await this._queueStore.deleteEntry(entry.id); + } else { + unexpiredEntries.push(convertEntry(entry)); + } + } + + return unexpiredEntries; + } + + /** + * Returns the number of entries present in the queue. + * Note that expired entries (per `maxRetentionTime`) are also included in this count. + * + * @return {Promise} + */ + async size(): Promise { + return await this._queueStore.size(); + } + + /** + * Adds the entry to the QueueStore and registers for a sync event. + * + * @param {Object} entry + * @param {Request} entry.request + * @param {Object} [entry.metadata] + * @param {number} [entry.timestamp=Date.now()] + * @param {string} operation ('push' or 'unshift') + * @private + */ + async _addRequest( + { request, metadata, timestamp = Date.now() }: QueueEntry, + operation: "push" | "unshift" + ): Promise { + const storableRequest = await StorableRequest.fromRequest(request.clone()); + const entry: UnidentifiedQueueStoreEntry = { + requestData: storableRequest.toObject(), + timestamp, + }; + + // Only include metadata if it's present. + if (metadata) { + entry.metadata = metadata; + } + + switch (operation) { + case "push": + await this._queueStore.pushEntry(entry); + break; + case "unshift": + await this._queueStore.unshiftEntry(entry); + break; + } + + if (process.env.NODE_ENV !== "production") { + logger.log( + `Request for '${getFriendlyURL(request.url)}' has ` + + `been added to background sync queue '${this._name}'.` + ); + } + + // Don't register for a sync if we're in the middle of a sync. Instead, + // we wait until the sync is complete and call register if + // `this._requestsAddedDuringSync` is true. + if (this._syncInProgress) { + this._requestsAddedDuringSync = true; + } else { + await this.registerSync(); + } + } + + /** + * Removes and returns the first or last (depending on `operation`) entry + * from the QueueStore that's not older than the `maxRetentionTime`. + * + * @param {string} operation ('pop' or 'shift') + * @return {Object|undefined} + * @private + */ + async _removeRequest( + operation: "pop" | "shift" + ): Promise { + const now = Date.now(); + let entry: QueueStoreEntry | undefined; + switch (operation) { + case "pop": + entry = await this._queueStore.popEntry(); + break; + case "shift": + entry = await this._queueStore.shiftEntry(); + break; + } + + if (entry) { + // Ignore requests older than maxRetentionTime. Call this function + // recursively until an unexpired request is found. + const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000; + if (now - entry.timestamp > maxRetentionTimeInMs) { + return this._removeRequest(operation); + } + + return convertEntry(entry); + } else { + return undefined; + } + } + + /** + * Loops through each request in the queue and attempts to re-fetch it. + * If any request fails to re-fetch, it's put back in the same position in + * the queue (which registers a retry for the next sync event). + */ + async replayRequests(): Promise { + let entry; + while ((entry = await this.shiftRequest())) { + try { + await fetch(entry.request.clone()); + + if (process.env.NODE_ENV !== "production") { + logger.log( + `Request for '${getFriendlyURL(entry.request.url)}' ` + + `has been replayed in queue '${this._name}'` + ); + } + } catch (error) { + await this.unshiftRequest(entry); + + if (process.env.NODE_ENV !== "production") { + logger.log( + `Request for '${getFriendlyURL(entry.request.url)}' ` + + `failed to replay, putting it back in queue '${this._name}'` + ); + } + throw new WorkboxError("queue-replay-failed", { name: this._name }); + } + } + if (process.env.NODE_ENV !== "production") { + logger.log( + `All requests in queue '${this.name}' have successfully ` + + `replayed; the queue is now empty!` + ); + } + } + + /** + * Registers a sync event with a tag unique to this instance. + */ + async registerSync(): Promise { + // See https://github.com/GoogleChrome/workbox/issues/2393 + if ("sync" in self.registration && !this._forceSyncFallback) { + try { + await self.registration.sync.register(`${TAG_PREFIX}:${this._name}`); + } catch (err) { + // This means the registration failed for some reason, possibly due to + // the user disabling it. + if (process.env.NODE_ENV !== "production") { + logger.warn( + `Unable to register sync event for '${this._name}'.`, + err + ); + } + } + } + } + + /** + * In sync-supporting browsers, this adds a listener for the sync event. + * In non-sync-supporting browsers, or if _forceSyncFallback is true, this + * will retry the queue on service worker startup. + * + * @private + */ + private _addSyncListener() { + // See https://github.com/GoogleChrome/workbox/issues/2393 + if ("sync" in self.registration && !this._forceSyncFallback) { + self.addEventListener("sync", (event: SyncEvent) => { + if (event.tag === `${TAG_PREFIX}:${this._name}`) { + if (process.env.NODE_ENV !== "production") { + logger.log( + `Background sync for tag '${event.tag}' ` + `has been received` + ); + } + + const syncComplete = async () => { + this._syncInProgress = true; + + let syncError; + try { + await this._onSync({ queue: this }); + } catch (error) { + if (error instanceof Error) { + syncError = error; + + // Rethrow the error. Note: the logic in the finally clause + // will run before this gets rethrown. + throw syncError; + } + } finally { + // New items may have been added to the queue during the sync, + // so we need to register for a new sync if that's happened... + // Unless there was an error during the sync, in which + // case the browser will automatically retry later, as long + // as `event.lastChance` is not true. + if ( + this._requestsAddedDuringSync && + !(syncError && !event.lastChance) + ) { + await this.registerSync(); + } + + this._syncInProgress = false; + this._requestsAddedDuringSync = false; + } + }; + event.waitUntil(syncComplete()); + } + }); + } else { + if (process.env.NODE_ENV !== "production") { + logger.log(`Background sync replaying without background sync event`); + } + // If the browser doesn't support background sync, or the developer has + // opted-in to not using it, retry every time the service worker starts up + // as a fallback. + void this._onSync({ queue: this }); + } + } + + /** + * Returns the set of queue names. This is primarily used to reset the list + * of queue names in tests. + * + * @return {Set} + * + * @private + */ + static get _queueNames(): Set { + return queueNames; + } +} + +export { Queue }; diff --git a/packages/workbox-background-sync/src/QueueStore.ts b/packages/workbox-background-sync/src/QueueStore.ts new file mode 100644 index 00000000..eb078d61 --- /dev/null +++ b/packages/workbox-background-sync/src/QueueStore.ts @@ -0,0 +1,14 @@ +/* + 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 "./_version.js"; + +// This is a temporary workaround to expose something from ./lib/ via our +// top-level public API. +// TODO: In Workbox v7, move the actual code from ./lib/ to this file. +export { QueueStore } from "./lib/QueueStore"; diff --git a/packages/workbox-background-sync/src/StorableRequest.ts b/packages/workbox-background-sync/src/StorableRequest.ts new file mode 100644 index 00000000..75cfe78b --- /dev/null +++ b/packages/workbox-background-sync/src/StorableRequest.ts @@ -0,0 +1,14 @@ +/* + 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 "./_version.js"; + +// This is a temporary workaround to expose something from ./lib/ via our +// top-level public API. +// TODO: In Workbox v7, move the actual code from ./lib/ to this file. +export { StorableRequest } from "./lib/StorableRequest"; diff --git a/packages/workbox-background-sync/src/_version.ts b/packages/workbox-background-sync/src/_version.ts new file mode 100644 index 00000000..a09900db --- /dev/null +++ b/packages/workbox-background-sync/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:background-sync:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-background-sync/src/index.ts b/packages/workbox-background-sync/src/index.ts new file mode 100644 index 00000000..12115875 --- /dev/null +++ b/packages/workbox-background-sync/src/index.ts @@ -0,0 +1,46 @@ +/* + 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 { BackgroundSyncPlugin } from "./BackgroundSyncPlugin.js"; +import { Queue, QueueOptions } from "./Queue.js"; +import { QueueStore } from "./QueueStore.js"; +import { StorableRequest } from "./StorableRequest.js"; + +import "./_version.js"; + +// See https://github.com/GoogleChrome/workbox/issues/2946 +interface SyncManager { + getTags(): Promise; + register(tag: string): Promise; +} + +declare global { + interface ServiceWorkerRegistration { + readonly sync: SyncManager; + } + + interface SyncEvent extends ExtendableEvent { + readonly lastChance: boolean; + readonly tag: string; + } + + interface ServiceWorkerGlobalScopeEventMap { + sync: SyncEvent; + } +} + +/** + * @module workbox-background-sync + */ +export { + BackgroundSyncPlugin, + Queue, + QueueOptions, + QueueStore, + StorableRequest, +}; diff --git a/packages/workbox-background-sync/src/lib/QueueDb.ts b/packages/workbox-background-sync/src/lib/QueueDb.ts new file mode 100644 index 00000000..409fa676 --- /dev/null +++ b/packages/workbox-background-sync/src/lib/QueueDb.ts @@ -0,0 +1,200 @@ +/* + 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 { openDB, DBSchema, IDBPDatabase } from "idb"; +import { RequestData } from "./StorableRequest.js"; +import "../_version.js"; + +interface QueueDBSchema extends DBSchema { + requests: { + key: number; + value: QueueStoreEntry; + indexes: { queueName: string }; + }; +} + +const DB_VERSION = 3; +const DB_NAME = "workbox-background-sync"; +const REQUEST_OBJECT_STORE_NAME = "requests"; +const QUEUE_NAME_INDEX = "queueName"; + +export interface UnidentifiedQueueStoreEntry { + requestData: RequestData; + timestamp: number; + id?: number; + queueName?: string; + // We could use Record as a type but that would be a breaking + // change, better do it in next major release. + // eslint-disable-next-line @typescript-eslint/ban-types + metadata?: object; +} + +export interface QueueStoreEntry extends UnidentifiedQueueStoreEntry { + id: number; +} + +/** + * A class to interact directly an IndexedDB created specifically to save and + * retrieve QueueStoreEntries. This class encapsulates all the schema details + * to store the representation of a Queue. + * + * @private + */ + +export class QueueDb { + private _db: IDBPDatabase | null = null; + + /** + * Add QueueStoreEntry to underlying db. + * + * @param {UnidentifiedQueueStoreEntry} entry + */ + async addEntry(entry: UnidentifiedQueueStoreEntry): Promise { + const db = await this.getDb(); + const tx = db.transaction(REQUEST_OBJECT_STORE_NAME, "readwrite", { + durability: "relaxed", + }); + await tx.store.add(entry as QueueStoreEntry); + await tx.done; + } + + /** + * Returns the first entry id in the ObjectStore. + * + * @return {number | undefined} + */ + async getFirstEntryId(): Promise { + const db = await this.getDb(); + const cursor = await db + .transaction(REQUEST_OBJECT_STORE_NAME) + .store.openCursor(); + return cursor?.value.id; + } + + /** + * Get all the entries filtered by index + * + * @param queueName + * @return {Promise} + */ + async getAllEntriesByQueueName( + queueName: string + ): Promise { + const db = await this.getDb(); + const results = await db.getAllFromIndex( + REQUEST_OBJECT_STORE_NAME, + QUEUE_NAME_INDEX, + IDBKeyRange.only(queueName) + ); + return results ? results : new Array(); + } + + /** + * Returns the number of entries filtered by index + * + * @param queueName + * @return {Promise} + */ + async getEntryCountByQueueName(queueName: string): Promise { + const db = await this.getDb(); + return db.countFromIndex( + REQUEST_OBJECT_STORE_NAME, + QUEUE_NAME_INDEX, + IDBKeyRange.only(queueName) + ); + } + + /** + * Deletes a single entry by id. + * + * @param {number} id the id of the entry to be deleted + */ + async deleteEntry(id: number): Promise { + const db = await this.getDb(); + await db.delete(REQUEST_OBJECT_STORE_NAME, id); + } + + /** + * + * @param queueName + * @returns {Promise} + */ + async getFirstEntryByQueueName( + queueName: string + ): Promise { + return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), "next"); + } + + /** + * + * @param queueName + * @returns {Promise} + */ + async getLastEntryByQueueName( + queueName: string + ): Promise { + return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), "prev"); + } + + /** + * Returns either the first or the last entries, depending on direction. + * Filtered by index. + * + * @param {IDBCursorDirection} direction + * @param {IDBKeyRange} query + * @return {Promise} + * @private + */ + async getEndEntryFromIndex( + query: IDBKeyRange, + direction: IDBCursorDirection + ): Promise { + const db = await this.getDb(); + + const cursor = await db + .transaction(REQUEST_OBJECT_STORE_NAME) + .store.index(QUEUE_NAME_INDEX) + .openCursor(query, direction); + return cursor?.value; + } + + /** + * Returns an open connection to the database. + * + * @private + */ + private async getDb() { + if (!this._db) { + this._db = await openDB(DB_NAME, DB_VERSION, { + upgrade: this._upgradeDb, + }); + } + return this._db; + } + + /** + * Upgrades QueueDB + * + * @param {IDBPDatabase} db + * @param {number} oldVersion + * @private + */ + private _upgradeDb(db: IDBPDatabase, oldVersion: number) { + if (oldVersion > 0 && oldVersion < DB_VERSION) { + if (db.objectStoreNames.contains(REQUEST_OBJECT_STORE_NAME)) { + db.deleteObjectStore(REQUEST_OBJECT_STORE_NAME); + } + } + + const objStore = db.createObjectStore(REQUEST_OBJECT_STORE_NAME, { + autoIncrement: true, + keyPath: "id", + }); + objStore.createIndex(QUEUE_NAME_INDEX, QUEUE_NAME_INDEX, { unique: false }); + } +} diff --git a/packages/workbox-background-sync/src/lib/QueueStore.ts b/packages/workbox-background-sync/src/lib/QueueStore.ts new file mode 100644 index 00000000..3f3e0dbc --- /dev/null +++ b/packages/workbox-background-sync/src/lib/QueueStore.ts @@ -0,0 +1,179 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { + UnidentifiedQueueStoreEntry, + QueueStoreEntry, + QueueDb, +} from "./QueueDb.js"; +import "../_version.js"; + +/** + * A class to manage storing requests from a Queue in IndexedDB, + * indexed by their queue name for easier access. + * + * Most developers will not need to access this class directly; + * it is exposed for advanced use cases. + */ +export class QueueStore { + private readonly _queueName: string; + private readonly _queueDb: QueueDb; + + /** + * Associates this instance with a Queue instance, so entries added can be + * identified by their queue name. + * + * @param {string} queueName + */ + constructor(queueName: string) { + this._queueName = queueName; + this._queueDb = new QueueDb(); + } + + /** + * Append an entry last in the queue. + * + * @param {Object} entry + * @param {Object} entry.requestData + * @param {number} [entry.timestamp] + * @param {Object} [entry.metadata] + */ + async pushEntry(entry: UnidentifiedQueueStoreEntry): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isType(entry, "object", { + moduleName: "workbox-background-sync", + className: "QueueStore", + funcName: "pushEntry", + paramName: "entry", + }); + assert!.isType(entry.requestData, "object", { + moduleName: "workbox-background-sync", + className: "QueueStore", + funcName: "pushEntry", + paramName: "entry.requestData", + }); + } + + // Don't specify an ID since one is automatically generated. + delete entry.id; + entry.queueName = this._queueName; + + await this._queueDb.addEntry(entry); + } + + /** + * Prepend an entry first in the queue. + * + * @param {Object} entry + * @param {Object} entry.requestData + * @param {number} [entry.timestamp] + * @param {Object} [entry.metadata] + */ + async unshiftEntry(entry: UnidentifiedQueueStoreEntry): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isType(entry, "object", { + moduleName: "workbox-background-sync", + className: "QueueStore", + funcName: "unshiftEntry", + paramName: "entry", + }); + assert!.isType(entry.requestData, "object", { + moduleName: "workbox-background-sync", + className: "QueueStore", + funcName: "unshiftEntry", + paramName: "entry.requestData", + }); + } + + const firstId = await this._queueDb.getFirstEntryId(); + + if (firstId) { + // Pick an ID one less than the lowest ID in the object store. + entry.id = firstId - 1; + } else { + // Otherwise let the auto-incrementor assign the ID. + delete entry.id; + } + entry.queueName = this._queueName; + + await this._queueDb.addEntry(entry); + } + + /** + * Removes and returns the last entry in the queue matching the `queueName`. + * + * @return {Promise} + */ + async popEntry(): Promise { + return this._removeEntry( + await this._queueDb.getLastEntryByQueueName(this._queueName) + ); + } + + /** + * Removes and returns the first entry in the queue matching the `queueName`. + * + * @return {Promise} + */ + async shiftEntry(): Promise { + return this._removeEntry( + await this._queueDb.getFirstEntryByQueueName(this._queueName) + ); + } + + /** + * Returns all entries in the store matching the `queueName`. + * + * @param {Object} options See {@link workbox-background-sync.Queue~getAll} + * @return {Promise>} + */ + async getAll(): Promise { + return await this._queueDb.getAllEntriesByQueueName(this._queueName); + } + + /** + * Returns the number of entries in the store matching the `queueName`. + * + * @param {Object} options See {@link workbox-background-sync.Queue~size} + * @return {Promise} + */ + async size(): Promise { + return await this._queueDb.getEntryCountByQueueName(this._queueName); + } + + /** + * Deletes the entry for the given ID. + * + * WARNING: this method does not ensure the deleted entry belongs to this + * queue (i.e. matches the `queueName`). But this limitation is acceptable + * as this class is not publicly exposed. An additional check would make + * this method slower than it needs to be. + * + * @param {number} id + */ + async deleteEntry(id: number): Promise { + await this._queueDb.deleteEntry(id); + } + + /** + * Removes and returns the first or last entry in the queue (based on the + * `direction` argument) matching the `queueName`. + * + * @return {Promise} + * @private + */ + async _removeEntry( + entry?: QueueStoreEntry + ): Promise { + if (entry) { + await this.deleteEntry(entry.id); + } + return entry; + } +} diff --git a/packages/workbox-background-sync/src/lib/StorableRequest.ts b/packages/workbox-background-sync/src/lib/StorableRequest.ts new file mode 100644 index 00000000..c648965c --- /dev/null +++ b/packages/workbox-background-sync/src/lib/StorableRequest.ts @@ -0,0 +1,156 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { MapLikeObject } from "workbox-core/types.js"; +import "../_version.js"; + +type SerializableProperties = + | "method" + | "referrer" + | "referrerPolicy" + | "mode" + | "credentials" + | "cache" + | "redirect" + | "integrity" + | "keepalive"; + +const serializableProperties: SerializableProperties[] = [ + "method", + "referrer", + "referrerPolicy", + "mode", + "credentials", + "cache", + "redirect", + "integrity", + "keepalive", +]; + +export interface RequestData extends MapLikeObject { + url: string; + headers: MapLikeObject; + body?: ArrayBuffer; +} + +/** + * A class to make it easier to serialize and de-serialize requests so they + * can be stored in IndexedDB. + * + * Most developers will not need to access this class directly; + * it is exposed for advanced use cases. + */ +class StorableRequest { + private readonly _requestData: RequestData; + + /** + * Converts a Request object to a plain object that can be structured + * cloned or JSON-stringified. + * + * @param {Request} request + * @return {Promise} + */ + static async fromRequest(request: Request): Promise { + const requestData: RequestData = { + url: request.url, + headers: {}, + }; + + // Set the body if present. + if (request.method !== "GET") { + // Use ArrayBuffer to support non-text request bodies. + // NOTE: we can't use Blobs becuse Safari doesn't support storing + // Blobs in IndexedDB in some cases: + // https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457 + requestData.body = await request.clone().arrayBuffer(); + } + + // Convert the headers from an iterable to an object. + for (const [key, value] of request.headers.entries()) { + requestData.headers[key] = value; + } + + // Add all other serializable request properties + for (const prop of serializableProperties) { + if (request[prop] !== undefined) { + requestData[prop] = request[prop]; + } + } + + return new StorableRequest(requestData); + } + + /** + * Accepts an object of request data that can be used to construct a + * `Request` but can also be stored in IndexedDB. + * + * @param {Object} requestData An object of request data that includes the + * `url` plus any relevant properties of + * [requestInit]{@link https://fetch.spec.whatwg.org/#requestinit}. + */ + constructor(requestData: RequestData) { + if (process.env.NODE_ENV !== "production") { + assert!.isType(requestData, "object", { + moduleName: "workbox-background-sync", + className: "StorableRequest", + funcName: "constructor", + paramName: "requestData", + }); + assert!.isType(requestData.url, "string", { + moduleName: "workbox-background-sync", + className: "StorableRequest", + funcName: "constructor", + paramName: "requestData.url", + }); + } + + // If the request's mode is `navigate`, convert it to `same-origin` since + // navigation requests can't be constructed via script. + if (requestData["mode"] === "navigate") { + requestData["mode"] = "same-origin"; + } + + this._requestData = requestData; + } + + /** + * Returns a deep clone of the instances `_requestData` object. + * + * @return {Object} + */ + toObject(): RequestData { + const requestData = Object.assign({}, this._requestData); + requestData.headers = Object.assign({}, this._requestData.headers); + if (requestData.body) { + requestData.body = requestData.body.slice(0); + } + + return requestData; + } + + /** + * Converts this instance to a Request. + * + * @return {Request} + */ + toRequest(): Request { + return new Request(this._requestData.url, this._requestData); + } + + /** + * Creates and returns a deep clone of the instance. + * + * @return {StorableRequest} + */ + clone(): StorableRequest { + return new StorableRequest(this.toObject()); + } +} + +export { StorableRequest }; diff --git a/packages/workbox-background-sync/tsconfig.json b/packages/workbox-background-sync/tsconfig.json new file mode 100644 index 00000000..0468b457 --- /dev/null +++ b/packages/workbox-background-sync/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-broadcast-update/README.md b/packages/workbox-broadcast-update/README.md new file mode 100644 index 00000000..a6796d28 --- /dev/null +++ b/packages/workbox-broadcast-update/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-broadcast-update diff --git a/packages/workbox-broadcast-update/package.json b/packages/workbox-broadcast-update/package.json new file mode 100644 index 00000000..c1625681 --- /dev/null +++ b/packages/workbox-broadcast-update/package.json @@ -0,0 +1,27 @@ +{ + "name": "@ducanh2912/workbox-broadcast-update", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "A service worker helper library that uses the Broadcast Channel API to announce when a cached response has updated", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "workbox-plugin" + ], + "workbox": { + "browserNamespace": "workbox.broadcastUpdate", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "7.0.0" + } +} diff --git a/packages/workbox-broadcast-update/src/BroadcastCacheUpdate.ts b/packages/workbox-broadcast-update/src/BroadcastCacheUpdate.ts new file mode 100644 index 00000000..f2eca47b --- /dev/null +++ b/packages/workbox-broadcast-update/src/BroadcastCacheUpdate.ts @@ -0,0 +1,215 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { timeout } from "workbox-core/_private/timeout.js"; +import { resultingClientExists } from "workbox-core/_private/resultingClientExists.js"; +import { CacheDidUpdateCallbackParam } from "workbox-core/types.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { responsesAreSame } from "./responsesAreSame.js"; +import { + CACHE_UPDATED_MESSAGE_META, + CACHE_UPDATED_MESSAGE_TYPE, + DEFAULT_HEADERS_TO_CHECK, + NOTIFY_ALL_CLIENTS, +} from "./utils/constants.js"; + +import "./_version.js"; + +// UA-sniff Safari: https://stackoverflow.com/questions/7944460/detect-safari-browser +// TODO(philipwalton): remove once this Safari bug fix has been released. +// https://bugs.webkit.org/show_bug.cgi?id=201169 +const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +export interface BroadcastCacheUpdateOptions { + headersToCheck?: string[]; + generatePayload?: ( + options: CacheDidUpdateCallbackParam + ) => Record; + notifyAllClients?: boolean; +} + +/** + * Generates the default payload used in update messages. By default the + * payload includes the `cacheName` and `updatedURL` fields. + * + * @return Object + * @private + */ +function defaultPayloadGenerator( + data: CacheDidUpdateCallbackParam +): Record { + return { + cacheName: data.cacheName, + updatedURL: data.request.url, + }; +} + +/** + * Uses the `postMessage()` API to inform any open windows/tabs when a cached + * response has been updated. + * + * For efficiency's sake, the underlying response bodies are not compared; + * only specific response headers are checked. + * + * @memberof workbox-broadcast-update + */ +class BroadcastCacheUpdate { + private readonly _headersToCheck: string[]; + private readonly _generatePayload: ( + options: CacheDidUpdateCallbackParam + ) => Record; + private readonly _notifyAllClients: boolean; + + /** + * Construct a BroadcastCacheUpdate instance with a specific `channelName` to + * broadcast messages on + * + * @param {Object} [options] + * @param {Array} [options.headersToCheck=['content-length', 'etag', 'last-modified']] + * A list of headers that will be used to determine whether the responses + * differ. + * @param {string} [options.generatePayload] A function whose return value + * will be used as the `payload` field in any cache update messages sent + * to the window clients. + * @param {boolean} [options.notifyAllClients=true] If true (the default) then + * all open clients will receive a message. If false, then only the client + * that make the original request will be notified of the update. + */ + constructor({ + generatePayload, + headersToCheck, + notifyAllClients, + }: BroadcastCacheUpdateOptions = {}) { + this._headersToCheck = headersToCheck || DEFAULT_HEADERS_TO_CHECK; + this._generatePayload = generatePayload || defaultPayloadGenerator; + this._notifyAllClients = notifyAllClients ?? NOTIFY_ALL_CLIENTS; + } + + /** + * Compares two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response) + * and sends a message (via `postMessage()`) to all window clients if the + * responses differ. Neither of the Responses can be + * [opaque](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses). + * + * The message that's posted has the following format (where `payload` can + * be customized via the `generatePayload` option the instance is created + * with): + * + * ``` + * { + * type: 'CACHE_UPDATED', + * meta: 'workbox-broadcast-update', + * payload: { + * cacheName: 'the-cache-name', + * updatedURL: 'https://example.com/' + * } + * } + * ``` + * + * @param {Object} options + * @param {Response} [options.oldResponse] Cached response to compare. + * @param {Response} options.newResponse Possibly updated response to compare. + * @param {Request} options.request The request. + * @param {string} options.cacheName Name of the cache the responses belong + * to. This is included in the broadcast message. + * @param {Event} options.event event The event that triggered + * this possible cache update. + * @return {Promise} Resolves once the update is sent. + */ + async notifyIfUpdated(options: CacheDidUpdateCallbackParam): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isType(options.cacheName, "string", { + moduleName: "workbox-broadcast-update", + className: "BroadcastCacheUpdate", + funcName: "notifyIfUpdated", + paramName: "cacheName", + }); + assert!.isInstance(options.newResponse, Response, { + moduleName: "workbox-broadcast-update", + className: "BroadcastCacheUpdate", + funcName: "notifyIfUpdated", + paramName: "newResponse", + }); + assert!.isInstance(options.request, Request, { + moduleName: "workbox-broadcast-update", + className: "BroadcastCacheUpdate", + funcName: "notifyIfUpdated", + paramName: "request", + }); + } + + // Without two responses there is nothing to compare. + if (!options.oldResponse) { + return; + } + + if ( + !responsesAreSame( + options.oldResponse, + options.newResponse, + this._headersToCheck + ) + ) { + if (process.env.NODE_ENV !== "production") { + logger.log( + `Newer response found (and cached) for:`, + options.request.url + ); + } + + const messageData = { + type: CACHE_UPDATED_MESSAGE_TYPE, + meta: CACHE_UPDATED_MESSAGE_META, + payload: this._generatePayload(options), + }; + + // For navigation requests, wait until the new window client exists + // before sending the message + if (options.request.mode === "navigate") { + let resultingClientId: string | undefined; + if (options.event instanceof FetchEvent) { + resultingClientId = options.event.resultingClientId; + } + + const resultingWin = await resultingClientExists(resultingClientId); + + // Safari does not currently implement postMessage buffering and + // there's no good way to feature detect that, so to increase the + // chances of the message being delivered in Safari, we add a timeout. + // We also do this if `resultingClientExists()` didn't return a client, + // which means it timed out, so it's worth waiting a bit longer. + if (!resultingWin || isSafari) { + // 3500 is chosen because (according to CrUX data) 80% of mobile + // websites hit the DOMContentLoaded event in less than 3.5 seconds. + // And presumably sites implementing service worker are on the + // higher end of the performance spectrum. + await timeout(3500); + } + } + + if (this._notifyAllClients) { + const windows = await self.clients.matchAll({ type: "window" }); + for (const win of windows) { + win.postMessage(messageData); + } + } else { + // See https://github.com/GoogleChrome/workbox/issues/2895 + if (options.event instanceof FetchEvent) { + const client = await self.clients.get(options.event.clientId); + client?.postMessage(messageData); + } + } + } + } +} + +export { BroadcastCacheUpdate }; diff --git a/packages/workbox-broadcast-update/src/BroadcastUpdatePlugin.ts b/packages/workbox-broadcast-update/src/BroadcastUpdatePlugin.ts new file mode 100644 index 00000000..9bbb967b --- /dev/null +++ b/packages/workbox-broadcast-update/src/BroadcastUpdatePlugin.ts @@ -0,0 +1,63 @@ +/* + 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 { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; +import { WorkboxPlugin } from "workbox-core/types.js"; + +import { + BroadcastCacheUpdate, + BroadcastCacheUpdateOptions, +} from "./BroadcastCacheUpdate.js"; + +import "./_version.js"; + +/** + * This plugin will automatically broadcast a message whenever a cached response + * is updated. + * + * @memberof workbox-broadcast-update + */ +class BroadcastUpdatePlugin implements WorkboxPlugin { + private readonly _broadcastUpdate: BroadcastCacheUpdate; + + /** + * Construct a {@link workbox-broadcast-update.BroadcastUpdate} instance with + * the passed options and calls its `notifyIfUpdated` method whenever the + * plugin's `cacheDidUpdate` callback is invoked. + * + * @param {Object} [options] + * @param {Array} [options.headersToCheck=['content-length', 'etag', 'last-modified']] + * A list of headers that will be used to determine whether the responses + * differ. + * @param {string} [options.generatePayload] A function whose return value + * will be used as the `payload` field in any cache update messages sent + * to the window clients. + */ + constructor(options?: BroadcastCacheUpdateOptions) { + this._broadcastUpdate = new BroadcastCacheUpdate(options); + } + + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is + * added to a cache. + * + * @private + * @param {Object} options The input object to this function. + * @param {string} options.cacheName Name of the cache being updated. + * @param {Response} [options.oldResponse] The previous cached value, if any. + * @param {Response} options.newResponse The new value in the cache. + * @param {Request} options.request The request that triggered the update. + * @param {Request} options.event The event that triggered the update. + */ + cacheDidUpdate: WorkboxPlugin["cacheDidUpdate"] = async (options) => { + dontWaitFor(this._broadcastUpdate.notifyIfUpdated(options)); + }; +} + +export { BroadcastUpdatePlugin }; diff --git a/packages/workbox-broadcast-update/src/_version.ts b/packages/workbox-broadcast-update/src/_version.ts new file mode 100644 index 00000000..a990dd9f --- /dev/null +++ b/packages/workbox-broadcast-update/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:broadcast-update:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-broadcast-update/src/index.ts b/packages/workbox-broadcast-update/src/index.ts new file mode 100644 index 00000000..096647ab --- /dev/null +++ b/packages/workbox-broadcast-update/src/index.ts @@ -0,0 +1,27 @@ +/* + 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 { + BroadcastCacheUpdate, + BroadcastCacheUpdateOptions, +} from "./BroadcastCacheUpdate.js"; +import { BroadcastUpdatePlugin } from "./BroadcastUpdatePlugin.js"; +import { responsesAreSame } from "./responsesAreSame.js"; + +import "./_version.js"; + +/** + * @module workbox-broadcast-update + */ + +export { + BroadcastCacheUpdate, + BroadcastCacheUpdateOptions, + BroadcastUpdatePlugin, + responsesAreSame, +}; diff --git a/packages/workbox-broadcast-update/src/responsesAreSame.ts b/packages/workbox-broadcast-update/src/responsesAreSame.ts new file mode 100644 index 00000000..ec4f49fc --- /dev/null +++ b/packages/workbox-broadcast-update/src/responsesAreSame.ts @@ -0,0 +1,72 @@ +/* + 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 { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { logger } from "workbox-core/_private/logger.js"; +import "./_version.js"; + +/** + * Given two `Response's`, compares several header values to see if they are + * the same or not. + * + * @param {Response} firstResponse + * @param {Response} secondResponse + * @param {Array} headersToCheck + * @return {boolean} + * + * @memberof workbox-broadcast-update + */ +const responsesAreSame = ( + firstResponse: Response, + secondResponse: Response, + headersToCheck: string[] +): boolean => { + if (process.env.NODE_ENV !== "production") { + if ( + !(firstResponse instanceof Response && secondResponse instanceof Response) + ) { + throw new WorkboxError("invalid-responses-are-same-args"); + } + } + + const atLeastOneHeaderAvailable = headersToCheck.some((header) => { + return ( + firstResponse.headers.has(header) && secondResponse.headers.has(header) + ); + }); + + if (!atLeastOneHeaderAvailable) { + if (process.env.NODE_ENV !== "production") { + logger.warn( + `Unable to determine where the response has been updated ` + + `because none of the headers that would be checked are present.` + ); + logger.debug( + `Attempting to compare the following: `, + firstResponse, + secondResponse, + headersToCheck + ); + } + + // Just return true, indicating the that responses are the same, since we + // can't determine otherwise. + return true; + } + + return headersToCheck.every((header) => { + const headerStateComparison = + firstResponse.headers.has(header) === secondResponse.headers.has(header); + const headerValueComparison = + firstResponse.headers.get(header) === secondResponse.headers.get(header); + + return headerStateComparison && headerValueComparison; + }); +}; + +export { responsesAreSame }; diff --git a/packages/workbox-broadcast-update/src/utils/constants.ts b/packages/workbox-broadcast-update/src/utils/constants.ts new file mode 100644 index 00000000..b3ff6970 --- /dev/null +++ b/packages/workbox-broadcast-update/src/utils/constants.ts @@ -0,0 +1,18 @@ +/* + 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 "../_version.js"; + +export const CACHE_UPDATED_MESSAGE_TYPE = "CACHE_UPDATED"; +export const CACHE_UPDATED_MESSAGE_META = "workbox-broadcast-update"; +export const NOTIFY_ALL_CLIENTS = true; +export const DEFAULT_HEADERS_TO_CHECK: string[] = [ + "content-length", + "etag", + "last-modified", +]; diff --git a/packages/workbox-broadcast-update/tsconfig.json b/packages/workbox-broadcast-update/tsconfig.json new file mode 100644 index 00000000..0468b457 --- /dev/null +++ b/packages/workbox-broadcast-update/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-build/README.md b/packages/workbox-build/README.md new file mode 100644 index 00000000..07ca6d82 --- /dev/null +++ b/packages/workbox-build/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-build diff --git a/packages/workbox-build/package.json b/packages/workbox-build/package.json new file mode 100644 index 00000000..10c48550 --- /dev/null +++ b/packages/workbox-build/package.json @@ -0,0 +1,69 @@ +{ + "name": "@ducanh2912/workbox-build", + "version": "7.0.0", + "description": "A module that integrates into your build process, helping you generate a manifest of local files that workbox-sw should precache.", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "caching", + "fetch requests", + "offline", + "file manifest" + ], + "engines": { + "node": ">=16.0.0" + }, + "author": "Google's Web DevRel Team", + "license": "MIT", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "dependencies": { + "@apideck/better-ajv-errors": "0.3.6", + "@babel/core": "7.23.2", + "@babel/preset-env": "7.23.2", + "@babel/runtime": "7.23.2", + "@ducanh2912/workbox-background-sync": "workspace:*", + "@ducanh2912/workbox-broadcast-update": "workspace:*", + "@ducanh2912/workbox-cacheable-response": "workspace:*", + "@ducanh2912/workbox-core": "workspace:*", + "@ducanh2912/workbox-expiration": "workspace:*", + "@ducanh2912/workbox-google-analytics": "workspace:*", + "@ducanh2912/workbox-navigation-preload": "workspace:*", + "@ducanh2912/workbox-precaching": "workspace:*", + "@ducanh2912/workbox-range-requests": "workspace:*", + "@ducanh2912/workbox-recipes": "workspace:*", + "@ducanh2912/workbox-routing": "workspace:*", + "@ducanh2912/workbox-strategies": "workspace:*", + "@ducanh2912/workbox-streams": "workspace:*", + "@ducanh2912/workbox-sw": "workspace:*", + "@ducanh2912/workbox-window": "workspace:*", + "@rollup/plugin-babel": "6.0.4", + "@rollup/plugin-node-resolve": "15.2.3", + "@rollup/plugin-replace": "5.0.4", + "@rollup/plugin-terser": "0.4.4", + "@surma/rollup-plugin-off-main-thread": "2.2.3", + "ajv": "8.12.0", + "common-tags": "1.8.2", + "fast-json-stable-stringify": "2.1.0", + "fs-extra": "11.1.1", + "glob": "10.3.10", + "lodash": "4.17.21", + "pretty-bytes": "6.1.1", + "rollup": "3.28.1", + "source-map": "0.8.0-beta.0", + "stringify-object": "5.0.0", + "strip-comments": "2.0.1", + "tempy": "3.1.0", + "upath": "2.0.1" + }, + "main": "build/index.js", + "workbox": { + "packageType": "node_ts" + }, + "types": "build/index.d.ts", + "devDependencies": { + "@types/node": "20.8.7" + } +} diff --git a/packages/workbox-build/src/_types.js b/packages/workbox-build/src/_types.js new file mode 100644 index 00000000..bae74479 --- /dev/null +++ b/packages/workbox-build/src/_types.js @@ -0,0 +1,120 @@ +/* + 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 "./_version.mjs"; + +/** + * @typedef {Object} ManifestEntry + * @property {string} url The URL to the asset in the manifest. + * @property {string} revision The revision details for the file. This should be + * either a hash generated based on the file contents, or `null` if there is + * versioning already included in the URL. + * @property {string} [integrity] Integrity metadata that will be used when + * making the network request for the URL. + * + * @memberof module:workbox-build + */ + +/** + * @typedef {Object} ManifestTransformResult + * @property {Array} manifest + * @property {Array|undefined} warnings + * + * @memberof module:workbox-build + */ + +/** + * @typedef {Object} RuntimeCachingEntry + * + * @property {string|module:workbox-routing~handlerCallback} handler + * Either the name of one of the [built-in strategy classes]{@link module:workbox-strategies}, + * or custom handler callback to use when the generated route matches. + * + * @property {string|RegExp|module:workbox-routing~matchCallback} urlPattern + * The value that will be passed to [`registerRoute()`]{@link module:workbox-routing.registerRoute}, + * used to determine whether the generated route will match a given request. + * + * @property {string} [method='GET'] The + * [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) that + * will match the generated route. + * + * @property {Object} [options] + * + * @property {Object} [options.backgroundSync] + * + * @property {string} [options.backgroundSync.name] The `name` property to use + * when creating the + * [`BackgroundSyncPlugin`]{@link module:workbox-background-sync.BackgroundSyncPlugin}. + * + * @property {Object} [options.backgroundSync.options] The `options` property + * to use when creating the + * [`BackgroundSyncPlugin`]{@link module:workbox-background-sync.BackgroundSyncPlugin}. + * + * @property {Object} [options.broadcastUpdate] + * + * @property {string} [options.broadcastUpdate.channelName] The `channelName` + * property to use when creating the + * [`BroadcastCacheUpdatePlugin`]{@link module:workbox-broadcast-update.BroadcastUpdatePlugin}. + * + * @property {Object} [options.broadcastUpdate.options] The `options` property + * to use when creating the + * [`BroadcastCacheUpdatePlugin`]{@link module:workbox-broadcast-update.BroadcastUpdatePlugin}. + * + * @property {Object} [options.cacheableResponse] + * + * @property {Object} [options.cacheableResponse.headers] The `headers` property + * to use when creating the + * [`CacheableResponsePlugin`]{@link module:workbox-cacheable-response.CacheableResponsePlugin}. + * + * @property {Array} [options.cacheableResponse.statuses] `statuses` + * property to use when creating the + * [`CacheableResponsePlugin`]{@link module:workbox-cacheable-response.CacheableResponsePlugin}. + * + * @property {string} [options.cacheName] The `cacheName` to use when + * constructing one of the + * [Workbox strategy classes]{@link module:workbox-strategies}. + * + * @property {Object} [options.fetchOptions] The `fetchOptions` property value + * to use when constructing one of the + * [Workbox strategy classes]{@link module:workbox-strategies}. + * + * @property {Object} [options.expiration] + * + * @property {number} [options.expiration.maxAgeSeconds] The `maxAgeSeconds` + * property to use when creating the + * [`ExpirationPlugin`]{@link module:workbox-expiration.ExpirationPlugin}. + * + * @property {number} [options.expiration.maxEntries] The `maxEntries` + * property to use when creating the + * [`ExpirationPlugin`]{@link module:workbox-expiration.ExpirationPlugin}. + * + * @property {Object} [options.precacheFallback] + * + * @property {string} [options.precacheFallback.fallbackURL] The `fallbackURL` + * property to use when creating the + * [`PrecacheFallbackPlugin`]{@link module:workbox-precaching.PrecacheFallbackPlugin}. + * + * @property {boolean} [options.rangeRequests] Set to `true` to add the + * [`RangeRequestsPlugin`]{@link module:workbox-range-requests.RangeRequestsPlugin} + * for the strategy being configured. + * + * @property {Object} [options.matchOptions] The `matchOptions` property value + * to use when constructing one of the + * [Workbox strategy classes]{@link module:workbox-strategies}. + * + * @property {number} [options.networkTimeoutSeconds] The + * `networkTimeoutSeconds` property value to use when creating a + * [`NetworkFirst`]{@link module:workbox-strategies.NetworkFirst} strategy. + * + * @property {Array} [options.plugins] + * One or more [additional plugins](https://developers.google.com/web/tools/workbox/guides/using-plugins#custom_plugins) + * to apply to the handler. Useful when you want a plugin that doesn't have a + * "shortcut" configuration. + * + * @memberof module:workbox-build + */ diff --git a/packages/workbox-build/src/cdn-details.json b/packages/workbox-build/src/cdn-details.json new file mode 100644 index 00000000..2d23c7fa --- /dev/null +++ b/packages/workbox-build/src/cdn-details.json @@ -0,0 +1,6 @@ +{ + "origin": "https://storage.googleapis.com", + "bucketName": "workbox-cdn", + "releasesDir": "releases", + "latestVersion": "7.0.0" +} diff --git a/packages/workbox-build/src/generate-sw.ts b/packages/workbox-build/src/generate-sw.ts new file mode 100644 index 00000000..fde3e89d --- /dev/null +++ b/packages/workbox-build/src/generate-sw.ts @@ -0,0 +1,117 @@ +/* + 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 upath from "upath"; + +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"; +import type { BuildResult, GenerateSWOptions,GetManifestOptions } from "./types"; + +/** + * This method creates a list of URLs to precache, referred to as a "precache + * manifest", based on the options you provide. + * + * It also takes in additional options that configures the service worker's + * behavior, like any `runtimeCaching` rules it should use. + * + * Based on the precache manifest and the additional configuration, it writes + * a ready-to-use service worker file to disk at `swDest`. + * + * ``` + * // The following lists some common options; see the rest of the documentation + * // for the full set of options and defaults. + * const {count, size, warnings} = await generateSW({ + * dontCacheBustURLsMatching: [new RegExp('...')], + * globDirectory: '...', + * globPatterns: ['...', '...'], + * maximumFileSizeToCacheInBytes: ..., + * navigateFallback: '...', + * runtimeCaching: [{ + * // Routing via a matchCallback function: + * urlPattern: ({request, url}) => ..., + * handler: '...', + * options: { + * cacheName: '...', + * expiration: { + * maxEntries: ..., + * }, + * }, + * }, { + * // Routing via a RegExp: + * urlPattern: new RegExp('...'), + * handler: '...', + * options: { + * cacheName: '...', + * plugins: [..., ...], + * }, + * }], + * skipWaiting: ..., + * swDest: '...', + * }); + * ``` + * + * @memberof workbox-build + */ +export async function generateSW( + config: GenerateSWOptions +): Promise { + const options = validateGenerateSWOptions(config); + let entriesResult; + + if (options.globDirectory) { + // Make sure we leave swDest out of the precache manifest. + options.globIgnores!.push( + rebasePath({ + baseDirectory: options.globDirectory, + file: options.swDest, + }) + ); + + // If we create an extra external runtime file, ignore that, too. + // See https://rollupjs.org/guide/en/#outputchunkfilenames for naming. + if (!options.inlineWorkboxRuntime) { + const swDestDir = upath.dirname(options.swDest); + const workboxRuntimeFile = upath.join(swDestDir, "workbox-*.js"); + 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 filePaths = await writeSWUsingDefaultTemplate( + Object.assign( + { + manifestEntries: entriesResult.manifestEntries, + }, + options + ) + ); + + return { + filePaths, + count: entriesResult.count, + size: entriesResult.size, + warnings: entriesResult.warnings, + }; +} diff --git a/packages/workbox-build/src/get-manifest.ts b/packages/workbox-build/src/get-manifest.ts new file mode 100644 index 00000000..9a7c038a --- /dev/null +++ b/packages/workbox-build/src/get-manifest.ts @@ -0,0 +1,37 @@ +/* + 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 { getFileManifestEntries } from "./lib/get-file-manifest-entries"; +import { validateGetManifestOptions } from "./lib/validate-options"; +import type { GetManifestOptions, GetManifestResult } from "./types"; + +/** + * This method returns a list of URLs to precache, referred to as a "precache + * manifest", along with details about the number of entries and their size, + * based on the options you provide. + * + * ``` + * // The following lists some common options; see the rest of the documentation + * // for the full set of options and defaults. + * const {count, manifestEntries, size, warnings} = await getManifest({ + * dontCacheBustURLsMatching: [new RegExp('...')], + * globDirectory: '...', + * globPatterns: ['...', '...'], + * maximumFileSizeToCacheInBytes: ..., + * }); + * ``` + * + * @memberof workbox-build + */ +export async function getManifest( + config: GetManifestOptions +): Promise { + const options = validateGetManifestOptions(config); + + return await getFileManifestEntries(options); +} diff --git a/packages/workbox-build/src/index.ts b/packages/workbox-build/src/index.ts new file mode 100644 index 00000000..03d677b8 --- /dev/null +++ b/packages/workbox-build/src/index.ts @@ -0,0 +1,26 @@ +/* + 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 { generateSW } from "./generate-sw"; +import { getManifest } from "./get-manifest"; +import { injectManifest } from "./inject-manifest"; +import { getModuleURL } from "./lib/cdn-utils"; +import { copyWorkboxLibraries } from "./lib/copy-workbox-libraries"; + +/** + * @module workbox-build + */ +export { + copyWorkboxLibraries, + generateSW, + getManifest, + getModuleURL, + injectManifest, +}; + +export * from "./types"; diff --git a/packages/workbox-build/src/inject-manifest.ts b/packages/workbox-build/src/inject-manifest.ts new file mode 100644 index 00000000..701ab938 --- /dev/null +++ b/packages/workbox-build/src/inject-manifest.ts @@ -0,0 +1,162 @@ +/* + 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 assert from "assert"; +import stringify from "fast-json-stable-stringify"; +import fse from "fs-extra"; +import type { RawSourceMap } from "source-map"; +import upath from "upath"; + +import { errors } from "./lib/errors"; +import { escapeRegExp } from "./lib/escape-regexp"; +import { getFileManifestEntries } from "./lib/get-file-manifest-entries"; +import { getSourceMapURL } from "./lib/get-source-map-url"; +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"; +import type { BuildResult, InjectManifestOptions } from "./types"; + +/** + * This method creates a list of URLs to precache, referred to as a "precache + * manifest", based on the options you provide. + * + * The manifest is injected into the `swSrc` file, and the placeholder string + * `injectionPoint` determines where in the file the manifest should go. + * + * The final service worker file, with the manifest injected, is written to + * disk at `swDest`. + * + * This method will not compile or bundle your `swSrc` file; it just handles + * injecting the manifest. + * + * ``` + * // The following lists some common options; see the rest of the documentation + * // for the full set of options and defaults. + * const {count, size, warnings} = await injectManifest({ + * dontCacheBustURLsMatching: [new RegExp('...')], + * globDirectory: '...', + * globPatterns: ['...', '...'], + * maximumFileSizeToCacheInBytes: ..., + * swDest: '...', + * swSrc: '...', + * }); + * ``` + * + * @memberof workbox-build + */ +export async function injectManifest( + config: InjectManifestOptions +): Promise { + 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({ + file, + baseDirectory: options.globDirectory, + }) + ); + } + + const globalRegexp = new RegExp(escapeRegExp(options.injectionPoint!), "g"); + + const { count, size, manifestEntries, warnings } = + await getFileManifestEntries(options); + let swFileContents: string; + try { + swFileContents = await fse.readFile(options.swSrc, "utf8"); + } catch (error) { + throw new Error( + `${errors["invalid-sw-src"]} ${ + error instanceof Error && error.message ? error.message : "" + }` + ); + } + + const injectionResults = swFileContents.match(globalRegexp); + // See https://github.com/GoogleChrome/workbox/issues/2230 + const injectionPoint = options.injectionPoint ? options.injectionPoint : ""; + if (!injectionResults) { + if (upath.resolve(options.swSrc) === upath.resolve(options.swDest)) { + throw new Error(`${errors["same-src-and-dest"]} ${injectionPoint}`); + } + throw new Error(`${errors["injection-point-not-found"]} ${injectionPoint}`); + } + + assert( + injectionResults.length === 1, + `${errors["multiple-injection-points"]} ${injectionPoint}` + ); + + const manifestString = stringify(manifestEntries); + const filesToWrite: { [key: string]: string } = {}; + + const url = getSourceMapURL(swFileContents); + // 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 (srcPath && destPath) { + const originalMap = (await fse.readJSON(srcPath, { + encoding: "utf8", + })) as RawSourceMap; + + const { map, source } = await replaceAndUpdateSourceMap({ + originalMap, + jsFilename: upath.basename(options.swDest), + originalSource: swFileContents, + replaceString: manifestString, + searchString: options.injectionPoint!, + }); + + filesToWrite[options.swDest] = source; + filesToWrite[destPath] = map; + } else { + // If there's no sourcemap associated with swSrc, a simple string + // replacement will suffice. + filesToWrite[options.swDest] = swFileContents.replace( + globalRegexp, + manifestString + ); + } + + for (const [file, contents] of Object.entries(filesToWrite)) { + try { + await fse.mkdirp(upath.dirname(file)); + } catch (error: unknown) { + throw new Error( + errors["unable-to-make-sw-directory"] + + ` '${error instanceof Error && error.message ? error.message : ""}'` + ); + } + + await fse.writeFile(file, contents); + } + + return { + count, + size, + warnings, + // Use upath.resolve() to make all the paths absolute. + filePaths: Object.keys(filesToWrite).map((f) => upath.resolve(f)), + }; +} diff --git a/packages/workbox-build/src/lib/additional-manifest-entries-transform.ts b/packages/workbox-build/src/lib/additional-manifest-entries-transform.ts new file mode 100644 index 00000000..3901bad2 --- /dev/null +++ b/packages/workbox-build/src/lib/additional-manifest-entries-transform.ts @@ -0,0 +1,58 @@ +/* + 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 type { ManifestEntry } from "../types"; +import { errors } from "./errors"; + +type AdditionalManifestEntriesTransform = { + (manifest: Array): { + manifest: Array; + warnings: string[]; + }; +}; + +export function additionalManifestEntriesTransform( + additionalManifestEntries: Array +): AdditionalManifestEntriesTransform { + return (manifest: Array) => { + const warnings: Array = []; + const stringEntries = new Set(); + + 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, + }; + }; +} diff --git a/packages/workbox-build/src/lib/bundle.ts b/packages/workbox-build/src/lib/bundle.ts new file mode 100644 index 00000000..be53a82a --- /dev/null +++ b/packages/workbox-build/src/lib/bundle.ts @@ -0,0 +1,153 @@ +/* + 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 presetEnv from "@babel/preset-env"; +import { babel } from "@rollup/plugin-babel"; +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import replace from "@rollup/plugin-replace"; +import omt from "@surma/rollup-plugin-off-main-thread"; +import { writeFile } from "fs-extra"; +import type { Plugin} from "rollup"; +import {rollup } from "rollup"; +import { terser } from "rollup-plugin-terser"; +import tempy from "tempy"; +import upath from "upath"; + +import type { GeneratePartial, RequiredSWDestPartial } from "../types"; + +interface NameAndContents { + contents: string | Uint8Array; + name: string; +} + +export async function bundle({ + babelPresetEnvTargets, + inlineWorkboxRuntime, + mode, + sourcemap, + swDest, + unbundledCode, +}: Omit & + RequiredSWDestPartial & { unbundledCode: string }): Promise< + Array +> { + // 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); + + const temporaryFile = tempy.file({ name: base }); + await writeFile(temporaryFile, unbundledCode); + + const plugins = [ + nodeResolve(), + replace({ + // See https://github.com/GoogleChrome/workbox/issues/2769 + preventAssignment: true, + "process.env.NODE_ENV": JSON.stringify(mode), + }), + babel({ + babelHelpers: "bundled", + // Disable the logic that checks for local Babel config files: + // https://github.com/GoogleChrome/workbox/issues/2111 + babelrc: false, + configFile: false, + presets: [ + [ + presetEnv, + { + targets: { + browsers: babelPresetEnvTargets, + }, + loose: true, + }, + ], + ], + }), + ]; + + if (mode === "production") { + plugins.push( + terser({ + mangle: { + toplevel: true, + properties: { + regex: /(^_|_$)/, + }, + }, + }) + ); + } + + const rollupConfig: { + input: string; + manualChunks?: (id: string) => string | undefined; + plugins: Array; + } = { + plugins, + input: temporaryFile, + }; + + // Rollup will inline the runtime by default. If we don't want that, we need + // to add in some additional config. + if (!inlineWorkboxRuntime) { + // No lint for omt(), library has no types. + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + rollupConfig.plugins.unshift(omt()); + rollupConfig.manualChunks = (id) => { + return id.includes("workbox") ? "workbox" : undefined; + }; + } + + const bundle = await rollup(rollupConfig); + + const { output } = await bundle.generate({ + sourcemap, + // Using an external Workbox runtime requires 'amd'. + format: inlineWorkboxRuntime ? "es" : "amd", + }); + + const files: Array = []; + for (const chunkOrAsset of output) { + if (chunkOrAsset.type === "asset") { + files.push({ + name: chunkOrAsset.fileName, + contents: chunkOrAsset.source, + }); + } else { + let code = chunkOrAsset.code; + + if (chunkOrAsset.map) { + const sourceMapFile = chunkOrAsset.fileName + ".map"; + code += `//# sourceMappingURL=${sourceMapFile}\n`; + + files.push({ + name: sourceMapFile, + contents: chunkOrAsset.map.toString(), + }); + } + + files.push({ + name: chunkOrAsset.fileName, + contents: code, + }); + } + } + + // Make sure that if there was a directory portion included in swDest, it's + // preprended to all of the generated files. + return files.map((file) => { + file.name = upath.format({ + dir, + base: file.name, + ext: "", + name: "", + root: "", + }); + return file; + }); +} diff --git a/packages/workbox-build/src/lib/cdn-utils.ts b/packages/workbox-build/src/lib/cdn-utils.ts new file mode 100644 index 00000000..7a49bde0 --- /dev/null +++ b/packages/workbox-build/src/lib/cdn-utils.ts @@ -0,0 +1,37 @@ +/* + 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 * as cdn from "../cdn-details.json"; +import type { BuildType, WorkboxPackageJSON } from "../types"; +import { errors } from "./errors"; + +function getVersionedURL(): string { + return `${getCDNPrefix()}/${cdn.latestVersion}`; +} + +function getCDNPrefix() { + return `${cdn.origin}/${cdn.bucketName}/${cdn.releasesDir}`; +} + +export function getModuleURL(moduleName: string, buildType: BuildType): string { + ok(moduleName, errors["no-module-name"]); + + if (buildType) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + 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`; +} diff --git a/packages/workbox-build/src/lib/copy-workbox-libraries.ts b/packages/workbox-build/src/lib/copy-workbox-libraries.ts new file mode 100644 index 00000000..71232dcd --- /dev/null +++ b/packages/workbox-build/src/lib/copy-workbox-libraries.ts @@ -0,0 +1,84 @@ +/* + 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 fse from "fs-extra"; +import upath from "upath"; + +import type { WorkboxPackageJSON } from "../types"; +import { errors } from "./errors"; + +// Used to filter the libraries to copy based on our package.json dependencies. +const WORKBOX_PREFIX = "workbox-"; + +// The directory within each package containing the final bundles. +const BUILD_DIR = "build"; + +/** + * This copies over a set of runtime libraries used by Workbox into a + * local directory, which should be deployed alongside your service worker file. + * + * As an alternative to deploying these local copies, you could instead use + * Workbox from its official CDN URL. + * + * This method is exposed for the benefit of developers using + * {@link workbox-build.injectManifest} who would + * prefer not to use the CDN copies of Workbox. Developers using + * {@link workbox-build.generateSW} don't need to + * explicitly call this method. + * + * @param {string} destDirectory The path to the parent directory under which + * the new directory of libraries will be created. + * @return {Promise} The name of the newly created directory. + * + * @alias workbox-build.copyWorkboxLibraries + */ +export async function copyWorkboxLibraries( + destDirectory: string +): Promise { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + 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 + // care about versioning the dependent libraries. + const workboxDirectoryName = `workbox-v${ + thisPkg.version ? thisPkg.version : "" + }`; + const workboxDirectoryPath = upath.join(destDirectory, workboxDirectoryName); + await fse.ensureDir(workboxDirectoryPath); + + const copyPromises: Array> = []; + const librariesToCopy = Object.keys(thisPkg.dependencies || {}).filter( + (dependency) => dependency.startsWith(WORKBOX_PREFIX) + ); + + for (const library of librariesToCopy) { + // Get the path to the package on the user's filesystem by require-ing + // the package's `package.json` file via the node resolution algorithm. + const libraryPath = upath.dirname( + require.resolve(`${library}/package.json`) + ); + + const buildPath = upath.join(libraryPath, BUILD_DIR); + + // fse.copy() copies all the files in a directory, not the directory itself. + // See https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy.md#copysrc-dest-options-callback + copyPromises.push(fse.copy(buildPath, workboxDirectoryPath)); + } + + try { + await Promise.all(copyPromises); + return workboxDirectoryName; + } catch (error) { + throw Error( + `${errors["unable-to-copy-workbox-libraries"]} ${ + error instanceof Error ? error.toString() : "" + }` + ); + } +} diff --git a/packages/workbox-build/src/lib/errors.ts b/packages/workbox-build/src/lib/errors.ts new file mode 100644 index 00000000..d8f7f232 --- /dev/null +++ b/packages/workbox-build/src/lib/errors.ts @@ -0,0 +1,124 @@ +/* + 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"; + +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.`, + "invalid-file-manifest-name": ol`The File Manifest Name must have at least one + character.`, + "unable-to-get-file-manifest-name": "Unable to get a file manifest name.", + "invalid-sw-dest": `The 'swDest' value must be a valid path.`, + "unable-to-get-sw-name": "Unable to get a service worker file name.", + "unable-to-get-save-config": ol`An error occurred when asking to save details + in a config file.`, + "unable-to-get-file-hash": ol`An error occurred when attempting to create a + file hash.`, + "unable-to-get-file-size": ol`An error occurred when attempting to get a file + size.`, + "unable-to-glob-files": "An error occurred when globbing for files.", + "unable-to-make-manifest-directory": ol`Unable to make output directory for + file manifest.`, + "read-manifest-template-failure": "Unable to read template for file manifest", + "populating-manifest-tmpl-failed": ol`An error occurred when populating the + file manifest template.`, + "manifest-file-write-failure": "Unable to write the file manifest.", + "unable-to-make-sw-directory": ol`Unable to make the directories to output + the service worker path.`, + "read-sw-template-failure": ol`Unable to read the service worker template + file.`, + "sw-write-failure": "Unable to write the service worker file.", + "sw-write-failure-directory": ol`Unable to write the service worker file; + 'swDest' should be a full path to the file, not a path to a directory.`, + "unable-to-copy-workbox-libraries": ol`One or more of the Workbox libraries + could not be copied over to the destination directory: `, + "invalid-generate-sw-input": ol`The input to generateSW() must be an object.`, + "invalid-glob-directory": ol`The supplied globDirectory must be a path as a + string.`, + "invalid-dont-cache-bust": ol`The supplied 'dontCacheBustURLsMatching' + parameter must be a RegExp.`, + "invalid-exclude-files": "The excluded files should be an array of strings.", + "invalid-get-manifest-entries-input": ol`The input to + 'getFileManifestEntries()' must be an object.`, + "invalid-manifest-path": ol`The supplied manifest path is not a string with + at least one character.`, + "invalid-manifest-entries": ol`The manifest entries must be an array of + strings or JavaScript objects containing a url parameter.`, + "invalid-manifest-format": ol`The value of the 'format' option passed to + generateFileManifest() must be either 'iife' (the default) or 'es'.`, + "invalid-static-file-globs": ol`The 'globPatterns' value must be an array + of strings.`, + "invalid-templated-urls": ol`The 'templatedURLs' value should be an object + that maps URLs to either a string, or to an array of glob patterns.`, + "templated-url-matches-glob": ol`One of the 'templatedURLs' URLs is already + being tracked via 'globPatterns': `, + "invalid-glob-ignores": ol`The 'globIgnores' parameter must be an array of + glob pattern strings.`, + "manifest-entry-bad-url": ol`The generated manifest contains an entry without + a URL string. This is likely an error with workbox-build.`, + "modify-url-prefix-bad-prefixes": ol`The 'modifyURLPrefix' parameter must be + an object with string key value pairs.`, + "invalid-inject-manifest-arg": ol`The input to 'injectManifest()' must be an + object.`, + "injection-point-not-found": ol`Unable to find a place to inject the manifest. + Please ensure that your service worker file contains the following: `, + "multiple-injection-points": ol`Please ensure that your 'swSrc' file contains + only one match for the following: `, + "populating-sw-tmpl-failed": ol`Unable to generate service worker from + template.`, + "useless-glob-pattern": ol`One of the glob patterns doesn't match any files. + Please remove or fix the following: `, + "bad-template-urls-asset": ol`There was an issue using one of the provided + 'templatedURLs'.`, + "invalid-runtime-caching": ol`The 'runtimeCaching' parameter must an an + array of objects with at least a 'urlPattern' and 'handler'.`, + "static-file-globs-deprecated": ol`'staticFileGlobs' is deprecated. + Please use 'globPatterns' instead.`, + "dynamic-url-deprecated": ol`'dynamicURLToDependencies' is deprecated. + Please use 'templatedURLs' instead.`, + "urlPattern-is-required": ol`The 'urlPattern' option is required when using + 'runtimeCaching'.`, + "handler-is-required": ol`The 'handler' option is required when using + runtimeCaching.`, + "invalid-generate-file-manifest-arg": ol`The input to generateFileManifest() + must be an Object.`, + "invalid-sw-src": `The 'swSrc' file can't be read.`, + "same-src-and-dest": ol`Unable to find a place to inject the manifest. This is + likely because swSrc and swDest are configured to the same file. + Please ensure that your swSrc file contains the following:`, + "only-regexp-routes-supported": ol`Please use a regular expression object as + the urlPattern parameter. (Express-style routes are not currently + supported.)`, + "bad-runtime-caching-config": ol`An unknown configuration option was used + with runtimeCaching: `, + "invalid-network-timeout-seconds": ol`When using networkTimeoutSeconds, you + must set the handler to 'NetworkFirst'.`, + "no-module-name": ol`You must provide a moduleName parameter when calling + getModuleURL().`, + "bad-manifest-transforms-return-value": ol`The return value from a + manifestTransform should be an object with 'manifest' and optionally + 'warnings' properties.`, + "string-entry-warning": ol`Some items were passed to additionalManifestEntries + without revisioning info. This is generally NOT safe. Learn more at + https://bit.ly/wb-precache.`, + "no-manifest-entries-or-runtime-caching": ol`Couldn't find configuration for + either precaching or runtime caching. Please ensure that the various glob + options are set to match one or more files, and/or configure the + 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.`, + "manifest-transforms": ol`When using manifestTransforms, you must provide + an array of functions.`, + "invalid-handler-string": ol`The handler name provided is not valid: `, +}; diff --git a/packages/workbox-build/src/lib/escape-regexp.ts b/packages/workbox-build/src/lib/escape-regexp.ts new file mode 100644 index 00000000..b5aa9adf --- /dev/null +++ b/packages/workbox-build/src/lib/escape-regexp.ts @@ -0,0 +1,12 @@ +/* + 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. +*/ + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions +export function escapeRegExp(str: string): string { + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} diff --git a/packages/workbox-build/src/lib/get-composite-details.ts b/packages/workbox-build/src/lib/get-composite-details.ts new file mode 100644 index 00000000..8fe9c751 --- /dev/null +++ b/packages/workbox-build/src/lib/get-composite-details.ts @@ -0,0 +1,34 @@ +/* + 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 crypto from "crypto"; + +import type { FileDetails } from "../types"; + +export function getCompositeDetails( + compositeURL: string, + dependencyDetails: Array +): FileDetails { + let totalSize = 0; + let compositeHash = ""; + + for (const fileDetails of dependencyDetails) { + totalSize += fileDetails.size; + compositeHash += fileDetails.hash; + } + + const md5 = crypto.createHash("md5"); + md5.update(compositeHash); + const hashOfHashes = md5.digest("hex"); + + return { + file: compositeURL, + hash: hashOfHashes, + size: totalSize, + }; +} diff --git a/packages/workbox-build/src/lib/get-file-details.ts b/packages/workbox-build/src/lib/get-file-details.ts new file mode 100644 index 00000000..97df8dd5 --- /dev/null +++ b/packages/workbox-build/src/lib/get-file-details.ts @@ -0,0 +1,76 @@ +/* + 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 type { GlobPartial } from "../types"; +import { errors } from "./errors"; +import { getFileHash } from "./get-file-hash"; +import { getFileSize } from "./get-file-size"; + +interface FileDetails { + file: string; + hash: string; + size: number; +} + +export function getFileDetails({ + globDirectory, + globFollow, + globIgnores, + globPattern, + globStrict, +}: Omit & { + // This will only be called when globDirectory is not undefined. + globDirectory: string; + globPattern: string; +}): { + globbedFileDetails: Array; + warning: string; +} { + let globbedFiles: Array; + 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 instanceof Error && err.message ? err.message : ""}'` + ); + } + + if (globbedFiles.length === 0) { + warning = + errors["useless-glob-pattern"] + + " " + + JSON.stringify({ globDirectory, globPattern, globIgnores }, null, 2); + } + + const globbedFileDetails: Array = []; + 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 }; +} diff --git a/packages/workbox-build/src/lib/get-file-hash.ts b/packages/workbox-build/src/lib/get-file-hash.ts new file mode 100644 index 00000000..fa6e873a --- /dev/null +++ b/packages/workbox-build/src/lib/get-file-hash.ts @@ -0,0 +1,24 @@ +/* + 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 fse from "fs-extra"; + +import { errors } from "./errors"; +import { getStringHash } from "./get-string-hash"; + +export function getFileHash(file: string): string { + try { + const buffer = fse.readFileSync(file); + return getStringHash(buffer); + } catch (err) { + throw new Error( + errors["unable-to-get-file-hash"] + + ` '${err instanceof Error && err.message ? err.message : ""}'` + ); + } +} diff --git a/packages/workbox-build/src/lib/get-file-manifest-entries.ts b/packages/workbox-build/src/lib/get-file-manifest-entries.ts new file mode 100644 index 00000000..559aec26 --- /dev/null +++ b/packages/workbox-build/src/lib/get-file-manifest-entries.ts @@ -0,0 +1,121 @@ +/* + 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 type { FileDetails, GetManifestOptions,GetManifestResult } 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 { + const warnings: Array = []; + const allFileDetails = new Map(); + + 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. + if (error instanceof Error && error.message) { + 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>( + (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 } = {}; + debugObj[url] = dependencies; + throw new Error( + `${errors["bad-template-urls-asset"]} ` + + `'${globPattern}' from '${JSON.stringify(debugObj)}':\n` + + `${error instanceof Error ? error.toString() : ""}` + ); + } + }, + [] + ); + if (details.length === 0) { + throw new Error( + `${errors["bad-template-urls-asset"]} The glob ` + + `pattern '${dependencies.toString()}' 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; +} diff --git a/packages/workbox-build/src/lib/get-file-size.ts b/packages/workbox-build/src/lib/get-file-size.ts new file mode 100644 index 00000000..bc420037 --- /dev/null +++ b/packages/workbox-build/src/lib/get-file-size.ts @@ -0,0 +1,26 @@ +/* + 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 fse from "fs-extra"; + +import { errors } from "./errors"; + +export function getFileSize(file: string): number | null { + try { + const stat = fse.statSync(file); + if (!stat.isFile()) { + return null; + } + return stat.size; + } catch (err) { + throw new Error( + errors["unable-to-get-file-size"] + + ` '${err instanceof Error && err.message ? err.message : ""}'` + ); + } +} diff --git a/packages/workbox-build/src/lib/get-source-map-url.ts b/packages/workbox-build/src/lib/get-source-map-url.ts new file mode 100644 index 00000000..41629999 --- /dev/null +++ b/packages/workbox-build/src/lib/get-source-map-url.ts @@ -0,0 +1,32 @@ +/* + Copyright 2022 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. +*/ + +// Adapted from https://github.com/lydell/source-map-url/blob/master/source-map-url.js +// See https://github.com/GoogleChrome/workbox/issues/3019 +const innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/; +const regex = RegExp( + "(?:" + + "/\\*" + + "(?:\\s*\r?\n(?://)?)?" + + "(?:" + + innerRegex.source + + ")" + + "\\s*" + + "\\*/" + + "|" + + "//(?:" + + innerRegex.source + + ")" + + ")" + + "\\s*" +); + +export function getSourceMapURL(srcContents: string): string | null { + const match = srcContents.match(regex); + return match ? match[1] || match[2] || "" : null; +} diff --git a/packages/workbox-build/src/lib/get-string-details.ts b/packages/workbox-build/src/lib/get-string-details.ts new file mode 100644 index 00000000..4a52e0df --- /dev/null +++ b/packages/workbox-build/src/lib/get-string-details.ts @@ -0,0 +1,18 @@ +/* + 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 type { FileDetails } from "../types"; +import { getStringHash } from "./get-string-hash"; + +export function getStringDetails(url: string, str: string): FileDetails { + return { + file: url, + hash: getStringHash(str), + size: str.length, + }; +} diff --git a/packages/workbox-build/src/lib/get-string-hash.ts b/packages/workbox-build/src/lib/get-string-hash.ts new file mode 100644 index 00000000..6cac9666 --- /dev/null +++ b/packages/workbox-build/src/lib/get-string-hash.ts @@ -0,0 +1,15 @@ +/* + 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 crypto from "crypto"; + +export function getStringHash(input: crypto.BinaryLike): string { + const md5 = crypto.createHash("md5"); + md5.update(input); + return md5.digest("hex"); +} diff --git a/packages/workbox-build/src/lib/maximum-size-transform.ts b/packages/workbox-build/src/lib/maximum-size-transform.ts new file mode 100644 index 00000000..003d5794 --- /dev/null +++ b/packages/workbox-build/src/lib/maximum-size-transform.ts @@ -0,0 +1,33 @@ +/* + 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 prettyBytes from "pretty-bytes"; + +import type { ManifestTransform } from "../types"; + +export function maximumSizeTransform( + maximumFileSizeToCacheInBytes: number +): ManifestTransform { + return (originalManifest) => { + const warnings: Array = []; + const manifest = originalManifest.filter((entry) => { + if (entry.size <= maximumFileSizeToCacheInBytes) { + return true; + } + + warnings.push( + `${entry.url} is ${prettyBytes(entry.size)}, and won't ` + + `be precached. Configure maximumFileSizeToCacheInBytes to change ` + + `this limit.` + ); + return false; + }); + + return { manifest, warnings }; + }; +} diff --git a/packages/workbox-build/src/lib/modify-url-prefix-transform.ts b/packages/workbox-build/src/lib/modify-url-prefix-transform.ts new file mode 100644 index 00000000..506da1cb --- /dev/null +++ b/packages/workbox-build/src/lib/modify-url-prefix-transform.ts @@ -0,0 +1,61 @@ +/* + 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 type { ManifestTransform } from "../types"; +import { errors } from "./errors"; +import { escapeRegExp } from "./escape-regexp"; + +export function modifyURLPrefixTransform(modifyURLPrefix: { + [key: string]: string; +}): ManifestTransform { + if ( + !modifyURLPrefix || + typeof modifyURLPrefix !== "object" || + Array.isArray(modifyURLPrefix) + ) { + throw new Error(errors["modify-url-prefix-bad-prefixes"]); + } + + // If there are no entries in modifyURLPrefix, just return an identity + // function as a shortcut. + if (Object.keys(modifyURLPrefix).length === 0) { + return (manifest) => { + return { manifest }; + }; + } + + 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); + // Join all the `modifyURLPrefix` keys so a single regex can be used. + const prefixMatchesStrings = safeModifyURLPrefixes.join("|"); + // Add `^` to the front the prefix matches so it only matches the start of + // a string. + const modifyRegex = new RegExp(`^(${prefixMatchesStrings})`); + + return (originalManifest) => { + const manifest = originalManifest.map((entry) => { + if (typeof entry.url !== "string") { + throw new Error(errors["manifest-entry-bad-url"]); + } + + entry.url = entry.url.replace(modifyRegex, (match) => { + return modifyURLPrefix[match]; + }); + + return entry; + }); + + return { manifest }; + }; +} diff --git a/packages/workbox-build/src/lib/module-registry.ts b/packages/workbox-build/src/lib/module-registry.ts new file mode 100644 index 00000000..618b9480 --- /dev/null +++ b/packages/workbox-build/src/lib/module-registry.ts @@ -0,0 +1,76 @@ +/* + 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 { oneLine as ol } from "common-tags"; +import upath from "upath"; + +/** + * Class for keeping track of which Workbox modules are used by the generated + * service worker script. + * + * @private + */ +export class ModuleRegistry { + private readonly _modulesUsed: Map< + string, + { moduleName: string; pkg: string } + >; + /** + * @private + */ + constructor() { + this._modulesUsed = new Map(); + } + + /** + * @return {Array} A list of all of the import statements that are + * needed for the modules being used. + * @private + */ + getImportStatements(): Array { + const workboxModuleImports: Array = []; + + 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 + // strip the '/package.json' from the resolved path. + const pkgJsonPath = require.resolve(`${pkg}/package.json`); + const pkgRoot = upath.dirname(pkgJsonPath); + const importStatement = ol`import {${moduleName} as ${localName}} from + '${pkgRoot}/${moduleName}.mjs';`; + + workboxModuleImports.push(importStatement); + } + + return workboxModuleImports; + } + + /** + * @param {string} pkg The workbox package that the module belongs to. + * @param {string} moduleName The name of the module to import. + * @return {string} The local variable name that corresponds to that module. + * @private + */ + getLocalName(pkg: string, moduleName: string): string { + return `${pkg.replace(/-/g, "_")}_${moduleName}`; + } + + /** + * @param {string} pkg The workbox package that the module belongs to. + * @param {string} moduleName The name of the module to import. + * @return {string} The local variable name that corresponds to that module. + * @private + */ + use(pkg: string, moduleName: string): string { + const localName = this.getLocalName(pkg, moduleName); + this._modulesUsed.set(localName, { moduleName, pkg }); + + return localName; + } +} diff --git a/packages/workbox-build/src/lib/no-revision-for-urls-matching-transform.ts b/packages/workbox-build/src/lib/no-revision-for-urls-matching-transform.ts new file mode 100644 index 00000000..0b987cff --- /dev/null +++ b/packages/workbox-build/src/lib/no-revision-for-urls-matching-transform.ts @@ -0,0 +1,34 @@ +/* + 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 type { ManifestTransform } from "../types"; +import { errors } from "./errors"; + +export function noRevisionForURLsMatchingTransform( + regexp: RegExp +): ManifestTransform { + if (!(regexp instanceof RegExp)) { + throw new Error(errors["invalid-dont-cache-bust"]); + } + + return (originalManifest) => { + const manifest = originalManifest.map((entry) => { + if (typeof entry.url !== "string") { + throw new Error(errors["manifest-entry-bad-url"]); + } + + if (entry.url.match(regexp)) { + entry.revision = null; + } + + return entry; + }); + + return { manifest }; + }; +} diff --git a/packages/workbox-build/src/lib/populate-sw-template.ts b/packages/workbox-build/src/lib/populate-sw-template.ts new file mode 100644 index 00000000..1b1c4f09 --- /dev/null +++ b/packages/workbox-build/src/lib/populate-sw-template.ts @@ -0,0 +1,105 @@ +/* + 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 template from "lodash/template"; + +import { swTemplate } from "../templates/sw-template"; +import type { GeneratePartial, ManifestEntry } from "../types"; +import { errors } from "./errors"; +import { ModuleRegistry } from "./module-registry"; +import { runtimeCachingConverter } from "./runtime-caching-converter"; +import { stringifyWithoutComments } from "./stringify-without-comments"; + +export function populateSWTemplate({ + cacheId, + cleanupOutdatedCaches, + clientsClaim, + directoryIndex, + disableDevLogs, + ignoreURLParametersMatching, + importScripts, + manifestEntries = [], + navigateFallback, + navigateFallbackDenylist, + navigateFallbackAllowlist, + navigationPreload, + offlineGoogleAnalytics, + runtimeCaching = [], + skipWaiting, +}: GeneratePartial & { manifestEntries?: Array }): 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"]); + } + + // These are all options that can be passed to the precacheAndRoute() method. + const precacheOptions = { + directoryIndex, + // An array of RegExp objects can't be serialized by JSON.stringify()'s + // default behavior, so if it's given, convert it manually. + ignoreURLParametersMatching: ignoreURLParametersMatching + ? ([] as Array) + : undefined, + }; + + let precacheOptionsString = JSON.stringify(precacheOptions, null, 2); + if (ignoreURLParametersMatching) { + precacheOptionsString = precacheOptionsString.replace( + `"ignoreURLParametersMatching": []`, + `"ignoreURLParametersMatching": [` + + `${ignoreURLParametersMatching.join(", ")}]` + ); + } + + 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. + offlineAnalyticsConfigString = + offlineGoogleAnalytics === true + ? // If it's the literal value true, then use an empty config string. + "{}" + : // Otherwise, convert the config object into a more complex string, taking + // into account the fact that functions might need to be stringified. + stringifyWithoutComments(offlineGoogleAnalytics); + } + + const moduleRegistry = new ModuleRegistry(); + + try { + const populatedTemplate = template(swTemplate)({ + cacheId, + cleanupOutdatedCaches, + clientsClaim, + disableDevLogs, + importScripts, + manifestEntries, + navigateFallback, + navigateFallbackDenylist, + navigateFallbackAllowlist, + navigationPreload, + offlineAnalyticsConfigString, + precacheOptionsString, + runtimeCaching: runtimeCachingConverter(moduleRegistry, runtimeCaching), + skipWaiting, + use: moduleRegistry.use.bind(moduleRegistry), + }); + + const workboxImportStatements = moduleRegistry.getImportStatements(); + + // We need the import statements for all of the Workbox runtime modules + // prepended, so that the correct bundle can be created. + return workboxImportStatements.join("\n") + populatedTemplate; + } catch (error) { + throw new Error( + `${errors["populating-sw-tmpl-failed"]} '${ + error instanceof Error && error.message ? error.message : "" + }'` + ); + } +} diff --git a/packages/workbox-build/src/lib/rebase-path.ts b/packages/workbox-build/src/lib/rebase-path.ts new file mode 100644 index 00000000..18f83779 --- /dev/null +++ b/packages/workbox-build/src/lib/rebase-path.ts @@ -0,0 +1,28 @@ +/* + 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 upath from "upath"; + +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); + + // Convert the absolute path so that it's relative to the baseDirectory. + const relativePath = upath.relative(baseDirectory, absolutePath); + + // Remove any leading ./ as it won't work in a glob pattern. + const normalizedPath = upath.normalize(relativePath); + + return normalizedPath; +} diff --git a/packages/workbox-build/src/lib/replace-and-update-source-map.ts b/packages/workbox-build/src/lib/replace-and-update-source-map.ts new file mode 100644 index 00000000..9cd48d03 --- /dev/null +++ b/packages/workbox-build/src/lib/replace-and-update-source-map.ts @@ -0,0 +1,127 @@ +/* + 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 type { + RawSourceMap} from "source-map"; +import { + SourceMapConsumer, + SourceMapGenerator, +} from "source-map"; + +/** + * Adapted from https://github.com/nsams/sourcemap-aware-replace, with modern + * JavaScript updates, along with additional properties copied from originalMap. + * + * @param {Object} options + * @param {string} options.jsFilename The name for the file whose contents + * correspond to originalSource. + * @param {Object} options.originalMap The sourcemap for originalSource, + * prior to any replacements. + * @param {string} options.originalSource The source code, prior to any + * replacements. + * @param {string} options.replaceString A string to swap in for searchString. + * @param {string} options.searchString A string in originalSource to replace. + * Only the first occurrence will be replaced. + * @return {{source: string, map: string}} An object containing both + * originalSource with the replacement applied, and the modified originalMap. + * + * @private + */ +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: number; + let src = originalSource; + const replacements: Array<{ line: number; column: number }> = []; + let lineNum = 0; + let filePos = 0; + + const lines = src.split("\n"); + for (let line of lines) { + lineNum++; + let searchPos = 0; + while ((pos = line.indexOf(searchString, searchPos)) !== -1) { + src = + src.substring(0, filePos + pos) + + replaceString + + src.substring(filePos + pos + searchString.length); + line = + line.substring(0, pos) + + replaceString + + line.substring(pos + searchString.length); + replacements.push({ line: lineNum, column: pos }); + searchPos = pos + replaceString.length; + } + filePos += line.length + 1; + } + + replacements.reverse(); + + consumer.eachMapping((mapping) => { + for (const replacement of replacements) { + if ( + replacement.line === mapping.generatedLine && + mapping.generatedColumn > replacement.column + ) { + const offset = searchString.length - replaceString.length; + mapping.generatedColumn -= offset; + } + } + + if (mapping.source) { + const newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn, + }, + original: { + line: mapping.originalLine, + column: mapping.originalColumn, + }, + source: mapping.source, + }; + return generator.addMapping(newMapping); + } + + return mapping; + }); + + consumer.destroy(); + // JSON.parse returns any. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const updatedSourceMap: RawSourceMap = Object.assign( + JSON.parse(generator.toString()), + { + names: originalMap.names, + sourceRoot: originalMap.sourceRoot, + sources: originalMap.sources, + sourcesContent: originalMap.sourcesContent, + } + ); + + return { + map: JSON.stringify(updatedSourceMap), + source: src, + }; +} diff --git a/packages/workbox-build/src/lib/runtime-caching-converter.ts b/packages/workbox-build/src/lib/runtime-caching-converter.ts new file mode 100644 index 00000000..f0f6af99 --- /dev/null +++ b/packages/workbox-build/src/lib/runtime-caching-converter.ts @@ -0,0 +1,215 @@ +/* + 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 type { RuntimeCaching } from "../types"; +import { errors } from "./errors"; +import type { ModuleRegistry } from "./module-registry"; +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 = []; + 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 +): Array { + 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)); +} diff --git a/packages/workbox-build/src/lib/stringify-without-comments.ts b/packages/workbox-build/src/lib/stringify-without-comments.ts new file mode 100644 index 00000000..d8b11570 --- /dev/null +++ b/packages/workbox-build/src/lib/stringify-without-comments.ts @@ -0,0 +1,23 @@ +/* + 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") { + // Can't typify correctly stripComments + return stripComments(str); // eslint-disable-line + } + return str; + }, + }); +} diff --git a/packages/workbox-build/src/lib/transform-manifest.ts b/packages/workbox-build/src/lib/transform-manifest.ts new file mode 100644 index 00000000..994770a9 --- /dev/null +++ b/packages/workbox-build/src/lib/transform-manifest.ts @@ -0,0 +1,162 @@ +/* + 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 type { + 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 + * `revision` properties of some or all of the + * {@link workbox-build.ManifestEntry} in the manifest. + * + * Deleting the `revision` property of an entry will cause + * the corresponding `url` to be precached without cache-busting parameters + * applied, which is to say, it implies that the URL itself contains + * proper versioning info. If the `revision` property is present, it must be + * set to a string. + * + * @example A transformation that prepended the origin of a CDN for any + * URL starting with '/assets/' could be implemented as: + * + * const cdnTransform = async (manifestEntries) => { + * const manifest = manifestEntries.map(entry => { + * const cdnOrigin = 'https://example.com'; + * if (entry.url.startsWith('/assets/')) { + * entry.url = cdnOrigin + entry.url; + * } + * return entry; + * }); + * return {manifest, warnings: []}; + * }; + * + * @example A transformation that nulls the revision field when the + * URL contains an 8-character hash surrounded by '.', indicating that it + * already contains revision information: + * + * const removeRevisionTransform = async (manifestEntries) => { + * const manifest = manifestEntries.map(entry => { + * const hashRegExp = /\.\w{8}\./; + * if (entry.url.match(hashRegExp)) { + * entry.revision = null; + * } + * return entry; + * }); + * return {manifest, warnings: []}; + * }; + * + * @callback ManifestTransform + * @param {Array} manifestEntries The full + * array of entries, prior to the current transformation. + * @param {Object} [compilation] When used in the webpack plugins, this param + * will be set to the current `compilation`. + * @return {Promise} + * The array of entries with the transformation applied, and optionally, any + * warnings that should be reported back to the build tool. + * + * @memberof workbox-build + */ + +interface ManifestTransformResultWithWarnings { + count: number; + size: number; + manifestEntries: ManifestEntry[]; + warnings: string[]; +} +export async function transformManifest({ + additionalManifestEntries, + dontCacheBustURLsMatching, + fileDetails, + manifestTransforms, + maximumFileSizeToCacheInBytes, + modifyURLPrefix, + transformParam, +}: BasePartial & { + fileDetails: Array; + // When this is called by the webpack plugin, transformParam will be the + // current webpack compilation. + transformParam?: unknown; +}): Promise { + const allWarnings: Array = []; + + // Take the array of fileDetail objects and convert it into an array of + // {url, revision, size} objects, with \ replaced with /. + const normalizedManifest = fileDetails.map((fileDetails) => { + return { + url: fileDetails.file.replace(/\\/g, "/"), + revision: fileDetails.hash, + size: fileDetails.size, + }; + }); + + const transformsToApply: Array = []; + + if (maximumFileSizeToCacheInBytes) { + transformsToApply.push(maximumSizeTransform(maximumFileSizeToCacheInBytes)); + } + + if (modifyURLPrefix) { + transformsToApply.push(modifyURLPrefixTransform(modifyURLPrefix)); + } + + if (dontCacheBustURLsMatching) { + transformsToApply.push( + noRevisionForURLsMatchingTransform(dontCacheBustURLsMatching) + ); + } + + // Run any manifestTransforms functions second-to-last. + if (manifestTransforms) { + transformsToApply.push(...manifestTransforms); + } + + // Run additionalManifestEntriesTransform last. + if (additionalManifestEntries) { + transformsToApply.push( + additionalManifestEntriesTransform(additionalManifestEntries) + ); + } + + let transformedManifest: Array = + normalizedManifest; + for (const transform of transformsToApply) { + const result = await transform(transformedManifest, transformParam); + if (!("manifest" in result)) { + throw new Error(errors["bad-manifest-transforms-return-value"]); + } + + transformedManifest = result.manifest; + 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 as Array< + ManifestEntry & { size?: number } + >) { + size += manifestEntry.size || 0; + delete manifestEntry.size; + } + + return { + count, + size, + manifestEntries: transformedManifest as Array, + warnings: allWarnings, + }; +} 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 00000000..44e1c131 --- /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 | null, + 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/packages/workbox-build/src/lib/validate-options.ts b/packages/workbox-build/src/lib/validate-options.ts new file mode 100644 index 00000000..74f94310 --- /dev/null +++ b/packages/workbox-build/src/lib/validate-options.ts @@ -0,0 +1,237 @@ +/* + 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 type { JSONSchemaType } from "ajv"; +import Ajv from "ajv"; +import { oneLine as ol } from "common-tags"; + +import type { + GenerateSWOptions, + GetManifestOptions, + InjectManifestOptions, + WebpackGenerateSWOptions, + WebpackInjectManifestOptions, +} from "../types"; +import { errors } from "./errors"; + +type MethodNames = + | "GenerateSW" + | "GetManifest" + | "InjectManifest" + | "WebpackGenerateSW" + | "WebpackInjectManifest"; + +const ajv = new Ajv({ + useDefaults: true, +}); + +const DEFAULT_EXCLUDE_VALUE = [/\.map$/, /^manifest.*\.js$/]; + +export class WorkboxConfigError extends Error { + constructor(message?: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + } +} + +// Some methods need to do follow-up validation using the JSON schema, +// so return both the validated options and then schema. +function validate( + input: unknown, + methodName: MethodNames +): [T, JSONSchemaType] { + // 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: JSONSchemaType = 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 = 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 as any, + }); + const messages = betterErrors.map( + (err) => ol`[${err.path}] ${err.message}. + ${err.suggestion ? err.suggestion : ""}` + ); + + throw new WorkboxConfigError(messages.join("\n\n")); +} + +function ensureValidManifestTransforms( + options: + | GenerateSWOptions + | GetManifestOptions + | InjectManifestOptions + | WebpackGenerateSWOptions + | WebpackInjectManifestOptions +): void { + if ( + "manifestTransforms" in options && + !( + Array.isArray(options.manifestTransforms) && + options.manifestTransforms.every((item) => typeof item === "function") + ) + ) { + throw new WorkboxConfigError(errors["manifest-transforms"]); + } +} + +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"] + ); + } +} + +// 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: GenerateSWOptions | WebpackGenerateSWOptions, + jsonSchema: JSONSchemaType +): void { + let validHandlers: Array = []; + /* eslint-disable */ + for (const handler of jsonSchema.definitions?.RuntimeCaching?.properties + ?.handler?.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["invalid-handler-string"] + runtimeCaching.handler + ); + } + } +} + +export function validateGenerateSWOptions(input: unknown): GenerateSWOptions { + const [validatedOptions, jsonSchema] = validate( + input, + "GenerateSW" + ); + ensureValidNavigationPreloadConfig(validatedOptions); + ensureValidCacheExpiration(validatedOptions); + ensureValidRuntimeCachingOrGlobDirectory(validatedOptions); + ensureValidStringHandler(validatedOptions, jsonSchema); + + return validatedOptions; +} + +export function validateGetManifestOptions(input: unknown): GetManifestOptions { + const [validatedOptions] = validate(input, "GetManifest"); + + return validatedOptions; +} + +export function validateInjectManifestOptions( + input: unknown +): InjectManifestOptions { + const [validatedOptions] = validate( + input, + "InjectManifest" + ); + + return validatedOptions; +} + +// 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, jsonSchema] = validate( + inputWithExcludeDefault, + "WebpackGenerateSW" + ); + + ensureValidNavigationPreloadConfig(validatedOptions); + ensureValidCacheExpiration(validatedOptions); + ensureValidStringHandler(validatedOptions, jsonSchema); + + 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 + ); + const [validatedOptions] = validate( + inputWithExcludeDefault, + "WebpackInjectManifest" + ); + + return validatedOptions; +} diff --git a/packages/workbox-build/src/lib/write-sw-using-default-template.ts b/packages/workbox-build/src/lib/write-sw-using-default-template.ts new file mode 100644 index 00000000..f2f478a3 --- /dev/null +++ b/packages/workbox-build/src/lib/write-sw-using-default-template.ts @@ -0,0 +1,96 @@ +/* + 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 fse from "fs-extra"; +import upath from "upath"; + +import type { GenerateSWOptions, ManifestEntry } from "../types"; +import { bundle } from "./bundle"; +import { errors } from "./errors"; +import { populateSWTemplate } from "./populate-sw-template"; + +export async function writeSWUsingDefaultTemplate({ + babelPresetEnvTargets, + cacheId, + cleanupOutdatedCaches, + clientsClaim, + directoryIndex, + disableDevLogs, + ignoreURLParametersMatching, + importScripts, + inlineWorkboxRuntime, + manifestEntries, + mode, + navigateFallback, + navigateFallbackDenylist, + navigateFallbackAllowlist, + navigationPreload, + offlineGoogleAnalytics, + runtimeCaching, + skipWaiting, + sourcemap, + swDest, +}: GenerateSWOptions & { manifestEntries: Array }): Promise< + Array +> { + const outputDir = upath.dirname(swDest); + try { + await fse.mkdirp(outputDir); + } catch (error) { + throw new Error( + `${errors["unable-to-make-sw-directory"]}. ` + + `'${error instanceof Error && error.message ? error.message : ""}'` + ); + } + + const unbundledCode = populateSWTemplate({ + cacheId, + cleanupOutdatedCaches, + clientsClaim, + directoryIndex, + disableDevLogs, + ignoreURLParametersMatching, + importScripts, + manifestEntries, + navigateFallback, + navigateFallbackDenylist, + navigateFallbackAllowlist, + navigationPreload, + offlineGoogleAnalytics, + runtimeCaching, + skipWaiting, + }); + + try { + const files = await bundle({ + babelPresetEnvTargets, + inlineWorkboxRuntime, + mode, + sourcemap, + swDest, + unbundledCode, + }); + + const filePaths: Array = []; + + for (const file of files) { + const filePath = upath.resolve(file.name); + filePaths.push(filePath); + await fse.writeFile(filePath, file.contents); + } + + return filePaths; + } catch (error) { + const err = error as NodeJS.ErrnoException; + if (err.code === "EISDIR") { + // See https://github.com/GoogleChrome/workbox/issues/612 + throw new Error(errors["sw-write-failure-directory"]); + } + throw new Error(`${errors["sw-write-failure"]} '${err.message}'`); + } +} diff --git a/packages/workbox-build/src/rollup-plugin-off-main-thread.d.ts b/packages/workbox-build/src/rollup-plugin-off-main-thread.d.ts new file mode 100644 index 00000000..280d1e53 --- /dev/null +++ b/packages/workbox-build/src/rollup-plugin-off-main-thread.d.ts @@ -0,0 +1 @@ +declare module "@surma/rollup-plugin-off-main-thread"; diff --git a/packages/workbox-build/src/schema/GenerateSWOptions.json b/packages/workbox-build/src/schema/GenerateSWOptions.json new file mode 100644 index 00000000..d08a456a --- /dev/null +++ b/packages/workbox-build/src/schema/GenerateSWOptions.json @@ -0,0 +1,872 @@ +{ + "additionalProperties": false, + "type": "object", + "properties": { + "additionalManifestEntries": { + "description": "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ManifestEntry" + }, + { + "type": "string" + } + ] + } + }, + "dontCacheBustURLsMatching": { + "description": "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.", + "$ref": "#/definitions/RegExp" + }, + "manifestTransforms": { + "description": "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.", + "type": "array", + "items": {} + }, + "maximumFileSizeToCacheInBytes": { + "description": "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.", + "default": 2097152, + "type": "number" + }, + "modifyURLPrefix": { + "description": "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "globFollow": { + "description": "Determines whether or not symlinks are followed when generating the\nprecache manifest. For more information, see the definition of `follow` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).", + "default": true, + "type": "boolean" + }, + "globIgnores": { + "description": "A set of patterns matching files to always exclude when generating the\nprecache manifest. For more information, see the definition of `ignore` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).", + "default": [ + "**/node_modules/**/*" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "globPatterns": { + "description": "Files matching any of these patterns will be included in the precache\nmanifest. For more information, see the\n[`glob` primer](https://github.com/isaacs/node-glob#glob-primer).", + "default": [ + "**/*.{js,css,html}" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "globStrict": { + "description": "If true, an error reading a directory when generating a precache manifest\nwill cause the build to fail. If false, the problematic directory will be\nskipped. For more information, see the definition of `strict` in the `glob`\n[documentation](https://github.com/isaacs/node-glob#options).", + "default": true, + "type": "boolean" + }, + "templatedURLs": { + "description": "If a URL is rendered based on some server-side logic, its contents may\ndepend on multiple files or on some other unique string value. The keys in\nthis object are server-rendered URLs. If the values are an array of\nstrings, they will be interpreted as `glob` patterns, and the contents of\nany files matching the patterns will be used to uniquely version the URL.\nIf used with a single string, it will be interpreted as unique versioning\ninformation that you've generated for a given URL.", + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + } + }, + "babelPresetEnvTargets": { + "description": "The [targets](https://babeljs.io/docs/en/babel-preset-env#targets) to pass\nto `babel-preset-env` when transpiling the service worker bundle.", + "default": [ + "chrome >= 56" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "cacheId": { + "description": "An optional ID to be prepended to cache names. This is primarily useful for\nlocal development where multiple sites may be served from the same\n`http://localhost:port` origin.", + "type": [ + "null", + "string" + ] + }, + "cleanupOutdatedCaches": { + "description": "Whether or not Workbox should attempt to identify and delete any precaches\ncreated by older, incompatible versions.", + "default": false, + "type": "boolean" + }, + "clientsClaim": { + "description": "Whether or not the service worker should [start controlling](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#clientsclaim)\nany existing clients as soon as it activates.", + "default": false, + "type": "boolean" + }, + "directoryIndex": { + "description": "If a navigation request for a URL ending in `/` fails to match a precached\nURL, this value will be appended to the URL and that will be checked for a\nprecache match. This should be set to what your web server is using for its\ndirectory index.", + "type": [ + "null", + "string" + ] + }, + "disableDevLogs": { + "default": false, + "type": "boolean" + }, + "ignoreURLParametersMatching": { + "description": "Any search parameter names that match against one of the RegExp in this\narray will be removed before looking for a precache match. This is useful\nif your users might request URLs that contain, for example, URL parameters\nused to track the source of the traffic. If not provided, the default value\nis `[/^utm_/, /^fbclid$/]`.", + "type": "array", + "items": { + "$ref": "#/definitions/RegExp" + } + }, + "importScripts": { + "description": "A list of JavaScript files that should be passed to\n[`importScripts()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts)\ninside the generated service worker file. This is useful when you want to\nlet Workbox create your top-level service worker file, but want to include\nsome additional code, such as a push event listener.", + "type": "array", + "items": { + "type": "string" + } + }, + "inlineWorkboxRuntime": { + "description": "Whether the runtime code for the Workbox library should be included in the\ntop-level service worker, or split into a separate file that needs to be\ndeployed alongside the service worker. Keeping the runtime separate means\nthat users will not have to re-download the Workbox code each time your\ntop-level service worker changes.", + "default": false, + "type": "boolean" + }, + "mode": { + "description": "If set to 'production', then an optimized service worker bundle that\nexcludes debugging info will be produced. If not explicitly configured\nhere, the `process.env.NODE_ENV` value will be used, and failing that, it\nwill fall back to `'production'`.", + "default": "production", + "type": [ + "null", + "string" + ] + }, + "navigateFallback": { + "description": "If specified, all\n[navigation requests](https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests)\nfor URLs that aren't precached will be fulfilled with the HTML at the URL\nprovided. You must pass in the URL of an HTML document that is listed in\nyour precache manifest. This is meant to be used in a Single Page App\nscenario, in which you want all navigations to use common\n[App Shell HTML](https://developers.google.com/web/fundamentals/architecture/app-shell).", + "default": null, + "type": [ + "null", + "string" + ] + }, + "navigateFallbackAllowlist": { + "description": "An optional array of regular expressions that restricts which URLs the\nconfigured `navigateFallback` behavior applies to. This is useful if only a\nsubset of your site's URLs should be treated as being part of a\n[Single Page App](https://en.wikipedia.org/wiki/Single-page_application).\nIf both `navigateFallbackDenylist` and `navigateFallbackAllowlist` are\nconfigured, the denylist takes precedent.\n\n*Note*: These RegExps may be evaluated against every destination URL during\na navigation. Avoid using\n[complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077),\nor else your users may see delays when navigating your site.", + "type": "array", + "items": { + "$ref": "#/definitions/RegExp" + } + }, + "navigateFallbackDenylist": { + "description": "An optional array of regular expressions that restricts which URLs the\nconfigured `navigateFallback` behavior applies to. This is useful if only a\nsubset of your site's URLs should be treated as being part of a\n[Single Page App](https://en.wikipedia.org/wiki/Single-page_application).\nIf both `navigateFallbackDenylist` and `navigateFallbackAllowlist` are\nconfigured, the denylist takes precedence.\n\n*Note*: These RegExps may be evaluated against every destination URL during\na navigation. Avoid using\n[complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077),\nor else your users may see delays when navigating your site.", + "type": "array", + "items": { + "$ref": "#/definitions/RegExp" + } + }, + "navigationPreload": { + "description": "Whether or not to enable\n[navigation preload](https://developers.google.com/web/tools/workbox/modules/workbox-navigation-preload)\nin the generated service worker. When set to true, you must also use\n`runtimeCaching` to set up an appropriate response strategy that will match\nnavigation requests, and make use of the preloaded response.", + "default": false, + "type": "boolean" + }, + "offlineGoogleAnalytics": { + "description": "Controls whether or not to include support for\n[offline Google Analytics](https://developers.google.com/web/tools/workbox/guides/enable-offline-analytics).\nWhen `true`, the call to `workbox-google-analytics`'s `initialize()` will\nbe added to your generated service worker. When set to an `Object`, that\nobject will be passed in to the `initialize()` call, allowing you to\ncustomize the behavior.", + "default": false, + "anyOf": [ + { + "$ref": "#/definitions/GoogleAnalyticsInitializeOptions" + }, + { + "type": "boolean" + } + ] + }, + "runtimeCaching": { + "description": "When using Workbox's build tools to generate your service worker, you can\nspecify one or more runtime caching configurations. These are then\ntranslated to {@link workbox-routing.registerRoute} calls using the match\nand handler configuration you define.\n\nFor all of the options, see the {@link workbox-build.RuntimeCaching}\ndocumentation. The example below shows a typical configuration, with two\nruntime routes defined:", + "type": "array", + "items": { + "$ref": "#/definitions/RuntimeCaching" + } + }, + "skipWaiting": { + "description": "Whether to add an unconditional call to [`skipWaiting()`](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#skip_the_waiting_phase)\nto the generated service worker. If `false`, then a `message` listener will\nbe added instead, allowing client pages to trigger `skipWaiting()` by\ncalling `postMessage({type: 'SKIP_WAITING'})` on a waiting service worker.", + "default": false, + "type": "boolean" + }, + "sourcemap": { + "description": "Whether to create a sourcemap for the generated service worker files.", + "default": true, + "type": "boolean" + }, + "swDest": { + "description": "The path and filename of the service worker file that will be created by\nthe build process, relative to the current working directory. It must end\nin '.js'.", + "type": "string" + }, + "globDirectory": { + "description": "The local directory you wish to match `globPatterns` against. The path is\nrelative to the current directory.", + "type": "string" + } + }, + "required": [ + "swDest" + ], + "definitions": { + "ManifestEntry": { + "type": "object", + "properties": { + "integrity": { + "type": "string" + }, + "revision": { + "type": [ + "null", + "string" + ] + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "revision", + "url" + ] + }, + "RegExp": { + "type": "object", + "properties": { + "source": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "ignoreCase": { + "type": "boolean" + }, + "multiline": { + "type": "boolean" + }, + "lastIndex": { + "type": "number" + }, + "flags": { + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "unicode": { + "type": "boolean" + }, + "dotAll": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "dotAll", + "flags", + "global", + "ignoreCase", + "lastIndex", + "multiline", + "source", + "sticky", + "unicode" + ] + }, + "GoogleAnalyticsInitializeOptions": { + "type": "object", + "properties": { + "cacheName": { + "type": "string" + }, + "parameterOverrides": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "hitFilter": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "RuntimeCaching": { + "type": "object", + "properties": { + "handler": { + "description": "This determines how the runtime route will generate a response.\nTo use one of the built-in {@link workbox-strategies}, provide its name,\nlike `'NetworkFirst'`.\nAlternatively, this can be a {@link workbox-core.RouteHandler} callback\nfunction with custom response logic.", + "anyOf": [ + { + "$ref": "#/definitions/RouteHandlerCallback" + }, + { + "$ref": "#/definitions/RouteHandlerObject" + }, + { + "enum": [ + "CacheFirst", + "CacheOnly", + "NetworkFirst", + "NetworkOnly", + "StaleWhileRevalidate" + ], + "type": "string" + } + ] + }, + "method": { + "description": "The HTTP method to match against. The default value of `'GET'` is normally\nsufficient, unless you explicitly need to match `'POST'`, `'PUT'`, or\nanother type of request.", + "default": "GET", + "enum": [ + "DELETE", + "GET", + "HEAD", + "PATCH", + "POST", + "PUT" + ], + "type": "string" + }, + "options": { + "type": "object", + "properties": { + "backgroundSync": { + "description": "Configuring this will add a\n{@link workbox-background-sync.BackgroundSyncPlugin} instance to the\n{@link workbox-strategies} configured in `handler`.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "options": { + "$ref": "#/definitions/QueueOptions" + } + }, + "additionalProperties": false, + "required": [ + "name" + ] + }, + "broadcastUpdate": { + "description": "Configuring this will add a\n{@link workbox-broadcast-update.BroadcastUpdatePlugin} instance to the\n{@link workbox-strategies} configured in `handler`.", + "type": "object", + "properties": { + "channelName": { + "type": "string" + }, + "options": { + "$ref": "#/definitions/BroadcastCacheUpdateOptions" + } + }, + "additionalProperties": false, + "required": [ + "options" + ] + }, + "cacheableResponse": { + "description": "Configuring this will add a\n{@link workbox-cacheable-response.CacheableResponsePlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/CacheableResponseOptions" + }, + "cacheName": { + "description": "If provided, this will set the `cacheName` property of the\n{@link workbox-strategies} configured in `handler`.", + "type": [ + "null", + "string" + ] + }, + "expiration": { + "description": "Configuring this will add a\n{@link workbox-expiration.ExpirationPlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/ExpirationPluginOptions" + }, + "networkTimeoutSeconds": { + "description": "If provided, this will set the `networkTimeoutSeconds` property of the\n{@link workbox-strategies} configured in `handler`. Note that only\n`'NetworkFirst'` and `'NetworkOnly'` support `networkTimeoutSeconds`.", + "type": "number" + }, + "plugins": { + "description": "Configuring this allows the use of one or more Workbox plugins that\ndon't have \"shortcut\" options (like `expiration` for\n{@link workbox-expiration.ExpirationPlugin}). The plugins provided here\nwill be added to the {@link workbox-strategies} configured in `handler`.", + "type": "array", + "items": { + "$ref": "#/definitions/WorkboxPlugin" + } + }, + "precacheFallback": { + "description": "Configuring this will add a\n{@link workbox-precaching.PrecacheFallbackPlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "type": "object", + "properties": { + "fallbackURL": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "fallbackURL" + ] + }, + "rangeRequests": { + "description": "Enabling this will add a\n{@link workbox-range-requests.RangeRequestsPlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "type": "boolean" + }, + "fetchOptions": { + "description": "Configuring this will pass along the `fetchOptions` value to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/RequestInit" + }, + "matchOptions": { + "description": "Configuring this will pass along the `matchOptions` value to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/CacheQueryOptions" + } + }, + "additionalProperties": false + }, + "urlPattern": { + "description": "This match criteria determines whether the configured handler will\ngenerate a response for any requests that don't match one of the precached\nURLs. If multiple `RuntimeCaching` routes are defined, then the first one\nwhose `urlPattern` matches will be the one that responds.\n\nThis value directly maps to the first parameter passed to\n{@link workbox-routing.registerRoute}. It's recommended to use a\n{@link workbox-core.RouteMatchCallback} function for greatest flexibility.", + "anyOf": [ + { + "$ref": "#/definitions/RegExp" + }, + { + "$ref": "#/definitions/RouteMatchCallback" + }, + { + "type": "string" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "handler", + "urlPattern" + ] + }, + "RouteHandlerCallback": {}, + "RouteHandlerObject": { + "description": "An object with a `handle` method of type `RouteHandlerCallback`.\n\nA `Route` object can be created with either an `RouteHandlerCallback`\nfunction or this `RouteHandler` object. The benefit of the `RouteHandler`\nis it can be extended (as is done by the `workbox-strategies` package).", + "type": "object", + "properties": { + "handle": { + "$ref": "#/definitions/RouteHandlerCallback" + } + }, + "additionalProperties": false, + "required": [ + "handle" + ] + }, + "QueueOptions": { + "type": "object", + "properties": { + "forceSyncFallback": { + "type": "boolean" + }, + "maxRetentionTime": { + "type": "number" + }, + "onSync": { + "$ref": "#/definitions/OnSyncCallback" + } + }, + "additionalProperties": false + }, + "OnSyncCallback": {}, + "BroadcastCacheUpdateOptions": { + "type": "object", + "properties": { + "headersToCheck": { + "type": "array", + "items": { + "type": "string" + } + }, + "generatePayload": { + "type": "object", + "additionalProperties": false + }, + "notifyAllClients": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "CacheableResponseOptions": { + "type": "object", + "properties": { + "statuses": { + "type": "array", + "items": { + "type": "number" + } + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "ExpirationPluginOptions": { + "type": "object", + "properties": { + "maxEntries": { + "type": "number" + }, + "maxAgeSeconds": { + "type": "number" + }, + "matchOptions": { + "$ref": "#/definitions/CacheQueryOptions" + }, + "purgeOnQuotaError": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "CacheQueryOptions": { + "type": "object", + "properties": { + "ignoreMethod": { + "type": "boolean" + }, + "ignoreSearch": { + "type": "boolean" + }, + "ignoreVary": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "WorkboxPlugin": { + "description": "An object with optional lifecycle callback properties for the fetch and\ncache operations.", + "type": "object", + "properties": { + "cacheDidUpdate": {}, + "cachedResponseWillBeUsed": {}, + "cacheKeyWillBeUsed": {}, + "cacheWillUpdate": {}, + "fetchDidFail": {}, + "fetchDidSucceed": {}, + "handlerDidComplete": {}, + "handlerDidError": {}, + "handlerDidRespond": {}, + "handlerWillRespond": {}, + "handlerWillStart": {}, + "requestWillFetch": {} + }, + "additionalProperties": false + }, + "CacheDidUpdateCallback": { + "type": "object", + "additionalProperties": false + }, + "CachedResponseWillBeUsedCallback": { + "type": "object", + "additionalProperties": false + }, + "CacheKeyWillBeUsedCallback": { + "type": "object", + "additionalProperties": false + }, + "CacheWillUpdateCallback": { + "type": "object", + "additionalProperties": false + }, + "FetchDidFailCallback": { + "type": "object", + "additionalProperties": false + }, + "FetchDidSucceedCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerDidCompleteCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerDidErrorCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerDidRespondCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerWillRespondCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerWillStartCallback": { + "type": "object", + "additionalProperties": false + }, + "RequestWillFetchCallback": { + "type": "object", + "additionalProperties": false + }, + "RequestInit": { + "type": "object", + "properties": { + "body": { + "anyOf": [ + { + "$ref": "#/definitions/ArrayBuffer" + }, + { + "$ref": "#/definitions/ArrayBufferView" + }, + { + "$ref": "#/definitions/ReadableStream" + }, + { + "$ref": "#/definitions/Blob" + }, + { + "$ref": "#/definitions/FormData" + }, + { + "$ref": "#/definitions/URLSearchParams" + }, + { + "type": [ + "null", + "string" + ] + } + ] + }, + "cache": { + "enum": [ + "default", + "force-cache", + "no-cache", + "no-store", + "only-if-cached", + "reload" + ], + "type": "string" + }, + "credentials": { + "enum": [ + "include", + "omit", + "same-origin" + ], + "type": "string" + }, + "headers": { + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "minItems": 2, + "maxItems": 2 + } + }, + { + "$ref": "#/definitions/Headers" + } + ] + }, + "integrity": { + "type": "string" + }, + "keepalive": { + "type": "boolean" + }, + "method": { + "type": "string" + }, + "mode": { + "enum": [ + "cors", + "navigate", + "no-cors", + "same-origin" + ], + "type": "string" + }, + "redirect": { + "enum": [ + "error", + "follow", + "manual" + ], + "type": "string" + }, + "referrer": { + "type": "string" + }, + "referrerPolicy": { + "enum": [ + "", + "no-referrer", + "no-referrer-when-downgrade", + "origin", + "origin-when-cross-origin", + "same-origin", + "strict-origin", + "strict-origin-when-cross-origin", + "unsafe-url" + ], + "type": "string" + }, + "signal": { + "anyOf": [ + { + "$ref": "#/definitions/AbortSignal" + }, + { + "type": "null" + } + ] + }, + "window": { + "type": "null" + } + }, + "additionalProperties": false + }, + "ArrayBuffer": { + "type": "object", + "properties": { + "byteLength": { + "type": "number" + }, + "__@toStringTag@25": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "__@toStringTag@25", + "byteLength" + ] + }, + "ArrayBufferView": { + "type": "object", + "properties": { + "buffer": { + "$ref": "#/definitions/ArrayBufferLike" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + } + }, + "additionalProperties": false, + "required": [ + "buffer", + "byteLength", + "byteOffset" + ] + }, + "ArrayBufferLike": { + "anyOf": [ + { + "$ref": "#/definitions/ArrayBuffer" + }, + { + "$ref": "#/definitions/SharedArrayBuffer" + } + ] + }, + "SharedArrayBuffer": { + "type": "object", + "properties": { + "byteLength": { + "type": "number" + }, + "__@species@598": { + "$ref": "#/definitions/SharedArrayBuffer" + }, + "__@toStringTag@25": { + "type": "string", + "enum": [ + "SharedArrayBuffer" + ] + } + }, + "additionalProperties": false, + "required": [ + "__@species@598", + "__@toStringTag@25", + "byteLength" + ] + }, + "ReadableStream": { + "type": "object", + "properties": { + "locked": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "locked" + ] + }, + "Blob": { + "type": "object", + "properties": { + "size": { + "type": "number" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "size", + "type" + ] + }, + "FormData": { + "type": "object", + "additionalProperties": false + }, + "URLSearchParams": { + "type": "object", + "additionalProperties": false + }, + "Record": { + "type": "object", + "additionalProperties": false + }, + "Headers": { + "type": "object", + "additionalProperties": false + }, + "AbortSignal": {}, + "RouteMatchCallback": {} + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/packages/workbox-build/src/schema/GetManifestOptions.json b/packages/workbox-build/src/schema/GetManifestOptions.json new file mode 100644 index 00000000..5f50fe56 --- /dev/null +++ b/packages/workbox-build/src/schema/GetManifestOptions.json @@ -0,0 +1,164 @@ +{ + "additionalProperties": false, + "type": "object", + "properties": { + "additionalManifestEntries": { + "description": "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ManifestEntry" + }, + { + "type": "string" + } + ] + } + }, + "dontCacheBustURLsMatching": { + "description": "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.", + "$ref": "#/definitions/RegExp" + }, + "manifestTransforms": { + "description": "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.", + "type": "array", + "items": {} + }, + "maximumFileSizeToCacheInBytes": { + "description": "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.", + "default": 2097152, + "type": "number" + }, + "modifyURLPrefix": { + "description": "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "globFollow": { + "description": "Determines whether or not symlinks are followed when generating the\nprecache manifest. For more information, see the definition of `follow` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).", + "default": true, + "type": "boolean" + }, + "globIgnores": { + "description": "A set of patterns matching files to always exclude when generating the\nprecache manifest. For more information, see the definition of `ignore` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).", + "default": [ + "**/node_modules/**/*" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "globPatterns": { + "description": "Files matching any of these patterns will be included in the precache\nmanifest. For more information, see the\n[`glob` primer](https://github.com/isaacs/node-glob#glob-primer).", + "default": [ + "**/*.{js,css,html}" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "globStrict": { + "description": "If true, an error reading a directory when generating a precache manifest\nwill cause the build to fail. If false, the problematic directory will be\nskipped. For more information, see the definition of `strict` in the `glob`\n[documentation](https://github.com/isaacs/node-glob#options).", + "default": true, + "type": "boolean" + }, + "templatedURLs": { + "description": "If a URL is rendered based on some server-side logic, its contents may\ndepend on multiple files or on some other unique string value. The keys in\nthis object are server-rendered URLs. If the values are an array of\nstrings, they will be interpreted as `glob` patterns, and the contents of\nany files matching the patterns will be used to uniquely version the URL.\nIf used with a single string, it will be interpreted as unique versioning\ninformation that you've generated for a given URL.", + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + } + }, + "globDirectory": { + "description": "The local directory you wish to match `globPatterns` against. The path is\nrelative to the current directory.", + "type": "string" + } + }, + "required": [ + "globDirectory" + ], + "definitions": { + "ManifestEntry": { + "type": "object", + "properties": { + "integrity": { + "type": "string" + }, + "revision": { + "type": [ + "null", + "string" + ] + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "revision", + "url" + ] + }, + "RegExp": { + "type": "object", + "properties": { + "source": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "ignoreCase": { + "type": "boolean" + }, + "multiline": { + "type": "boolean" + }, + "lastIndex": { + "type": "number" + }, + "flags": { + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "unicode": { + "type": "boolean" + }, + "dotAll": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "dotAll", + "flags", + "global", + "ignoreCase", + "lastIndex", + "multiline", + "source", + "sticky", + "unicode" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/packages/workbox-build/src/schema/InjectManifestOptions.json b/packages/workbox-build/src/schema/InjectManifestOptions.json new file mode 100644 index 00000000..b69ee153 --- /dev/null +++ b/packages/workbox-build/src/schema/InjectManifestOptions.json @@ -0,0 +1,179 @@ +{ + "additionalProperties": false, + "type": "object", + "properties": { + "additionalManifestEntries": { + "description": "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ManifestEntry" + }, + { + "type": "string" + } + ] + } + }, + "dontCacheBustURLsMatching": { + "description": "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.", + "$ref": "#/definitions/RegExp" + }, + "manifestTransforms": { + "description": "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.", + "type": "array", + "items": {} + }, + "maximumFileSizeToCacheInBytes": { + "description": "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.", + "default": 2097152, + "type": "number" + }, + "modifyURLPrefix": { + "description": "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "globFollow": { + "description": "Determines whether or not symlinks are followed when generating the\nprecache manifest. For more information, see the definition of `follow` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).", + "default": true, + "type": "boolean" + }, + "globIgnores": { + "description": "A set of patterns matching files to always exclude when generating the\nprecache manifest. For more information, see the definition of `ignore` in\nthe `glob` [documentation](https://github.com/isaacs/node-glob#options).", + "default": [ + "**/node_modules/**/*" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "globPatterns": { + "description": "Files matching any of these patterns will be included in the precache\nmanifest. For more information, see the\n[`glob` primer](https://github.com/isaacs/node-glob#glob-primer).", + "default": [ + "**/*.{js,css,html}" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "globStrict": { + "description": "If true, an error reading a directory when generating a precache manifest\nwill cause the build to fail. If false, the problematic directory will be\nskipped. For more information, see the definition of `strict` in the `glob`\n[documentation](https://github.com/isaacs/node-glob#options).", + "default": true, + "type": "boolean" + }, + "templatedURLs": { + "description": "If a URL is rendered based on some server-side logic, its contents may\ndepend on multiple files or on some other unique string value. The keys in\nthis object are server-rendered URLs. If the values are an array of\nstrings, they will be interpreted as `glob` patterns, and the contents of\nany files matching the patterns will be used to uniquely version the URL.\nIf used with a single string, it will be interpreted as unique versioning\ninformation that you've generated for a given URL.", + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + } + }, + "injectionPoint": { + "description": "The string to find inside of the `swSrc` file. Once found, it will be\nreplaced by the generated precache manifest.", + "default": "self.__WB_MANIFEST", + "type": "string" + }, + "swSrc": { + "description": "The path and filename of the service worker file that will be read during\nthe build process, relative to the current working directory.", + "type": "string" + }, + "swDest": { + "description": "The path and filename of the service worker file that will be created by\nthe build process, relative to the current working directory. It must end\nin '.js'.", + "type": "string" + }, + "globDirectory": { + "description": "The local directory you wish to match `globPatterns` against. The path is\nrelative to the current directory.", + "type": "string" + } + }, + "required": [ + "globDirectory", + "swDest", + "swSrc" + ], + "definitions": { + "ManifestEntry": { + "type": "object", + "properties": { + "integrity": { + "type": "string" + }, + "revision": { + "type": [ + "null", + "string" + ] + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "revision", + "url" + ] + }, + "RegExp": { + "type": "object", + "properties": { + "source": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "ignoreCase": { + "type": "boolean" + }, + "multiline": { + "type": "boolean" + }, + "lastIndex": { + "type": "number" + }, + "flags": { + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "unicode": { + "type": "boolean" + }, + "dotAll": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "dotAll", + "flags", + "global", + "ignoreCase", + "lastIndex", + "multiline", + "source", + "sticky", + "unicode" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/packages/workbox-build/src/schema/WebpackGenerateSWOptions.json b/packages/workbox-build/src/schema/WebpackGenerateSWOptions.json new file mode 100644 index 00000000..404fe96e --- /dev/null +++ b/packages/workbox-build/src/schema/WebpackGenerateSWOptions.json @@ -0,0 +1,850 @@ +{ + "additionalProperties": false, + "type": "object", + "properties": { + "additionalManifestEntries": { + "description": "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ManifestEntry" + }, + { + "type": "string" + } + ] + } + }, + "dontCacheBustURLsMatching": { + "description": "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.", + "$ref": "#/definitions/RegExp" + }, + "manifestTransforms": { + "description": "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.", + "type": "array", + "items": {} + }, + "maximumFileSizeToCacheInBytes": { + "description": "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.", + "default": 2097152, + "type": "number" + }, + "modifyURLPrefix": { + "description": "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "chunks": { + "description": "One or more chunk names whose corresponding output files should be included\nin the precache manifest.", + "type": "array", + "items": { + "type": "string" + } + }, + "exclude": { + "description": "One or more specifiers used to exclude assets from the precache manifest.\nThis is interpreted following\n[the same rules](https://webpack.js.org/configuration/module/#condition)\nas `webpack`'s standard `exclude` option.\nIf not provided, the default value is `[/\\.map$/, /^manifest.*\\.js$]`.", + "type": "array", + "items": {} + }, + "excludeChunks": { + "description": "One or more chunk names whose corresponding output files should be excluded\nfrom the precache manifest.", + "type": "array", + "items": { + "type": "string" + } + }, + "include": { + "description": "One or more specifiers used to include assets in the precache manifest.\nThis is interpreted following\n[the same rules](https://webpack.js.org/configuration/module/#condition)\nas `webpack`'s standard `include` option.", + "type": "array", + "items": {} + }, + "mode": { + "description": "If set to 'production', then an optimized service worker bundle that\nexcludes debugging info will be produced. If not explicitly configured\nhere, the `process.env.NODE_ENV` value will be used, and failing that, it\nwill fall back to `'production'`.", + "default": "production", + "type": [ + "null", + "string" + ] + }, + "babelPresetEnvTargets": { + "description": "The [targets](https://babeljs.io/docs/en/babel-preset-env#targets) to pass\nto `babel-preset-env` when transpiling the service worker bundle.", + "default": [ + "chrome >= 56" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "cacheId": { + "description": "An optional ID to be prepended to cache names. This is primarily useful for\nlocal development where multiple sites may be served from the same\n`http://localhost:port` origin.", + "type": [ + "null", + "string" + ] + }, + "cleanupOutdatedCaches": { + "description": "Whether or not Workbox should attempt to identify and delete any precaches\ncreated by older, incompatible versions.", + "default": false, + "type": "boolean" + }, + "clientsClaim": { + "description": "Whether or not the service worker should [start controlling](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#clientsclaim)\nany existing clients as soon as it activates.", + "default": false, + "type": "boolean" + }, + "directoryIndex": { + "description": "If a navigation request for a URL ending in `/` fails to match a precached\nURL, this value will be appended to the URL and that will be checked for a\nprecache match. This should be set to what your web server is using for its\ndirectory index.", + "type": [ + "null", + "string" + ] + }, + "disableDevLogs": { + "default": false, + "type": "boolean" + }, + "ignoreURLParametersMatching": { + "description": "Any search parameter names that match against one of the RegExp in this\narray will be removed before looking for a precache match. This is useful\nif your users might request URLs that contain, for example, URL parameters\nused to track the source of the traffic. If not provided, the default value\nis `[/^utm_/, /^fbclid$/]`.", + "type": "array", + "items": { + "$ref": "#/definitions/RegExp" + } + }, + "importScripts": { + "description": "A list of JavaScript files that should be passed to\n[`importScripts()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts)\ninside the generated service worker file. This is useful when you want to\nlet Workbox create your top-level service worker file, but want to include\nsome additional code, such as a push event listener.", + "type": "array", + "items": { + "type": "string" + } + }, + "inlineWorkboxRuntime": { + "description": "Whether the runtime code for the Workbox library should be included in the\ntop-level service worker, or split into a separate file that needs to be\ndeployed alongside the service worker. Keeping the runtime separate means\nthat users will not have to re-download the Workbox code each time your\ntop-level service worker changes.", + "default": false, + "type": "boolean" + }, + "navigateFallback": { + "description": "If specified, all\n[navigation requests](https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests)\nfor URLs that aren't precached will be fulfilled with the HTML at the URL\nprovided. You must pass in the URL of an HTML document that is listed in\nyour precache manifest. This is meant to be used in a Single Page App\nscenario, in which you want all navigations to use common\n[App Shell HTML](https://developers.google.com/web/fundamentals/architecture/app-shell).", + "default": null, + "type": [ + "null", + "string" + ] + }, + "navigateFallbackAllowlist": { + "description": "An optional array of regular expressions that restricts which URLs the\nconfigured `navigateFallback` behavior applies to. This is useful if only a\nsubset of your site's URLs should be treated as being part of a\n[Single Page App](https://en.wikipedia.org/wiki/Single-page_application).\nIf both `navigateFallbackDenylist` and `navigateFallbackAllowlist` are\nconfigured, the denylist takes precedent.\n\n*Note*: These RegExps may be evaluated against every destination URL during\na navigation. Avoid using\n[complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077),\nor else your users may see delays when navigating your site.", + "type": "array", + "items": { + "$ref": "#/definitions/RegExp" + } + }, + "navigateFallbackDenylist": { + "description": "An optional array of regular expressions that restricts which URLs the\nconfigured `navigateFallback` behavior applies to. This is useful if only a\nsubset of your site's URLs should be treated as being part of a\n[Single Page App](https://en.wikipedia.org/wiki/Single-page_application).\nIf both `navigateFallbackDenylist` and `navigateFallbackAllowlist` are\nconfigured, the denylist takes precedence.\n\n*Note*: These RegExps may be evaluated against every destination URL during\na navigation. Avoid using\n[complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077),\nor else your users may see delays when navigating your site.", + "type": "array", + "items": { + "$ref": "#/definitions/RegExp" + } + }, + "navigationPreload": { + "description": "Whether or not to enable\n[navigation preload](https://developers.google.com/web/tools/workbox/modules/workbox-navigation-preload)\nin the generated service worker. When set to true, you must also use\n`runtimeCaching` to set up an appropriate response strategy that will match\nnavigation requests, and make use of the preloaded response.", + "default": false, + "type": "boolean" + }, + "offlineGoogleAnalytics": { + "description": "Controls whether or not to include support for\n[offline Google Analytics](https://developers.google.com/web/tools/workbox/guides/enable-offline-analytics).\nWhen `true`, the call to `workbox-google-analytics`'s `initialize()` will\nbe added to your generated service worker. When set to an `Object`, that\nobject will be passed in to the `initialize()` call, allowing you to\ncustomize the behavior.", + "default": false, + "anyOf": [ + { + "$ref": "#/definitions/GoogleAnalyticsInitializeOptions" + }, + { + "type": "boolean" + } + ] + }, + "runtimeCaching": { + "description": "When using Workbox's build tools to generate your service worker, you can\nspecify one or more runtime caching configurations. These are then\ntranslated to {@link workbox-routing.registerRoute} calls using the match\nand handler configuration you define.\n\nFor all of the options, see the {@link workbox-build.RuntimeCaching}\ndocumentation. The example below shows a typical configuration, with two\nruntime routes defined:", + "type": "array", + "items": { + "$ref": "#/definitions/RuntimeCaching" + } + }, + "skipWaiting": { + "description": "Whether to add an unconditional call to [`skipWaiting()`](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#skip_the_waiting_phase)\nto the generated service worker. If `false`, then a `message` listener will\nbe added instead, allowing client pages to trigger `skipWaiting()` by\ncalling `postMessage({type: 'SKIP_WAITING'})` on a waiting service worker.", + "default": false, + "type": "boolean" + }, + "sourcemap": { + "description": "Whether to create a sourcemap for the generated service worker files.", + "default": true, + "type": "boolean" + }, + "importScriptsViaChunks": { + "description": "One or more names of webpack chunks. The content of those chunks will be\nincluded in the generated service worker, via a call to `importScripts()`.", + "type": "array", + "items": { + "type": "string" + } + }, + "swDest": { + "description": "The asset name of the service worker file created by this plugin.", + "default": "service-worker.js", + "type": "string" + } + }, + "definitions": { + "ManifestEntry": { + "type": "object", + "properties": { + "integrity": { + "type": "string" + }, + "revision": { + "type": [ + "null", + "string" + ] + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "revision", + "url" + ] + }, + "RegExp": { + "type": "object", + "properties": { + "source": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "ignoreCase": { + "type": "boolean" + }, + "multiline": { + "type": "boolean" + }, + "lastIndex": { + "type": "number" + }, + "flags": { + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "unicode": { + "type": "boolean" + }, + "dotAll": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "dotAll", + "flags", + "global", + "ignoreCase", + "lastIndex", + "multiline", + "source", + "sticky", + "unicode" + ] + }, + "GoogleAnalyticsInitializeOptions": { + "type": "object", + "properties": { + "cacheName": { + "type": "string" + }, + "parameterOverrides": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "hitFilter": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "RuntimeCaching": { + "type": "object", + "properties": { + "handler": { + "description": "This determines how the runtime route will generate a response.\nTo use one of the built-in {@link workbox-strategies}, provide its name,\nlike `'NetworkFirst'`.\nAlternatively, this can be a {@link workbox-core.RouteHandler} callback\nfunction with custom response logic.", + "anyOf": [ + { + "$ref": "#/definitions/RouteHandlerCallback" + }, + { + "$ref": "#/definitions/RouteHandlerObject" + }, + { + "enum": [ + "CacheFirst", + "CacheOnly", + "NetworkFirst", + "NetworkOnly", + "StaleWhileRevalidate" + ], + "type": "string" + } + ] + }, + "method": { + "description": "The HTTP method to match against. The default value of `'GET'` is normally\nsufficient, unless you explicitly need to match `'POST'`, `'PUT'`, or\nanother type of request.", + "default": "GET", + "enum": [ + "DELETE", + "GET", + "HEAD", + "PATCH", + "POST", + "PUT" + ], + "type": "string" + }, + "options": { + "type": "object", + "properties": { + "backgroundSync": { + "description": "Configuring this will add a\n{@link workbox-background-sync.BackgroundSyncPlugin} instance to the\n{@link workbox-strategies} configured in `handler`.", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "options": { + "$ref": "#/definitions/QueueOptions" + } + }, + "additionalProperties": false, + "required": [ + "name" + ] + }, + "broadcastUpdate": { + "description": "Configuring this will add a\n{@link workbox-broadcast-update.BroadcastUpdatePlugin} instance to the\n{@link workbox-strategies} configured in `handler`.", + "type": "object", + "properties": { + "channelName": { + "type": "string" + }, + "options": { + "$ref": "#/definitions/BroadcastCacheUpdateOptions" + } + }, + "additionalProperties": false, + "required": [ + "options" + ] + }, + "cacheableResponse": { + "description": "Configuring this will add a\n{@link workbox-cacheable-response.CacheableResponsePlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/CacheableResponseOptions" + }, + "cacheName": { + "description": "If provided, this will set the `cacheName` property of the\n{@link workbox-strategies} configured in `handler`.", + "type": [ + "null", + "string" + ] + }, + "expiration": { + "description": "Configuring this will add a\n{@link workbox-expiration.ExpirationPlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/ExpirationPluginOptions" + }, + "networkTimeoutSeconds": { + "description": "If provided, this will set the `networkTimeoutSeconds` property of the\n{@link workbox-strategies} configured in `handler`. Note that only\n`'NetworkFirst'` and `'NetworkOnly'` support `networkTimeoutSeconds`.", + "type": "number" + }, + "plugins": { + "description": "Configuring this allows the use of one or more Workbox plugins that\ndon't have \"shortcut\" options (like `expiration` for\n{@link workbox-expiration.ExpirationPlugin}). The plugins provided here\nwill be added to the {@link workbox-strategies} configured in `handler`.", + "type": "array", + "items": { + "$ref": "#/definitions/WorkboxPlugin" + } + }, + "precacheFallback": { + "description": "Configuring this will add a\n{@link workbox-precaching.PrecacheFallbackPlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "type": "object", + "properties": { + "fallbackURL": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "fallbackURL" + ] + }, + "rangeRequests": { + "description": "Enabling this will add a\n{@link workbox-range-requests.RangeRequestsPlugin} instance to\nthe {@link workbox-strategies} configured in `handler`.", + "type": "boolean" + }, + "fetchOptions": { + "description": "Configuring this will pass along the `fetchOptions` value to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/RequestInit" + }, + "matchOptions": { + "description": "Configuring this will pass along the `matchOptions` value to\nthe {@link workbox-strategies} configured in `handler`.", + "$ref": "#/definitions/CacheQueryOptions" + } + }, + "additionalProperties": false + }, + "urlPattern": { + "description": "This match criteria determines whether the configured handler will\ngenerate a response for any requests that don't match one of the precached\nURLs. If multiple `RuntimeCaching` routes are defined, then the first one\nwhose `urlPattern` matches will be the one that responds.\n\nThis value directly maps to the first parameter passed to\n{@link workbox-routing.registerRoute}. It's recommended to use a\n{@link workbox-core.RouteMatchCallback} function for greatest flexibility.", + "anyOf": [ + { + "$ref": "#/definitions/RegExp" + }, + { + "$ref": "#/definitions/RouteMatchCallback" + }, + { + "type": "string" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "handler", + "urlPattern" + ] + }, + "RouteHandlerCallback": {}, + "RouteHandlerObject": { + "description": "An object with a `handle` method of type `RouteHandlerCallback`.\n\nA `Route` object can be created with either an `RouteHandlerCallback`\nfunction or this `RouteHandler` object. The benefit of the `RouteHandler`\nis it can be extended (as is done by the `workbox-strategies` package).", + "type": "object", + "properties": { + "handle": { + "$ref": "#/definitions/RouteHandlerCallback" + } + }, + "additionalProperties": false, + "required": [ + "handle" + ] + }, + "QueueOptions": { + "type": "object", + "properties": { + "forceSyncFallback": { + "type": "boolean" + }, + "maxRetentionTime": { + "type": "number" + }, + "onSync": { + "$ref": "#/definitions/OnSyncCallback" + } + }, + "additionalProperties": false + }, + "OnSyncCallback": {}, + "BroadcastCacheUpdateOptions": { + "type": "object", + "properties": { + "headersToCheck": { + "type": "array", + "items": { + "type": "string" + } + }, + "generatePayload": { + "type": "object", + "additionalProperties": false + }, + "notifyAllClients": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "CacheableResponseOptions": { + "type": "object", + "properties": { + "statuses": { + "type": "array", + "items": { + "type": "number" + } + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "ExpirationPluginOptions": { + "type": "object", + "properties": { + "maxEntries": { + "type": "number" + }, + "maxAgeSeconds": { + "type": "number" + }, + "matchOptions": { + "$ref": "#/definitions/CacheQueryOptions" + }, + "purgeOnQuotaError": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "CacheQueryOptions": { + "type": "object", + "properties": { + "ignoreMethod": { + "type": "boolean" + }, + "ignoreSearch": { + "type": "boolean" + }, + "ignoreVary": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "WorkboxPlugin": { + "description": "An object with optional lifecycle callback properties for the fetch and\ncache operations.", + "type": "object", + "properties": { + "cacheDidUpdate": {}, + "cachedResponseWillBeUsed": {}, + "cacheKeyWillBeUsed": {}, + "cacheWillUpdate": {}, + "fetchDidFail": {}, + "fetchDidSucceed": {}, + "handlerDidComplete": {}, + "handlerDidError": {}, + "handlerDidRespond": {}, + "handlerWillRespond": {}, + "handlerWillStart": {}, + "requestWillFetch": {} + }, + "additionalProperties": false + }, + "CacheDidUpdateCallback": { + "type": "object", + "additionalProperties": false + }, + "CachedResponseWillBeUsedCallback": { + "type": "object", + "additionalProperties": false + }, + "CacheKeyWillBeUsedCallback": { + "type": "object", + "additionalProperties": false + }, + "CacheWillUpdateCallback": { + "type": "object", + "additionalProperties": false + }, + "FetchDidFailCallback": { + "type": "object", + "additionalProperties": false + }, + "FetchDidSucceedCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerDidCompleteCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerDidErrorCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerDidRespondCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerWillRespondCallback": { + "type": "object", + "additionalProperties": false + }, + "HandlerWillStartCallback": { + "type": "object", + "additionalProperties": false + }, + "RequestWillFetchCallback": { + "type": "object", + "additionalProperties": false + }, + "RequestInit": { + "type": "object", + "properties": { + "body": { + "anyOf": [ + { + "$ref": "#/definitions/ArrayBuffer" + }, + { + "$ref": "#/definitions/ArrayBufferView" + }, + { + "$ref": "#/definitions/ReadableStream" + }, + { + "$ref": "#/definitions/Blob" + }, + { + "$ref": "#/definitions/FormData" + }, + { + "$ref": "#/definitions/URLSearchParams" + }, + { + "type": [ + "null", + "string" + ] + } + ] + }, + "cache": { + "enum": [ + "default", + "force-cache", + "no-cache", + "no-store", + "only-if-cached", + "reload" + ], + "type": "string" + }, + "credentials": { + "enum": [ + "include", + "omit", + "same-origin" + ], + "type": "string" + }, + "headers": { + "anyOf": [ + { + "$ref": "#/definitions/Record" + }, + { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "string" + }, + { + "type": "string" + } + ], + "minItems": 2, + "maxItems": 2 + } + }, + { + "$ref": "#/definitions/Headers" + } + ] + }, + "integrity": { + "type": "string" + }, + "keepalive": { + "type": "boolean" + }, + "method": { + "type": "string" + }, + "mode": { + "enum": [ + "cors", + "navigate", + "no-cors", + "same-origin" + ], + "type": "string" + }, + "redirect": { + "enum": [ + "error", + "follow", + "manual" + ], + "type": "string" + }, + "referrer": { + "type": "string" + }, + "referrerPolicy": { + "enum": [ + "", + "no-referrer", + "no-referrer-when-downgrade", + "origin", + "origin-when-cross-origin", + "same-origin", + "strict-origin", + "strict-origin-when-cross-origin", + "unsafe-url" + ], + "type": "string" + }, + "signal": { + "anyOf": [ + { + "$ref": "#/definitions/AbortSignal" + }, + { + "type": "null" + } + ] + }, + "window": { + "type": "null" + } + }, + "additionalProperties": false + }, + "ArrayBuffer": { + "type": "object", + "properties": { + "byteLength": { + "type": "number" + }, + "__@toStringTag@25": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "__@toStringTag@25", + "byteLength" + ] + }, + "ArrayBufferView": { + "type": "object", + "properties": { + "buffer": { + "$ref": "#/definitions/ArrayBufferLike" + }, + "byteLength": { + "type": "number" + }, + "byteOffset": { + "type": "number" + } + }, + "additionalProperties": false, + "required": [ + "buffer", + "byteLength", + "byteOffset" + ] + }, + "ArrayBufferLike": { + "anyOf": [ + { + "$ref": "#/definitions/ArrayBuffer" + }, + { + "$ref": "#/definitions/SharedArrayBuffer" + } + ] + }, + "SharedArrayBuffer": { + "type": "object", + "properties": { + "byteLength": { + "type": "number" + }, + "__@species@598": { + "$ref": "#/definitions/SharedArrayBuffer" + }, + "__@toStringTag@25": { + "type": "string", + "enum": [ + "SharedArrayBuffer" + ] + } + }, + "additionalProperties": false, + "required": [ + "__@species@598", + "__@toStringTag@25", + "byteLength" + ] + }, + "ReadableStream": { + "type": "object", + "properties": { + "locked": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "locked" + ] + }, + "Blob": { + "type": "object", + "properties": { + "size": { + "type": "number" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "size", + "type" + ] + }, + "FormData": { + "type": "object", + "additionalProperties": false + }, + "URLSearchParams": { + "type": "object", + "additionalProperties": false + }, + "Record": { + "type": "object", + "additionalProperties": false + }, + "Headers": { + "type": "object", + "additionalProperties": false + }, + "AbortSignal": {}, + "RouteMatchCallback": {} + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/packages/workbox-build/src/schema/WebpackInjectManifestOptions.json b/packages/workbox-build/src/schema/WebpackInjectManifestOptions.json new file mode 100644 index 00000000..b9f112b5 --- /dev/null +++ b/packages/workbox-build/src/schema/WebpackInjectManifestOptions.json @@ -0,0 +1,167 @@ +{ + "additionalProperties": false, + "type": "object", + "properties": { + "additionalManifestEntries": { + "description": "A list of entries to be precached, in addition to any entries that are\ngenerated as part of the build configuration.", + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/definitions/ManifestEntry" + }, + { + "type": "string" + } + ] + } + }, + "dontCacheBustURLsMatching": { + "description": "Assets that match this will be assumed to be uniquely versioned via their\nURL, and exempted from the normal HTTP cache-busting that's done when\npopulating the precache. While not required, it's recommended that if your\nexisting build process already inserts a `[hash]` value into each filename,\nyou provide a RegExp that will detect that, as it will reduce the bandwidth\nconsumed when precaching.", + "$ref": "#/definitions/RegExp" + }, + "manifestTransforms": { + "description": "One or more functions which will be applied sequentially against the\ngenerated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are\nalso specified, their corresponding transformations will be applied first.", + "type": "array", + "items": {} + }, + "maximumFileSizeToCacheInBytes": { + "description": "This value can be used to determine the maximum size of files that will be\nprecached. This prevents you from inadvertently precaching very large files\nthat might have accidentally matched one of your patterns.", + "default": 2097152, + "type": "number" + }, + "modifyURLPrefix": { + "description": "An object mapping string prefixes to replacement string values. This can be\nused to, e.g., remove or add a path prefix from a manifest entry if your\nweb hosting setup doesn't match your local filesystem setup. As an\nalternative with more flexibility, you can use the `manifestTransforms`\noption and provide a function that modifies the entries in the manifest\nusing whatever logic you provide.\n\nExample usage:\n\n```\n// Replace a '/dist/' prefix with '/', and also prepend\n// '/static' to every URL.\nmodifyURLPrefix: {\n '/dist/': '/',\n '': '/static',\n}\n```", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "chunks": { + "description": "One or more chunk names whose corresponding output files should be included\nin the precache manifest.", + "type": "array", + "items": { + "type": "string" + } + }, + "exclude": { + "description": "One or more specifiers used to exclude assets from the precache manifest.\nThis is interpreted following\n[the same rules](https://webpack.js.org/configuration/module/#condition)\nas `webpack`'s standard `exclude` option.\nIf not provided, the default value is `[/\\.map$/, /^manifest.*\\.js$]`.", + "type": "array", + "items": {} + }, + "excludeChunks": { + "description": "One or more chunk names whose corresponding output files should be excluded\nfrom the precache manifest.", + "type": "array", + "items": { + "type": "string" + } + }, + "include": { + "description": "One or more specifiers used to include assets in the precache manifest.\nThis is interpreted following\n[the same rules](https://webpack.js.org/configuration/module/#condition)\nas `webpack`'s standard `include` option.", + "type": "array", + "items": {} + }, + "mode": { + "description": "If set to 'production', then an optimized service worker bundle that\nexcludes debugging info will be produced. If not explicitly configured\nhere, the `mode` value configured in the current `webpack` compilation\nwill be used.", + "type": [ + "null", + "string" + ] + }, + "injectionPoint": { + "description": "The string to find inside of the `swSrc` file. Once found, it will be\nreplaced by the generated precache manifest.", + "default": "self.__WB_MANIFEST", + "type": "string" + }, + "swSrc": { + "description": "The path and filename of the service worker file that will be read during\nthe build process, relative to the current working directory.", + "type": "string" + }, + "compileSrc": { + "description": "When `true` (the default), the `swSrc` file will be compiled by webpack.\nWhen `false`, compilation will not occur (and `webpackCompilationPlugins`\ncan't be used.) Set to `false` if you want to inject the manifest into,\ne.g., a JSON file.", + "default": true, + "type": "boolean" + }, + "swDest": { + "description": "The asset name of the service worker file that will be created by this\nplugin. If omitted, the name will be based on the `swSrc` name.", + "type": "string" + }, + "webpackCompilationPlugins": { + "description": "Optional `webpack` plugins that will be used when compiling the `swSrc`\ninput file. Only valid if `compileSrc` is `true`.", + "type": "array", + "items": {} + } + }, + "required": [ + "swSrc" + ], + "definitions": { + "ManifestEntry": { + "type": "object", + "properties": { + "integrity": { + "type": "string" + }, + "revision": { + "type": [ + "null", + "string" + ] + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "revision", + "url" + ] + }, + "RegExp": { + "type": "object", + "properties": { + "source": { + "type": "string" + }, + "global": { + "type": "boolean" + }, + "ignoreCase": { + "type": "boolean" + }, + "multiline": { + "type": "boolean" + }, + "lastIndex": { + "type": "number" + }, + "flags": { + "type": "string" + }, + "sticky": { + "type": "boolean" + }, + "unicode": { + "type": "boolean" + }, + "dotAll": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "dotAll", + "flags", + "global", + "ignoreCase", + "lastIndex", + "multiline", + "source", + "sticky", + "unicode" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} diff --git a/packages/workbox-build/src/strip-comments.d.ts b/packages/workbox-build/src/strip-comments.d.ts new file mode 100644 index 00000000..f37e7288 --- /dev/null +++ b/packages/workbox-build/src/strip-comments.d.ts @@ -0,0 +1 @@ +declare module "strip-comments"; diff --git a/packages/workbox-build/src/templates/sw-template.ts b/packages/workbox-build/src/templates/sw-template.ts new file mode 100644 index 00000000..dacfaef8 --- /dev/null +++ b/packages/workbox-build/src/templates/sw-template.ts @@ -0,0 +1,60 @@ +/* + 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. +*/ + +export const swTemplate = `/** + * Welcome to your Workbox-powered service worker! + * + * You'll need to register this file in your web app. + * See https://goo.gl/nhQhGp + * + * The rest of the code is auto-generated. Please don't update this file + * directly; instead, make changes to your Workbox build configuration + * and re-run your build process. + * See https://goo.gl/2aRDsh + */ + +<% if (importScripts) { %> +importScripts( + <%= importScripts.map(JSON.stringify).join(',\\n ') %> +); +<% } %> + +<% if (navigationPreload) { %><%= use('workbox-navigation-preload', 'enable') %>();<% } %> + +<% if (cacheId) { %><%= use('workbox-core', 'setCacheNameDetails') %>({prefix: <%= JSON.stringify(cacheId) %>});<% } %> + +<% if (skipWaiting) { %> +self.skipWaiting(); +<% } else { %> +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } +}); +<% } %> +<% if (clientsClaim) { %><%= use('workbox-core', 'clientsClaim') %>();<% } %> + +<% if (Array.isArray(manifestEntries) && manifestEntries.length > 0) {%> +/** + * The precacheAndRoute() method efficiently caches and responds to + * requests for URLs in the manifest. + * See https://goo.gl/S9QRab + */ +<%= use('workbox-precaching', 'precacheAndRoute') %>(<%= JSON.stringify(manifestEntries, null, 2) %>, <%= precacheOptionsString %>); +<% if (cleanupOutdatedCaches) { %><%= use('workbox-precaching', 'cleanupOutdatedCaches') %>();<% } %> +<% if (navigateFallback) { %><%= use('workbox-routing', 'registerRoute') %>(new <%= use('workbox-routing', 'NavigationRoute') %>(<%= use('workbox-precaching', 'createHandlerBoundToURL') %>(<%= JSON.stringify(navigateFallback) %>)<% if (navigateFallbackAllowlist || navigateFallbackDenylist) { %>, { + <% if (navigateFallbackAllowlist) { %>allowlist: [<%= navigateFallbackAllowlist %>],<% } %> + <% if (navigateFallbackDenylist) { %>denylist: [<%= navigateFallbackDenylist %>],<% } %> +}<% } %>));<% } %> +<% } %> + +<% if (runtimeCaching) { runtimeCaching.forEach(runtimeCachingString => {%><%= runtimeCachingString %><% });} %> + +<% if (offlineAnalyticsConfigString) { %><%= use('workbox-google-analytics', 'initialize') %>(<%= offlineAnalyticsConfigString %>);<% } %> + +<% if (disableDevLogs) { %>self.__WB_DISABLE_DEV_LOGS = true;<% } %>`; diff --git a/packages/workbox-build/src/types.ts b/packages/workbox-build/src/types.ts new file mode 100644 index 00000000..223c3617 --- /dev/null +++ b/packages/workbox-build/src/types.ts @@ -0,0 +1,590 @@ +import type { PackageJson } from "type-fest"; +import type { QueueOptions } from "workbox-background-sync/Queue"; +import type { BroadcastCacheUpdateOptions } from "workbox-broadcast-update/BroadcastCacheUpdate"; +import type { CacheableResponseOptions } from "workbox-cacheable-response/CacheableResponse"; +import type { RouteHandler, RouteMatchCallback , WorkboxPlugin } from "workbox-core/types"; +import type { ExpirationPluginOptions } from "workbox-expiration/ExpirationPlugin"; +import type { GoogleAnalyticsInitializeOptions } from "workbox-google-analytics/initialize"; +import type { HTTPMethod } from "workbox-routing/utils/constants"; + +export interface ManifestEntry { + integrity?: string; + revision: string | null; + url: string; +} + +export type StrategyName = + | "CacheFirst" + | "CacheOnly" + | "NetworkFirst" + | "NetworkOnly" + | "StaleWhileRevalidate"; + +export interface RuntimeCaching { + /** + * This determines how the runtime route will generate a response. + * To use one of the built-in {@link workbox-strategies}, provide its name, + * like `'NetworkFirst'`. + * Alternatively, this can be a {@link workbox-core.RouteHandler} callback + * function with custom response logic. + */ + handler: RouteHandler | StrategyName; + /** + * The HTTP method to match against. The default value of `'GET'` is normally + * sufficient, unless you explicitly need to match `'POST'`, `'PUT'`, or + * another type of request. + * @default "GET" + */ + method?: HTTPMethod; + options?: { + /** + * Configuring this will add a + * {@link workbox-background-sync.BackgroundSyncPlugin} instance to the + * {@link workbox-strategies} configured in `handler`. + */ + backgroundSync?: { + name: string; + options?: QueueOptions; + }; + /** + * Configuring this will add a + * {@link workbox-broadcast-update.BroadcastUpdatePlugin} instance to the + * {@link workbox-strategies} configured in `handler`. + */ + broadcastUpdate?: { + // TODO: This option is ignored since we switched to using postMessage(). + // Remove it in the next major release. + channelName?: string; + options: BroadcastCacheUpdateOptions; + }; + /** + * Configuring this will add a + * {@link workbox-cacheable-response.CacheableResponsePlugin} instance to + * the {@link workbox-strategies} configured in `handler`. + */ + cacheableResponse?: CacheableResponseOptions; + /** + * If provided, this will set the `cacheName` property of the + * {@link workbox-strategies} configured in `handler`. + */ + cacheName?: string | null; + /** + * Configuring this will add a + * {@link workbox-expiration.ExpirationPlugin} instance to + * the {@link workbox-strategies} configured in `handler`. + */ + expiration?: ExpirationPluginOptions; + /** + * If provided, this will set the `networkTimeoutSeconds` property of the + * {@link workbox-strategies} configured in `handler`. Note that only + * `'NetworkFirst'` and `'NetworkOnly'` support `networkTimeoutSeconds`. + */ + networkTimeoutSeconds?: number; + /** + * Configuring this allows the use of one or more Workbox plugins that + * don't have "shortcut" options (like `expiration` for + * {@link workbox-expiration.ExpirationPlugin}). The plugins provided here + * will be added to the {@link workbox-strategies} configured in `handler`. + */ + plugins?: Array; + /** + * Configuring this will add a + * {@link workbox-precaching.PrecacheFallbackPlugin} instance to + * the {@link workbox-strategies} configured in `handler`. + */ + precacheFallback?: { + fallbackURL: string; + }; + /** + * Enabling this will add a + * {@link workbox-range-requests.RangeRequestsPlugin} instance to + * the {@link workbox-strategies} configured in `handler`. + */ + rangeRequests?: boolean; + /** + * Configuring this will pass along the `fetchOptions` value to + * the {@link workbox-strategies} configured in `handler`. + */ + fetchOptions?: RequestInit; + /** + * Configuring this will pass along the `matchOptions` value to + * the {@link workbox-strategies} configured in `handler`. + */ + matchOptions?: CacheQueryOptions; + }; + /** + * This match criteria determines whether the configured handler will + * generate a response for any requests that don't match one of the precached + * URLs. If multiple `RuntimeCaching` routes are defined, then the first one + * whose `urlPattern` matches will be the one that responds. + * + * This value directly maps to the first parameter passed to + * {@link workbox-routing.registerRoute}. It's recommended to use a + * {@link workbox-core.RouteMatchCallback} function for greatest flexibility. + */ + urlPattern: RegExp | string | RouteMatchCallback; +} + +export interface ManifestTransformResult { + manifest: Array; + warnings?: Array; +} + +export type ManifestTransform = ( + manifestEntries: Array, + compilation?: unknown +) => Promise | ManifestTransformResult; + +export interface BasePartial { + /** + * A list of entries to be precached, in addition to any entries that are + * generated as part of the build configuration. + */ + additionalManifestEntries?: Array; + /** + * Assets that match this will be assumed to be uniquely versioned via their + * URL, and exempted from the normal HTTP cache-busting that's done when + * populating the precache. While not required, it's recommended that if your + * existing build process already inserts a `[hash]` value into each filename, + * you provide a RegExp that will detect that, as it will reduce the bandwidth + * consumed when precaching. + */ + dontCacheBustURLsMatching?: RegExp; + /** + * One or more functions which will be applied sequentially against the + * generated manifest. If `modifyURLPrefix` or `dontCacheBustURLsMatching` are + * also specified, their corresponding transformations will be applied first. + */ + manifestTransforms?: Array; + /** + * This value can be used to determine the maximum size of files that will be + * precached. This prevents you from inadvertently precaching very large files + * that might have accidentally matched one of your patterns. + * @default 2097152 + */ + maximumFileSizeToCacheInBytes?: number; + /** + * An object mapping string prefixes to replacement string values. This can be + * used to, e.g., remove or add a path prefix from a manifest entry if your + * web hosting setup doesn't match your local filesystem setup. As an + * alternative with more flexibility, you can use the `manifestTransforms` + * option and provide a function that modifies the entries in the manifest + * using whatever logic you provide. + * + * Example usage: + * + * ``` + * // Replace a '/dist/' prefix with '/', and also prepend + * // '/static' to every URL. + * modifyURLPrefix: { + * '/dist/': '/', + * '': '/static', + * } + * ``` + */ + modifyURLPrefix?: { + [key: string]: string; + }; +} + +export interface GeneratePartial { + /** + * The [targets](https://babeljs.io/docs/en/babel-preset-env#targets) to pass + * to `babel-preset-env` when transpiling the service worker bundle. + * @default ["chrome >= 56"] + */ + babelPresetEnvTargets?: Array; + /** + * An optional ID to be prepended to cache names. This is primarily useful for + * local development where multiple sites may be served from the same + * `http://localhost:port` origin. + */ + cacheId?: string | null; + /** + * Whether or not Workbox should attempt to identify and delete any precaches + * created by older, incompatible versions. + * @default false + */ + cleanupOutdatedCaches?: boolean; + /** + * Whether or not the service worker should [start controlling](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#clientsclaim) + * any existing clients as soon as it activates. + * @default false + */ + clientsClaim?: boolean; + /** + * If a navigation request for a URL ending in `/` fails to match a precached + * URL, this value will be appended to the URL and that will be checked for a + * precache match. This should be set to what your web server is using for its + * directory index. + */ + directoryIndex?: string | null; + /** + * @default false + */ + disableDevLogs?: boolean; + // We can't use the @default annotation here to assign the value via AJV, as + // an Array can't be serialized into JSON. + /** + * Any search parameter names that match against one of the RegExp in this + * array will be removed before looking for a precache match. This is useful + * if your users might request URLs that contain, for example, URL parameters + * used to track the source of the traffic. If not provided, the default value + * is `[/^utm_/, /^fbclid$/]`. + * + */ + ignoreURLParametersMatching?: Array; + /** + * A list of JavaScript files that should be passed to + * [`importScripts()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts) + * inside the generated service worker file. This is useful when you want to + * let Workbox create your top-level service worker file, but want to include + * some additional code, such as a push event listener. + */ + importScripts?: Array; + /** + * Whether the runtime code for the Workbox library should be included in the + * top-level service worker, or split into a separate file that needs to be + * deployed alongside the service worker. Keeping the runtime separate means + * that users will not have to re-download the Workbox code each time your + * top-level service worker changes. + * @default false + */ + inlineWorkboxRuntime?: boolean; + /** + * If set to 'production', then an optimized service worker bundle that + * excludes debugging info will be produced. If not explicitly configured + * here, the `process.env.NODE_ENV` value will be used, and failing that, it + * will fall back to `'production'`. + * @default "production" + */ + mode?: string | null; + /** + * If specified, all + * [navigation requests](https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests) + * for URLs that aren't precached will be fulfilled with the HTML at the URL + * provided. You must pass in the URL of an HTML document that is listed in + * your precache manifest. This is meant to be used in a Single Page App + * scenario, in which you want all navigations to use common + * [App Shell HTML](https://developers.google.com/web/fundamentals/architecture/app-shell). + * @default null + */ + navigateFallback?: string | null; + /** + * An optional array of regular expressions that restricts which URLs the + * configured `navigateFallback` behavior applies to. This is useful if only a + * subset of your site's URLs should be treated as being part of a + * [Single Page App](https://en.wikipedia.org/wiki/Single-page_application). + * If both `navigateFallbackDenylist` and `navigateFallbackAllowlist` are + * configured, the denylist takes precedent. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + */ + navigateFallbackAllowlist?: Array; + /** + * An optional array of regular expressions that restricts which URLs the + * configured `navigateFallback` behavior applies to. This is useful if only a + * subset of your site's URLs should be treated as being part of a + * [Single Page App](https://en.wikipedia.org/wiki/Single-page_application). + * If both `navigateFallbackDenylist` and `navigateFallbackAllowlist` are + * configured, the denylist takes precedence. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + */ + navigateFallbackDenylist?: Array; + /** + * Whether or not to enable + * [navigation preload](https://developers.google.com/web/tools/workbox/modules/workbox-navigation-preload) + * in the generated service worker. When set to true, you must also use + * `runtimeCaching` to set up an appropriate response strategy that will match + * navigation requests, and make use of the preloaded response. + * @default false + */ + navigationPreload?: boolean; + /** + * Controls whether or not to include support for + * [offline Google Analytics](https://developers.google.com/web/tools/workbox/guides/enable-offline-analytics). + * When `true`, the call to `workbox-google-analytics`'s `initialize()` will + * be added to your generated service worker. When set to an `Object`, that + * object will be passed in to the `initialize()` call, allowing you to + * customize the behavior. + * @default false + */ + offlineGoogleAnalytics?: boolean | GoogleAnalyticsInitializeOptions; + /** + * When using Workbox's build tools to generate your service worker, you can + * specify one or more runtime caching configurations. These are then + * translated to {@link workbox-routing.registerRoute} calls using the match + * and handler configuration you define. + * + * For all of the options, see the {@link workbox-build.RuntimeCaching} + * documentation. The example below shows a typical configuration, with two + * runtime routes defined: + * + * @example + * runtimeCaching: [{ + * urlPattern: ({url}) => url.origin === 'https://api.example.com', + * handler: 'NetworkFirst', + * options: { + * cacheName: 'api-cache', + * }, + * }, { + * urlPattern: ({request}) => request.destination === 'image', + * handler: 'StaleWhileRevalidate', + * options: { + * cacheName: 'images-cache', + * expiration: { + * maxEntries: 10, + * }, + * }, + * }] + */ + runtimeCaching?: Array; + /** + * Whether to add an unconditional call to [`skipWaiting()`](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#skip_the_waiting_phase) + * to the generated service worker. If `false`, then a `message` listener will + * be added instead, allowing client pages to trigger `skipWaiting()` by + * calling `postMessage({type: 'SKIP_WAITING'})` on a waiting service worker. + * @default false + */ + skipWaiting?: boolean; + /** + * Whether to create a sourcemap for the generated service worker files. + * @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 { + /** + * The local directory you wish to match `globPatterns` against. The path is + * relative to the current directory. + */ + globDirectory: string; +} + +export interface OptionalGlobDirectoryPartial { + /** + * The local directory you wish to match `globPatterns` against. The path is + * relative to the current directory. + */ + globDirectory?: string; +} + +export interface GlobPartial { + /** + * Determines whether or not symlinks are followed when generating the + * precache manifest. For more information, see the definition of `follow` in + * the `glob` [documentation](https://github.com/isaacs/node-glob#options). + * @default true + */ + globFollow?: boolean; + /** + * A set of patterns matching files to always exclude when generating the + * precache manifest. For more information, see the definition of `ignore` in + * the `glob` [documentation](https://github.com/isaacs/node-glob#options). + * @default ["**\/node_modules\/**\/*"] + */ + globIgnores?: Array; + /** + * Files matching any of these patterns will be included in the precache + * manifest. For more information, see the + * [`glob` primer](https://github.com/isaacs/node-glob#glob-primer). + * @default ["**\/*.{js,css,html}"] + */ + globPatterns?: Array; + /** + * If true, an error reading a directory when generating a precache manifest + * will cause the build to fail. If false, the problematic directory will be + * skipped. For more information, see the definition of `strict` in the `glob` + * [documentation](https://github.com/isaacs/node-glob#options). + * @default true + */ + globStrict?: boolean; + /** + * If a URL is rendered based on some server-side logic, its contents may + * depend on multiple files or on some other unique string value. The keys in + * this object are server-rendered URLs. If the values are an array of + * strings, they will be interpreted as `glob` patterns, and the contents of + * any files matching the patterns will be used to uniquely version the URL. + * If used with a single string, it will be interpreted as unique versioning + * information that you've generated for a given URL. + */ + templatedURLs?: { + [key: string]: string | Array; + }; +} + +export interface InjectPartial { + /** + * The string to find inside of the `swSrc` file. Once found, it will be + * replaced by the generated precache manifest. + * @default "self.__WB_MANIFEST" + */ + injectionPoint?: string; + /** + * The path and filename of the service worker file that will be read during + * the build process, relative to the current working directory. + */ + swSrc: string; +} + +export interface WebpackPartial { + /** + * One or more chunk names whose corresponding output files should be included + * in the precache manifest. + */ + chunks?: Array; + // We can't use the @default annotation here to assign the value via AJV, as + // an Array 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. + /** + * One or more specifiers used to exclude assets from the precache manifest. + * This is interpreted following + * [the same rules](https://webpack.js.org/configuration/module/#condition) + * as `webpack`'s standard `exclude` option. + * If not provided, the default value is `[/\.map$/, /^manifest.*\.js$]`. + */ + //eslint-disable-next-line @typescript-eslint/ban-types + exclude?: Array boolean)>; + /** + * One or more chunk names whose corresponding output files should be excluded + * from the precache manifest. + */ + excludeChunks?: Array; + /** + * One or more specifiers used to include assets in the precache manifest. + * This is interpreted following + * [the same rules](https://webpack.js.org/configuration/module/#condition) + * as `webpack`'s standard `include` option. + */ + //eslint-disable-next-line @typescript-eslint/ban-types + include?: Array boolean)>; + /** + * If set to 'production', then an optimized service worker bundle that + * excludes debugging info will be produced. If not explicitly configured + * here, the `mode` value configured in the current `webpack` compilation + * will be used. + */ + mode?: string | null; +} + +export interface RequiredSWDestPartial { + /** + * The path and filename of the service worker file that will be created by + * the build process, relative to the current working directory. It must end + * in '.js'. + */ + swDest: string; +} + +export interface WebpackGenerateSWPartial { + /** + * One or more names of webpack chunks. The content of those chunks will be + * included in the generated service worker, via a call to `importScripts()`. + */ + importScriptsViaChunks?: Array; + /** + * The asset name of the service worker file created by this plugin. + * @default "service-worker.js" + */ + swDest?: string; +} + +export interface WebpackInjectManifestPartial { + /** + * When `true` (the default), the `swSrc` file will be compiled by webpack. + * When `false`, compilation will not occur (and `webpackCompilationPlugins` + * can't be used.) Set to `false` if you want to inject the manifest into, + * e.g., a JSON file. + * @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. + /** + * The asset name of the service worker file that will be created by this + * plugin. If omitted, the name will be based on the `swSrc` name. + */ + 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. + /** + * Optional `webpack` plugins that will be used when compiling the `swSrc` + * input file. Only valid if `compileSrc` is `true`. + */ + webpackCompilationPlugins?: Array; +} + +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; + size: number; + warnings: Array; +} + +export type BuildResult = Omit & { + filePaths: Array; +}; + +/** + * @private + */ +export interface FileDetails { + file: string; + hash: string; + size: number; +} + +/** + * @private + */ +export type BuildType = "dev" | "prod"; + +/** + * @private + */ +export interface WorkboxPackageJSON extends PackageJson { + workbox?: { + browserNamespace?: string; + packageType?: string; + prodOnly?: boolean; + }; +} diff --git a/packages/workbox-build/tsconfig.json b/packages/workbox-build/tsconfig.json new file mode 100644 index 00000000..c40643cf --- /dev/null +++ b/packages/workbox-build/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "esModuleInterop": true, + "module": "CommonJS", + "moduleResolution": "Node", + "outDir": "./build", + "resolveJsonModule": true, + "rootDir": "./src", + "target": "ES2018" + }, + "files": ["src/cdn-details.json"], + "include": ["src/**/*.ts", "src/schema/*.json"] +} diff --git a/packages/workbox-cacheable-response/README.md b/packages/workbox-cacheable-response/README.md new file mode 100644 index 00000000..5a4dbdca --- /dev/null +++ b/packages/workbox-cacheable-response/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-cacheable-response diff --git a/packages/workbox-cacheable-response/package.json b/packages/workbox-cacheable-response/package.json new file mode 100755 index 00000000..c4bd7487 --- /dev/null +++ b/packages/workbox-cacheable-response/package.json @@ -0,0 +1,27 @@ +{ + "name": "@ducanh2912/workbox-cacheable-response", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "This library takes a Response object and determines whether it's cacheable based on a specific configuration.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "workbox-plugin" + ], + "workbox": { + "browserNamespace": "workbox.cacheableResponse", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "7.0.0" + } +} diff --git a/packages/workbox-cacheable-response/src/CacheableResponse.ts b/packages/workbox-cacheable-response/src/CacheableResponse.ts new file mode 100644 index 00000000..e4a1915c --- /dev/null +++ b/packages/workbox-cacheable-response/src/CacheableResponse.ts @@ -0,0 +1,150 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "workbox-core/_private/logger.js"; +import "./_version.js"; + +export interface CacheableResponseOptions { + statuses?: number[]; + headers?: { [headerName: string]: string }; +} + +/** + * This class allows you to set up rules determining what + * status codes and/or headers need to be present in order for a + * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) + * to be considered cacheable. + * + * @memberof workbox-cacheable-response + */ +class CacheableResponse { + private readonly _statuses?: CacheableResponseOptions["statuses"]; + private readonly _headers?: CacheableResponseOptions["headers"]; + + /** + * To construct a new CacheableResponse instance you must provide at least + * one of the `config` properties. + * + * If both `statuses` and `headers` are specified, then both conditions must + * be met for the `Response` to be considered cacheable. + * + * @param {Object} config + * @param {Array} [config.statuses] One or more status codes that a + * `Response` can have and be considered cacheable. + * @param {Object} [config.headers] A mapping of header names + * and expected values that a `Response` can have and be considered cacheable. + * If multiple headers are provided, only one needs to be present. + */ + constructor(config: CacheableResponseOptions = {}) { + if (process.env.NODE_ENV !== "production") { + if (!(config.statuses || config.headers)) { + throw new WorkboxError("statuses-or-headers-required", { + moduleName: "workbox-cacheable-response", + className: "CacheableResponse", + funcName: "constructor", + }); + } + + if (config.statuses) { + assert!.isArray(config.statuses, { + moduleName: "workbox-cacheable-response", + className: "CacheableResponse", + funcName: "constructor", + paramName: "config.statuses", + }); + } + + if (config.headers) { + assert!.isType(config.headers, "object", { + moduleName: "workbox-cacheable-response", + className: "CacheableResponse", + funcName: "constructor", + paramName: "config.headers", + }); + } + } + + this._statuses = config.statuses; + this._headers = config.headers; + } + + /** + * Checks a response to see whether it's cacheable or not, based on this + * object's configuration. + * + * @param {Response} response The response whose cacheability is being + * checked. + * @return {boolean} `true` if the `Response` is cacheable, and `false` + * otherwise. + */ + isResponseCacheable(response: Response): boolean { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(response, Response, { + moduleName: "workbox-cacheable-response", + className: "CacheableResponse", + funcName: "isResponseCacheable", + paramName: "response", + }); + } + + let cacheable = true; + + if (this._statuses) { + cacheable = this._statuses.includes(response.status); + } + + if (this._headers && cacheable) { + cacheable = Object.keys(this._headers).some((headerName) => { + return response.headers.get(headerName) === this._headers![headerName]; + }); + } + + if (process.env.NODE_ENV !== "production") { + if (!cacheable) { + logger.groupCollapsed( + `The request for ` + + `'${getFriendlyURL(response.url)}' returned a response that does ` + + `not meet the criteria for being cached.` + ); + + logger.groupCollapsed(`View cacheability criteria here.`); + logger.log(`Cacheable statuses: ` + JSON.stringify(this._statuses)); + logger.log( + `Cacheable headers: ` + JSON.stringify(this._headers, null, 2) + ); + logger.groupEnd(); + + const logFriendlyHeaders: { [key: string]: string } = {}; + response.headers.forEach((value, key) => { + logFriendlyHeaders[key] = value; + }); + + logger.groupCollapsed(`View response status and headers here.`); + logger.log(`Response status: ${response.status}`); + logger.log( + `Response headers: ` + JSON.stringify(logFriendlyHeaders, null, 2) + ); + logger.groupEnd(); + + logger.groupCollapsed(`View full response details here.`); + logger.log(response.headers); + logger.log(response); + logger.groupEnd(); + + logger.groupEnd(); + } + } + + return cacheable; + } +} + +export { CacheableResponse }; diff --git a/packages/workbox-cacheable-response/src/CacheableResponsePlugin.ts b/packages/workbox-cacheable-response/src/CacheableResponsePlugin.ts new file mode 100644 index 00000000..1b3316d8 --- /dev/null +++ b/packages/workbox-cacheable-response/src/CacheableResponsePlugin.ts @@ -0,0 +1,58 @@ +/* + 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 { WorkboxPlugin } from "workbox-core/types.js"; +import { + CacheableResponse, + CacheableResponseOptions, +} from "./CacheableResponse.js"; +import "./_version.js"; + +/** + * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it + * easier to add in cacheability checks to requests made via Workbox's built-in + * strategies. + * + * @memberof workbox-cacheable-response + */ +class CacheableResponsePlugin implements WorkboxPlugin { + private readonly _cacheableResponse: CacheableResponse; + + /** + * To construct a new CacheableResponsePlugin instance you must provide at + * least one of the `config` properties. + * + * If both `statuses` and `headers` are specified, then both conditions must + * be met for the `Response` to be considered cacheable. + * + * @param {Object} config + * @param {Array} [config.statuses] One or more status codes that a + * `Response` can have and be considered cacheable. + * @param {Object} [config.headers] A mapping of header names + * and expected values that a `Response` can have and be considered cacheable. + * If multiple headers are provided, only one needs to be present. + */ + constructor(config: CacheableResponseOptions) { + this._cacheableResponse = new CacheableResponse(config); + } + + /** + * @param {Object} options + * @param {Response} options.response + * @return {Response|null} + * @private + */ + cacheWillUpdate: WorkboxPlugin["cacheWillUpdate"] = async ({ response }) => { + if (this._cacheableResponse.isResponseCacheable(response)) { + return response; + } + return null; + }; +} + +export { CacheableResponsePlugin }; diff --git a/packages/workbox-cacheable-response/src/_version.ts b/packages/workbox-cacheable-response/src/_version.ts new file mode 100644 index 00000000..6997215d --- /dev/null +++ b/packages/workbox-cacheable-response/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:cacheable-response:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-cacheable-response/src/index.ts b/packages/workbox-cacheable-response/src/index.ts new file mode 100644 index 00000000..74ccc4a0 --- /dev/null +++ b/packages/workbox-cacheable-response/src/index.ts @@ -0,0 +1,21 @@ +/* + 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 { + CacheableResponse, + CacheableResponseOptions, +} from "./CacheableResponse.js"; +import { CacheableResponsePlugin } from "./CacheableResponsePlugin.js"; + +import "./_version.js"; + +/** + * @module workbox-cacheable-response + */ + +export { CacheableResponse, CacheableResponseOptions, CacheableResponsePlugin }; diff --git a/packages/workbox-cacheable-response/tsconfig.json b/packages/workbox-cacheable-response/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-cacheable-response/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-cli/README.md b/packages/workbox-cli/README.md new file mode 100644 index 00000000..e9e7f7f1 --- /dev/null +++ b/packages/workbox-cli/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-cli diff --git a/packages/workbox-cli/package.json b/packages/workbox-cli/package.json new file mode 100644 index 00000000..f191192d --- /dev/null +++ b/packages/workbox-cli/package.json @@ -0,0 +1,53 @@ +{ + "name": "@ducanh2912/workbox-cli", + "version": "7.0.0", + "description": "workbox-cli is the command line interface for Workbox.", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "caching", + "fetch requests", + "offline", + "cli" + ], + "bin": { + "workbox": "build/bin.js" + }, + "files": [ + "build" + ], + "engines": { + "node": ">=16.0.0" + }, + "author": "Google's Web DevRel Team", + "license": "MIT", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://github.com/GoogleChrome/workbox/tree/master/packages/workbox-cli", + "dependencies": { + "@ducanh2912/workbox-build": "workspace:*", + "chalk": "5.3.0", + "chokidar": "3.5.3", + "common-tags": "1.8.2", + "fs-extra": "11.1.1", + "glob": "10.3.10", + "inquirer": "9.2.11", + "meow": "12.1.1", + "ora": "7.0.1", + "pretty-bytes": "6.1.1", + "stringify-object": "5.0.0", + "upath": "2.0.1", + "update-notifier": "6.0.2" + }, + "workbox": { + "packageType": "node_ts" + }, + "devDependencies": { + "@types/common-tags": "1.8.3", + "@types/fs-extra": "11.0.2", + "@types/inquirer": "9.0.5", + "@types/stringify-object": "4.0.3", + "@types/update-notifier": "6.0.5" + } +} diff --git a/packages/workbox-cli/src/app.ts b/packages/workbox-cli/src/app.ts new file mode 100644 index 00000000..ec0dacd8 --- /dev/null +++ b/packages/workbox-cli/src/app.ts @@ -0,0 +1,156 @@ +/* + 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 assert from "assert"; +import type { WatchOptions } from "chokidar"; +import { default as chokidar } from "chokidar"; +import { oneLine as ol } from "common-tags"; +import type meow from "meow"; +import prettyBytes from "pretty-bytes"; +import upath from "upath"; +import * as workboxBuild from "workbox-build"; + +import type { SupportedFlags } from "./bin.js"; +import { constants } from "./lib/constants.js"; +import { errors } from "./lib/errors.js"; +import { logger } from "./lib/logger.js"; +import { readConfig } from "./lib/read-config.js"; +import { runWizard } from "./lib/run-wizard.js"; + +interface BuildCommand { + command: "generateSW" | "injectManifest"; + config: workboxBuild.GenerateSWOptions | workboxBuild.InjectManifestOptions; + watch: boolean; +} + +/** + * Runs the specified build command with the provided configuration. + * + * @param {Object} options + */ +async function runBuildCommand({ command, config, watch }: BuildCommand) { + const { count, filePaths, size, warnings } = await workboxBuild[command]( + config as any + ); + + 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}`); + } + + logger.log( + `The service worker will precache ${count} URLs, ` + + `totaling ${prettyBytes(size)}.` + ); + + if (watch) { + logger.log(`\nWatching for changes...`); + } +} + +export const app = async ( + params: meow.Result +): Promise => { + // This should not be a user-visible error, unless meow() messes something up. + assert(params && Array.isArray(params.input), errors["missing-input"]); + + // Default to showing the help message if there's no command provided. + const [command = "help", option] = params.input; + + switch (command) { + case "wizard": { + await runWizard(params.flags); + break; + } + + case "copyLibraries": { + assert(option, errors["missing-dest-dir-param"]); + const parentDirectory = upath.resolve(process.cwd(), option); + + const dirName = await workboxBuild.copyWorkboxLibraries(parentDirectory); + const fullPath = upath.join(parentDirectory, dirName); + + logger.log(`The Workbox libraries were copied to ${fullPath}`); + logger.log(ol`Add a call to workbox.setConfig({modulePathPrefix: '...'}) + to your service worker to use these local libraries.`); + logger.log(`See https://goo.gl/Fo9gPX for further documentation.`); + break; + } + + case "generateSW": + case "injectManifest": { + const configPath = upath.resolve( + process.cwd(), + option || constants.defaultConfigFile + ); + + let configFromDisk: + | workboxBuild.GenerateSWOptions + | workboxBuild.InjectManifestOptions; + try { + configFromDisk = readConfig(configPath); + } catch (error) { + if (error instanceof Error) { + logger.error(errors["invalid-common-js-module"]); + throw error; + } + } + + logger.log(`Using configuration from ${configPath}.`); + + const config = configFromDisk!; + // Determine whether we're in --watch mode, or one-off mode. + if (params?.flags?.watch) { + const options: WatchOptions = { + ignoreInitial: true, + }; + if (config.globIgnores) { + options.ignored = config.globIgnores; + } + if (config.globDirectory) { + options.cwd = config.globDirectory; + } + + if (config.globPatterns) { + chokidar + .watch(config.globPatterns, options) + .on("all", async () => { + await runBuildCommand({ command, config, watch: true }); + }) + .on("ready", async () => { + await runBuildCommand({ command, config, watch: true }); + }) + .on("error", (err) => { + logger.error(err.toString()); + }); + } + } else { + await runBuildCommand({ command, config, watch: false }); + } + break; + } + + case "help": { + params.showHelp(); + break; + } + + default: { + throw new Error(errors["unknown-command"] + ` ` + command); + } + } +}; diff --git a/packages/workbox-cli/src/bin.ts b/packages/workbox-cli/src/bin.ts new file mode 100755 index 00000000..97b0b8cf --- /dev/null +++ b/packages/workbox-cli/src/bin.ts @@ -0,0 +1,46 @@ +#! /usr/bin/env node + +/* + 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 meow from "meow"; +import updateNotifier from "update-notifier"; + +import { app } from "./app"; +import { cleanupStackTrace } from "./lib/cleanup-stack-trace.js"; +import { helpText } from "./lib/help-text"; +import { logger } from "./lib/logger"; + +export interface SupportedFlags extends meow.AnyFlags { + debug: meow.BooleanFlag; + injectManifest: meow.BooleanFlag; + watch: meow.BooleanFlag; +} + +void (async () => { + const params: meow.Result = meow(helpText); + updateNotifier({ pkg: params.pkg as updateNotifier.Package }).notify(); + + try { + await app(params); + } catch (error) { + if (error instanceof Error) { + // Show the full error and stack trace if we're run with --debug. + if (params.flags.debug) { + if (error.stack) { + logger.error(`\n${error.stack}`); + } + } else { + logger.error(`\n${error.message}`); + logger.debug(`${cleanupStackTrace(error, "app.js")}\n`); + } + } + + process.exit(1); + } +})(); diff --git a/packages/workbox-cli/src/lib/cleanup-stack-trace.ts b/packages/workbox-cli/src/lib/cleanup-stack-trace.ts new file mode 100644 index 00000000..90f2dc4c --- /dev/null +++ b/packages/workbox-cli/src/lib/cleanup-stack-trace.ts @@ -0,0 +1,30 @@ +/* + 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. +*/ + +// Helper to parse out less relevant info from an Error's stack trace. +// Removes the initial portion, since that's obtained from error.message. +// Removes every stack frame earlier than the last instance of moduleName, +// since that's just frames related to the Node runtime/loader. +export function cleanupStackTrace(error: Error, moduleName: string): string { + if (!error.stack) { + return ""; + } + const frames = error.stack.split(`\n`); + let startFrame: number | undefined; + let lastFrame = 0; + frames.forEach((frame, index) => { + if (startFrame === undefined && frame.includes(` at `)) { + startFrame = index; + } + + if (frame.includes(`${moduleName}:`)) { + lastFrame = index; + } + }); + return frames.slice(startFrame, lastFrame + 1).join(`\n`); +} diff --git a/packages/workbox-cli/src/lib/constants.ts b/packages/workbox-cli/src/lib/constants.ts new file mode 100644 index 00000000..5b06f03d --- /dev/null +++ b/packages/workbox-cli/src/lib/constants.ts @@ -0,0 +1,14 @@ +/* + 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. +*/ + +export const constants = { + defaultConfigFile: "workbox-config.js", + ignoredDirectories: ["node_modules"], + ignoredFileExtensions: ["map"], + ignoreURLParametersMatching: [/^utm_/, /^fbclid$/], +}; diff --git a/packages/workbox-cli/src/lib/errors.ts b/packages/workbox-cli/src/lib/errors.ts new file mode 100644 index 00000000..d30fba88 --- /dev/null +++ b/packages/workbox-cli/src/lib/errors.ts @@ -0,0 +1,35 @@ +/* + 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"; + +export const errors = { + "missing-input": `params.input value was not set properly.`, + "missing-dest-dir-param": ol`Please provide the path to a directory in which + the libraries will be copied.`, + "invalid-common-js-module": ol`Please pass in a valid CommonJS module that + exports your configuration.`, + "config-validation-failed": `Your configuration is invalid:`, + "workbox-build-runtime-error": `Service worker generation failed:`, + "unknown-command": `Unknown command:`, + "no-file-extensions-found": ol`No files could be found that are suitable for + caching.`, + "no-file-extensions-selected": `Please select at least one file extension.`, + "invalid-sw-dest": ol`Please enter a valid path to use for the service worker + file that's created.`, + "glob-directory-invalid": ol`The path you entered isn't a valid directory.`, + "invalid-config-location": ol`Please enter a valid path to use for the saved + configuration file.`, + "sw-src-missing-injection-point": ol`That is not a valid source service worker + file. Please try again with a file containing + 'self.__WB_MANIFEST'.`, + "no-search-parameters-supplied": ol`Please provide the url search param(s) + you would like to ignore.`, + "invalid-search-parameters-supplied": ol`Please provide the valid URL search parameter(s) + without the leading '/' or '?' (i.e. source,version,language).`, +}; diff --git a/packages/workbox-cli/src/lib/help-text.ts b/packages/workbox-cli/src/lib/help-text.ts new file mode 100644 index 00000000..9d27bc09 --- /dev/null +++ b/packages/workbox-cli/src/lib/help-text.ts @@ -0,0 +1,57 @@ +/* + 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. +*/ + +export const helpText = `Usage: +$ workbox [options] + +Commands: + wizard [--injectManifest] + Runs the configuration wizard, which will generate a + config file based on answers to questions. + By default the configuration will be tailored to the + generateSW use case. + If --injectManifest is provided, the wizard will ask + questions needed for the injectManifest use case. + + generateSW [] [--watch] + Creates a new service worker file based on the options + in the config file (defaults to workbox-config.js). + If --watch is provided, the CLI will stay running, and will + rebuild the service worker each time a file in the precache + manifest changes. + See https://bit.ly/wb-generateSW + + injectManifest [] [--watch] + Takes an existing service worker file and creates a + copy of it with a precache manifest "injected" into + it. The precache manifest is generated based on the + options in the config file (defaults to workbox-config.js). + If --watch is provided, the CLI will stay running, and will + rebuild the service worker each time a file in the precache + manifest changes. + See https://bit.ly/wb-injectManifest + + copyLibraries + Makes a local copy of all of the Workbox libraries inside + a version directory at the location specified. This is intended + for developers using injectManifest who prefer using local, + rather than CDN hosted, libraries. + +Config file: + In 'generateSW' or 'injectManifest' mode, the config file should be a + JavaScript file, in CommonJS module format. + By default, a config file named workbox-config.js in the current + directory is assumed, but this can be overridden. + +Examples: + $ workbox wizard + $ workbox wizard --injectManifest + $ workbox generateSW --watch + $ workbox injectManifest configs/workbox-dev-config.js + $ workbox copyLibraries build/ +`; diff --git a/packages/workbox-cli/src/lib/logger.ts b/packages/workbox-cli/src/lib/logger.ts new file mode 100644 index 00000000..fc693f2f --- /dev/null +++ b/packages/workbox-cli/src/lib/logger.ts @@ -0,0 +1,16 @@ +/* + 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 chalk from "chalk"; + +export const logger = { + debug: (...args: string[]): void => console.log(chalk.gray(...args)), + log: (...args: string[]): void => console.log(...args), + warn: (...args: string[]): void => console.warn(chalk.yellow(...args)), + error: (...args: string[]): void => console.error(chalk.red.bold(...args)), +}; diff --git a/packages/workbox-cli/src/lib/questions/ask-config-location.ts b/packages/workbox-cli/src/lib/questions/ask-config-location.ts new file mode 100644 index 00000000..4b2459fb --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-config-location.ts @@ -0,0 +1,42 @@ +/* + 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 assert from "assert"; +import { oneLine as ol } from "common-tags"; +import type { Answers, Question } from "inquirer"; +import inquirer from "inquirer"; + +import { constants } from "../constants"; +import { errors } from "../errors"; + +// The key used for the question/answer. +const name = "configLocation"; + +const configLocationQuestion: Question = { + name, + message: ol`Where would you like to save these configuration options?`, + type: "input", + default: constants.defaultConfigFile, +}; +/** + * @return {Promise} The answers from inquirer. + */ +function askQuestion(): Promise { + return inquirer.prompt([configLocationQuestion]); +} + +export async function askConfigLocation(): Promise { + const answers = await askQuestion(); + // The value of the answer when the question type is 'input' is String + // and it has a default value, the casting is safe. + const configLocation: string = (answers[name] as string).trim(); + + assert(configLocation, errors["invalid-config-location"]); + + return configLocation; +} diff --git a/packages/workbox-cli/src/lib/questions/ask-extensions-to-cache.ts b/packages/workbox-cli/src/lib/questions/ask-extensions-to-cache.ts new file mode 100644 index 00000000..6ba2b68e --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-extensions-to-cache.ts @@ -0,0 +1,109 @@ +/* + 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 assert from "assert"; +import glob from "glob"; +import type { Answers } from "inquirer"; +import inquirer from "inquirer"; +import ora from "ora"; +import upath from "upath"; + +import { constants } from "../constants"; +import { errors } from "../errors"; + +// The key used for the question/answer. +const name = "globPatterns"; + +/** + * @param {string} globDirectory The directory used for the root of globbing. + * @return {Promise>} The unique file extensions corresponding + * to all of the files under globDirectory. + */ +async function getAllFileExtensions(globDirectory: string) { + const files: string[] = await new Promise((resolve, reject) => { + // Use a pattern to match any file that contains a '.', since that signifies + // the presence of a file extension. + glob( + "**/*.*", + { + cwd: globDirectory, + nodir: true, + ignore: [ + ...constants.ignoredDirectories.map( + (directory) => `**/${directory}/**` + ), + ...constants.ignoredFileExtensions.map( + (extension) => `**/*.${extension}` + ), + ], + }, + (error, files) => { + if (error) { + reject(error); + } else { + resolve(files); + } + } + ); + }); + + const extensions: Set = new Set(); + for (const file of files) { + const extension = upath.extname(file); + if (extension) { + // Get rid of the leading . character. + extensions.add(extension.replace(/^\./, "")); + } + } + + return [...extensions]; +} + +/** + * @param {string} globDirectory The directory used for the root of globbing. + * @return {Promise} The answers from inquirer. + */ +async function askQuestion(globDirectory: string): Promise { + // We need to get a list of extensions corresponding to files in the directory + // to use when asking the next question. That could potentially take some + // time, so we show a spinner and explanatory text. + const spinner = ora({ + text: `Examining files in ${globDirectory}...`, + stream: process.stdout, + }).start(); + const fileExtensions = await getAllFileExtensions(globDirectory); + spinner.stop(); + + assert(fileExtensions.length > 0, errors["no-file-extensions-found"]); + + return inquirer.prompt([ + { + name, + message: "Which file types would you like to precache?", + type: "checkbox", + choices: fileExtensions, + default: fileExtensions, + }, + ]); +} + +export async function askExtensionsToCache( + globDirectory: string +): Promise { + const answers = await askQuestion(globDirectory); + // The return value is an array of strings with the selected values + // and there is a default, the casting is safe. + const extensions: string[] = answers[name] as string[]; + assert(extensions.length > 0, errors["no-file-extensions-selected"]); + + // glob isn't happy with a single option inside of a {} group, so use a + // pattern without a {} group when there's only one extension. + const extensionsPattern: string = + extensions.length === 1 ? extensions[0] : `{${extensions.join(",")}}`; + return [`**/*.${extensionsPattern}`]; +} diff --git a/packages/workbox-cli/src/lib/questions/ask-questions.ts b/packages/workbox-cli/src/lib/questions/ask-questions.ts new file mode 100644 index 00000000..513f755a --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-questions.ts @@ -0,0 +1,56 @@ +/* + 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 { askConfigLocation } from "./ask-config-location"; +import { askExtensionsToCache } from "./ask-extensions-to-cache"; +import { askRootOfWebApp } from "./ask-root-of-web-app"; +import { askQueryParametersInStartUrl } from "./ask-start_url-query-params"; +import { askSWDest } from "./ask-sw-dest"; +import { askSWSrc } from "./ask-sw-src"; + +interface ConfigWithConfigLocation { + config: { + [key: string]: any; + }; + configLocation: string; +} + +export async function askQuestions( + options = {} +): Promise { + const isInjectManifest = "injectManifest" in options; + + const globDirectory = await askRootOfWebApp(); + const globPatterns = await askExtensionsToCache(globDirectory); + const swSrc = isInjectManifest ? await askSWSrc() : undefined; + const swDest = await askSWDest(globDirectory); + const configLocation = await askConfigLocation(); + // See https://github.com/GoogleChrome/workbox/issues/2985 + const ignoreURLParametersMatching = isInjectManifest + ? undefined + : await askQueryParametersInStartUrl(); + + const config: { [key: string]: any } = { + globDirectory, + globPatterns, + swDest, + }; + + if (swSrc) { + config.swSrc = swSrc; + } + + if (ignoreURLParametersMatching) { + config.ignoreURLParametersMatching = ignoreURLParametersMatching; + } + + return { + config, + configLocation, + }; +} diff --git a/packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts b/packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts new file mode 100644 index 00000000..7b8f69ca --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts @@ -0,0 +1,100 @@ +/* + 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 assert from "assert"; +import { oneLine as ol } from "common-tags"; +import fse from "fs-extra"; +import glob from "glob"; +import inquirer from "inquirer"; + +import { constants } from "../constants"; +import { errors } from "../errors"; + +const ROOT_PROMPT = "Please enter the path to the root of your web app:"; + +// The keys used for the questions/answers. +const questionRootDirectory = "globDirectory"; +const questionManualInput = "manualDirectoryInput"; + +/** + * @return {Promise>} The subdirectories of the current + * working directory, with hidden and ignored ones filtered out. + */ +async function getSubdirectories(): Promise> { + return await new Promise((resolve, reject) => { + glob( + "*/", + { + ignore: constants.ignoredDirectories.map( + (directory) => `${directory}/` + ), + }, + (error, directories) => { + if (error) { + reject(error); + } else { + resolve(directories); + } + } + ); + }); +} + +/** + * @return {Promise} The answers from inquirer. + */ +async function askQuestion(): Promise<{ + globDirectory: string; + manualDirectoryInput?: string; +}> { + const subdirectories: (string | InstanceType)[] = + await getSubdirectories(); + + if (subdirectories.length > 0) { + const manualEntryChoice = "Manually enter path"; + return inquirer.prompt([ + { + name: questionRootDirectory, + type: "list", + message: ol`What is the root of your web app (i.e. which directory do + you deploy)?`, + choices: subdirectories.concat([ + new inquirer.Separator(), + manualEntryChoice, + ]), + }, + { + name: questionManualInput, + when: (answers: { globDirectory: string }) => + answers.globDirectory === manualEntryChoice, + message: ROOT_PROMPT, + }, + ]); + } + + return inquirer.prompt([ + { + name: questionRootDirectory, + message: ROOT_PROMPT, + default: ".", + }, + ]); +} + +export async function askRootOfWebApp(): Promise { + const { manualDirectoryInput, globDirectory } = await askQuestion(); + + try { + const stat = await fse.stat(manualDirectoryInput || globDirectory); + assert(stat.isDirectory()); + } catch (error) { + throw new Error(errors["glob-directory-invalid"]); + } + + return manualDirectoryInput || globDirectory; +} diff --git a/packages/workbox-cli/src/lib/questions/ask-start_url-query-params.ts b/packages/workbox-cli/src/lib/questions/ask-start_url-query-params.ts new file mode 100644 index 00000000..653263be --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-start_url-query-params.ts @@ -0,0 +1,84 @@ +/* + 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 { oneLine as ol } from "common-tags"; +import inquirer from "inquirer"; + +import { constants } from "../constants"; +import { errors } from "../errors"; + +const START_URL_QUERY_PARAMS_PROMPT = + "Please enter the search parameter(s) that you would like to ignore (separated by comma):"; + +// The keys used for the questions/answers. +const question_ignoreURLParametersMatching = "ignoreURLParametersMatching"; +const question_shouldAskForIgnoreURLParametersMatching = + "shouldAskForIgnoreURLParametersMatching"; + +/** + * @return {Promise} The answers from inquirer. + */ +async function askQuestion(): Promise<{ + shouldAskForIgnoreURLParametersMatching: boolean; + ignoreURLParametersMatching?: string; +}> { + return inquirer.prompt([ + { + name: question_shouldAskForIgnoreURLParametersMatching, + message: ol`Does your web app manifest include search parameter(s) + in the 'start_url', other than 'utm_' or 'fbclid' + (like '?source=pwa')?`, + type: "confirm", + default: false, + }, + { + name: question_ignoreURLParametersMatching, + when: (answer: { shouldAskForIgnoreURLParametersMatching: boolean }) => + answer.shouldAskForIgnoreURLParametersMatching, + message: START_URL_QUERY_PARAMS_PROMPT, + type: "input", + }, + ]); +} + +export async function askQueryParametersInStartUrl( + defaultIgnoredSearchParameters: RegExp[] = constants.ignoreURLParametersMatching +): Promise { + const { + shouldAskForIgnoreURLParametersMatching, + ignoreURLParametersMatching = "", + } = await askQuestion(); + + if (!shouldAskForIgnoreURLParametersMatching) { + return defaultIgnoredSearchParameters; + } + + assert( + ignoreURLParametersMatching.length > 0, + errors["no-search-parameters-supplied"] + ); + + const ignoreSearchParameters = ignoreURLParametersMatching + .trim() + .split(",") + .filter(Boolean); + + assert( + ignoreSearchParameters.length > 0, + errors["no-search-parameters-supplied"] + ); + assert( + ignoreSearchParameters.every((param) => !param.match(/^[^\w|-]/g)), + errors["invalid-search-parameters-supplied"] + ); + + return defaultIgnoredSearchParameters.concat( + ignoreSearchParameters.map((searchParam) => new RegExp(`^${searchParam}`)) + ); +} diff --git a/packages/workbox-cli/src/lib/questions/ask-sw-dest.ts b/packages/workbox-cli/src/lib/questions/ask-sw-dest.ts new file mode 100644 index 00000000..3593e723 --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-sw-dest.ts @@ -0,0 +1,43 @@ +/* + 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 assert from "assert"; +import type { Answers } from "inquirer"; +import inquirer from "inquirer"; +import upath from "upath"; + +import { errors } from "../errors"; + +// The key used for the question/answer. +const name = "swDest"; + +/** + * @param {string} defaultDir + * @return {Promise} The answers from inquirer. + */ +function askQuestion(defaultDir: string): Promise { + return inquirer.prompt([ + { + name, + message: `Where would you like your service worker file to be saved?`, + type: "input", + default: upath.join(defaultDir, "sw.js"), + }, + ]); +} + +export async function askSWDest(defaultDir = "."): Promise { + const answers = await askQuestion(defaultDir); + // When prompt type is input the return type is string + // casting is safe + const swDest: string = (answers[name] as string).trim(); + + assert(swDest, errors["invalid-sw-dest"]); + + return swDest; +} diff --git a/packages/workbox-cli/src/lib/questions/ask-sw-src.ts b/packages/workbox-cli/src/lib/questions/ask-sw-src.ts new file mode 100644 index 00000000..5485fe37 --- /dev/null +++ b/packages/workbox-cli/src/lib/questions/ask-sw-src.ts @@ -0,0 +1,35 @@ +/* + 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 type { Answers } from "inquirer"; +import inquirer from "inquirer"; + +// The key used for the question/answer. +const name = "swSrc"; + +/** + * @return {Promise} The answers from inquirer. + */ +function askQuestion(): Promise { + return inquirer.prompt([ + { + name, + message: ol`Where's your existing service worker file? To be used with + injectManifest, it should include a call to + 'self.__WB_MANIFEST'`, + type: "input", + }, + ]); +} + +export async function askSWSrc(): Promise { + const answers = await askQuestion(); + // When prompt type is input the return is string or null + return answers[name] ? (answers[name] as string).trim() : null; +} diff --git a/packages/workbox-cli/src/lib/read-config.ts b/packages/workbox-cli/src/lib/read-config.ts new file mode 100644 index 00000000..10193713 --- /dev/null +++ b/packages/workbox-cli/src/lib/read-config.ts @@ -0,0 +1,17 @@ +/* + 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 type { GenerateSWOptions, InjectManifestOptions } from "workbox-build"; + +// A really light wrapper on top of Node's require() to make it easier to stub +// out reading the configuration during tests. +export function readConfig( + configFile: string +): GenerateSWOptions | InjectManifestOptions { + return require(configFile) as GenerateSWOptions | InjectManifestOptions; +} diff --git a/packages/workbox-cli/src/lib/run-wizard.ts b/packages/workbox-cli/src/lib/run-wizard.ts new file mode 100644 index 00000000..d3b20b71 --- /dev/null +++ b/packages/workbox-cli/src/lib/run-wizard.ts @@ -0,0 +1,37 @@ +/* + 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 fse from "fs-extra"; +import stringifyObject from "stringify-object"; + +import { logger } from "./logger"; +import { askQuestions } from "./questions/ask-questions"; + +export async function runWizard(options = {}): Promise { + const { configLocation, config } = await askQuestions(options); + + // See https://github.com/GoogleChrome/workbox/issues/2796 + const contents = `module.exports = ${stringifyObject(config)};`; + await fse.writeFile(configLocation, contents); + + const command = "injectManifest" in options ? "injectManifest" : "generateSW"; + logger.log(`To build your service worker, run + + workbox ${command} ${configLocation} + +as part of a build process. See https://goo.gl/fdTQBf for details.`); + + const configDocsURL = + "injectManifest" in options + ? "https://goo.gl/8bs14N" + : "https://goo.gl/gVo87N"; + + logger.log(ol`You can further customize your service worker by making changes + to ${configLocation}. See ${configDocsURL} for details.`); +} diff --git a/packages/workbox-cli/tsconfig.json b/packages/workbox-cli/tsconfig.json new file mode 100644 index 00000000..51242135 --- /dev/null +++ b/packages/workbox-cli/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "esModuleInterop": true, + "module": "CommonJS", + "outDir": "build", + "rootDir": "src", + "target": "ES2018", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-build/"}] +} diff --git a/packages/workbox-core/README.md b/packages/workbox-core/README.md new file mode 100644 index 00000000..0cd4cfea --- /dev/null +++ b/packages/workbox-core/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-core diff --git a/packages/workbox-core/package.json b/packages/workbox-core/package.json new file mode 100644 index 00000000..f218ff9c --- /dev/null +++ b/packages/workbox-core/package.json @@ -0,0 +1,23 @@ +{ + "name": "@ducanh2912/workbox-core", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "This module is used by a number of the other Workbox modules to share common code.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw" + ], + "workbox": { + "browserNamespace": "workbox.core", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts" +} diff --git a/packages/workbox-core/src/_private.ts b/packages/workbox-core/src/_private.ts new file mode 100644 index 00000000..2c0d879e --- /dev/null +++ b/packages/workbox-core/src/_private.ts @@ -0,0 +1,42 @@ +/* + 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. +*/ + +// We either expose defaults or we expose every named export. +import { assert } from "./_private/assert.js"; +import { cacheNames } from "./_private/cacheNames.js"; +import { cacheMatchIgnoreParams } from "./_private/cacheMatchIgnoreParams.js"; +import { canConstructReadableStream } from "./_private/canConstructReadableStream.js"; +import { canConstructResponseFromBodyStream } from "./_private/canConstructResponseFromBodyStream.js"; +import { dontWaitFor } from "./_private/dontWaitFor.js"; +import { Deferred } from "./_private/Deferred.js"; +import { executeQuotaErrorCallbacks } from "./_private/executeQuotaErrorCallbacks.js"; +import { getFriendlyURL } from "./_private/getFriendlyURL.js"; +import { logger } from "./_private/logger.js"; +import { resultingClientExists } from "./_private/resultingClientExists.js"; +import { timeout } from "./_private/timeout.js"; +import { waitUntil } from "./_private/waitUntil.js"; +import { WorkboxError } from "./_private/WorkboxError.js"; + +import "./_version.js"; + +export { + assert, + cacheMatchIgnoreParams, + cacheNames, + canConstructReadableStream, + canConstructResponseFromBodyStream, + dontWaitFor, + Deferred, + executeQuotaErrorCallbacks, + getFriendlyURL, + logger, + resultingClientExists, + timeout, + waitUntil, + WorkboxError, +}; diff --git a/packages/workbox-core/src/_private/Deferred.ts b/packages/workbox-core/src/_private/Deferred.ts new file mode 100644 index 00000000..6c1da7c5 --- /dev/null +++ b/packages/workbox-core/src/_private/Deferred.ts @@ -0,0 +1,35 @@ +/* + 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 "../_version.js"; + +/** + * The Deferred class composes Promises in a way that allows for them to be + * resolved or rejected from outside the constructor. In most cases promises + * should be used directly, but Deferreds can be necessary when the logic to + * resolve a promise must be separate. + * + * @private + */ +class Deferred { + promise: Promise; + resolve!: (value: T) => void; + reject!: (reason?: any) => void; + + /** + * Creates a promise and exposes its resolve and reject functions as methods. + */ + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } +} + +export { Deferred }; diff --git a/packages/workbox-core/src/_private/WorkboxError.ts b/packages/workbox-core/src/_private/WorkboxError.ts new file mode 100644 index 00000000..19dd5bc0 --- /dev/null +++ b/packages/workbox-core/src/_private/WorkboxError.ts @@ -0,0 +1,43 @@ +/* + 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 { messageGenerator } from "../models/messages/messageGenerator.js"; +import { MapLikeObject } from "../types.js"; +import "../_version.js"; + +/** + * Workbox errors should be thrown with this class. + * This allows use to ensure the type easily in tests, + * helps developers identify errors from workbox + * easily and allows use to optimise error + * messages correctly. + * + * @private + */ +class WorkboxError extends Error { + details?: MapLikeObject; + + /** + * + * @param {string} errorCode The error code that + * identifies this particular error. + * @param {Object=} details Any relevant arguments + * that will help developers identify issues should + * be added as a key on the context object. + */ + constructor(errorCode: string, details?: MapLikeObject) { + const message = messageGenerator(errorCode, details); + + super(message); + + this.name = errorCode; + this.details = details; + } +} + +export { WorkboxError }; diff --git a/packages/workbox-core/src/_private/assert.ts b/packages/workbox-core/src/_private/assert.ts new file mode 100644 index 00000000..74bf5db0 --- /dev/null +++ b/packages/workbox-core/src/_private/assert.ts @@ -0,0 +1,100 @@ +/* + 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 { WorkboxError } from "../_private/WorkboxError.js"; +import { MapLikeObject } from "../types.js"; +import "../_version.js"; + +/* + * This method throws if the supplied value is not an array. + * The destructed values are required to produce a meaningful error for users. + * The destructed and restructured object is so it's clear what is + * needed. + */ +const isArray = (value: any[], details: MapLikeObject) => { + if (!Array.isArray(value)) { + throw new WorkboxError("not-an-array", details); + } +}; + +const hasMethod = ( + object: MapLikeObject, + expectedMethod: string, + details: MapLikeObject +) => { + const type = typeof object[expectedMethod]; + if (type !== "function") { + details["expectedMethod"] = expectedMethod; + throw new WorkboxError("missing-a-method", details); + } +}; + +const isType = ( + object: unknown, + expectedType: string, + details: MapLikeObject +) => { + if (typeof object !== expectedType) { + details["expectedType"] = expectedType; + throw new WorkboxError("incorrect-type", details); + } +}; + +const isInstance = ( + object: unknown, + // Need the general type to do the check later. + // eslint-disable-next-line @typescript-eslint/ban-types + expectedClass: Function, + details: MapLikeObject +) => { + if (!(object instanceof expectedClass)) { + details["expectedClassName"] = expectedClass.name; + throw new WorkboxError("incorrect-class", details); + } +}; + +const isOneOf = (value: any, validValues: any[], details: MapLikeObject) => { + if (!validValues.includes(value)) { + details["validValueDescription"] = `Valid values are ${JSON.stringify( + validValues + )}.`; + throw new WorkboxError("invalid-value", details); + } +}; + +const isArrayOfClass = ( + value: any, + // Need general type to do check later. + expectedClass: Function, // eslint-disable-line + details: MapLikeObject +) => { + const error = new WorkboxError("not-array-of-class", details); + if (!Array.isArray(value)) { + throw error; + } + + for (const item of value) { + if (!(item instanceof expectedClass)) { + throw error; + } + } +}; + +const finalAssertExports = + process.env.NODE_ENV === "production" + ? null + : { + hasMethod, + isArray, + isInstance, + isOneOf, + isType, + isArrayOfClass, + }; + +export { finalAssertExports as assert }; diff --git a/packages/workbox-core/src/_private/cacheMatchIgnoreParams.ts b/packages/workbox-core/src/_private/cacheMatchIgnoreParams.ts new file mode 100644 index 00000000..66b4f415 --- /dev/null +++ b/packages/workbox-core/src/_private/cacheMatchIgnoreParams.ts @@ -0,0 +1,56 @@ +/* + Copyright 2020 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 "../_version.js"; + +function stripParams(fullURL: string, ignoreParams: string[]) { + const strippedURL = new URL(fullURL); + for (const param of ignoreParams) { + strippedURL.searchParams.delete(param); + } + return strippedURL.href; +} + +/** + * Matches an item in the cache, ignoring specific URL params. This is similar + * to the `ignoreSearch` option, but it allows you to ignore just specific + * params (while continuing to match on the others). + * + * @private + * @param {Cache} cache + * @param {Request} request + * @param {Object} matchOptions + * @param {Array} ignoreParams + * @return {Promise} + */ +async function cacheMatchIgnoreParams( + cache: Cache, + request: Request, + ignoreParams: string[], + matchOptions?: CacheQueryOptions +): Promise { + const strippedRequestURL = stripParams(request.url, ignoreParams); + + // If the request doesn't include any ignored params, match as normal. + if (request.url === strippedRequestURL) { + return cache.match(request, matchOptions); + } + + // Otherwise, match by comparing keys + const keysOptions = { ...matchOptions, ignoreSearch: true }; + const cacheKeys = await cache.keys(request, keysOptions); + + for (const cacheKey of cacheKeys) { + const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams); + if (strippedRequestURL === strippedCacheKeyURL) { + return cache.match(cacheKey, matchOptions); + } + } + return; +} + +export { cacheMatchIgnoreParams }; diff --git a/packages/workbox-core/src/_private/cacheNames.ts b/packages/workbox-core/src/_private/cacheNames.ts new file mode 100644 index 00000000..1756aeae --- /dev/null +++ b/packages/workbox-core/src/_private/cacheNames.ts @@ -0,0 +1,75 @@ +/* + 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 "../_version.js"; + +declare let registration: ServiceWorkerRegistration | undefined; + +export interface CacheNameDetails { + googleAnalytics: string; + precache: string; + prefix: string; + runtime: string; + suffix: string; +} + +export interface PartialCacheNameDetails { + [propName: string]: string; +} + +export type CacheNameDetailsProp = + | "googleAnalytics" + | "precache" + | "prefix" + | "runtime" + | "suffix"; + +const _cacheNameDetails: CacheNameDetails = { + googleAnalytics: "googleAnalytics", + precache: "precache-v2", + prefix: "workbox", + runtime: "runtime", + suffix: typeof registration !== "undefined" ? registration.scope : "", +}; + +const _createCacheName = (cacheName: string): string => { + return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix] + .filter((value) => value && value.length > 0) + .join("-"); +}; + +const eachCacheNameDetail = (fn: (key: CacheNameDetailsProp) => void): void => { + for (const key of Object.keys(_cacheNameDetails)) { + fn(key as CacheNameDetailsProp); + } +}; + +export const cacheNames = { + updateDetails: (details: PartialCacheNameDetails): void => { + eachCacheNameDetail((key: CacheNameDetailsProp): void => { + if (typeof details[key] === "string") { + _cacheNameDetails[key] = details[key]; + } + }); + }, + getGoogleAnalyticsName: (userCacheName?: string): string => { + return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics); + }, + getPrecacheName: (userCacheName?: string): string => { + return userCacheName || _createCacheName(_cacheNameDetails.precache); + }, + getPrefix: (): string => { + return _cacheNameDetails.prefix; + }, + getRuntimeName: (userCacheName?: string): string => { + return userCacheName || _createCacheName(_cacheNameDetails.runtime); + }, + getSuffix: (): string => { + return _cacheNameDetails.suffix; + }, +}; diff --git a/packages/workbox-core/src/_private/canConstructReadableStream.ts b/packages/workbox-core/src/_private/canConstructReadableStream.ts new file mode 100644 index 00000000..5401f0f1 --- /dev/null +++ b/packages/workbox-core/src/_private/canConstructReadableStream.ts @@ -0,0 +1,37 @@ +/* + 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 "../_version.js"; + +let supportStatus: boolean | undefined; + +/** + * A utility function that determines whether the current browser supports + * constructing a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream) + * object. + * + * @return {boolean} `true`, if the current browser can successfully + * construct a `ReadableStream`, `false` otherwise. + * + * @private + */ +function canConstructReadableStream(): boolean { + if (supportStatus === undefined) { + // See https://github.com/GoogleChrome/workbox/issues/1473 + try { + new ReadableStream({ start() {} }); + supportStatus = true; + } catch (error) { + supportStatus = false; + } + } + + return supportStatus; +} + +export { canConstructReadableStream }; diff --git a/packages/workbox-core/src/_private/canConstructResponseFromBodyStream.ts b/packages/workbox-core/src/_private/canConstructResponseFromBodyStream.ts new file mode 100644 index 00000000..ee61a694 --- /dev/null +++ b/packages/workbox-core/src/_private/canConstructResponseFromBodyStream.ts @@ -0,0 +1,40 @@ +/* + 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 "../_version.js"; + +let supportStatus: boolean | undefined; + +/** + * A utility function that determines whether the current browser supports + * constructing a new `Response` from a `response.body` stream. + * + * @return {boolean} `true`, if the current browser can successfully + * construct a `Response` from a `response.body` stream, `false` otherwise. + * + * @private + */ +function canConstructResponseFromBodyStream(): boolean { + if (supportStatus === undefined) { + const testResponse = new Response(""); + + if ("body" in testResponse) { + try { + new Response(testResponse.body); + supportStatus = true; + } catch (error) { + supportStatus = false; + } + } + supportStatus = false; + } + + return supportStatus; +} + +export { canConstructResponseFromBodyStream }; diff --git a/packages/workbox-core/src/_private/dontWaitFor.ts b/packages/workbox-core/src/_private/dontWaitFor.ts new file mode 100644 index 00000000..5cd736c0 --- /dev/null +++ b/packages/workbox-core/src/_private/dontWaitFor.ts @@ -0,0 +1,18 @@ +/* + 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 "../_version.js"; + +/** + * A helper function that prevents a promise from being flagged as unused. + * + * @private + **/ +export function dontWaitFor(promise: Promise): void { + // Effective no-op. + void promise.then(() => {}); +} diff --git a/packages/workbox-core/src/_private/executeQuotaErrorCallbacks.ts b/packages/workbox-core/src/_private/executeQuotaErrorCallbacks.ts new file mode 100644 index 00000000..728d712a --- /dev/null +++ b/packages/workbox-core/src/_private/executeQuotaErrorCallbacks.ts @@ -0,0 +1,40 @@ +/* + 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 { logger } from "../_private/logger.js"; +import { quotaErrorCallbacks } from "../models/quotaErrorCallbacks.js"; +import "../_version.js"; + +/** + * Runs all of the callback functions, one at a time sequentially, in the order + * in which they were registered. + * + * @memberof workbox-core + * @private + */ +async function executeQuotaErrorCallbacks(): Promise { + if (process.env.NODE_ENV !== "production") { + logger.log( + `About to run ${quotaErrorCallbacks.size} ` + + `callbacks to clean up caches.` + ); + } + + for (const callback of quotaErrorCallbacks) { + await callback(); + if (process.env.NODE_ENV !== "production") { + logger.log(callback, "is complete."); + } + } + + if (process.env.NODE_ENV !== "production") { + logger.log("Finished running callbacks."); + } +} + +export { executeQuotaErrorCallbacks }; diff --git a/packages/workbox-core/src/_private/getFriendlyURL.ts b/packages/workbox-core/src/_private/getFriendlyURL.ts new file mode 100644 index 00000000..4bfbbc10 --- /dev/null +++ b/packages/workbox-core/src/_private/getFriendlyURL.ts @@ -0,0 +1,18 @@ +/* + 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 "../_version.js"; + +const getFriendlyURL = (url: URL | string): string => { + const urlObj = new URL(String(url), location.href); + // See https://github.com/GoogleChrome/workbox/issues/2323 + // We want to include everything, except for the origin if it's same-origin. + return urlObj.href.replace(new RegExp(`^${location.origin}`), ""); +}; + +export { getFriendlyURL }; diff --git a/packages/workbox-core/src/_private/logger.ts b/packages/workbox-core/src/_private/logger.ts new file mode 100644 index 00000000..2b8b151a --- /dev/null +++ b/packages/workbox-core/src/_private/logger.ts @@ -0,0 +1,100 @@ +/* + 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 "../_version.js"; + +// logger is used inside of both service workers and the window global scope. +declare global { + interface WorkerGlobalScope { + __WB_DISABLE_DEV_LOGS: boolean; + } + + interface Window { + __WB_DISABLE_DEV_LOGS: boolean; + } +} + +type LoggerMethods = + | "debug" + | "log" + | "warn" + | "error" + | "groupCollapsed" + | "groupEnd"; + +const logger = ( + process.env.NODE_ENV === "production" + ? null + : (() => { + // Don't overwrite this value if it's already set. + // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923 + if (!("__WB_DISABLE_DEV_LOGS" in globalThis)) { + self.__WB_DISABLE_DEV_LOGS = false; + } + + let inGroup = false; + + const methodToColorMap: { [methodName: string]: string | null } = { + debug: `#7f8c8d`, // Gray + log: `#2ecc71`, // Green + warn: `#f39c12`, // Yellow + error: `#c0392b`, // Red + groupCollapsed: `#3498db`, // Blue + groupEnd: null, // No colored prefix on groupEnd + }; + + const print = function (method: LoggerMethods, args: any[]) { + if (self.__WB_DISABLE_DEV_LOGS) { + return; + } + + if (method === "groupCollapsed") { + // Safari doesn't print all console.groupCollapsed() arguments: + // https://bugs.webkit.org/show_bug.cgi?id=182754 + if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + console[method](...args); + return; + } + } + + const styles = [ + `background: ${methodToColorMap[method]!}`, + `border-radius: 0.5em`, + `color: white`, + `font-weight: bold`, + `padding: 2px 0.5em`, + ]; + + // When in a group, the workbox prefix is not displayed. + const logPrefix = inGroup ? [] : ["%cworkbox", styles.join(";")]; + + console[method](...logPrefix, ...args); + + if (method === "groupCollapsed") { + inGroup = true; + } + if (method === "groupEnd") { + inGroup = false; + } + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const api: { [methodName: string]: Function } = {}; + const loggerMethods = Object.keys(methodToColorMap); + + for (const key of loggerMethods) { + const method = key as LoggerMethods; + + api[method] = (...args: any[]) => { + print(method, args); + }; + } + + return api as unknown; + })() +) as Console; + +export { logger }; diff --git a/packages/workbox-core/src/_private/resultingClientExists.ts b/packages/workbox-core/src/_private/resultingClientExists.ts new file mode 100644 index 00000000..1f9312c6 --- /dev/null +++ b/packages/workbox-core/src/_private/resultingClientExists.ts @@ -0,0 +1,62 @@ +/* + 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 { timeout } from "./timeout.js"; +import "../_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +const MAX_RETRY_TIME = 2000; + +/** + * Returns a promise that resolves to a window client matching the passed + * `resultingClientId`. For browsers that don't support `resultingClientId` + * or if waiting for the resulting client to apper takes too long, resolve to + * `undefined`. + * + * @param {string} [resultingClientId] + * @return {Promise} + * @private + */ +export async function resultingClientExists( + resultingClientId?: string +): Promise { + if (!resultingClientId) { + return; + } + + let existingWindows = await self.clients.matchAll({ type: "window" }); + const existingWindowIds = new Set(existingWindows.map((w) => w.id)); + + let resultingWindow; + const startTime = performance.now(); + + // Only wait up to `MAX_RETRY_TIME` to find a matching client. + while (performance.now() - startTime < MAX_RETRY_TIME) { + existingWindows = await self.clients.matchAll({ type: "window" }); + + resultingWindow = existingWindows.find((w) => { + if (resultingClientId) { + // If we have a `resultingClientId`, we can match on that. + return w.id === resultingClientId; + } else { + // Otherwise match on finding a window not in `existingWindowIds`. + return !existingWindowIds.has(w.id); + } + }); + + if (resultingWindow) { + break; + } + + // Sleep for 100ms and retry. + await timeout(100); + } + + return resultingWindow; +} diff --git a/packages/workbox-core/src/_private/timeout.ts b/packages/workbox-core/src/_private/timeout.ts new file mode 100644 index 00000000..75a23f73 --- /dev/null +++ b/packages/workbox-core/src/_private/timeout.ts @@ -0,0 +1,21 @@ +/* + 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 "../_version.js"; + +/** + * Returns a promise that resolves and the passed number of milliseconds. + * This utility is an async/await-friendly version of `setTimeout`. + * + * @param {number} ms + * @return {Promise} + * @private + */ + +export function timeout(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/packages/workbox-core/src/_private/waitUntil.ts b/packages/workbox-core/src/_private/waitUntil.ts new file mode 100644 index 00000000..cfa3dd88 --- /dev/null +++ b/packages/workbox-core/src/_private/waitUntil.ts @@ -0,0 +1,28 @@ +/* + Copyright 2020 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 "../_version.js"; + +/** + * A utility method that makes it easier to use `event.waitUntil` with + * async functions and return the result. + * + * @param {ExtendableEvent} event + * @param {Function} asyncFn + * @return {Function} + * @private + */ +function waitUntil( + event: ExtendableEvent, + asyncFn: () => Promise +): Promise { + const returnPromise = asyncFn(); + event.waitUntil(returnPromise); + return returnPromise; +} + +export { waitUntil }; diff --git a/packages/workbox-core/src/_version.ts b/packages/workbox-core/src/_version.ts new file mode 100644 index 00000000..e35a8e03 --- /dev/null +++ b/packages/workbox-core/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:core:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-core/src/cacheNames.ts b/packages/workbox-core/src/cacheNames.ts new file mode 100644 index 00000000..40187b85 --- /dev/null +++ b/packages/workbox-core/src/cacheNames.ts @@ -0,0 +1,45 @@ +/* + 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 { cacheNames as _cacheNames } from "./_private/cacheNames.js"; +import "./_version.js"; + +/** + * Get the current cache names and prefix/suffix used by Workbox. + * + * `cacheNames.precache` is used for precached assets, + * `cacheNames.googleAnalytics` is used by `workbox-google-analytics` to + * store `analytics.js`, and `cacheNames.runtime` is used for everything else. + * + * `cacheNames.prefix` can be used to retrieve just the current prefix value. + * `cacheNames.suffix` can be used to retrieve just the current suffix value. + * + * @return {Object} An object with `precache`, `runtime`, `prefix`, and + * `googleAnalytics` properties. + * + * @memberof workbox-core + */ +const cacheNames = { + get googleAnalytics(): string { + return _cacheNames.getGoogleAnalyticsName(); + }, + get precache(): string { + return _cacheNames.getPrecacheName(); + }, + get prefix(): string { + return _cacheNames.getPrefix(); + }, + get runtime(): string { + return _cacheNames.getRuntimeName(); + }, + get suffix(): string { + return _cacheNames.getSuffix(); + }, +}; + +export { cacheNames }; diff --git a/packages/workbox-core/src/clientsClaim.ts b/packages/workbox-core/src/clientsClaim.ts new file mode 100644 index 00000000..a8895a6d --- /dev/null +++ b/packages/workbox-core/src/clientsClaim.ts @@ -0,0 +1,24 @@ +/* + 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 "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * Claim any currently available clients once the service worker + * becomes active. This is normally used in conjunction with `skipWaiting()`. + * + * @memberof workbox-core + */ +function clientsClaim(): void { + self.addEventListener("activate", () => self.clients.claim()); +} + +export { clientsClaim }; diff --git a/packages/workbox-core/src/copyResponse.ts b/packages/workbox-core/src/copyResponse.ts new file mode 100644 index 00000000..0db57dd2 --- /dev/null +++ b/packages/workbox-core/src/copyResponse.ts @@ -0,0 +1,70 @@ +/* + 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 { canConstructResponseFromBodyStream } from "./_private/canConstructResponseFromBodyStream.js"; +import { WorkboxError } from "./_private/WorkboxError.js"; + +import "./_version.js"; + +/** + * Allows developers to copy a response and modify its `headers`, `status`, + * or `statusText` values (the values settable via a + * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax} + * object in the constructor). + * To modify these values, pass a function as the second argument. That + * function will be invoked with a single object with the response properties + * `{headers, status, statusText}`. The return value of this function will + * be used as the `ResponseInit` for the new `Response`. To change the values + * either modify the passed parameter(s) and return it, or return a totally + * new object. + * + * This method is intentionally limited to same-origin responses, regardless of + * whether CORS was used or not. + * + * @param {Response} response + * @param {Function} modifier + * @memberof workbox-core + */ +async function copyResponse( + response: Response, + modifier?: (responseInit: ResponseInit) => ResponseInit +): Promise { + let origin = null; + // If response.url isn't set, assume it's cross-origin and keep origin null. + if (response.url) { + const responseURL = new URL(response.url); + origin = responseURL.origin; + } + + if (origin !== self.location.origin) { + throw new WorkboxError("cross-origin-copy-response", { origin }); + } + + const clonedResponse = response.clone(); + + // Create a fresh `ResponseInit` object by cloning the headers. + const responseInit: ResponseInit = { + headers: new Headers(clonedResponse.headers), + status: clonedResponse.status, + statusText: clonedResponse.statusText, + }; + + // Apply any user modifications. + const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit; + + // Create the new response from the body stream and `ResponseInit` + // modifications. Note: not all browsers support the Response.body stream, + // so fall back to reading the entire body into memory as a blob. + const body = canConstructResponseFromBodyStream() + ? clonedResponse.body + : await clonedResponse.blob(); + + return new Response(body, modifiedResponseInit); +} + +export { copyResponse }; diff --git a/packages/workbox-core/src/index.ts b/packages/workbox-core/src/index.ts new file mode 100644 index 00000000..5ee6db75 --- /dev/null +++ b/packages/workbox-core/src/index.ts @@ -0,0 +1,35 @@ +/* + 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 { registerQuotaErrorCallback } from "./registerQuotaErrorCallback.js"; +import * as _private from "./_private.js"; +import { cacheNames } from "./cacheNames.js"; +import { copyResponse } from "./copyResponse.js"; +import { clientsClaim } from "./clientsClaim.js"; +import { setCacheNameDetails } from "./setCacheNameDetails.js"; +import { skipWaiting } from "./skipWaiting.js"; +import "./_version.js"; + +/** + * All of the Workbox service worker libraries use workbox-core for shared + * code as well as setting default values that need to be shared (like cache + * names). + * + * @module workbox-core + */ +export { + _private, + cacheNames, + clientsClaim, + copyResponse, + registerQuotaErrorCallback, + setCacheNameDetails, + skipWaiting, +}; + +export * from "./types.js"; diff --git a/packages/workbox-core/src/models/messages/messageGenerator.ts b/packages/workbox-core/src/models/messages/messageGenerator.ts new file mode 100644 index 00000000..ff9faa94 --- /dev/null +++ b/packages/workbox-core/src/models/messages/messageGenerator.ts @@ -0,0 +1,30 @@ +/* + 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 { messages } from "./messages.js"; +import "../../_version.js"; + +const fallback = (code: string, ...args: any[]) => { + let msg = code; + if (args.length > 0) { + msg += ` :: ${JSON.stringify(args)}`; + } + return msg; +}; + +const generatorFunction = (code: string, details = {}) => { + const message = messages[code]; + if (!message) { + throw new Error(`Unable to find message for code '${code}'.`); + } + + return message(details); +}; + +export const messageGenerator = + process.env.NODE_ENV === "production" ? fallback : generatorFunction; diff --git a/packages/workbox-core/src/models/messages/messages.ts b/packages/workbox-core/src/models/messages/messages.ts new file mode 100644 index 00000000..3d426c54 --- /dev/null +++ b/packages/workbox-core/src/models/messages/messages.ts @@ -0,0 +1,387 @@ +/* + 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 "../../_version.js"; + +interface LoggableObject { + [key: string]: string | number; +} +interface MessageMap { + [messageID: string]: (param: LoggableObject) => string; +} + +export const messages: MessageMap = { + "invalid-value": ({ paramName, validValueDescription, value }) => { + if (!paramName || !validValueDescription) { + throw new Error(`Unexpected input to 'invalid-value' error.`); + } + return ( + `The '${paramName}' parameter was given a value with an ` + + `unexpected value. ${validValueDescription} Received a value of ` + + `${JSON.stringify(value)}.` + ); + }, + + "not-an-array": ({ moduleName, className, funcName, paramName }) => { + if (!moduleName || !className || !funcName || !paramName) { + throw new Error(`Unexpected input to 'not-an-array' error.`); + } + return ( + `The parameter '${paramName}' passed into ` + + `'${moduleName}.${className}.${funcName}()' must be an array.` + ); + }, + + "incorrect-type": ({ + expectedType, + paramName, + moduleName, + className, + funcName, + }) => { + if (!expectedType || !paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-type' error.`); + } + const classNameStr = className ? `${className}.` : ""; + return ( + `The parameter '${paramName}' passed into ` + + `'${moduleName}.${classNameStr}` + + `${funcName}()' must be of type ${expectedType}.` + ); + }, + + "incorrect-class": ({ + expectedClassName, + paramName, + moduleName, + className, + funcName, + isReturnValueProblem, + }) => { + if (!expectedClassName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-class' error.`); + } + const classNameStr = className ? `${className}.` : ""; + if (isReturnValueProblem) { + return ( + `The return value from ` + + `'${moduleName}.${classNameStr}${funcName}()' ` + + `must be an instance of class ${expectedClassName}.` + ); + } + + return ( + `The parameter '${paramName}' passed into ` + + `'${moduleName}.${classNameStr}${funcName}()' ` + + `must be an instance of class ${expectedClassName}.` + ); + }, + + "missing-a-method": ({ + expectedMethod, + paramName, + moduleName, + className, + funcName, + }) => { + if ( + !expectedMethod || + !paramName || + !moduleName || + !className || + !funcName + ) { + throw new Error(`Unexpected input to 'missing-a-method' error.`); + } + return ( + `${moduleName}.${className}.${funcName}() expected the ` + + `'${paramName}' parameter to expose a '${expectedMethod}' method.` + ); + }, + + "add-to-cache-list-unexpected-type": ({ entry }) => { + return ( + `An unexpected entry was passed to ` + + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + + `'${JSON.stringify( + entry + )}' isn't supported. You must supply an array of ` + + `strings with one or more characters, objects with a url property or ` + + `Request objects.` + ); + }, + + "add-to-cache-list-conflicting-entries": ({ firstEntry, secondEntry }) => { + if (!firstEntry || !secondEntry) { + throw new Error( + `Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.` + ); + } + + return ( + `Two of the entries passed to ` + + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + + `${firstEntry} but different revision details. Workbox is ` + + `unable to cache and version the asset correctly. Please remove one ` + + `of the entries.` + ); + }, + + "plugin-error-request-will-fetch": ({ thrownErrorMessage }) => { + if (!thrownErrorMessage) { + throw new Error( + `Unexpected input to ` + `'plugin-error-request-will-fetch', error.` + ); + } + + return ( + `An error was thrown by a plugins 'requestWillFetch()' method. ` + + `The thrown error message was: '${thrownErrorMessage}'.` + ); + }, + + "invalid-cache-name": ({ cacheNameId, value }) => { + if (!cacheNameId) { + throw new Error( + `Expected a 'cacheNameId' for error 'invalid-cache-name'` + ); + } + + return ( + `You must provide a name containing at least one character for ` + + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + + `'${JSON.stringify(value)}'` + ); + }, + + "unregister-route-but-not-found-with-method": ({ method }) => { + if (!method) { + throw new Error( + `Unexpected input to ` + + `'unregister-route-but-not-found-with-method' error.` + ); + } + + return ( + `The route you're trying to unregister was not previously ` + + `registered for the method type '${method}'.` + ); + }, + + "unregister-route-route-not-registered": () => { + return ( + `The route you're trying to unregister was not previously ` + + `registered.` + ); + }, + + "queue-replay-failed": ({ name }) => { + return `Replaying the background sync queue '${name}' failed.`; + }, + + "duplicate-queue-name": ({ name }) => { + return ( + `The Queue name '${name}' is already being used. ` + + `All instances of backgroundSync.Queue must be given unique names.` + ); + }, + + "expired-test-without-max-age": ({ methodName, paramName }) => { + return ( + `The '${methodName}()' method can only be used when the ` + + `'${paramName}' is used in the constructor.` + ); + }, + + "unsupported-route-type": ({ + moduleName, + className, + funcName, + paramName, + }) => { + return ( + `The supplied '${paramName}' parameter was an unsupported type. ` + + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + + `valid input types.` + ); + }, + + "not-array-of-class": ({ + value, + expectedClass, + moduleName, + className, + funcName, + paramName, + }) => { + return ( + `The supplied '${paramName}' parameter must be an array of ` + + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + + `Please check the call to ${moduleName}.${className}.${funcName}() ` + + `to fix the issue.` + ); + }, + + "max-entries-or-age-required": ({ moduleName, className, funcName }) => { + return ( + `You must define either config.maxEntries or config.maxAgeSeconds` + + `in ${moduleName}.${className}.${funcName}` + ); + }, + + "statuses-or-headers-required": ({ moduleName, className, funcName }) => { + return ( + `You must define either config.statuses or config.headers` + + `in ${moduleName}.${className}.${funcName}` + ); + }, + + "invalid-string": ({ moduleName, funcName, paramName }) => { + if (!paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'invalid-string' error.`); + } + return ( + `When using strings, the '${paramName}' parameter must start with ` + + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + + `Please see the docs for ${moduleName}.${funcName}() for ` + + `more info.` + ); + }, + + "channel-name-required": () => { + return ( + `You must provide a channelName to construct a ` + + `BroadcastCacheUpdate instance.` + ); + }, + + "invalid-responses-are-same-args": () => { + return ( + `The arguments passed into responsesAreSame() appear to be ` + + `invalid. Please ensure valid Responses are used.` + ); + }, + + "expire-custom-caches-only": () => { + return ( + `You must provide a 'cacheName' property when using the ` + + `expiration plugin with a runtime caching strategy.` + ); + }, + + "unit-must-be-bytes": ({ normalizedRangeHeader }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`); + } + return ( + `The 'unit' portion of the Range header must be set to 'bytes'. ` + + `The Range header provided was "${normalizedRangeHeader}"` + ); + }, + + "single-range-only": ({ normalizedRangeHeader }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'single-range-only' error.`); + } + return ( + `Multiple ranges are not supported. Please use a single start ` + + `value, and optional end value. The Range header provided was ` + + `"${normalizedRangeHeader}"` + ); + }, + + "invalid-range-values": ({ normalizedRangeHeader }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'invalid-range-values' error.`); + } + return ( + `The Range header is missing both start and end values. At least ` + + `one of those values is needed. The Range header provided was ` + + `"${normalizedRangeHeader}"` + ); + }, + + "no-range-header": () => { + return `No Range header was found in the Request provided.`; + }, + + "range-not-satisfiable": ({ size, start, end }) => { + return ( + `The start (${start}) and end (${end}) values in the Range are ` + + `not satisfiable by the cached response, which is ${size} bytes.` + ); + }, + + "attempt-to-cache-non-get-request": ({ url, method }) => { + return ( + `Unable to cache '${url}' because it is a '${method}' request and ` + + `only 'GET' requests can be cached.` + ); + }, + + "cache-put-with-no-response": ({ url }) => { + return ( + `There was an attempt to cache '${url}' but the response was not ` + + `defined.` + ); + }, + + "no-response": ({ url, error }) => { + let message = `The strategy could not generate a response for '${url}'.`; + if (error) { + message += ` The underlying error is ${error}.`; + } + return message; + }, + + "bad-precaching-response": ({ url, status }) => { + return ( + `The precaching request for '${url}' failed` + + (status ? ` with an HTTP status of ${status}.` : `.`) + ); + }, + + "non-precached-url": ({ url }) => { + return ( + `createHandlerBoundToURL('${url}') was called, but that URL is ` + + `not precached. Please pass in a URL that is precached instead.` + ); + }, + + "add-to-cache-list-conflicting-integrities": ({ url }) => { + return ( + `Two of the entries passed to ` + + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + + `${url} with different integrity values. Please remove one of them.` + ); + }, + + "missing-precache-entry": ({ cacheName, url }) => { + return `Unable to find a precached response in ${cacheName} for ${url}.`; + }, + + "cross-origin-copy-response": ({ origin }) => { + return ( + `workbox-core.copyResponse() can only be used with same-origin ` + + `responses. It was passed a response with origin ${origin}.` + ); + }, + + "opaque-streams-source": ({ type }) => { + const message = + `One of the workbox-streams sources resulted in an ` + + `'${type}' response.`; + if (type === "opaqueredirect") { + return ( + `${message} Please do not use a navigation request that results ` + + `in a redirect as a source.` + ); + } + return `${message} Please ensure your sources are CORS-enabled.`; + }, +}; diff --git a/packages/workbox-core/src/models/pluginEvents.ts b/packages/workbox-core/src/models/pluginEvents.ts new file mode 100644 index 00000000..9bf6b4ec --- /dev/null +++ b/packages/workbox-core/src/models/pluginEvents.ts @@ -0,0 +1,19 @@ +/* + 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 "../_version.js"; + +export const enum pluginEvents { + CACHE_DID_UPDATE = "cacheDidUpdate", + CACHE_KEY_WILL_BE_USED = "cacheKeyWillBeUsed", + CACHE_WILL_UPDATE = "cacheWillUpdate", + CACHED_RESPONSE_WILL_BE_USED = "cachedResponseWillBeUsed", + FETCH_DID_FAIL = "fetchDidFail", + FETCH_DID_SUCCEED = "fetchDidSucceed", + REQUEST_WILL_FETCH = "requestWillFetch", +} diff --git a/packages/workbox-core/src/models/quotaErrorCallbacks.ts b/packages/workbox-core/src/models/quotaErrorCallbacks.ts new file mode 100644 index 00000000..aa894c0b --- /dev/null +++ b/packages/workbox-core/src/models/quotaErrorCallbacks.ts @@ -0,0 +1,16 @@ +/* + 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 "../_version.js"; + +// Callbacks to be executed whenever there's a quota error. +// Can't change Function type right now. +// eslint-disable-next-line @typescript-eslint/ban-types +const quotaErrorCallbacks: Set = new Set(); + +export { quotaErrorCallbacks }; diff --git a/packages/workbox-core/src/registerQuotaErrorCallback.ts b/packages/workbox-core/src/registerQuotaErrorCallback.ts new file mode 100644 index 00000000..382525d9 --- /dev/null +++ b/packages/workbox-core/src/registerQuotaErrorCallback.ts @@ -0,0 +1,39 @@ +/* + 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 { logger } from "./_private/logger.js"; +import { assert } from "./_private/assert.js"; +import { quotaErrorCallbacks } from "./models/quotaErrorCallbacks.js"; +import "./_version.js"; + +/** + * Adds a function to the set of quotaErrorCallbacks that will be executed if + * there's a quota error. + * + * @param {Function} callback + * @memberof workbox-core + */ +// Can't change Function type +// eslint-disable-next-line @typescript-eslint/ban-types +function registerQuotaErrorCallback(callback: Function): void { + if (process.env.NODE_ENV !== "production") { + assert!.isType(callback, "function", { + moduleName: "workbox-core", + funcName: "register", + paramName: "callback", + }); + } + + quotaErrorCallbacks.add(callback); + + if (process.env.NODE_ENV !== "production") { + logger.log("Registered a callback to respond to quota errors.", callback); + } +} + +export { registerQuotaErrorCallback }; diff --git a/packages/workbox-core/src/setCacheNameDetails.ts b/packages/workbox-core/src/setCacheNameDetails.ts new file mode 100644 index 00000000..6f1a2186 --- /dev/null +++ b/packages/workbox-core/src/setCacheNameDetails.ts @@ -0,0 +1,69 @@ +/* + 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 { assert } from "./_private/assert.js"; +import { cacheNames, PartialCacheNameDetails } from "./_private/cacheNames.js"; +import { WorkboxError } from "./_private/WorkboxError.js"; +import "./_version.js"; + +/** + * Modifies the default cache names used by the Workbox packages. + * Cache names are generated as `--`. + * + * @param {Object} details + * @param {Object} [details.prefix] The string to add to the beginning of + * the precache and runtime cache names. + * @param {Object} [details.suffix] The string to add to the end of + * the precache and runtime cache names. + * @param {Object} [details.precache] The cache name to use for precache + * caching. + * @param {Object} [details.runtime] The cache name to use for runtime caching. + * @param {Object} [details.googleAnalytics] The cache name to use for + * `workbox-google-analytics` caching. + * + * @memberof workbox-core + */ +function setCacheNameDetails(details: PartialCacheNameDetails): void { + if (process.env.NODE_ENV !== "production") { + Object.keys(details).forEach((key) => { + assert!.isType(details[key], "string", { + moduleName: "workbox-core", + funcName: "setCacheNameDetails", + paramName: `details.${key}`, + }); + }); + + if ("precache" in details && details["precache"]!.length === 0) { + throw new WorkboxError("invalid-cache-name", { + cacheNameId: "precache", + value: details["precache"], + }); + } + + if ("runtime" in details && details["runtime"]!.length === 0) { + throw new WorkboxError("invalid-cache-name", { + cacheNameId: "runtime", + value: details["runtime"], + }); + } + + if ( + "googleAnalytics" in details && + details["googleAnalytics"].length === 0 + ) { + throw new WorkboxError("invalid-cache-name", { + cacheNameId: "googleAnalytics", + value: details["googleAnalytics"], + }); + } + } + + cacheNames.updateDetails(details); +} + +export { setCacheNameDetails }; diff --git a/packages/workbox-core/src/skipWaiting.ts b/packages/workbox-core/src/skipWaiting.ts new file mode 100644 index 00000000..49ce4af9 --- /dev/null +++ b/packages/workbox-core/src/skipWaiting.ts @@ -0,0 +1,37 @@ +/* + 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 { logger } from "./_private/logger.js"; + +import "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * This method is deprecated, and will be removed in Workbox v7. + * + * Calling self.skipWaiting() is equivalent, and should be used instead. + * + * @memberof workbox-core + */ +function skipWaiting(): void { + // Just call self.skipWaiting() directly. + // See https://github.com/GoogleChrome/workbox/issues/2525 + if (process.env.NODE_ENV !== "production") { + logger.warn( + `skipWaiting() from workbox-core is no longer recommended ` + + `and will be removed in Workbox v7. Using self.skipWaiting() instead ` + + `is equivalent.` + ); + } + + void self.skipWaiting(); +} + +export { skipWaiting }; diff --git a/packages/workbox-core/src/types.ts b/packages/workbox-core/src/types.ts new file mode 100644 index 00000000..321f117e --- /dev/null +++ b/packages/workbox-core/src/types.ts @@ -0,0 +1,282 @@ +/* + 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 "./_version.js"; + +export interface MapLikeObject { + [key: string]: any; +} + +/** + * Using a plain `MapLikeObject` for now, but could extend/restrict this + * in the future. + */ +export type PluginState = MapLikeObject; + +/** + * Options passed to a `RouteMatchCallback` function. + */ +export interface RouteMatchCallbackOptions { + event: ExtendableEvent; + request: Request; + sameOrigin: boolean; + url: URL; +} + +/** + * The "match" callback is used to determine if a `Route` should apply for a + * particular URL and request. When matching occurs in response to a fetch + * event from the client, the `event` object is also supplied. However, since + * the match callback can be invoked outside of a fetch event, matching logic + * should not assume the `event` object will always be available. + * If the match callback returns a truthy value, the matching route's + * `RouteHandlerCallback` will be invoked immediately. If the value returned + * is a non-empty array or object, that value will be set on the handler's + * `options.params` argument. + */ +export interface RouteMatchCallback { + (options: RouteMatchCallbackOptions): any; +} + +/** + * Options passed to a `RouteHandlerCallback` function. + */ +export declare interface RouteHandlerCallbackOptions { + event: ExtendableEvent; + request: Request; + url: URL; + params?: string[] | MapLikeObject; +} + +/** + * Options passed to a `ManualHandlerCallback` function. + */ +export interface ManualHandlerCallbackOptions { + event: ExtendableEvent; + request: Request | string; +} + +export type HandlerCallbackOptions = + | RouteHandlerCallbackOptions + | ManualHandlerCallbackOptions; + +/** + * The "handler" callback is invoked whenever a `Router` matches a URL/Request + * to a `Route` via its `RouteMatchCallback`. This handler callback should + * return a `Promise` that resolves with a `Response`. + * + * If a non-empty array or object is returned by the `RouteMatchCallback` it + * will be passed in as this handler's `options.params` argument. + */ +export interface RouteHandlerCallback { + (options: RouteHandlerCallbackOptions): Promise; +} + +/** + * The "handler" callback is invoked whenever a `Router` matches a URL/Request + * to a `Route` via its `RouteMatchCallback`. This handler callback should + * return a `Promise` that resolves with a `Response`. + * + * If a non-empty array or object is returned by the `RouteMatchCallback` it + * will be passed in as this handler's `options.params` argument. + */ +export interface ManualHandlerCallback { + (options: ManualHandlerCallbackOptions): Promise; +} + +/** + * An object with a `handle` method of type `RouteHandlerCallback`. + * + * A `Route` object can be created with either an `RouteHandlerCallback` + * function or this `RouteHandler` object. The benefit of the `RouteHandler` + * is it can be extended (as is done by the `workbox-strategies` package). + */ +export interface RouteHandlerObject { + handle: RouteHandlerCallback; +} + +/** + * Either a `RouteHandlerCallback` or a `RouteHandlerObject`. + * Most APIs in `workbox-routing` that accept route handlers take either. + */ +export type RouteHandler = RouteHandlerCallback | RouteHandlerObject; + +export interface HandlerWillStartCallbackParam { + request: Request; + event: ExtendableEvent; + state?: PluginState; +} + +export interface HandlerWillStartCallback { + (param: HandlerWillStartCallbackParam): Promise; +} + +export interface CacheDidUpdateCallbackParam { + cacheName: string; + newResponse: Response; + request: Request; + event: ExtendableEvent; + oldResponse?: Response | null; + state?: PluginState; +} + +export interface CacheDidUpdateCallback { + (param: CacheDidUpdateCallbackParam): Promise; +} + +export interface CacheKeyWillBeUsedCallbackParam { + mode: string; + request: Request; + event: ExtendableEvent; + params?: any; + state?: PluginState; +} + +export interface CacheKeyWillBeUsedCallback { + (param: CacheKeyWillBeUsedCallbackParam): Promise; +} + +export interface CacheWillUpdateCallbackParam { + request: Request; + response: Response; + event: ExtendableEvent; + state?: PluginState; +} + +export interface CacheWillUpdateCallback { + ( + param: CacheWillUpdateCallbackParam + ): Promise; +} + +export interface CachedResponseWillBeUsedCallbackParam { + cacheName: string; + request: Request; + cachedResponse?: Response; + event: ExtendableEvent; + matchOptions?: CacheQueryOptions; + state?: PluginState; +} + +export interface CachedResponseWillBeUsedCallback { + ( + param: CachedResponseWillBeUsedCallbackParam + ): Promise; +} + +export interface FetchDidFailCallbackParam { + error: Error; + originalRequest: Request; + request: Request; + event: ExtendableEvent; + state?: PluginState; +} + +export interface FetchDidFailCallback { + (param: FetchDidFailCallbackParam): Promise; +} + +export interface FetchDidSucceedCallbackParam { + request: Request; + response: Response; + event: ExtendableEvent; + state?: PluginState; +} + +export interface FetchDidSucceedCallback { + (param: FetchDidSucceedCallbackParam): Promise; +} + +export interface RequestWillFetchCallbackParam { + request: Request; + event: ExtendableEvent; + state?: PluginState; +} + +export interface RequestWillFetchCallback { + (param: RequestWillFetchCallbackParam): Promise; +} + +export interface HandlerWillRespondCallbackParam { + request: Request; + response: Response; + event: ExtendableEvent; + state?: PluginState; +} + +export interface HandlerWillRespondCallback { + (param: HandlerWillRespondCallbackParam): Promise; +} + +export interface HandlerDidErrorCallbackParam { + request: Request; + event: ExtendableEvent; + error: Error; + state?: PluginState; +} + +export interface HandlerDidErrorCallback { + (param: HandlerDidErrorCallbackParam): Promise; +} + +export interface HandlerDidRespondCallbackParam { + request: Request; + event: ExtendableEvent; + response?: Response; + state?: PluginState; +} + +export interface HandlerDidRespondCallback { + (param: HandlerDidRespondCallbackParam): Promise; +} + +export interface HandlerDidCompleteCallbackParam { + request: Request; + error?: Error; + event: ExtendableEvent; + response?: Response; + state?: PluginState; +} + +export interface HandlerDidCompleteCallback { + (param: HandlerDidCompleteCallbackParam): Promise; +} + +/** + * An object with optional lifecycle callback properties for the fetch and + * cache operations. + */ +export declare interface WorkboxPlugin { + cacheDidUpdate?: CacheDidUpdateCallback; + cachedResponseWillBeUsed?: CachedResponseWillBeUsedCallback; + cacheKeyWillBeUsed?: CacheKeyWillBeUsedCallback; + cacheWillUpdate?: CacheWillUpdateCallback; + fetchDidFail?: FetchDidFailCallback; + fetchDidSucceed?: FetchDidSucceedCallback; + handlerDidComplete?: HandlerDidCompleteCallback; + handlerDidError?: HandlerDidErrorCallback; + handlerDidRespond?: HandlerDidRespondCallback; + handlerWillRespond?: HandlerWillRespondCallback; + handlerWillStart?: HandlerWillStartCallback; + requestWillFetch?: RequestWillFetchCallback; +} + +export interface WorkboxPluginCallbackParam { + cacheDidUpdate: CacheDidUpdateCallbackParam; + cachedResponseWillBeUsed: CachedResponseWillBeUsedCallbackParam; + cacheKeyWillBeUsed: CacheKeyWillBeUsedCallbackParam; + cacheWillUpdate: CacheWillUpdateCallbackParam; + fetchDidFail: FetchDidFailCallbackParam; + fetchDidSucceed: FetchDidSucceedCallbackParam; + handlerDidComplete: HandlerDidCompleteCallbackParam; + handlerDidError: HandlerDidErrorCallbackParam; + handlerDidRespond: HandlerDidRespondCallbackParam; + handlerWillRespond: HandlerWillRespondCallbackParam; + handlerWillStart: HandlerWillStartCallbackParam; + requestWillFetch: RequestWillFetchCallbackParam; +} diff --git a/packages/workbox-core/src/utils/pluginUtils.ts b/packages/workbox-core/src/utils/pluginUtils.ts new file mode 100644 index 00000000..3edbed3e --- /dev/null +++ b/packages/workbox-core/src/utils/pluginUtils.ts @@ -0,0 +1,16 @@ +/* + 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 { WorkboxPlugin } from "../types.js"; +import "../_version.js"; + +export const pluginUtils = { + filter: (plugins: WorkboxPlugin[], callbackName: string): WorkboxPlugin[] => { + return plugins.filter((plugin) => callbackName in plugin); + }, +}; diff --git a/packages/workbox-core/src/utils/welcome.ts b/packages/workbox-core/src/utils/welcome.ts new file mode 100644 index 00000000..e46af867 --- /dev/null +++ b/packages/workbox-core/src/utils/welcome.ts @@ -0,0 +1,35 @@ +/* + 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 { logger } from "../_private/logger.js"; +import "../_version.js"; + +// A WorkboxCore instance must be exported before we can use the logger. +// This is so it can get the current log level. +if (process.env.NODE_ENV !== "production") { + const padding = " "; + logger.groupCollapsed("Welcome to Workbox!"); + logger.log( + `You are currently using a development build. ` + + `By default this will switch to prod builds when not on localhost. ` + + `You can force this with workbox.setConfig({debug: true|false}).` + ); + logger.log( + `📖 Read the guides and documentation\n` + + `${padding}https://developers.google.com/web/tools/workbox/` + ); + logger.log( + `❓ Use the [workbox] tag on Stack Overflow to ask questions\n` + + `${padding}https://stackoverflow.com/questions/ask?tags=workbox` + ); + logger.log( + `🐛 Found a bug? Report it on GitHub\n` + + `${padding}https://github.com/GoogleChrome/workbox/issues/new` + ); + logger.groupEnd(); +} diff --git a/packages/workbox-core/tsconfig.json b/packages/workbox-core/tsconfig.json new file mode 100644 index 00000000..921c642c --- /dev/null +++ b/packages/workbox-core/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-expiration/README.md b/packages/workbox-expiration/README.md new file mode 100644 index 00000000..9f3b1962 --- /dev/null +++ b/packages/workbox-expiration/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-expiration diff --git a/packages/workbox-expiration/package.json b/packages/workbox-expiration/package.json new file mode 100644 index 00000000..689e6158 --- /dev/null +++ b/packages/workbox-expiration/package.json @@ -0,0 +1,28 @@ +{ + "name": "@ducanh2912/workbox-expiration", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "A service worker helper library that expires cached responses based on age or maximum number of entries.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "workbox-plugin" + ], + "workbox": { + "browserNamespace": "workbox.expiration", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*", + "idb": "7.1.1" + } +} diff --git a/packages/workbox-expiration/src/CacheExpiration.ts b/packages/workbox-expiration/src/CacheExpiration.ts new file mode 100644 index 00000000..a2c0a4da --- /dev/null +++ b/packages/workbox-expiration/src/CacheExpiration.ts @@ -0,0 +1,205 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import { CacheTimestampsModel } from "./models/CacheTimestampsModel.js"; + +import "./_version.js"; + +interface CacheExpirationConfig { + maxEntries?: number; + maxAgeSeconds?: number; + matchOptions?: CacheQueryOptions; +} + +/** + * The `CacheExpiration` class allows you define an expiration and / or + * limit on the number of responses stored in a + * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache). + * + * @memberof workbox-expiration + */ +class CacheExpiration { + private _isRunning = false; + private _rerunRequested = false; + private readonly _maxEntries?: number; + private readonly _maxAgeSeconds?: number; + private readonly _matchOptions?: CacheQueryOptions; + private readonly _cacheName: string; + private readonly _timestampModel: CacheTimestampsModel; + + /** + * To construct a new CacheExpiration instance you must provide at least + * one of the `config` properties. + * + * @param {string} cacheName Name of the cache to apply restrictions to. + * @param {Object} config + * @param {number} [config.maxEntries] The maximum number of entries to cache. + * Entries used the least will be removed as the maximum is reached. + * @param {number} [config.maxAgeSeconds] The maximum age of an entry before + * it's treated as stale and removed. + * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) + * that will be used when calling `delete()` on the cache. + */ + constructor(cacheName: string, config: CacheExpirationConfig = {}) { + if (process.env.NODE_ENV !== "production") { + assert!.isType(cacheName, "string", { + moduleName: "workbox-expiration", + className: "CacheExpiration", + funcName: "constructor", + paramName: "cacheName", + }); + + if (!(config.maxEntries || config.maxAgeSeconds)) { + throw new WorkboxError("max-entries-or-age-required", { + moduleName: "workbox-expiration", + className: "CacheExpiration", + funcName: "constructor", + }); + } + + if (config.maxEntries) { + assert!.isType(config.maxEntries, "number", { + moduleName: "workbox-expiration", + className: "CacheExpiration", + funcName: "constructor", + paramName: "config.maxEntries", + }); + } + + if (config.maxAgeSeconds) { + assert!.isType(config.maxAgeSeconds, "number", { + moduleName: "workbox-expiration", + className: "CacheExpiration", + funcName: "constructor", + paramName: "config.maxAgeSeconds", + }); + } + } + + this._maxEntries = config.maxEntries; + this._maxAgeSeconds = config.maxAgeSeconds; + this._matchOptions = config.matchOptions; + this._cacheName = cacheName; + this._timestampModel = new CacheTimestampsModel(cacheName); + } + + /** + * Expires entries for the given cache and given criteria. + */ + async expireEntries(): Promise { + if (this._isRunning) { + this._rerunRequested = true; + return; + } + this._isRunning = true; + + const minTimestamp = this._maxAgeSeconds + ? Date.now() - this._maxAgeSeconds * 1000 + : 0; + + const urlsExpired = await this._timestampModel.expireEntries( + minTimestamp, + this._maxEntries + ); + + // Delete URLs from the cache + const cache = await self.caches.open(this._cacheName); + for (const url of urlsExpired) { + await cache.delete(url, this._matchOptions); + } + + if (process.env.NODE_ENV !== "production") { + if (urlsExpired.length > 0) { + logger.groupCollapsed( + `Expired ${urlsExpired.length} ` + + `${urlsExpired.length === 1 ? "entry" : "entries"} and removed ` + + `${urlsExpired.length === 1 ? "it" : "them"} from the ` + + `'${this._cacheName}' cache.` + ); + logger.log( + `Expired the following ${urlsExpired.length === 1 ? "URL" : "URLs"}:` + ); + urlsExpired.forEach((url) => logger.log(` ${url}`)); + logger.groupEnd(); + } else { + logger.debug(`Cache expiration ran and found no entries to remove.`); + } + } + + this._isRunning = false; + if (this._rerunRequested) { + this._rerunRequested = false; + dontWaitFor(this.expireEntries()); + } + } + + /** + * Update the timestamp for the given URL. This ensures the when + * removing entries based on maximum entries, most recently used + * is accurate or when expiring, the timestamp is up-to-date. + * + * @param {string} url + */ + async updateTimestamp(url: string): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isType(url, "string", { + moduleName: "workbox-expiration", + className: "CacheExpiration", + funcName: "updateTimestamp", + paramName: "url", + }); + } + + await this._timestampModel.setTimestamp(url, Date.now()); + } + + /** + * Can be used to check if a URL has expired or not before it's used. + * + * This requires a look up from IndexedDB, so can be slow. + * + * Note: This method will not remove the cached entry, call + * `expireEntries()` to remove indexedDB and Cache entries. + * + * @param {string} url + * @return {boolean} + */ + async isURLExpired(url: string): Promise { + if (!this._maxAgeSeconds) { + if (process.env.NODE_ENV !== "production") { + throw new WorkboxError(`expired-test-without-max-age`, { + methodName: "isURLExpired", + paramName: "maxAgeSeconds", + }); + } + return false; + } else { + const timestamp = await this._timestampModel.getTimestamp(url); + const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000; + return timestamp !== undefined ? timestamp < expireOlderThan : true; + } + } + + /** + * Removes the IndexedDB object store used to keep track of cache expiration + * metadata. + */ + async delete(): Promise { + // Make sure we don't attempt another rerun if we're called in the middle of + // a cache expiration. + this._rerunRequested = false; + await this._timestampModel.expireEntries(Infinity); // Expires all. + } +} + +export { CacheExpiration }; diff --git a/packages/workbox-expiration/src/ExpirationPlugin.ts b/packages/workbox-expiration/src/ExpirationPlugin.ts new file mode 100644 index 00000000..07eee351 --- /dev/null +++ b/packages/workbox-expiration/src/ExpirationPlugin.ts @@ -0,0 +1,302 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { cacheNames } from "workbox-core/_private/cacheNames.js"; +import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { registerQuotaErrorCallback } from "workbox-core/registerQuotaErrorCallback.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { WorkboxPlugin } from "workbox-core/types.js"; + +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. + * + * It can only be used with `workbox-strategy` instances that have a + * [custom `cacheName` property set](/web/tools/workbox/guides/configure-workbox#custom_cache_names_in_strategies). + * In other words, it can't be used to expire entries in strategy that uses the + * default runtime cache name. + * + * Whenever a cached response is used or updated, this plugin will look + * at the associated cache and remove any old or extra responses. + * + * When using `maxAgeSeconds`, responses may be used *once* after expiring + * because the expiration clean up will not have occurred until *after* the + * cached response has been used. If the response has a "Date" header, then + * a light weight expiration check is performed and the response will not be + * used immediately. + * + * When using `maxEntries`, the entry least-recently requested will be removed + * from the cache first. + * + * @memberof workbox-expiration + */ +class ExpirationPlugin implements WorkboxPlugin { + private readonly _config: ExpirationPluginOptions; + private readonly _maxAgeSeconds?: number; + private _cacheExpirations: Map; + + /** + * @param {ExpirationPluginOptions} config + * @param {number} [config.maxEntries] The maximum number of entries to cache. + * Entries used the least will be removed as the maximum is reached. + * @param {number} [config.maxAgeSeconds] The maximum age of an entry before + * it's treated as stale and removed. + * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) + * that will be used when calling `delete()` on the cache. + * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to + * automatic deletion if the available storage quota has been exceeded. + */ + constructor(config: ExpirationPluginOptions = {}) { + if (process.env.NODE_ENV !== "production") { + if (!(config.maxEntries || config.maxAgeSeconds)) { + throw new WorkboxError("max-entries-or-age-required", { + moduleName: "workbox-expiration", + className: "Plugin", + funcName: "constructor", + }); + } + + if (config.maxEntries) { + assert!.isType(config.maxEntries, "number", { + moduleName: "workbox-expiration", + className: "Plugin", + funcName: "constructor", + paramName: "config.maxEntries", + }); + } + + if (config.maxAgeSeconds) { + assert!.isType(config.maxAgeSeconds, "number", { + moduleName: "workbox-expiration", + className: "Plugin", + funcName: "constructor", + paramName: "config.maxAgeSeconds", + }); + } + } + + this._config = config; + this._maxAgeSeconds = config.maxAgeSeconds; + this._cacheExpirations = new Map(); + + if (config.purgeOnQuotaError) { + registerQuotaErrorCallback(() => this.deleteCacheAndMetadata()); + } + } + + /** + * A simple helper method to return a CacheExpiration instance for a given + * cache name. + * + * @param {string} cacheName + * @return {CacheExpiration} + * + * @private + */ + private _getCacheExpiration(cacheName: string): CacheExpiration { + if (cacheName === cacheNames.getRuntimeName()) { + throw new WorkboxError("expire-custom-caches-only"); + } + + let cacheExpiration = this._cacheExpirations.get(cacheName); + if (!cacheExpiration) { + cacheExpiration = new CacheExpiration(cacheName, this._config); + this._cacheExpirations.set(cacheName, cacheExpiration); + } + return cacheExpiration; + } + + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-strategies` handlers when a `Response` is about to be returned + * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to + * the handler. It allows the `Response` to be inspected for freshness and + * prevents it from being used if the `Response`'s `Date` header value is + * older than the configured `maxAgeSeconds`. + * + * @param {Object} options + * @param {string} options.cacheName Name of the cache the response is in. + * @param {Response} options.cachedResponse The `Response` object that's been + * read from a cache and whose freshness should be checked. + * @return {Response} Either the `cachedResponse`, if it's + * fresh, or `null` if the `Response` is older than `maxAgeSeconds`. + * + * @private + */ + cachedResponseWillBeUsed: WorkboxPlugin["cachedResponseWillBeUsed"] = async ({ + event, + request, + cacheName, + cachedResponse, + }) => { + if (!cachedResponse) { + return null; + } + + const isFresh = this._isResponseDateFresh(cachedResponse); + + // Expire entries to ensure that even if the expiration date has + // expired, it'll only be used once. + const cacheExpiration = this._getCacheExpiration(cacheName); + dontWaitFor(cacheExpiration.expireEntries()); + + // Update the metadata for the request URL to the current timestamp, + // but don't `await` it as we don't want to block the response. + const updateTimestampDone = cacheExpiration.updateTimestamp(request.url); + if (event) { + try { + event.waitUntil(updateTimestampDone); + } catch (error) { + if (process.env.NODE_ENV !== "production") { + // The event may not be a fetch event; only log the URL if it is. + if ("request" in event) { + logger.warn( + `Unable to ensure service worker stays alive when ` + + `updating cache entry for ` + + `'${getFriendlyURL((event as FetchEvent).request.url)}'.` + ); + } + } + } + } + + return isFresh ? cachedResponse : null; + }; + + /** + * @param {Response} cachedResponse + * @return {boolean} + * + * @private + */ + private _isResponseDateFresh(cachedResponse: Response): boolean { + if (!this._maxAgeSeconds) { + // We aren't expiring by age, so return true, it's fresh + return true; + } + + // Check if the 'date' header will suffice a quick expiration check. + // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for + // discussion. + const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse); + if (dateHeaderTimestamp === null) { + // Unable to parse date, so assume it's fresh. + return true; + } + + // If we have a valid headerTime, then our response is fresh iff the + // headerTime plus maxAgeSeconds is greater than the current time. + const now = Date.now(); + return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1000; + } + + /** + * This method will extract the data header and parse it into a useful + * value. + * + * @param {Response} cachedResponse + * @return {number|null} + * + * @private + */ + private _getDateHeaderTimestamp(cachedResponse: Response): number | null { + if (!cachedResponse.headers.has("date")) { + return null; + } + + const dateHeader = cachedResponse.headers.get("date"); + const parsedDate = new Date(dateHeader!); + const headerTime = parsedDate.getTime(); + + // If the Date header was invalid for some reason, parsedDate.getTime() + // will return NaN. + if (isNaN(headerTime)) { + return null; + } + + return headerTime; + } + + /** + * A "lifecycle" callback that will be triggered automatically by the + * `workbox-strategies` handlers when an entry is added to a cache. + * + * @param {Object} options + * @param {string} options.cacheName Name of the cache that was updated. + * @param {string} options.request The Request for the cached entry. + * + * @private + */ + cacheDidUpdate: WorkboxPlugin["cacheDidUpdate"] = async ({ + cacheName, + request, + }) => { + if (process.env.NODE_ENV !== "production") { + assert!.isType(cacheName, "string", { + moduleName: "workbox-expiration", + className: "Plugin", + funcName: "cacheDidUpdate", + paramName: "cacheName", + }); + assert!.isInstance(request, Request, { + moduleName: "workbox-expiration", + className: "Plugin", + funcName: "cacheDidUpdate", + paramName: "request", + }); + } + + const cacheExpiration = this._getCacheExpiration(cacheName); + await cacheExpiration.updateTimestamp(request.url); + await cacheExpiration.expireEntries(); + }; + + /** + * This is a helper method that performs two operations: + * + * - Deletes *all* the underlying Cache instances associated with this plugin + * instance, by calling caches.delete() on your behalf. + * - Deletes the metadata from IndexedDB used to keep track of expiration + * details for each Cache instance. + * + * When using cache expiration, calling this method is preferable to calling + * `caches.delete()` directly, since this will ensure that the IndexedDB + * metadata is also cleanly removed and open IndexedDB instances are deleted. + * + * Note that if you're *not* using cache expiration for a given cache, calling + * `caches.delete()` and passing in the cache's name should be sufficient. + * There is no Workbox-specific method needed for cleanup in that case. + */ + async deleteCacheAndMetadata(): Promise { + // Do this one at a time instead of all at once via `Promise.all()` to + // reduce the chance of inconsistency if a promise rejects. + for (const [cacheName, cacheExpiration] of this._cacheExpirations) { + await self.caches.delete(cacheName); + await cacheExpiration.delete(); + } + + // Reset this._cacheExpirations to its initial state. + this._cacheExpirations = new Map(); + } +} + +export { ExpirationPlugin }; diff --git a/packages/workbox-expiration/src/_version.ts b/packages/workbox-expiration/src/_version.ts new file mode 100644 index 00000000..36132505 --- /dev/null +++ b/packages/workbox-expiration/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:expiration:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-expiration/src/index.ts b/packages/workbox-expiration/src/index.ts new file mode 100644 index 00000000..d7d8ab42 --- /dev/null +++ b/packages/workbox-expiration/src/index.ts @@ -0,0 +1,21 @@ +/* + 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 { CacheExpiration } from "./CacheExpiration.js"; +import { + ExpirationPlugin, + ExpirationPluginOptions, +} from "./ExpirationPlugin.js"; + +import "./_version.js"; + +/** + * @module workbox-expiration + */ + +export { CacheExpiration, ExpirationPlugin, ExpirationPluginOptions }; diff --git a/packages/workbox-expiration/src/models/CacheTimestampsModel.ts b/packages/workbox-expiration/src/models/CacheTimestampsModel.ts new file mode 100644 index 00000000..ae80dc97 --- /dev/null +++ b/packages/workbox-expiration/src/models/CacheTimestampsModel.ts @@ -0,0 +1,226 @@ +/* + 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 { openDB, DBSchema, IDBPDatabase, deleteDB } from "idb"; +import "../_version.js"; + +const DB_NAME = "workbox-expiration"; +const CACHE_OBJECT_STORE = "cache-entries"; + +const normalizeURL = (unNormalizedUrl: string) => { + const url = new URL(unNormalizedUrl, location.href); + url.hash = ""; + + return url.href; +}; + +interface CacheTimestampsModelEntry { + id: string; + cacheName: string; + url: string; + timestamp: number; +} + +interface CacheDbSchema extends DBSchema { + "cache-entries": { + key: string; + value: CacheTimestampsModelEntry; + indexes: { cacheName: string; timestamp: number }; + }; +} + +/** + * Returns the timestamp model. + * + * @private + */ +class CacheTimestampsModel { + private readonly _cacheName: string; + private _db: IDBPDatabase | null = null; + + /** + * + * @param {string} cacheName + * + * @private + */ + constructor(cacheName: string) { + this._cacheName = cacheName; + } + + /** + * Performs an upgrade of indexedDB. + * + * @param {IDBPDatabase} db + * + * @private + */ + private _upgradeDb(db: IDBPDatabase) { + // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we + // have to use the `id` keyPath here and create our own values (a + // concatenation of `url + cacheName`) instead of simply using + // `keyPath: ['url', 'cacheName']`, which is supported in other browsers. + const objStore = db.createObjectStore(CACHE_OBJECT_STORE, { + keyPath: "id", + }); + + // TODO(philipwalton): once we don't have to support EdgeHTML, we can + // create a single index with the keyPath `['cacheName', 'timestamp']` + // instead of doing both these indexes. + objStore.createIndex("cacheName", "cacheName", { unique: false }); + objStore.createIndex("timestamp", "timestamp", { unique: false }); + } + + /** + * Performs an upgrade of indexedDB and deletes deprecated DBs. + * + * @param {IDBPDatabase} db + * + * @private + */ + private _upgradeDbAndDeleteOldDbs(db: IDBPDatabase) { + this._upgradeDb(db); + if (this._cacheName) { + void deleteDB(this._cacheName); + } + } + + /** + * @param {string} url + * @param {number} timestamp + * + * @private + */ + async setTimestamp(url: string, timestamp: number): Promise { + url = normalizeURL(url); + + const entry: CacheTimestampsModelEntry = { + url, + timestamp, + cacheName: this._cacheName, + // Creating an ID from the URL and cache name won't be necessary once + // Edge switches to Chromium and all browsers we support work with + // array keyPaths. + id: this._getId(url), + }; + const db = await this.getDb(); + const tx = db.transaction(CACHE_OBJECT_STORE, "readwrite", { + durability: "relaxed", + }); + await tx.store.put(entry); + await tx.done; + } + + /** + * Returns the timestamp stored for a given URL. + * + * @param {string} url + * @return {number | undefined} + * + * @private + */ + async getTimestamp(url: string): Promise { + const db = await this.getDb(); + const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url)); + return entry?.timestamp; + } + + /** + * Iterates through all the entries in the object store (from newest to + * oldest) and removes entries once either `maxCount` is reached or the + * entry's timestamp is less than `minTimestamp`. + * + * @param {number} minTimestamp + * @param {number} maxCount + * @return {Array} + * + * @private + */ + async expireEntries( + minTimestamp: number, + maxCount?: number + ): Promise { + const db = await this.getDb(); + let cursor = await db + .transaction(CACHE_OBJECT_STORE) + .store.index("timestamp") + .openCursor(null, "prev"); + const entriesToDelete: CacheTimestampsModelEntry[] = []; + let entriesNotDeletedCount = 0; + while (cursor) { + const result = cursor.value; + // TODO(philipwalton): once we can use a multi-key index, we + // won't have to check `cacheName` here. + if (result.cacheName === this._cacheName) { + // Delete an entry if it's older than the max age or + // if we already have the max number allowed. + if ( + (minTimestamp && result.timestamp < minTimestamp) || + (maxCount && entriesNotDeletedCount >= maxCount) + ) { + // TODO(philipwalton): we should be able to delete the + // entry right here, but doing so causes an iteration + // bug in Safari stable (fixed in TP). Instead we can + // store the keys of the entries to delete, and then + // delete the separate transactions. + // https://github.com/GoogleChrome/workbox/issues/1978 + // cursor.delete(); + + // We only need to return the URL, not the whole entry. + entriesToDelete.push(cursor.value); + } else { + entriesNotDeletedCount++; + } + } + cursor = await cursor.continue(); + } + + // TODO(philipwalton): once the Safari bug in the following issue is fixed, + // we should be able to remove this loop and do the entry deletion in the + // cursor loop above: + // https://github.com/GoogleChrome/workbox/issues/1978 + const urlsDeleted: string[] = []; + for (const entry of entriesToDelete) { + await db.delete(CACHE_OBJECT_STORE, entry.id); + urlsDeleted.push(entry.url); + } + + return urlsDeleted; + } + + /** + * Takes a URL and returns an ID that will be unique in the object store. + * + * @param {string} url + * @return {string} + * + * @private + */ + private _getId(url: string): string { + // Creating an ID from the URL and cache name won't be necessary once + // Edge switches to Chromium and all browsers we support work with + // array keyPaths. + return this._cacheName + "|" + normalizeURL(url); + } + + /** + * Returns an open connection to the database. + * + * @private + */ + private async getDb() { + if (!this._db) { + this._db = await openDB(DB_NAME, 1, { + upgrade: this._upgradeDbAndDeleteOldDbs.bind(this), + }); + } + return this._db; + } +} + +export { CacheTimestampsModel }; diff --git a/packages/workbox-expiration/tsconfig.json b/packages/workbox-expiration/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-expiration/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-google-analytics/README.md b/packages/workbox-google-analytics/README.md new file mode 100644 index 00000000..3678fb2f --- /dev/null +++ b/packages/workbox-google-analytics/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-google-analytics diff --git a/packages/workbox-google-analytics/package.json b/packages/workbox-google-analytics/package.json new file mode 100644 index 00000000..1cf4f0dc --- /dev/null +++ b/packages/workbox-google-analytics/package.json @@ -0,0 +1,33 @@ +{ + "name": "@ducanh2912/workbox-google-analytics", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "Queues failed requests and uses the Background Sync API to replay them when the network is available", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "offline", + "google", + "analytics" + ], + "workbox": { + "browserNamespace": "workbox.googleAnalytics", + "outputFilename": "workbox-offline-ga", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-background-sync": "workspace:*", + "@ducanh2912/workbox-core": "workspace:*", + "@ducanh2912/workbox-routing": "workspace:*", + "@ducanh2912/workbox-strategies": "workspace:*" + } +} diff --git a/packages/workbox-google-analytics/src/_version.ts b/packages/workbox-google-analytics/src/_version.ts new file mode 100644 index 00000000..e34069fb --- /dev/null +++ b/packages/workbox-google-analytics/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:google-analytics:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-google-analytics/src/index.ts b/packages/workbox-google-analytics/src/index.ts new file mode 100644 index 00000000..2b56c549 --- /dev/null +++ b/packages/workbox-google-analytics/src/index.ts @@ -0,0 +1,17 @@ +/* + 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 { initialize, GoogleAnalyticsInitializeOptions } from "./initialize.js"; + +import "./_version.js"; + +/** + * @module workbox-google-analytics + */ + +export { initialize, GoogleAnalyticsInitializeOptions }; diff --git a/packages/workbox-google-analytics/src/initialize.ts b/packages/workbox-google-analytics/src/initialize.ts new file mode 100644 index 00000000..cdcc8903 --- /dev/null +++ b/packages/workbox-google-analytics/src/initialize.ts @@ -0,0 +1,233 @@ +/* + 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 { BackgroundSyncPlugin } from "workbox-background-sync/BackgroundSyncPlugin.js"; +import { Queue } from "workbox-background-sync/Queue.js"; +import { cacheNames } from "workbox-core/_private/cacheNames.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { RouteMatchCallbackOptions } from "workbox-core/types.js"; +import { Route } from "workbox-routing/Route.js"; +import { Router } from "workbox-routing/Router.js"; +import { NetworkFirst } from "workbox-strategies/NetworkFirst.js"; +import { NetworkOnly } from "workbox-strategies/NetworkOnly.js"; +import { + QUEUE_NAME, + MAX_RETENTION_TIME, + GOOGLE_ANALYTICS_HOST, + GTM_HOST, + ANALYTICS_JS_PATH, + GTAG_JS_PATH, + GTM_JS_PATH, + COLLECT_PATHS_REGEX, +} from "./utils/constants.js"; +import "./_version.js"; + +export interface GoogleAnalyticsInitializeOptions { + cacheName?: string; + parameterOverrides?: { [paramName: string]: string }; + hitFilter?: (params: URLSearchParams) => void; +} + +/** + * Creates the requestWillDequeue callback to be used with the background + * sync plugin. The callback takes the failed request and adds the + * `qt` param based on the current time, as well as applies any other + * user-defined hit modifications. + * + * @param {Object} config See {@link workbox-google-analytics.initialize}. + * @return {Function} The requestWillDequeue callback function. + * + * @private + */ +const createOnSyncCallback = (config: GoogleAnalyticsInitializeOptions) => { + return async ({ queue }: { queue: Queue }) => { + let entry; + while ((entry = await queue.shiftRequest())) { + const { request, timestamp } = entry; + const url = new URL(request.url); + + try { + // Measurement protocol requests can set their payload parameters in + // either the URL query string (for GET requests) or the POST body. + const params = + request.method === "POST" + ? new URLSearchParams(await request.clone().text()) + : url.searchParams; + + // Calculate the qt param, accounting for the fact that an existing + // qt param may be present and should be updated rather than replaced. + const originalHitTime = timestamp! - (Number(params.get("qt")) || 0); + const queueTime = Date.now() - originalHitTime; + + // Set the qt param prior to applying hitFilter or parameterOverrides. + params.set("qt", String(queueTime)); + + // Apply `parameterOverrides`, if set. + if (config.parameterOverrides) { + for (const param of Object.keys(config.parameterOverrides)) { + const value = config.parameterOverrides[param]; + params.set(param, value); + } + } + + // Apply `hitFilter`, if set. + if (typeof config.hitFilter === "function") { + config.hitFilter.call(null, params); + } + + // Retry the fetch. Ignore URL search params from the URL as they're + // now in the post body. + await fetch( + new Request(url.origin + url.pathname, { + body: params.toString(), + method: "POST", + mode: "cors", + credentials: "omit", + headers: { "Content-Type": "text/plain" }, + }) + ); + + if (process.env.NODE_ENV !== "production") { + logger.log( + `Request for '${getFriendlyURL(url.href)}' ` + `has been replayed` + ); + } + } catch (err) { + await queue.unshiftRequest(entry); + + if (process.env.NODE_ENV !== "production") { + logger.log( + `Request for '${getFriendlyURL(url.href)}' ` + + `failed to replay, putting it back in the queue.` + ); + } + throw err; + } + } + if (process.env.NODE_ENV !== "production") { + logger.log( + `All Google Analytics request successfully replayed; ` + + `the queue is now empty!` + ); + } + }; +}; + +/** + * Creates GET and POST routes to catch failed Measurement Protocol hits. + * + * @param {BackgroundSyncPlugin} bgSyncPlugin + * @return {Array} The created routes. + * + * @private + */ +const createCollectRoutes = (bgSyncPlugin: BackgroundSyncPlugin) => { + const match = ({ url }: RouteMatchCallbackOptions) => + url.hostname === GOOGLE_ANALYTICS_HOST && + COLLECT_PATHS_REGEX.test(url.pathname); + + const handler = new NetworkOnly({ + plugins: [bgSyncPlugin], + }); + + return [new Route(match, handler, "GET"), new Route(match, handler, "POST")]; +}; + +/** + * Creates a route with a network first strategy for the analytics.js script. + * + * @param {string} cacheName + * @return {Route} The created route. + * + * @private + */ +const createAnalyticsJsRoute = (cacheName: string) => { + const match = ({ url }: RouteMatchCallbackOptions) => + url.hostname === GOOGLE_ANALYTICS_HOST && + url.pathname === ANALYTICS_JS_PATH; + + const handler = new NetworkFirst({ cacheName }); + + return new Route(match, handler, "GET"); +}; + +/** + * Creates a route with a network first strategy for the gtag.js script. + * + * @param {string} cacheName + * @return {Route} The created route. + * + * @private + */ +const createGtagJsRoute = (cacheName: string) => { + const match = ({ url }: RouteMatchCallbackOptions) => + url.hostname === GTM_HOST && url.pathname === GTAG_JS_PATH; + + const handler = new NetworkFirst({ cacheName }); + + return new Route(match, handler, "GET"); +}; + +/** + * Creates a route with a network first strategy for the gtm.js script. + * + * @param {string} cacheName + * @return {Route} The created route. + * + * @private + */ +const createGtmJsRoute = (cacheName: string) => { + const match = ({ url }: RouteMatchCallbackOptions) => + url.hostname === GTM_HOST && url.pathname === GTM_JS_PATH; + + const handler = new NetworkFirst({ cacheName }); + + return new Route(match, handler, "GET"); +}; + +/** + * @param {Object=} [options] + * @param {Object} [options.cacheName] The cache name to store and retrieve + * analytics.js. Defaults to the cache names provided by `workbox-core`. + * @param {Object} [options.parameterOverrides] + * [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters), + * expressed as key/value pairs, to be added to replayed Google Analytics + * requests. This can be used to, e.g., set a custom dimension indicating + * that the request was replayed. + * @param {Function} [options.hitFilter] A function that allows you to modify + * the hit parameters prior to replaying + * the hit. The function is invoked with the original hit's URLSearchParams + * object as its only argument. + * + * @memberof workbox-google-analytics + */ +const initialize = (options: GoogleAnalyticsInitializeOptions = {}): void => { + const cacheName = cacheNames.getGoogleAnalyticsName(options.cacheName); + + const bgSyncPlugin = new BackgroundSyncPlugin(QUEUE_NAME, { + maxRetentionTime: MAX_RETENTION_TIME, + onSync: createOnSyncCallback(options), + }); + + const routes = [ + createGtmJsRoute(cacheName), + createAnalyticsJsRoute(cacheName), + createGtagJsRoute(cacheName), + ...createCollectRoutes(bgSyncPlugin), + ]; + + const router = new Router(); + for (const route of routes) { + router.registerRoute(route); + } + + router.addFetchListener(); +}; + +export { initialize }; diff --git a/packages/workbox-google-analytics/src/utils/constants.ts b/packages/workbox-google-analytics/src/utils/constants.ts new file mode 100644 index 00000000..7945d2df --- /dev/null +++ b/packages/workbox-google-analytics/src/utils/constants.ts @@ -0,0 +1,24 @@ +/* + 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 "../_version.js"; + +export const QUEUE_NAME = "workbox-google-analytics"; +export const MAX_RETENTION_TIME = 60 * 48; // Two days in minutes +export const GOOGLE_ANALYTICS_HOST = "www.google-analytics.com"; +export const GTM_HOST = "www.googletagmanager.com"; +export const ANALYTICS_JS_PATH = "/analytics.js"; +export const GTAG_JS_PATH = "/gtag/js"; +export const GTM_JS_PATH = "/gtm.js"; +export const COLLECT_DEFAULT_PATH = "/collect"; + +// This RegExp matches all known Measurement Protocol single-hit collect +// endpoints. Most of the time the default path (/collect) is used, but +// occasionally an experimental endpoint is used when testing new features, +// (e.g. /r/collect or /j/collect) +export const COLLECT_PATHS_REGEX = /^\/(\w+\/)?collect/; diff --git a/packages/workbox-google-analytics/tsconfig.json b/packages/workbox-google-analytics/tsconfig.json new file mode 100644 index 00000000..7b7f3375 --- /dev/null +++ b/packages/workbox-google-analytics/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [ + {"path": "../workbox-background-sync/"}, + {"path": "../workbox-core/"}, + {"path": "../workbox-routing/"}, + {"path": "../workbox-strategies/"} + ] +} diff --git a/packages/workbox-navigation-preload/README.md b/packages/workbox-navigation-preload/README.md new file mode 100644 index 00000000..ff61ae45 --- /dev/null +++ b/packages/workbox-navigation-preload/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-navigation-preload diff --git a/packages/workbox-navigation-preload/package.json b/packages/workbox-navigation-preload/package.json new file mode 100755 index 00000000..d995edc8 --- /dev/null +++ b/packages/workbox-navigation-preload/package.json @@ -0,0 +1,27 @@ +{ + "name": "@ducanh2912/workbox-navigation-preload", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "This library allows developers to opt-in to using Navigation Preload in their service worker.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "navigation" + ], + "workbox": { + "browserNamespace": "workbox.navigationPreload", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*" + } +} diff --git a/packages/workbox-navigation-preload/src/_version.ts b/packages/workbox-navigation-preload/src/_version.ts new file mode 100644 index 00000000..a2778dfb --- /dev/null +++ b/packages/workbox-navigation-preload/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:navigation-preload:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-navigation-preload/src/disable.ts b/packages/workbox-navigation-preload/src/disable.ts new file mode 100644 index 00000000..654b0435 --- /dev/null +++ b/packages/workbox-navigation-preload/src/disable.ts @@ -0,0 +1,39 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import { isSupported } from "./isSupported.js"; +import "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * If the browser supports Navigation Preload, then this will disable it. + * + * @memberof workbox-navigation-preload + */ +function disable(): void { + if (isSupported()) { + self.addEventListener("activate", (event: ExtendableEvent) => { + event.waitUntil( + self.registration.navigationPreload.disable().then(() => { + if (process.env.NODE_ENV !== "production") { + logger.log(`Navigation preload is disabled.`); + } + }) + ); + }); + } else { + if (process.env.NODE_ENV !== "production") { + logger.log(`Navigation preload is not supported in this browser.`); + } + } +} + +export { disable }; diff --git a/packages/workbox-navigation-preload/src/enable.ts b/packages/workbox-navigation-preload/src/enable.ts new file mode 100644 index 00000000..31b1fa78 --- /dev/null +++ b/packages/workbox-navigation-preload/src/enable.ts @@ -0,0 +1,51 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import { isSupported } from "./isSupported.js"; +import "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * If the browser supports Navigation Preload, then this will enable it. + * + * @param {string} [headerValue] Optionally, allows developers to + * [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header) + * the value of the `Service-Worker-Navigation-Preload` header which will be + * sent to the server when making the navigation request. + * + * @memberof workbox-navigation-preload + */ +function enable(headerValue?: string): void { + if (isSupported()) { + self.addEventListener("activate", (event: ExtendableEvent) => { + event.waitUntil( + self.registration.navigationPreload.enable().then(() => { + // Defaults to Service-Worker-Navigation-Preload: true if not set. + if (headerValue) { + void self.registration.navigationPreload.setHeaderValue( + headerValue + ); + } + + if (process.env.NODE_ENV !== "production") { + logger.log(`Navigation preload is enabled.`); + } + }) + ); + }); + } else { + if (process.env.NODE_ENV !== "production") { + logger.log(`Navigation preload is not supported in this browser.`); + } + } +} + +export { enable }; diff --git a/packages/workbox-navigation-preload/src/index.ts b/packages/workbox-navigation-preload/src/index.ts new file mode 100644 index 00000000..9efcb50c --- /dev/null +++ b/packages/workbox-navigation-preload/src/index.ts @@ -0,0 +1,37 @@ +/* + 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 { disable } from "./disable.js"; +import { enable } from "./enable.js"; +import { isSupported } from "./isSupported.js"; +import "./_version.js"; + +// See https://github.com/GoogleChrome/workbox/issues/2946 +interface NavigationPreloadState { + enabled?: boolean; + headerValue?: string; +} + +interface NavigationPreloadManager { + disable(): Promise; + enable(): Promise; + getState(): Promise; + setHeaderValue(value: string): Promise; +} + +declare global { + interface ServiceWorkerRegistration { + readonly navigationPreload: NavigationPreloadManager; + } +} + +/** + * @module workbox-navigation-preload + */ + +export { disable, enable, isSupported }; diff --git a/packages/workbox-navigation-preload/src/isSupported.ts b/packages/workbox-navigation-preload/src/isSupported.ts new file mode 100644 index 00000000..c2fd8274 --- /dev/null +++ b/packages/workbox-navigation-preload/src/isSupported.ts @@ -0,0 +1,24 @@ +/* + 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 "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * @return {boolean} Whether or not the current browser supports enabling + * navigation preload. + * + * @memberof workbox-navigation-preload + */ +function isSupported(): boolean { + return Boolean(self.registration && self.registration.navigationPreload); +} + +export { isSupported }; diff --git a/packages/workbox-navigation-preload/tsconfig.json b/packages/workbox-navigation-preload/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-navigation-preload/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-precaching/README.md b/packages/workbox-precaching/README.md new file mode 100644 index 00000000..c1f629bc --- /dev/null +++ b/packages/workbox-precaching/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-precaching diff --git a/packages/workbox-precaching/package.json b/packages/workbox-precaching/package.json new file mode 100644 index 00000000..7b5c2f13 --- /dev/null +++ b/packages/workbox-precaching/package.json @@ -0,0 +1,28 @@ +{ + "name": "@ducanh2912/workbox-precaching", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "This module efficiently precaches assets.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw" + ], + "workbox": { + "browserNamespace": "workbox.precaching", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*", + "@ducanh2912/workbox-routing": "workspace:*", + "@ducanh2912/workbox-strategies": "workspace:*" + } +} diff --git a/packages/workbox-precaching/src/PrecacheController.ts b/packages/workbox-precaching/src/PrecacheController.ts new file mode 100644 index 00000000..6e2cca4a --- /dev/null +++ b/packages/workbox-precaching/src/PrecacheController.ts @@ -0,0 +1,366 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { cacheNames } from "workbox-core/_private/cacheNames.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { waitUntil } from "workbox-core/_private/waitUntil.js"; +import { Strategy } from "workbox-strategies/Strategy.js"; +import { RouteHandlerCallback, WorkboxPlugin } from "workbox-core/types.js"; + +import { createCacheKey } from "./utils/createCacheKey.js"; +import { PrecacheInstallReportPlugin } from "./utils/PrecacheInstallReportPlugin.js"; +import { PrecacheCacheKeyPlugin } from "./utils/PrecacheCacheKeyPlugin.js"; +import { printCleanupDetails } from "./utils/printCleanupDetails.js"; +import { printInstallDetails } from "./utils/printInstallDetails.js"; +import { PrecacheStrategy } from "./PrecacheStrategy.js"; +import { PrecacheEntry, InstallResult, CleanupResult } from "./_types.js"; +import "./_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +declare global { + interface ServiceWorkerGlobalScope { + __WB_MANIFEST: Array; + } +} + +interface PrecacheControllerOptions { + cacheName?: string; + plugins?: WorkboxPlugin[]; + fallbackToNetwork?: boolean; +} + +/** + * Performs efficient precaching of assets. + * + * @memberof workbox-precaching + */ +class PrecacheController { + private _installAndActiveListenersAdded?: boolean; + private readonly _strategy: Strategy; + private readonly _urlsToCacheKeys: Map = new Map(); + private readonly _urlsToCacheModes: Map< + string, + | "reload" + | "default" + | "no-store" + | "no-cache" + | "force-cache" + | "only-if-cached" + > = new Map(); + private readonly _cacheKeysToIntegrities: Map = new Map(); + + /** + * Create a new PrecacheController. + * + * @param {Object} [options] + * @param {string} [options.cacheName] The cache to use for precaching. + * @param {string} [options.plugins] Plugins to use when precaching as well + * as responding to fetch events for precached assets. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor({ + cacheName, + plugins = [], + fallbackToNetwork = true, + }: PrecacheControllerOptions = {}) { + this._strategy = new PrecacheStrategy({ + cacheName: cacheNames.getPrecacheName(cacheName), + plugins: [ + ...plugins, + new PrecacheCacheKeyPlugin({ precacheController: this }), + ], + fallbackToNetwork, + }); + + // Bind the install and activate methods to the instance. + this.install = this.install.bind(this); + this.activate = this.activate.bind(this); + } + + /** + * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and + * used to cache assets and respond to fetch events. + */ + get strategy(): Strategy { + return this._strategy; + } + + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * @param {Array} [entries=[]] Array of entries to precache. + */ + precache(entries: Array): void { + this.addToCacheList(entries); + + if (!this._installAndActiveListenersAdded) { + self.addEventListener("install", this.install); + self.addEventListener("activate", this.activate); + this._installAndActiveListenersAdded = true; + } + } + + /** + * This method will add items to the precache list, removing duplicates + * and ensuring the information is valid. + * + * @param {Array} entries + * Array of entries to precache. + */ + addToCacheList(entries: Array): void { + if (process.env.NODE_ENV !== "production") { + assert!.isArray(entries, { + moduleName: "workbox-precaching", + className: "PrecacheController", + funcName: "addToCacheList", + paramName: "entries", + }); + } + + const urlsToWarnAbout: string[] = []; + for (const entry of entries) { + // See https://github.com/GoogleChrome/workbox/issues/2259 + if (typeof entry === "string") { + urlsToWarnAbout.push(entry); + } else if (entry && entry.revision === undefined) { + urlsToWarnAbout.push(entry.url); + } + + const { cacheKey, url } = createCacheKey(entry); + const cacheMode = + typeof entry !== "string" && entry.revision ? "reload" : "default"; + + if ( + this._urlsToCacheKeys.has(url) && + this._urlsToCacheKeys.get(url) !== cacheKey + ) { + throw new WorkboxError("add-to-cache-list-conflicting-entries", { + firstEntry: this._urlsToCacheKeys.get(url), + secondEntry: cacheKey, + }); + } + + if (typeof entry !== "string" && entry.integrity) { + if ( + this._cacheKeysToIntegrities.has(cacheKey) && + this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity + ) { + throw new WorkboxError("add-to-cache-list-conflicting-integrities", { + url, + }); + } + this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); + } + + this._urlsToCacheKeys.set(url, cacheKey); + this._urlsToCacheModes.set(url, cacheMode); + + if (urlsToWarnAbout.length > 0) { + const warningMessage = + `Workbox is precaching URLs without revision ` + + `info: ${urlsToWarnAbout.join(", ")}\nThis is generally NOT safe. ` + + `Learn more at https://bit.ly/wb-precache`; + if (process.env.NODE_ENV === "production") { + // Use console directly to display this warning without bloating + // bundle sizes by pulling in all of the logger codebase in prod. + console.warn(warningMessage); + } else { + logger.warn(warningMessage); + } + } + } + } + + /** + * Precaches new and updated assets. Call this method from the service worker + * install event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + install(event: ExtendableEvent): Promise { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const installReportPlugin = new PrecacheInstallReportPlugin(); + this.strategy.plugins.push(installReportPlugin); + + // Cache entries one at a time. + // See https://github.com/GoogleChrome/workbox/issues/2528 + for (const [url, cacheKey] of this._urlsToCacheKeys) { + const integrity = this._cacheKeysToIntegrities.get(cacheKey); + const cacheMode = this._urlsToCacheModes.get(url); + + const request = new Request(url, { + integrity, + cache: cacheMode, + credentials: "same-origin", + }); + + await Promise.all( + this.strategy.handleAll({ + params: { cacheKey }, + request, + event, + }) + ); + } + + const { updatedURLs, notUpdatedURLs } = installReportPlugin; + + if (process.env.NODE_ENV !== "production") { + printInstallDetails(updatedURLs, notUpdatedURLs); + } + + return { updatedURLs, notUpdatedURLs }; + }); + } + + /** + * Deletes assets that are no longer present in the current precache manifest. + * Call this method from the service worker activate event. + * + * Note: this method calls `event.waitUntil()` for you, so you do not need + * to call it yourself in your event handlers. + * + * @param {ExtendableEvent} event + * @return {Promise} + */ + activate(event: ExtendableEvent): Promise { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return waitUntil(event, async () => { + const cache = await self.caches.open(this.strategy.cacheName); + const currentlyCachedRequests = await cache.keys(); + const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); + + const deletedURLs = []; + for (const request of currentlyCachedRequests) { + if (!expectedCacheKeys.has(request.url)) { + await cache.delete(request); + deletedURLs.push(request.url); + } + } + + if (process.env.NODE_ENV !== "production") { + printCleanupDetails(deletedURLs); + } + + return { deletedURLs }; + }); + } + + /** + * Returns a mapping of a precached URL to the corresponding cache key, taking + * into account the revision information for the URL. + * + * @return {Map} A URL to cache key mapping. + */ + getURLsToCacheKeys(): Map { + return this._urlsToCacheKeys; + } + + /** + * Returns a list of all the URLs that have been precached by the current + * service worker. + * + * @return {Array} The precached URLs. + */ + getCachedURLs(): Array { + return [...this._urlsToCacheKeys.keys()]; + } + + /** + * Returns the cache key used for storing a given URL. If that URL is + * unversioned, like `/index.html', then the cache key will be the original + * URL with a search parameter appended to it. + * + * @param {string} url A URL whose cache key you want to look up. + * @return {string} The versioned URL that corresponds to a cache key + * for the original URL, or undefined if that URL isn't precached. + */ + getCacheKeyForURL(url: string): string | undefined { + const urlObject = new URL(url, location.href); + return this._urlsToCacheKeys.get(urlObject.href); + } + + /** + * @param {string} url A cache key whose SRI you want to look up. + * @return {string} The subresource integrity associated with the cache key, + * or undefined if it's not set. + */ + getIntegrityForCacheKey(cacheKey: string): string | undefined { + return this._cacheKeysToIntegrities.get(cacheKey); + } + + /** + * This acts as a drop-in replacement for + * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) + * with the following differences: + * + * - It knows what the name of the precache is, and only checks in that cache. + * - It allows you to pass in an "original" URL without versioning parameters, + * and it will automatically look up the correct cache key for the currently + * active revision of that URL. + * + * E.g., `matchPrecache('index.html')` will find the correct precached + * response for the currently active service worker, even if the actual cache + * key is `'/index.html?__WB_REVISION__=1234abcd'`. + * + * @param {string|Request} request The key (without revisioning parameters) + * to look up in the precache. + * @return {Promise} + */ + async matchPrecache( + request: string | Request + ): Promise { + const url = request instanceof Request ? request.url : request; + const cacheKey = this.getCacheKeyForURL(url); + if (cacheKey) { + const cache = await self.caches.open(this.strategy.cacheName); + return cache.match(cacheKey); + } + return undefined; + } + + /** + * Returns a function that looks up `url` in the precache (taking into + * account revision information), and returns the corresponding `Response`. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @return {workbox-routing~handlerCallback} + */ + createHandlerBoundToURL(url: string): RouteHandlerCallback { + const cacheKey = this.getCacheKeyForURL(url); + if (!cacheKey) { + throw new WorkboxError("non-precached-url", { url }); + } + return (options) => { + options.request = new Request(url); + options.params = { cacheKey, ...options.params }; + + return this.strategy.handle(options); + }; + } +} + +export { PrecacheController }; diff --git a/packages/workbox-precaching/src/PrecacheFallbackPlugin.ts b/packages/workbox-precaching/src/PrecacheFallbackPlugin.ts new file mode 100644 index 00000000..0768bafd --- /dev/null +++ b/packages/workbox-precaching/src/PrecacheFallbackPlugin.ts @@ -0,0 +1,65 @@ +/* + Copyright 2020 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 { WorkboxPlugin } from "workbox-core/types.js"; + +import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; +import { PrecacheController } from "./PrecacheController.js"; + +import "./_version.js"; + +/** + * `PrecacheFallbackPlugin` allows you to specify an "offline fallback" + * response to be used when a given strategy is unable to generate a response. + * + * It does this by intercepting the `handlerDidError` plugin callback + * and returning a precached response, taking the expected revision parameter + * into account automatically. + * + * Unless you explicitly pass in a `PrecacheController` instance to the + * constructor, the default instance will be used. Generally speaking, most + * developers will end up using the default. + * + * @memberof workbox-precaching + */ +class PrecacheFallbackPlugin implements WorkboxPlugin { + private readonly _fallbackURL: string; + private readonly _precacheController: PrecacheController; + + /** + * Constructs a new PrecacheFallbackPlugin with the associated fallbackURL. + * + * @param {Object} config + * @param {string} config.fallbackURL A precached URL to use as the fallback + * if the associated strategy can't generate a response. + * @param {PrecacheController} [config.precacheController] An optional + * PrecacheController instance. If not provided, the default + * PrecacheController will be used. + */ + constructor({ + fallbackURL, + precacheController, + }: { + fallbackURL: string; + precacheController?: PrecacheController; + }) { + this._fallbackURL = fallbackURL; + this._precacheController = + precacheController || getOrCreatePrecacheController(); + } + + /** + * @return {Promise} The precache response for the fallback URL. + * + * @private + */ + handlerDidError: WorkboxPlugin["handlerDidError"] = () => + this._precacheController.matchPrecache(this._fallbackURL); +} + +export { PrecacheFallbackPlugin }; diff --git a/packages/workbox-precaching/src/PrecacheRoute.ts b/packages/workbox-precaching/src/PrecacheRoute.ts new file mode 100644 index 00000000..3c63f786 --- /dev/null +++ b/packages/workbox-precaching/src/PrecacheRoute.ts @@ -0,0 +1,77 @@ +/* + Copyright 2020 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 { logger } from "workbox-core/_private/logger.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { + RouteMatchCallback, + RouteMatchCallbackOptions, +} from "workbox-core/types.js"; +import { Route } from "workbox-routing/Route.js"; + +import { PrecacheRouteOptions } from "./_types.js"; +import { PrecacheController } from "./PrecacheController.js"; +import { generateURLVariations } from "./utils/generateURLVariations.js"; + +import "./_version.js"; + +/** + * A subclass of {@link workbox-routing.Route} that takes a + * {@link workbox-precaching.PrecacheController} + * instance and uses it to match incoming requests and handle fetching + * responses from the precache. + * + * @memberof workbox-precaching + * @extends workbox-routing.Route + */ +class PrecacheRoute extends Route { + /** + * @param {PrecacheController} precacheController A `PrecacheController` + * instance used to both match requests and respond to fetch events. + * @param {Object} [options] Options to control how requests are matched + * against the list of precached URLs. + * @param {string} [options.directoryIndex=index.html] The `directoryIndex` will + * check cache entries for a URLs ending with '/' to see if there is a hit when + * appending the `directoryIndex` value. + * @param {Array} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An + * array of regex's to remove search params when looking for a cache match. + * @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will + * check the cache for the URL with a `.html` added to the end of the end. + * @param {workbox-precaching~urlManipulation} [options.urlManipulation] + * This is a function that should take a URL and return an array of + * alternative URLs that should be checked for precache matches. + */ + constructor( + precacheController: PrecacheController, + options?: PrecacheRouteOptions + ) { + const match: RouteMatchCallback = ({ + request, + }: RouteMatchCallbackOptions) => { + const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); + for (const possibleURL of generateURLVariations(request.url, options)) { + const cacheKey = urlsToCacheKeys.get(possibleURL); + if (cacheKey) { + const integrity = + precacheController.getIntegrityForCacheKey(cacheKey); + return { cacheKey, integrity }; + } + } + if (process.env.NODE_ENV !== "production") { + logger.debug( + `Precaching did not find a match for ` + getFriendlyURL(request.url) + ); + } + return; + }; + + super(match, precacheController.strategy); + } +} + +export { PrecacheRoute }; diff --git a/packages/workbox-precaching/src/PrecacheStrategy.ts b/packages/workbox-precaching/src/PrecacheStrategy.ts new file mode 100644 index 00000000..5ce2ef10 --- /dev/null +++ b/packages/workbox-precaching/src/PrecacheStrategy.ts @@ -0,0 +1,287 @@ +/* + Copyright 2020 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 { copyResponse } from "workbox-core/copyResponse.js"; +import { cacheNames } from "workbox-core/_private/cacheNames.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { WorkboxPlugin } from "workbox-core/types.js"; +import { Strategy, StrategyOptions } from "workbox-strategies/Strategy.js"; +import { StrategyHandler } from "workbox-strategies/StrategyHandler.js"; + +import "./_version.js"; + +interface PrecacheStrategyOptions extends StrategyOptions { + fallbackToNetwork?: boolean; +} + +/** + * A {@link workbox-strategies.Strategy} implementation + * specifically designed to work with + * {@link workbox-precaching.PrecacheController} + * to both cache and fetch precached assets. + * + * Note: an instance of this class is created automatically when creating a + * `PrecacheController`; it's generally not necessary to create this yourself. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-precaching + */ +class PrecacheStrategy extends Strategy { + private readonly _fallbackToNetwork: boolean; + + static readonly defaultPrecacheCacheabilityPlugin: WorkboxPlugin = { + async cacheWillUpdate({ response }) { + if (!response || response.status >= 400) { + return null; + } + + return response; + }, + }; + + static readonly copyRedirectedCacheableResponsesPlugin: WorkboxPlugin = { + async cacheWillUpdate({ response }) { + return response.redirected ? await copyResponse(response) : response; + }, + }; + + /** + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init} + * of all fetch() requests made by this strategy. + * @param {Object} [options.matchOptions] The + * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to + * get the response from the network if there's a precache miss. + */ + constructor(options: PrecacheStrategyOptions = {}) { + options.cacheName = cacheNames.getPrecacheName(options.cacheName); + super(options); + + this._fallbackToNetwork = + options.fallbackToNetwork === false ? false : true; + + // Redirected responses cannot be used to satisfy a navigation request, so + // any redirected response must be "copied" rather than cloned, so the new + // response doesn't contain the `redirected` flag. See: + // https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 + this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); + } + + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request: Request, handler: StrategyHandler): Promise { + const response = await handler.cacheMatch(request); + if (response) { + return response; + } + + // If this is an `install` event for an entry that isn't already cached, + // then populate the cache. + if (handler.event && handler.event.type === "install") { + return await this._handleInstall(request, handler); + } + + // Getting here means something went wrong. An entry that should have been + // precached wasn't found in the cache. + return await this._handleFetch(request, handler); + } + + async _handleFetch( + request: Request, + handler: StrategyHandler + ): Promise { + let response; + const params = (handler.params || {}) as { + cacheKey?: string; + integrity?: string; + }; + + // Fall back to the network if we're configured to do so. + if (this._fallbackToNetwork) { + if (process.env.NODE_ENV !== "production") { + logger.warn( + `The precached response for ` + + `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` + + `found. Falling back to the network.` + ); + } + + const integrityInManifest = params.integrity; + const integrityInRequest = request.integrity; + const noIntegrityConflict = + !integrityInRequest || integrityInRequest === integrityInManifest; + + // Do not add integrity if the original request is no-cors + // See https://github.com/GoogleChrome/workbox/issues/3096 + response = await handler.fetch( + new Request(request, { + integrity: + request.mode !== "no-cors" + ? integrityInRequest || integrityInManifest + : undefined, + }) + ); + + // It's only "safe" to repair the cache if we're using SRI to guarantee + // that the response matches the precache manifest's expectations, + // and there's either a) no integrity property in the incoming request + // or b) there is an integrity, and it matches the precache manifest. + // See https://github.com/GoogleChrome/workbox/issues/2858 + // Also if the original request users no-cors we don't use integrity. + // See https://github.com/GoogleChrome/workbox/issues/3096 + if ( + integrityInManifest && + noIntegrityConflict && + request.mode !== "no-cors" + ) { + this._useDefaultCacheabilityPluginIfNeeded(); + const wasCached = await handler.cachePut(request, response.clone()); + if (process.env.NODE_ENV !== "production") { + if (wasCached) { + logger.log( + `A response for ${getFriendlyURL(request.url)} ` + + `was used to "repair" the precache.` + ); + } + } + } + } else { + // This shouldn't normally happen, but there are edge cases: + // https://github.com/GoogleChrome/workbox/issues/1441 + throw new WorkboxError("missing-precache-entry", { + cacheName: this.cacheName, + url: request.url, + }); + } + + if (process.env.NODE_ENV !== "production") { + const cacheKey = + params.cacheKey || (await handler.getCacheKey(request, "read")); + + // Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed( + `Precaching is responding to: ` + getFriendlyURL(request.url) + ); + logger.log( + `Serving the precached url: ${getFriendlyURL( + cacheKey instanceof Request ? cacheKey.url : cacheKey + )}` + ); + + logger.groupCollapsed(`View request details here.`); + logger.log(request); + logger.groupEnd(); + + logger.groupCollapsed(`View response details here.`); + logger.log(response); + logger.groupEnd(); + + logger.groupEnd(); + } + + return response; + } + + async _handleInstall( + request: Request, + handler: StrategyHandler + ): Promise { + this._useDefaultCacheabilityPluginIfNeeded(); + + const response = await handler.fetch(request); + + // Make sure we defer cachePut() until after we know the response + // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 + const wasCached = await handler.cachePut(request, response.clone()); + if (!wasCached) { + // Throwing here will lead to the `install` handler failing, which + // we want to do if *any* of the responses aren't safe to cache. + throw new WorkboxError("bad-precaching-response", { + url: request.url, + status: response.status, + }); + } + + return response; + } + + /** + * This method is complex, as there a number of things to account for: + * + * The `plugins` array can be set at construction, and/or it might be added to + * to at any time before the strategy is used. + * + * At the time the strategy is used (i.e. during an `install` event), there + * needs to be at least one plugin that implements `cacheWillUpdate` in the + * array, other than `copyRedirectedCacheableResponsesPlugin`. + * + * - If this method is called and there are no suitable `cacheWillUpdate` + * plugins, we need to add `defaultPrecacheCacheabilityPlugin`. + * + * - If this method is called and there is exactly one `cacheWillUpdate`, then + * we don't have to do anything (this might be a previously added + * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). + * + * - If this method is called and there is more than one `cacheWillUpdate`, + * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, + * we need to remove it. (This situation is unlikely, but it could happen if + * the strategy is used multiple times, the first without a `cacheWillUpdate`, + * and then later on after manually adding a custom `cacheWillUpdate`.) + * + * See https://github.com/GoogleChrome/workbox/issues/2737 for more context. + * + * @private + */ + _useDefaultCacheabilityPluginIfNeeded(): void { + let defaultPluginIndex: number | null = null; + let cacheWillUpdatePluginCount = 0; + + for (const [index, plugin] of this.plugins.entries()) { + // Ignore the copy redirected plugin when determining what to do. + if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { + continue; + } + + // Save the default plugin's index, in case it needs to be removed. + if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { + defaultPluginIndex = index; + } + + if (plugin.cacheWillUpdate) { + cacheWillUpdatePluginCount++; + } + } + + if (cacheWillUpdatePluginCount === 0) { + this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); + } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { + // Only remove the default plugin; multiple custom plugins are allowed. + this.plugins.splice(defaultPluginIndex, 1); + } + // Nothing needs to be done if cacheWillUpdatePluginCount is 1 + } +} + +export { PrecacheStrategy }; diff --git a/packages/workbox-precaching/src/_types.ts b/packages/workbox-precaching/src/_types.ts new file mode 100644 index 00000000..e469ac99 --- /dev/null +++ b/packages/workbox-precaching/src/_types.ts @@ -0,0 +1,85 @@ +/* + 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 "./_version.js"; + +export interface InstallResult { + updatedURLs: string[]; + notUpdatedURLs: string[]; +} + +export interface CleanupResult { + deletedCacheRequests: string[]; +} + +export declare interface PrecacheEntry { + integrity?: string; + url: string; + revision?: string | null; +} + +export interface PrecacheRouteOptions { + directoryIndex?: string; + ignoreURLParametersMatching?: RegExp[]; + cleanURLs?: boolean; + urlManipulation?: urlManipulation; +} + +export type urlManipulation = ({ url }: { url: URL }) => URL[]; + +// * * * IMPORTANT! * * * +// ------------------------------------------------------------------------- // +// jdsoc type definitions cannot be declared above TypeScript definitions or +// they'll be stripped from the built `.js` files, and they'll only be in the +// `d.ts` files, which aren't read by the jsdoc generator. As a result we +// have to put declare them below. + +/** + * @typedef {Object} InstallResult + * @property {Array} updatedURLs List of URLs that were updated during + * installation. + * @property {Array} notUpdatedURLs List of URLs that were already up to + * date. + * + * @memberof workbox-precaching + */ + +/** + * @typedef {Object} CleanupResult + * @property {Array} deletedCacheRequests List of URLs that were deleted + * while cleaning up the cache. + * + * @memberof workbox-precaching + */ + +/** + * @typedef {Object} PrecacheEntry + * @property {string} url URL to precache. + * @property {string} [revision] Revision information for the URL. + * @property {string} [integrity] Integrity metadata that will be used when + * making the network request for the URL. + * + * @memberof workbox-precaching + */ + +/** + * The "urlManipulation" callback can be used to determine if there are any + * additional permutations of a URL that should be used to check against + * the available precached files. + * + * For example, Workbox supports checking for '/index.html' when the URL + * '/' is provided. This callback allows additional, custom checks. + * + * @callback ~urlManipulation + * @param {Object} context + * @param {URL} context.url The request's URL. + * @return {Array} To add additional urls to test, return an Array of + * URLs. Please note that these **should not be strings**, but URL objects. + * + * @memberof workbox-precaching + */ diff --git a/packages/workbox-precaching/src/_version.ts b/packages/workbox-precaching/src/_version.ts new file mode 100644 index 00000000..89f76383 --- /dev/null +++ b/packages/workbox-precaching/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:precaching:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-precaching/src/addPlugins.ts b/packages/workbox-precaching/src/addPlugins.ts new file mode 100644 index 00000000..b1b5e668 --- /dev/null +++ b/packages/workbox-precaching/src/addPlugins.ts @@ -0,0 +1,25 @@ +/* + 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 { WorkboxPlugin } from "workbox-core/types.js"; +import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; +import "./_version.js"; + +/** + * Adds plugins to the precaching strategy. + * + * @param {Array} plugins + * + * @memberof workbox-precaching + */ +function addPlugins(plugins: WorkboxPlugin[]): void { + const precacheController = getOrCreatePrecacheController(); + precacheController.strategy.plugins.push(...plugins); +} + +export { addPlugins }; diff --git a/packages/workbox-precaching/src/addRoute.ts b/packages/workbox-precaching/src/addRoute.ts new file mode 100644 index 00000000..236c3de9 --- /dev/null +++ b/packages/workbox-precaching/src/addRoute.ts @@ -0,0 +1,38 @@ +/* + 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 { registerRoute } from "workbox-routing/registerRoute.js"; + +import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; +import { PrecacheRoute } from "./PrecacheRoute.js"; +import { PrecacheRouteOptions } from "./_types.js"; + +import "./_version.js"; + +/** + * Add a `fetch` listener to the service worker that will + * respond to + * [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests} + * with precached assets. + * + * Requests for assets that aren't precached, the `FetchEvent` will not be + * responded to, allowing the event to fall through to other `fetch` event + * listeners. + * + * @param {Object} [options] See the {@link workbox-precaching.PrecacheRoute} + * options. + * + * @memberof workbox-precaching + */ +function addRoute(options?: PrecacheRouteOptions): void { + const precacheController = getOrCreatePrecacheController(); + + const precacheRoute = new PrecacheRoute(precacheController, options); + registerRoute(precacheRoute); +} + +export { addRoute }; diff --git a/packages/workbox-precaching/src/cleanupOutdatedCaches.ts b/packages/workbox-precaching/src/cleanupOutdatedCaches.ts new file mode 100644 index 00000000..b887cdcb --- /dev/null +++ b/packages/workbox-precaching/src/cleanupOutdatedCaches.ts @@ -0,0 +1,41 @@ +/* + 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 { cacheNames } from "workbox-core/_private/cacheNames.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { deleteOutdatedCaches } from "./utils/deleteOutdatedCaches.js"; +import "./_version.js"; + +/** + * Adds an `activate` event listener which will clean up incompatible + * precaches that were created by older versions of Workbox. + * + * @memberof workbox-precaching + */ +function cleanupOutdatedCaches(): void { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener("activate", ((event: ExtendableEvent) => { + const cacheName = cacheNames.getPrecacheName(); + + event.waitUntil( + deleteOutdatedCaches(cacheName).then((cachesDeleted) => { + if (process.env.NODE_ENV !== "production") { + if (cachesDeleted.length > 0) { + logger.log( + `The following out-of-date precaches were cleaned up ` + + `automatically:`, + cachesDeleted + ); + } + } + }) + ); + }) as EventListener); +} + +export { cleanupOutdatedCaches }; diff --git a/packages/workbox-precaching/src/createHandlerBoundToURL.ts b/packages/workbox-precaching/src/createHandlerBoundToURL.ts new file mode 100644 index 00000000..8b55e6cc --- /dev/null +++ b/packages/workbox-precaching/src/createHandlerBoundToURL.ts @@ -0,0 +1,35 @@ +/* + 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 { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; +import { RouteHandlerCallback } from "workbox-core/types.js"; +import "./_version.js"; + +/** + * Helper function that calls + * {@link PrecacheController#createHandlerBoundToURL} on the default + * {@link PrecacheController} instance. + * + * If you are creating your own {@link PrecacheController}, then call the + * {@link PrecacheController#createHandlerBoundToURL} on that instance, + * instead of using this function. + * + * @param {string} url The precached URL which will be used to lookup the + * `Response`. + * @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the + * response from the network if there's a precache miss. + * @return {workbox-routing~handlerCallback} + * + * @memberof workbox-precaching + */ +function createHandlerBoundToURL(url: string): RouteHandlerCallback { + const precacheController = getOrCreatePrecacheController(); + return precacheController.createHandlerBoundToURL(url); +} + +export { createHandlerBoundToURL }; diff --git a/packages/workbox-precaching/src/getCacheKeyForURL.ts b/packages/workbox-precaching/src/getCacheKeyForURL.ts new file mode 100644 index 00000000..598132d0 --- /dev/null +++ b/packages/workbox-precaching/src/getCacheKeyForURL.ts @@ -0,0 +1,36 @@ +/* + 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 { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; +import "./_version.js"; + +/** + * Takes in a URL, and returns the corresponding URL that could be used to + * lookup the entry in the precache. + * + * If a relative URL is provided, the location of the service worker file will + * be used as the base. + * + * For precached entries without revision information, the cache key will be the + * same as the original URL. + * + * For precached entries with revision information, the cache key will be the + * original URL with the addition of a query parameter used for keeping track of + * the revision info. + * + * @param {string} url The URL whose cache key to look up. + * @return {string} The cache key that corresponds to that URL. + * + * @memberof workbox-precaching + */ +function getCacheKeyForURL(url: string): string | undefined { + const precacheController = getOrCreatePrecacheController(); + return precacheController.getCacheKeyForURL(url); +} + +export { getCacheKeyForURL }; diff --git a/packages/workbox-precaching/src/index.ts b/packages/workbox-precaching/src/index.ts new file mode 100644 index 00000000..888ccbcf --- /dev/null +++ b/packages/workbox-precaching/src/index.ts @@ -0,0 +1,52 @@ +/* + 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 { addPlugins } from "./addPlugins.js"; +import { addRoute } from "./addRoute.js"; +import { cleanupOutdatedCaches } from "./cleanupOutdatedCaches.js"; +import { createHandlerBoundToURL } from "./createHandlerBoundToURL.js"; +import { getCacheKeyForURL } from "./getCacheKeyForURL.js"; +import { matchPrecache } from "./matchPrecache.js"; +import { precache } from "./precache.js"; +import { precacheAndRoute } from "./precacheAndRoute.js"; +import { PrecacheController } from "./PrecacheController.js"; +import { PrecacheRoute } from "./PrecacheRoute.js"; +import { PrecacheStrategy } from "./PrecacheStrategy.js"; +import { PrecacheFallbackPlugin } from "./PrecacheFallbackPlugin.js"; + +import "./_version.js"; + +/** + * Most consumers of this module will want to use the + * {@link workbox-precaching.precacheAndRoute} + * method to add assets to the cache and respond to network requests with these + * cached assets. + * + * If you require more control over caching and routing, you can use the + * {@link workbox-precaching.PrecacheController} + * interface. + * + * @module workbox-precaching + */ + +export { + addPlugins, + addRoute, + cleanupOutdatedCaches, + createHandlerBoundToURL, + getCacheKeyForURL, + matchPrecache, + precache, + precacheAndRoute, + PrecacheController, + PrecacheRoute, + PrecacheStrategy, + PrecacheFallbackPlugin, +}; + +export * from "./_types.js"; diff --git a/packages/workbox-precaching/src/matchPrecache.ts b/packages/workbox-precaching/src/matchPrecache.ts new file mode 100644 index 00000000..4e4c1f42 --- /dev/null +++ b/packages/workbox-precaching/src/matchPrecache.ts @@ -0,0 +1,35 @@ +/* + 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 { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; + +import "./_version.js"; + +/** + * Helper function that calls + * {@link PrecacheController#matchPrecache} on the default + * {@link PrecacheController} instance. + * + * If you are creating your own {@link PrecacheController}, then call + * {@link PrecacheController#matchPrecache} on that instance, + * instead of using this function. + * + * @param {string|Request} request The key (without revisioning parameters) + * to look up in the precache. + * @return {Promise} + * + * @memberof workbox-precaching + */ +function matchPrecache( + request: string | Request +): Promise { + const precacheController = getOrCreatePrecacheController(); + return precacheController.matchPrecache(request); +} + +export { matchPrecache }; diff --git a/packages/workbox-precaching/src/precache.ts b/packages/workbox-precaching/src/precache.ts new file mode 100644 index 00000000..3ee437c6 --- /dev/null +++ b/packages/workbox-precaching/src/precache.ts @@ -0,0 +1,37 @@ +/* + 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 { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; +import { PrecacheEntry } from "./_types.js"; +import "./_version.js"; + +/** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * Please note: This method **will not** serve any of the cached files for you. + * It only precaches files. To respond to a network request you call + * {@link workbox-precaching.addRoute}. + * + * If you have a single array of files to precache, you can just call + * {@link workbox-precaching.precacheAndRoute}. + * + * @param {Array} [entries=[]] Array of entries to precache. + * + * @memberof workbox-precaching + */ +function precache(entries: Array): void { + const precacheController = getOrCreatePrecacheController(); + precacheController.precache(entries); +} + +export { precache }; diff --git a/packages/workbox-precaching/src/precacheAndRoute.ts b/packages/workbox-precaching/src/precacheAndRoute.ts new file mode 100644 index 00000000..964789d5 --- /dev/null +++ b/packages/workbox-precaching/src/precacheAndRoute.ts @@ -0,0 +1,36 @@ +/* + 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 { addRoute } from "./addRoute.js"; +import { precache } from "./precache.js"; +import { PrecacheRouteOptions, PrecacheEntry } from "./_types.js"; +import "./_version.js"; + +/** + * This method will add entries to the precache list and add a route to + * respond to fetch events. + * + * This is a convenience method that will call + * {@link workbox-precaching.precache} and + * {@link workbox-precaching.addRoute} in a single call. + * + * @param {Array} entries Array of entries to precache. + * @param {Object} [options] See the + * {@link workbox-precaching.PrecacheRoute} options. + * + * @memberof workbox-precaching + */ +function precacheAndRoute( + entries: Array, + options?: PrecacheRouteOptions +): void { + precache(entries); + addRoute(options); +} + +export { precacheAndRoute }; diff --git a/packages/workbox-precaching/src/utils/PrecacheCacheKeyPlugin.ts b/packages/workbox-precaching/src/utils/PrecacheCacheKeyPlugin.ts new file mode 100644 index 00000000..9233894f --- /dev/null +++ b/packages/workbox-precaching/src/utils/PrecacheCacheKeyPlugin.ts @@ -0,0 +1,52 @@ +/* + Copyright 2020 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 { + WorkboxPlugin, + WorkboxPluginCallbackParam, +} from "workbox-core/types.js"; + +import { PrecacheController } from "../PrecacheController.js"; + +import "../_version.js"; + +/** + * A plugin, designed to be used with PrecacheController, to translate URLs into + * the corresponding cache key, based on the current revision info. + * + * @private + */ +class PrecacheCacheKeyPlugin implements WorkboxPlugin { + private readonly _precacheController: PrecacheController; + + constructor({ + precacheController, + }: { + precacheController: PrecacheController; + }) { + this._precacheController = precacheController; + } + + cacheKeyWillBeUsed: WorkboxPlugin["cacheKeyWillBeUsed"] = async ({ + request, + params, + }: WorkboxPluginCallbackParam["cacheKeyWillBeUsed"]) => { + // Params is type any, can't change right now. + /* eslint-disable */ + const cacheKey = + params?.cacheKey || + this._precacheController.getCacheKeyForURL(request.url); + /* eslint-enable */ + + return cacheKey + ? new Request(cacheKey, { headers: request.headers }) + : request; + }; +} + +export { PrecacheCacheKeyPlugin }; diff --git a/packages/workbox-precaching/src/utils/PrecacheInstallReportPlugin.ts b/packages/workbox-precaching/src/utils/PrecacheInstallReportPlugin.ts new file mode 100644 index 00000000..473fdcde --- /dev/null +++ b/packages/workbox-precaching/src/utils/PrecacheInstallReportPlugin.ts @@ -0,0 +1,61 @@ +/* + Copyright 2020 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 { + WorkboxPlugin, + WorkboxPluginCallbackParam, +} from "workbox-core/types.js"; + +import "../_version.js"; + +/** + * A plugin, designed to be used with PrecacheController, to determine the + * of assets that were updated (or not updated) during the install event. + * + * @private + */ +class PrecacheInstallReportPlugin implements WorkboxPlugin { + updatedURLs: string[] = []; + notUpdatedURLs: string[] = []; + + handlerWillStart: WorkboxPlugin["handlerWillStart"] = async ({ + request, + state, + }: WorkboxPluginCallbackParam["handlerWillStart"]) => { + // TODO: `state` should never be undefined... + if (state) { + state.originalRequest = request; + } + }; + + cachedResponseWillBeUsed: WorkboxPlugin["cachedResponseWillBeUsed"] = async ({ + event, + state, + cachedResponse, + }: WorkboxPluginCallbackParam["cachedResponseWillBeUsed"]) => { + if (event.type === "install") { + if ( + state && + state.originalRequest && + state.originalRequest instanceof Request + ) { + // TODO: `state` should never be undefined... + const url = state.originalRequest.url; + + if (cachedResponse) { + this.notUpdatedURLs.push(url); + } else { + this.updatedURLs.push(url); + } + } + } + return cachedResponse; + }; +} + +export { PrecacheInstallReportPlugin }; diff --git a/packages/workbox-precaching/src/utils/createCacheKey.ts b/packages/workbox-precaching/src/utils/createCacheKey.ts new file mode 100644 index 00000000..5a92da2a --- /dev/null +++ b/packages/workbox-precaching/src/utils/createCacheKey.ts @@ -0,0 +1,69 @@ +/* + 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 { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { PrecacheEntry } from "../_types.js"; +import "../_version.js"; + +interface CacheKey { + cacheKey: string; + url: string; +} + +// Name of the search parameter used to store revision info. +const REVISION_SEARCH_PARAM = "__WB_REVISION__"; + +/** + * Converts a manifest entry into a versioned URL suitable for precaching. + * + * @param {Object|string} entry + * @return {string} A URL with versioning info. + * + * @private + * @memberof workbox-precaching + */ +export function createCacheKey(entry: PrecacheEntry | string): CacheKey { + if (!entry) { + throw new WorkboxError("add-to-cache-list-unexpected-type", { entry }); + } + + // If a precache manifest entry is a string, it's assumed to be a versioned + // URL, like '/app.abcd1234.js'. Return as-is. + if (typeof entry === "string") { + const urlObject = new URL(entry, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href, + }; + } + + const { revision, url } = entry; + if (!url) { + throw new WorkboxError("add-to-cache-list-unexpected-type", { entry }); + } + + // If there's just a URL and no revision, then it's also assumed to be a + // versioned URL. + if (!revision) { + const urlObject = new URL(url, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href, + }; + } + + // Otherwise, construct a properly versioned URL using the custom Workbox + // search parameter along with the revision info. + const cacheKeyURL = new URL(url, location.href); + const originalURL = new URL(url, location.href); + cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision); + return { + cacheKey: cacheKeyURL.href, + url: originalURL.href, + }; +} diff --git a/packages/workbox-precaching/src/utils/deleteOutdatedCaches.ts b/packages/workbox-precaching/src/utils/deleteOutdatedCaches.ts new file mode 100644 index 00000000..d95ce170 --- /dev/null +++ b/packages/workbox-precaching/src/utils/deleteOutdatedCaches.ts @@ -0,0 +1,55 @@ +/* + 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 "../_version.js"; + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +const SUBSTRING_TO_FIND = "-precache-"; + +/** + * Cleans up incompatible precaches that were created by older versions of + * Workbox, by a service worker registered under the current scope. + * + * This is meant to be called as part of the `activate` event. + * + * This should be safe to use as long as you don't include `substringToFind` + * (defaulting to `-precache-`) in your non-precache cache names. + * + * @param {string} currentPrecacheName The cache name currently in use for + * precaching. This cache won't be deleted. + * @param {string} [substringToFind='-precache-'] Cache names which include this + * substring will be deleted (excluding `currentPrecacheName`). + * @return {Array} A list of all the cache names that were deleted. + * + * @private + * @memberof workbox-precaching + */ +const deleteOutdatedCaches = async ( + currentPrecacheName: string, + substringToFind: string = SUBSTRING_TO_FIND +): Promise => { + const cacheNames = await self.caches.keys(); + + const cacheNamesToDelete = cacheNames.filter((cacheName) => { + return ( + cacheName.includes(substringToFind) && + cacheName.includes(self.registration.scope) && + cacheName !== currentPrecacheName + ); + }); + + await Promise.all( + cacheNamesToDelete.map((cacheName) => self.caches.delete(cacheName)) + ); + + return cacheNamesToDelete; +}; + +export { deleteOutdatedCaches }; diff --git a/packages/workbox-precaching/src/utils/generateURLVariations.ts b/packages/workbox-precaching/src/utils/generateURLVariations.ts new file mode 100644 index 00000000..d6fb42f5 --- /dev/null +++ b/packages/workbox-precaching/src/utils/generateURLVariations.ts @@ -0,0 +1,60 @@ +/* + 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 { removeIgnoredSearchParams } from "./removeIgnoredSearchParams.js"; +import { PrecacheRouteOptions } from "../_types.js"; +import "../_version.js"; + +/** + * Generator function that yields possible variations on the original URL to + * check, one at a time. + * + * @param {string} url + * @param {Object} options + * + * @private + * @memberof workbox-precaching + */ +export function* generateURLVariations( + url: string, + { + ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], + directoryIndex = "index.html", + cleanURLs = true, + urlManipulation, + }: PrecacheRouteOptions = {} +): Generator { + const urlObject = new URL(url, location.href); + urlObject.hash = ""; + yield urlObject.href; + + const urlWithoutIgnoredParams = removeIgnoredSearchParams( + urlObject, + ignoreURLParametersMatching + ); + yield urlWithoutIgnoredParams.href; + + if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith("/")) { + const directoryURL = new URL(urlWithoutIgnoredParams.href); + directoryURL.pathname += directoryIndex; + yield directoryURL.href; + } + + if (cleanURLs) { + const cleanURL = new URL(urlWithoutIgnoredParams.href); + cleanURL.pathname += ".html"; + yield cleanURL.href; + } + + if (urlManipulation) { + const additionalURLs = urlManipulation({ url: urlObject }); + for (const urlToAttempt of additionalURLs) { + yield urlToAttempt.href; + } + } +} diff --git a/packages/workbox-precaching/src/utils/getCacheKeyForURL.ts b/packages/workbox-precaching/src/utils/getCacheKeyForURL.ts new file mode 100644 index 00000000..ee44a94a --- /dev/null +++ b/packages/workbox-precaching/src/utils/getCacheKeyForURL.ts @@ -0,0 +1,38 @@ +/* + 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 { getOrCreatePrecacheController } from "./getOrCreatePrecacheController.js"; +import { generateURLVariations } from "./generateURLVariations.js"; +import { PrecacheRouteOptions } from "../_types.js"; +import "../_version.js"; + +/** + * This function will take the request URL and manipulate it based on the + * configuration options. + * + * @param {string} url + * @param {Object} options + * @return {string} Returns the URL in the cache that matches the request, + * if possible. + * + * @private + */ +export const getCacheKeyForURL = ( + url: string, + options: PrecacheRouteOptions +): string | void => { + const precacheController = getOrCreatePrecacheController(); + + const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); + for (const possibleURL of generateURLVariations(url, options)) { + const possibleCacheKey = urlsToCacheKeys.get(possibleURL); + if (possibleCacheKey) { + return possibleCacheKey; + } + } +}; diff --git a/packages/workbox-precaching/src/utils/getOrCreatePrecacheController.ts b/packages/workbox-precaching/src/utils/getOrCreatePrecacheController.ts new file mode 100644 index 00000000..a61c89b7 --- /dev/null +++ b/packages/workbox-precaching/src/utils/getOrCreatePrecacheController.ts @@ -0,0 +1,23 @@ +/* + 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 { PrecacheController } from "../PrecacheController.js"; +import "../_version.js"; + +let precacheController: PrecacheController | undefined; + +/** + * @return {PrecacheController} + * @private + */ +export const getOrCreatePrecacheController = (): PrecacheController => { + if (!precacheController) { + precacheController = new PrecacheController(); + } + return precacheController; +}; diff --git a/packages/workbox-precaching/src/utils/printCleanupDetails.ts b/packages/workbox-precaching/src/utils/printCleanupDetails.ts new file mode 100644 index 00000000..070a809e --- /dev/null +++ b/packages/workbox-precaching/src/utils/printCleanupDetails.ts @@ -0,0 +1,45 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import "../_version.js"; + +/** + * @param {string} groupTitle + * @param {Array} deletedURLs + * + * @private + */ +const logGroup = (groupTitle: string, deletedURLs: string[]) => { + logger.groupCollapsed(groupTitle); + + for (const url of deletedURLs) { + logger.log(url); + } + + logger.groupEnd(); +}; + +/** + * @param {Array} deletedURLs + * + * @private + * @memberof workbox-precaching + */ +export function printCleanupDetails(deletedURLs: string[]): void { + const deletionCount = deletedURLs.length; + if (deletionCount > 0) { + logger.groupCollapsed( + `During precaching cleanup, ` + + `${deletionCount} cached ` + + `request${deletionCount === 1 ? " was" : "s were"} deleted.` + ); + logGroup("Deleted Cache Requests", deletedURLs); + logger.groupEnd(); + } +} diff --git a/packages/workbox-precaching/src/utils/printInstallDetails.ts b/packages/workbox-precaching/src/utils/printInstallDetails.ts new file mode 100644 index 00000000..88e99002 --- /dev/null +++ b/packages/workbox-precaching/src/utils/printInstallDetails.ts @@ -0,0 +1,63 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import "../_version.js"; + +/** + * @param {string} groupTitle + * @param {Array} urls + * + * @private + */ +function _nestedGroup(groupTitle: string, urls: string[]): void { + if (urls.length === 0) { + return; + } + + logger.groupCollapsed(groupTitle); + + for (const url of urls) { + logger.log(url); + } + + logger.groupEnd(); +} + +/** + * @param {Array} urlsToPrecache + * @param {Array} urlsAlreadyPrecached + * + * @private + * @memberof workbox-precaching + */ +export function printInstallDetails( + urlsToPrecache: string[], + urlsAlreadyPrecached: string[] +): void { + const precachedCount = urlsToPrecache.length; + const alreadyPrecachedCount = urlsAlreadyPrecached.length; + + if (precachedCount || alreadyPrecachedCount) { + let message = `Precaching ${precachedCount} file${ + precachedCount === 1 ? "" : "s" + }.`; + + if (alreadyPrecachedCount > 0) { + message += + ` ${alreadyPrecachedCount} ` + + `file${alreadyPrecachedCount === 1 ? " is" : "s are"} already cached.`; + } + + logger.groupCollapsed(message); + + _nestedGroup(`View newly precached URLs.`, urlsToPrecache); + _nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); + logger.groupEnd(); + } +} diff --git a/packages/workbox-precaching/src/utils/removeIgnoredSearchParams.ts b/packages/workbox-precaching/src/utils/removeIgnoredSearchParams.ts new file mode 100644 index 00000000..65f8a476 --- /dev/null +++ b/packages/workbox-precaching/src/utils/removeIgnoredSearchParams.ts @@ -0,0 +1,36 @@ +/* + 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 "../_version.js"; + +/** + * Removes any URL search parameters that should be ignored. + * + * @param {URL} urlObject The original URL. + * @param {Array} ignoreURLParametersMatching RegExps to test against + * each search parameter name. Matches mean that the search parameter should be + * ignored. + * @return {URL} The URL with any ignored search parameters removed. + * + * @private + * @memberof workbox-precaching + */ +export function removeIgnoredSearchParams( + urlObject: URL, + ignoreURLParametersMatching: RegExp[] = [] +): URL { + // Convert the iterable into an array at the start of the loop to make sure + // deletion doesn't mess up iteration. + for (const paramName of [...urlObject.searchParams.keys()]) { + if (ignoreURLParametersMatching.some((regExp) => regExp.test(paramName))) { + urlObject.searchParams.delete(paramName); + } + } + + return urlObject; +} diff --git a/packages/workbox-precaching/tsconfig.json b/packages/workbox-precaching/tsconfig.json new file mode 100644 index 00000000..ff2b28d5 --- /dev/null +++ b/packages/workbox-precaching/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [ + {"path": "../workbox-core/"}, + {"path": "../workbox-routing/"}, + {"path": "../workbox-strategies/"} + ] +} diff --git a/packages/workbox-range-requests/README.md b/packages/workbox-range-requests/README.md new file mode 100644 index 00000000..ac4afc6f --- /dev/null +++ b/packages/workbox-range-requests/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-range-requests diff --git a/packages/workbox-range-requests/package.json b/packages/workbox-range-requests/package.json new file mode 100755 index 00000000..323fcabc --- /dev/null +++ b/packages/workbox-range-requests/package.json @@ -0,0 +1,31 @@ +{ + "name": "@ducanh2912/workbox-range-requests", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "This library creates a new Response, given a source Response and a Range header value.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "caching", + "cache", + "range", + "media", + "workbox-plugin" + ], + "workbox": { + "browserNamespace": "workbox.rangeRequests", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*" + } +} diff --git a/packages/workbox-range-requests/src/RangeRequestsPlugin.ts b/packages/workbox-range-requests/src/RangeRequestsPlugin.ts new file mode 100644 index 00000000..8549b384 --- /dev/null +++ b/packages/workbox-range-requests/src/RangeRequestsPlugin.ts @@ -0,0 +1,50 @@ +/* + 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 { WorkboxPlugin } from "workbox-core/types.js"; +import { createPartialResponse } from "./createPartialResponse.js"; +import "./_version.js"; + +/** + * The range request plugin makes it easy for a request with a 'Range' header to + * be fulfilled by a cached response. + * + * It does this by intercepting the `cachedResponseWillBeUsed` plugin callback + * and returning the appropriate subset of the cached response body. + * + * @memberof workbox-range-requests + */ +class RangeRequestsPlugin implements WorkboxPlugin { + /** + * @param {Object} options + * @param {Request} options.request The original request, which may or may not + * contain a Range: header. + * @param {Response} options.cachedResponse The complete cached response. + * @return {Promise} If request contains a 'Range' header, then a + * new response with status 206 whose body is a subset of `cachedResponse` is + * returned. Otherwise, `cachedResponse` is returned as-is. + * + * @private + */ + cachedResponseWillBeUsed: WorkboxPlugin["cachedResponseWillBeUsed"] = async ({ + request, + cachedResponse, + }) => { + // Only return a sliced response if there's something valid in the cache, + // and there's a Range: header in the request. + if (cachedResponse && request.headers.has("range")) { + return await createPartialResponse(request, cachedResponse); + } + + // If there was no Range: header, or if cachedResponse wasn't valid, just + // pass it through as-is. + return cachedResponse; + }; +} + +export { RangeRequestsPlugin }; diff --git a/packages/workbox-range-requests/src/_version.ts b/packages/workbox-range-requests/src/_version.ts new file mode 100644 index 00000000..d5f9b075 --- /dev/null +++ b/packages/workbox-range-requests/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:range-requests:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-range-requests/src/createPartialResponse.ts b/packages/workbox-range-requests/src/createPartialResponse.ts new file mode 100644 index 00000000..ba567fcf --- /dev/null +++ b/packages/workbox-range-requests/src/createPartialResponse.ts @@ -0,0 +1,115 @@ +/* + 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 { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { calculateEffectiveBoundaries } from "./utils/calculateEffectiveBoundaries.js"; +import { parseRangeHeader } from "./utils/parseRangeHeader.js"; +import "./_version.js"; + +/** + * Given a `Request` and `Response` objects as input, this will return a + * promise for a new `Response`. + * + * If the original `Response` already contains partial content (i.e. it has + * a status of 206), then this assumes it already fulfills the `Range:` + * requirements, and will return it as-is. + * + * @param {Request} request A request, which should contain a Range: + * header. + * @param {Response} originalResponse A response. + * @return {Promise} Either a `206 Partial Content` response, with + * the response body set to the slice of content specified by the request's + * `Range:` header, or a `416 Range Not Satisfiable` response if the + * conditions of the `Range:` header can't be met. + * + * @memberof workbox-range-requests + */ +async function createPartialResponse( + request: Request, + originalResponse: Response +): Promise { + try { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-range-requests", + funcName: "createPartialResponse", + paramName: "request", + }); + + assert!.isInstance(originalResponse, Response, { + moduleName: "workbox-range-requests", + funcName: "createPartialResponse", + paramName: "originalResponse", + }); + } + + if (originalResponse.status === 206) { + // If we already have a 206, then just pass it through as-is; + // see https://github.com/GoogleChrome/workbox/issues/1720 + return originalResponse; + } + + const rangeHeader = request.headers.get("range"); + if (!rangeHeader) { + throw new WorkboxError("no-range-header"); + } + + const boundaries = parseRangeHeader(rangeHeader); + const originalBlob = await originalResponse.blob(); + + const effectiveBoundaries = calculateEffectiveBoundaries( + originalBlob, + boundaries.start, + boundaries.end + ); + + const slicedBlob = originalBlob.slice( + effectiveBoundaries.start, + effectiveBoundaries.end + ); + const slicedBlobSize = slicedBlob.size; + + const slicedResponse = new Response(slicedBlob, { + // Status code 206 is for a Partial Content response. + // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206 + status: 206, + statusText: "Partial Content", + headers: originalResponse.headers, + }); + + slicedResponse.headers.set("Content-Length", String(slicedBlobSize)); + slicedResponse.headers.set( + "Content-Range", + `bytes ${effectiveBoundaries.start}-${effectiveBoundaries.end - 1}/` + + `${originalBlob.size}` + ); + + return slicedResponse; + } catch (error) { + if (process.env.NODE_ENV !== "production") { + logger.warn( + `Unable to construct a partial response; returning a ` + + `416 Range Not Satisfiable response instead.` + ); + logger.groupCollapsed(`View details here.`); + logger.log(error); + logger.log(request); + logger.log(originalResponse); + logger.groupEnd(); + } + + return new Response("", { + status: 416, + statusText: "Range Not Satisfiable", + }); + } +} + +export { createPartialResponse }; diff --git a/packages/workbox-range-requests/src/index.ts b/packages/workbox-range-requests/src/index.ts new file mode 100644 index 00000000..dc9721b0 --- /dev/null +++ b/packages/workbox-range-requests/src/index.ts @@ -0,0 +1,17 @@ +/* + 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 { createPartialResponse } from "./createPartialResponse.js"; +import { RangeRequestsPlugin } from "./RangeRequestsPlugin.js"; +import "./_version.js"; + +/** + * @module workbox-range-requests + */ + +export { createPartialResponse, RangeRequestsPlugin }; diff --git a/packages/workbox-range-requests/src/utils/calculateEffectiveBoundaries.ts b/packages/workbox-range-requests/src/utils/calculateEffectiveBoundaries.ts new file mode 100644 index 00000000..3b940900 --- /dev/null +++ b/packages/workbox-range-requests/src/utils/calculateEffectiveBoundaries.ts @@ -0,0 +1,67 @@ +/* + 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 { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "workbox-core/_private/assert.js"; +import "../_version.js"; + +/** + * @param {Blob} blob A source blob. + * @param {number} [start] The offset to use as the start of the + * slice. + * @param {number} [end] The offset to use as the end of the slice. + * @return {Object} An object with `start` and `end` properties, reflecting + * the effective boundaries to use given the size of the blob. + * + * @private + */ +function calculateEffectiveBoundaries( + blob: Blob, + start?: number, + end?: number +): { start: number; end: number } { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(blob, Blob, { + moduleName: "workbox-range-requests", + funcName: "calculateEffectiveBoundaries", + paramName: "blob", + }); + } + + const blobSize = blob.size; + + if ((end && end > blobSize) || (start && start < 0)) { + throw new WorkboxError("range-not-satisfiable", { + size: blobSize, + end, + start, + }); + } + + let effectiveStart: number; + let effectiveEnd: number; + + if (start !== undefined && end !== undefined) { + effectiveStart = start; + // Range values are inclusive, so add 1 to the value. + effectiveEnd = end + 1; + } else if (start !== undefined && end === undefined) { + effectiveStart = start; + effectiveEnd = blobSize; + } else if (end !== undefined && start === undefined) { + effectiveStart = blobSize - end; + effectiveEnd = blobSize; + } + + return { + start: effectiveStart!, + end: effectiveEnd!, + }; +} + +export { calculateEffectiveBoundaries }; diff --git a/packages/workbox-range-requests/src/utils/parseRangeHeader.ts b/packages/workbox-range-requests/src/utils/parseRangeHeader.ts new file mode 100644 index 00000000..17f99ac3 --- /dev/null +++ b/packages/workbox-range-requests/src/utils/parseRangeHeader.ts @@ -0,0 +1,57 @@ +/* + 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 { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "workbox-core/_private/assert.js"; +import "../_version.js"; + +/** + * @param {string} rangeHeader A Range: header value. + * @return {Object} An object with `start` and `end` properties, reflecting + * the parsed value of the Range: header. If either the `start` or `end` are + * omitted, then `null` will be returned. + * + * @private + */ +function parseRangeHeader(rangeHeader: string): { + start?: number; + end?: number; +} { + if (process.env.NODE_ENV !== "production") { + assert!.isType(rangeHeader, "string", { + moduleName: "workbox-range-requests", + funcName: "parseRangeHeader", + paramName: "rangeHeader", + }); + } + + const normalizedRangeHeader = rangeHeader.trim().toLowerCase(); + if (!normalizedRangeHeader.startsWith("bytes=")) { + throw new WorkboxError("unit-must-be-bytes", { normalizedRangeHeader }); + } + + // Specifying multiple ranges separate by commas is valid syntax, but this + // library only attempts to handle a single, contiguous sequence of bytes. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range#Syntax + if (normalizedRangeHeader.includes(",")) { + throw new WorkboxError("single-range-only", { normalizedRangeHeader }); + } + + const rangeParts = /(\d*)-(\d*)/.exec(normalizedRangeHeader); + // We need either at least one of the start or end values. + if (!rangeParts || !(rangeParts[1] || rangeParts[2])) { + throw new WorkboxError("invalid-range-values", { normalizedRangeHeader }); + } + + return { + start: rangeParts[1] === "" ? undefined : Number(rangeParts[1]), + end: rangeParts[2] === "" ? undefined : Number(rangeParts[2]), + }; +} + +export { parseRangeHeader }; diff --git a/packages/workbox-range-requests/tsconfig.json b/packages/workbox-range-requests/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-range-requests/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-recipes/README.md b/packages/workbox-recipes/README.md new file mode 100644 index 00000000..7c1f2728 --- /dev/null +++ b/packages/workbox-recipes/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-recipes diff --git a/packages/workbox-recipes/package.json b/packages/workbox-recipes/package.json new file mode 100644 index 00000000..c3747c84 --- /dev/null +++ b/packages/workbox-recipes/package.json @@ -0,0 +1,33 @@ +{ + "name": "@ducanh2912/workbox-recipes", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "A service worker helper library to manage common request and caching patterns", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "router", + "routing" + ], + "workbox": { + "browserNamespace": "workbox.recipes", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-cacheable-response": "workspace:*", + "@ducanh2912/workbox-core": "workspace:*", + "@ducanh2912/workbox-expiration": "workspace:*", + "@ducanh2912/workbox-precaching": "workspace:*", + "@ducanh2912/workbox-routing": "workspace:*", + "@ducanh2912/workbox-strategies": "workspace:*" + } +} diff --git a/packages/workbox-recipes/src/_version.ts b/packages/workbox-recipes/src/_version.ts new file mode 100644 index 00000000..f757abc2 --- /dev/null +++ b/packages/workbox-recipes/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:recipes:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-recipes/src/googleFontsCache.ts b/packages/workbox-recipes/src/googleFontsCache.ts new file mode 100644 index 00000000..04213339 --- /dev/null +++ b/packages/workbox-recipes/src/googleFontsCache.ts @@ -0,0 +1,64 @@ +/* + Copyright 2020 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 { registerRoute } from "workbox-routing/registerRoute.js"; +import { StaleWhileRevalidate } from "workbox-strategies/StaleWhileRevalidate.js"; +import { CacheFirst } from "workbox-strategies/CacheFirst.js"; +import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; +import { ExpirationPlugin } from "workbox-expiration/ExpirationPlugin.js"; + +import "./_version.js"; + +export interface GoogleFontCacheOptions { + cachePrefix?: string; + maxAgeSeconds?: number; + maxEntries?: number; +} + +/** + * An implementation of the [Google fonts]{@link https://developers.google.com/web/tools/workbox/guides/common-recipes#google_fonts} caching recipe + * + * @memberof workbox-recipes + * + * @param {Object} [options] + * @param {string} [options.cachePrefix] Cache prefix for caching stylesheets and webfonts. Defaults to google-fonts + * @param {number} [options.maxAgeSeconds] Maximum age, in seconds, that font entries will be cached for. Defaults to 1 year + * @param {number} [options.maxEntries] Maximum number of fonts that will be cached. Defaults to 30 + */ +function googleFontsCache(options: GoogleFontCacheOptions = {}): void { + const sheetCacheName = `${options.cachePrefix || "google-fonts"}-stylesheets`; + const fontCacheName = `${options.cachePrefix || "google-fonts"}-webfonts`; + const maxAgeSeconds = options.maxAgeSeconds || 60 * 60 * 24 * 365; + const maxEntries = options.maxEntries || 30; + + // Cache the Google Fonts stylesheets with a stale-while-revalidate strategy. + registerRoute( + ({ url }) => url.origin === "https://fonts.googleapis.com", + new StaleWhileRevalidate({ + cacheName: sheetCacheName, + }) + ); + + // Cache the underlying font files with a cache-first strategy for 1 year. + registerRoute( + ({ url }) => url.origin === "https://fonts.gstatic.com", + new CacheFirst({ + cacheName: fontCacheName, + plugins: [ + new CacheableResponsePlugin({ + statuses: [0, 200], + }), + new ExpirationPlugin({ + maxAgeSeconds, + maxEntries, + }), + ], + }) + ); +} + +export { googleFontsCache }; diff --git a/packages/workbox-recipes/src/imageCache.ts b/packages/workbox-recipes/src/imageCache.ts new file mode 100644 index 00000000..66f04d9a --- /dev/null +++ b/packages/workbox-recipes/src/imageCache.ts @@ -0,0 +1,77 @@ +/* + Copyright 2020 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 { warmStrategyCache } from "./warmStrategyCache"; +import { registerRoute } from "workbox-routing/registerRoute.js"; +import { CacheFirst } from "workbox-strategies/CacheFirst.js"; +import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; +import { ExpirationPlugin } from "workbox-expiration/ExpirationPlugin.js"; +import { + RouteMatchCallback, + RouteMatchCallbackOptions, + WorkboxPlugin, +} from "workbox-core/types.js"; + +import "./_version.js"; + +export interface ImageCacheOptions { + cacheName?: string; + matchCallback?: RouteMatchCallback; + maxAgeSeconds?: number; + maxEntries?: number; + plugins?: Array; + warmCache?: Array; +} + +/** + * An implementation of the [image caching recipe]{@link https://developers.google.com/web/tools/workbox/guides/common-recipes#caching_images} + * + * @memberof workbox-recipes + * + * @param {Object} [options] + * @param {string} [options.cacheName] Name for cache. Defaults to images + * @param {RouteMatchCallback} [options.matchCallback] Workbox callback function to call to match to. Defaults to request.destination === 'image'; + * @param {number} [options.maxAgeSeconds] Maximum age, in seconds, that font entries will be cached for. Defaults to 30 days + * @param {number} [options.maxEntries] Maximum number of images that will be cached. Defaults to 60 + * @param {WorkboxPlugin[]} [options.plugins] Additional plugins to use for this recipe + * @param {string[]} [options.warmCache] Paths to call to use to warm this cache + */ +function imageCache(options: ImageCacheOptions = {}): void { + const defaultMatchCallback = ({ request }: RouteMatchCallbackOptions) => + request.destination === "image"; + + const cacheName = options.cacheName || "images"; + const matchCallback = options.matchCallback || defaultMatchCallback; + const maxAgeSeconds = options.maxAgeSeconds || 30 * 24 * 60 * 60; + const maxEntries = options.maxEntries || 60; + const plugins = options.plugins || []; + plugins.push( + new CacheableResponsePlugin({ + statuses: [0, 200], + }) + ); + plugins.push( + new ExpirationPlugin({ + maxEntries, + maxAgeSeconds, + }) + ); + + const strategy = new CacheFirst({ + cacheName, + plugins, + }); + + registerRoute(matchCallback, strategy); + + // Warms the cache + if (options.warmCache) { + warmStrategyCache({ urls: options.warmCache, strategy }); + } +} + +export { imageCache }; diff --git a/packages/workbox-recipes/src/index.ts b/packages/workbox-recipes/src/index.ts new file mode 100644 index 00000000..879a6381 --- /dev/null +++ b/packages/workbox-recipes/src/index.ts @@ -0,0 +1,41 @@ +/* + Copyright 2020 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 { googleFontsCache, GoogleFontCacheOptions } from "./googleFontsCache"; +import { imageCache, ImageCacheOptions } from "./imageCache"; +import { + staticResourceCache, + StaticResourceOptions, +} from "./staticResourceCache"; +import { pageCache, PageCacheOptions } from "./pageCache"; +import { offlineFallback, OfflineFallbackOptions } from "./offlineFallback"; +import { + warmStrategyCache, + WarmStrategyCacheOptions, +} from "./warmStrategyCache"; + +import "./_version.js"; + +/** + * @module workbox-recipes + */ + +export { + GoogleFontCacheOptions, + googleFontsCache, + imageCache, + ImageCacheOptions, + offlineFallback, + OfflineFallbackOptions, + pageCache, + PageCacheOptions, + staticResourceCache, + StaticResourceOptions, + warmStrategyCache, + WarmStrategyCacheOptions, +}; diff --git a/packages/workbox-recipes/src/offlineFallback.ts b/packages/workbox-recipes/src/offlineFallback.ts new file mode 100644 index 00000000..29ddf016 --- /dev/null +++ b/packages/workbox-recipes/src/offlineFallback.ts @@ -0,0 +1,90 @@ +/* + Copyright 2020 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 { setCatchHandler } from "workbox-routing/setCatchHandler.js"; +import { matchPrecache } from "workbox-precaching/matchPrecache.js"; +import { + RouteHandler, + RouteHandlerCallbackOptions, +} from "workbox-core/types.js"; + +import "./_version.js"; + +export interface OfflineFallbackOptions { + pageFallback?: string; + imageFallback?: string; + fontFallback?: string; +} + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * An implementation of the [comprehensive fallbacks recipe]{@link https://developers.google.com/web/tools/workbox/guides/advanced-recipes#comprehensive_fallbacks}. Be sure to include the fallbacks in your precache injection + * + * @memberof workbox-recipes + * + * @param {Object} [options] + * @param {string} [options.pageFallback] Precache name to match for pag fallbacks. Defaults to offline.html + * @param {string} [options.imageFallback] Precache name to match for image fallbacks. + * @param {string} [options.fontFallback] Precache name to match for font fallbacks. + */ +function offlineFallback(options: OfflineFallbackOptions = {}): void { + const pageFallback = options.pageFallback || "offline.html"; + const imageFallback = options.imageFallback || false; + const fontFallback = options.fontFallback || false; + + self.addEventListener("install", (event) => { + const files = [pageFallback]; + if (imageFallback) { + files.push(imageFallback); + } + if (fontFallback) { + files.push(fontFallback); + } + + event.waitUntil( + self.caches + .open("workbox-offline-fallbacks") + .then((cache) => cache.addAll(files)) + ); + }); + + const handler: RouteHandler = async ( + options: RouteHandlerCallbackOptions + ) => { + const dest = options.request.destination; + const cache = await self.caches.open("workbox-offline-fallbacks"); + + if (dest === "document") { + const match = + (await matchPrecache(pageFallback)) || + (await cache.match(pageFallback)); + return match || Response.error(); + } + + if (dest === "image" && imageFallback !== false) { + const match = + (await matchPrecache(imageFallback)) || + (await cache.match(imageFallback)); + return match || Response.error(); + } + + if (dest === "font" && fontFallback !== false) { + const match = + (await matchPrecache(fontFallback)) || + (await cache.match(fontFallback)); + return match || Response.error(); + } + + return Response.error(); + }; + + setCatchHandler(handler); +} + +export { offlineFallback }; diff --git a/packages/workbox-recipes/src/pageCache.ts b/packages/workbox-recipes/src/pageCache.ts new file mode 100644 index 00000000..4190fe91 --- /dev/null +++ b/packages/workbox-recipes/src/pageCache.ts @@ -0,0 +1,69 @@ +/* + Copyright 2020 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 { warmStrategyCache } from "./warmStrategyCache"; +import { registerRoute } from "workbox-routing/registerRoute.js"; +import { NetworkFirst } from "workbox-strategies/NetworkFirst.js"; +import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; +import { + RouteMatchCallback, + RouteMatchCallbackOptions, + WorkboxPlugin, +} from "workbox-core/types.js"; + +import "./_version.js"; + +export interface PageCacheOptions { + cacheName?: string; + matchCallback?: RouteMatchCallback; + networkTimeoutSeconds?: number; + plugins?: Array; + warmCache?: Array; +} + +/** + * An implementation of a page caching recipe with a network timeout + * + * @memberof workbox-recipes + * + * @param {Object} [options] + * @param {string} [options.cacheName] Name for cache. Defaults to pages + * @param {RouteMatchCallback} [options.matchCallback] Workbox callback function to call to match to. Defaults to request.mode === 'navigate'; + * @param {number} [options.networkTimoutSeconds] Maximum amount of time, in seconds, to wait on the network before falling back to cache. Defaults to 3 + * @param {WorkboxPlugin[]} [options.plugins] Additional plugins to use for this recipe + * @param {string[]} [options.warmCache] Paths to call to use to warm this cache + */ +function pageCache(options: PageCacheOptions = {}): void { + const defaultMatchCallback = ({ request }: RouteMatchCallbackOptions) => + request.mode === "navigate"; + + const cacheName = options.cacheName || "pages"; + const matchCallback = options.matchCallback || defaultMatchCallback; + const networkTimeoutSeconds = options.networkTimeoutSeconds || 3; + const plugins = options.plugins || []; + plugins.push( + new CacheableResponsePlugin({ + statuses: [0, 200], + }) + ); + + const strategy = new NetworkFirst({ + networkTimeoutSeconds, + cacheName, + plugins, + }); + + // Registers the route + registerRoute(matchCallback, strategy); + + // Warms the cache + if (options.warmCache) { + warmStrategyCache({ urls: options.warmCache, strategy }); + } +} + +export { pageCache }; diff --git a/packages/workbox-recipes/src/staticResourceCache.ts b/packages/workbox-recipes/src/staticResourceCache.ts new file mode 100644 index 00000000..118eeff8 --- /dev/null +++ b/packages/workbox-recipes/src/staticResourceCache.ts @@ -0,0 +1,66 @@ +/* + Copyright 2020 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 { warmStrategyCache } from "./warmStrategyCache"; +import { registerRoute } from "workbox-routing/registerRoute.js"; +import { StaleWhileRevalidate } from "workbox-strategies/StaleWhileRevalidate.js"; +import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; +import { + RouteMatchCallback, + RouteMatchCallbackOptions, + WorkboxPlugin, +} from "workbox-core/types.js"; + +import "./_version.js"; + +export interface StaticResourceOptions { + cacheName?: string; + matchCallback?: RouteMatchCallback; + plugins?: Array; + warmCache?: Array; +} + +/** + * An implementation of the [CSS and JavaScript files recipe]{@link https://developers.google.com/web/tools/workbox/guides/common-recipes#cache_css_and_javascript_files} + * + * @memberof workbox-recipes + * + * @param {Object} [options] + * @param {string} [options.cacheName] Name for cache. Defaults to static-resources + * @param {RouteMatchCallback} [options.matchCallback] Workbox callback function to call to match to. Defaults to request.destination === 'style' || request.destination === 'script' || request.destination === 'worker'; + * @param {WorkboxPlugin[]} [options.plugins] Additional plugins to use for this recipe + * @param {string[]} [options.warmCache] Paths to call to use to warm this cache + */ +function staticResourceCache(options: StaticResourceOptions = {}): void { + const defaultMatchCallback = ({ request }: RouteMatchCallbackOptions) => + request.destination === "style" || + request.destination === "script" || + request.destination === "worker"; + + const cacheName = options.cacheName || "static-resources"; + const matchCallback = options.matchCallback || defaultMatchCallback; + const plugins = options.plugins || []; + plugins.push( + new CacheableResponsePlugin({ + statuses: [0, 200], + }) + ); + + const strategy = new StaleWhileRevalidate({ + cacheName, + plugins, + }); + + registerRoute(matchCallback, strategy); + + // Warms the cache + if (options.warmCache) { + warmStrategyCache({ urls: options.warmCache, strategy }); + } +} + +export { staticResourceCache }; diff --git a/packages/workbox-recipes/src/warmStrategyCache.ts b/packages/workbox-recipes/src/warmStrategyCache.ts new file mode 100644 index 00000000..bf6a4dc5 --- /dev/null +++ b/packages/workbox-recipes/src/warmStrategyCache.ts @@ -0,0 +1,34 @@ +import { Strategy } from "workbox-strategies/Strategy.js"; + +import "./_version.js"; + +export interface WarmStrategyCacheOptions { + urls: Array; + strategy: Strategy; +} + +// Give TypeScript the correct global. +declare let self: ServiceWorkerGlobalScope; + +/** + * @memberof workbox-recipes + + * @param {Object} options + * @param {string[]} options.urls Paths to warm the strategy's cache with + * @param {Strategy} options.strategy Strategy to use + */ +function warmStrategyCache(options: WarmStrategyCacheOptions): void { + self.addEventListener("install", (event) => { + const done = options.urls.map( + (path) => + options.strategy.handleAll({ + event, + request: new Request(path), + })[1] + ); + + event.waitUntil(Promise.all(done)); + }); +} + +export { warmStrategyCache }; diff --git a/packages/workbox-recipes/tsconfig.json b/packages/workbox-recipes/tsconfig.json new file mode 100644 index 00000000..22f8f82b --- /dev/null +++ b/packages/workbox-recipes/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [ + {"path": "../workbox-core/"}, + {"path": "../workbox-routing/"}, + {"path": "../workbox-strategies/"}, + {"path": "../workbox-cacheable-response/"}, + {"path": "../workbox-expiration/"}, + {"path": "../workbox-precaching/"} + ] +} diff --git a/packages/workbox-routing/README.md b/packages/workbox-routing/README.md new file mode 100644 index 00000000..0c19ecc1 --- /dev/null +++ b/packages/workbox-routing/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-routing diff --git a/packages/workbox-routing/package.json b/packages/workbox-routing/package.json new file mode 100644 index 00000000..03ee396b --- /dev/null +++ b/packages/workbox-routing/package.json @@ -0,0 +1,28 @@ +{ + "name": "@ducanh2912/workbox-routing", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "A service worker helper library to route request URLs to handlers.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "router", + "routing" + ], + "workbox": { + "browserNamespace": "workbox.routing", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*" + } +} diff --git a/packages/workbox-routing/src/NavigationRoute.ts b/packages/workbox-routing/src/NavigationRoute.ts new file mode 100644 index 00000000..a1fc9f63 --- /dev/null +++ b/packages/workbox-routing/src/NavigationRoute.ts @@ -0,0 +1,143 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { RouteHandler, RouteMatchCallbackOptions } from "workbox-core/types.js"; + +import { Route } from "./Route.js"; + +import "./_version.js"; + +export interface NavigationRouteMatchOptions { + allowlist?: RegExp[]; + denylist?: RegExp[]; +} + +/** + * NavigationRoute makes it easy to create a + * {@link workbox-routing.Route} that matches for browser + * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}. + * + * It will only match incoming Requests whose + * {@link https://fetch.spec.whatwg.org/#concept-request-mode|mode} + * is set to `navigate`. + * + * You can optionally only apply this route to a subset of navigation requests + * by using one or both of the `denylist` and `allowlist` parameters. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ +class NavigationRoute extends Route { + private readonly _allowlist: RegExp[]; + private readonly _denylist: RegExp[]; + + /** + * If both `denylist` and `allowlist` are provided, the `denylist` will + * take precedence and the request will not match this route. + * + * The regular expressions in `allowlist` and `denylist` + * are matched against the concatenated + * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname} + * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search} + * portions of the requested URL. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {Object} options + * @param {Array} [options.denylist] If any of these patterns match, + * the route will not handle the request (even if a allowlist RegExp matches). + * @param {Array} [options.allowlist=[/./]] If any of these patterns + * match the URL's pathname and search parameter, the route will handle the + * request (assuming the denylist doesn't match). + */ + constructor( + handler: RouteHandler, + { allowlist = [/./], denylist = [] }: NavigationRouteMatchOptions = {} + ) { + if (process.env.NODE_ENV !== "production") { + assert!.isArrayOfClass(allowlist, RegExp, { + moduleName: "workbox-routing", + className: "NavigationRoute", + funcName: "constructor", + paramName: "options.allowlist", + }); + assert!.isArrayOfClass(denylist, RegExp, { + moduleName: "workbox-routing", + className: "NavigationRoute", + funcName: "constructor", + paramName: "options.denylist", + }); + } + + super( + (options: RouteMatchCallbackOptions) => this._match(options), + handler + ); + + this._allowlist = allowlist; + this._denylist = denylist; + } + + /** + * Routes match handler. + * + * @param {Object} options + * @param {URL} options.url + * @param {Request} options.request + * @return {boolean} + * + * @private + */ + private _match({ url, request }: RouteMatchCallbackOptions): boolean { + if (request && request.mode !== "navigate") { + return false; + } + + const pathnameAndSearch = url.pathname + url.search; + + for (const regExp of this._denylist) { + if (regExp.test(pathnameAndSearch)) { + if (process.env.NODE_ENV !== "production") { + logger.log( + `The navigation route ${pathnameAndSearch} is not ` + + `being used, since the URL matches this denylist pattern: ` + + `${regExp.toString()}` + ); + } + return false; + } + } + + if (this._allowlist.some((regExp) => regExp.test(pathnameAndSearch))) { + if (process.env.NODE_ENV !== "production") { + logger.debug( + `The navigation route ${pathnameAndSearch} ` + `is being used.` + ); + } + return true; + } + + if (process.env.NODE_ENV !== "production") { + logger.log( + `The navigation route ${pathnameAndSearch} is not ` + + `being used, since the URL being navigated to doesn't ` + + `match the allowlist.` + ); + } + return false; + } +} + +export { NavigationRoute }; diff --git a/packages/workbox-routing/src/RegExpRoute.ts b/packages/workbox-routing/src/RegExpRoute.ts new file mode 100644 index 00000000..5480377e --- /dev/null +++ b/packages/workbox-routing/src/RegExpRoute.ts @@ -0,0 +1,92 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { + RouteHandler, + RouteMatchCallback, + RouteMatchCallbackOptions, +} from "workbox-core/types.js"; + +import { HTTPMethod } from "./utils/constants.js"; +import { Route } from "./Route.js"; + +import "./_version.js"; + +/** + * RegExpRoute makes it easy to create a regular expression based + * {@link workbox-routing.Route}. + * + * For same-origin requests the RegExp only needs to match part of the URL. For + * requests against third-party servers, you must define a RegExp that matches + * the start of the URL. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ +class RegExpRoute extends Route { + /** + * If the regular expression contains + * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references}, + * the captured values will be passed to the + * {@link workbox-routing~handlerCallback} `params` + * argument. + * + * @param {RegExp} regExp The regular expression to match against URLs. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(regExp, RegExp, { + moduleName: "workbox-routing", + className: "RegExpRoute", + funcName: "constructor", + paramName: "pattern", + }); + } + + const match: RouteMatchCallback = ({ url }: RouteMatchCallbackOptions) => { + const result = regExp.exec(url.href); + + // Return immediately if there's no match. + if (!result) { + return; + } + + // Require that the match start at the first character in the URL string + // if it's a cross-origin request. + // See https://github.com/GoogleChrome/workbox/issues/281 for the context + // behind this behavior. + if (url.origin !== location.origin && result.index !== 0) { + if (process.env.NODE_ENV !== "production") { + logger.debug( + `The regular expression '${regExp.toString()}' only partially matched ` + + `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` + + `handle cross-origin requests if they match the entire URL.` + ); + } + + return; + } + + // If the route matches, but there aren't any capture groups defined, then + // this will return [], which is truthy and therefore sufficient to + // indicate a match. + // If there are capture groups, then it will return their values. + return result.slice(1); + }; + + super(match, handler, method); + } +} + +export { RegExpRoute }; diff --git a/packages/workbox-routing/src/Route.ts b/packages/workbox-routing/src/Route.ts new file mode 100644 index 00000000..3866279a --- /dev/null +++ b/packages/workbox-routing/src/Route.ts @@ -0,0 +1,80 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { HTTPMethod, defaultMethod, validMethods } from "./utils/constants.js"; +import { normalizeHandler } from "./utils/normalizeHandler.js"; +import { + RouteHandler, + RouteHandlerObject, + RouteMatchCallback, +} from "workbox-core/types.js"; +import "./_version.js"; + +/** + * A `Route` consists of a pair of callback functions, "match" and "handler". + * The "match" callback determine if a route should be used to "handle" a + * request by returning a non-falsy value if it can. The "handler" callback + * is called when there is a match and should return a Promise that resolves + * to a `Response`. + * + * @memberof workbox-routing + */ +class Route { + handler: RouteHandlerObject; + match: RouteMatchCallback; + method: HTTPMethod; + catchHandler?: RouteHandlerObject; + + /** + * Constructor for Route class. + * + * @param {workbox-routing~matchCallback} match + * A callback function that determines whether the route matches a given + * `fetch` event by returning a non-falsy value. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resolving to a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor( + match: RouteMatchCallback, + handler: RouteHandler, + method: HTTPMethod = defaultMethod + ) { + if (process.env.NODE_ENV !== "production") { + assert!.isType(match, "function", { + moduleName: "workbox-routing", + className: "Route", + funcName: "constructor", + paramName: "match", + }); + + if (method) { + assert!.isOneOf(method, validMethods, { paramName: "method" }); + } + } + + // These values are referenced directly by Router so cannot be + // altered by minificaton. + this.handler = normalizeHandler(handler); + this.match = match; + this.method = method; + } + + /** + * + * @param {workbox-routing-handlerCallback} handler A callback + * function that returns a Promise resolving to a Response + */ + setCatchHandler(handler: RouteHandler): void { + this.catchHandler = normalizeHandler(handler); + } +} + +export { Route }; diff --git a/packages/workbox-routing/src/Router.ts b/packages/workbox-routing/src/Router.ts new file mode 100644 index 00000000..23148c3e --- /dev/null +++ b/packages/workbox-routing/src/Router.ts @@ -0,0 +1,487 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { + RouteHandler, + RouteHandlerObject, + RouteHandlerCallbackOptions, + RouteMatchCallbackOptions, +} from "workbox-core/types.js"; +import { HTTPMethod, defaultMethod } from "./utils/constants.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { normalizeHandler } from "./utils/normalizeHandler.js"; +import { Route } from "./Route.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import "./_version.js"; + +type RequestArgs = string | [string, RequestInit?]; + +interface CacheURLsMessageData { + type: string; + payload: { + urlsToCache: RequestArgs[]; + }; +} + +/** + * The Router can be used to process a `FetchEvent` using one or more + * {@link workbox-routing.Route}, responding with a `Response` if + * a matching route exists. + * + * If no route matches a given a request, the Router will use a "default" + * handler if one is defined. + * + * Should the matching Route throw an error, the Router will use a "catch" + * handler if one is defined to gracefully deal with issues and respond with a + * Request. + * + * If a request matches multiple routes, the **earliest** registered route will + * be used to respond to the request. + * + * @memberof workbox-routing + */ +class Router { + private readonly _routes: Map; + private readonly _defaultHandlerMap: Map; + private _catchHandler?: RouteHandlerObject; + + /** + * Initializes a new Router. + */ + constructor() { + this._routes = new Map(); + this._defaultHandlerMap = new Map(); + } + + /** + * @return {Map>} routes A `Map` of HTTP + * method name ('GET', etc.) to an array of all the corresponding `Route` + * instances that are registered. + */ + get routes(): Map { + return this._routes; + } + + /** + * Adds a fetch event listener to respond to events when a route matches + * the event's request. + */ + addFetchListener(): void { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener("fetch", ((event: FetchEvent) => { + const { request } = event; + const responsePromise = this.handleRequest({ request, event }); + if (responsePromise) { + event.respondWith(responsePromise); + } + }) as EventListener); + } + + /** + * Adds a message event listener for URLs to cache from the window. + * This is useful to cache resources loaded on the page prior to when the + * service worker started controlling it. + * + * The format of the message data sent from the window should be as follows. + * Where the `urlsToCache` array may consist of URL strings or an array of + * URL string + `requestInit` object (the same as you'd pass to `fetch()`). + * + * ``` + * { + * type: 'CACHE_URLS', + * payload: { + * urlsToCache: [ + * './script1.js', + * './script2.js', + * ['./script3.js', {mode: 'no-cors'}], + * ], + * }, + * } + * ``` + */ + addCacheListener(): void { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener("message", ((event: ExtendableMessageEvent) => { + // event.data is type 'any' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.data && event.data.type === "CACHE_URLS") { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { payload }: CacheURLsMessageData = event.data; + + if (process.env.NODE_ENV !== "production") { + logger.debug(`Caching URLs from the window`, payload.urlsToCache); + } + + const requestPromises = Promise.all( + payload.urlsToCache.map((entry: string | [string, RequestInit?]) => { + if (typeof entry === "string") { + entry = [entry]; + } + + const request = new Request(...entry); + return this.handleRequest({ request, event }); + + // TODO(philipwalton): TypeScript errors without this typecast for + // some reason (probably a bug). The real type here should work but + // doesn't: `Array | undefined>`. + }) as any[] + ); // TypeScript + + event.waitUntil(requestPromises); + + // If a MessageChannel was used, reply to the message on success. + if (event.ports && event.ports[0]) { + void requestPromises.then(() => event.ports[0].postMessage(true)); + } + } + }) as EventListener); + } + + /** + * Apply the routing rules to a FetchEvent object to get a Response from an + * appropriate Route's handler. + * + * @param {Object} options + * @param {Request} options.request The request to handle. + * @param {ExtendableEvent} options.event The event that triggered the + * request. + * @return {Promise|undefined} A promise is returned if a + * registered route can handle the request. If there is no matching + * route and there's no `defaultHandler`, `undefined` is returned. + */ + handleRequest({ + request, + event, + }: { + request: Request; + event: ExtendableEvent; + }): Promise | undefined { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-routing", + className: "Router", + funcName: "handleRequest", + paramName: "options.request", + }); + } + + const url = new URL(request.url, location.href); + if (!url.protocol.startsWith("http")) { + if (process.env.NODE_ENV !== "production") { + logger.debug( + `Workbox Router only supports URLs that start with 'http'.` + ); + } + return; + } + + const sameOrigin = url.origin === location.origin; + const { params, route } = this.findMatchingRoute({ + event, + request, + sameOrigin, + url, + }); + let handler = route && route.handler; + + const debugMessages = []; + if (process.env.NODE_ENV !== "production") { + if (handler) { + debugMessages.push([`Found a route to handle this request:`, route]); + + if (params) { + debugMessages.push([ + `Passing the following params to the route's handler:`, + params, + ]); + } + } + } + + // If we don't have a handler because there was no matching route, then + // fall back to defaultHandler if that's defined. + const method = request.method as HTTPMethod; + if (!handler && this._defaultHandlerMap.has(method)) { + if (process.env.NODE_ENV !== "production") { + debugMessages.push( + `Failed to find a matching route. Falling ` + + `back to the default handler for ${method}.` + ); + } + handler = this._defaultHandlerMap.get(method); + } + + if (!handler) { + if (process.env.NODE_ENV !== "production") { + // No handler so Workbox will do nothing. If logs is set of debug + // i.e. verbose, we should print out this information. + logger.debug(`No route found for: ${getFriendlyURL(url)}`); + } + return; + } + + if (process.env.NODE_ENV !== "production") { + // We have a handler, meaning Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`); + + debugMessages.forEach((msg) => { + if (Array.isArray(msg)) { + logger.log(...msg); + } else { + logger.log(msg); + } + }); + + logger.groupEnd(); + } + + // Wrap in try and catch in case the handle method throws a synchronous + // error. It should still callback to the catch handler. + let responsePromise; + try { + responsePromise = handler.handle({ url, request, event, params }); + } catch (err) { + responsePromise = Promise.reject(err); + } + + // Get route's catch handler, if it exists + const catchHandler = route && route.catchHandler; + + if ( + responsePromise instanceof Promise && + (this._catchHandler || catchHandler) + ) { + responsePromise = responsePromise.catch(async (err) => { + // If there's a route catch handler, process that first + if (catchHandler) { + if (process.env.NODE_ENV !== "production") { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed( + `Error thrown when responding to: ` + + ` ${getFriendlyURL( + url + )}. Falling back to route's Catch Handler.` + ); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + + try { + return await catchHandler.handle({ url, request, event, params }); + } catch (catchErr) { + if (catchErr instanceof Error) { + err = catchErr; + } + } + } + + if (this._catchHandler) { + if (process.env.NODE_ENV !== "production") { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed( + `Error thrown when responding to: ` + + ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.` + ); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + return this._catchHandler.handle({ url, request, event }); + } + + throw err; + }); + } + + return responsePromise; + } + + /** + * Checks a request and URL (and optionally an event) against the list of + * registered routes, and if there's a match, returns the corresponding + * route along with any params generated by the match. + * + * @param {Object} options + * @param {URL} options.url + * @param {boolean} options.sameOrigin The result of comparing `url.origin` + * against the current origin. + * @param {Request} options.request The request to match. + * @param {Event} options.event The corresponding event. + * @return {Object} An object with `route` and `params` properties. + * They are populated if a matching route was found or `undefined` + * otherwise. + */ + findMatchingRoute({ + url, + sameOrigin, + request, + event, + }: RouteMatchCallbackOptions): { + route?: Route; + params?: RouteHandlerCallbackOptions["params"]; + } { + const routes = this._routes.get(request.method as HTTPMethod) || []; + for (const route of routes) { + let params: Promise | undefined; + // route.match returns type any, not possible to change right now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const matchResult = route.match({ url, sameOrigin, request, event }); + if (matchResult) { + if (process.env.NODE_ENV !== "production") { + // Warn developers that using an async matchCallback is almost always + // not the right thing to do. + if (matchResult instanceof Promise) { + logger.warn( + `While routing ${getFriendlyURL(url)}, an async ` + + `matchCallback function was used. Please convert the ` + + `following route to use a synchronous matchCallback function:`, + route + ); + } + } + + // See https://github.com/GoogleChrome/workbox/issues/2079 + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + params = matchResult; + if (Array.isArray(params) && params.length === 0) { + // Instead of passing an empty array in as params, use undefined. + params = undefined; + } else if ( + matchResult.constructor === Object && // eslint-disable-line + Object.keys(matchResult).length === 0 + ) { + // Instead of passing an empty object in as params, use undefined. + params = undefined; + } else if (typeof matchResult === "boolean") { + // For the boolean value true (rather than just something truth-y), + // don't set params. + // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353 + params = undefined; + } + + // Return early if have a match. + return { route, params }; + } + } + // If no match was found above, return and empty object. + return {}; + } + + /** + * Define a default `handler` that's called when no routes explicitly + * match the incoming request. + * + * Each HTTP method ('GET', 'POST', etc.) gets its own default handler. + * + * Without a default handler, unmatched requests will go against the + * network as if there were no service worker present. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to associate with this + * default handler. Each method has its own default. + */ + setDefaultHandler( + handler: RouteHandler, + method: HTTPMethod = defaultMethod + ): void { + this._defaultHandlerMap.set(method, normalizeHandler(handler)); + } + + /** + * If a Route throws an error while handling a request, this `handler` + * will be called and given a chance to provide a response. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + */ + setCatchHandler(handler: RouteHandler): void { + this._catchHandler = normalizeHandler(handler); + } + + /** + * Registers a route with the router. + * + * @param {workbox-routing.Route} route The route to register. + */ + registerRoute(route: Route): void { + if (process.env.NODE_ENV !== "production") { + assert!.isType(route, "object", { + moduleName: "workbox-routing", + className: "Router", + funcName: "registerRoute", + paramName: "route", + }); + + assert!.hasMethod(route, "match", { + moduleName: "workbox-routing", + className: "Router", + funcName: "registerRoute", + paramName: "route", + }); + + assert!.isType(route.handler, "object", { + moduleName: "workbox-routing", + className: "Router", + funcName: "registerRoute", + paramName: "route", + }); + + assert!.hasMethod(route.handler, "handle", { + moduleName: "workbox-routing", + className: "Router", + funcName: "registerRoute", + paramName: "route.handler", + }); + + assert!.isType(route.method, "string", { + moduleName: "workbox-routing", + className: "Router", + funcName: "registerRoute", + paramName: "route.method", + }); + } + + if (!this._routes.has(route.method)) { + this._routes.set(route.method, []); + } + + // Give precedence to all of the earlier routes by adding this additional + // route to the end of the array. + this._routes.get(route.method)!.push(route); + } + + /** + * Unregisters a route with the router. + * + * @param {workbox-routing.Route} route The route to unregister. + */ + unregisterRoute(route: Route): void { + if (!this._routes.has(route.method)) { + throw new WorkboxError("unregister-route-but-not-found-with-method", { + method: route.method, + }); + } + + const routeIndex = this._routes.get(route.method)!.indexOf(route); + if (routeIndex > -1) { + this._routes.get(route.method)!.splice(routeIndex, 1); + } else { + throw new WorkboxError("unregister-route-route-not-registered"); + } + } +} + +export { Router }; diff --git a/packages/workbox-routing/src/_types.ts b/packages/workbox-routing/src/_types.ts new file mode 100644 index 00000000..2cb6f534 --- /dev/null +++ b/packages/workbox-routing/src/_types.ts @@ -0,0 +1,66 @@ +/* + 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 "./_version.js"; + +// * * * IMPORTANT! * * * +// ------------------------------------------------------------------------- // +// jdsoc type definitions cannot be declared above TypeScript definitions or +// they'll be stripped from the built `.js` files, and they'll only be in the +// `d.ts` files, which aren't read by the jsdoc generator. As a result we +// have to put declare them below. + +/** + * The "match" callback is used to determine if a `Route` should apply for a + * particular URL. When matching occurs in response to a fetch event from the + * client, the `event` object is supplied in addition to the `url`, `request`, + * and `sameOrigin` value. However, since the match callback can be invoked + * outside of a fetch event, matching logic should not assume the `event` + * object will always be available. + * + * If the match callback returns a truthy value, the matching route's + * {@link workbox-routing~handlerCallback} will be + * invoked immediately. If the value returned is a non-empty array or object, + * that value will be set on the handler's `context.params` argument. + * + * @callback ~matchCallback + * @param {Object} context + * @param {Request} context.request The corresponding request. + * @param {URL} context.url The request's URL. + * @param {ExtendableEvent} context.event The corresponding event that triggered + * the request. + * @param {boolean} context.sameOrigin The result of comparing `url.origin` + * against the current origin. + * @return {*} To signify a match, return a truthy value. + * + * @memberof workbox-routing + */ + +/** + * The "handler" callback is invoked whenever a `Router` matches a URL to a + * `Route` via its {@link workbox-routing~matchCallback} + * callback. This callback should return a Promise that resolves with a + * `Response`. + * + * If a non-empty array or object is returned by the + * {@link workbox-routing~matchCallback} it + * will be passed in as the handler's `context.params` argument. + * + * @callback ~handlerCallback + * @param {Object} context + * @param {Request|string} context.request The corresponding request. + * @param {URL} context.url The URL that matched, if available. + * @param {ExtendableEvent} context.event The corresponding event that triggered + * the request. + * @param {Object} [context.params] Array or Object parameters returned by the + * Route's {@link workbox-routing~matchCallback}. + * This will be undefined if an empty array or object were returned. + * @return {Promise} The response that will fulfill the request. + * + * @memberof workbox-routing + */ diff --git a/packages/workbox-routing/src/_version.ts b/packages/workbox-routing/src/_version.ts new file mode 100644 index 00000000..2c4e47c9 --- /dev/null +++ b/packages/workbox-routing/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:routing:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-routing/src/index.ts b/packages/workbox-routing/src/index.ts new file mode 100644 index 00000000..389b313e --- /dev/null +++ b/packages/workbox-routing/src/index.ts @@ -0,0 +1,35 @@ +/* + 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 { + NavigationRoute, + NavigationRouteMatchOptions, +} from "./NavigationRoute.js"; +import { RegExpRoute } from "./RegExpRoute.js"; +import { registerRoute } from "./registerRoute.js"; +import { Route } from "./Route.js"; +import { Router } from "./Router.js"; +import { setCatchHandler } from "./setCatchHandler.js"; +import { setDefaultHandler } from "./setDefaultHandler.js"; + +import "./_version.js"; + +/** + * @module workbox-routing + */ + +export { + NavigationRoute, + RegExpRoute, + registerRoute, + Route, + Router, + setCatchHandler, + setDefaultHandler, + NavigationRouteMatchOptions, +}; diff --git a/packages/workbox-routing/src/registerRoute.ts b/packages/workbox-routing/src/registerRoute.ts new file mode 100644 index 00000000..97bdb68c --- /dev/null +++ b/packages/workbox-routing/src/registerRoute.ts @@ -0,0 +1,115 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { RouteHandler, RouteMatchCallback } from "workbox-core/types.js"; + +import { Route } from "./Route.js"; +import { RegExpRoute } from "./RegExpRoute.js"; +import { HTTPMethod } from "./utils/constants.js"; +import { getOrCreateDefaultRouter } from "./utils/getOrCreateDefaultRouter.js"; + +import "./_version.js"; + +/** + * Easily register a RegExp, string, or function with a caching + * strategy to a singleton Router instance. + * + * This method will generate a Route for you if needed and + * call {@link workbox-routing.Router#registerRoute}. + * + * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture + * If the capture param is a `Route`, all other arguments will be ignored. + * @param {workbox-routing~handlerCallback} [handler] A callback + * function that returns a Promise resulting in a Response. This parameter + * is required if `capture` is not a `Route` object. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + * @return {workbox-routing.Route} The generated `Route`. + * + * @memberof workbox-routing + */ +function registerRoute( + capture: RegExp | string | RouteMatchCallback | Route, + handler?: RouteHandler, + method?: HTTPMethod +): Route { + let route; + + if (typeof capture === "string") { + const captureUrl = new URL(capture, location.href); + + if (process.env.NODE_ENV !== "production") { + if (!(capture.startsWith("/") || capture.startsWith("http"))) { + throw new WorkboxError("invalid-string", { + moduleName: "workbox-routing", + funcName: "registerRoute", + paramName: "capture", + }); + } + + // We want to check if Express-style wildcards are in the pathname only. + // TODO: Remove this log message in v4. + const valueToCheck = capture.startsWith("http") + ? captureUrl.pathname + : capture; + + // See https://github.com/pillarjs/path-to-regexp#parameters + const wildcards = "[*:?+]"; + if (new RegExp(`${wildcards}`).exec(valueToCheck)) { + logger.debug( + `The '$capture' parameter contains an Express-style wildcard ` + + `character (${wildcards}). Strings are now always interpreted as ` + + `exact matches; use a RegExp for partial or wildcard matches.` + ); + } + } + + const matchCallback: RouteMatchCallback = ({ url }) => { + if (process.env.NODE_ENV !== "production") { + if ( + url.pathname === captureUrl.pathname && + url.origin !== captureUrl.origin + ) { + logger.debug( + `${capture} only partially matches the cross-origin URL ` + + `${url.toString()}. This route will only handle cross-origin requests ` + + `if they match the entire URL.` + ); + } + } + + return url.href === captureUrl.href; + }; + + // If `capture` is a string then `handler` and `method` must be present. + route = new Route(matchCallback, handler!, method); + } else if (capture instanceof RegExp) { + // If `capture` is a `RegExp` then `handler` and `method` must be present. + route = new RegExpRoute(capture, handler!, method); + } else if (typeof capture === "function") { + // If `capture` is a function then `handler` and `method` must be present. + route = new Route(capture, handler!, method); + } else if (capture instanceof Route) { + route = capture; + } else { + throw new WorkboxError("unsupported-route-type", { + moduleName: "workbox-routing", + funcName: "registerRoute", + paramName: "capture", + }); + } + + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.registerRoute(route); + + return route; +} + +export { registerRoute }; diff --git a/packages/workbox-routing/src/setCatchHandler.ts b/packages/workbox-routing/src/setCatchHandler.ts new file mode 100644 index 00000000..24d586cd --- /dev/null +++ b/packages/workbox-routing/src/setCatchHandler.ts @@ -0,0 +1,29 @@ +/* + 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 { RouteHandler } from "workbox-core/types.js"; + +import { getOrCreateDefaultRouter } from "./utils/getOrCreateDefaultRouter.js"; + +import "./_version.js"; + +/** + * If a Route throws an error while handling a request, this `handler` + * will be called and given a chance to provide a response. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * + * @memberof workbox-routing + */ +function setCatchHandler(handler: RouteHandler): void { + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.setCatchHandler(handler); +} + +export { setCatchHandler }; diff --git a/packages/workbox-routing/src/setDefaultHandler.ts b/packages/workbox-routing/src/setDefaultHandler.ts new file mode 100644 index 00000000..a125ef44 --- /dev/null +++ b/packages/workbox-routing/src/setDefaultHandler.ts @@ -0,0 +1,32 @@ +/* + 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 { RouteHandler } from "workbox-core/types.js"; + +import { getOrCreateDefaultRouter } from "./utils/getOrCreateDefaultRouter.js"; + +import "./_version.js"; + +/** + * Define a default `handler` that's called when no routes explicitly + * match the incoming request. + * + * Without a default handler, unmatched requests will go against the + * network as if there were no service worker present. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * + * @memberof workbox-routing + */ +function setDefaultHandler(handler: RouteHandler): void { + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.setDefaultHandler(handler); +} + +export { setDefaultHandler }; diff --git a/packages/workbox-routing/src/utils/constants.ts b/packages/workbox-routing/src/utils/constants.ts new file mode 100644 index 00000000..34197f4c --- /dev/null +++ b/packages/workbox-routing/src/utils/constants.ts @@ -0,0 +1,37 @@ +/* + 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 "../_version.js"; + +export type HTTPMethod = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT"; + +/** + * The default HTTP method, 'GET', used when there's no specific method + * configured for a route. + * + * @type {string} + * + * @private + */ +export const defaultMethod: HTTPMethod = "GET"; + +/** + * The list of valid HTTP methods associated with requests that could be routed. + * + * @type {Array} + * + * @private + */ +export const validMethods: HTTPMethod[] = [ + "DELETE", + "GET", + "HEAD", + "PATCH", + "POST", + "PUT", +]; diff --git a/packages/workbox-routing/src/utils/getOrCreateDefaultRouter.ts b/packages/workbox-routing/src/utils/getOrCreateDefaultRouter.ts new file mode 100644 index 00000000..2c808787 --- /dev/null +++ b/packages/workbox-routing/src/utils/getOrCreateDefaultRouter.ts @@ -0,0 +1,30 @@ +/* + 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 { Router } from "../Router.js"; +import "../_version.js"; + +let defaultRouter: Router; + +/** + * Creates a new, singleton Router instance if one does not exist. If one + * does already exist, that instance is returned. + * + * @private + * @return {Router} + */ +export const getOrCreateDefaultRouter = (): Router => { + if (!defaultRouter) { + defaultRouter = new Router(); + + // The helpers that use the default Router assume these listeners exist. + defaultRouter.addFetchListener(); + defaultRouter.addCacheListener(); + } + return defaultRouter; +}; diff --git a/packages/workbox-routing/src/utils/normalizeHandler.ts b/packages/workbox-routing/src/utils/normalizeHandler.ts new file mode 100644 index 00000000..8924ce51 --- /dev/null +++ b/packages/workbox-routing/src/utils/normalizeHandler.ts @@ -0,0 +1,43 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { RouteHandler, RouteHandlerObject } from "workbox-core/types.js"; + +import "../_version.js"; + +/** + * @param {function()|Object} handler Either a function, or an object with a + * 'handle' method. + * @return {Object} An object with a handle method. + * + * @private + */ +export const normalizeHandler = (handler: RouteHandler): RouteHandlerObject => { + if (handler && typeof handler === "object") { + if (process.env.NODE_ENV !== "production") { + assert!.hasMethod(handler, "handle", { + moduleName: "workbox-routing", + className: "Route", + funcName: "constructor", + paramName: "handler", + }); + } + return handler; + } else { + if (process.env.NODE_ENV !== "production") { + assert!.isType(handler, "function", { + moduleName: "workbox-routing", + className: "Route", + funcName: "constructor", + paramName: "handler", + }); + } + return { handle: handler }; + } +}; diff --git a/packages/workbox-routing/tsconfig.json b/packages/workbox-routing/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-routing/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-strategies/README.md b/packages/workbox-strategies/README.md new file mode 100644 index 00000000..d1a5ec5b --- /dev/null +++ b/packages/workbox-strategies/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-strategies diff --git a/packages/workbox-strategies/package.json b/packages/workbox-strategies/package.json new file mode 100644 index 00000000..e17efdb5 --- /dev/null +++ b/packages/workbox-strategies/package.json @@ -0,0 +1,28 @@ +{ + "name": "@ducanh2912/workbox-strategies", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "A service worker helper library implementing common caching strategies.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "router", + "routing" + ], + "workbox": { + "browserNamespace": "workbox.strategies", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*" + } +} diff --git a/packages/workbox-strategies/src/CacheFirst.ts b/packages/workbox-strategies/src/CacheFirst.ts new file mode 100644 index 00000000..511b8381 --- /dev/null +++ b/packages/workbox-strategies/src/CacheFirst.ts @@ -0,0 +1,101 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import { Strategy } from "./Strategy.js"; +import { StrategyHandler } from "./StrategyHandler.js"; +import { messages } from "./utils/messages.js"; +import "./_version.js"; + +/** + * An implementation of a [cache-first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-first-falling-back-to-network) + * request strategy. + * + * A cache first strategy is useful for assets that have been revisioned, + * such as URLs like `/styles/example.a8f5f1.css`, since they + * can be cached for long periods of time. + * + * If the network request fails, and there is no cache match, this will throw + * a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ +class CacheFirst extends Strategy { + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request: Request, handler: StrategyHandler): Promise { + const logs = []; + + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-strategies", + className: this.constructor.name, + funcName: "makeRequest", + paramName: "request", + }); + } + + let response = await handler.cacheMatch(request); + + let error: Error | undefined = undefined; + if (!response) { + if (process.env.NODE_ENV !== "production") { + logs.push( + `No response found in the '${this.cacheName}' cache. ` + + `Will respond with a network request.` + ); + } + try { + response = await handler.fetchAndCachePut(request); + } catch (err) { + if (err instanceof Error) { + error = err; + } + } + + if (process.env.NODE_ENV !== "production") { + if (response) { + logs.push(`Got response from network.`); + } else { + logs.push(`Unable to get a response from the network.`); + } + } + } else { + if (process.env.NODE_ENV !== "production") { + logs.push(`Found a cached response in the '${this.cacheName}' cache.`); + } + } + + if (process.env.NODE_ENV !== "production") { + logger.groupCollapsed( + messages.strategyStart(this.constructor.name, request) + ); + for (const log of logs) { + logger.log(log); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + + if (!response) { + throw new WorkboxError("no-response", { url: request.url, error }); + } + return response; + } +} + +export { CacheFirst }; diff --git a/packages/workbox-strategies/src/CacheOnly.ts b/packages/workbox-strategies/src/CacheOnly.ts new file mode 100644 index 00000000..3c211e95 --- /dev/null +++ b/packages/workbox-strategies/src/CacheOnly.ts @@ -0,0 +1,72 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import { Strategy } from "./Strategy.js"; +import { StrategyHandler } from "./StrategyHandler.js"; +import { messages } from "./utils/messages.js"; +import "./_version.js"; + +/** + * An implementation of a [cache-only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-only) + * request strategy. + * + * This class is useful if you want to take advantage of any + * [Workbox plugins](https://developer.chrome.com/docs/workbox/using-plugins/). + * + * If there is no cache match, this will throw a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ +class CacheOnly extends Strategy { + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request: Request, handler: StrategyHandler): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-strategies", + className: this.constructor.name, + funcName: "makeRequest", + paramName: "request", + }); + } + + const response = await handler.cacheMatch(request); + + if (process.env.NODE_ENV !== "production") { + logger.groupCollapsed( + messages.strategyStart(this.constructor.name, request) + ); + if (response) { + logger.log( + `Found a cached response in the '${this.cacheName}' ` + `cache.` + ); + messages.printFinalResponse(response); + } else { + logger.log(`No response found in the '${this.cacheName}' cache.`); + } + logger.groupEnd(); + } + + if (!response) { + throw new WorkboxError("no-response", { url: request.url }); + } + return response; + } +} + +export { CacheOnly }; diff --git a/packages/workbox-strategies/src/NetworkFirst.ts b/packages/workbox-strategies/src/NetworkFirst.ts new file mode 100644 index 00000000..83e79039 --- /dev/null +++ b/packages/workbox-strategies/src/NetworkFirst.ts @@ -0,0 +1,263 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import { cacheOkAndOpaquePlugin } from "./plugins/cacheOkAndOpaquePlugin.js"; +import { Strategy, StrategyOptions } from "./Strategy.js"; +import { StrategyHandler } from "./StrategyHandler.js"; +import { messages } from "./utils/messages.js"; +import "./_version.js"; + +export interface NetworkFirstOptions extends StrategyOptions { + networkTimeoutSeconds?: number; +} + +/** + * An implementation of a + * [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache) + * request strategy. + * + * By default, this strategy will cache responses with a 200 status code as + * well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses). + * Opaque responses are are cross-origin requests where the response doesn't + * support [CORS](https://enable-cors.org/). + * + * If the network request fails, and there is no cache match, this will throw + * a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ +class NetworkFirst extends Strategy { + private readonly _networkTimeoutSeconds: number; + + /** + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions) + * @param {number} [options.networkTimeoutSeconds] If set, any network requests + * that fail to respond within the timeout will fallback to the cache. + * + * This option can be used to combat + * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}" + * scenarios. + */ + constructor(options: NetworkFirstOptions = {}) { + super(options); + + // If this instance contains no plugins with a 'cacheWillUpdate' callback, + // prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list. + if (!this.plugins.some((p) => "cacheWillUpdate" in p)) { + this.plugins.unshift(cacheOkAndOpaquePlugin); + } + + this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0; + if (process.env.NODE_ENV !== "production") { + if (this._networkTimeoutSeconds) { + assert!.isType(this._networkTimeoutSeconds, "number", { + moduleName: "workbox-strategies", + className: this.constructor.name, + funcName: "constructor", + paramName: "networkTimeoutSeconds", + }); + } + } + } + + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request: Request, handler: StrategyHandler): Promise { + const logs: any[] = []; + + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-strategies", + className: this.constructor.name, + funcName: "handle", + paramName: "makeRequest", + }); + } + + const promises: Promise[] = []; + let timeoutId: number | undefined; + + if (this._networkTimeoutSeconds) { + const { id, promise } = this._getTimeoutPromise({ + request, + logs, + handler, + }); + timeoutId = id; + promises.push(promise); + } + + const networkPromise = this._getNetworkPromise({ + timeoutId, + request, + logs, + handler, + }); + + promises.push(networkPromise); + + const response = await handler.waitUntil( + (async () => { + // Promise.race() will resolve as soon as the first promise resolves. + return ( + (await handler.waitUntil(Promise.race(promises))) || + // If Promise.race() resolved with null, it might be due to a network + // timeout + a cache miss. If that were to happen, we'd rather wait until + // the networkPromise resolves instead of returning null. + // Note that it's fine to await an already-resolved promise, so we don't + // have to check to see if it's still "in flight". + (await networkPromise) + ); + })() + ); + + if (process.env.NODE_ENV !== "production") { + logger.groupCollapsed( + messages.strategyStart(this.constructor.name, request) + ); + for (const log of logs) { + logger.log(log); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + + if (!response) { + throw new WorkboxError("no-response", { url: request.url }); + } + return response; + } + + /** + * @param {Object} options + * @param {Request} options.request + * @param {Array} options.logs A reference to the logs array + * @param {Event} options.event + * @return {Promise} + * + * @private + */ + private _getTimeoutPromise({ + request, + logs, + handler, + }: { + request: Request; + logs: any[]; + handler: StrategyHandler; + }): { promise: Promise; id?: number } { + let timeoutId; + const timeoutPromise: Promise = new Promise( + (resolve) => { + const onNetworkTimeout = async () => { + if (process.env.NODE_ENV !== "production") { + logs.push( + `Timing out the network response at ` + + `${this._networkTimeoutSeconds} seconds.` + ); + } + resolve(await handler.cacheMatch(request)); + }; + timeoutId = setTimeout( + onNetworkTimeout, + this._networkTimeoutSeconds * 1000 + ); + } + ); + + return { + promise: timeoutPromise, + id: timeoutId, + }; + } + + /** + * @param {Object} options + * @param {number|undefined} options.timeoutId + * @param {Request} options.request + * @param {Array} options.logs A reference to the logs Array. + * @param {Event} options.event + * @return {Promise} + * + * @private + */ + async _getNetworkPromise({ + timeoutId, + request, + logs, + handler, + }: { + request: Request; + logs: any[]; + timeoutId?: number; + handler: StrategyHandler; + }): Promise { + let error; + let response; + try { + response = await handler.fetchAndCachePut(request); + } catch (fetchError) { + if (fetchError instanceof Error) { + error = fetchError; + } + } + + if (timeoutId) { + clearTimeout(timeoutId); + } + + if (process.env.NODE_ENV !== "production") { + if (response) { + logs.push(`Got response from network.`); + } else { + logs.push( + `Unable to get a response from the network. Will respond ` + + `with a cached response.` + ); + } + } + + if (error || !response) { + response = await handler.cacheMatch(request); + + if (process.env.NODE_ENV !== "production") { + if (response) { + logs.push( + `Found a cached response in the '${this.cacheName}'` + ` cache.` + ); + } else { + logs.push(`No response found in the '${this.cacheName}' cache.`); + } + } + } + + return response; + } +} + +export { NetworkFirst }; diff --git a/packages/workbox-strategies/src/NetworkOnly.ts b/packages/workbox-strategies/src/NetworkOnly.ts new file mode 100644 index 00000000..a18ace0a --- /dev/null +++ b/packages/workbox-strategies/src/NetworkOnly.ts @@ -0,0 +1,122 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { timeout } from "workbox-core/_private/timeout.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import { Strategy, StrategyOptions } from "./Strategy.js"; +import { StrategyHandler } from "./StrategyHandler.js"; +import { messages } from "./utils/messages.js"; +import "./_version.js"; + +interface NetworkOnlyOptions + extends Omit { + networkTimeoutSeconds?: number; +} + +/** + * An implementation of a + * [network-only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-only) + * request strategy. + * + * This class is useful if you want to take advantage of any + * [Workbox plugins](https://developer.chrome.com/docs/workbox/using-plugins/). + * + * If the network request fails, this will throw a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ +class NetworkOnly extends Strategy { + private readonly _networkTimeoutSeconds: number; + + /** + * @param {Object} [options] + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {number} [options.networkTimeoutSeconds] If set, any network requests + * that fail to respond within the timeout will result in a network error. + */ + constructor(options: NetworkOnlyOptions = {}) { + super(options); + + this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0; + } + + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request: Request, handler: StrategyHandler): Promise { + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-strategies", + className: this.constructor.name, + funcName: "_handle", + paramName: "request", + }); + } + + let error: Error | undefined = undefined; + let response: Response | undefined; + + try { + const promises: Promise[] = [ + handler.fetch(request), + ]; + + if (this._networkTimeoutSeconds) { + const timeoutPromise = timeout( + this._networkTimeoutSeconds * 1000 + ) as Promise; + promises.push(timeoutPromise); + } + + response = await Promise.race(promises); + if (!response) { + throw new Error( + `Timed out the network response after ` + + `${this._networkTimeoutSeconds} seconds.` + ); + } + } catch (err) { + if (err instanceof Error) { + error = err; + } + } + + if (process.env.NODE_ENV !== "production") { + logger.groupCollapsed( + messages.strategyStart(this.constructor.name, request) + ); + if (response) { + logger.log(`Got response from network.`); + } else { + logger.log(`Unable to get a response from the network.`); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + + if (!response) { + throw new WorkboxError("no-response", { url: request.url, error }); + } + return response; + } +} + +export { NetworkOnly, NetworkOnlyOptions }; diff --git a/packages/workbox-strategies/src/StaleWhileRevalidate.ts b/packages/workbox-strategies/src/StaleWhileRevalidate.ts new file mode 100644 index 00000000..40fa28e6 --- /dev/null +++ b/packages/workbox-strategies/src/StaleWhileRevalidate.ts @@ -0,0 +1,135 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import { cacheOkAndOpaquePlugin } from "./plugins/cacheOkAndOpaquePlugin.js"; +import { Strategy, StrategyOptions } from "./Strategy.js"; +import { StrategyHandler } from "./StrategyHandler.js"; +import { messages } from "./utils/messages.js"; +import "./_version.js"; + +/** + * An implementation of a + * [stale-while-revalidate](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate) + * request strategy. + * + * Resources are requested from both the cache and the network in parallel. + * The strategy will respond with the cached version if available, otherwise + * wait for the network response. The cache is updated with the network response + * with each successful request. + * + * By default, this strategy will cache responses with a 200 status code as + * well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses). + * Opaque responses are cross-origin requests where the response doesn't + * support [CORS](https://enable-cors.org/). + * + * If the network request fails, and there is no cache match, this will throw + * a `WorkboxError` exception. + * + * @extends workbox-strategies.Strategy + * @memberof workbox-strategies + */ +class StaleWhileRevalidate extends Strategy { + /** + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions) + */ + constructor(options: StrategyOptions = {}) { + super(options); + + // If this instance contains no plugins with a 'cacheWillUpdate' callback, + // prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list. + if (!this.plugins.some((p) => "cacheWillUpdate" in p)) { + this.plugins.unshift(cacheOkAndOpaquePlugin); + } + } + + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request: Request, handler: StrategyHandler): Promise { + const logs = []; + + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(request, Request, { + moduleName: "workbox-strategies", + className: this.constructor.name, + funcName: "handle", + paramName: "request", + }); + } + + const fetchAndCachePromise = handler.fetchAndCachePut(request).catch(() => { + // Swallow this error because a 'no-response' error will be thrown in + // main handler return flow. This will be in the `waitUntil()` flow. + }); + void handler.waitUntil(fetchAndCachePromise); + + let response = await handler.cacheMatch(request); + + let error; + if (response) { + if (process.env.NODE_ENV !== "production") { + logs.push( + `Found a cached response in the '${this.cacheName}'` + + ` cache. Will update with the network response in the background.` + ); + } + } else { + if (process.env.NODE_ENV !== "production") { + logs.push( + `No response found in the '${this.cacheName}' cache. ` + + `Will wait for the network response.` + ); + } + try { + // NOTE(philipwalton): Really annoying that we have to type cast here. + // https://github.com/microsoft/TypeScript/issues/20006 + response = (await fetchAndCachePromise) as Response | undefined; + } catch (err) { + if (err instanceof Error) { + error = err; + } + } + } + + if (process.env.NODE_ENV !== "production") { + logger.groupCollapsed( + messages.strategyStart(this.constructor.name, request) + ); + for (const log of logs) { + logger.log(log); + } + messages.printFinalResponse(response); + logger.groupEnd(); + } + + if (!response) { + throw new WorkboxError("no-response", { url: request.url, error }); + } + return response; + } +} + +export { StaleWhileRevalidate }; diff --git a/packages/workbox-strategies/src/Strategy.ts b/packages/workbox-strategies/src/Strategy.ts new file mode 100644 index 00000000..e38dc839 --- /dev/null +++ b/packages/workbox-strategies/src/Strategy.ts @@ -0,0 +1,289 @@ +/* + Copyright 2020 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 { cacheNames } from "workbox-core/_private/cacheNames.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { + HandlerCallbackOptions, + RouteHandlerObject, + WorkboxPlugin, +} from "workbox-core/types.js"; + +import { StrategyHandler } from "./StrategyHandler.js"; + +import "./_version.js"; + +export interface StrategyOptions { + cacheName?: string; + plugins?: WorkboxPlugin[]; + fetchOptions?: RequestInit; + matchOptions?: CacheQueryOptions; +} + +/** + * An abstract base class that all other strategy classes must extend from: + * + * @memberof workbox-strategies + */ +abstract class Strategy implements RouteHandlerObject { + cacheName: string; + plugins: WorkboxPlugin[]; + fetchOptions?: RequestInit; + matchOptions?: CacheQueryOptions; + + protected abstract _handle( + request: Request, + handler: StrategyHandler + ): Promise; + + /** + * Creates a new instance of the strategy and sets all documented option + * properties as public instance properties. + * + * Note: if a custom strategy class extends the base Strategy class and does + * not need more than these properties, it does not need to define its own + * constructor. + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `fetch()` requests made by this strategy. + * @param {Object} [options.matchOptions] The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + */ + constructor(options: StrategyOptions = {}) { + /** + * Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * + * @type {string} + */ + this.cacheName = cacheNames.getRuntimeName(options.cacheName); + /** + * The list + * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * used by this strategy. + * + * @type {Array} + */ + this.plugins = options.plugins || []; + /** + * Values passed along to the + * [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters} + * of all fetch() requests made by this strategy. + * + * @type {Object} + */ + this.fetchOptions = options.fetchOptions; + /** + * The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * + * @type {Object} + */ + this.matchOptions = options.matchOptions; + } + + /** + * Perform a request strategy and returns a `Promise` that will resolve with + * a `Response`, invoking all relevant plugin callbacks. + * + * When a strategy instance is registered with a Workbox + * {@link workbox-routing.Route}, this method is automatically + * called when the route matches. + * + * Alternatively, this method can be used in a standalone `FetchEvent` + * listener by passing it to `event.respondWith()`. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + */ + handle(options: FetchEvent | HandlerCallbackOptions): Promise { + const [responseDone] = this.handleAll(options); + return responseDone; + } + + /** + * Similar to {@link workbox-strategies.Strategy~handle}, but + * instead of just returning a `Promise` that resolves to a `Response` it + * it will return an tuple of `[response, done]` promises, where the former + * (`response`) is equivalent to what `handle()` returns, and the latter is a + * Promise that will resolve once any promises that were added to + * `event.waitUntil()` as part of performing the strategy have completed. + * + * You can await the `done` promise to ensure any extra work performed by + * the strategy (usually caching responses) completes successfully. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + * @return {Array} A tuple of [response, done] + * promises that can be used to determine when the response resolves as + * well as when the handler has completed all its work. + */ + handleAll( + options: FetchEvent | HandlerCallbackOptions + ): [Promise, Promise] { + // Allow for flexible options to be passed. + if (options instanceof FetchEvent) { + options = { + event: options, + request: options.request, + }; + } + + const event = options.event; + const request = + typeof options.request === "string" + ? new Request(options.request) + : options.request; + const params = "params" in options ? options.params : undefined; + + const handler = new StrategyHandler(this, { event, request, params }); + + const responseDone = this._getResponse(handler, request, event); + const handlerDone = this._awaitComplete( + responseDone, + handler, + request, + event + ); + + // Return an array of promises, suitable for use with Promise.all(). + return [responseDone, handlerDone]; + } + + async _getResponse( + handler: StrategyHandler, + request: Request, + event: ExtendableEvent + ): Promise { + await handler.runCallbacks("handlerWillStart", { event, request }); + + let response: Response | undefined = undefined; + try { + response = await this._handle(request, handler); + // The "official" Strategy subclasses all throw this error automatically, + // but in case a third-party Strategy doesn't, ensure that we have a + // consistent failure when there's no response or an error response. + if (!response || response.type === "error") { + throw new WorkboxError("no-response", { url: request.url }); + } + } catch (error) { + if (error instanceof Error) { + for (const callback of handler.iterateCallbacks("handlerDidError")) { + response = await callback({ error, event, request }); + if (response) { + break; + } + } + } + + if (!response) { + throw error; + } else if (process.env.NODE_ENV !== "production") { + logger.log( + `While responding to '${getFriendlyURL(request.url)}', ` + + `an ${ + error instanceof Error ? error.toString() : "" + } error occurred. Using a fallback response provided by ` + + `a handlerDidError plugin.` + ); + } + } + + for (const callback of handler.iterateCallbacks("handlerWillRespond")) { + response = await callback({ event, request, response }); + } + + return response; + } + + async _awaitComplete( + responseDone: Promise, + handler: StrategyHandler, + request: Request, + event: ExtendableEvent + ): Promise { + let response; + let error; + + try { + response = await responseDone; + } catch (error) { + // Ignore errors, as response errors should be caught via the `response` + // promise above. The `done` promise will only throw for errors in + // promises passed to `handler.waitUntil()`. + } + + try { + await handler.runCallbacks("handlerDidRespond", { + event, + request, + response, + }); + await handler.doneWaiting(); + } catch (waitUntilError) { + if (waitUntilError instanceof Error) { + error = waitUntilError; + } + } + + await handler.runCallbacks("handlerDidComplete", { + event, + request, + response, + error: error as Error, + }); + handler.destroy(); + + if (error) { + throw error; + } + } +} + +export { Strategy }; + +/** + * Classes extending the `Strategy` based class should implement this method, + * and leverage the {@link workbox-strategies.StrategyHandler} + * arg to perform all fetching and cache logic, which will ensure all relevant + * cache, cache options, fetch options and plugins are used (per the current + * strategy instance). + * + * @name _handle + * @instance + * @abstract + * @function + * @param {Request} request + * @param {workbox-strategies.StrategyHandler} handler + * @return {Promise} + * + * @memberof workbox-strategies.Strategy + */ diff --git a/packages/workbox-strategies/src/StrategyHandler.ts b/packages/workbox-strategies/src/StrategyHandler.ts new file mode 100644 index 00000000..87bc26b2 --- /dev/null +++ b/packages/workbox-strategies/src/StrategyHandler.ts @@ -0,0 +1,636 @@ +/* + Copyright 2020 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 "workbox-core/_private/assert.js"; +import { cacheMatchIgnoreParams } from "workbox-core/_private/cacheMatchIgnoreParams.js"; +import { Deferred } from "workbox-core/_private/Deferred.js"; +import { executeQuotaErrorCallbacks } from "workbox-core/_private/executeQuotaErrorCallbacks.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { timeout } from "workbox-core/_private/timeout.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { + HandlerCallbackOptions, + MapLikeObject, + WorkboxPlugin, + WorkboxPluginCallbackParam, +} from "workbox-core/types.js"; + +import { Strategy } from "./Strategy.js"; +import "./_version.js"; + +function toRequest(input: RequestInfo) { + return typeof input === "string" ? new Request(input) : input; +} + +/** + * A class created every time a Strategy instance instance calls + * {@link workbox-strategies.Strategy~handle} or + * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and + * cache actions around plugin callbacks and keeps track of when the strategy + * is "done" (i.e. all added `event.waitUntil()` promises have resolved). + * + * @memberof workbox-strategies + */ +class StrategyHandler { + public request!: Request; + public url?: URL; + public event: ExtendableEvent; + public params?: any; + + private _cacheKeys: Record = {}; + + private readonly _strategy: Strategy; + private readonly _extendLifetimePromises: Promise[]; + private readonly _handlerDeferred: Deferred; + private readonly _plugins: WorkboxPlugin[]; + private readonly _pluginStateMap: Map; + + /** + * Creates a new instance associated with the passed strategy and event + * that's handling the request. + * + * The constructor also initializes the state that will be passed to each of + * the plugins handling this request. + * + * @param {workbox-strategies.Strategy} strategy + * @param {Object} options + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] The return value from the + * {@link workbox-routing~matchCallback} (if applicable). + */ + constructor(strategy: Strategy, options: HandlerCallbackOptions) { + /** + * The request the strategy is performing (passed to the strategy's + * `handle()` or `handleAll()` method). + * @name request + * @instance + * @type {Request} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * The event associated with this request. + * @name event + * @instance + * @type {ExtendableEvent} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `URL` instance of `request.url` (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `url` param will be present if the strategy was invoked + * from a workbox `Route` object. + * @name url + * @instance + * @type {URL|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `param` value (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `param` param will be present if the strategy was invoked + * from a workbox `Route` object and the + * {@link workbox-routing~matchCallback} returned + * a truthy value (it will be that value). + * @name params + * @instance + * @type {*|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + if (process.env.NODE_ENV !== "production") { + assert!.isInstance(options.event, ExtendableEvent, { + moduleName: "workbox-strategies", + className: "StrategyHandler", + funcName: "constructor", + paramName: "options.event", + }); + } + + Object.assign(this, options); + + this.event = options.event; + this._strategy = strategy; + this._handlerDeferred = new Deferred(); + this._extendLifetimePromises = []; + + // Copy the plugins list (since it's mutable on the strategy), + // so any mutations don't affect this handler instance. + this._plugins = [...strategy.plugins]; + this._pluginStateMap = new Map(); + for (const plugin of this._plugins) { + this._pluginStateMap.set(plugin, {}); + } + + this.event.waitUntil(this._handlerDeferred.promise); + } + + /** + * Fetches a given request (and invokes any applicable plugin callback + * methods) using the `fetchOptions` (for non-navigation requests) and + * `plugins` defined on the `Strategy` object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - `requestWillFetch()` + * - `fetchDidSucceed()` + * - `fetchDidFail()` + * + * @param {Request|string} input The URL or request to fetch. + * @return {Promise} + */ + async fetch(input: RequestInfo): Promise { + const { event } = this; + let request: Request = toRequest(input); + + if ( + request.mode === "navigate" && + event instanceof FetchEvent && + event.preloadResponse + ) { + const possiblePreloadResponse = (await event.preloadResponse) as + | Response + | undefined; + if (possiblePreloadResponse) { + if (process.env.NODE_ENV !== "production") { + logger.log( + `Using a preloaded navigation response for ` + + `'${getFriendlyURL(request.url)}'` + ); + } + return possiblePreloadResponse; + } + } + + // If there is a fetchDidFail plugin, we need to save a clone of the + // original request before it's either modified by a requestWillFetch + // plugin or before the original request's body is consumed via fetch(). + const originalRequest = this.hasCallback("fetchDidFail") + ? request.clone() + : null; + + try { + for (const cb of this.iterateCallbacks("requestWillFetch")) { + request = await cb({ request: request.clone(), event }); + } + } catch (err) { + if (err instanceof Error) { + throw new WorkboxError("plugin-error-request-will-fetch", { + thrownErrorMessage: err.message, + }); + } + } + + // The request can be altered by plugins with `requestWillFetch` making + // the original request (most likely from a `fetch` event) different + // from the Request we make. Pass both to `fetchDidFail` to aid debugging. + const pluginFilteredRequest: Request = request.clone(); + + try { + let fetchResponse: Response; + + // See https://github.com/GoogleChrome/workbox/issues/1796 + fetchResponse = await fetch( + request, + request.mode === "navigate" ? undefined : this._strategy.fetchOptions + ); + + if (process.env.NODE_ENV !== "production") { + logger.debug( + `Network request for ` + + `'${getFriendlyURL(request.url)}' returned a response with ` + + `status '${fetchResponse.status}'.` + ); + } + + for (const callback of this.iterateCallbacks("fetchDidSucceed")) { + fetchResponse = await callback({ + event, + request: pluginFilteredRequest, + response: fetchResponse, + }); + } + return fetchResponse; + } catch (error) { + if (process.env.NODE_ENV !== "production") { + logger.log( + `Network request for ` + + `'${getFriendlyURL(request.url)}' threw an error.`, + error + ); + } + + // `originalRequest` will only exist if a `fetchDidFail` callback + // is being used (see above). + if (originalRequest) { + await this.runCallbacks("fetchDidFail", { + error: error as Error, + event, + originalRequest: originalRequest.clone(), + request: pluginFilteredRequest.clone(), + }); + } + throw error; + } + } + + /** + * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on + * the response generated by `this.fetch()`. + * + * The call to `this.cachePut()` automatically invokes `this.waitUntil()`, + * so you do not have to manually call `waitUntil()` on the event. + * + * @param {Request|string} input The request or URL to fetch and cache. + * @return {Promise} + */ + async fetchAndCachePut(input: RequestInfo): Promise { + const response = await this.fetch(input); + const responseClone = response.clone(); + + void this.waitUntil(this.cachePut(input, responseClone)); + + return response; + } + + /** + * Matches a request from the cache (and invokes any applicable plugin + * callback methods) using the `cacheName`, `matchOptions`, and `plugins` + * defined on the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillByUsed() + * - cachedResponseWillByUsed() + * + * @param {Request|string} key The Request or URL to use as the cache key. + * @return {Promise} A matching response, if found. + */ + async cacheMatch(key: RequestInfo): Promise { + const request: Request = toRequest(key); + let cachedResponse: Response | undefined; + const { cacheName, matchOptions } = this._strategy; + + const effectiveRequest = await this.getCacheKey(request, "read"); + const multiMatchOptions = { ...matchOptions, ...{ cacheName } }; + + cachedResponse = await caches.match(effectiveRequest, multiMatchOptions); + + if (process.env.NODE_ENV !== "production") { + if (cachedResponse) { + logger.debug(`Found a cached response in '${cacheName}'.`); + } else { + logger.debug(`No cached response found in '${cacheName}'.`); + } + } + + for (const callback of this.iterateCallbacks("cachedResponseWillBeUsed")) { + cachedResponse = + (await callback({ + cacheName, + matchOptions, + cachedResponse, + request: effectiveRequest, + event: this.event, + })) || undefined; + } + return cachedResponse; + } + + /** + * Puts a request/response pair in the cache (and invokes any applicable + * plugin callback methods) using the `cacheName` and `plugins` defined on + * the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillByUsed() + * - cacheWillUpdate() + * - cacheDidUpdate() + * + * @param {Request|string} key The request or URL to use as the cache key. + * @param {Response} response The response to cache. + * @return {Promise} `false` if a cacheWillUpdate caused the response + * not be cached, and `true` otherwise. + */ + async cachePut(key: RequestInfo, response: Response): Promise { + const request: Request = toRequest(key); + + // Run in the next task to avoid blocking other cache reads. + // https://github.com/w3c/ServiceWorker/issues/1397 + await timeout(0); + + const effectiveRequest = await this.getCacheKey(request, "write"); + + if (process.env.NODE_ENV !== "production") { + if (effectiveRequest.method && effectiveRequest.method !== "GET") { + throw new WorkboxError("attempt-to-cache-non-get-request", { + url: getFriendlyURL(effectiveRequest.url), + method: effectiveRequest.method, + }); + } + + // See https://github.com/GoogleChrome/workbox/issues/2818 + const vary = response.headers.get("Vary"); + if (vary) { + logger.debug( + `The response for ${getFriendlyURL(effectiveRequest.url)} ` + + `has a 'Vary: ${vary}' header. ` + + `Consider setting the {ignoreVary: true} option on your strategy ` + + `to ensure cache matching and deletion works as expected.` + ); + } + } + + if (!response) { + if (process.env.NODE_ENV !== "production") { + logger.error( + `Cannot cache non-existent response for ` + + `'${getFriendlyURL(effectiveRequest.url)}'.` + ); + } + + throw new WorkboxError("cache-put-with-no-response", { + url: getFriendlyURL(effectiveRequest.url), + }); + } + + const responseToCache = await this._ensureResponseSafeToCache(response); + + if (!responseToCache) { + if (process.env.NODE_ENV !== "production") { + logger.debug( + `Response '${getFriendlyURL(effectiveRequest.url)}' ` + + `will not be cached.`, + responseToCache + ); + } + return false; + } + + const { cacheName, matchOptions } = this._strategy; + const cache = await self.caches.open(cacheName); + + const hasCacheUpdateCallback = this.hasCallback("cacheDidUpdate"); + const oldResponse = hasCacheUpdateCallback + ? await cacheMatchIgnoreParams( + // TODO(philipwalton): the `__WB_REVISION__` param is a precaching + // feature. Consider into ways to only add this behavior if using + // precaching. + cache, + effectiveRequest.clone(), + ["__WB_REVISION__"], + matchOptions + ) + : null; + + if (process.env.NODE_ENV !== "production") { + logger.debug( + `Updating the '${cacheName}' cache with a new Response ` + + `for ${getFriendlyURL(effectiveRequest.url)}.` + ); + } + + try { + await cache.put( + effectiveRequest, + hasCacheUpdateCallback ? responseToCache.clone() : responseToCache + ); + } catch (error) { + if (error instanceof Error) { + // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError + if (error.name === "QuotaExceededError") { + await executeQuotaErrorCallbacks(); + } + throw error; + } + } + + for (const callback of this.iterateCallbacks("cacheDidUpdate")) { + await callback({ + cacheName, + oldResponse, + newResponse: responseToCache.clone(), + request: effectiveRequest, + event: this.event, + }); + } + + return true; + } + + /** + * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and + * executes any of those callbacks found in sequence. The final `Request` + * object returned by the last plugin is treated as the cache key for cache + * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have + * been registered, the passed request is returned unmodified + * + * @param {Request} request + * @param {string} mode + * @return {Promise} + */ + async getCacheKey( + request: Request, + mode: "read" | "write" + ): Promise { + const key = `${request.url} | ${mode}`; + if (!this._cacheKeys[key]) { + let effectiveRequest = request; + + for (const callback of this.iterateCallbacks("cacheKeyWillBeUsed")) { + effectiveRequest = toRequest( + await callback({ + mode, + request: effectiveRequest, + event: this.event, + // params has a type any can't change right now. + params: this.params, // eslint-disable-line + }) + ); + } + + this._cacheKeys[key] = effectiveRequest; + } + return this._cacheKeys[key]; + } + + /** + * Returns true if the strategy has at least one plugin with the given + * callback. + * + * @param {string} name The name of the callback to check for. + * @return {boolean} + */ + hasCallback(name: C): boolean { + for (const plugin of this._strategy.plugins) { + if (name in plugin) { + return true; + } + } + return false; + } + + /** + * Runs all plugin callbacks matching the given name, in order, passing the + * given param object (merged ith the current plugin state) as the only + * argument. + * + * Note: since this method runs all plugins, it's not suitable for cases + * where the return value of a callback needs to be applied prior to calling + * the next callback. See + * {@link workbox-strategies.StrategyHandler#iterateCallbacks} + * below for how to handle that case. + * + * @param {string} name The name of the callback to run within each plugin. + * @param {Object} param The object to pass as the first (and only) param + * when executing each callback. This object will be merged with the + * current plugin state prior to callback execution. + */ + async runCallbacks>( + name: C, + param: Omit + ): Promise { + for (const callback of this.iterateCallbacks(name)) { + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + await callback(param as any); + } + } + + /** + * Accepts a callback and returns an iterable of matching plugin callbacks, + * where each callback is wrapped with the current handler state (i.e. when + * you call each callback, whatever object parameter you pass it will + * be merged with the plugin's current state). + * + * @param {string} name The name fo the callback to run + * @return {Array} + */ + *iterateCallbacks( + name: C + ): Generator> { + for (const plugin of this._strategy.plugins) { + if (typeof plugin[name] === "function") { + const state = this._pluginStateMap.get(plugin); + const statefulCallback = ( + param: Omit + ) => { + const statefulParam = { ...param, state }; + + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + return plugin[name]!(statefulParam as any); + }; + yield statefulCallback as NonNullable; + } + } + } + + /** + * Adds a promise to the + * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises} + * of the event event associated with the request being handled (usually a + * `FetchEvent`). + * + * Note: you can await + * {@link workbox-strategies.StrategyHandler~doneWaiting} + * to know when all added promises have settled. + * + * @param {Promise} promise A promise to add to the extend lifetime promises + * of the event that triggered the request. + */ + waitUntil(promise: Promise): Promise { + this._extendLifetimePromises.push(promise); + return promise; + } + + /** + * Returns a promise that resolves once all promises passed to + * {@link workbox-strategies.StrategyHandler~waitUntil} + * have settled. + * + * Note: any work done after `doneWaiting()` settles should be manually + * passed to an event's `waitUntil()` method (not this handler's + * `waitUntil()` method), otherwise the service worker thread my be killed + * prior to your work completing. + */ + async doneWaiting(): Promise { + let promise; + while ((promise = this._extendLifetimePromises.shift())) { + await promise; + } + } + + /** + * Stops running the strategy and immediately resolves any pending + * `waitUntil()` promises. + */ + destroy(): void { + this._handlerDeferred.resolve(null); + } + + /** + * This method will call cacheWillUpdate on the available plugins (or use + * status === 200) to determine if the Response is safe and valid to cache. + * + * @param {Request} options.request + * @param {Response} options.response + * @return {Promise} + * + * @private + */ + async _ensureResponseSafeToCache( + response: Response + ): Promise { + let responseToCache: Response | undefined = response; + let pluginsUsed = false; + + for (const callback of this.iterateCallbacks("cacheWillUpdate")) { + responseToCache = + (await callback({ + request: this.request, + response: responseToCache, + event: this.event, + })) || undefined; + pluginsUsed = true; + + if (!responseToCache) { + break; + } + } + + if (!pluginsUsed) { + if (responseToCache && responseToCache.status !== 200) { + responseToCache = undefined; + } + if (process.env.NODE_ENV !== "production") { + if (responseToCache) { + if (responseToCache.status !== 200) { + if (responseToCache.status === 0) { + logger.warn( + `The response for '${this.request.url}' ` + + `is an opaque response. The caching strategy that you're ` + + `using will not cache opaque responses by default.` + ); + } else { + logger.debug( + `The response for '${this.request.url}' ` + + `returned a status code of '${response.status}' and won't ` + + `be cached as a result.` + ); + } + } + } + } + } + + return responseToCache; + } +} + +export { StrategyHandler }; diff --git a/packages/workbox-strategies/src/_version.ts b/packages/workbox-strategies/src/_version.ts new file mode 100644 index 00000000..5f2f0400 --- /dev/null +++ b/packages/workbox-strategies/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:strategies:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-strategies/src/index.ts b/packages/workbox-strategies/src/index.ts new file mode 100644 index 00000000..09fd3359 --- /dev/null +++ b/packages/workbox-strategies/src/index.ts @@ -0,0 +1,44 @@ +/* + 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 { CacheFirst } from "./CacheFirst.js"; +import { CacheOnly } from "./CacheOnly.js"; +import { NetworkFirst, NetworkFirstOptions } from "./NetworkFirst.js"; +import { NetworkOnly, NetworkOnlyOptions } from "./NetworkOnly.js"; +import { StaleWhileRevalidate } from "./StaleWhileRevalidate.js"; +import { Strategy, StrategyOptions } from "./Strategy.js"; +import { StrategyHandler } from "./StrategyHandler.js"; +import "./_version.js"; + +// See https://github.com/GoogleChrome/workbox/issues/2946 +declare global { + interface FetchEvent { + // See https://github.com/GoogleChrome/workbox/issues/2974 + readonly preloadResponse: Promise; + } +} + +/** + * There are common caching strategies that most service workers will need + * and use. This module provides simple implementations of these strategies. + * + * @module workbox-strategies + */ + +export { + CacheFirst, + CacheOnly, + NetworkFirst, + NetworkFirstOptions, + NetworkOnly, + NetworkOnlyOptions, + StaleWhileRevalidate, + Strategy, + StrategyHandler, + StrategyOptions, +}; diff --git a/packages/workbox-strategies/src/plugins/cacheOkAndOpaquePlugin.ts b/packages/workbox-strategies/src/plugins/cacheOkAndOpaquePlugin.ts new file mode 100644 index 00000000..298330bb --- /dev/null +++ b/packages/workbox-strategies/src/plugins/cacheOkAndOpaquePlugin.ts @@ -0,0 +1,29 @@ +/* + 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 { WorkboxPlugin } from "workbox-core/types.js"; +import "../_version.js"; + +export const cacheOkAndOpaquePlugin: WorkboxPlugin = { + /** + * Returns a valid response (to allow caching) if the status is 200 (OK) or + * 0 (opaque). + * + * @param {Object} options + * @param {Response} options.response + * @return {Response|null} + * + * @private + */ + cacheWillUpdate: async ({ response }) => { + if (response.status === 200 || response.status === 0) { + return response; + } + return null; + }, +}; diff --git a/packages/workbox-strategies/src/utils/messages.ts b/packages/workbox-strategies/src/utils/messages.ts new file mode 100644 index 00000000..7c353fea --- /dev/null +++ b/packages/workbox-strategies/src/utils/messages.ts @@ -0,0 +1,23 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import "../_version.js"; + +export const messages = { + strategyStart: (strategyName: string, request: Request): string => + `Using ${strategyName} to respond to '${getFriendlyURL(request.url)}'`, + printFinalResponse: (response?: Response): void => { + if (response) { + logger.groupCollapsed(`View the final response here.`); + logger.log(response || "[No response returned]"); + logger.groupEnd(); + } + }, +}; diff --git a/packages/workbox-strategies/tsconfig.json b/packages/workbox-strategies/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-strategies/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-streams/README.md b/packages/workbox-streams/README.md new file mode 100644 index 00000000..8abfa9cd --- /dev/null +++ b/packages/workbox-streams/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-streams diff --git a/packages/workbox-streams/package.json b/packages/workbox-streams/package.json new file mode 100644 index 00000000..24b8183c --- /dev/null +++ b/packages/workbox-streams/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ducanh2912/workbox-streams", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "A library that makes it easier to work with Streams in the browser.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "streams", + "readablestream" + ], + "workbox": { + "browserNamespace": "workbox.streams", + "packageType": "sw" + }, + "main": "index.js", + "module": "index.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "workspace:*", + "@ducanh2912/workbox-routing": "workspace:*" + } +} diff --git a/packages/workbox-streams/src/_types.ts b/packages/workbox-streams/src/_types.ts new file mode 100644 index 00000000..3f0fc0b9 --- /dev/null +++ b/packages/workbox-streams/src/_types.ts @@ -0,0 +1,23 @@ +/* + 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 "./_version.js"; + +export type StreamSource = Response | ReadableStream | BodyInit; + +// * * * IMPORTANT! * * * +// ------------------------------------------------------------------------- // +// jdsoc type definitions cannot be declared above TypeScript definitions or +// they'll be stripped from the built `.js` files, and they'll only be in the +// `d.ts` files, which aren't read by the jsdoc generator. As a result we +// have to put declare them below. + +/** + * @typedef {Response|ReadableStream|BodyInit} StreamSource + * @memberof workbox-streams + */ diff --git a/packages/workbox-streams/src/_version.ts b/packages/workbox-streams/src/_version.ts new file mode 100644 index 00000000..ba2456cf --- /dev/null +++ b/packages/workbox-streams/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:streams:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-streams/src/concatenate.ts b/packages/workbox-streams/src/concatenate.ts new file mode 100644 index 00000000..39cb555e --- /dev/null +++ b/packages/workbox-streams/src/concatenate.ts @@ -0,0 +1,146 @@ +/* + 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 { assert } from "workbox-core/_private/assert.js"; +import { Deferred } from "workbox-core/_private/Deferred.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { StreamSource } from "./_types.js"; +import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; + +import "./_version.js"; + +/** + * Takes either a Response, a ReadableStream, or a + * [BodyInit](https://fetch.spec.whatwg.org/#bodyinit) and returns the + * ReadableStreamReader object associated with it. + * + * @param {workbox-streams.StreamSource} source + * @return {ReadableStreamReader} + * @private + */ +function _getReaderFromSource( + source: StreamSource +): ReadableStreamReader { + if (source instanceof Response) { + // See https://github.com/GoogleChrome/workbox/issues/2998 + if (source.body) { + return source.body.getReader(); + } + throw new WorkboxError("opaque-streams-source", { type: source.type }); + } + if (source instanceof ReadableStream) { + return source.getReader(); + } + return new Response(source as BodyInit).body!.getReader(); +} + +/** + * Takes multiple source Promises, each of which could resolve to a Response, a + * ReadableStream, or a [BodyInit](https://fetch.spec.whatwg.org/#bodyinit). + * + * Returns an object exposing a ReadableStream with each individual stream's + * data returned in sequence, along with a Promise which signals when the + * stream is finished (useful for passing to a FetchEvent's waitUntil()). + * + * @param {Array>} sourcePromises + * @return {Object<{done: Promise, stream: ReadableStream}>} + * + * @memberof workbox-streams + */ +function concatenate(sourcePromises: Promise[]): { + done: Promise; + stream: ReadableStream; +} { + if (process.env.NODE_ENV !== "production") { + assert!.isArray(sourcePromises, { + moduleName: "workbox-streams", + funcName: "concatenate", + paramName: "sourcePromises", + }); + } + + const readerPromises = sourcePromises.map((sourcePromise) => { + return Promise.resolve(sourcePromise).then((source) => { + return _getReaderFromSource(source); + }); + }); + + const streamDeferred: Deferred = new Deferred(); + + let i = 0; + const logMessages: any[] = []; + const stream = new ReadableStream({ + pull(controller: ReadableStreamDefaultController) { + return readerPromises[i] + .then((reader) => { + if (reader instanceof ReadableStreamDefaultReader) { + return reader.read(); + } else { + return; + } + }) + .then((result) => { + if (result?.done) { + if (process.env.NODE_ENV !== "production") { + logMessages.push([ + "Reached the end of source:", + sourcePromises[i], + ]); + } + + i++; + if (i >= readerPromises.length) { + // Log all the messages in the group at once in a single group. + if (process.env.NODE_ENV !== "production") { + logger.groupCollapsed( + `Concatenating ${readerPromises.length} sources.` + ); + for (const message of logMessages) { + if (Array.isArray(message)) { + logger.log(...message); + } else { + logger.log(message); + } + } + logger.log("Finished reading all sources."); + logger.groupEnd(); + } + + controller.close(); + streamDeferred.resolve(); + return; + } + + // The `pull` method is defined because we're inside it. + return this.pull!(controller); + } else { + controller.enqueue(result?.value); + } + }) + .catch((error) => { + if (process.env.NODE_ENV !== "production") { + logger.error("An error occurred:", error); + } + streamDeferred.reject(error); + throw error; + }); + }, + + cancel() { + if (process.env.NODE_ENV !== "production") { + logger.warn("The ReadableStream was cancelled."); + } + + streamDeferred.resolve(); + }, + }); + + return { done: streamDeferred.promise, stream }; +} + +export { concatenate }; diff --git a/packages/workbox-streams/src/concatenateToResponse.ts b/packages/workbox-streams/src/concatenateToResponse.ts new file mode 100644 index 00000000..bf15745b --- /dev/null +++ b/packages/workbox-streams/src/concatenateToResponse.ts @@ -0,0 +1,43 @@ +/* + 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 { createHeaders } from "./utils/createHeaders.js"; +import { concatenate } from "./concatenate.js"; +import { StreamSource } from "./_types.js"; +import "./_version.js"; + +/** + * Takes multiple source Promises, each of which could resolve to a Response, a + * ReadableStream, or a [BodyInit](https://fetch.spec.whatwg.org/#bodyinit), + * along with a + * [HeadersInit](https://fetch.spec.whatwg.org/#typedefdef-headersinit). + * + * Returns an object exposing a Response whose body consists of each individual + * stream's data returned in sequence, along with a Promise which signals when + * the stream is finished (useful for passing to a FetchEvent's waitUntil()). + * + * @param {Array>} sourcePromises + * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified, + * `'text/html'` will be used by default. + * @return {Object<{done: Promise, response: Response}>} + * + * @memberof workbox-streams + */ +function concatenateToResponse( + sourcePromises: Promise[], + headersInit: HeadersInit +): { done: Promise; response: Response } { + const { done, stream } = concatenate(sourcePromises); + + const headers = createHeaders(headersInit); + const response = new Response(stream, { headers }); + + return { done, response }; +} + +export { concatenateToResponse }; diff --git a/packages/workbox-streams/src/index.ts b/packages/workbox-streams/src/index.ts new file mode 100644 index 00000000..328f7767 --- /dev/null +++ b/packages/workbox-streams/src/index.ts @@ -0,0 +1,28 @@ +/* + 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 { concatenate } from "./concatenate.js"; +import { concatenateToResponse } from "./concatenateToResponse.js"; +import { isSupported } from "./isSupported.js"; +import { strategy, StreamsHandlerCallback } from "./strategy.js"; + +import "./_version.js"; + +/** + * @module workbox-streams + */ + +export { + concatenate, + concatenateToResponse, + isSupported, + strategy, + StreamsHandlerCallback, +}; + +export * from "./_types.js"; diff --git a/packages/workbox-streams/src/isSupported.ts b/packages/workbox-streams/src/isSupported.ts new file mode 100644 index 00000000..81e138df --- /dev/null +++ b/packages/workbox-streams/src/isSupported.ts @@ -0,0 +1,27 @@ +/* + 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 { canConstructReadableStream } from "workbox-core/_private/canConstructReadableStream.js"; +import "./_version.js"; + +/** + * This is a utility method that determines whether the current browser supports + * the features required to create streamed responses. Currently, it checks if + * [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream) + * can be created. + * + * @return {boolean} `true`, if the current browser meets the requirements for + * streaming responses, and `false` otherwise. + * + * @memberof workbox-streams + */ +function isSupported(): boolean { + return canConstructReadableStream(); +} + +export { isSupported }; diff --git a/packages/workbox-streams/src/strategy.ts b/packages/workbox-streams/src/strategy.ts new file mode 100644 index 00000000..7d888fbb --- /dev/null +++ b/packages/workbox-streams/src/strategy.ts @@ -0,0 +1,102 @@ +/* + 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 { logger } from "workbox-core/_private/logger.js"; +import { + RouteHandlerCallback, + RouteHandlerCallbackOptions, +} from "workbox-core/types.js"; +import { createHeaders } from "./utils/createHeaders.js"; +import { concatenateToResponse } from "./concatenateToResponse.js"; +import { isSupported } from "./isSupported.js"; +import { StreamSource } from "./_types.js"; +import "./_version.js"; + +export interface StreamsHandlerCallback { + ({ + url, + request, + event, + params, + }: RouteHandlerCallbackOptions): Promise | StreamSource; +} + +/** + * A shortcut to create a strategy that could be dropped-in to Workbox's router. + * + * On browsers that do not support constructing new `ReadableStream`s, this + * strategy will automatically wait for all the `sourceFunctions` to complete, + * and create a final response that concatenates their values together. + * + * @param {Array} sourceFunctions + * An array of functions similar to {@link workbox-routing~handlerCallback} + * but that instead return a {@link workbox-streams.StreamSource} (or a + * Promise which resolves to one). + * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified, + * `'text/html'` will be used by default. + * @return {workbox-routing~handlerCallback} + * @memberof workbox-streams + */ +function strategy( + sourceFunctions: StreamsHandlerCallback[], + headersInit: HeadersInit +): RouteHandlerCallback { + return async ({ + event, + request, + url, + params, + }: RouteHandlerCallbackOptions) => { + const sourcePromises = sourceFunctions.map((fn) => { + // Ensure the return value of the function is always a promise. + return Promise.resolve(fn({ event, request, url, params })); + }); + + if (isSupported()) { + const { done, response } = concatenateToResponse( + sourcePromises, + headersInit + ); + + if (event) { + event.waitUntil(done); + } + return response; + } + + if (process.env.NODE_ENV !== "production") { + logger.log( + `The current browser doesn't support creating response ` + + `streams. Falling back to non-streaming response instead.` + ); + } + + // Fallback to waiting for everything to finish, and concatenating the + // responses. + const blobPartsPromises = sourcePromises.map(async (sourcePromise) => { + const source = await sourcePromise; + if (source instanceof Response) { + return source.blob(); + } else { + // Technically, a `StreamSource` object can include any valid + // `BodyInit` type, including `FormData` and `URLSearchParams`, which + // cannot be passed to the Blob constructor directly, so we have to + // convert them to actual Blobs first. + return new Response(source).blob(); + } + }); + const blobParts = await Promise.all(blobPartsPromises); + const headers = createHeaders(headersInit); + + // Constructing a new Response from a Blob source is well-supported. + // So is constructing a new Blob from multiple source Blobs or strings. + return new Response(new Blob(blobParts), { headers }); + }; +} + +export { strategy }; diff --git a/packages/workbox-streams/src/utils/createHeaders.ts b/packages/workbox-streams/src/utils/createHeaders.ts new file mode 100644 index 00000000..ef94a92e --- /dev/null +++ b/packages/workbox-streams/src/utils/createHeaders.ts @@ -0,0 +1,34 @@ +/* + 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 "../_version.js"; + +/** + * This is a utility method that determines whether the current browser supports + * the features required to create streamed responses. Currently, it checks if + * [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream) + * is available. + * + * @private + * @param {HeadersInit} [headersInit] If there's no `Content-Type` specified, + * `'text/html'` will be used by default. + * @return {boolean} `true`, if the current browser meets the requirements for + * streaming responses, and `false` otherwise. + * + * @memberof workbox-streams + */ +function createHeaders(headersInit = {}): Headers { + // See https://github.com/GoogleChrome/workbox/issues/1461 + const headers = new Headers(headersInit); + if (!headers.has("content-type")) { + headers.set("content-type", "text/html"); + } + return headers; +} + +export { createHeaders }; diff --git a/packages/workbox-streams/tsconfig.json b/packages/workbox-streams/tsconfig.json new file mode 100644 index 00000000..2457eadc --- /dev/null +++ b/packages/workbox-streams/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-core/"}] +} diff --git a/packages/workbox-sw/README.md b/packages/workbox-sw/README.md new file mode 100644 index 00000000..b4504bf7 --- /dev/null +++ b/packages/workbox-sw/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-sw diff --git a/packages/workbox-sw/_types.mjs b/packages/workbox-sw/_types.mjs new file mode 100644 index 00000000..face4fd2 --- /dev/null +++ b/packages/workbox-sw/_types.mjs @@ -0,0 +1,24 @@ +/* + 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 "./_version.mjs"; + +/** + * A `ModulePathCallback` function can be used to modify the modify the where + * Workbox modules are loaded. + * + * @callback ~ModulePathCallback + * @param {string} moduleName The name of the module to load (i.e. + * 'workbox-core', 'workbox-precaching' etc.). + * @param {boolean} debug When true, `dev` builds should be loaded, otherwise + * load `prod` builds. + * @return {string} This callback should return a path of module. This will + * be passed to `importScripts()`. + * + * @memberof workbox + */ diff --git a/packages/workbox-sw/_version.mjs b/packages/workbox-sw/_version.mjs new file mode 100644 index 00000000..bd0011c0 --- /dev/null +++ b/packages/workbox-sw/_version.mjs @@ -0,0 +1,3 @@ +try { + self["workbox:sw:7.0.0"] && _(); +} catch (e) {} // eslint-disable-line diff --git a/packages/workbox-sw/controllers/WorkboxSW.mjs b/packages/workbox-sw/controllers/WorkboxSW.mjs new file mode 100644 index 00000000..19306f94 --- /dev/null +++ b/packages/workbox-sw/controllers/WorkboxSW.mjs @@ -0,0 +1,221 @@ +/* + 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 "../_version.mjs"; + +const CDN_PATH = `WORKBOX_CDN_ROOT_URL`; + +const MODULE_KEY_TO_NAME_MAPPING = { + /** + * @name backgroundSync + * @memberof workbox + * @see module:workbox-background-sync + */ + backgroundSync: "background-sync", + /** + * @name broadcastUpdate + * @memberof workbox + * @see module:workbox-broadcast-update + */ + broadcastUpdate: "broadcast-update", + /** + * @name cacheableResponse + * @memberof workbox + * @see module:workbox-cacheable-response + */ + cacheableResponse: "cacheable-response", + /** + * @name core + * @memberof workbox + * @see module:workbox-core + */ + core: "core", + /** + * @name expiration + * @memberof workbox + * @see module:workbox-expiration + */ + expiration: "expiration", + /** + * @name googleAnalytics + * @memberof workbox + * @see module:workbox-google-analytics + */ + googleAnalytics: "offline-ga", + /** + * @name navigationPreload + * @memberof workbox + * @see module:workbox-navigation-preload + */ + navigationPreload: "navigation-preload", + /** + * @name precaching + * @memberof workbox + * @see module:workbox-precaching + */ + precaching: "precaching", + /** + * @name rangeRequests + * @memberof workbox + * @see module:workbox-range-requests + */ + rangeRequests: "range-requests", + /** + * @name routing + * @memberof workbox + * @see module:workbox-routing + */ + routing: "routing", + /** + * @name strategies + * @memberof workbox + * @see module:workbox-strategies + */ + strategies: "strategies", + /** + * @name streams + * @memberof workbox + * @see module:workbox-streams + */ + streams: "streams", + /** + * @name recipes + * @memberof workbox + * @see module:workbox-recipes + */ + recipes: "recipes", +}; + +/** + * This class can be used to make it easy to use the various parts of + * Workbox. + * + * @private + */ +export class WorkboxSW { + /** + * Creates a proxy that automatically loads workbox namespaces on demand. + * + * @private + */ + constructor() { + this.v = {}; + this._options = { + debug: self.location.hostname === "localhost", + modulePathPrefix: null, + modulePathCb: null, + }; + + this._env = this._options.debug ? "dev" : "prod"; + this._modulesLoaded = false; + + return new Proxy(this, { + get(target, key) { + if (target[key]) { + return target[key]; + } + + const moduleName = MODULE_KEY_TO_NAME_MAPPING[key]; + if (moduleName) { + target.loadModule(`workbox-${moduleName}`); + } + + return target[key]; + }, + }); + } + + /** + * Updates the configuration options. You can specify whether to treat as a + * debug build and whether to use a CDN or a specific path when importing + * other workbox-modules + * + * @param {Object} [options] + * @param {boolean} [options.debug] If true, `dev` builds are using, otherwise + * `prod` builds are used. By default, `prod` is used unless on localhost. + * @param {Function} [options.modulePathPrefix] To avoid using the CDN with + * `workbox-sw` set the path prefix of where modules should be loaded from. + * For example `modulePathPrefix: '/third_party/workbox/v3.0.0/'`. + * @param {workbox~ModulePathCallback} [options.modulePathCb] If defined, + * this callback will be responsible for determining the path of each + * workbox module. + * + * @alias workbox.setConfig + */ + setConfig(options = {}) { + if (!this._modulesLoaded) { + Object.assign(this._options, options); + this._env = this._options.debug ? "dev" : "prod"; + } else { + throw new Error("Config must be set before accessing workbox.* modules"); + } + } + + /** + * Load a Workbox module by passing in the appropriate module name. + * + * This is not generally needed unless you know there are modules that are + * dynamically used and you want to safe guard use of the module while the + * user may be offline. + * + * @param {string} moduleName + * + * @alias workbox.loadModule + */ + loadModule(moduleName) { + const modulePath = this._getImportPath(moduleName); + try { + importScripts(modulePath); + this._modulesLoaded = true; + } catch (err) { + // TODO Add context of this error if using the CDN vs the local file. + + // We can't rely on workbox-core being loaded so using console + // eslint-disable-next-line + console.error( + `Unable to import module '${moduleName}' from '${modulePath}'.` + ); + throw err; + } + } + + /** + * This method will get the path / CDN URL to be used for importScript calls. + * + * @param {string} moduleName + * @return {string} URL to the desired module. + * + * @private + */ + _getImportPath(moduleName) { + if (this._options.modulePathCb) { + return this._options.modulePathCb(moduleName, this._options.debug); + } + + // TODO: This needs to be dynamic some how. + let pathParts = [CDN_PATH]; + + const fileName = `${moduleName}.${this._env}.js`; + + const pathPrefix = this._options.modulePathPrefix; + if (pathPrefix) { + // Split to avoid issues with developers ending / not ending with slash + pathParts = pathPrefix.split("/"); + + // We don't need a slash at the end as we will be adding + // a filename regardless + if (pathParts[pathParts.length - 1] === "") { + pathParts.splice(pathParts.length - 1, 1); + } + } + + pathParts.push(fileName); + + return pathParts.join("/"); + } +} diff --git a/packages/workbox-sw/index.mjs b/packages/workbox-sw/index.mjs new file mode 100644 index 00000000..16c72485 --- /dev/null +++ b/packages/workbox-sw/index.mjs @@ -0,0 +1,17 @@ +/* + 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 { WorkboxSW } from "./controllers/WorkboxSW.mjs"; +import "./_version.mjs"; + +/** + * @namespace workbox + */ + +// Don't export anything, just expose a global. +self.workbox = new WorkboxSW(); diff --git a/packages/workbox-sw/package.json b/packages/workbox-sw/package.json new file mode 100644 index 00000000..7a2695fb --- /dev/null +++ b/packages/workbox-sw/package.json @@ -0,0 +1,23 @@ +{ + "name": "@ducanh2912/workbox-sw", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "This module makes it easy to get started with the Workbox service worker libraries.", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw" + ], + "workbox": { + "browserNamespace": "workbox", + "packageType": "sw", + "prodOnly": true + }, + "main": "build/workbox-sw.js", + "module": "index.mjs" +} diff --git a/packages/workbox-webpack-plugin/README.md b/packages/workbox-webpack-plugin/README.md new file mode 100644 index 00000000..92170ccc --- /dev/null +++ b/packages/workbox-webpack-plugin/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developer.chrome.com/docs/workbox/modules/workbox-webpack-plugin/ diff --git a/packages/workbox-webpack-plugin/package.json b/packages/workbox-webpack-plugin/package.json new file mode 100644 index 00000000..0011f3e6 --- /dev/null +++ b/packages/workbox-webpack-plugin/package.json @@ -0,0 +1,42 @@ +{ + "name": "@ducanh2912/workbox-webpack-plugin", + "version": "7.0.0", + "description": "A plugin for your Webpack build process, helping you generate a manifest of local files that workbox-sw should precache.", + "keywords": [ + "workbox", + "workboxjs", + "webpack", + "service worker", + "caching", + "fetch requests", + "offline", + "file manifest" + ], + "workbox": { + "packageType": "node_ts" + }, + "main": "build/index.js", + "types": "build/index.d.ts", + "engines": { + "node": ">=16.0.0" + }, + "dependencies": { + "@ducanh2912/workbox-build": "workspace:*", + "fast-json-stable-stringify": "2.1.0", + "pretty-bytes": "6.1.1", + "upath": "2.0.1", + "webpack-sources": "3.2.3" + }, + "peerDependencies": { + "webpack": "4.4.0 || ^5.9.0" + }, + "devDependencies": { + "@types/node": "20.8.7", + "@types/webpack": "5.28.3" + }, + "author": "Google's Web DevRel Team", + "license": "MIT", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app" +} diff --git a/packages/workbox-webpack-plugin/src/generate-sw.ts b/packages/workbox-webpack-plugin/src/generate-sw.ts new file mode 100644 index 00000000..ff90d514 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/generate-sw.ts @@ -0,0 +1,244 @@ +/* + 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 prettyBytes from "pretty-bytes"; +import webpack from "webpack"; +import type { ManifestEntry, WebpackGenerateSWOptions } from "workbox-build"; +import { bundle } from "workbox-build/build/lib/bundle"; +import { populateSWTemplate } from "workbox-build/build/lib/populate-sw-template"; +import { validateWebpackGenerateSWOptions } from "workbox-build/build/lib/validate-options"; + +import { getManifestEntriesFromCompilation } from "./lib/get-manifest-entries-from-compilation"; +import { getScriptFilesForChunks } from "./lib/get-script-files-for-chunks"; +import { relativeToOutputPath } from "./lib/relative-to-output-path"; + +// webpack v4/v5 compatibility: +// https://github.com/webpack/webpack/issues/11425#issuecomment-686607633 +const { RawSource } = webpack.sources || require("webpack-sources"); + +// Used to keep track of swDest files written by *any* instance of this plugin. +// See https://github.com/GoogleChrome/workbox/issues/2181 +const _generatedAssetNames = new Set(); + +export interface GenerateSWConfig extends WebpackGenerateSWOptions { + manifestEntries?: Array; +} + +/** + * This class supports creating a new, ready-to-use service worker file as + * part of the webpack compilation process. + * + * Use an instance of `GenerateSW` in the + * [`plugins` array](https://webpack.js.org/concepts/plugins/#usage) of a + * webpack config. + * + * ``` + * // The following lists some common options; see the rest of the documentation + * // for the full set of options and defaults. + * new GenerateSW({ + * exclude: [/.../, '...'], + * maximumFileSizeToCacheInBytes: ..., + * navigateFallback: '...', + * runtimeCaching: [{ + * // Routing via a matchCallback function: + * urlPattern: ({request, url}) => ..., + * handler: '...', + * options: { + * cacheName: '...', + * expiration: { + * maxEntries: ..., + * }, + * }, + * }, { + * // Routing via a RegExp: + * urlPattern: new RegExp('...'), + * handler: '...', + * options: { + * cacheName: '...', + * plugins: [..., ...], + * }, + * }], + * skipWaiting: ..., + * }); + * ``` + * + * @memberof module:workbox-webpack-plugin + */ +class GenerateSW { + protected config: GenerateSWConfig; + private alreadyCalled: boolean; + + /** + * Creates an instance of GenerateSW. + */ + constructor(config: GenerateSWConfig = {}) { + this.config = config; + this.alreadyCalled = false; + } + + /** + * @param {Object} [compiler] default compiler object passed from webpack + * + * @private + */ + propagateWebpackConfig(compiler: webpack.Compiler): void { + // Because this.config is listed last, properties that are already set + // there take precedence over derived properties from the compiler. + this.config = Object.assign( + { + mode: compiler.options.mode, + sourcemap: Boolean(compiler.options.devtool), + }, + this.config + ); + } + + /** + * @param {Object} [compiler] default compiler object passed from webpack + * + * @private + */ + apply(compiler: webpack.Compiler): void { + this.propagateWebpackConfig(compiler); + + // webpack v4/v5 compatibility: + // https://github.com/webpack/webpack/issues/11425#issuecomment-690387207 + if (webpack.version.startsWith("4.")) { + compiler.hooks.emit.tapPromise(this.constructor.name, (compilation) => + this.addAssets(compilation).catch((error) => { + compilation.errors.push(error); + }) + ); + } else { + const { PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER } = webpack.Compilation; + // Specifically hook into thisCompilation, as per + // https://github.com/webpack/webpack/issues/11425#issuecomment-690547848 + compiler.hooks.thisCompilation.tap( + this.constructor.name, + (compilation) => { + compilation.hooks.processAssets.tapPromise( + { + name: this.constructor.name, + // TODO(jeffposnick): This may need to change eventually. + // See https://github.com/webpack/webpack/issues/11822#issuecomment-726184972 + stage: PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER - 10, + }, + () => + this.addAssets(compilation).catch( + (error: webpack.WebpackError) => { + compilation.errors.push(error); + } + ) + ); + } + ); + } + } + + /** + * @param {Object} compilation The webpack compilation. + * + * @private + */ + async addAssets(compilation: webpack.Compilation): Promise { + // See https://github.com/GoogleChrome/workbox/issues/1790 + if (this.alreadyCalled) { + const warningMessage = + `${this.constructor.name} has been called ` + + `multiple times, perhaps due to running webpack in --watch mode. The ` + + `precache manifest generated after the first call may be inaccurate! ` + + `Please see https://github.com/GoogleChrome/workbox/issues/1790 for ` + + `more information.`; + + if ( + !compilation.warnings.some( + (warning) => + warning instanceof Error && warning.message === warningMessage + ) + ) { + compilation.warnings.push( + Error(warningMessage) as webpack.WebpackError + ); + } + } else { + this.alreadyCalled = true; + } + + let config: GenerateSWConfig = {}; + try { + // emit might be called multiple times; instead of modifying this.config, + // use a validated copy. + // See https://github.com/GoogleChrome/workbox/issues/2158 + config = validateWebpackGenerateSWOptions(this.config); + } catch (error) { + if (error instanceof Error) { + throw new Error( + `Please check your ${this.constructor.name} plugin ` + + `configuration:\n${error.message}` + ); + } + } + + // Ensure that we don't precache any of the assets generated by *any* + // instance of this plugin. + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + config.exclude!.push(({ asset }) => _generatedAssetNames.has(asset.name)); + + if (config.importScriptsViaChunks) { + // Anything loaded via importScripts() is implicitly cached by the service + // worker, and should not be added to the precache manifest. + config.excludeChunks = (config.excludeChunks || []).concat( + config.importScriptsViaChunks + ); + + const scripts = getScriptFilesForChunks( + compilation, + config.importScriptsViaChunks + ); + + config.importScripts = (config.importScripts || []).concat(scripts); + } + + const { size, sortedEntries } = await getManifestEntriesFromCompilation( + compilation, + config + ); + config.manifestEntries = sortedEntries; + + const unbundledCode = populateSWTemplate(config); + + const files = await bundle({ + babelPresetEnvTargets: config.babelPresetEnvTargets, + inlineWorkboxRuntime: config.inlineWorkboxRuntime, + mode: config.mode, + sourcemap: config.sourcemap, + swDest: relativeToOutputPath(compilation, config.swDest!), + unbundledCode, + }); + + for (const file of files) { + compilation.emitAsset( + file.name, + new RawSource(Buffer.from(file.contents)), + { + // See https://github.com/webpack-contrib/compression-webpack-plugin/issues/218#issuecomment-726196160 + minimized: config.mode === "production", + } + ); + _generatedAssetNames.add(file.name); + } + + if (compilation.getLogger) { + const logger = compilation.getLogger(this.constructor.name); + logger.info(`The service worker at ${config.swDest ?? ""} will precache + ${config.manifestEntries.length} URLs, totaling ${prettyBytes(size)}.`); + } + } +} + +export { GenerateSW }; diff --git a/packages/workbox-webpack-plugin/src/index.ts b/packages/workbox-webpack-plugin/src/index.ts new file mode 100644 index 00000000..540948b3 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/index.ts @@ -0,0 +1,19 @@ +/* + 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 { GenerateSW, GenerateSWConfig } from "./generate-sw"; +import { InjectManifest } from "./inject-manifest"; + +/** + * @module workbox-webpack-plugin + */ +export { GenerateSW, GenerateSWConfig, InjectManifest }; + +// TODO: remove this in v7. +// See https://github.com/GoogleChrome/workbox/issues/3033 +export default { GenerateSW, InjectManifest }; diff --git a/packages/workbox-webpack-plugin/src/inject-manifest.ts b/packages/workbox-webpack-plugin/src/inject-manifest.ts new file mode 100644 index 00000000..9ca0eab4 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/inject-manifest.ts @@ -0,0 +1,371 @@ +/* + 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 stringify from "fast-json-stable-stringify"; +import prettyBytes from "pretty-bytes"; +import upath from "upath"; +import webpack from "webpack"; +import type { WebpackInjectManifestOptions } from "workbox-build"; +import { escapeRegExp } from "workbox-build/build/lib/escape-regexp"; +import { replaceAndUpdateSourceMap } from "workbox-build/build/lib/replace-and-update-source-map"; +import { validateWebpackInjectManifestOptions } from "workbox-build/build/lib/validate-options"; + +import { getManifestEntriesFromCompilation } from "./lib/get-manifest-entries-from-compilation"; +import { getSourcemapAssetName } from "./lib/get-sourcemap-asset-name"; +import { relativeToOutputPath } from "./lib/relative-to-output-path"; +// Used to keep track of swDest files written by *any* instance of this plugin. +// See https://github.com/GoogleChrome/workbox/issues/2181 +const _generatedAssetNames = new Set(); + +// SingleEntryPlugin in v4 was renamed to EntryPlugin in v5. +const SingleEntryPlugin = webpack.EntryPlugin || webpack.SingleEntryPlugin; + +// webpack v4/v5 compatibility: +// https://github.com/webpack/webpack/issues/11425#issuecomment-686607633 +const { RawSource } = webpack.sources || require("webpack-sources"); + +/** + * This class supports compiling a service worker file provided via `swSrc`, + * and injecting into that service worker a list of URLs and revision + * information for precaching based on the webpack asset pipeline. + * + * Use an instance of `InjectManifest` in the + * [`plugins` array](https://webpack.js.org/concepts/plugins/#usage) of a + * webpack config. + * + * In addition to injecting the manifest, this plugin will perform a compilation + * of the `swSrc` file, using the options from the main webpack configuration. + * + * ``` + * // The following lists some common options; see the rest of the documentation + * // for the full set of options and defaults. + * new InjectManifest({ + * exclude: [/.../, '...'], + * maximumFileSizeToCacheInBytes: ..., + * swSrc: '...', + * }); + * ``` + * + * @memberof module:workbox-webpack-plugin + */ +class InjectManifest { + protected config: WebpackInjectManifestOptions; + private alreadyCalled: boolean; + + /** + * Creates an instance of InjectManifest. + */ + constructor(config: WebpackInjectManifestOptions) { + this.config = config; + this.alreadyCalled = false; + } + + /** + * @param {Object} [compiler] default compiler object passed from webpack + * + * @private + */ + propagateWebpackConfig(compiler: webpack.Compiler): void { + // Because this.config is listed last, properties that are already set + // there take precedence over derived properties from the compiler. + this.config = Object.assign( + { + mode: compiler.options.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 + ); + } + + /** + * @param {Object} [compiler] default compiler object passed from webpack + * + * @private + */ + apply(compiler: webpack.Compiler): void { + this.propagateWebpackConfig(compiler); + + compiler.hooks.make.tapPromise(this.constructor.name, (compilation) => + this.handleMake(compilation, compiler).catch( + (error: webpack.WebpackError) => { + compilation.errors.push(error); + } + ) + ); + + // webpack v4/v5 compatibility: + // https://github.com/webpack/webpack/issues/11425#issuecomment-690387207 + if (webpack.version?.startsWith("4.")) { + compiler.hooks.emit.tapPromise(this.constructor.name, (compilation) => + this.addAssets(compilation).catch((error: webpack.WebpackError) => { + compilation.errors.push(error); + }) + ); + } else { + const { PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER } = webpack.Compilation; + // Specifically hook into thisCompilation, as per + // https://github.com/webpack/webpack/issues/11425#issuecomment-690547848 + compiler.hooks.thisCompilation.tap( + this.constructor.name, + (compilation) => { + compilation.hooks.processAssets.tapPromise( + { + name: this.constructor.name, + // TODO(jeffposnick): This may need to change eventually. + // See https://github.com/webpack/webpack/issues/11822#issuecomment-726184972 + stage: PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER - 10, + }, + () => + this.addAssets(compilation).catch( + (error: webpack.WebpackError) => { + compilation.errors.push(error); + } + ) + ); + } + ); + } + } + + /** + * @param {Object} compilation The webpack compilation. + * @param {Object} parentCompiler The webpack parent compiler. + * + * @private + */ + async performChildCompilation( + compilation: webpack.Compilation, + parentCompiler: webpack.Compiler + ): Promise { + const outputOptions = { + path: parentCompiler.options.output.path, + filename: this.config.swDest, + }; + + const childCompiler = compilation.createChildCompiler( + this.constructor.name, + outputOptions, + [] + ); + + childCompiler.context = parentCompiler.context; + childCompiler.inputFileSystem = parentCompiler.inputFileSystem; + childCompiler.outputFileSystem = parentCompiler.outputFileSystem; + + if (Array.isArray(this.config.webpackCompilationPlugins)) { + for (const plugin of this.config.webpackCompilationPlugins) { + // plugin has a generic type, eslint complains for an unsafe + // assign and unsafe use + // eslint-disable-next-line + plugin.apply(childCompiler); + } + } + + new SingleEntryPlugin( + parentCompiler.context, + this.config.swSrc, + this.constructor.name + ).apply(childCompiler); + + await new Promise((resolve, reject) => { + childCompiler.runAsChild((error, _entries, childCompilation) => { + if (error) { + reject(error); + } else { + compilation.warnings = compilation.warnings.concat( + childCompilation?.warnings ?? [] + ); + compilation.errors = compilation.errors.concat( + childCompilation?.errors ?? [] + ); + + resolve(); + } + }); + }); + } + + /** + * @param {Object} compilation The webpack compilation. + * @param {Object} parentCompiler The webpack parent compiler. + * + * @private + */ + addSrcToAssets( + compilation: webpack.Compilation, + parentCompiler: webpack.Compiler + ): void { + // eslint-disable-next-line + const source = (parentCompiler.inputFileSystem as any).readFileSync( + this.config.swSrc + ); + compilation.emitAsset(this.config.swDest!, new RawSource(source)); + } + + /** + * @param {Object} compilation The webpack compilation. + * @param {Object} parentCompiler The webpack parent compiler. + * + * @private + */ + async handleMake( + compilation: webpack.Compilation, + parentCompiler: webpack.Compiler + ): Promise { + try { + this.config = validateWebpackInjectManifestOptions(this.config); + } catch (error) { + if (error instanceof Error) { + throw new Error( + `Please check your ${this.constructor.name} plugin ` + + `configuration:\n${error.message}` + ); + } + } + + this.config.swDest = relativeToOutputPath(compilation, this.config.swDest!); + _generatedAssetNames.add(this.config.swDest); + + if (this.config.compileSrc) { + 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." + ) as webpack.WebpackError + ); + } + } + } + + /** + * @param {Object} compilation The webpack compilation. + * + * @private + */ + async addAssets(compilation: webpack.Compilation): Promise { + // See https://github.com/GoogleChrome/workbox/issues/1790 + if (this.alreadyCalled) { + const warningMessage = + `${this.constructor.name} has been called ` + + `multiple times, perhaps due to running webpack in --watch mode. The ` + + `precache manifest generated after the first call may be inaccurate! ` + + `Please see https://github.com/GoogleChrome/workbox/issues/1790 for ` + + `more information.`; + + if ( + !compilation.warnings.some( + (warning) => + warning instanceof Error && warning.message === warningMessage + ) + ) { + compilation.warnings.push( + new Error(warningMessage) as webpack.WebpackError + ); + } + } else { + this.alreadyCalled = true; + } + + const config = Object.assign({}, this.config); + + // Ensure that we don't precache any of the assets generated by *any* + // instance of this plugin. + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + config.exclude!.push(({ asset }) => _generatedAssetNames.has(asset.name)); + + // See https://webpack.js.org/contribute/plugin-patterns/#monitoring-the-watch-graph + const absoluteSwSrc = upath.resolve(this.config.swSrc); + compilation.fileDependencies.add(absoluteSwSrc); + + const swAsset = compilation.getAsset(config.swDest!); + const swAssetString = swAsset!.source.source().toString(); + + const globalRegexp = new RegExp(escapeRegExp(config.injectionPoint!), "g"); + const injectionResults = swAssetString.match(globalRegexp); + + if (!injectionResults) { + throw new Error( + `Can't find ${config.injectionPoint ?? ""} in your SW source.` + ); + } + if (injectionResults.length !== 1) { + throw new Error( + `Multiple instances of ${config.injectionPoint ?? ""} were ` + + `found in your SW source. Include it only once. For more info, see ` + + `https://github.com/GoogleChrome/workbox/issues/2681` + ); + } + + const { size, sortedEntries } = await getManifestEntriesFromCompilation( + compilation, + config + ); + + let manifestString = stringify(sortedEntries); + if ( + this.config.compileSrc && + // See https://github.com/GoogleChrome/workbox/issues/2729 + !( + compilation.options?.devtool === "eval-cheap-source-map" && + compilation.options.optimization?.minimize + ) + ) { + // See https://github.com/GoogleChrome/workbox/issues/2263 + manifestString = manifestString.replace(/"/g, `'`); + } + + const sourcemapAssetName = getSourcemapAssetName( + compilation, + swAssetString, + config.swDest! + ); + + if (sourcemapAssetName) { + _generatedAssetNames.add(sourcemapAssetName); + const sourcemapAsset = compilation.getAsset(sourcemapAssetName); + const { source, map } = await replaceAndUpdateSourceMap({ + jsFilename: config.swDest!, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + originalMap: JSON.parse(sourcemapAsset!.source.source().toString()), + originalSource: swAssetString, + replaceString: manifestString, + searchString: config.injectionPoint!, + }); + + compilation.updateAsset(sourcemapAssetName, new RawSource(map)); + compilation.updateAsset(config.swDest!, new RawSource(source)); + } else { + // If there's no sourcemap associated with swDest, a simple string + // replacement will suffice. + compilation.updateAsset( + config.swDest!, + new RawSource( + swAssetString.replace(config.injectionPoint!, manifestString) + ) + ); + } + + if (compilation.getLogger) { + const logger = compilation.getLogger(this.constructor.name); + logger.info(`The service worker at ${config.swDest ?? ""} will precache + ${sortedEntries.length} URLs, totaling ${prettyBytes(size)}.`); + } + } +} + +export { InjectManifest }; diff --git a/packages/workbox-webpack-plugin/src/lib/get-asset-hash.ts b/packages/workbox-webpack-plugin/src/lib/get-asset-hash.ts new file mode 100644 index 00000000..53a155cb --- /dev/null +++ b/packages/workbox-webpack-plugin/src/lib/get-asset-hash.ts @@ -0,0 +1,30 @@ +/* + 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 crypto from "crypto"; +import type { Asset } from "webpack"; + +/** + * @param {Asset} asset + * @return {string} The MD5 hash of the asset's source. + * + * @private + */ +export function getAssetHash(asset: Asset): string | null { + // If webpack has the asset marked as immutable, then we don't need to + // use an out-of-band revision for it. + // See https://github.com/webpack/webpack/issues/9038 + if (asset.info && asset.info.immutable) { + return null; + } + + return crypto + .createHash("md5") + .update(Buffer.from(asset.source.source())) + .digest("hex"); +} diff --git a/packages/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts b/packages/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts new file mode 100644 index 00000000..b6ca8ab8 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts @@ -0,0 +1,253 @@ +/* + 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 type { + Asset, + Chunk, + Compilation, + WebpackError} from "webpack"; +import { + ModuleFilenameHelpers +} from "webpack"; +import type { + FileDetails, + ManifestEntry, + WebpackGenerateSWOptions, + WebpackInjectManifestOptions, +} from "workbox-build"; +import { transformManifest } from "workbox-build/build/lib/transform-manifest"; + +import { getAssetHash } from "./get-asset-hash"; +import { resolveWebpackURL } from "./resolve-webpack-url"; + +/** + * For a given asset, checks whether at least one of the conditions matches. + * + * @param {Asset} asset The webpack asset in question. This will be passed + * to any functions that are listed as conditions. + * @param {Compilation} compilation The webpack compilation. This will be passed + * to any functions that are listed as conditions. + * @param {Array} conditions + * @return {boolean} Whether or not at least one condition matches. + * @private + */ +function checkConditions( + asset: Asset, + compilation: Compilation, + + conditions: Array< + //eslint-disable-next-line @typescript-eslint/ban-types + string | RegExp | ((arg0: any) => boolean) + > = [] +): boolean { + for (const condition of conditions) { + if (typeof condition === "function") { + return condition({ asset, compilation }); + //return compilation !== null; + } else { + if (ModuleFilenameHelpers.matchPart(asset.name, condition)) { + return true; + } + } + } + + // We'll only get here if none of the conditions applied. + return false; +} + +/** + * Returns the names of all the assets in all the chunks in a chunk group, + * if provided a chunk group name. + * Otherwise, if provided a chunk name, return all the assets in that chunk. + * Otherwise, if there isn't a chunk group or chunk with that name, return null. + * + * @param {Compilation} compilation + * @param {string} chunkOrGroup + * @return {Array|null} + * @private + */ +function getNamesOfAssetsInChunkOrGroup( + compilation: Compilation, + chunkOrGroup: string +): Array | null { + const chunkGroup = + compilation.namedChunkGroups && + compilation.namedChunkGroups.get(chunkOrGroup); + if (chunkGroup) { + const assetNames = []; + for (const chunk of chunkGroup.chunks) { + assetNames.push(...getNamesOfAssetsInChunk(chunk)); + } + return assetNames; + } else { + const chunk = + compilation.namedChunks && compilation.namedChunks.get(chunkOrGroup); + if (chunk) { + return getNamesOfAssetsInChunk(chunk); + } + } + + // If we get here, there's no chunkGroup or chunk with that name. + return null; +} + +/** + * Returns the names of all the assets in a chunk. + * + * @param {Chunk} chunk + * @return {Array} + * @private + */ +function getNamesOfAssetsInChunk(chunk: Chunk): Array { + const assetNames: Array = []; + + assetNames.push(...chunk.files); + + // This only appears to be set in webpack v5. + if (chunk.auxiliaryFiles) { + assetNames.push(...chunk.auxiliaryFiles); + } + + return assetNames; +} + +/** + * Filters the set of assets out, based on the configuration options provided: + * - chunks and excludeChunks, for chunkName-based criteria. + * - include and exclude, for more general criteria. + * + * @param {Compilation} compilation The webpack compilation. + * @param {Object} config The validated configuration, obtained from the plugin. + * @return {Set} The assets that should be included in the manifest, + * based on the criteria provided. + * @private + */ +function filterAssets( + compilation: Compilation, + config: WebpackInjectManifestOptions | WebpackGenerateSWOptions +): Set { + const filteredAssets = new Set(); + const assets = compilation.getAssets(); + + const allowedAssetNames = new Set(); + // See https://github.com/GoogleChrome/workbox/issues/1287 + if (Array.isArray(config.chunks)) { + for (const name of config.chunks) { + // See https://github.com/GoogleChrome/workbox/issues/2717 + const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup( + compilation, + name + ); + if (assetsInChunkOrGroup) { + for (const assetName of assetsInChunkOrGroup) { + allowedAssetNames.add(assetName); + } + } else { + compilation.warnings.push( + new Error( + `The chunk '${name}' was ` + + `provided in your Workbox chunks config, but was not found in the ` + + `compilation.` + ) as WebpackError + ); + } + } + } + + const deniedAssetNames = new Set(); + if (Array.isArray(config.excludeChunks)) { + for (const name of config.excludeChunks) { + // See https://github.com/GoogleChrome/workbox/issues/2717 + const assetsInChunkOrGroup = getNamesOfAssetsInChunkOrGroup( + compilation, + name + ); + if (assetsInChunkOrGroup) { + for (const assetName of assetsInChunkOrGroup) { + deniedAssetNames.add(assetName); + } + } // Don't warn if the chunk group isn't found. + } + } + + for (const asset of assets) { + // chunk based filtering is funky because: + // - Each asset might belong to one or more chunks. + // - If *any* of those chunk names match our config.excludeChunks, + // then we skip that asset. + // - If the config.chunks is defined *and* there's no match + // between at least one of the chunkNames and one entry, then + // we skip that assets as well. + + if (deniedAssetNames.has(asset.name)) { + continue; + } + + if (Array.isArray(config.chunks) && !allowedAssetNames.has(asset.name)) { + continue; + } + + // Next, check asset-level checks via includes/excludes: + const isExcluded = checkConditions(asset, compilation, config.exclude); + if (isExcluded) { + continue; + } + + // Treat an empty config.includes as an implicit inclusion. + const isIncluded = + !Array.isArray(config.include) || + checkConditions(asset, compilation, config.include); + if (!isIncluded) { + continue; + } + + // If we've gotten this far, then add the asset. + filteredAssets.add(asset); + } + + return filteredAssets; +} + +export async function getManifestEntriesFromCompilation( + compilation: Compilation, + config: WebpackGenerateSWOptions | WebpackInjectManifestOptions +): Promise<{ size: number; sortedEntries: ManifestEntry[] }> { + const filteredAssets = filterAssets(compilation, config); + + const { publicPath } = compilation.options.output; + + const fileDetails = Array.from(filteredAssets).map((asset) => { + return { + file: resolveWebpackURL(publicPath as string, asset.name), + hash: getAssetHash(asset), + size: asset.source.size() || 0, + } as FileDetails; + }); + + const { manifestEntries, size, warnings } = await transformManifest({ + fileDetails, + additionalManifestEntries: config.additionalManifestEntries, + dontCacheBustURLsMatching: config.dontCacheBustURLsMatching, + manifestTransforms: config.manifestTransforms, + maximumFileSizeToCacheInBytes: config.maximumFileSizeToCacheInBytes, + modifyURLPrefix: config.modifyURLPrefix, + transformParam: compilation, + }); + + // See https://github.com/GoogleChrome/workbox/issues/2790 + for (const warning of warnings) { + compilation.warnings.push(new Error(warning) as WebpackError); + } + + // Ensure that the entries are properly sorted by URL. + const sortedEntries = manifestEntries.sort((a, b) => + a.url === b.url ? 0 : a.url > b.url ? 1 : -1 + ); + + return { size, sortedEntries }; +} diff --git a/packages/workbox-webpack-plugin/src/lib/get-script-files-for-chunks.ts b/packages/workbox-webpack-plugin/src/lib/get-script-files-for-chunks.ts new file mode 100644 index 00000000..df482301 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/lib/get-script-files-for-chunks.ts @@ -0,0 +1,51 @@ +/* + 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 upath from "upath"; +import type { Compilation, WebpackError } from "webpack"; + +import { resolveWebpackURL } from "./resolve-webpack-url"; + +export function getScriptFilesForChunks( + compilation: Compilation, + chunkNames: Array +): Array { + const { chunks } = compilation.getStats().toJson({ chunks: true }); + const { publicPath } = compilation.options.output; + const scriptFiles = new Set(); + + for (const chunkName of chunkNames) { + const chunk = chunks!.find((chunk) => chunk.names?.includes(chunkName)); + if (chunk) { + for (const file of chunk?.files ?? []) { + // See https://github.com/GoogleChrome/workbox/issues/2161 + if (upath.extname(file) === ".js") { + scriptFiles.add(resolveWebpackURL(publicPath as string, file)); + } + } + } else { + compilation.warnings.push( + new Error( + `${chunkName} was provided to ` + + `importScriptsViaChunks, but didn't match any named chunks.` + ) as WebpackError + ); + } + } + + if (scriptFiles.size === 0) { + compilation.warnings.push( + new Error( + `There were no assets matching ` + + `importScriptsViaChunks: [${chunkNames.join(" ")}].` + ) as WebpackError + ); + } + + return Array.from(scriptFiles); +} diff --git a/packages/workbox-webpack-plugin/src/lib/get-sourcemap-asset-name.ts b/packages/workbox-webpack-plugin/src/lib/get-sourcemap-asset-name.ts new file mode 100644 index 00000000..4bf9bc77 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/lib/get-sourcemap-asset-name.ts @@ -0,0 +1,54 @@ +/* + 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 upath from "upath"; +import type { Compilation } from "webpack"; +import { getSourceMapURL } from "workbox-build/build/lib/get-source-map-url"; + +/** + * If our bundled swDest 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 + * at the same time. + * + * See https://github.com/GoogleChrome/workbox/issues/2235 + * + * @param {Object} compilation The current webpack compilation. + * @param {string} swContents The contents of the swSrc file, which may or + * may not include a valid sourcemap comment. + * @param {string} swDest The configured swDest value. + * @return {string|undefined} If the swContents contains a valid sourcemap + * comment pointing to an asset present in the compilation, this will return the + * name of that asset. Otherwise, it will return undefined. + * + * @private + */ +export function getSourcemapAssetName( + compilation: Compilation, + swContents: string, + swDest: string +): string | undefined { + const url = getSourceMapURL(swContents); + if (url) { + // Translate the relative URL to what the presumed name for the webpack + // asset should be. + // This *might* not be a valid asset if the sourcemap URL that was found + // was added by another module incidentally. + // See https://github.com/GoogleChrome/workbox/issues/2250 + const swAssetDirname = upath.dirname(swDest); + const sourcemapURLAssetName = upath.normalize( + upath.join(swAssetDirname, url) + ); + + // Not sure if there's a better way to check for asset existence? + if (compilation.getAsset(sourcemapURLAssetName)) { + return sourcemapURLAssetName; + } + } + return undefined; +} diff --git a/packages/workbox-webpack-plugin/src/lib/relative-to-output-path.ts b/packages/workbox-webpack-plugin/src/lib/relative-to-output-path.ts new file mode 100644 index 00000000..d4a5e586 --- /dev/null +++ b/packages/workbox-webpack-plugin/src/lib/relative-to-output-path.ts @@ -0,0 +1,32 @@ +/* + 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 upath from "upath"; +import type { Compilation } from "webpack"; + +/** + * @param {Object} compilation The webpack compilation. + * @param {string} swDest The original swDest value. + * + * @return {string} If swDest was not absolute, the returns swDest as-is. + * Otherwise, returns swDest relative to the compilation's output path. + * + * @private + */ +export function relativeToOutputPath( + compilation: Compilation, + swDest: string +): string { + // See https://github.com/jantimon/html-webpack-plugin/pull/266/files#diff-168726dbe96b3ce427e7fedce31bb0bcR38 + if (upath.resolve(swDest) === upath.normalize(swDest)) { + return upath.relative(compilation.options.output.path!, swDest); + } + + // Otherwise, return swDest as-is. + return swDest; +} diff --git a/packages/workbox-webpack-plugin/src/lib/resolve-webpack-url.ts b/packages/workbox-webpack-plugin/src/lib/resolve-webpack-url.ts new file mode 100644 index 00000000..a03da25f --- /dev/null +++ b/packages/workbox-webpack-plugin/src/lib/resolve-webpack-url.ts @@ -0,0 +1,33 @@ +/* + 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. +*/ + +/** + * Resolves a url in the way that webpack would (with string concatenation) + * + * Use publicPath + filePath instead of url.resolve(publicPath, filePath) see: + * https://webpack.js.org/configuration/output/#output-publicpath + * + * @function resolveWebpackURL + * @param {string} publicPath The publicPath value from webpack's compilation. + * @param {Array} paths File paths to join + * @return {string} Joined file path + * + * @private + */ +export function resolveWebpackURL( + publicPath: string, + ...paths: Array +): string { + // This is a change in webpack v5. + // See https://github.com/jantimon/html-webpack-plugin/pull/1516 + if (publicPath === "auto") { + return paths.join(""); + } else { + return [publicPath, ...paths].join(""); + } +} diff --git a/packages/workbox-webpack-plugin/tsconfig.json b/packages/workbox-webpack-plugin/tsconfig.json new file mode 100644 index 00000000..de55c750 --- /dev/null +++ b/packages/workbox-webpack-plugin/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "esModuleInterop": true, + "module": "CommonJS", + "outDir": "./build", + "resolveJsonModule": true, + "rootDir": "./src", + "target": "ES2018", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [{"path": "../workbox-build/"}] +} diff --git a/packages/workbox-window/README.md b/packages/workbox-window/README.md new file mode 100644 index 00000000..a8c9b9b4 --- /dev/null +++ b/packages/workbox-window/README.md @@ -0,0 +1 @@ +This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-window diff --git a/packages/workbox-window/package.json b/packages/workbox-window/package.json new file mode 100644 index 00000000..8d113ff1 --- /dev/null +++ b/packages/workbox-window/package.json @@ -0,0 +1,30 @@ +{ + "name": "@ducanh2912/workbox-window", + "version": "7.0.0", + "license": "MIT", + "author": "Google's Web DevRel Team", + "description": "Simplifies communications with Workbox packages running in the service worker", + "repository": "DuCanhGH/next-pwa", + "bugs": "https://github.com/DuCanhGH/next-pwa/issues", + "homepage": "https://ducanh-next-pwa.vercel.app", + "keywords": [ + "workbox", + "workboxjs", + "service worker", + "sw", + "window", + "message", + "postMessage" + ], + "workbox": { + "packageType": "window", + "primaryBuild": "build/workbox-window.prod.mjs" + }, + "main": "build/workbox-window.prod.umd.js", + "module": "build/workbox-window.prod.es5.mjs", + "types": "index.d.ts", + "dependencies": { + "@ducanh2912/workbox-core": "7.0.0", + "@types/trusted-types": "2.0.4" + } +} diff --git a/packages/workbox-window/src/Workbox.ts b/packages/workbox-window/src/Workbox.ts new file mode 100644 index 00000000..40326c4a --- /dev/null +++ b/packages/workbox-window/src/Workbox.ts @@ -0,0 +1,743 @@ +/* + 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 { Deferred } from "workbox-core/_private/Deferred.js"; +import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; +import { logger } from "workbox-core/_private/logger.js"; +import { TrustedScriptURL } from "trusted-types/lib"; + +import { messageSW } from "./messageSW.js"; +import { WorkboxEventTarget } from "./utils/WorkboxEventTarget.js"; +import { urlsMatch } from "./utils/urlsMatch.js"; +import { + WorkboxEvent, + WorkboxLifecycleEventMap, +} from "./utils/WorkboxEvent.js"; + +import "./_version.js"; + +// The time a SW must be in the waiting phase before we can conclude +// `skipWaiting()` wasn't called. This 200 amount wasn't scientifically +// chosen, but it seems to avoid false positives in my testing. +const WAITING_TIMEOUT_DURATION = 200; + +// The amount of time after a registration that we can reasonably conclude +// that the registration didn't trigger an update. +const REGISTRATION_TIMEOUT_DURATION = 60000; + +// The de facto standard message that a service worker should be listening for +// to trigger a call to skipWaiting(). +const SKIP_WAITING_MESSAGE = { type: "SKIP_WAITING" }; + +/** + * A class to aid in handling service worker registration, updates, and + * reacting to service worker lifecycle events. + * + * @fires {@link workbox-window.Workbox#message} + * @fires {@link workbox-window.Workbox#installed} + * @fires {@link workbox-window.Workbox#waiting} + * @fires {@link workbox-window.Workbox#controlling} + * @fires {@link workbox-window.Workbox#activated} + * @fires {@link workbox-window.Workbox#redundant} + * @memberof workbox-window + */ +class Workbox extends WorkboxEventTarget { + private readonly _scriptURL: string | TrustedScriptURL; + private readonly _registerOptions: RegistrationOptions = {}; + private _updateFoundCount = 0; + + // Deferreds we can resolve later. + private readonly _swDeferred: Deferred = new Deferred(); + private readonly _activeDeferred: Deferred = new Deferred(); + private readonly _controllingDeferred: Deferred = + new Deferred(); + + private _registrationTime: DOMHighResTimeStamp = 0; + private _isUpdate?: boolean; + private _compatibleControllingSW?: ServiceWorker; + private _registration?: ServiceWorkerRegistration; + private _sw?: ServiceWorker; + private readonly _ownSWs: Set = new Set(); + private _externalSW?: ServiceWorker; + private _waitingTimeout?: number; + + /** + * Creates a new Workbox instance with a script URL and service worker + * options. The script URL and options are the same as those used when + * calling [navigator.serviceWorker.register(scriptURL, options)](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register). + * + * @param {string|TrustedScriptURL} scriptURL The service worker script + * associated with this instance. Using a + * [`TrustedScriptURL`](https://web.dev/trusted-types/) is supported. + * @param {Object} [registerOptions] The service worker options associated + * with this instance. + */ + // eslint-disable-next-line @typescript-eslint/ban-types + constructor(scriptURL: string | TrustedScriptURL, registerOptions: {} = {}) { + super(); + + this._scriptURL = scriptURL; + this._registerOptions = registerOptions; + + // Add a message listener immediately since messages received during + // page load are buffered only until the DOMContentLoaded event: + // https://github.com/GoogleChrome/workbox/issues/2202 + navigator.serviceWorker.addEventListener("message", this._onMessage); + } + + /** + * Registers a service worker for this instances script URL and service + * worker options. By default this method delays registration until after + * the window has loaded. + * + * @param {Object} [options] + * @param {Function} [options.immediate=false] Setting this to true will + * register the service worker immediately, even if the window has + * not loaded (not recommended). + */ + async register({ immediate = false } = {}): Promise< + ServiceWorkerRegistration | undefined + > { + if (process.env.NODE_ENV !== "production") { + if (this._registrationTime) { + logger.error( + "Cannot re-register a Workbox instance after it has " + + "been registered. Create a new instance instead." + ); + return; + } + } + + if (!immediate && document.readyState !== "complete") { + await new Promise((res) => window.addEventListener("load", res)); + } + + // Set this flag to true if any service worker was controlling the page + // at registration time. + this._isUpdate = Boolean(navigator.serviceWorker.controller); + + // Before registering, attempt to determine if a SW is already controlling + // the page, and if that SW script (and version, if specified) matches this + // instance's script. + this._compatibleControllingSW = this._getControllingSWIfCompatible(); + + this._registration = await this._registerScript(); + + // If we have a compatible controller, store the controller as the "own" + // SW, resolve active/controlling deferreds and add necessary listeners. + if (this._compatibleControllingSW) { + this._sw = this._compatibleControllingSW; + this._activeDeferred.resolve(this._compatibleControllingSW); + this._controllingDeferred.resolve(this._compatibleControllingSW); + + this._compatibleControllingSW.addEventListener( + "statechange", + this._onStateChange, + { once: true } + ); + } + + // If there's a waiting service worker with a matching URL before the + // `updatefound` event fires, it likely means that this site is open + // in another tab, or the user refreshed the page (and thus the previous + // page wasn't fully unloaded before this page started loading). + // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting + const waitingSW = this._registration.waiting; + if ( + waitingSW && + urlsMatch(waitingSW.scriptURL, this._scriptURL.toString()) + ) { + // Store the waiting SW as the "own" Sw, even if it means overwriting + // a compatible controller. + this._sw = waitingSW; + + // Run this in the next microtask, so any code that adds an event + // listener after awaiting `register()` will get this event. + dontWaitFor( + Promise.resolve().then(() => { + this.dispatchEvent( + new WorkboxEvent("waiting", { + sw: waitingSW, + wasWaitingBeforeRegister: true, + }) + ); + if (process.env.NODE_ENV !== "production") { + logger.warn( + "A service worker was already waiting to activate " + + "before this script was registered..." + ); + } + }) + ); + } + + // If an "own" SW is already set, resolve the deferred. + if (this._sw) { + this._swDeferred.resolve(this._sw); + this._ownSWs.add(this._sw); + } + + if (process.env.NODE_ENV !== "production") { + logger.log( + "Successfully registered service worker.", + this._scriptURL.toString() + ); + + if (navigator.serviceWorker.controller) { + if (this._compatibleControllingSW) { + logger.debug( + "A service worker with the same script URL " + + "is already controlling this page." + ); + } else { + logger.debug( + "A service worker with a different script URL is " + + "currently controlling the page. The browser is now fetching " + + "the new script now..." + ); + } + } + + const currentPageIsOutOfScope = () => { + const scopeURL = new URL( + this._registerOptions.scope || this._scriptURL.toString(), + document.baseURI + ); + const scopeURLBasePath = new URL("./", scopeURL.href).pathname; + return !location.pathname.startsWith(scopeURLBasePath); + }; + if (currentPageIsOutOfScope()) { + logger.warn( + "The current page is not in scope for the registered " + + "service worker. Was this a mistake?" + ); + } + } + + this._registration.addEventListener("updatefound", this._onUpdateFound); + navigator.serviceWorker.addEventListener( + "controllerchange", + this._onControllerChange + ); + + return this._registration; + } + + /** + * Checks for updates of the registered service worker. + */ + async update(): Promise { + if (!this._registration) { + if (process.env.NODE_ENV !== "production") { + logger.error( + "Cannot update a Workbox instance without " + + "being registered. Register the Workbox instance first." + ); + } + return; + } + + // Try to update registration + await this._registration.update(); + } + + /** + * Resolves to the service worker registered by this instance as soon as it + * is active. If a service worker was already controlling at registration + * time then it will resolve to that if the script URLs (and optionally + * script versions) match, otherwise it will wait until an update is found + * and activates. + * + * @return {Promise} + */ + get active(): Promise { + return this._activeDeferred.promise; + } + + /** + * Resolves to the service worker registered by this instance as soon as it + * is controlling the page. If a service worker was already controlling at + * registration time then it will resolve to that if the script URLs (and + * optionally script versions) match, otherwise it will wait until an update + * is found and starts controlling the page. + * Note: the first time a service worker is installed it will active but + * not start controlling the page unless `clients.claim()` is called in the + * service worker. + * + * @return {Promise} + */ + get controlling(): Promise { + return this._controllingDeferred.promise; + } + + /** + * Resolves with a reference to a service worker that matches the script URL + * of this instance, as soon as it's available. + * + * If, at registration time, there's already an active or waiting service + * worker with a matching script URL, it will be used (with the waiting + * service worker taking precedence over the active service worker if both + * match, since the waiting service worker would have been registered more + * recently). + * If there's no matching active or waiting service worker at registration + * time then the promise will not resolve until an update is found and starts + * installing, at which point the installing service worker is used. + * + * @return {Promise} + */ + getSW(): Promise { + // If `this._sw` is set, resolve with that as we want `getSW()` to + // return the correct (new) service worker if an update is found. + return this._sw !== undefined + ? Promise.resolve(this._sw) + : this._swDeferred.promise; + } + + /** + * Sends the passed data object to the service worker registered by this + * instance (via {@link workbox-window.Workbox#getSW}) and resolves + * with a response (if any). + * + * A response can be set in a message handler in the service worker by + * calling `event.ports[0].postMessage(...)`, which will resolve the promise + * returned by `messageSW()`. If no response is set, the promise will never + * resolve. + * + * @param {Object} data An object to send to the service worker + * @return {Promise} + */ + // We might be able to change the 'data' type to Record in the future. + // eslint-disable-next-line @typescript-eslint/ban-types + async messageSW(data: object): Promise { + const sw = await this.getSW(); + return messageSW(sw, data); + } + + /** + * Sends a `{type: 'SKIP_WAITING'}` message to the service worker that's + * currently in the `waiting` state associated with the current registration. + * + * If there is no current registration or no service worker is `waiting`, + * calling this will have no effect. + */ + messageSkipWaiting(): void { + if (this._registration && this._registration.waiting) { + void messageSW(this._registration.waiting, SKIP_WAITING_MESSAGE); + } + } + + /** + * Checks for a service worker already controlling the page and returns + * it if its script URL matches. + * + * @private + * @return {ServiceWorker|undefined} + */ + private _getControllingSWIfCompatible() { + const controller = navigator.serviceWorker.controller; + if ( + controller && + urlsMatch(controller.scriptURL, this._scriptURL.toString()) + ) { + return controller; + } else { + return undefined; + } + } + + /** + * Registers a service worker for this instances script URL and register + * options and tracks the time registration was complete. + * + * @private + */ + private async _registerScript() { + try { + // this._scriptURL may be a TrustedScriptURL, but there's no support for + // passing that to register() in lib.dom right now. + // https://github.com/GoogleChrome/workbox/issues/2855 + const reg = await navigator.serviceWorker.register( + this._scriptURL as string, + this._registerOptions + ); + + // Keep track of when registration happened, so it can be used in the + // `this._onUpdateFound` heuristic. Also use the presence of this + // property as a way to see if `.register()` has been called. + this._registrationTime = performance.now(); + + return reg; + } catch (error) { + if (process.env.NODE_ENV !== "production") { + logger.error(error); + } + // Re-throw the error. + throw error; + } + } + + /** + * @private + */ + private readonly _onUpdateFound = () => { + // `this._registration` will never be `undefined` after an update is found. + const registration = this._registration!; + const installingSW = registration.installing as ServiceWorker; + + // If the script URL passed to `navigator.serviceWorker.register()` is + // different from the current controlling SW's script URL, we know any + // successful registration calls will trigger an `updatefound` event. + // But if the registered script URL is the same as the current controlling + // SW's script URL, we'll only get an `updatefound` event if the file + // changed since it was last registered. This can be a problem if the user + // opens up the same page in a different tab, and that page registers + // a SW that triggers an update. It's a problem because this page has no + // good way of knowing whether the `updatefound` event came from the SW + // script it registered or from a registration attempt made by a newer + // version of the page running in another tab. + // To minimize the possibility of a false positive, we use the logic here: + const updateLikelyTriggeredExternally = + // Since we enforce only calling `register()` once, and since we don't + // add the `updatefound` event listener until the `register()` call, if + // `_updateFoundCount` is > 0 then it means this method has already + // been called, thus this SW must be external + this._updateFoundCount > 0 || + // If the script URL of the installing SW is different from this + // instance's script URL, we know it's definitely not from our + // registration. + !urlsMatch(installingSW.scriptURL, this._scriptURL.toString()) || + // If all of the above are false, then we use a time-based heuristic: + // Any `updatefound` event that occurs long after our registration is + // assumed to be external. + performance.now() > this._registrationTime + REGISTRATION_TIMEOUT_DURATION + ? // If any of the above are not true, we assume the update was + // triggered by this instance. + true + : false; + + if (updateLikelyTriggeredExternally) { + this._externalSW = installingSW; + registration.removeEventListener("updatefound", this._onUpdateFound); + } else { + // If the update was not triggered externally we know the installing + // SW is the one we registered, so we set it. + this._sw = installingSW; + this._ownSWs.add(installingSW); + this._swDeferred.resolve(installingSW); + + // The `installing` state isn't something we have a dedicated + // callback for, but we do log messages for it in development. + if (process.env.NODE_ENV !== "production") { + if (navigator.serviceWorker.controller) { + logger.log("Updated service worker found. Installing now..."); + } else { + logger.log("Service worker is installing..."); + } + } + } + + // Increment the `updatefound` count, so future invocations of this + // method can be sure they were triggered externally. + ++this._updateFoundCount; + + // Add a `statechange` listener regardless of whether this update was + // triggered externally, since we have callbacks for both. + installingSW.addEventListener("statechange", this._onStateChange); + }; + + /** + * @private + * @param {Event} originalEvent + */ + private readonly _onStateChange = (originalEvent: Event) => { + // `this._registration` will never be `undefined` after an update is found. + const registration = this._registration!; + const sw = originalEvent.target as ServiceWorker; + const { state } = sw; + const isExternal = sw === this._externalSW; + + const eventProps: { + sw: ServiceWorker; + originalEvent: Event; + isUpdate?: boolean; + isExternal: boolean; + } = { + sw, + isExternal, + originalEvent, + }; + if (!isExternal && this._isUpdate) { + eventProps.isUpdate = true; + } + + this.dispatchEvent( + new WorkboxEvent(state as keyof WorkboxLifecycleEventMap, eventProps) + ); + + if (state === "installed") { + // This timeout is used to ignore cases where the service worker calls + // `skipWaiting()` in the install event, thus moving it directly in the + // activating state. (Since all service workers *must* go through the + // waiting phase, the only way to detect `skipWaiting()` called in the + // install event is to observe that the time spent in the waiting phase + // is very short.) + // NOTE: we don't need separate timeouts for the own and external SWs + // since they can't go through these phases at the same time. + this._waitingTimeout = self.setTimeout(() => { + // Ensure the SW is still waiting (it may now be redundant). + if (state === "installed" && registration.waiting === sw) { + this.dispatchEvent(new WorkboxEvent("waiting", eventProps)); + + if (process.env.NODE_ENV !== "production") { + if (isExternal) { + logger.warn( + "An external service worker has installed but is " + + "waiting for this client to close before activating..." + ); + } else { + logger.warn( + "The service worker has installed but is waiting " + + "for existing clients to close before activating..." + ); + } + } + } + }, WAITING_TIMEOUT_DURATION); + } else if (state === "activating") { + clearTimeout(this._waitingTimeout); + if (!isExternal) { + this._activeDeferred.resolve(sw); + } + } + + if (process.env.NODE_ENV !== "production") { + switch (state) { + case "installed": + if (isExternal) { + logger.warn( + "An external service worker has installed. " + + "You may want to suggest users reload this page." + ); + } else { + logger.log("Registered service worker installed."); + } + break; + case "activated": + if (isExternal) { + logger.warn("An external service worker has activated."); + } else { + logger.log("Registered service worker activated."); + if (sw !== navigator.serviceWorker.controller) { + logger.warn( + "The registered service worker is active but " + + "not yet controlling the page. Reload or run " + + "`clients.claim()` in the service worker." + ); + } + } + break; + case "redundant": + if (sw === this._compatibleControllingSW) { + logger.log("Previously controlling service worker now redundant!"); + } else if (!isExternal) { + logger.log("Registered service worker now redundant!"); + } + break; + } + } + }; + + /** + * @private + * @param {Event} originalEvent + */ + private readonly _onControllerChange = (originalEvent: Event) => { + const sw = this._sw; + const isExternal = sw !== navigator.serviceWorker.controller; + + // Unconditionally dispatch the controlling event, with isExternal set + // to distinguish between controller changes due to the initial registration + // vs. an update-check or other tab's registration. + // See https://github.com/GoogleChrome/workbox/issues/2786 + this.dispatchEvent( + new WorkboxEvent("controlling", { + isExternal, + originalEvent, + sw, + isUpdate: this._isUpdate, + }) + ); + + if (!isExternal) { + if (process.env.NODE_ENV !== "production") { + logger.log("Registered service worker now controlling this page."); + } + this._controllingDeferred.resolve(sw); + } + }; + + /** + * @private + * @param {Event} originalEvent + */ + private readonly _onMessage = async (originalEvent: MessageEvent) => { + // Can't change type 'any' of data. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { data, ports, source } = originalEvent; + + // Wait until there's an "own" service worker. This is used to buffer + // `message` events that may be received prior to calling `register()`. + await this.getSW(); + + // If the service worker that sent the message is in the list of own + // service workers for this instance, dispatch a `message` event. + // NOTE: we check for all previously owned service workers rather than + // just the current one because some messages (e.g. cache updates) use + // a timeout when sent and may be delayed long enough for a service worker + // update to be found. + if (this._ownSWs.has(source as ServiceWorker)) { + this.dispatchEvent( + new WorkboxEvent("message", { + // Can't change type 'any' of data. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + data, + originalEvent, + ports, + sw: source as ServiceWorker, + }) + ); + } + }; +} + +export { Workbox }; + +// The jsdoc comments below outline the events this instance may dispatch: +// ----------------------------------------------------------------------- + +/** + * The `message` event is dispatched any time a `postMessage` is received. + * + * @event workbox-window.Workbox#message + * @type {WorkboxEvent} + * @property {*} data The `data` property from the original `message` event. + * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent} + * event. + * @property {string} type `message`. + * @property {MessagePort[]} ports The `ports` value from `originalEvent`. + * @property {Workbox} target The `Workbox` instance. + */ + +/** + * The `installed` event is dispatched if the state of a + * {@link workbox-window.Workbox} instance's + * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker} + * changes to `installed`. + * + * Then can happen either the very first time a service worker is installed, + * or after an update to the current service worker is found. In the case + * of an update being found, the event's `isUpdate` property will be `true`. + * + * @event workbox-window.Workbox#installed + * @type {WorkboxEvent} + * @property {ServiceWorker} sw The service worker instance. + * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange} + * event. + * @property {boolean|undefined} isUpdate True if a service worker was already + * controlling when this `Workbox` instance called `register()`. + * @property {boolean|undefined} isExternal True if this event is associated + * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}. + * @property {string} type `installed`. + * @property {Workbox} target The `Workbox` instance. + */ + +/** + * The `waiting` event is dispatched if the state of a + * {@link workbox-window.Workbox} instance's + * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw} + * changes to `installed` and then doesn't immediately change to `activating`. + * It may also be dispatched if a service worker with the same + * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL} + * was already waiting when the {@link workbox-window.Workbox#register} + * method was called. + * + * @event workbox-window.Workbox#waiting + * @type {WorkboxEvent} + * @property {ServiceWorker} sw The service worker instance. + * @property {Event|undefined} originalEvent The original + * [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange} + * event, or `undefined` in the case where the service worker was waiting + * to before `.register()` was called. + * @property {boolean|undefined} isUpdate True if a service worker was already + * controlling when this `Workbox` instance called `register()`. + * @property {boolean|undefined} isExternal True if this event is associated + * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}. + * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with + * a matching `scriptURL` was already waiting when this `Workbox` + * instance called `register()`. + * @property {string} type `waiting`. + * @property {Workbox} target The `Workbox` instance. + */ + +/** + * The `controlling` event is dispatched if a + * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange} + * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer} + * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL} + * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller} + * matches the `scriptURL` of the `Workbox` instance's + * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}. + * + * @event workbox-window.Workbox#controlling + * @type {WorkboxEvent} + * @property {ServiceWorker} sw The service worker instance. + * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange} + * event. + * @property {boolean|undefined} isUpdate True if a service worker was already + * controlling when this service worker was registered. + * @property {boolean|undefined} isExternal True if this event is associated + * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}. + * @property {string} type `controlling`. + * @property {Workbox} target The `Workbox` instance. + */ + +/** + * The `activated` event is dispatched if the state of a + * {@link workbox-window.Workbox} instance's + * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker} + * changes to `activated`. + * + * @event workbox-window.Workbox#activated + * @type {WorkboxEvent} + * @property {ServiceWorker} sw The service worker instance. + * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange} + * event. + * @property {boolean|undefined} isUpdate True if a service worker was already + * controlling when this `Workbox` instance called `register()`. + * @property {boolean|undefined} isExternal True if this event is associated + * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}. + * @property {string} type `activated`. + * @property {Workbox} target The `Workbox` instance. + */ + +/** + * The `redundant` event is dispatched if the state of a + * {@link workbox-window.Workbox} instance's + * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw} + * changes to `redundant`. + * + * @event workbox-window.Workbox#redundant + * @type {WorkboxEvent} + * @property {ServiceWorker} sw The service worker instance. + * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange} + * event. + * @property {boolean|undefined} isUpdate True if a service worker was already + * controlling when this `Workbox` instance called `register()`. + * @property {string} type `redundant`. + * @property {Workbox} target The `Workbox` instance. + */ diff --git a/packages/workbox-window/src/_version.ts b/packages/workbox-window/src/_version.ts new file mode 100644 index 00000000..eab8e54f --- /dev/null +++ b/packages/workbox-window/src/_version.ts @@ -0,0 +1,4 @@ +// @ts-ignore +try { + self["workbox:window:7.0.0"] && _(); +} catch (e) {} diff --git a/packages/workbox-window/src/index.ts b/packages/workbox-window/src/index.ts new file mode 100644 index 00000000..1e9c8b3d --- /dev/null +++ b/packages/workbox-window/src/index.ts @@ -0,0 +1,20 @@ +/* + 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 { messageSW } from "./messageSW.js"; +import { Workbox } from "./Workbox.js"; + +import "./_version.js"; + +/** + * @module workbox-window + */ +export { messageSW, Workbox }; + +// See https://github.com/GoogleChrome/workbox/issues/2770 +export * from "./utils/WorkboxEvent.js"; diff --git a/packages/workbox-window/src/messageSW.ts b/packages/workbox-window/src/messageSW.ts new file mode 100644 index 00000000..08512bd9 --- /dev/null +++ b/packages/workbox-window/src/messageSW.ts @@ -0,0 +1,37 @@ +/* + 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 "./_version.js"; + +/** + * Sends a data object to a service worker via `postMessage` and resolves with + * a response (if any). + * + * A response can be set in a message handler in the service worker by + * calling `event.ports[0].postMessage(...)`, which will resolve the promise + * returned by `messageSW()`. If no response is set, the promise will not + * resolve. + * + * @param {ServiceWorker} sw The service worker to send the message to. + * @param {Object} data An object to send to the service worker. + * @return {Promise} + * @memberof workbox-window + */ +// Better not change type of data. +// eslint-disable-next-line @typescript-eslint/ban-types +function messageSW(sw: ServiceWorker, data: {}): Promise { + return new Promise((resolve) => { + const messageChannel = new MessageChannel(); + messageChannel.port1.onmessage = (event: MessageEvent) => { + resolve(event.data); + }; + sw.postMessage(data, [messageChannel.port2]); + }); +} + +export { messageSW }; diff --git a/packages/workbox-window/src/utils/WorkboxEvent.ts b/packages/workbox-window/src/utils/WorkboxEvent.ts new file mode 100644 index 00000000..d003d10f --- /dev/null +++ b/packages/workbox-window/src/utils/WorkboxEvent.ts @@ -0,0 +1,59 @@ +/* + 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 { WorkboxEventTarget } from "./WorkboxEventTarget.js"; +import "../_version.js"; + +/** + * A minimal `Event` subclass shim. + * This doesn't *actually* subclass `Event` because not all browsers support + * constructable `EventTarget`, and using a real `Event` will error. + * @private + */ +export class WorkboxEvent { + target?: WorkboxEventTarget; + sw?: ServiceWorker; + originalEvent?: Event; + isExternal?: boolean; + + constructor( + public type: K, + props: Omit + ) { + Object.assign(this, props); + } +} + +export interface WorkboxMessageEvent extends WorkboxEvent<"message"> { + data: any; + originalEvent: Event; + ports: readonly MessagePort[]; +} + +export interface WorkboxLifecycleEvent + extends WorkboxEvent { + isUpdate?: boolean; +} + +export interface WorkboxLifecycleWaitingEvent extends WorkboxLifecycleEvent { + wasWaitingBeforeRegister?: boolean; +} + +export interface WorkboxLifecycleEventMap { + installing: WorkboxLifecycleEvent; + installed: WorkboxLifecycleEvent; + waiting: WorkboxLifecycleWaitingEvent; + activating: WorkboxLifecycleEvent; + activated: WorkboxLifecycleEvent; + controlling: WorkboxLifecycleEvent; + redundant: WorkboxLifecycleEvent; +} + +export interface WorkboxEventMap extends WorkboxLifecycleEventMap { + message: WorkboxMessageEvent; +} diff --git a/packages/workbox-window/src/utils/WorkboxEventTarget.ts b/packages/workbox-window/src/utils/WorkboxEventTarget.ts new file mode 100644 index 00000000..4bb5999c --- /dev/null +++ b/packages/workbox-window/src/utils/WorkboxEventTarget.ts @@ -0,0 +1,77 @@ +/* + 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 { WorkboxEvent, WorkboxEventMap } from "./WorkboxEvent.js"; + +export type ListenerCallback = (event: WorkboxEvent) => any; + +/** + * A minimal `EventTarget` shim. + * This is necessary because not all browsers support constructable + * `EventTarget`, so using a real `EventTarget` will error. + * @private + */ +export class WorkboxEventTarget { + private readonly _eventListenerRegistry: Map< + keyof WorkboxEventMap, + Set + > = new Map(); + + /** + * @param {string} type + * @param {Function} listener + * @private + */ + addEventListener( + type: K, + listener: (event: WorkboxEventMap[K]) => any + ): void { + const foo = this._getEventListenersByType(type); + foo.add(listener as ListenerCallback); + } + + /** + * @param {string} type + * @param {Function} listener + * @private + */ + removeEventListener( + type: K, + listener: (event: WorkboxEventMap[K]) => any + ): void { + this._getEventListenersByType(type).delete(listener as ListenerCallback); + } + + /** + * @param {Object} event + * @private + */ + dispatchEvent(event: WorkboxEvent): void { + event.target = this; + + const listeners = this._getEventListenersByType(event.type); + for (const listener of listeners) { + listener(event); + } + } + + /** + * Returns a Set of listeners associated with the passed event type. + * If no handlers have been registered, an empty Set is returned. + * + * @param {string} type The event type. + * @return {Set} An array of handler functions. + * @private + */ + private _getEventListenersByType(type: keyof WorkboxEventMap) { + if (!this._eventListenerRegistry.has(type)) { + this._eventListenerRegistry.set(type, new Set()); + } + return this._eventListenerRegistry.get(type)!; + } +} diff --git a/packages/workbox-window/src/utils/urlsMatch.ts b/packages/workbox-window/src/utils/urlsMatch.ts new file mode 100644 index 00000000..1620bbf0 --- /dev/null +++ b/packages/workbox-window/src/utils/urlsMatch.ts @@ -0,0 +1,23 @@ +/* + 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 "../_version.js"; + +/** + * Returns true if two URLs have the same `.href` property. The URLS can be + * relative, and if they are the current location href is used to resolve URLs. + * + * @private + * @param {string} url1 + * @param {string} url2 + * @return {boolean} + */ +export function urlsMatch(url1: string, url2: string): boolean { + const { href } = location; + return new URL(url1, href).href === new URL(url2, href).href; +} diff --git a/packages/workbox-window/tsconfig.json b/packages/workbox-window/tsconfig.json new file mode 100644 index 00000000..79279e16 --- /dev/null +++ b/packages/workbox-window/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "lib": ["es2017", "dom"], + "outDir": "./", + "rootDir": "./src", + "tsBuildInfoFile": "./tsconfig.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "references": [ + { + "path": "../workbox-core/" + } + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e92ff8c8..30ae8167 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,17 +21,17 @@ importers: specifier: workspace:* version: link:packages/next-sw '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/shell-quote': specifier: 1.7.2 version: 1.7.2 '@typescript-eslint/eslint-plugin': - specifier: 6.7.5 - version: 6.7.5(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + specifier: 6.8.0 + version: 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.3.0-dev.20231018) '@typescript-eslint/parser': - specifier: 6.7.5 - version: 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + specifier: 6.8.0 + version: 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) cross-env: specifier: 7.0.3 version: 7.0.3 @@ -39,8 +39,8 @@ importers: specifier: 8.51.0 version: 8.51.0 eslint-config-next: - specifier: 13.5.4 - version: 13.5.4(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + specifier: 13.5.5 + version: 13.5.5(eslint@8.51.0)(typescript@5.3.0-dev.20231018) eslint-config-prettier: specifier: 9.0.0 version: 9.0.0(eslint@8.51.0) @@ -49,7 +49,7 @@ importers: version: 1.10.15(eslint@8.51.0) eslint-plugin-import: specifier: 2.28.1 - version: 2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) + version: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) eslint-plugin-simple-import-sort: specifier: 10.0.0 version: 10.0.0(eslint@8.51.0) @@ -61,19 +61,19 @@ importers: version: 8.0.3 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.8.4) + version: 29.7.0(@types/node@20.8.7) lint-staged: - specifier: 14.0.1 - version: 14.0.1 + specifier: 15.0.1 + version: 15.0.1 npm-check-updates: - specifier: 16.14.5 - version: 16.14.5 + specifier: 16.14.6 + version: 16.14.6 prettier: specifier: 3.0.3 version: 3.0.3 prettier-plugin-tailwindcss: - specifier: 0.5.5 - version: 0.5.5(prettier@3.0.3) + specifier: 0.5.6 + version: 0.5.6(prettier@3.0.3) rimraf: specifier: 5.0.5 version: 5.0.5 @@ -87,8 +87,8 @@ importers: specifier: 1.10.15 version: 1.10.15 typescript: - specifier: 5.3.0-dev.20231011 - version: 5.3.0-dev.20231011 + specifier: 5.3.0-dev.20231018 + version: 5.3.0-dev.20231018 docs: dependencies: @@ -96,8 +96,8 @@ importers: specifier: workspace:* version: link:../packages/next-pwa '@mantine/hooks': - specifier: 7.1.2 - version: 7.1.2(react@18.2.0) + specifier: 7.1.3 + version: 7.1.3(react@18.2.0) '@tabler/icons-react': specifier: 2.39.0 version: 2.39.0(react@18.2.0) @@ -114,11 +114,11 @@ importers: specifier: 11.9.0 version: 11.9.0 next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) next-contentlayer: specifier: 0.3.4 - version: 0.3.4(contentlayer@0.3.4)(esbuild@0.17.19)(next@13.5.4)(react-dom@18.2.0)(react@18.2.0) + version: 0.3.4(contentlayer@0.3.4)(esbuild@0.17.19)(next@13.5.5)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -142,20 +142,20 @@ importers: version: 4.4.3(@types/react@18.2.28)(react@18.2.0) devDependencies: '@types/extend': + specifier: 3.0.3 + version: 3.0.3 + '@types/hast': specifier: 3.0.2 version: 3.0.2 - '@types/hast': - specifier: 3.0.1 - version: 3.0.1 '@types/mdast': - specifier: 4.0.1 - version: 4.0.1 + specifier: 4.0.2 + version: 4.0.2 '@types/mdx': specifier: 2.0.8 version: 2.0.8 '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -208,11 +208,11 @@ importers: specifier: 3.3.3 version: 3.3.3 typescript: - specifier: 5.3.0-dev.20231011 - version: 5.3.0-dev.20231011 + specifier: 5.3.0-dev.20231018 + version: 5.3.0-dev.20231018 unified: - specifier: 10.1.2 - version: 10.1.2 + specifier: 11.0.3 + version: 11.0.3 unist-util-is: specifier: 6.0.0 version: 6.0.0 @@ -226,8 +226,8 @@ importers: specifier: latest version: link:../../packages/next-pwa next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -236,8 +236,8 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -260,11 +260,11 @@ importers: specifier: 7.0.3 version: 7.0.3 fastify: - specifier: 4.24.0 - version: 4.24.0 + specifier: 4.24.2 + version: 4.24.2 next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -273,11 +273,11 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@swc/core': - specifier: 1.3.92 - version: 1.3.92 + specifier: 1.3.93 + version: 1.3.93 '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -292,7 +292,7 @@ importers: version: 5.0.5 ts-node: specifier: 10.9.1 - version: 10.9.1(@swc/core@1.3.92)(@types/node@20.8.4)(typescript@5.2.2) + version: 10.9.1(@swc/core@1.3.93)(@types/node@20.8.7)(typescript@5.2.2) typescript: specifier: 5.2.2 version: 5.2.2 @@ -303,8 +303,8 @@ importers: specifier: latest version: link:../../packages/next-pwa next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -313,8 +313,8 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -331,8 +331,8 @@ importers: specifier: latest version: link:../../packages/next-pwa next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -341,8 +341,8 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -371,11 +371,11 @@ importers: specifier: 23.5.1 version: 23.5.1 next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) next-i18next: specifier: 14.0.3 - version: 14.0.3(i18next@23.5.1)(next@13.5.4)(react-i18next@13.2.2)(react@18.2.0) + version: 14.0.3(i18next@23.5.1)(next@13.5.5)(react-i18next@13.3.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -383,12 +383,12 @@ importers: specifier: 18.2.0 version: 18.2.0(react@18.2.0) react-i18next: - specifier: 13.2.2 - version: 13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.3.0 + version: 13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -405,8 +405,8 @@ importers: specifier: latest version: link:../../packages/next-pwa next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -415,8 +415,8 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -433,8 +433,8 @@ importers: specifier: latest version: link:../../packages/next-pwa next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -446,8 +446,8 @@ importers: version: 0.32.6 devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -464,8 +464,8 @@ importers: specifier: latest version: link:../../packages/next-pwa next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -477,8 +477,8 @@ importers: version: 3.6.6 devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -498,8 +498,8 @@ importers: specifier: latest version: link:../../packages/next-sw next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -508,8 +508,8 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -523,14 +523,14 @@ importers: packages/constants: devDependencies: '@swc/core': - specifier: 1.3.92 - version: 1.3.92 + specifier: 1.3.93 + version: 1.3.93 packages/next-pwa: dependencies: clean-webpack-plugin: specifier: 4.0.0 - version: 4.0.0(webpack@5.88.2) + version: 4.0.0(webpack@5.89.0) fast-glob: specifier: 3.3.1 version: 3.3.1 @@ -539,7 +539,7 @@ importers: version: 7.5.4 terser-webpack-plugin: specifier: 5.3.9 - version: 5.3.9(@swc/core@1.3.92)(webpack@5.88.2) + version: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0) workbox-build: specifier: 7.0.0 version: 7.0.0 @@ -548,7 +548,7 @@ importers: version: 7.0.0 workbox-webpack-plugin: specifier: 7.0.0 - version: 7.0.0(webpack@5.88.2) + version: 7.0.0(webpack@5.89.0) workbox-window: specifier: 7.0.0 version: 7.0.0 @@ -570,16 +570,16 @@ importers: version: 15.2.3(rollup@3.28.1) '@rollup/plugin-swc': specifier: 0.2.1 - version: 0.2.1(@swc/core@1.3.92)(rollup@3.28.1) + version: 0.2.1(@swc/core@1.3.93)(rollup@3.28.1) '@rollup/plugin-typescript': specifier: 11.1.5 - version: 11.1.5(rollup@3.28.1)(tslib@2.6.2)(typescript@5.3.0-dev.20231011) + version: 11.1.5(rollup@3.28.1)(tslib@2.6.2)(typescript@5.3.0-dev.20231018) '@swc/core': - specifier: 1.3.92 - version: 1.3.92 + specifier: 1.3.93 + version: 1.3.93 '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 '@types/semver': specifier: 7.5.3 version: 7.5.3 @@ -587,8 +587,8 @@ importers: specifier: 5.3.0 version: 5.3.0 next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -600,16 +600,16 @@ importers: version: 3.28.1 rollup-plugin-dts: specifier: 6.0.2 - version: 6.0.2(rollup@3.28.1)(typescript@5.3.0-dev.20231011) + version: 6.0.2(rollup@3.28.1)(typescript@5.3.0-dev.20231018) type-fest: specifier: 4.4.0 version: 4.4.0 typescript: - specifier: 5.3.0-dev.20231011 - version: 5.3.0-dev.20231011 + specifier: 5.3.0-dev.20231018 + version: 5.3.0-dev.20231018 webpack: - specifier: 5.88.2 - version: 5.88.2(@swc/core@1.3.92) + specifier: 5.89.0 + version: 5.89.0(@swc/core@1.3.93) packages/next-pwa/__tests__: devDependencies: @@ -617,8 +617,8 @@ importers: specifier: 29.7.0 version: 29.7.0 '@types/jest': - specifier: 29.5.5 - version: 29.5.5 + specifier: 29.5.6 + version: 29.5.6 '@types/react': specifier: 18.2.28 version: 18.2.28 @@ -633,10 +633,10 @@ importers: dependencies: clean-webpack-plugin: specifier: 4.0.0 - version: 4.0.0(webpack@5.88.2) + version: 4.0.0(webpack@5.89.0) terser-webpack-plugin: specifier: 5.3.9 - version: 5.3.9(@swc/core@1.3.92)(webpack@5.88.2) + version: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0) devDependencies: '@ducanh2912/constants': specifier: workspace:* @@ -652,22 +652,22 @@ importers: version: 15.2.3(rollup@3.28.1) '@rollup/plugin-swc': specifier: 0.2.1 - version: 0.2.1(@swc/core@1.3.92)(rollup@3.28.1) + version: 0.2.1(@swc/core@1.3.93)(rollup@3.28.1) '@rollup/plugin-typescript': specifier: 11.1.5 - version: 11.1.5(rollup@3.28.1)(tslib@2.6.2)(typescript@5.3.0-dev.20231011) + version: 11.1.5(rollup@3.28.1)(tslib@2.6.2)(typescript@5.3.0-dev.20231018) '@swc/core': - specifier: 1.3.92 - version: 1.3.92 + specifier: 1.3.93 + version: 1.3.93 '@types/node': - specifier: 20.8.4 - version: 20.8.4 + specifier: 20.8.7 + version: 20.8.7 chalk: specifier: 5.3.0 version: 5.3.0 next: - specifier: 13.5.4 - version: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + specifier: 13.5.5 + version: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -679,13 +679,13 @@ importers: version: 3.28.1 rollup-plugin-dts: specifier: 6.0.2 - version: 6.0.2(rollup@3.28.1)(typescript@5.3.0-dev.20231011) + version: 6.0.2(rollup@3.28.1)(typescript@5.3.0-dev.20231018) typescript: - specifier: 5.3.0-dev.20231011 - version: 5.3.0-dev.20231011 + specifier: 5.3.0-dev.20231018 + version: 5.3.0-dev.20231018 webpack: - specifier: 5.88.2 - version: 5.88.2(@swc/core@1.3.92) + specifier: 5.89.0 + version: 5.89.0(@swc/core@1.3.93) packages/test-utils: dependencies: @@ -703,8 +703,8 @@ importers: specifier: 11.0.2 version: 11.0.2 '@types/jest': - specifier: 29.5.5 - version: 29.5.5 + specifier: 29.5.6 + version: 29.5.6 packages/utils: dependencies: @@ -723,10 +723,10 @@ importers: version: 15.2.3(rollup@3.28.1) '@rollup/plugin-swc': specifier: 0.2.1 - version: 0.2.1(@swc/core@1.3.92)(rollup@3.28.1) + version: 0.2.1(@swc/core@1.3.93)(rollup@3.28.1) '@swc/core': - specifier: 1.3.92 - version: 1.3.92 + specifier: 1.3.93 + version: 1.3.93 '@types/semver': specifier: 7.5.3 version: 7.5.3 @@ -735,13 +735,341 @@ importers: version: 3.28.1 terser-webpack-plugin: specifier: 5.3.9 - version: 5.3.9(@swc/core@1.3.92)(webpack@5.88.2) + version: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0) type-fest: specifier: 4.4.0 version: 4.4.0 typescript: - specifier: 5.3.0-dev.20231011 - version: 5.3.0-dev.20231011 + specifier: 5.3.0-dev.20231018 + version: 5.3.0-dev.20231018 + + packages/workbox-background-sync: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + idb: + specifier: 7.1.1 + version: 7.1.1 + + packages/workbox-broadcast-update: + dependencies: + '@ducanh2912/workbox-core': + specifier: 7.0.0 + version: link:../workbox-core + + packages/workbox-build: + dependencies: + '@apideck/better-ajv-errors': + specifier: 0.3.6 + version: 0.3.6(ajv@8.12.0) + '@babel/core': + specifier: 7.23.2 + version: 7.23.2 + '@babel/preset-env': + specifier: 7.23.2 + version: 7.23.2(@babel/core@7.23.2) + '@babel/runtime': + specifier: 7.23.2 + version: 7.23.2 + '@ducanh2912/workbox-background-sync': + specifier: workspace:* + version: link:../workbox-background-sync + '@ducanh2912/workbox-broadcast-update': + specifier: workspace:* + version: link:../workbox-broadcast-update + '@ducanh2912/workbox-cacheable-response': + specifier: workspace:* + version: link:../workbox-cacheable-response + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + '@ducanh2912/workbox-expiration': + specifier: workspace:* + version: link:../workbox-expiration + '@ducanh2912/workbox-google-analytics': + specifier: workspace:* + version: link:../workbox-google-analytics + '@ducanh2912/workbox-navigation-preload': + specifier: workspace:* + version: link:../workbox-navigation-preload + '@ducanh2912/workbox-precaching': + specifier: workspace:* + version: link:../workbox-precaching + '@ducanh2912/workbox-range-requests': + specifier: workspace:* + version: link:../workbox-range-requests + '@ducanh2912/workbox-recipes': + specifier: workspace:* + version: link:../workbox-recipes + '@ducanh2912/workbox-routing': + specifier: workspace:* + version: link:../workbox-routing + '@ducanh2912/workbox-strategies': + specifier: workspace:* + version: link:../workbox-strategies + '@ducanh2912/workbox-streams': + specifier: workspace:* + version: link:../workbox-streams + '@ducanh2912/workbox-sw': + specifier: workspace:* + version: link:../workbox-sw + '@ducanh2912/workbox-window': + specifier: workspace:* + version: link:../workbox-window + '@rollup/plugin-babel': + specifier: 6.0.4 + version: 6.0.4(@babel/core@7.23.2)(rollup@3.28.1) + '@rollup/plugin-node-resolve': + specifier: 15.2.3 + version: 15.2.3(rollup@3.28.1) + '@rollup/plugin-replace': + specifier: 5.0.4 + version: 5.0.4(rollup@3.28.1) + '@rollup/plugin-terser': + specifier: 0.4.4 + version: 0.4.4(rollup@3.28.1) + '@surma/rollup-plugin-off-main-thread': + specifier: 2.2.3 + version: 2.2.3 + ajv: + specifier: 8.12.0 + version: 8.12.0 + common-tags: + specifier: 1.8.2 + version: 1.8.2 + fast-json-stable-stringify: + specifier: 2.1.0 + version: 2.1.0 + fs-extra: + specifier: 11.1.1 + version: 11.1.1 + glob: + specifier: 10.3.10 + version: 10.3.10 + lodash: + specifier: 4.17.21 + version: 4.17.21 + pretty-bytes: + specifier: 6.1.1 + version: 6.1.1 + rollup: + specifier: 3.28.1 + version: 3.28.1 + source-map: + specifier: 0.8.0-beta.0 + version: 0.8.0-beta.0 + stringify-object: + specifier: 5.0.0 + version: 5.0.0 + strip-comments: + specifier: 2.0.1 + version: 2.0.1 + tempy: + specifier: 3.1.0 + version: 3.1.0 + upath: + specifier: 2.0.1 + version: 2.0.1 + devDependencies: + '@types/node': + specifier: 20.8.7 + version: 20.8.7 + + packages/workbox-cacheable-response: + dependencies: + '@ducanh2912/workbox-core': + specifier: 7.0.0 + version: link:../workbox-core + + packages/workbox-cli: + dependencies: + '@ducanh2912/workbox-build': + specifier: workspace:* + version: link:../workbox-build + chalk: + specifier: 5.3.0 + version: 5.3.0 + chokidar: + specifier: 3.5.3 + version: 3.5.3 + common-tags: + specifier: 1.8.2 + version: 1.8.2 + fs-extra: + specifier: 11.1.1 + version: 11.1.1 + glob: + specifier: 10.3.10 + version: 10.3.10 + inquirer: + specifier: 9.2.11 + version: 9.2.11 + meow: + specifier: 12.1.1 + version: 12.1.1 + ora: + specifier: 7.0.1 + version: 7.0.1 + pretty-bytes: + specifier: 6.1.1 + version: 6.1.1 + stringify-object: + specifier: 5.0.0 + version: 5.0.0 + upath: + specifier: 2.0.1 + version: 2.0.1 + update-notifier: + specifier: 6.0.2 + version: 6.0.2 + devDependencies: + '@types/common-tags': + specifier: 1.8.3 + version: 1.8.3 + '@types/fs-extra': + specifier: 11.0.2 + version: 11.0.2 + '@types/inquirer': + specifier: 9.0.5 + version: 9.0.5 + '@types/stringify-object': + specifier: 4.0.3 + version: 4.0.3 + '@types/update-notifier': + specifier: 6.0.5 + version: 6.0.5 + + packages/workbox-core: {} + + packages/workbox-expiration: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + idb: + specifier: 7.1.1 + version: 7.1.1 + + packages/workbox-google-analytics: + dependencies: + '@ducanh2912/workbox-background-sync': + specifier: workspace:* + version: link:../workbox-background-sync + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + '@ducanh2912/workbox-routing': + specifier: workspace:* + version: link:../workbox-routing + '@ducanh2912/workbox-strategies': + specifier: workspace:* + version: link:../workbox-strategies + + packages/workbox-navigation-preload: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + + packages/workbox-precaching: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + '@ducanh2912/workbox-routing': + specifier: workspace:* + version: link:../workbox-routing + '@ducanh2912/workbox-strategies': + specifier: workspace:* + version: link:../workbox-strategies + + packages/workbox-range-requests: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + + packages/workbox-recipes: + dependencies: + '@ducanh2912/workbox-cacheable-response': + specifier: workspace:* + version: link:../workbox-cacheable-response + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + '@ducanh2912/workbox-expiration': + specifier: workspace:* + version: link:../workbox-expiration + '@ducanh2912/workbox-precaching': + specifier: workspace:* + version: link:../workbox-precaching + '@ducanh2912/workbox-routing': + specifier: workspace:* + version: link:../workbox-routing + '@ducanh2912/workbox-strategies': + specifier: workspace:* + version: link:../workbox-strategies + + packages/workbox-routing: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + + packages/workbox-strategies: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + + packages/workbox-streams: + dependencies: + '@ducanh2912/workbox-core': + specifier: workspace:* + version: link:../workbox-core + '@ducanh2912/workbox-routing': + specifier: workspace:* + version: link:../workbox-routing + + packages/workbox-sw: {} + + packages/workbox-webpack-plugin: + dependencies: + '@ducanh2912/workbox-build': + specifier: workspace:* + version: link:../workbox-build + fast-json-stable-stringify: + specifier: 2.1.0 + version: 2.1.0 + pretty-bytes: + specifier: 6.1.1 + version: 6.1.1 + upath: + specifier: 2.0.1 + version: 2.0.1 + webpack: + specifier: 4.4.0 || ^5.9.0 + version: 5.89.0 + webpack-sources: + specifier: 3.2.3 + version: 3.2.3 + devDependencies: + '@types/node': + specifier: 20.8.7 + version: 20.8.7 + '@types/webpack': + specifier: 5.28.3 + version: 5.28.3 + + packages/workbox-window: + dependencies: + '@ducanh2912/workbox-core': + specifier: 7.0.0 + version: link:../workbox-core + '@types/trusted-types': + specifier: 2.0.4 + version: 2.0.4 packages: @@ -774,6 +1102,18 @@ packages: leven: 3.1.0 dev: false + /@apideck/better-ajv-errors@0.3.6(ajv@8.12.0): + resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} + engines: {node: '>=10'} + peerDependencies: + ajv: '>=8' + dependencies: + ajv: 8.12.0 + json-schema: 0.4.0 + jsonpointer: 5.0.1 + leven: 3.1.0 + dev: false + /@babel/code-frame@7.22.13: resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} engines: {node: '>=6.9.0'} @@ -786,6 +1126,10 @@ packages: resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.23.2: + resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} + engines: {node: '>=6.9.0'} + /@babel/core@7.20.5: resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} engines: {node: '>=6.9.0'} @@ -808,6 +1152,28 @@ packages: transitivePeerDependencies: - supports-color + /@babel/core@7.23.2: + resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helpers': 7.23.2 + '@babel/parser': 7.23.0 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + /@babel/generator@7.22.5: resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==} engines: {node: '>=6.9.0'} @@ -817,11 +1183,20 @@ packages: '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 + /@babel/generator@7.23.0: + resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: false /@babel/helper-builder-binary-assignment-operator-visitor@7.18.9: @@ -832,6 +1207,13 @@ packages: '@babel/types': 7.22.5 dev: false + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: + resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: false + /@babel/helper-compilation-targets@7.20.0(@babel/core@7.20.5): resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} engines: {node: '>=6.9.0'} @@ -841,8 +1223,36 @@ packages: '@babel/compat-data': 7.20.5 '@babel/core': 7.20.5 '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.6 + browserslist: 4.21.10 + semver: 6.3.1 + + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.23.2 + '@babel/helper-validator-option': 7.22.15 + browserslist: 4.21.10 + lru-cache: 5.1.1 + semver: 6.3.1 + + /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 + dev: false /@babel/helper-create-class-features-plugin@7.22.5(@babel/core@7.20.5): resolution: {integrity: sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==} @@ -864,6 +1274,26 @@ packages: - supports-color dev: false + /@babel/helper-create-class-features-plugin@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/helper-create-regexp-features-plugin@7.20.5(@babel/core@7.20.5): resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} engines: {node: '>=6.9.0'} @@ -875,6 +1305,29 @@ packages: regexpu-core: 5.2.2 dev: false + /@babel/helper-create-regexp-features-plugin@7.20.5(@babel/core@7.23.2): + resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.2.2 + dev: false + + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: false + /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.20.5): resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} peerDependencies: @@ -891,6 +1344,25 @@ packages: - supports-color dev: false + /@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.23.2): + resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + /@babel/helper-environment-visitor@7.22.5: resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} engines: {node: '>=6.9.0'} @@ -907,13 +1379,20 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.5 - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 /@babel/helper-member-expression-to-functions@7.22.5: resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} @@ -922,6 +1401,19 @@ packages: '@babel/types': 7.22.5 dev: false + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + dev: false + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + /@babel/helper-module-imports@7.22.5: resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} engines: {node: '>=6.9.0'} @@ -943,11 +1435,24 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + /@babel/helper-optimise-call-expression@7.22.5: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: false /@babel/helper-plugin-utils@7.22.5: @@ -969,6 +1474,30 @@ packages: - supports-color dev: false + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.2): + resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-wrap-function': 7.22.20 + dev: false + + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.2): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: false + /@babel/helper-replace-supers@7.22.5: resolution: {integrity: sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==} engines: {node: '>=6.9.0'} @@ -978,7 +1507,7 @@ packages: '@babel/helper-optimise-call-expression': 7.22.5 '@babel/template': 7.22.5 '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: false @@ -989,23 +1518,39 @@ packages: dependencies: '@babel/types': 7.22.5 + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: false /@babel/helper-split-export-declaration@7.22.5: resolution: {integrity: sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.0 /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.22.5: resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} engines: {node: '>=6.9.0'} @@ -1014,6 +1559,10 @@ packages: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + engines: {node: '>=6.9.0'} + /@babel/helper-wrap-function@7.20.5: resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} engines: {node: '>=6.9.0'} @@ -1026,6 +1575,15 @@ packages: - supports-color dev: false + /@babel/helper-wrap-function@7.22.20: + resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.22.5 + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 + dev: false + /@babel/helpers@7.20.6: resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} engines: {node: '>=6.9.0'} @@ -1036,12 +1594,22 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helpers@7.23.2: + resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 + transitivePeerDependencies: + - supports-color + /@babel/highlight@7.22.13: resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} engines: {node: '>=6.9.0'} requiresBuild: true dependencies: - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 @@ -1052,6 +1620,13 @@ packages: dependencies: '@babel/types': 7.22.5 + /@babel/parser@7.23.0: + resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.0 + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} engines: {node: '>=6.9.0'} @@ -1062,6 +1637,16 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.18.9(@babel/core@7.20.5): resolution: {integrity: sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==} engines: {node: '>=6.9.0'} @@ -1074,9 +1659,22 @@ packages: '@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.20.5) dev: false + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2) + dev: false + /@babel/plugin-proposal-async-generator-functions@7.20.1(@babel/core@7.20.5): resolution: {integrity: sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1092,6 +1690,7 @@ packages: /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1105,6 +1704,7 @@ packages: /@babel/plugin-proposal-class-static-block@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead. peerDependencies: '@babel/core': ^7.12.0 dependencies: @@ -1119,6 +1719,7 @@ packages: /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1130,6 +1731,7 @@ packages: /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.20.5): resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1141,6 +1743,7 @@ packages: /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1152,6 +1755,7 @@ packages: /@babel/plugin-proposal-logical-assignment-operators@7.18.9(@babel/core@7.20.5): resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1163,6 +1767,7 @@ packages: /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1174,6 +1779,7 @@ packages: /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1185,6 +1791,7 @@ packages: /@babel/plugin-proposal-object-rest-spread@7.20.2(@babel/core@7.20.5): resolution: {integrity: sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1199,6 +1806,7 @@ packages: /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1210,6 +1818,7 @@ packages: /@babel/plugin-proposal-optional-chaining@7.18.9(@babel/core@7.20.5): resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1222,6 +1831,7 @@ packages: /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1235,6 +1845,7 @@ packages: /@babel/plugin-proposal-private-property-in-object@7.20.5(@babel/core@7.20.5): resolution: {integrity: sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1247,9 +1858,19 @@ packages: - supports-color dev: false + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + dev: false + /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.20.5): resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} engines: {node: '>=4'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead. peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -1265,13 +1886,22 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.20.5): + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.2): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true @@ -1282,6 +1912,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.2): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.20.5): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} @@ -1293,6 +1932,16 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.2): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: @@ -1302,6 +1951,15 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: @@ -1311,6 +1969,15 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.20.5): resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} engines: {node: '>=6.9.0'} @@ -1321,14 +1988,33 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.20.5): + /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.2): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - dev: true /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} @@ -1337,14 +2023,23 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.20.5): + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: true @@ -1355,6 +2050,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.2): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} @@ -1363,6 +2067,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.20.5): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} @@ -1371,6 +2084,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.2): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} @@ -1379,6 +2101,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} @@ -1387,6 +2118,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.20.5): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} @@ -1395,6 +2135,15 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.2): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.20.5): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} @@ -1406,6 +2155,16 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.2): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.20.5): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} @@ -1414,114 +2173,664 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.2): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.20.5): + /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.2): resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.2): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.20.5(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-arrow-functions@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-async-generator-functions@7.23.2(@babel/core@7.23.2): + resolution: {integrity: sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-async-to-generator@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.20.5) + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-block-scoping@7.20.5(@babel/core@7.20.5): + resolution: {integrity: sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-block-scoping@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-classes@7.20.2(@babel/core@7.20.5): + resolution: {integrity: sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-classes@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 + dev: false + + /@babel/plugin-transform-computed-properties@7.18.9(@babel/core@7.20.5): + resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.5 + dev: false + + /@babel/plugin-transform-destructuring@7.20.2(@babel/core@7.20.5): + resolution: {integrity: sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-destructuring@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5(@babel/core@7.20.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.20.5): + resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-dynamic-import@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-export-namespace-from@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-for-of@7.18.8(@babel/core@7.20.5): + resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-for-of@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.20.5): + resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) + '@babel/helper-function-name': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-literals@7.18.9(@babel/core@7.20.5): + resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-literals@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-logical-assignment-operators@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) + dev: false + + /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-modules-amd@7.19.6(@babel/core@7.20.5): + resolution: {integrity: sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-modules-commonjs@7.19.6(@babel/core@7.20.5): + resolution: {integrity: sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: false + + /@babel/plugin-transform-modules-systemjs@7.19.6(@babel/core@7.20.5): + resolution: {integrity: sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + dev: false + + /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.20.5): + resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5(@babel/core@7.20.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 - dev: true + dev: false - /@babel/plugin-transform-arrow-functions@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} + /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-async-to-generator@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} + /@babel/plugin-transform-nullish-coalescing-operator@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.20.5) - transitivePeerDependencies: - - supports-color + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) dev: false - /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + /@babel/plugin-transform-numeric-separator@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) dev: false - /@babel/plugin-transform-block-scoping@7.20.5(@babel/core@7.20.5): - resolution: {integrity: sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==} + /@babel/plugin-transform-object-rest-spread@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/compat-data': 7.23.2 + '@babel/core': 7.23.2 + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2) dev: false - /@babel/plugin-transform-classes@7.20.2(@babel/core@7.20.5): - resolution: {integrity: sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==} + /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-replace-supers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.5 - globals: 11.12.0 transitivePeerDependencies: - supports-color dev: false - /@babel/plugin-transform-computed-properties@7.18.9(@babel/core@7.20.5): - resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} + /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + transitivePeerDependencies: + - supports-color dev: false - /@babel/plugin-transform-destructuring@7.20.2(@babel/core@7.20.5): - resolution: {integrity: sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==} + /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) dev: false - /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + /@babel/plugin-transform-optional-chaining@7.23.0(@babel/core@7.23.2): + resolution: {integrity: sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/helper-create-regexp-features-plugin': 7.20.5(@babel/core@7.20.5) + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) dev: false - /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.20.5): - resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + /@babel/plugin-transform-parameters@7.20.5(@babel/core@7.20.5): + resolution: {integrity: sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1530,41 +2839,44 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + /@babel/plugin-transform-parameters@7.22.15(@babel/core@7.23.2): + resolution: {integrity: sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-for-of@7.18.8(@babel/core@7.20.5): - resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} + /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color dev: false - /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.20.5): - resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.2): + resolution: {integrity: sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) - '@babel/helper-function-name': 7.22.5 + '@babel/core': 7.23.2 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2) dev: false - /@babel/plugin-transform-literals@7.18.9(@babel/core@7.20.5): - resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1573,117 +2885,102 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-modules-amd@7.19.6(@babel/core@7.20.5): - resolution: {integrity: sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==} + /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.20.5): + resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color + regenerator-transform: 0.15.1 dev: false - /@babel/plugin-transform-modules-commonjs@7.19.6(@babel/core@7.20.5): - resolution: {integrity: sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==} + /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.23.2): + resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/helper-module-transforms': 7.20.2 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color + regenerator-transform: 0.15.2 dev: false - /@babel/plugin-transform-modules-systemjs@7.19.6(@babel/core@7.20.5): - resolution: {integrity: sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==} + /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.20.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false - /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/helper-module-transforms': 7.20.2 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false - /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.20.5): - resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-create-regexp-features-plugin': 7.20.5(@babel/core@7.20.5) '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + /@babel/plugin-transform-spread@7.19.0(@babel/core@7.20.5): + resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.5 - transitivePeerDependencies: - - supports-color + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: false - /@babel/plugin-transform-parameters@7.20.5(@babel/core@7.20.5): - resolution: {integrity: sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==} + /@babel/plugin-transform-spread@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: false - /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.20.5): + resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1692,19 +2989,18 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.20.5): - resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} + /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - regenerator-transform: 0.15.1 dev: false - /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.20.5): + resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1713,39 +3009,38 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-spread@7.19.0(@babel/core@7.20.5): - resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} + /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.20.5): + resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: false - /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.20.5): - resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.20.5): - resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.20.5): + resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1754,23 +3049,24 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.20.5): - resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.23.2): + resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 dev: false - /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.20.5): - resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} + /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: false @@ -1785,6 +3081,28 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: false + /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.23.2): + resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) + '@babel/helper-plugin-utils': 7.22.5 + dev: false + /@babel/preset-env@7.20.2(@babel/core@7.20.5): resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} engines: {node: '>=6.9.0'} @@ -1871,6 +3189,97 @@ packages: - supports-color dev: false + /@babel/preset-env@7.23.2(@babel/core@7.23.2): + resolution: {integrity: sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.2 + '@babel/core': 7.23.2 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.15 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.2) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-async-generator-functions': 7.23.2(@babel/core@7.23.2) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-block-scoping': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-classes': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-destructuring': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-dynamic-import': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-export-namespace-from': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-for-of': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-json-strings': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-modules-amd': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-modules-systemjs': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-numeric-separator': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-object-rest-spread': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-optional-catch-binding': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-optional-chaining': 7.23.0(@babel/core@7.23.2) + '@babel/plugin-transform-parameters': 7.22.15(@babel/core@7.23.2) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-private-property-in-object': 7.22.11(@babel/core@7.23.2) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.23.2) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.2) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.2) + '@babel/types': 7.23.0 + babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.23.2) + babel-plugin-polyfill-corejs3: 0.8.5(@babel/core@7.23.2) + babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.23.2) + core-js-compat: 3.33.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/preset-modules@0.1.5(@babel/core@7.20.5): resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: @@ -1884,6 +3293,21 @@ packages: esutils: 2.0.3 dev: false + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.2): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.23.0 + esutils: 2.0.3 + dev: false + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: false + /@babel/runtime@7.21.0: resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} engines: {node: '>=6.9.0'} @@ -1895,6 +3319,21 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 + dev: false + + /@babel/runtime@7.23.2: + resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 /@babel/template@7.22.5: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} @@ -1902,7 +3341,7 @@ packages: dependencies: '@babel/code-frame': 7.22.13 '@babel/parser': 7.22.5 - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 /@babel/traverse@7.22.5: resolution: {integrity: sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==} @@ -1915,7 +3354,24 @@ packages: '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.5 '@babel/parser': 7.22.5 - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + /@babel/traverse@7.23.2: + resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -1929,6 +3385,14 @@ packages: '@babel/helper-validator-identifier': 7.22.5 to-fast-properties: 2.0.0 + /@babel/types@7.23.0: + resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -1936,7 +3400,7 @@ packages: /@changesets/apply-release-plan@6.1.4: resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/config': 2.3.1 '@changesets/get-version-range-type': 0.3.2 '@changesets/git': 2.0.0 @@ -1954,7 +3418,7 @@ packages: /@changesets/assemble-release-plan@5.2.4: resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/errors': 0.1.4 '@changesets/get-dependents-graph': 1.3.6 '@changesets/types': 5.2.1 @@ -1982,7 +3446,7 @@ packages: resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} hasBin: true dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/apply-release-plan': 6.1.4 '@changesets/assemble-release-plan': 5.2.4 '@changesets/changelog-git': 0.1.14 @@ -2057,7 +3521,7 @@ packages: /@changesets/get-release-plan@3.0.17: resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/assemble-release-plan': 5.2.4 '@changesets/config': 2.3.1 '@changesets/pre': 1.0.14 @@ -2073,7 +3537,7 @@ packages: /@changesets/git@2.0.0: resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 @@ -2098,7 +3562,7 @@ packages: /@changesets/pre@1.0.14: resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 @@ -2108,7 +3572,7 @@ packages: /@changesets/read@0.5.9: resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 '@changesets/parse': 0.3.16 @@ -2129,7 +3593,7 @@ packages: /@changesets/write@0.2.3: resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/types': 5.2.1 fs-extra: 7.0.1 human-id: 1.0.2 @@ -2570,8 +4034,8 @@ packages: /@fastify/ajv-compiler@3.5.0: resolution: {integrity: sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==} dependencies: - ajv: 8.11.2 - ajv-formats: 2.1.1(ajv@8.11.2) + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) fast-uri: 2.2.0 dev: false @@ -2592,14 +4056,14 @@ packages: resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} dev: false - /@fastify/error@3.2.0: - resolution: {integrity: sha512-KAfcLa+CnknwVi5fWogrLXgidLic+GXnLjijXdpl8pvkvbXU5BGa37iZO9FGvsh9ZL4y+oFi5cbHBm5UOG+dmQ==} + /@fastify/error@3.4.0: + resolution: {integrity: sha512-e/mafFwbK3MNqxUcFBLgHhgxsF8UT1m8aj0dAlqEa2nJEgPsRtpHTZ3ObgrgkZ2M1eJHPTwgyUl/tXkvabsZdQ==} dev: false /@fastify/fast-json-stringify-compiler@4.3.0: resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} dependencies: - fast-json-stringify: 5.7.0 + fast-json-stringify: 5.8.0 dev: false /@gar/promisify@1.1.3: @@ -2611,7 +4075,7 @@ packages: engines: {node: ^8.13.0 || >=10.10.0} dependencies: '@grpc/proto-loader': 0.7.7 - '@types/node': 20.8.4 + '@types/node': 20.8.7 dev: false /@grpc/proto-loader@0.7.7: @@ -2656,7 +4120,6 @@ packages: strip-ansi-cjs: /strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} @@ -2679,7 +4142,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -2700,14 +4163,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.8.4) + jest-config: 29.7.0(@types/node@20.8.7) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -2735,7 +4198,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 jest-mock: 29.7.0 dev: true @@ -2762,7 +4225,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.1.0 - '@types/node': 20.8.4 + '@types/node': 20.8.7 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -2795,7 +4258,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 20.8.4 + '@types/node': 20.8.7 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -2857,7 +4320,7 @@ packages: resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.18 babel-plugin-istanbul: 6.1.1 @@ -2883,7 +4346,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.8.4 + '@types/node': 20.8.7 '@types/yargs': 17.0.24 chalk: 4.1.2 dev: true @@ -2950,8 +4413,15 @@ packages: tslib: 2.6.2 dev: false - /@mantine/hooks@7.1.2(react@18.2.0): - resolution: {integrity: sha512-2sqfBKse/aJq93zEpIn4OY+jRACmDIWBixfBgobRfltDyeL8G+3223LSAaeT6ZD8+h2YBJVmbCD5QY7bx2l11Q==} + /@ljharb/through@2.3.11: + resolution: {integrity: sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + dev: false + + /@mantine/hooks@7.1.3(react@18.2.0): + resolution: {integrity: sha512-jCOedyl229vzNEoya9L/PIeT+Btwuoqh09vRbFRNoTdRZgVMTWi4BT08BRWK5iqSa9PlvWtIaSGcCtjqqXKZcA==} peerDependencies: react: ^18.2.0 dependencies: @@ -2961,7 +4431,7 @@ packages: /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 @@ -2970,7 +4440,7 @@ packages: /@manypkg/get-packages@1.1.3: resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -3013,81 +4483,81 @@ packages: transitivePeerDependencies: - supports-color - /@next/env@13.5.4: - resolution: {integrity: sha512-LGegJkMvRNw90WWphGJ3RMHMVplYcOfRWf2Be3td3sUa+1AaxmsYyANsA+znrGCBjXJNi4XAQlSoEfUxs/4kIQ==} + /@next/env@13.5.5: + resolution: {integrity: sha512-agvIhYWp+ilbScg81s/sLueZo8CNEYLjNOqhISxheLmD/AQI4/VxV7bV76i/KzxH4iHy/va0YS9z0AOwGnw4Fg==} - /@next/eslint-plugin-next@13.5.4: - resolution: {integrity: sha512-vI94U+D7RNgX6XypSyjeFrOzxGlZyxOplU0dVE5norIfZGn/LDjJYPHdvdsR5vN1eRtl6PDAsOHmycFEOljK5A==} + /@next/eslint-plugin-next@13.5.5: + resolution: {integrity: sha512-S/32s4S+SCOpW58lHKdmILAAPRdnsSei7Y3L1oZSoe5Eh0QSlzbG1nYyIpnpwWgz3T7qe3imdq7cJ6Hf29epRA==} dependencies: glob: 7.1.7 dev: true - /@next/swc-darwin-arm64@13.5.4: - resolution: {integrity: sha512-Df8SHuXgF1p+aonBMcDPEsaahNo2TCwuie7VXED4FVyECvdXfRT9unapm54NssV9tF3OQFKBFOdlje4T43VO0w==} + /@next/swc-darwin-arm64@13.5.5: + resolution: {integrity: sha512-FvTdcJdTA7H1FGY8dKPPbf/O0oDC041/znHZwXA7liiGUhgw5hOQ+9z8tWvuz0M5a/SDjY/IRPBAb5FIFogYww==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@next/swc-darwin-x64@13.5.4: - resolution: {integrity: sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==} + /@next/swc-darwin-x64@13.5.5: + resolution: {integrity: sha512-mTqNIecaojmyia7appVO2QggBe1Z2fdzxgn6jb3x9qlAk8yY2sy4MAcsj71kC9RlenCqDmr9vtC/ESFf110TPA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@next/swc-linux-arm64-gnu@13.5.4: - resolution: {integrity: sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==} + /@next/swc-linux-arm64-gnu@13.5.5: + resolution: {integrity: sha512-U9e+kNkfvwh/T8yo+xcslvNXgyMzPPX1IbwCwnHHFmX5ckb1Uc3XZSInNjFQEQR5xhJpB5sFdal+IiBIiLYkZA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@next/swc-linux-arm64-musl@13.5.4: - resolution: {integrity: sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==} + /@next/swc-linux-arm64-musl@13.5.5: + resolution: {integrity: sha512-h7b58eIoNCSmKVC5fr167U0HWZ/yGLbkKD9wIller0nGdyl5zfTji0SsPKJvrG8jvKPFt2xOkVBmXlFOtuKynw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@next/swc-linux-x64-gnu@13.5.4: - resolution: {integrity: sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==} + /@next/swc-linux-x64-gnu@13.5.5: + resolution: {integrity: sha512-6U4y21T1J6FfcpM9uqzBJicxycpB5gJKLyQ3g6KOfBzT8H1sMwfHTRrvHKB09GIn1BCRy5YJHrA1G26DzqR46w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@next/swc-linux-x64-musl@13.5.4: - resolution: {integrity: sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==} + /@next/swc-linux-x64-musl@13.5.5: + resolution: {integrity: sha512-OuqWSAQHJQM2EsapPFTSU/FLQ0wKm7UeRNatiR/jLeCe1V02aB9xmzuWYo2Neaxxag4rss3S8fj+lvMLzwDaFA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@next/swc-win32-arm64-msvc@13.5.4: - resolution: {integrity: sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==} + /@next/swc-win32-arm64-msvc@13.5.5: + resolution: {integrity: sha512-+yLrOZIIZDY4uGn9bLOc0wTgs+M8RuOUFSUK3BhmcLav9e+tcAj0jyBHD4aXv2qWhppUeuYMsyBo1I58/eE6Dg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@next/swc-win32-ia32-msvc@13.5.4: - resolution: {integrity: sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==} + /@next/swc-win32-ia32-msvc@13.5.5: + resolution: {integrity: sha512-SyMxXyJtf9ScMH0Dh87THJMXNFvfkRAk841xyW9SeOX3KxM1buXX3hN7vof4kMGk0Yg996OGsX+7C9ueS8ugsw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@next/swc-win32-x64-msvc@13.5.4: - resolution: {integrity: sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==} + /@next/swc-win32-x64-msvc@13.5.5: + resolution: {integrity: sha512-n5KVf2Ok0BbLwofAaHiiKf+BQCj1M8WmTujiER4/qzYAVngnsNSjqEWvJ03raeN9eURqxDO+yL5VRoDrR33H9A==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3363,7 +4833,6 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} requiresBuild: true - dev: true optional: true /@pkgr/utils@2.3.1: @@ -3383,7 +4852,6 @@ packages: engines: {node: '>=12.22.0'} dependencies: graceful-fs: 4.2.10 - dev: true /@pnpm/npm-conf@1.0.5: resolution: {integrity: sha512-hD8ml183638O3R6/Txrh0L8VzGOrFXgRtRDG4qQC4tONdZ5Z1M+tlUUDUvrjYdmK6G+JTBTeaCLMna11cXzi8A==} @@ -3391,7 +4859,6 @@ packages: dependencies: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 - dev: true /@protobufjs/aspromise@1.1.2: resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -3466,6 +4933,25 @@ packages: rollup: 2.79.1 dev: false + /@rollup/plugin-babel@6.0.4(@babel/core@7.23.2)(rollup@3.28.1): + resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + rollup: + optional: true + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-module-imports': 7.22.5 + '@rollup/pluginutils': 5.0.2(rollup@3.28.1) + rollup: 3.28.1 + dev: false + /@rollup/plugin-json@6.0.1(rollup@3.28.1): resolution: {integrity: sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==} engines: {node: '>=14.0.0'} @@ -3510,7 +4996,6 @@ packages: is-module: 1.0.0 resolve: 1.22.2 rollup: 3.28.1 - dev: true /@rollup/plugin-replace@2.4.2(rollup@2.79.1): resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} @@ -3522,7 +5007,21 @@ packages: rollup: 2.79.1 dev: false - /@rollup/plugin-swc@0.2.1(@swc/core@1.3.92)(rollup@3.28.1): + /@rollup/plugin-replace@5.0.4(rollup@3.28.1): + resolution: {integrity: sha512-E2hmRnlh09K8HGT0rOnnri9OTh+BILGr7NVJGB30S4E3cLRn3J0xjdiyOZ74adPs4NiAMgrjUMGAZNJDBgsdmQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@3.28.1) + magic-string: 0.30.4 + rollup: 3.28.1 + dev: false + + /@rollup/plugin-swc@0.2.1(@swc/core@1.3.93)(rollup@3.28.1): resolution: {integrity: sha512-VioOZNQ72+EIR7zyDBM/2woQ8nGkQ5PlmnK1yArt1oJpf/eapYihWcybfyfZ9bCHMTadAMnaHGoy186nCQ5Mng==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3533,12 +5032,27 @@ packages: optional: true dependencies: '@rollup/pluginutils': 5.0.2(rollup@3.28.1) - '@swc/core': 1.3.92 + '@swc/core': 1.3.93 rollup: 3.28.1 smob: 1.4.0 dev: true - /@rollup/plugin-typescript@11.1.5(rollup@3.28.1)(tslib@2.6.2)(typescript@5.3.0-dev.20231011): + /@rollup/plugin-terser@0.4.4(rollup@3.28.1): + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 3.28.1 + serialize-javascript: 6.0.1 + smob: 1.4.0 + terser: 5.17.6 + dev: false + + /@rollup/plugin-typescript@11.1.5(rollup@3.28.1)(tslib@2.6.2)(typescript@5.3.0-dev.20231018): resolution: {integrity: sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3555,7 +5069,7 @@ packages: resolve: 1.22.2 rollup: 3.28.1 tslib: 2.6.2 - typescript: 5.3.0-dev.20231011 + typescript: 5.3.0-dev.20231018 dev: true /@rollup/pluginutils@3.1.0(rollup@2.79.1): @@ -3583,7 +5097,6 @@ packages: estree-walker: 2.0.2 picomatch: 2.3.1 rollup: 3.28.1 - dev: true /@rushstack/eslint-patch@1.4.0: resolution: {integrity: sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==} @@ -3601,7 +5114,6 @@ packages: /@sindresorhus/is@5.3.0: resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==} engines: {node: '>=14.16'} - dev: true /@sinonjs/commons@3.0.0: resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} @@ -3624,88 +5136,88 @@ packages: string.prototype.matchall: 4.0.8 dev: false - /@swc/core-darwin-arm64@1.3.92: - resolution: {integrity: sha512-v7PqZUBtIF6Q5Cp48gqUiG8zQQnEICpnfNdoiY3xjQAglCGIQCjJIDjreZBoeZQZspB27lQN4eZ43CX18+2SnA==} + /@swc/core-darwin-arm64@1.3.93: + resolution: {integrity: sha512-gEKgk7FVIgltnIfDO6GntyuQBBlAYg5imHpRgLxB1zSI27ijVVkksc6QwISzFZAhKYaBWIsFSVeL9AYSziAF7A==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] requiresBuild: true optional: true - /@swc/core-darwin-x64@1.3.92: - resolution: {integrity: sha512-Q3XIgQfXyxxxms3bPN+xGgvwk0TtG9l89IomApu+yTKzaIIlf051mS+lGngjnh9L0aUiCp6ICyjDLtutWP54fw==} + /@swc/core-darwin-x64@1.3.93: + resolution: {integrity: sha512-ZQPxm/fXdDQtn3yrYSL/gFfA8OfZ5jTi33yFQq6vcg/Y8talpZ+MgdSlYM0FkLrZdMTYYTNFiuBQuuvkA+av+Q==} engines: {node: '>=10'} cpu: [x64] os: [darwin] requiresBuild: true optional: true - /@swc/core-linux-arm-gnueabihf@1.3.92: - resolution: {integrity: sha512-tnOCoCpNVXC+0FCfG84PBZJyLlz0Vfj9MQhyhCvlJz9hQmvpf8nTdKH7RHrOn8VfxtUBLdVi80dXgIFgbvl7qA==} + /@swc/core-linux-arm-gnueabihf@1.3.93: + resolution: {integrity: sha512-OYFMMI2yV+aNe3wMgYhODxHdqUB/jrK0SEMHHS44GZpk8MuBXEF+Mcz4qjkY5Q1EH7KVQqXb/gVWwdgTHpjM2A==} engines: {node: '>=10'} cpu: [arm] os: [linux] requiresBuild: true optional: true - /@swc/core-linux-arm64-gnu@1.3.92: - resolution: {integrity: sha512-lFfGhX32w8h1j74Iyz0Wv7JByXIwX11OE9UxG+oT7lG0RyXkF4zKyxP8EoxfLrDXse4Oop434p95e3UNC3IfCw==} + /@swc/core-linux-arm64-gnu@1.3.93: + resolution: {integrity: sha512-BT4dT78odKnJMNiq5HdjBsv29CiIdcCcImAPxeFqAeFw1LL6gh9nzI8E96oWc+0lVT5lfhoesCk4Qm7J6bty8w==} engines: {node: '>=10'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@swc/core-linux-arm64-musl@1.3.92: - resolution: {integrity: sha512-rOZtRcLj57MSAbiecMsqjzBcZDuaCZ8F6l6JDwGkQ7u1NYR57cqF0QDyU7RKS1Jq27Z/Vg21z5cwqoH5fLN+Sg==} + /@swc/core-linux-arm64-musl@1.3.93: + resolution: {integrity: sha512-yH5fWEl1bktouC0mhh0Chuxp7HEO4uCtS/ly1Vmf18gs6wZ8DOOkgAEVv2dNKIryy+Na++ljx4Ym7C8tSJTrLw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] requiresBuild: true optional: true - /@swc/core-linux-x64-gnu@1.3.92: - resolution: {integrity: sha512-qptoMGnBL6v89x/Qpn+l1TH1Y0ed+v0qhNfAEVzZvCvzEMTFXphhlhYbDdpxbzRmCjH6GOGq7Y+xrWt9T1/ARg==} + /@swc/core-linux-x64-gnu@1.3.93: + resolution: {integrity: sha512-OFUdx64qvrGJhXKEyxosHxgoUVgba2ztYh7BnMiU5hP8lbI8G13W40J0SN3CmFQwPP30+3oEbW7LWzhKEaYjlg==} engines: {node: '>=10'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@swc/core-linux-x64-musl@1.3.92: - resolution: {integrity: sha512-g2KrJ43bZkCZHH4zsIV5ErojuV1OIpUHaEyW1gf7JWKaFBpWYVyubzFPvPkjcxHGLbMsEzO7w/NVfxtGMlFH/Q==} + /@swc/core-linux-x64-musl@1.3.93: + resolution: {integrity: sha512-4B8lSRwEq1XYm6xhxHhvHmKAS7pUp1Q7E33NQ2TlmFhfKvCOh86qvThcjAOo57x8DRwmpvEVrqvpXtYagMN6Ig==} engines: {node: '>=10'} cpu: [x64] os: [linux] requiresBuild: true optional: true - /@swc/core-win32-arm64-msvc@1.3.92: - resolution: {integrity: sha512-3MCRGPAYDoQ8Yyd3WsCMc8eFSyKXY5kQLyg/R5zEqA0uthomo0m0F5/fxAJMZGaSdYkU1DgF73ctOWOf+Z/EzQ==} + /@swc/core-win32-arm64-msvc@1.3.93: + resolution: {integrity: sha512-BHShlxtkven8ZjjvZ5QR6sC5fZCJ9bMujEkiha6W4cBUTY7ce7qGFyHmQd+iPC85d9kD/0cCiX/Xez8u0BhO7w==} engines: {node: '>=10'} cpu: [arm64] os: [win32] requiresBuild: true optional: true - /@swc/core-win32-ia32-msvc@1.3.92: - resolution: {integrity: sha512-zqTBKQhgfWm73SVGS8FKhFYDovyRl1f5dTX1IwSKynO0qHkRCqJwauFJv/yevkpJWsI2pFh03xsRs9HncTQKSA==} + /@swc/core-win32-ia32-msvc@1.3.93: + resolution: {integrity: sha512-nEwNWnz4JzYAK6asVvb92yeylfxMYih7eMQOnT7ZVlZN5ba9WF29xJ6kcQKs9HRH6MvWhz9+wRgv3FcjlU6HYA==} engines: {node: '>=10'} cpu: [ia32] os: [win32] requiresBuild: true optional: true - /@swc/core-win32-x64-msvc@1.3.92: - resolution: {integrity: sha512-41bE66ddr9o/Fi1FBh0sHdaKdENPTuDpv1IFHxSg0dJyM/jX8LbkjnpdInYXHBxhcLVAPraVRrNsC4SaoPw2Pg==} + /@swc/core-win32-x64-msvc@1.3.93: + resolution: {integrity: sha512-jibQ0zUr4kwJaQVwgmH+svS04bYTPnPw/ZkNInzxS+wFAtzINBYcU8s2PMWbDb2NGYiRSEeoSGyAvS9H+24JFA==} engines: {node: '>=10'} cpu: [x64] os: [win32] requiresBuild: true optional: true - /@swc/core@1.3.92: - resolution: {integrity: sha512-vx0vUrf4YTEw59njOJ46Ha5i0cZTMYdRHQ7KXU29efN1MxcmJH2RajWLPlvQarOP1ab9iv9cApD7SMchDyx2vA==} + /@swc/core@1.3.93: + resolution: {integrity: sha512-690GRr1wUGmGYZHk7fUduX/JUwViMF2o74mnZYIWEcJaCcd9MQfkhsxPBtjeg6tF+h266/Cf3RPYhsFBzzxXcA==} engines: {node: '>=10'} requiresBuild: true peerDependencies: @@ -3717,16 +5229,16 @@ packages: '@swc/counter': 0.1.2 '@swc/types': 0.1.5 optionalDependencies: - '@swc/core-darwin-arm64': 1.3.92 - '@swc/core-darwin-x64': 1.3.92 - '@swc/core-linux-arm-gnueabihf': 1.3.92 - '@swc/core-linux-arm64-gnu': 1.3.92 - '@swc/core-linux-arm64-musl': 1.3.92 - '@swc/core-linux-x64-gnu': 1.3.92 - '@swc/core-linux-x64-musl': 1.3.92 - '@swc/core-win32-arm64-msvc': 1.3.92 - '@swc/core-win32-ia32-msvc': 1.3.92 - '@swc/core-win32-x64-msvc': 1.3.92 + '@swc/core-darwin-arm64': 1.3.93 + '@swc/core-darwin-x64': 1.3.93 + '@swc/core-linux-arm-gnueabihf': 1.3.93 + '@swc/core-linux-arm64-gnu': 1.3.93 + '@swc/core-linux-arm64-musl': 1.3.93 + '@swc/core-linux-x64-gnu': 1.3.93 + '@swc/core-linux-x64-musl': 1.3.93 + '@swc/core-win32-arm64-msvc': 1.3.93 + '@swc/core-win32-ia32-msvc': 1.3.93 + '@swc/core-win32-x64-msvc': 1.3.93 /@swc/counter@0.1.2: resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==} @@ -3744,7 +5256,6 @@ packages: engines: {node: '>=14.16'} dependencies: defer-to-connect: 2.0.1 - dev: true /@tabler/icons-react@2.39.0(react@18.2.0): resolution: {integrity: sha512-MyUK1jqtmHPZBnDXqIc1Y5OnfoqG+tGaSB1/gcl0mlY462fJ5f3QB0ZIZzAHMAGYb6K2iJSdFIFavhcgpDDZ7Q==} @@ -3828,6 +5339,14 @@ packages: '@babel/types': 7.22.5 dev: true + /@types/common-tags@1.8.3: + resolution: {integrity: sha512-v3smfzf7umSwpkJrmlUe+apSv6bVnrIFCeBeprnP4f8lIh6pECZxyD50e8yFwfouIt85TdxN5yXiFwS5fnsS3w==} + dev: true + + /@types/configstore@6.0.1: + resolution: {integrity: sha512-ML2U2xzN6PwCh1I6QgWI3TdzS7CRLsv5DSCLX4/Wfg+f30JF60WgS9ZbVOOrTk+N67WTCSUKm6Q7k6M/BjbXQw==} + dev: true + /@types/debug@4.1.8: resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} dependencies: @@ -3843,7 +5362,7 @@ packages: resolution: {integrity: sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==} dependencies: '@types/estree': 1.0.0 - '@types/json-schema': 7.0.11 + '@types/json-schema': 7.0.12 /@types/estree-jsx@1.0.0: resolution: {integrity: sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==} @@ -3857,28 +5376,28 @@ packages: /@types/estree@1.0.0: resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} - /@types/extend@3.0.2: - resolution: {integrity: sha512-CqDQhn7jxaN9zw7zAu926zIx51ZzMaX8U8Wa4jGpKI6jeBr9ejFE68AQ+h+ztfrNJD+leo7K1cLbvMjpHfZSRg==} + /@types/extend@3.0.3: + resolution: {integrity: sha512-1Hz9SFYIkslmAt4R5WCpJBzCX9Cn+flMDgKbBXV3c47VyhLOOGYo52SIeoW00VBiUCI/dqKbnfM/8IC7Cm0h6g==} dev: true /@types/fs-extra@11.0.2: resolution: {integrity: sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ==} dependencies: '@types/jsonfile': 6.1.1 - '@types/node': 20.8.4 + '@types/node': 20.8.7 dev: true /@types/glob@7.2.0: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.8.4 + '@types/node': 20.8.7 dev: false /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 dev: true /@types/hast@2.3.4: @@ -3886,8 +5405,8 @@ packages: dependencies: '@types/unist': 3.0.0 - /@types/hast@3.0.1: - resolution: {integrity: sha512-hs/iBJx2aydugBQx5ETV3ZgeSS0oIreQrFJ4bjBl0XvM4wAmDjFEALY7p0rTSLt2eL+ibjRAAs9dTPiCLtmbqQ==} + /@types/hast@3.0.2: + resolution: {integrity: sha512-B5hZHgHsXvfCoO3xgNJvBnX7N8p86TqQeGKXcokW4XXi+qY4vxxPSFYofytvVmpFxzPv7oxDQzjg5Un5m2/xiw==} dependencies: '@types/unist': 3.0.0 dev: true @@ -3901,6 +5420,12 @@ packages: /@types/http-cache-semantics@4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} + + /@types/inquirer@9.0.5: + resolution: {integrity: sha512-j3QoaC6WX4waapzwBW32csSrMCgwK40TOt1Nxc60frDcQyef4QmlKZus4wUZH6e559kPoIECxrXRU4+I4hPTcQ==} + dependencies: + '@types/through': 0.0.31 + rxjs: 7.8.1 dev: true /@types/is-ci@3.0.0: @@ -3925,19 +5450,15 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: true - /@types/jest@29.5.5: - resolution: {integrity: sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==} + /@types/jest@29.5.6: + resolution: {integrity: sha512-/t9NnzkOpXb4Nfvg17ieHE6EeSjDS2SGSpNYfoLbUAeL/EOueU/RSdOWFpfQTXBEM7BguYW1XQ0EbM+6RlIh6w==} dependencies: expect: 29.7.0 pretty-format: 29.7.0 dev: true - /@types/json-schema@7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} - /@types/json-schema@7.0.12: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} - dev: true /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} @@ -3946,7 +5467,7 @@ packages: /@types/jsonfile@6.1.1: resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 dev: true /@types/long@4.0.2: @@ -3958,8 +5479,8 @@ packages: dependencies: '@types/unist': 3.0.0 - /@types/mdast@4.0.1: - resolution: {integrity: sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==} + /@types/mdast@4.0.2: + resolution: {integrity: sha512-tYR83EignvhYO9iU3kDg8V28M0jqyh9zzp5GV+EO+AYnyUl3P5ltkTeJuTiFZQFz670FSb3EwT/6LQdX+UdKfw==} dependencies: '@types/unist': 3.0.0 dev: true @@ -3982,8 +5503,8 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node@20.8.4: - resolution: {integrity: sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==} + /@types/node@20.8.7: + resolution: {integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==} dependencies: undici-types: 5.25.3 @@ -4014,7 +5535,7 @@ packages: /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 dev: false /@types/resolve@1.20.2: @@ -4035,16 +5556,37 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true + /@types/stringify-object@4.0.3: + resolution: {integrity: sha512-mJopEHaDdx8cIXy23etLuRCOwXgQ9PJiHgzZg1QbdAQ7vIatRKBTeJ8auVfFwUsHajW+ZvEWwp4+4gFW2XkLAg==} + dev: true + + /@types/through@0.0.31: + resolution: {integrity: sha512-LpKpmb7FGevYgXnBXYs6HWnmiFyVG07Pt1cnbgM1IhEacITTiUaBXXvOR3Y50ksaJWGSfhbEvQFivQEFGCC55w==} + dependencies: + '@types/node': 20.8.7 + dev: true + /@types/trusted-types@2.0.2: resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} dev: false + /@types/trusted-types@2.0.4: + resolution: {integrity: sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==} + dev: false + /@types/unist@2.0.6: resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} /@types/unist@3.0.0: resolution: {integrity: sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==} + /@types/update-notifier@6.0.5: + resolution: {integrity: sha512-uUOhxsJ3edPHu06r3k4I2yJ4eoyqBt+53ra9+caXEx0ruoPwqNHTlkq75CUvI4yWsrCA5+31tih+opunLCYnXw==} + dependencies: + '@types/configstore': 6.0.1 + boxen: 7.0.0 + dev: true + /@types/uuid@9.0.5: resolution: {integrity: sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ==} dev: true @@ -4052,7 +5594,20 @@ packages: /@types/web-push@3.6.1: resolution: {integrity: sha512-Zu6Iju7c4IlE8I8eEeFLYRb7XFqvHFmWWAYr1cmug9EX3c6CDarxIXWN/GO0sxjbJLkHPwozUzp6cLdXsrq7Ew==} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 + dev: true + + /@types/webpack@5.28.3: + resolution: {integrity: sha512-Hd0GBzpP0mO2ZKChw2V7flK45m01/2g9FalpMum2X66uouzG3P1vkxvOtLVzAWLna4N9h0s2sVjND9Slnlef8A==} + dependencies: + '@types/node': 20.8.7 + tapable: 2.2.1 + webpack: 5.89.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + - webpack-cli dev: true /@types/yargs-parser@21.0.0: @@ -4065,8 +5620,8 @@ packages: '@types/yargs-parser': 21.0.0 dev: true - /@typescript-eslint/eslint-plugin@6.7.5(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.3.0-dev.20231011): - resolution: {integrity: sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==} + /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.3.0-dev.20231018): + resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -4077,25 +5632,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.7.0 - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) - '@typescript-eslint/scope-manager': 6.7.5 - '@typescript-eslint/type-utils': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) - '@typescript-eslint/utils': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) - '@typescript-eslint/visitor-keys': 6.7.5 + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) + '@typescript-eslint/scope-manager': 6.8.0 + '@typescript-eslint/type-utils': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) + '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) + '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4 eslint: 8.51.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.3.0-dev.20231011) - typescript: 5.3.0-dev.20231011 + ts-api-utils: 1.0.1(typescript@5.3.0-dev.20231018) + typescript: 5.3.0-dev.20231018 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011): - resolution: {integrity: sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==} + /@typescript-eslint/parser@6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018): + resolution: {integrity: sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4104,27 +5659,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.7.5 - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.3.0-dev.20231011) - '@typescript-eslint/visitor-keys': 6.7.5 + '@typescript-eslint/scope-manager': 6.8.0 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.0-dev.20231018) + '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4 eslint: 8.51.0 - typescript: 5.3.0-dev.20231011 + typescript: 5.3.0-dev.20231018 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.7.5: - resolution: {integrity: sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==} + /@typescript-eslint/scope-manager@6.8.0: + resolution: {integrity: sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/visitor-keys': 6.7.5 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/visitor-keys': 6.8.0 dev: true - /@typescript-eslint/type-utils@6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011): - resolution: {integrity: sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==} + /@typescript-eslint/type-utils@6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018): + resolution: {integrity: sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4133,23 +5688,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.3.0-dev.20231011) - '@typescript-eslint/utils': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.0-dev.20231018) + '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) debug: 4.3.4 eslint: 8.51.0 - ts-api-utils: 1.0.1(typescript@5.3.0-dev.20231011) - typescript: 5.3.0-dev.20231011 + ts-api-utils: 1.0.1(typescript@5.3.0-dev.20231018) + typescript: 5.3.0-dev.20231018 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.7.5: - resolution: {integrity: sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==} + /@typescript-eslint/types@6.8.0: + resolution: {integrity: sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.7.5(typescript@5.3.0-dev.20231011): - resolution: {integrity: sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==} + /@typescript-eslint/typescript-estree@6.8.0(typescript@5.3.0-dev.20231018): + resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -4157,20 +5712,20 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/visitor-keys': 6.7.5 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.3.0-dev.20231011) - typescript: 5.3.0-dev.20231011 + ts-api-utils: 1.0.1(typescript@5.3.0-dev.20231018) + typescript: 5.3.0-dev.20231018 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011): - resolution: {integrity: sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==} + /@typescript-eslint/utils@6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018): + resolution: {integrity: sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -4178,9 +5733,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.3 - '@typescript-eslint/scope-manager': 6.7.5 - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.3.0-dev.20231011) + '@typescript-eslint/scope-manager': 6.8.0 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.3.0-dev.20231018) eslint: 8.51.0 semver: 7.5.4 transitivePeerDependencies: @@ -4188,11 +5743,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.7.5: - resolution: {integrity: sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==} + /@typescript-eslint/visitor-keys@6.8.0: + resolution: {integrity: sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.7.5 + '@typescript-eslint/types': 6.8.0 eslint-visitor-keys: 3.4.3 dev: true @@ -4348,6 +5903,7 @@ packages: resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} engines: {node: '>=0.4.0'} hasBin: true + dev: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -4386,7 +5942,7 @@ packages: indent-string: 4.0.0 dev: true - /ajv-formats@2.1.1(ajv@8.11.2): + /ajv-formats@2.1.1(ajv@8.12.0): resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: ajv: ^8.0.0 @@ -4394,7 +5950,7 @@ packages: ajv: optional: true dependencies: - ajv: 8.11.2 + ajv: 8.12.0 dev: false /ajv-keywords@3.5.2(ajv@6.12.6): @@ -4421,11 +5977,19 @@ packages: uri-js: 4.4.1 dev: false + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: false + /ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} dependencies: string-width: 4.2.3 - dev: true /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -4437,7 +6001,6 @@ packages: engines: {node: '>=8'} dependencies: type-fest: 0.21.3 - dev: true /ansi-escapes@5.0.0: resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} @@ -4453,7 +6016,6 @@ packages: /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - dev: true /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -4475,7 +6037,6 @@ packages: /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - dev: true /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -4531,7 +6092,6 @@ packages: dependencies: call-bind: 1.0.2 is-array-buffer: 3.0.2 - dev: true /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} @@ -4620,7 +6180,6 @@ packages: get-intrinsic: 1.2.1 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 - dev: true /arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} @@ -4683,7 +6242,6 @@ packages: /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} - dev: true /avvio@8.2.1: resolution: {integrity: sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==} @@ -4710,17 +6268,17 @@ packages: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} dev: false - /babel-jest@29.7.0(@babel/core@7.20.5): + /babel-jest@29.7.0(@babel/core@7.23.2): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.1 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.20.5) + babel-preset-jest: 29.6.3(@babel/core@7.23.2) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -4764,6 +6322,19 @@ packages: - supports-color dev: false + /babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.23.2): + resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.23.2 + '@babel/core': 7.23.2 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: false + /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.20.5): resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} peerDependencies: @@ -4776,6 +6347,18 @@ packages: - supports-color dev: false + /babel-plugin-polyfill-corejs3@0.8.5(@babel/core@7.23.2): + resolution: {integrity: sha512-Q6CdATeAvbScWPNLB8lzSO7fgUVBkQt6zLgNlfyeCr/EQaEQR+bWiBYYPYAFyE528BMjRhL+1QBMOI4jc/c5TA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) + core-js-compat: 3.33.0 + transitivePeerDependencies: + - supports-color + dev: false + /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.20.5): resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} peerDependencies: @@ -4787,35 +6370,46 @@ packages: - supports-color dev: false - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.20.5): + /babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.23.2): + resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.2 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.2) + transitivePeerDependencies: + - supports-color + dev: false + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.2): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.5 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.20.5) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.20.5) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.20.5) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.20.5) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.20.5) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.20.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.20.5) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.20.5) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.20.5) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.20.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.20.5) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.20.5) - dev: true - - /babel-preset-jest@29.6.3(@babel/core@7.20.5): + '@babel/core': 7.23.2 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.23.2): resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.20.5) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2) dev: true /bail@2.0.2: @@ -4847,6 +6441,14 @@ packages: readable-stream: 3.6.0 dev: false + /bl@5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: false + /bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} dev: false @@ -4887,7 +6489,6 @@ packages: type-fest: 2.19.0 widest-line: 4.0.1 wrap-ansi: 8.1.0 - dev: true /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -4931,17 +6532,17 @@ packages: electron-to-chromium: 1.4.498 node-releases: 2.0.13 update-browserslist-db: 1.0.11(browserslist@4.21.10) - dev: true - /browserslist@4.21.6: - resolution: {integrity: sha512-PF07dKGXKR+/bljJzCB6rAYtHEu21TthLxmJagtQizx+rwiqdRDBO5971Xu1N7MgcMLi4+mr4Cnl76x7O3DHtA==} + /browserslist@4.22.1: + resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001522 - electron-to-chromium: 1.4.411 - node-releases: 2.0.12 - update-browserslist-db: 1.0.11(browserslist@4.21.6) + caniuse-lite: 1.0.30001550 + electron-to-chromium: 1.4.557 + node-releases: 2.0.13 + update-browserslist-db: 1.0.13(browserslist@4.22.1) + dev: false /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -5041,7 +6642,6 @@ packages: /cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} - dev: true /cacheable-request@10.2.3: resolution: {integrity: sha512-6BehRBOs7iurNjAYN9iPazTwFDaMQavJO8W1MEm3s2pH8q/tkPTtLDRUZaweWK87WFGf2Y5wLAlaCJlR5kOz3w==} @@ -5054,7 +6654,6 @@ packages: mimic-response: 4.0.0 normalize-url: 8.0.0 responselike: 3.0.0 - dev: true /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} @@ -5101,14 +6700,14 @@ packages: /camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} - dev: true - - /caniuse-lite@1.0.30001522: - resolution: {integrity: sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==} /caniuse-lite@1.0.30001538: resolution: {integrity: sha512-HWJnhnID+0YMtGlzcp3T9drmBJUVDchPJ08tpUGFLs9CYlwWPH2uLgpHn8fND5pCgXVtnGS3H4QR9XLMHVNkHw==} + /caniuse-lite@1.0.30001550: + resolution: {integrity: sha512-p82WjBYIypO0ukTsd/FG3Xxs+4tFeaY9pfT4amQL8KWtYH7H9nYwReGAbMTJ0hsmRO8IfDtsS6p3ZWj8+1c2RQ==} + dev: false + /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -5150,7 +6749,6 @@ packages: /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true /cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -5206,7 +6804,6 @@ packages: /ci-info@3.7.0: resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} engines: {node: '>=8'} - dev: true /cjs-module-lexer@1.2.3: resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} @@ -5217,27 +6814,37 @@ packages: engines: {node: '>=6'} dev: true - /clean-webpack-plugin@4.0.0(webpack@5.88.2): + /clean-webpack-plugin@4.0.0(webpack@5.89.0): resolution: {integrity: sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==} engines: {node: '>=10.0.0'} peerDependencies: webpack: '>=4.0.0 <6.0.0' dependencies: del: 4.1.1 - webpack: 5.88.2(@swc/core@1.3.92) + webpack: 5.89.0(@swc/core@1.3.93) dev: false /cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} - dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: false /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: restore-cursor: 4.0.0 - dev: true + + /cli-spinners@2.9.1: + resolution: {integrity: sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==} + engines: {node: '>=6'} + dev: false /cli-table3@0.6.3: resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} @@ -5256,6 +6863,11 @@ packages: string-width: 5.1.2 dev: true + /cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + dev: false + /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} @@ -5286,7 +6898,6 @@ packages: /clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - dev: true /co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} @@ -5346,8 +6957,8 @@ packages: engines: {node: '>=14'} dev: true - /commander@11.0.0: - resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + /commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} dev: true @@ -5383,7 +6994,6 @@ packages: dependencies: ini: 1.3.8 proto-list: 1.2.4 - dev: true /configstore@6.0.0: resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} @@ -5394,7 +7004,6 @@ packages: unique-string: 3.0.0 write-file-atomic: 3.0.3 xdg-basedir: 5.1.0 - dev: true /console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} @@ -5436,7 +7045,6 @@ packages: /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -5450,7 +7058,13 @@ packages: /core-js-compat@3.26.1: resolution: {integrity: sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==} dependencies: - browserslist: 4.21.6 + browserslist: 4.21.10 + dev: false + + /core-js-compat@3.33.0: + resolution: {integrity: sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==} + dependencies: + browserslist: 4.22.1 dev: false /core-js@3.29.0: @@ -5462,7 +7076,7 @@ packages: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: false - /create-jest@29.7.0(@types/node@20.8.4): + /create-jest@29.7.0(@types/node@20.8.7): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5471,7 +7085,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.8.4) + jest-config: 29.7.0(@types/node@20.8.7) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -5518,7 +7132,6 @@ packages: engines: {node: '>=12'} dependencies: type-fest: 1.4.0 - dev: true /css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} @@ -5683,12 +7296,10 @@ packages: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: clone: 1.0.4 - dev: true /defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} - dev: true /define-data-property@1.1.0: resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==} @@ -5697,7 +7308,6 @@ packages: get-intrinsic: 1.2.1 gopd: 1.0.1 has-property-descriptors: 1.0.0 - dev: true /define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} @@ -5717,7 +7327,6 @@ packages: dependencies: has-property-descriptors: 1.0.0 object-keys: 1.1.1 - dev: true /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} @@ -5726,7 +7335,6 @@ packages: define-data-property: 1.1.0 has-property-descriptors: 1.0.0 object-keys: 1.1.1 - dev: true /del@4.1.1: resolution: {integrity: sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==} @@ -5860,7 +7468,6 @@ packages: engines: {node: '>=10'} dependencies: is-obj: 2.0.0 - dev: true /dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} @@ -5892,7 +7499,6 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true /ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} @@ -5912,24 +7518,27 @@ packages: jake: 10.8.5 dev: false - /electron-to-chromium@1.4.411: - resolution: {integrity: sha512-5VXLW4Qw89vM2WTICHua/y8v7fKGDRVa2VPOtBB9IpLvW316B+xd8yD1wTmLPY2ot/00P/qt87xdolj4aG/Lzg==} - /electron-to-chromium@1.4.498: resolution: {integrity: sha512-4LODxAzKGVy7CJyhhN5mebwe7U2L29P+0G+HUriHnabm0d7LSff8Yn7t+Wq+2/9ze2Fu1dhX7mww090xfv7qXQ==} - dev: true + + /electron-to-chromium@1.4.557: + resolution: {integrity: sha512-6x0zsxyMXpnMJnHrondrD3SuAeKcwij9S+83j2qHAQPXbGTDDfgImzzwgGlzrIcXbHQ42tkG4qA6U860cImNhw==} + dev: false /emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} dev: true + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} @@ -6061,7 +7670,6 @@ packages: typed-array-length: 1.0.4 unbox-primitive: 1.0.2 which-typed-array: 1.1.11 - dev: true /es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} @@ -6106,7 +7714,6 @@ packages: get-intrinsic: 1.2.1 has: 1.0.3 has-tostringtag: 1.0.0 - dev: true /es-shim-unscopables@1.0.0: resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} @@ -6158,7 +7765,6 @@ packages: /escape-goat@4.0.0: resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} engines: {node: '>=12'} - dev: true /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -6177,8 +7783,13 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - /eslint-config-next@13.5.4(eslint@8.51.0)(typescript@5.3.0-dev.20231011): - resolution: {integrity: sha512-FzQGIj4UEszRX7fcRSJK6L1LrDiVZvDFW320VVntVKh3BSU8Fb9kpaoxQx0cdFgf3MQXdeSbrCXJ/5Z/NndDkQ==} + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: false + + /eslint-config-next@13.5.5(eslint@8.51.0)(typescript@5.3.0-dev.20231018): + resolution: {integrity: sha512-kQr/eevFyzeVt0yCKTchQp3MTIx8ZmBsAKLW+7bzmAXHcf2vvxIqAt2N/afb9SZpuXXhSb/8yrKQGVUVpYmafQ==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 typescript: '>=3.3.1' @@ -6186,17 +7797,17 @@ packages: typescript: optional: true dependencies: - '@next/eslint-plugin-next': 13.5.4 + '@next/eslint-plugin-next': 13.5.5 '@rushstack/eslint-patch': 1.4.0 - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) eslint: 8.51.0 eslint-import-resolver-node: 0.3.7 eslint-import-resolver-typescript: 3.5.3(eslint-plugin-import@2.28.1)(eslint@8.51.0) - eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) + eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) eslint-plugin-jsx-a11y: 6.7.1(eslint@8.51.0) eslint-plugin-react: 7.33.2(eslint@8.51.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.51.0) - typescript: 5.3.0-dev.20231011 + typescript: 5.3.0-dev.20231018 transitivePeerDependencies: - eslint-import-resolver-webpack - supports-color @@ -6240,7 +7851,7 @@ packages: debug: 4.3.4 enhanced-resolve: 5.15.0 eslint: 8.51.0 - eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) + eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) get-tsconfig: 4.4.0 globby: 13.1.3 is-core-module: 2.13.0 @@ -6250,7 +7861,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -6271,7 +7882,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) debug: 3.2.7(supports-color@5.5.0) eslint: 8.51.0 eslint-import-resolver-node: 0.3.7 @@ -6280,7 +7891,7 @@ packages: - supports-color dev: true - /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0): + /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0): resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} engines: {node: '>=4'} peerDependencies: @@ -6290,7 +7901,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.3.0-dev.20231011) + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.3.0-dev.20231018) array-includes: 3.1.6 array.prototype.findlastindex: 1.2.2 array.prototype.flat: 1.3.1 @@ -6299,7 +7910,7 @@ packages: doctrine: 2.1.0 eslint: 8.51.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.3)(eslint@8.51.0) has: 1.0.3 is-core-module: 2.13.0 is-glob: 4.0.3 @@ -6321,7 +7932,7 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 aria-query: 5.1.3 array-includes: 3.1.6 array.prototype.flatmap: 1.3.1 @@ -6535,7 +8146,6 @@ packages: /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: true /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -6579,18 +8189,18 @@ packages: strip-final-newline: 2.0.0 dev: true - /execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} dependencies: cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 + get-stream: 8.0.1 + human-signals: 5.0.0 is-stream: 3.0.0 merge-stream: 2.0.0 npm-run-path: 5.1.0 onetime: 6.0.0 - signal-exit: 3.0.7 + signal-exit: 4.1.0 strip-final-newline: 3.0.0 dev: true @@ -6674,10 +8284,9 @@ packages: chardet: 0.7.0 iconv-lite: 0.4.24 tmp: 0.0.33 - dev: true - /fast-content-type-parse@1.0.0: - resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==} + /fast-content-type-parse@1.1.0: + resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} dev: false /fast-decode-uri-component@1.0.1: @@ -6715,12 +8324,12 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - /fast-json-stringify@5.7.0: - resolution: {integrity: sha512-sBVPTgnAZseLu1Qgj6lUbQ0HfjFhZWXAmpZ5AaSGkyLh5gAXBga/uPJjQPHpDFjC9adWIpdOcCLSDTgrZ7snoQ==} + /fast-json-stringify@5.8.0: + resolution: {integrity: sha512-VVwK8CFMSALIvt14U8AvrSzQAwN/0vaVRiFFUVlpnXSnDGrSkOAO5MtzyN8oQNjLd5AqTW5OZRgyjoNuAuR3jQ==} dependencies: '@fastify/deepmerge': 1.3.0 - ajv: 8.11.2 - ajv-formats: 2.1.1(ajv@8.11.2) + ajv: 8.12.0 + ajv-formats: 2.1.1(ajv@8.12.0) fast-deep-equal: 3.1.3 fast-uri: 2.2.0 rfdc: 1.3.0 @@ -6783,25 +8392,25 @@ packages: resolution: {integrity: sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==} dev: false - /fastify@4.24.0: - resolution: {integrity: sha512-6Uu2cCAV1UgexPnWKchgRt77lng9ivNmyFhPMcgUbJ4VaVBE1l6aYluiYZiVsgOBFpHrmdj7FD6n1aHswln4yQ==} + /fastify@4.24.2: + resolution: {integrity: sha512-V/7fdhFas7HoAyjD8ha8wPCeiRLUzPgwwM5dSSUx/eBUv7GvG61YzjggqOchMOsa7Sw32MNN4uCCoFrl+9ccJA==} dependencies: '@fastify/ajv-compiler': 3.5.0 - '@fastify/error': 3.2.0 + '@fastify/error': 3.4.0 '@fastify/fast-json-stringify-compiler': 4.3.0 abstract-logging: 2.0.1 avvio: 8.2.1 - fast-content-type-parse: 1.0.0 - fast-json-stringify: 5.7.0 + fast-content-type-parse: 1.1.0 + fast-json-stringify: 5.8.0 find-my-way: 7.7.0 - light-my-request: 5.9.1 - pino: 8.14.1 + light-my-request: 5.11.0 + pino: 8.16.0 process-warning: 2.2.0 proxy-addr: 2.0.7 rfdc: 1.3.0 secure-json-parse: 2.7.0 semver: 7.5.4 - toad-cache: 3.2.0 + toad-cache: 3.3.0 transitivePeerDependencies: - supports-color dev: false @@ -6829,6 +8438,14 @@ packages: node-domexception: 1.0.0 web-streams-polyfill: 3.2.1 + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: false + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -6911,7 +8528,6 @@ packages: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: is-callable: 1.2.7 - dev: true /foreground-child@3.1.1: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} @@ -6919,12 +8535,10 @@ packages: dependencies: cross-spawn: 7.0.3 signal-exit: 4.0.2 - dev: true /form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} - dev: true /format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} @@ -6941,8 +8555,8 @@ packages: engines: {node: '>= 0.6'} dev: false - /fp-and-or@0.1.3: - resolution: {integrity: sha512-wJaE62fLaB3jCYvY2ZHjZvmKK2iiLiiehX38rz5QZxtdN8fVPJDeZUiVvJrHStdTc+23LHlyZuSEKgFc0pxi2g==} + /fp-and-or@0.1.4: + resolution: {integrity: sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==} engines: {node: '>=10'} dev: true @@ -7082,7 +8696,11 @@ packages: has: 1.0.3 has-proto: 1.0.1 has-symbols: 1.0.3 - dev: true + + /get-own-enumerable-keys@1.0.0: + resolution: {integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==} + engines: {node: '>=14.16'} + dev: false /get-own-enumerable-property-symbols@3.0.2: resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} @@ -7101,6 +8719,10 @@ packages: /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} dev: true /get-symbol-description@1.0.0: @@ -7148,7 +8770,6 @@ packages: minimatch: 9.0.3 minipass: 6.0.2 path-scurry: 1.10.1 - dev: true /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} @@ -7198,7 +8819,6 @@ packages: engines: {node: '>=10'} dependencies: ini: 2.0.0 - dev: true /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -7216,7 +8836,6 @@ packages: engines: {node: '>= 0.4'} dependencies: define-properties: 1.2.0 - dev: true /globalyzer@0.1.0: resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} @@ -7264,7 +8883,6 @@ packages: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: get-intrinsic: 1.2.1 - dev: true /got@12.5.3: resolution: {integrity: sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==} @@ -7281,11 +8899,9 @@ packages: lowercase-keys: 3.0.0 p-cancelable: 3.0.0 responselike: 3.0.0 - dev: true /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -7336,7 +8952,6 @@ packages: /has-proto@1.0.1: resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} engines: {node: '>= 0.4'} - dev: true /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} @@ -7355,7 +8970,6 @@ packages: /has-yarn@3.0.0: resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} @@ -7382,19 +8996,19 @@ packages: /hast-util-has-property@3.0.0: resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 dev: true /hast-util-heading-rank@3.0.0: resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 dev: true /hast-util-is-element@3.0.0: resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 dev: true /hast-util-parse-selector@3.1.1: @@ -7422,7 +9036,7 @@ packages: /hast-util-sanitize@5.0.0: resolution: {integrity: sha512-L0g/qhOA82zG2hA3O29hnlv4mLU7YVVT1if5JZSr2tKO1ywkQbuMDcN05btgX0HtpqDXQniAM0ar0K+Lv4MDBQ==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 '@ungap/structured-clone': 1.2.0 unist-util-position: 5.0.0 dev: true @@ -7478,13 +9092,13 @@ packages: /hast-util-to-string@3.0.0: resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 dev: true /hast-util-to-text@4.0.0: resolution: {integrity: sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 '@types/unist': 3.0.0 hast-util-is-element: 3.0.0 unist-util-find-after: 5.0.0 @@ -7562,7 +9176,6 @@ packages: /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} - dev: true /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} @@ -7592,7 +9205,6 @@ packages: dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - dev: true /http_ece@1.1.0: resolution: {integrity: sha512-bptAfCDdPJxOs5zYSe7Y3lpr772s1G346R4Td5LgRUeCwIGpCGDUTJxRrhTNcAXbx37spge0kWEIH7QAYWNTlA==} @@ -7630,9 +9242,9 @@ packages: engines: {node: '>=10.17.0'} dev: true - /human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} dev: true /humanize-ms@1.2.1: @@ -7712,7 +9324,6 @@ packages: /import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} - dev: true /import-local@3.1.0: resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} @@ -7726,7 +9337,6 @@ packages: /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - dev: true /indent-string@4.0.0: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} @@ -7757,7 +9367,6 @@ packages: /ini@2.0.0: resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} engines: {node: '>=10'} - dev: true /ini@4.1.1: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} @@ -7767,6 +9376,27 @@ packages: /inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + /inquirer@9.2.11: + resolution: {integrity: sha512-B2LafrnnhbRzCWfAdOXisUzL89Kg8cVJlYmhqoi3flSiV/TveO+nsXwgKr9h9PIo+J1hz7nBSk6gegRIMBBf7g==} + engines: {node: '>=14.18.0'} + dependencies: + '@ljharb/through': 2.3.11 + ansi-escapes: 4.3.2 + chalk: 5.3.0 + cli-cursor: 3.1.0 + cli-width: 4.1.0 + external-editor: 3.1.0 + figures: 5.0.0 + lodash: 4.17.21 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 3.0.0 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: false + /internal-slot@1.0.5: resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} engines: {node: '>= 0.4'} @@ -7815,7 +9445,6 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.2.1 is-typed-array: 1.1.10 - dev: true /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -7859,7 +9488,6 @@ packages: engines: {node: '>=6'} dependencies: builtin-modules: 3.3.0 - dev: true /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} @@ -7870,7 +9498,6 @@ packages: hasBin: true dependencies: ci-info: 3.7.0 - dev: true /is-core-module@2.13.0: resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} @@ -7951,7 +9578,16 @@ packages: dependencies: global-dirs: 3.0.1 is-path-inside: 3.0.3 - dev: true + + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: false + + /is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: false /is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} @@ -7971,7 +9607,6 @@ packages: /is-npm@6.0.0: resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} @@ -7991,7 +9626,11 @@ packages: /is-obj@2.0.0: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} - dev: true + + /is-obj@3.0.0: + resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} + engines: {node: '>=12'} + dev: false /is-path-cwd@2.2.0: resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} @@ -8015,7 +9654,6 @@ packages: /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - dev: true /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} @@ -8047,6 +9685,11 @@ packages: engines: {node: '>=0.10.0'} dev: false + /is-regexp@3.1.0: + resolution: {integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==} + engines: {node: '>=12'} + dev: false + /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} dev: true @@ -8063,7 +9706,6 @@ packages: /is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} @@ -8093,11 +9735,19 @@ packages: for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 - dev: true /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: true + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: false + + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: false /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} @@ -8130,7 +9780,6 @@ packages: /is-yarn-global@0.4.1: resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} engines: {node: '>=12'} - dev: true /is-zip@1.0.0: resolution: {integrity: sha512-aym/dLqHZVMW/+bbNrA/eTeWTyW4fE6koLSoFSsM2GF3/pho7aPCcmHFWFLvzHu7MDuf67domYn36GDwU/cJkQ==} @@ -8143,7 +9792,6 @@ packages: /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -8157,7 +9805,7 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/parser': 7.22.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -8170,7 +9818,7 @@ packages: resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==} engines: {node: '>=10'} dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/parser': 7.22.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -8224,7 +9872,6 @@ packages: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - dev: true /jake@10.8.5: resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} @@ -8254,7 +9901,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -8275,7 +9922,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.8.4): + /jest-cli@29.7.0(@types/node@20.8.7): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -8289,10 +9936,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.8.4) + create-jest: 29.7.0(@types/node@20.8.7) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.8.4) + jest-config: 29.7.0(@types/node@20.8.7) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -8303,7 +9950,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.8.4): + /jest-config@29.7.0(@types/node@20.8.7): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -8315,11 +9962,11 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 - babel-jest: 29.7.0(@babel/core@7.20.5) + '@types/node': 20.8.7 + babel-jest: 29.7.0(@babel/core@7.23.2) chalk: 4.1.2 ci-info: 3.7.0 deepmerge: 4.3.1 @@ -8378,7 +10025,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -8394,7 +10041,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.6 - '@types/node': 20.8.4 + '@types/node': 20.8.7 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -8445,7 +10092,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 jest-util: 29.7.0 dev: true @@ -8500,7 +10147,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -8531,7 +10178,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.1 @@ -8554,15 +10201,15 @@ packages: resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.23.2 '@babel/generator': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.20.5) - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.20.5) + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2) '@babel/types': 7.22.5 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.20.5) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -8583,7 +10230,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.11 @@ -8608,7 +10255,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -8620,7 +10267,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 merge-stream: 2.0.0 supports-color: 7.2.0 dev: false @@ -8629,7 +10276,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -8637,13 +10284,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.7 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.8.4): + /jest@29.7.0(@types/node@20.8.7): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -8656,7 +10303,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.8.4) + jest-cli: 29.7.0(@types/node@20.8.7) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -8705,7 +10352,6 @@ packages: /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -8803,7 +10449,6 @@ packages: resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} dependencies: json-buffer: 3.0.1 - dev: true /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} @@ -8833,7 +10478,6 @@ packages: engines: {node: '>=14.16'} dependencies: package-json: 8.1.0 - dev: true /leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -8847,8 +10491,8 @@ packages: type-check: 0.4.0 dev: true - /light-my-request@5.9.1: - resolution: {integrity: sha512-UT7pUk8jNCR1wR7w3iWfIjx32DiB2f3hFdQSOwy3/EPQ3n3VocyipUxcyRZR0ahoev+fky69uA+GejPa9KuHKg==} + /light-my-request@5.11.0: + resolution: {integrity: sha512-qkFCeloXCOMpmEdZ/MV91P8AT4fjwFXWaAFz3lUeStM8RcoM1ks4J/F8r1b3r6y/H4u3ACEJ1T+Gv5bopj7oDA==} dependencies: cookie: 0.5.0 process-warning: 2.2.0 @@ -8864,34 +10508,28 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /lint-staged@14.0.1: - resolution: {integrity: sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==} - engines: {node: ^16.14.0 || >=18.0.0} + /lint-staged@15.0.1: + resolution: {integrity: sha512-2IU5OWmCaxch0X0+IBF4/v7sutpB+F3qoXbro43pYjQTOo5wumckjxoxn47pQBqqBsCWrD5HnI2uG/zJA7isew==} + engines: {node: '>=18.12.0'} hasBin: true dependencies: chalk: 5.3.0 - commander: 11.0.0 + commander: 11.1.0 debug: 4.3.4 - execa: 7.2.0 + execa: 8.0.1 lilconfig: 2.1.0 - listr2: 6.6.1 + listr2: 7.0.1 micromatch: 4.0.5 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.1 + yaml: 2.3.2 transitivePeerDependencies: - - enquirer - supports-color dev: true - /listr2@6.6.1: - resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} + /listr2@7.0.1: + resolution: {integrity: sha512-nz+7hwgbDp8eWNoDgzdl4hA/xDSLrNRzPu1TLgOYs6l5Y+Ma6zVWWy9Oyt9TQFONwKoSPoka3H50D3vD5EuNwg==} engines: {node: '>=16.0.0'} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true dependencies: cli-truncate: 3.1.0 colorette: 2.0.20 @@ -8951,6 +10589,22 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: false + + /log-symbols@5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + dev: false + /log-update@5.0.1: resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8988,12 +10642,11 @@ packages: /lowercase-keys@3.0.0: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true /lowlight@3.0.0: resolution: {integrity: sha512-kedX6yxvgak8P4LGh3vKRDQuMbVcnP+qRuDJlve2w+mNJAbEhEQPjYCp9QJnpVL5F2aAAVjeIzzrbQZUKHiDJw==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 devlop: 1.1.0 highlight.js: 11.8.0 dev: true @@ -9001,7 +10654,6 @@ packages: /lru-cache@10.0.1: resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} engines: {node: 14 || >=16.14} - dev: true /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -9010,6 +10662,11 @@ packages: yallist: 2.1.2 dev: true + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -9032,7 +10689,6 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - dev: true /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} @@ -9142,7 +10798,7 @@ packages: /mdast-util-from-markdown@2.0.0: resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} dependencies: - '@types/mdast': 4.0.1 + '@types/mdast': 4.0.2 '@types/unist': 3.0.0 decode-named-character-reference: 1.0.2 devlop: 1.1.0 @@ -9180,8 +10836,8 @@ packages: resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} dependencies: '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.1 - '@types/mdast': 4.0.1 + '@types/hast': 3.0.2 + '@types/mdast': 4.0.2 devlop: 1.1.0 mdast-util-from-markdown: 2.0.0 mdast-util-to-markdown: 2.1.0 @@ -9211,8 +10867,8 @@ packages: resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==} dependencies: '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.1 - '@types/mdast': 4.0.1 + '@types/hast': 3.0.2 + '@types/mdast': 4.0.2 '@types/unist': 3.0.0 ccount: 2.0.1 devlop: 1.1.0 @@ -9265,8 +10921,8 @@ packages: resolution: {integrity: sha512-EG0cLH2CbWIn2cZaKBD0tC1lZNZDsggUd1w6ine9GoM8EcPtsg4VmyXtNdDB9aSjIruSClKiXoUTD1BshLKWoA==} dependencies: '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.1 - '@types/mdast': 4.0.1 + '@types/hast': 3.0.2 + '@types/mdast': 4.0.2 devlop: 1.1.0 mdast-util-from-markdown: 2.0.0 mdast-util-to-markdown: 2.1.0 @@ -9283,7 +10939,7 @@ packages: /mdast-util-phrasing@4.0.0: resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} dependencies: - '@types/mdast': 4.0.1 + '@types/mdast': 4.0.2 unist-util-is: 6.0.0 dev: true @@ -9314,7 +10970,7 @@ packages: /mdast-util-to-markdown@2.1.0: resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} dependencies: - '@types/mdast': 4.0.1 + '@types/mdast': 4.0.2 '@types/unist': 3.0.0 longest-streak: 3.1.0 mdast-util-phrasing: 4.0.0 @@ -9332,7 +10988,7 @@ packages: /mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} dependencies: - '@types/mdast': 4.0.1 + '@types/mdast': 4.0.2 dev: true /mdx-bundler@9.2.1(esbuild@0.17.19): @@ -9366,6 +11022,11 @@ packages: fs-monkey: 1.0.3 dev: false + /meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + dev: false + /meow@6.1.1: resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} engines: {node: '>=8'} @@ -9840,7 +11501,6 @@ packages: /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - dev: true /mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} @@ -9854,7 +11514,6 @@ packages: /mimic-response@4.0.0: resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -9881,7 +11540,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 - dev: true /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} @@ -10009,6 +11667,11 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + /mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: false + /mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} dependencies: @@ -10037,7 +11700,7 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - /next-contentlayer@0.3.4(contentlayer@0.3.4)(esbuild@0.17.19)(next@13.5.4)(react-dom@18.2.0)(react@18.2.0): + /next-contentlayer@0.3.4(contentlayer@0.3.4)(esbuild@0.17.19)(next@13.5.5)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-UtUCwgAl159KwfhNaOwyiI7Lg6sdioyKMeh+E7jxx0CJ29JuXGxBEYmCI6+72NxFGIFZKx8lvttbbQhbnYWYSw==} peerDependencies: contentlayer: 0.3.4 @@ -10048,7 +11711,7 @@ packages: '@contentlayer/core': 0.3.4(esbuild@0.17.19) '@contentlayer/utils': 0.3.4 contentlayer: 0.3.4(esbuild@0.17.19) - next: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + next: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -10058,7 +11721,7 @@ packages: - supports-color dev: false - /next-i18next@14.0.3(i18next@23.5.1)(next@13.5.4)(react-i18next@13.2.2)(react@18.2.0): + /next-i18next@14.0.3(i18next@23.5.1)(next@13.5.5)(react-i18next@13.3.0)(react@18.2.0): resolution: {integrity: sha512-FtnjRMfhlamk8YyeyWqd+pndNL+3er83iMZnH4M4mhiGA93l0+vtBUvuObgOAMHDJGLLB2SS2xOOZq69oiJh7A==} engines: {node: '>=14'} peerDependencies: @@ -10073,13 +11736,13 @@ packages: hoist-non-react-statics: 3.3.2 i18next: 23.5.1 i18next-fs-backend: 2.1.5 - next: 13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) + next: 13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-i18next: 13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) + react-i18next: 13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) dev: false - /next@13.5.4(@babel/core@7.20.5)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+93un5S779gho8y9ASQhb/bTkQF17FNQOtXLKAj3lsNgltEcF0C5PMLLncDmH+8X1EnJH1kbqAERa29nRXqhjA==} + /next@13.5.5(@babel/core@7.20.5)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-LddFJjpfrtrMMw8Q9VLhIURuSidiCNcMQjRqcPtrKd+Fx07MsG7hYndJb/f2d3I+mTbTotsTJfCnn0eZ/YPk8w==} engines: {node: '>=16.14.0'} hasBin: true peerDependencies: @@ -10093,8 +11756,7 @@ packages: sass: optional: true dependencies: - '@next/env': 13.5.4 - '@opentelemetry/api': 1.4.1 + '@next/env': 13.5.5 '@swc/helpers': 0.5.2 busboy: 1.6.0 caniuse-lite: 1.0.30001538 @@ -10104,15 +11766,55 @@ packages: styled-jsx: 5.1.1(@babel/core@7.20.5)(react@18.2.0) watchpack: 2.4.0 optionalDependencies: - '@next/swc-darwin-arm64': 13.5.4 - '@next/swc-darwin-x64': 13.5.4 - '@next/swc-linux-arm64-gnu': 13.5.4 - '@next/swc-linux-arm64-musl': 13.5.4 - '@next/swc-linux-x64-gnu': 13.5.4 - '@next/swc-linux-x64-musl': 13.5.4 - '@next/swc-win32-arm64-msvc': 13.5.4 - '@next/swc-win32-ia32-msvc': 13.5.4 - '@next/swc-win32-x64-msvc': 13.5.4 + '@next/swc-darwin-arm64': 13.5.5 + '@next/swc-darwin-x64': 13.5.5 + '@next/swc-linux-arm64-gnu': 13.5.5 + '@next/swc-linux-arm64-musl': 13.5.5 + '@next/swc-linux-x64-gnu': 13.5.5 + '@next/swc-linux-x64-musl': 13.5.5 + '@next/swc-win32-arm64-msvc': 13.5.5 + '@next/swc-win32-ia32-msvc': 13.5.5 + '@next/swc-win32-x64-msvc': 13.5.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: true + + /next@13.5.5(@babel/core@7.23.2)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-LddFJjpfrtrMMw8Q9VLhIURuSidiCNcMQjRqcPtrKd+Fx07MsG7hYndJb/f2d3I+mTbTotsTJfCnn0eZ/YPk8w==} + engines: {node: '>=16.14.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + sass: + optional: true + dependencies: + '@next/env': 13.5.5 + '@opentelemetry/api': 1.4.1 + '@swc/helpers': 0.5.2 + busboy: 1.6.0 + caniuse-lite: 1.0.30001538 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.1(@babel/core@7.23.2)(react@18.2.0) + watchpack: 2.4.0 + optionalDependencies: + '@next/swc-darwin-arm64': 13.5.5 + '@next/swc-darwin-x64': 13.5.5 + '@next/swc-linux-arm64-gnu': 13.5.5 + '@next/swc-linux-arm64-musl': 13.5.5 + '@next/swc-linux-x64-gnu': 13.5.5 + '@next/swc-linux-x64-musl': 13.5.5 + '@next/swc-win32-arm64-msvc': 13.5.5 + '@next/swc-win32-ia32-msvc': 13.5.5 + '@next/swc-win32-x64-msvc': 13.5.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros @@ -10183,12 +11885,8 @@ packages: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} dev: true - /node-releases@2.0.12: - resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} - /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} - dev: true /nodemon@3.0.1: resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} @@ -10253,7 +11951,6 @@ packages: /normalize-url@8.0.0: resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} engines: {node: '>=14.16'} - dev: true /npm-bundled@3.0.0: resolution: {integrity: sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==} @@ -10262,8 +11959,8 @@ packages: npm-normalize-package-bin: 3.0.0 dev: true - /npm-check-updates@16.14.5: - resolution: {integrity: sha512-f7v3YzPUgadtkB2LAVhiWMjrSejJ0N8OM9JjjVfxBz2neHqmPSWQUAUA+U/p3xeXHl9bghRD6knRqBhm9dkRGg==} + /npm-check-updates@16.14.6: + resolution: {integrity: sha512-sJ6w4AmSDP7YzBXah94Ul2JhiIbjBDfx9XYgib15um2wtiQkOyjE7Lov3MNUSQ84Ry7T81mE4ynMbl/mGbK4HQ==} engines: {node: '>=14.14'} hasBin: true dependencies: @@ -10272,7 +11969,7 @@ packages: commander: 10.0.1 fast-memoize: 2.5.2 find-up: 5.0.0 - fp-and-or: 0.1.3 + fp-and-or: 0.1.4 get-stdin: 8.0.0 globby: 11.1.0 hosted-git-info: 5.2.1 @@ -10294,7 +11991,7 @@ packages: semver: 7.5.4 semver-utils: 1.1.4 source-map-support: 0.5.21 - spawn-please: 2.0.1 + spawn-please: 2.0.2 strip-ansi: 7.1.0 strip-json-comments: 5.0.1 untildify: 4.0.0 @@ -10486,7 +12183,6 @@ packages: engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 - dev: true /onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} @@ -10521,10 +12217,39 @@ packages: type-check: 0.4.0 dev: true + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.1 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: false + + /ora@7.0.1: + resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} + engines: {node: '>=16'} + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.1 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + stdin-discarder: 0.1.0 + string-width: 6.1.0 + strip-ansi: 7.1.0 + dev: false + /os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} - dev: true /outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} @@ -10533,7 +12258,6 @@ packages: /p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} - dev: true /p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} @@ -10599,7 +12323,6 @@ packages: registry-auth-token: 5.0.1 registry-url: 6.0.1 semver: 7.5.4 - dev: true /pacote@15.2.0: resolution: {integrity: sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==} @@ -10724,7 +12447,6 @@ packages: dependencies: lru-cache: 10.0.1 minipass: 6.0.2 - dev: true /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} @@ -10783,8 +12505,8 @@ packages: engines: {node: '>=0.10.0'} dev: false - /pino-abstract-transport@1.0.0: - resolution: {integrity: sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==} + /pino-abstract-transport@1.1.0: + resolution: {integrity: sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA==} dependencies: readable-stream: 4.3.0 split2: 4.1.0 @@ -10794,20 +12516,20 @@ packages: resolution: {integrity: sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==} dev: false - /pino@8.14.1: - resolution: {integrity: sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==} + /pino@8.16.0: + resolution: {integrity: sha512-UUmvQ/7KTZt/vHjhRrnyS7h+J7qPBQnpG80V56xmIC+o9IqYmQOw/UIny9S9zYDfRBR0ClouCr464EkBMIT7Fw==} hasBin: true dependencies: atomic-sleep: 1.0.0 fast-redact: 3.1.2 on-exit-leak-free: 2.1.0 - pino-abstract-transport: 1.0.0 + pino-abstract-transport: 1.1.0 pino-std-serializers: 6.1.0 process-warning: 2.2.0 quick-format-unescaped: 4.0.4 real-require: 0.2.0 safe-stable-stringify: 2.4.2 - sonic-boom: 3.2.1 + sonic-boom: 3.7.0 thread-stream: 2.3.0 dev: false @@ -10926,8 +12648,8 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /prettier-plugin-tailwindcss@0.5.5(prettier@3.0.3): - resolution: {integrity: sha512-voy0CjWv/CM8yeaduv5ZwovovpTGMR5LbzlhGF+LtEvMJt9wBeVTVnW781hL38R/RcDXCJwN2rolsgr94B/n0Q==} + /prettier-plugin-tailwindcss@0.5.6(prettier@3.0.3): + resolution: {integrity: sha512-2Xgb+GQlkPAUCFi3sV+NOYcSI5XgduvDBL2Zt/hwJudeKXkyvRS65c38SB0yb9UB40+1rL83I6m0RtlOQ8eHdg==} engines: {node: '>=14.21.3'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' @@ -10998,6 +12720,11 @@ packages: engines: {node: '>=6'} dev: false + /pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + dev: false + /pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -11079,7 +12806,6 @@ packages: /proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - dev: true /protobufjs@7.2.3: resolution: {integrity: sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==} @@ -11096,7 +12822,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.8.4 + '@types/node': 20.8.7 long: 5.2.3 dev: false @@ -11140,7 +12866,6 @@ packages: engines: {node: '>=12.20'} dependencies: escape-goat: 4.0.0 - dev: true /pure-rand@6.0.2: resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} @@ -11172,7 +12897,6 @@ packages: /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - dev: true /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -11223,8 +12947,8 @@ packages: react: 18.2.0 scheduler: 0.23.0 - /react-i18next@13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+nFUkbRByFwnrfDcYqvzBuaeZb+nACHx+fAWN/pZMddWOCJH5hoc21+Sa/N/Lqi6ne6/9wC/qRGOoQhJa6IkEQ==} + /react-i18next@13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-FlR9xjYHSPIJfQspEmkN0yOlxgRyNuiJKJ8gCaZH08UJ7SZHG+VrptEPcpEMEchjNoCOZdKcvJ3PnmHEZhkeXg==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -11236,7 +12960,7 @@ packages: react-native: optional: true dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 html-parse-stringify: 3.0.1 i18next: 23.5.1 react: 18.2.0 @@ -11392,10 +13116,19 @@ packages: /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + /regenerator-transform@0.15.1: resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.23.2 + dev: false + + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.23.2 dev: false /regexp.prototype.flags@1.4.3: @@ -11413,7 +13146,6 @@ packages: call-bind: 1.0.2 define-properties: 1.2.0 functions-have-names: 1.2.3 - dev: true /regexpu-core@5.2.2: resolution: {integrity: sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==} @@ -11427,19 +13159,29 @@ packages: unicode-match-property-value-ecmascript: 2.1.0 dev: false + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: false + /registry-auth-token@5.0.1: resolution: {integrity: sha512-UfxVOj8seK1yaIOiieV4FIP01vfBDLsY0H9sQzi9EbbUdJiuuBjJgLa1DpImXMNPnVkBD4eVxTEXcrZA6kfpJA==} engines: {node: '>=14'} dependencies: '@pnpm/npm-conf': 1.0.5 - dev: true /registry-url@6.0.1: resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} engines: {node: '>=12'} dependencies: rc: 1.2.8 - dev: true /regjsgen@0.7.1: resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} @@ -11455,7 +13197,7 @@ packages: /rehype-highlight@7.0.0: resolution: {integrity: sha512-QtobgRgYoQaK6p1eSr2SD1i61f7bjF2kZHAQHxeCHAuJf7ZUDMvQ7owDq9YTkmar5m5TSUol+2D3bp3KfJf/oA==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 hast-util-to-text: 4.0.0 lowlight: 3.0.0 unist-util-visit: 5.0.0 @@ -11465,7 +13207,7 @@ packages: /rehype-sanitize@6.0.0: resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==} dependencies: - '@types/hast': 3.0.1 + '@types/hast': 3.0.2 hast-util-sanitize: 5.0.0 dev: true @@ -11543,7 +13285,6 @@ packages: /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - dev: true /resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} @@ -11589,7 +13330,14 @@ packages: engines: {node: '>=14.16'} dependencies: lowercase-keys: 3.0.0 - dev: true + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: false /restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} @@ -11597,7 +13345,6 @@ packages: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 - dev: true /ret@0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} @@ -11638,7 +13385,7 @@ packages: glob: 10.3.10 dev: true - /rollup-plugin-dts@6.0.2(rollup@3.28.1)(typescript@5.3.0-dev.20231011): + /rollup-plugin-dts@6.0.2(rollup@3.28.1)(typescript@5.3.0-dev.20231018): resolution: {integrity: sha512-GYCCy9DyE5csSuUObktJBpjNpW2iLZMabNDIiAqzQWBl7l/WHzjvtAXevf8Lftk8EA920tuxeB/g8dM8MVMR6A==} engines: {node: '>=v16'} peerDependencies: @@ -11647,7 +13394,7 @@ packages: dependencies: magic-string: 0.30.4 rollup: 3.28.1 - typescript: 5.3.0-dev.20231011 + typescript: 5.3.0-dev.20231018 optionalDependencies: '@babel/code-frame': 7.22.13 dev: true @@ -11679,13 +13426,22 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.2 - dev: true + + /run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + dev: false /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.2 + /sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} @@ -11700,7 +13456,6 @@ packages: get-intrinsic: 1.2.1 has-symbols: 1.0.3 isarray: 2.0.5 - dev: true /safe-array-concat@1.0.1: resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} @@ -11749,7 +13504,7 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/json-schema': 7.0.11 + '@types/json-schema': 7.0.12 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) @@ -11769,7 +13524,6 @@ packages: engines: {node: '>=12'} dependencies: semver: 7.5.4 - dev: true /semver-utils@1.1.4: resolution: {integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==} @@ -11910,11 +13664,14 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true /signal-exit@4.0.2: resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} engines: {node: '>=14'} + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} dev: true /sigstore@1.4.0: @@ -11997,7 +13754,6 @@ packages: /smob@1.4.0: resolution: {integrity: sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==} - dev: true /socks-proxy-agent@7.0.0: resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} @@ -12018,8 +13774,8 @@ packages: smart-buffer: 4.2.0 dev: true - /sonic-boom@3.2.1: - resolution: {integrity: sha512-iITeTHxy3B9FGu8aVdiDXUVAcHMF9Ss0cCsAOo2HfCrmVGT3/DT5oYaeu0M/YKZDlKTvChEyPq0zI9Hf33EX6A==} + /sonic-boom@3.7.0: + resolution: {integrity: sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==} dependencies: atomic-sleep: 1.0.0 dev: false @@ -12068,8 +13824,8 @@ packages: /space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - /spawn-please@2.0.1: - resolution: {integrity: sha512-W+cFbZR2q2mMTfjz5ZGvhBAiX+e/zczFCNlbS9mxiSdYswBXwUuBUT+a0urH+xZZa8f/bs0mXHyZsZHR9hKogA==} + /spawn-please@2.0.2: + resolution: {integrity: sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==} engines: {node: '>=14'} dependencies: cross-spawn: 7.0.3 @@ -12138,6 +13894,13 @@ packages: engines: {node: '>= 0.8'} dev: false + /stdin-discarder@0.1.0: + resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + bl: 5.1.0 + dev: false + /stop-iteration-iterator@1.0.0: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} @@ -12200,18 +13963,26 @@ packages: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - dev: true + + /string-width@6.1.0: + resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} + engines: {node: '>=16'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 10.3.0 + strip-ansi: 7.1.0 + dev: false /string.prototype.matchall@4.0.8: resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} dependencies: call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - get-intrinsic: 1.2.0 + define-properties: 1.2.1 + es-abstract: 1.22.1 + get-intrinsic: 1.2.1 has-symbols: 1.0.3 internal-slot: 1.0.5 - regexp.prototype.flags: 1.4.3 + regexp.prototype.flags: 1.5.0 side-channel: 1.0.4 /string.prototype.trim@1.2.7: @@ -12221,7 +13992,6 @@ packages: call-bind: 1.0.2 define-properties: 1.2.0 es-abstract: 1.22.1 - dev: true /string.prototype.trimend@1.0.6: resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} @@ -12263,6 +14033,15 @@ packages: is-regexp: 1.0.0 dev: false + /stringify-object@5.0.0: + resolution: {integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==} + engines: {node: '>=14.16'} + dependencies: + get-own-enumerable-keys: 1.0.0 + is-obj: 3.0.0 + is-regexp: 3.1.0 + dev: false + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -12274,7 +14053,6 @@ packages: engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 - dev: true /strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} @@ -12347,6 +14125,24 @@ packages: '@babel/core': 7.20.5 client-only: 0.0.1 react: 18.2.0 + dev: true + + /styled-jsx@5.1.1(@babel/core@7.23.2)(react@18.2.0): + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + '@babel/core': 7.23.2 + client-only: 0.0.1 + react: 18.2.0 /sucrase@3.32.0: resolution: {integrity: sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==} @@ -12484,6 +14280,11 @@ packages: engines: {node: '>=8'} dev: false + /temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + dev: false + /tempy@0.6.0: resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} engines: {node: '>=10'} @@ -12494,12 +14295,46 @@ packages: unique-string: 2.0.0 dev: false + /tempy@3.1.0: + resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} + engines: {node: '>=14.16'} + dependencies: + is-stream: 3.0.0 + temp-dir: 3.0.0 + type-fest: 2.19.0 + unique-string: 3.0.0 + dev: false + /term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} dev: true - /terser-webpack-plugin@5.3.9(@swc/core@1.3.92)(webpack@5.88.2): + /terser-webpack-plugin@5.3.9(@swc/core@1.3.93)(webpack@5.89.0): + resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.18 + '@swc/core': 1.3.93 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.1 + terser: 5.17.6 + webpack: 5.89.0(@swc/core@1.3.93) + + /terser-webpack-plugin@5.3.9(webpack@5.89.0): resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==} engines: {node: '>= 10.13.0'} peerDependencies: @@ -12516,12 +14351,11 @@ packages: optional: true dependencies: '@jridgewell/trace-mapping': 0.3.18 - '@swc/core': 1.3.92 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.1 terser: 5.17.6 - webpack: 5.88.2(@swc/core@1.3.92) + webpack: 5.89.0 /terser@5.17.6: resolution: {integrity: sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ==} @@ -12529,7 +14363,7 @@ packages: hasBin: true dependencies: '@jridgewell/source-map': 0.3.2 - acorn: 8.8.1 + acorn: 8.10.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -12584,7 +14418,6 @@ packages: engines: {node: '>=0.6.0'} dependencies: os-tmpdir: 1.0.2 - dev: true /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -12600,8 +14433,8 @@ packages: dependencies: is-number: 7.0.0 - /toad-cache@3.2.0: - resolution: {integrity: sha512-Hj5zSqBS6OHbZoQk9IU8VqIr+0JUpwzunnwSlFJhG8aJSInYUMEuzItl3kJsGteTPd1qtflafdRHlRtUazYeqg==} + /toad-cache@3.3.0: + resolution: {integrity: sha512-3oDzcogWGHZdkwrHyvJVpPjA7oNzY6ENOV3PsWJY9XYPZ6INo94Yd47s5may1U+nleBPwDhrRiTPMIvKaa3MQg==} engines: {node: '>=12'} dev: false @@ -12641,20 +14474,20 @@ packages: /trough@2.1.0: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} - /ts-api-utils@1.0.1(typescript@5.3.0-dev.20231011): + /ts-api-utils@1.0.1(typescript@5.3.0-dev.20231018): resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.3.0-dev.20231011 + typescript: 5.3.0-dev.20231018 dev: true /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true - /ts-node@10.9.1(@swc/core@1.3.92)(@types/node@20.8.4)(typescript@5.2.2): + /ts-node@10.9.1(@swc/core@1.3.93)(@types/node@20.8.7)(typescript@5.2.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -12669,12 +14502,12 @@ packages: optional: true dependencies: '@cspotcode/source-map-support': 0.8.1 - '@swc/core': 1.3.92 + '@swc/core': 1.3.93 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 20.8.4 + '@types/node': 20.8.7 acorn: 8.8.1 acorn-walk: 8.2.0 arg: 4.1.3 @@ -12827,7 +14660,6 @@ packages: /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - dev: true /type-fest@0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} @@ -12842,12 +14674,10 @@ packages: /type-fest@1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} - dev: true /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - dev: true /type-fest@3.13.0: resolution: {integrity: sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==} @@ -12873,7 +14703,6 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.2.1 is-typed-array: 1.1.10 - dev: true /typed-array-byte-length@1.0.0: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} @@ -12883,7 +14712,6 @@ packages: for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.10 - dev: true /typed-array-byte-offset@1.0.0: resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} @@ -12894,7 +14722,6 @@ packages: for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.10 - dev: true /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} @@ -12902,13 +14729,11 @@ packages: call-bind: 1.0.2 for-each: 0.3.3 is-typed-array: 1.1.10 - dev: true /typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: is-typedarray: 1.0.0 - dev: true /typescript@5.2.2: resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} @@ -12916,8 +14741,8 @@ packages: hasBin: true dev: true - /typescript@5.3.0-dev.20231011: - resolution: {integrity: sha512-qpyUI7J37X3Xj7/bPWSNPUvmJ8yDGVnkQ8665xD4+LVWKUX7vwO7n2E1CUuQzeQIF4y369iPaz1d396rTW5LfA==} + /typescript@5.3.0-dev.20231018: + resolution: {integrity: sha512-qBPaVi+ntB9Ys4T3uP1ZYCtxFWIV/1ieooBDhFEd8nw4IqAoB/Us7XobF3xb756bnX8cS/zIt9fgukde4MG4bA==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -12971,6 +14796,18 @@ packages: trough: 2.1.0 vfile: 5.3.7 + /unified@11.0.3: + resolution: {integrity: sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==} + dependencies: + '@types/unist': 3.0.0 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 6.0.1 + dev: true + /unique-filename@2.0.1: resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -13011,7 +14848,6 @@ packages: engines: {node: '>=12'} dependencies: crypto-random-string: 4.0.0 - dev: true /unist-util-find-after@5.0.0: resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} @@ -13127,6 +14963,11 @@ packages: engines: {node: '>=4'} dev: false + /upath@2.0.1: + resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} + engines: {node: '>=4'} + dev: false + /update-browserslist-db@1.0.11(browserslist@4.21.10): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} hasBin: true @@ -13136,17 +14977,17 @@ packages: browserslist: 4.21.10 escalade: 3.1.1 picocolors: 1.0.0 - dev: true - /update-browserslist-db@1.0.11(browserslist@4.21.6): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /update-browserslist-db@1.0.13(browserslist@4.22.1): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.6 + browserslist: 4.22.1 escalade: 3.1.1 picocolors: 1.0.0 + dev: false /update-notifier@6.0.2: resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} @@ -13166,7 +15007,6 @@ packages: semver: 7.5.4 semver-diff: 4.0.0 xdg-basedir: 5.1.0 - dev: true /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -13302,7 +15142,6 @@ packages: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: defaults: 1.0.4 - dev: true /web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} @@ -13345,8 +15184,47 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - /webpack@5.88.2(@swc/core@1.3.92): - resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==} + /webpack@5.89.0: + resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.4 + '@types/estree': 1.0.0 + '@webassemblyjs/ast': 1.11.5 + '@webassemblyjs/wasm-edit': 1.11.5 + '@webassemblyjs/wasm-parser': 1.11.5 + acorn: 8.10.0 + acorn-import-assertions: 1.9.0(acorn@8.10.0) + browserslist: 4.21.10 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.15.0 + es-module-lexer: 1.2.1 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.9(webpack@5.89.0) + watchpack: 2.4.0 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + /webpack@5.89.0(@swc/core@1.3.93): + resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -13362,7 +15240,7 @@ packages: '@webassemblyjs/wasm-parser': 1.11.5 acorn: 8.10.0 acorn-import-assertions: 1.9.0(acorn@8.10.0) - browserslist: 4.21.6 + browserslist: 4.21.10 chrome-trace-event: 1.0.3 enhanced-resolve: 5.15.0 es-module-lexer: 1.2.1 @@ -13376,7 +15254,7 @@ packages: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.9(@swc/core@1.3.92)(webpack@5.88.2) + terser-webpack-plugin: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0) watchpack: 2.4.0 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -13456,7 +15334,6 @@ packages: for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 - dev: true /which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} @@ -13491,7 +15368,6 @@ packages: engines: {node: '>=12'} dependencies: string-width: 5.1.2 - dev: true /workbox-background-sync@7.0.0: resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==} @@ -13632,7 +15508,7 @@ packages: resolution: {integrity: sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA==} dev: false - /workbox-webpack-plugin@7.0.0(webpack@5.88.2): + /workbox-webpack-plugin@7.0.0(webpack@5.89.0): resolution: {integrity: sha512-R1ZzCHPfzeJjLK2/TpKUhxSQ3fFDCxlWxgRhhSjMQLz3G2MlBnyw/XeYb34e7SGgSv0qG22zEhMIzjMNqNeKbw==} engines: {node: '>=16.0.0'} peerDependencies: @@ -13641,7 +15517,7 @@ packages: fast-json-stable-stringify: 2.1.0 pretty-bytes: 5.6.0 upath: 1.2.0 - webpack: 5.88.2(@swc/core@1.3.92) + webpack: 5.89.0(@swc/core@1.3.93) webpack-sources: 1.4.3 workbox-build: 7.0.0 transitivePeerDependencies: @@ -13663,7 +15539,6 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} @@ -13680,7 +15555,6 @@ packages: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 - dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -13692,7 +15566,6 @@ packages: is-typedarray: 1.0.0 signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - dev: true /write-file-atomic@4.0.2: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} @@ -13705,7 +15578,6 @@ packages: /xdg-basedir@5.1.0: resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} engines: {node: '>=12'} - dev: true /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} @@ -13724,6 +15596,9 @@ packages: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} dev: true + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -13731,6 +15606,11 @@ packages: resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} engines: {node: '>= 14'} + /yaml@2.3.2: + resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==} + engines: {node: '>= 14'} + dev: true + /yargs-parser@18.1.3: resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} engines: {node: '>=6'} From 291fec33b3490ac2688bb9e33eff1c00f57c5d23 Mon Sep 17 00:00:00 2001 From: DuCanhGH <75556609+DuCanhGH@users.noreply.github.com> Date: Wed, 18 Oct 2023 20:05:40 +0700 Subject: [PATCH 2/9] rename --- LICENSE | 2 +- packages/next-pwa/README.md | 14 - packages/serwiss/README.md | 17 + .../background-sync}/README.md | 0 .../background-sync}/package.json | 4 +- .../src/BackgroundSyncPlugin.ts | 0 .../background-sync}/src/Queue.ts | 0 .../background-sync}/src/QueueStore.ts | 0 .../background-sync}/src/StorableRequest.ts | 0 .../background-sync}/src/_version.ts | 0 .../background-sync}/src/index.ts | 0 .../background-sync}/src/lib/QueueDb.ts | 0 .../background-sync}/src/lib/QueueStore.ts | 0 .../src/lib/StorableRequest.ts | 0 .../serwiss/background-sync/tsconfig.json | 7 + .../broadcast-update}/README.md | 0 .../broadcast-update}/package.json | 6 +- .../src/BroadcastCacheUpdate.ts | 0 .../src/BroadcastUpdatePlugin.ts | 0 .../broadcast-update}/src/_version.ts | 0 .../broadcast-update}/src/index.ts | 0 .../broadcast-update}/src/responsesAreSame.ts | 0 .../broadcast-update}/src/utils/constants.ts | 0 .../serwiss/broadcast-update/tsconfig.json | 7 + .../build}/README.md | 0 .../build}/package.json | 36 +- .../build}/src/_types.js | 0 .../build}/src/cdn-details.json | 0 .../build}/src/generate-sw.ts | 0 .../build}/src/get-manifest.ts | 0 .../build}/src/index.ts | 0 .../build}/src/inject-manifest.ts | 0 .../additional-manifest-entries-transform.ts | 0 .../build}/src/lib/bundle.ts | 0 .../build}/src/lib/cdn-utils.ts | 0 .../build}/src/lib/copy-workbox-libraries.ts | 0 .../build}/src/lib/errors.ts | 0 .../build}/src/lib/escape-regexp.ts | 0 .../build}/src/lib/get-composite-details.ts | 0 .../build}/src/lib/get-file-details.ts | 0 .../build}/src/lib/get-file-hash.ts | 0 .../src/lib/get-file-manifest-entries.ts | 0 .../build}/src/lib/get-file-size.ts | 0 .../build}/src/lib/get-source-map-url.ts | 0 .../build}/src/lib/get-string-details.ts | 0 .../build}/src/lib/get-string-hash.ts | 0 .../build}/src/lib/maximum-size-transform.ts | 0 .../src/lib/modify-url-prefix-transform.ts | 0 .../build}/src/lib/module-registry.ts | 0 ...no-revision-for-urls-matching-transform.ts | 0 .../build}/src/lib/populate-sw-template.ts | 0 .../build}/src/lib/rebase-path.ts | 0 .../src/lib/replace-and-update-source-map.ts | 0 .../src/lib/runtime-caching-converter.ts | 0 .../src/lib/stringify-without-comments.ts | 0 .../build}/src/lib/transform-manifest.ts | 0 .../lib/translate-url-to-sourcemap-paths.ts | 0 .../build}/src/lib/validate-options.ts | 0 .../lib/write-sw-using-default-template.ts | 0 .../src/rollup-plugin-off-main-thread.d.ts | 0 .../build}/src/schema/GenerateSWOptions.json | 0 .../build}/src/schema/GetManifestOptions.json | 0 .../src/schema/InjectManifestOptions.json | 0 .../src/schema/WebpackGenerateSWOptions.json | 0 .../schema/WebpackInjectManifestOptions.json | 0 .../build}/src/strip-comments.d.ts | 0 .../build}/src/templates/sw-template.ts | 0 .../build}/src/types.ts | 0 packages/serwiss/build/tsconfig.json | 7 + .../cacheable-response}/README.md | 0 .../cacheable-response}/package.json | 6 +- .../src/CacheableResponse.ts | 0 .../src/CacheableResponsePlugin.ts | 0 .../cacheable-response}/src/_version.ts | 0 .../cacheable-response}/src/index.ts | 0 .../serwiss/cacheable-response/tsconfig.json | 7 + .../{workbox-cli => serwiss/cli}/README.md | 0 .../{workbox-cli => serwiss/cli}/package.json | 6 +- .../{workbox-cli => serwiss/cli}/src/app.ts | 0 .../{workbox-cli => serwiss/cli}/src/bin.ts | 0 .../cli}/src/lib/cleanup-stack-trace.ts | 0 .../cli}/src/lib/constants.ts | 0 .../cli}/src/lib/errors.ts | 0 .../cli}/src/lib/help-text.ts | 0 .../cli}/src/lib/logger.ts | 0 .../src/lib/questions/ask-config-location.ts | 0 .../lib/questions/ask-extensions-to-cache.ts | 0 .../cli}/src/lib/questions/ask-questions.ts | 0 .../src/lib/questions/ask-root-of-web-app.ts | 0 .../questions/ask-start_url-query-params.ts | 0 .../cli}/src/lib/questions/ask-sw-dest.ts | 0 .../cli}/src/lib/questions/ask-sw-src.ts | 0 .../cli}/src/lib/read-config.ts | 0 .../cli}/src/lib/run-wizard.ts | 0 packages/serwiss/cli/tsconfig.json | 7 + .../{workbox-core => serwiss/core}/README.md | 0 .../core}/package.json | 4 +- .../core}/src/_private.ts | 0 .../core}/src/_private/Deferred.ts | 0 .../core}/src/_private/WorkboxError.ts | 0 .../core}/src/_private/assert.ts | 0 .../src/_private/cacheMatchIgnoreParams.ts | 0 .../core}/src/_private/cacheNames.ts | 0 .../_private/canConstructReadableStream.ts | 0 .../canConstructResponseFromBodyStream.ts | 0 .../core}/src/_private/dontWaitFor.ts | 0 .../_private/executeQuotaErrorCallbacks.ts | 0 .../core}/src/_private/getFriendlyURL.ts | 0 .../core}/src/_private/logger.ts | 0 .../src/_private/resultingClientExists.ts | 0 .../core}/src/_private/timeout.ts | 0 .../core}/src/_private/waitUntil.ts | 0 .../core}/src/_version.ts | 0 .../core}/src/cacheNames.ts | 0 .../core}/src/clientsClaim.ts | 0 .../core}/src/copyResponse.ts | 0 .../core}/src/index.ts | 0 .../src/models/messages/messageGenerator.ts | 0 .../core}/src/models/messages/messages.ts | 0 .../core}/src/models/pluginEvents.ts | 0 .../core}/src/models/quotaErrorCallbacks.ts | 0 .../core}/src/registerQuotaErrorCallback.ts | 0 .../core}/src/setCacheNameDetails.ts | 0 .../core}/src/skipWaiting.ts | 0 .../core}/src/types.ts | 0 .../core}/src/utils/pluginUtils.ts | 0 .../core}/src/utils/welcome.ts | 0 packages/serwiss/core/tsconfig.json | 7 + .../expiration}/README.md | 0 .../expiration}/package.json | 6 +- .../expiration}/src/CacheExpiration.ts | 0 .../expiration}/src/ExpirationPlugin.ts | 0 .../expiration}/src/_version.ts | 0 .../expiration}/src/index.ts | 0 .../src/models/CacheTimestampsModel.ts | 0 packages/serwiss/expiration/tsconfig.json | 7 + .../google-analytics}/README.md | 0 .../google-analytics}/package.json | 12 +- .../google-analytics}/src/_version.ts | 0 .../google-analytics}/src/index.ts | 0 .../google-analytics}/src/initialize.ts | 0 .../google-analytics}/src/utils/constants.ts | 0 .../serwiss/google-analytics/tsconfig.json | 7 + .../navigation-preload}/README.md | 0 .../navigation-preload}/package.json | 6 +- .../navigation-preload}/src/_version.ts | 0 .../navigation-preload}/src/disable.ts | 0 .../navigation-preload}/src/enable.ts | 0 .../navigation-preload}/src/index.ts | 0 .../navigation-preload}/src/isSupported.ts | 0 .../serwiss/navigation-preload/tsconfig.json | 7 + .../precaching}/README.md | 0 .../precaching}/package.json | 10 +- .../precaching}/src/PrecacheController.ts | 0 .../precaching}/src/PrecacheFallbackPlugin.ts | 0 .../precaching}/src/PrecacheRoute.ts | 0 .../precaching}/src/PrecacheStrategy.ts | 0 .../precaching}/src/_types.ts | 0 .../precaching}/src/_version.ts | 0 .../precaching}/src/addPlugins.ts | 0 .../precaching}/src/addRoute.ts | 0 .../precaching}/src/cleanupOutdatedCaches.ts | 0 .../src/createHandlerBoundToURL.ts | 0 .../precaching}/src/getCacheKeyForURL.ts | 0 .../precaching}/src/index.ts | 0 .../precaching}/src/matchPrecache.ts | 0 .../precaching}/src/precache.ts | 0 .../precaching}/src/precacheAndRoute.ts | 0 .../src/utils/PrecacheCacheKeyPlugin.ts | 0 .../src/utils/PrecacheInstallReportPlugin.ts | 0 .../precaching}/src/utils/createCacheKey.ts | 0 .../src/utils/deleteOutdatedCaches.ts | 0 .../src/utils/generateURLVariations.ts | 0 .../src/utils/getCacheKeyForURL.ts | 0 .../utils/getOrCreatePrecacheController.ts | 0 .../src/utils/printCleanupDetails.ts | 0 .../src/utils/printInstallDetails.ts | 0 .../src/utils/removeIgnoredSearchParams.ts | 0 packages/serwiss/precaching/tsconfig.json | 7 + .../range-requests}/README.md | 0 .../range-requests}/package.json | 6 +- .../src/RangeRequestsPlugin.ts | 0 .../range-requests}/src/_version.ts | 0 .../src/createPartialResponse.ts | 0 .../range-requests}/src/index.ts | 0 .../src/utils/calculateEffectiveBoundaries.ts | 0 .../src/utils/parseRangeHeader.ts | 0 packages/serwiss/range-requests/tsconfig.json | 7 + .../recipes}/README.md | 0 .../recipes}/package.json | 16 +- .../recipes}/src/_version.ts | 0 .../recipes}/src/googleFontsCache.ts | 0 .../recipes}/src/imageCache.ts | 0 .../recipes}/src/index.ts | 0 .../recipes}/src/offlineFallback.ts | 0 .../recipes}/src/pageCache.ts | 0 .../recipes}/src/staticResourceCache.ts | 0 .../recipes}/src/warmStrategyCache.ts | 0 packages/serwiss/recipes/tsconfig.json | 7 + .../routing}/README.md | 0 .../routing}/package.json | 6 +- .../routing}/src/NavigationRoute.ts | 0 .../routing}/src/RegExpRoute.ts | 0 .../routing}/src/Route.ts | 0 .../routing}/src/Router.ts | 0 .../routing}/src/_types.ts | 0 .../routing}/src/_version.ts | 0 .../routing}/src/index.ts | 0 .../routing}/src/registerRoute.ts | 0 .../routing}/src/setCatchHandler.ts | 0 .../routing}/src/setDefaultHandler.ts | 0 .../routing}/src/utils/constants.ts | 0 .../src/utils/getOrCreateDefaultRouter.ts | 0 .../routing}/src/utils/normalizeHandler.ts | 0 packages/serwiss/routing/tsconfig.json | 7 + .../strategies}/README.md | 0 .../strategies}/package.json | 6 +- .../strategies}/src/CacheFirst.ts | 0 .../strategies}/src/CacheOnly.ts | 0 .../strategies}/src/NetworkFirst.ts | 0 .../strategies}/src/NetworkOnly.ts | 0 .../strategies}/src/StaleWhileRevalidate.ts | 0 .../strategies}/src/Strategy.ts | 0 .../strategies}/src/StrategyHandler.ts | 0 .../strategies}/src/_version.ts | 0 .../strategies}/src/index.ts | 0 .../src/plugins/cacheOkAndOpaquePlugin.ts | 0 .../strategies}/src/utils/messages.ts | 0 packages/serwiss/strategies/tsconfig.json | 7 + .../streams}/README.md | 0 .../streams}/package.json | 8 +- .../streams}/src/_types.ts | 0 .../streams}/src/_version.ts | 0 .../streams}/src/concatenate.ts | 0 .../streams}/src/concatenateToResponse.ts | 0 .../streams}/src/index.ts | 0 .../streams}/src/isSupported.ts | 0 .../streams}/src/strategy.ts | 0 .../streams}/src/utils/createHeaders.ts | 0 packages/serwiss/streams/tsconfig.json | 7 + packages/{workbox-sw => serwiss/sw}/README.md | 0 .../{workbox-sw => serwiss/sw}/_types.mjs | 0 .../{workbox-sw => serwiss/sw}/_version.mjs | 0 .../sw}/controllers/WorkboxSW.mjs | 0 packages/{workbox-sw => serwiss/sw}/index.mjs | 0 .../{workbox-sw => serwiss/sw}/package.json | 4 +- .../webpack-plugin}/README.md | 0 .../webpack-plugin}/package.json | 6 +- .../webpack-plugin}/src/generate-sw.ts | 0 .../webpack-plugin}/src/index.ts | 0 .../webpack-plugin}/src/inject-manifest.ts | 0 .../webpack-plugin}/src/lib/get-asset-hash.ts | 0 .../get-manifest-entries-from-compilation.ts | 0 .../src/lib/get-script-files-for-chunks.ts | 0 .../src/lib/get-sourcemap-asset-name.ts | 0 .../src/lib/relative-to-output-path.ts | 0 .../src/lib/resolve-webpack-url.ts | 0 packages/serwiss/webpack-plugin/tsconfig.json | 7 + .../window}/README.md | 0 .../window}/package.json | 6 +- .../window}/src/Workbox.ts | 0 .../window}/src/_version.ts | 0 .../window}/src/index.ts | 0 .../window}/src/messageSW.ts | 0 .../window}/src/utils/WorkboxEvent.ts | 0 .../window}/src/utils/WorkboxEventTarget.ts | 0 .../window}/src/utils/urlsMatch.ts | 0 packages/serwiss/window/tsconfig.json | 7 + .../workbox-background-sync/tsconfig.json | 9 - .../workbox-broadcast-update/tsconfig.json | 9 - packages/workbox-build/tsconfig.json | 14 - .../workbox-cacheable-response/tsconfig.json | 10 - packages/workbox-cli/tsconfig.json | 13 - packages/workbox-core/tsconfig.json | 9 - packages/workbox-expiration/tsconfig.json | 10 - .../workbox-google-analytics/tsconfig.json | 15 - .../workbox-navigation-preload/tsconfig.json | 10 - packages/workbox-precaching/tsconfig.json | 14 - packages/workbox-range-requests/tsconfig.json | 10 - packages/workbox-recipes/tsconfig.json | 17 - packages/workbox-routing/tsconfig.json | 10 - packages/workbox-strategies/tsconfig.json | 10 - packages/workbox-streams/tsconfig.json | 10 - packages/workbox-webpack-plugin/tsconfig.json | 14 - packages/workbox-window/tsconfig.json | 15 - pnpm-lock.yaml | 521 ++++++++---------- 286 files changed, 457 insertions(+), 569 deletions(-) create mode 100644 packages/serwiss/README.md rename packages/{workbox-background-sync => serwiss/background-sync}/README.md (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/package.json (88%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/BackgroundSyncPlugin.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/Queue.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/QueueStore.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/StorableRequest.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/_version.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/index.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/lib/QueueDb.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/lib/QueueStore.ts (100%) rename packages/{workbox-background-sync => serwiss/background-sync}/src/lib/StorableRequest.ts (100%) create mode 100644 packages/serwiss/background-sync/tsconfig.json rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/README.md (100%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/package.json (82%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/src/BroadcastCacheUpdate.ts (100%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/src/BroadcastUpdatePlugin.ts (100%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/src/_version.ts (100%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/src/index.ts (100%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/src/responsesAreSame.ts (100%) rename packages/{workbox-broadcast-update => serwiss/broadcast-update}/src/utils/constants.ts (100%) create mode 100644 packages/serwiss/broadcast-update/tsconfig.json rename packages/{workbox-build => serwiss/build}/README.md (100%) rename packages/{workbox-build => serwiss/build}/package.json (61%) rename packages/{workbox-build => serwiss/build}/src/_types.js (100%) rename packages/{workbox-build => serwiss/build}/src/cdn-details.json (100%) rename packages/{workbox-build => serwiss/build}/src/generate-sw.ts (100%) rename packages/{workbox-build => serwiss/build}/src/get-manifest.ts (100%) rename packages/{workbox-build => serwiss/build}/src/index.ts (100%) rename packages/{workbox-build => serwiss/build}/src/inject-manifest.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/additional-manifest-entries-transform.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/bundle.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/cdn-utils.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/copy-workbox-libraries.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/errors.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/escape-regexp.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-composite-details.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-file-details.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-file-hash.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-file-manifest-entries.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-file-size.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-source-map-url.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-string-details.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/get-string-hash.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/maximum-size-transform.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/modify-url-prefix-transform.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/module-registry.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/no-revision-for-urls-matching-transform.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/populate-sw-template.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/rebase-path.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/replace-and-update-source-map.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/runtime-caching-converter.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/stringify-without-comments.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/transform-manifest.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/translate-url-to-sourcemap-paths.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/validate-options.ts (100%) rename packages/{workbox-build => serwiss/build}/src/lib/write-sw-using-default-template.ts (100%) rename packages/{workbox-build => serwiss/build}/src/rollup-plugin-off-main-thread.d.ts (100%) rename packages/{workbox-build => serwiss/build}/src/schema/GenerateSWOptions.json (100%) rename packages/{workbox-build => serwiss/build}/src/schema/GetManifestOptions.json (100%) rename packages/{workbox-build => serwiss/build}/src/schema/InjectManifestOptions.json (100%) rename packages/{workbox-build => serwiss/build}/src/schema/WebpackGenerateSWOptions.json (100%) rename packages/{workbox-build => serwiss/build}/src/schema/WebpackInjectManifestOptions.json (100%) rename packages/{workbox-build => serwiss/build}/src/strip-comments.d.ts (100%) rename packages/{workbox-build => serwiss/build}/src/templates/sw-template.ts (100%) rename packages/{workbox-build => serwiss/build}/src/types.ts (100%) create mode 100644 packages/serwiss/build/tsconfig.json rename packages/{workbox-cacheable-response => serwiss/cacheable-response}/README.md (100%) rename packages/{workbox-cacheable-response => serwiss/cacheable-response}/package.json (82%) rename packages/{workbox-cacheable-response => serwiss/cacheable-response}/src/CacheableResponse.ts (100%) rename packages/{workbox-cacheable-response => serwiss/cacheable-response}/src/CacheableResponsePlugin.ts (100%) rename packages/{workbox-cacheable-response => serwiss/cacheable-response}/src/_version.ts (100%) rename packages/{workbox-cacheable-response => serwiss/cacheable-response}/src/index.ts (100%) create mode 100644 packages/serwiss/cacheable-response/tsconfig.json rename packages/{workbox-cli => serwiss/cli}/README.md (100%) rename packages/{workbox-cli => serwiss/cli}/package.json (90%) rename packages/{workbox-cli => serwiss/cli}/src/app.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/bin.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/cleanup-stack-trace.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/constants.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/errors.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/help-text.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/logger.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-config-location.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-extensions-to-cache.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-questions.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-root-of-web-app.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-start_url-query-params.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-sw-dest.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/questions/ask-sw-src.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/read-config.ts (100%) rename packages/{workbox-cli => serwiss/cli}/src/lib/run-wizard.ts (100%) create mode 100644 packages/serwiss/cli/tsconfig.json rename packages/{workbox-core => serwiss/core}/README.md (100%) rename packages/{workbox-core => serwiss/core}/package.json (87%) rename packages/{workbox-core => serwiss/core}/src/_private.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/Deferred.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/WorkboxError.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/assert.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/cacheMatchIgnoreParams.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/cacheNames.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/canConstructReadableStream.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/canConstructResponseFromBodyStream.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/dontWaitFor.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/executeQuotaErrorCallbacks.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/getFriendlyURL.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/logger.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/resultingClientExists.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/timeout.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_private/waitUntil.ts (100%) rename packages/{workbox-core => serwiss/core}/src/_version.ts (100%) rename packages/{workbox-core => serwiss/core}/src/cacheNames.ts (100%) rename packages/{workbox-core => serwiss/core}/src/clientsClaim.ts (100%) rename packages/{workbox-core => serwiss/core}/src/copyResponse.ts (100%) rename packages/{workbox-core => serwiss/core}/src/index.ts (100%) rename packages/{workbox-core => serwiss/core}/src/models/messages/messageGenerator.ts (100%) rename packages/{workbox-core => serwiss/core}/src/models/messages/messages.ts (100%) rename packages/{workbox-core => serwiss/core}/src/models/pluginEvents.ts (100%) rename packages/{workbox-core => serwiss/core}/src/models/quotaErrorCallbacks.ts (100%) rename packages/{workbox-core => serwiss/core}/src/registerQuotaErrorCallback.ts (100%) rename packages/{workbox-core => serwiss/core}/src/setCacheNameDetails.ts (100%) rename packages/{workbox-core => serwiss/core}/src/skipWaiting.ts (100%) rename packages/{workbox-core => serwiss/core}/src/types.ts (100%) rename packages/{workbox-core => serwiss/core}/src/utils/pluginUtils.ts (100%) rename packages/{workbox-core => serwiss/core}/src/utils/welcome.ts (100%) create mode 100644 packages/serwiss/core/tsconfig.json rename packages/{workbox-expiration => serwiss/expiration}/README.md (100%) rename packages/{workbox-expiration => serwiss/expiration}/package.json (82%) rename packages/{workbox-expiration => serwiss/expiration}/src/CacheExpiration.ts (100%) rename packages/{workbox-expiration => serwiss/expiration}/src/ExpirationPlugin.ts (100%) rename packages/{workbox-expiration => serwiss/expiration}/src/_version.ts (100%) rename packages/{workbox-expiration => serwiss/expiration}/src/index.ts (100%) rename packages/{workbox-expiration => serwiss/expiration}/src/models/CacheTimestampsModel.ts (100%) create mode 100644 packages/serwiss/expiration/tsconfig.json rename packages/{workbox-google-analytics => serwiss/google-analytics}/README.md (100%) rename packages/{workbox-google-analytics => serwiss/google-analytics}/package.json (69%) rename packages/{workbox-google-analytics => serwiss/google-analytics}/src/_version.ts (100%) rename packages/{workbox-google-analytics => serwiss/google-analytics}/src/index.ts (100%) rename packages/{workbox-google-analytics => serwiss/google-analytics}/src/initialize.ts (100%) rename packages/{workbox-google-analytics => serwiss/google-analytics}/src/utils/constants.ts (100%) create mode 100644 packages/serwiss/google-analytics/tsconfig.json rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/README.md (100%) rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/package.json (81%) rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/src/_version.ts (100%) rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/src/disable.ts (100%) rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/src/enable.ts (100%) rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/src/index.ts (100%) rename packages/{workbox-navigation-preload => serwiss/navigation-preload}/src/isSupported.ts (100%) create mode 100644 packages/serwiss/navigation-preload/tsconfig.json rename packages/{workbox-precaching => serwiss/precaching}/README.md (100%) rename packages/{workbox-precaching => serwiss/precaching}/package.json (69%) rename packages/{workbox-precaching => serwiss/precaching}/src/PrecacheController.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/PrecacheFallbackPlugin.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/PrecacheRoute.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/PrecacheStrategy.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/_types.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/_version.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/addPlugins.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/addRoute.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/cleanupOutdatedCaches.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/createHandlerBoundToURL.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/getCacheKeyForURL.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/index.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/matchPrecache.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/precache.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/precacheAndRoute.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/PrecacheCacheKeyPlugin.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/PrecacheInstallReportPlugin.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/createCacheKey.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/deleteOutdatedCaches.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/generateURLVariations.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/getCacheKeyForURL.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/getOrCreatePrecacheController.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/printCleanupDetails.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/printInstallDetails.ts (100%) rename packages/{workbox-precaching => serwiss/precaching}/src/utils/removeIgnoredSearchParams.ts (100%) create mode 100644 packages/serwiss/precaching/tsconfig.json rename packages/{workbox-range-requests => serwiss/range-requests}/README.md (100%) rename packages/{workbox-range-requests => serwiss/range-requests}/package.json (82%) rename packages/{workbox-range-requests => serwiss/range-requests}/src/RangeRequestsPlugin.ts (100%) rename packages/{workbox-range-requests => serwiss/range-requests}/src/_version.ts (100%) rename packages/{workbox-range-requests => serwiss/range-requests}/src/createPartialResponse.ts (100%) rename packages/{workbox-range-requests => serwiss/range-requests}/src/index.ts (100%) rename packages/{workbox-range-requests => serwiss/range-requests}/src/utils/calculateEffectiveBoundaries.ts (100%) rename packages/{workbox-range-requests => serwiss/range-requests}/src/utils/parseRangeHeader.ts (100%) create mode 100644 packages/serwiss/range-requests/tsconfig.json rename packages/{workbox-recipes => serwiss/recipes}/README.md (100%) rename packages/{workbox-recipes => serwiss/recipes}/package.json (59%) rename packages/{workbox-recipes => serwiss/recipes}/src/_version.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/googleFontsCache.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/imageCache.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/index.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/offlineFallback.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/pageCache.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/staticResourceCache.ts (100%) rename packages/{workbox-recipes => serwiss/recipes}/src/warmStrategyCache.ts (100%) create mode 100644 packages/serwiss/recipes/tsconfig.json rename packages/{workbox-routing => serwiss/routing}/README.md (100%) rename packages/{workbox-routing => serwiss/routing}/package.json (81%) rename packages/{workbox-routing => serwiss/routing}/src/NavigationRoute.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/RegExpRoute.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/Route.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/Router.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/_types.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/_version.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/index.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/registerRoute.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/setCatchHandler.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/setDefaultHandler.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/utils/constants.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/utils/getOrCreateDefaultRouter.ts (100%) rename packages/{workbox-routing => serwiss/routing}/src/utils/normalizeHandler.ts (100%) create mode 100644 packages/serwiss/routing/tsconfig.json rename packages/{workbox-strategies => serwiss/strategies}/README.md (100%) rename packages/{workbox-strategies => serwiss/strategies}/package.json (81%) rename packages/{workbox-strategies => serwiss/strategies}/src/CacheFirst.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/CacheOnly.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/NetworkFirst.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/NetworkOnly.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/StaleWhileRevalidate.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/Strategy.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/StrategyHandler.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/_version.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/index.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/plugins/cacheOkAndOpaquePlugin.ts (100%) rename packages/{workbox-strategies => serwiss/strategies}/src/utils/messages.ts (100%) create mode 100644 packages/serwiss/strategies/tsconfig.json rename packages/{workbox-streams => serwiss/streams}/README.md (100%) rename packages/{workbox-streams => serwiss/streams}/package.json (76%) rename packages/{workbox-streams => serwiss/streams}/src/_types.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/_version.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/concatenate.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/concatenateToResponse.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/index.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/isSupported.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/strategy.ts (100%) rename packages/{workbox-streams => serwiss/streams}/src/utils/createHeaders.ts (100%) create mode 100644 packages/serwiss/streams/tsconfig.json rename packages/{workbox-sw => serwiss/sw}/README.md (100%) rename packages/{workbox-sw => serwiss/sw}/_types.mjs (100%) rename packages/{workbox-sw => serwiss/sw}/_version.mjs (100%) rename packages/{workbox-sw => serwiss/sw}/controllers/WorkboxSW.mjs (100%) rename packages/{workbox-sw => serwiss/sw}/index.mjs (100%) rename packages/{workbox-sw => serwiss/sw}/package.json (87%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/README.md (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/package.json (87%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/generate-sw.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/index.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/inject-manifest.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/lib/get-asset-hash.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/lib/get-manifest-entries-from-compilation.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/lib/get-script-files-for-chunks.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/lib/get-sourcemap-asset-name.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/lib/relative-to-output-path.ts (100%) rename packages/{workbox-webpack-plugin => serwiss/webpack-plugin}/src/lib/resolve-webpack-url.ts (100%) create mode 100644 packages/serwiss/webpack-plugin/tsconfig.json rename packages/{workbox-window => serwiss/window}/README.md (100%) rename packages/{workbox-window => serwiss/window}/package.json (85%) rename packages/{workbox-window => serwiss/window}/src/Workbox.ts (100%) rename packages/{workbox-window => serwiss/window}/src/_version.ts (100%) rename packages/{workbox-window => serwiss/window}/src/index.ts (100%) rename packages/{workbox-window => serwiss/window}/src/messageSW.ts (100%) rename packages/{workbox-window => serwiss/window}/src/utils/WorkboxEvent.ts (100%) rename packages/{workbox-window => serwiss/window}/src/utils/WorkboxEventTarget.ts (100%) rename packages/{workbox-window => serwiss/window}/src/utils/urlsMatch.ts (100%) create mode 100644 packages/serwiss/window/tsconfig.json delete mode 100644 packages/workbox-background-sync/tsconfig.json delete mode 100644 packages/workbox-broadcast-update/tsconfig.json delete mode 100644 packages/workbox-build/tsconfig.json delete mode 100644 packages/workbox-cacheable-response/tsconfig.json delete mode 100644 packages/workbox-cli/tsconfig.json delete mode 100644 packages/workbox-core/tsconfig.json delete mode 100644 packages/workbox-expiration/tsconfig.json delete mode 100644 packages/workbox-google-analytics/tsconfig.json delete mode 100644 packages/workbox-navigation-preload/tsconfig.json delete mode 100644 packages/workbox-precaching/tsconfig.json delete mode 100644 packages/workbox-range-requests/tsconfig.json delete mode 100644 packages/workbox-recipes/tsconfig.json delete mode 100644 packages/workbox-routing/tsconfig.json delete mode 100644 packages/workbox-strategies/tsconfig.json delete mode 100644 packages/workbox-streams/tsconfig.json delete mode 100644 packages/workbox-webpack-plugin/tsconfig.json delete mode 100644 packages/workbox-window/tsconfig.json diff --git a/LICENSE b/LICENSE index 6b7781c2..d4d28437 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 ShadowWalker w@weiw.io https://weiw.io, 2022 DuCanhGH (fork version) +Copyright (c) 2018 Google LLC, 2019 ShadowWalker w@weiw.io https://weiw.io, 2022 DuCanhGH (fork version) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/next-pwa/README.md b/packages/next-pwa/README.md index 805c89e2..9dfe70f2 100644 --- a/packages/next-pwa/README.md +++ b/packages/next-pwa/README.md @@ -5,20 +5,6 @@ This plugin is powered by [Workbox](https://developer.chrome.com/docs/workbox/) [![Build Size](https://img.shields.io/bundlephobia/minzip/@ducanh2912/next-pwa?label=Bundle%20size&style=flat&color=success)](https://bundlephobia.com/result?p=@ducanh2912/next-pwa) [![Version](https://img.shields.io/npm/v/@ducanh2912/next-pwa?style=flat&color=success)](https://www.npmjs.com/package/@ducanh2912/next-pwa) -## Features - -- 0️⃣ No configuration needed, but is configurable using Workbox's options and our own options. -- ✨ Optimized precaching and runtime caching. -- 💯 Maximal Lighthouse score. -- 🎈 Easy-to-understand examples. -- 📴 Offline support [(you can also provide fallbacks for when fetching fails)](/examples/offline-fallback-v2). -- 🔉 Default range requests for audios and videos. -- 📐 [Custom worker to run your own code (also supports path aliases, TypeScript and code splitting!).](/examples/custom-worker) -- 📜 [Public environment variables](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables) are available in custom workers. -- 🐞 Debug service worker in development mode. -- 🌏 [Internationalization support with `next-i18next`.](/examples/next-i18next) -- ⚡ Supports [blitz.js](https://blitzjs.com/) (simply add `blitz.config.js`) and [GitPod](https://gitpod.io/#https://github.com/DuCanhGH/next-pwa/). - --- ## Getting Started diff --git a/packages/serwiss/README.md b/packages/serwiss/README.md new file mode 100644 index 00000000..68f6dbe1 --- /dev/null +++ b/packages/serwiss/README.md @@ -0,0 +1,17 @@ +# A Swiss Army knife for service workers. + +Serwiss is a collection of JavaScript libraries for [Progressive Web Apps](https://web.dev/progressive-web-apps/). + +It is a fork of Workbox that happened due to the aforementioned's development being stagnated. Most work was done by Google LLC's team and the community. In addition to those that appear in this repo's commit history, these are [the ones who have also contributed](https://github.com/GoogleChrome/workbox/graphs/contributors) + +--- + +## Documentation + +- [Overview](https://developers.google.com/web/tools/workbox/) ([site source](https://github.com/google/WebFundamentals/tree/main/src/content/en/tools/workbox)) +- [Get started](https://developers.google.com/web/tools/workbox/guides/get-started) +- [Contribute](/CONTRIBUTING.md) + +## Contributing + +Please see [our contributing guide](/CONTRIBUTING.md). diff --git a/packages/workbox-background-sync/README.md b/packages/serwiss/background-sync/README.md similarity index 100% rename from packages/workbox-background-sync/README.md rename to packages/serwiss/background-sync/README.md diff --git a/packages/workbox-background-sync/package.json b/packages/serwiss/background-sync/package.json similarity index 88% rename from packages/workbox-background-sync/package.json rename to packages/serwiss/background-sync/package.json index dc54c4bc..5c19b982 100644 --- a/packages/workbox-background-sync/package.json +++ b/packages/serwiss/background-sync/package.json @@ -1,5 +1,5 @@ { - "name": "@ducanh2912/workbox-background-sync", + "name": "@serwiss/background-sync", "version": "7.0.0", "license": "MIT", "author": "Google's Web DevRel Team, DuCanhGH", @@ -24,7 +24,7 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*", + "@serwiss/core": "workspace:*", "idb": "7.1.1" } } diff --git a/packages/workbox-background-sync/src/BackgroundSyncPlugin.ts b/packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts similarity index 100% rename from packages/workbox-background-sync/src/BackgroundSyncPlugin.ts rename to packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts diff --git a/packages/workbox-background-sync/src/Queue.ts b/packages/serwiss/background-sync/src/Queue.ts similarity index 100% rename from packages/workbox-background-sync/src/Queue.ts rename to packages/serwiss/background-sync/src/Queue.ts diff --git a/packages/workbox-background-sync/src/QueueStore.ts b/packages/serwiss/background-sync/src/QueueStore.ts similarity index 100% rename from packages/workbox-background-sync/src/QueueStore.ts rename to packages/serwiss/background-sync/src/QueueStore.ts diff --git a/packages/workbox-background-sync/src/StorableRequest.ts b/packages/serwiss/background-sync/src/StorableRequest.ts similarity index 100% rename from packages/workbox-background-sync/src/StorableRequest.ts rename to packages/serwiss/background-sync/src/StorableRequest.ts diff --git a/packages/workbox-background-sync/src/_version.ts b/packages/serwiss/background-sync/src/_version.ts similarity index 100% rename from packages/workbox-background-sync/src/_version.ts rename to packages/serwiss/background-sync/src/_version.ts diff --git a/packages/workbox-background-sync/src/index.ts b/packages/serwiss/background-sync/src/index.ts similarity index 100% rename from packages/workbox-background-sync/src/index.ts rename to packages/serwiss/background-sync/src/index.ts diff --git a/packages/workbox-background-sync/src/lib/QueueDb.ts b/packages/serwiss/background-sync/src/lib/QueueDb.ts similarity index 100% rename from packages/workbox-background-sync/src/lib/QueueDb.ts rename to packages/serwiss/background-sync/src/lib/QueueDb.ts diff --git a/packages/workbox-background-sync/src/lib/QueueStore.ts b/packages/serwiss/background-sync/src/lib/QueueStore.ts similarity index 100% rename from packages/workbox-background-sync/src/lib/QueueStore.ts rename to packages/serwiss/background-sync/src/lib/QueueStore.ts diff --git a/packages/workbox-background-sync/src/lib/StorableRequest.ts b/packages/serwiss/background-sync/src/lib/StorableRequest.ts similarity index 100% rename from packages/workbox-background-sync/src/lib/StorableRequest.ts rename to packages/serwiss/background-sync/src/lib/StorableRequest.ts diff --git a/packages/serwiss/background-sync/tsconfig.json b/packages/serwiss/background-sync/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/background-sync/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-broadcast-update/README.md b/packages/serwiss/broadcast-update/README.md similarity index 100% rename from packages/workbox-broadcast-update/README.md rename to packages/serwiss/broadcast-update/README.md diff --git a/packages/workbox-broadcast-update/package.json b/packages/serwiss/broadcast-update/package.json similarity index 82% rename from packages/workbox-broadcast-update/package.json rename to packages/serwiss/broadcast-update/package.json index c1625681..2d25acdc 100644 --- a/packages/workbox-broadcast-update/package.json +++ b/packages/serwiss/broadcast-update/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-broadcast-update", + "name": "@serwiss/broadcast-update", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library that uses the Broadcast Channel API to announce when a cached response has updated", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -22,6 +22,6 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "7.0.0" + "@serwiss/core": "7.0.0" } } diff --git a/packages/workbox-broadcast-update/src/BroadcastCacheUpdate.ts b/packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts similarity index 100% rename from packages/workbox-broadcast-update/src/BroadcastCacheUpdate.ts rename to packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts diff --git a/packages/workbox-broadcast-update/src/BroadcastUpdatePlugin.ts b/packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts similarity index 100% rename from packages/workbox-broadcast-update/src/BroadcastUpdatePlugin.ts rename to packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts diff --git a/packages/workbox-broadcast-update/src/_version.ts b/packages/serwiss/broadcast-update/src/_version.ts similarity index 100% rename from packages/workbox-broadcast-update/src/_version.ts rename to packages/serwiss/broadcast-update/src/_version.ts diff --git a/packages/workbox-broadcast-update/src/index.ts b/packages/serwiss/broadcast-update/src/index.ts similarity index 100% rename from packages/workbox-broadcast-update/src/index.ts rename to packages/serwiss/broadcast-update/src/index.ts diff --git a/packages/workbox-broadcast-update/src/responsesAreSame.ts b/packages/serwiss/broadcast-update/src/responsesAreSame.ts similarity index 100% rename from packages/workbox-broadcast-update/src/responsesAreSame.ts rename to packages/serwiss/broadcast-update/src/responsesAreSame.ts diff --git a/packages/workbox-broadcast-update/src/utils/constants.ts b/packages/serwiss/broadcast-update/src/utils/constants.ts similarity index 100% rename from packages/workbox-broadcast-update/src/utils/constants.ts rename to packages/serwiss/broadcast-update/src/utils/constants.ts diff --git a/packages/serwiss/broadcast-update/tsconfig.json b/packages/serwiss/broadcast-update/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/broadcast-update/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-build/README.md b/packages/serwiss/build/README.md similarity index 100% rename from packages/workbox-build/README.md rename to packages/serwiss/build/README.md diff --git a/packages/workbox-build/package.json b/packages/serwiss/build/package.json similarity index 61% rename from packages/workbox-build/package.json rename to packages/serwiss/build/package.json index 10c48550..f6d51167 100644 --- a/packages/workbox-build/package.json +++ b/packages/serwiss/build/package.json @@ -1,5 +1,5 @@ { - "name": "@ducanh2912/workbox-build", + "name": "@serwiss/build", "version": "7.0.0", "description": "A module that integrates into your build process, helping you generate a manifest of local files that workbox-sw should precache.", "keywords": [ @@ -14,7 +14,7 @@ "engines": { "node": ">=16.0.0" }, - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "license": "MIT", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -24,26 +24,26 @@ "@babel/core": "7.23.2", "@babel/preset-env": "7.23.2", "@babel/runtime": "7.23.2", - "@ducanh2912/workbox-background-sync": "workspace:*", - "@ducanh2912/workbox-broadcast-update": "workspace:*", - "@ducanh2912/workbox-cacheable-response": "workspace:*", - "@ducanh2912/workbox-core": "workspace:*", - "@ducanh2912/workbox-expiration": "workspace:*", - "@ducanh2912/workbox-google-analytics": "workspace:*", - "@ducanh2912/workbox-navigation-preload": "workspace:*", - "@ducanh2912/workbox-precaching": "workspace:*", - "@ducanh2912/workbox-range-requests": "workspace:*", - "@ducanh2912/workbox-recipes": "workspace:*", - "@ducanh2912/workbox-routing": "workspace:*", - "@ducanh2912/workbox-strategies": "workspace:*", - "@ducanh2912/workbox-streams": "workspace:*", - "@ducanh2912/workbox-sw": "workspace:*", - "@ducanh2912/workbox-window": "workspace:*", + "@serwiss/background-sync": "workspace:*", + "@serwiss/broadcast-update": "workspace:*", + "@serwiss/cacheable-response": "workspace:*", + "@serwiss/core": "workspace:*", + "@serwiss/expiration": "workspace:*", + "@serwiss/google-analytics": "workspace:*", + "@serwiss/navigation-preload": "workspace:*", + "@serwiss/precaching": "workspace:*", + "@serwiss/range-requests": "workspace:*", + "@serwiss/recipes": "workspace:*", + "@serwiss/routing": "workspace:*", + "@serwiss/strategies": "workspace:*", + "@serwiss/streams": "workspace:*", + "@serwiss/sw": "workspace:*", + "@serwiss/window": "workspace:*", + "@surma/rollup-plugin-off-main-thread": "2.2.3", "@rollup/plugin-babel": "6.0.4", "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-replace": "5.0.4", "@rollup/plugin-terser": "0.4.4", - "@surma/rollup-plugin-off-main-thread": "2.2.3", "ajv": "8.12.0", "common-tags": "1.8.2", "fast-json-stable-stringify": "2.1.0", diff --git a/packages/workbox-build/src/_types.js b/packages/serwiss/build/src/_types.js similarity index 100% rename from packages/workbox-build/src/_types.js rename to packages/serwiss/build/src/_types.js diff --git a/packages/workbox-build/src/cdn-details.json b/packages/serwiss/build/src/cdn-details.json similarity index 100% rename from packages/workbox-build/src/cdn-details.json rename to packages/serwiss/build/src/cdn-details.json diff --git a/packages/workbox-build/src/generate-sw.ts b/packages/serwiss/build/src/generate-sw.ts similarity index 100% rename from packages/workbox-build/src/generate-sw.ts rename to packages/serwiss/build/src/generate-sw.ts diff --git a/packages/workbox-build/src/get-manifest.ts b/packages/serwiss/build/src/get-manifest.ts similarity index 100% rename from packages/workbox-build/src/get-manifest.ts rename to packages/serwiss/build/src/get-manifest.ts diff --git a/packages/workbox-build/src/index.ts b/packages/serwiss/build/src/index.ts similarity index 100% rename from packages/workbox-build/src/index.ts rename to packages/serwiss/build/src/index.ts diff --git a/packages/workbox-build/src/inject-manifest.ts b/packages/serwiss/build/src/inject-manifest.ts similarity index 100% rename from packages/workbox-build/src/inject-manifest.ts rename to packages/serwiss/build/src/inject-manifest.ts diff --git a/packages/workbox-build/src/lib/additional-manifest-entries-transform.ts b/packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts similarity index 100% rename from packages/workbox-build/src/lib/additional-manifest-entries-transform.ts rename to packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts diff --git a/packages/workbox-build/src/lib/bundle.ts b/packages/serwiss/build/src/lib/bundle.ts similarity index 100% rename from packages/workbox-build/src/lib/bundle.ts rename to packages/serwiss/build/src/lib/bundle.ts diff --git a/packages/workbox-build/src/lib/cdn-utils.ts b/packages/serwiss/build/src/lib/cdn-utils.ts similarity index 100% rename from packages/workbox-build/src/lib/cdn-utils.ts rename to packages/serwiss/build/src/lib/cdn-utils.ts diff --git a/packages/workbox-build/src/lib/copy-workbox-libraries.ts b/packages/serwiss/build/src/lib/copy-workbox-libraries.ts similarity index 100% rename from packages/workbox-build/src/lib/copy-workbox-libraries.ts rename to packages/serwiss/build/src/lib/copy-workbox-libraries.ts diff --git a/packages/workbox-build/src/lib/errors.ts b/packages/serwiss/build/src/lib/errors.ts similarity index 100% rename from packages/workbox-build/src/lib/errors.ts rename to packages/serwiss/build/src/lib/errors.ts diff --git a/packages/workbox-build/src/lib/escape-regexp.ts b/packages/serwiss/build/src/lib/escape-regexp.ts similarity index 100% rename from packages/workbox-build/src/lib/escape-regexp.ts rename to packages/serwiss/build/src/lib/escape-regexp.ts diff --git a/packages/workbox-build/src/lib/get-composite-details.ts b/packages/serwiss/build/src/lib/get-composite-details.ts similarity index 100% rename from packages/workbox-build/src/lib/get-composite-details.ts rename to packages/serwiss/build/src/lib/get-composite-details.ts diff --git a/packages/workbox-build/src/lib/get-file-details.ts b/packages/serwiss/build/src/lib/get-file-details.ts similarity index 100% rename from packages/workbox-build/src/lib/get-file-details.ts rename to packages/serwiss/build/src/lib/get-file-details.ts diff --git a/packages/workbox-build/src/lib/get-file-hash.ts b/packages/serwiss/build/src/lib/get-file-hash.ts similarity index 100% rename from packages/workbox-build/src/lib/get-file-hash.ts rename to packages/serwiss/build/src/lib/get-file-hash.ts diff --git a/packages/workbox-build/src/lib/get-file-manifest-entries.ts b/packages/serwiss/build/src/lib/get-file-manifest-entries.ts similarity index 100% rename from packages/workbox-build/src/lib/get-file-manifest-entries.ts rename to packages/serwiss/build/src/lib/get-file-manifest-entries.ts diff --git a/packages/workbox-build/src/lib/get-file-size.ts b/packages/serwiss/build/src/lib/get-file-size.ts similarity index 100% rename from packages/workbox-build/src/lib/get-file-size.ts rename to packages/serwiss/build/src/lib/get-file-size.ts diff --git a/packages/workbox-build/src/lib/get-source-map-url.ts b/packages/serwiss/build/src/lib/get-source-map-url.ts similarity index 100% rename from packages/workbox-build/src/lib/get-source-map-url.ts rename to packages/serwiss/build/src/lib/get-source-map-url.ts diff --git a/packages/workbox-build/src/lib/get-string-details.ts b/packages/serwiss/build/src/lib/get-string-details.ts similarity index 100% rename from packages/workbox-build/src/lib/get-string-details.ts rename to packages/serwiss/build/src/lib/get-string-details.ts diff --git a/packages/workbox-build/src/lib/get-string-hash.ts b/packages/serwiss/build/src/lib/get-string-hash.ts similarity index 100% rename from packages/workbox-build/src/lib/get-string-hash.ts rename to packages/serwiss/build/src/lib/get-string-hash.ts diff --git a/packages/workbox-build/src/lib/maximum-size-transform.ts b/packages/serwiss/build/src/lib/maximum-size-transform.ts similarity index 100% rename from packages/workbox-build/src/lib/maximum-size-transform.ts rename to packages/serwiss/build/src/lib/maximum-size-transform.ts diff --git a/packages/workbox-build/src/lib/modify-url-prefix-transform.ts b/packages/serwiss/build/src/lib/modify-url-prefix-transform.ts similarity index 100% rename from packages/workbox-build/src/lib/modify-url-prefix-transform.ts rename to packages/serwiss/build/src/lib/modify-url-prefix-transform.ts diff --git a/packages/workbox-build/src/lib/module-registry.ts b/packages/serwiss/build/src/lib/module-registry.ts similarity index 100% rename from packages/workbox-build/src/lib/module-registry.ts rename to packages/serwiss/build/src/lib/module-registry.ts diff --git a/packages/workbox-build/src/lib/no-revision-for-urls-matching-transform.ts b/packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts similarity index 100% rename from packages/workbox-build/src/lib/no-revision-for-urls-matching-transform.ts rename to packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts diff --git a/packages/workbox-build/src/lib/populate-sw-template.ts b/packages/serwiss/build/src/lib/populate-sw-template.ts similarity index 100% rename from packages/workbox-build/src/lib/populate-sw-template.ts rename to packages/serwiss/build/src/lib/populate-sw-template.ts diff --git a/packages/workbox-build/src/lib/rebase-path.ts b/packages/serwiss/build/src/lib/rebase-path.ts similarity index 100% rename from packages/workbox-build/src/lib/rebase-path.ts rename to packages/serwiss/build/src/lib/rebase-path.ts diff --git a/packages/workbox-build/src/lib/replace-and-update-source-map.ts b/packages/serwiss/build/src/lib/replace-and-update-source-map.ts similarity index 100% rename from packages/workbox-build/src/lib/replace-and-update-source-map.ts rename to packages/serwiss/build/src/lib/replace-and-update-source-map.ts diff --git a/packages/workbox-build/src/lib/runtime-caching-converter.ts b/packages/serwiss/build/src/lib/runtime-caching-converter.ts similarity index 100% rename from packages/workbox-build/src/lib/runtime-caching-converter.ts rename to packages/serwiss/build/src/lib/runtime-caching-converter.ts diff --git a/packages/workbox-build/src/lib/stringify-without-comments.ts b/packages/serwiss/build/src/lib/stringify-without-comments.ts similarity index 100% rename from packages/workbox-build/src/lib/stringify-without-comments.ts rename to packages/serwiss/build/src/lib/stringify-without-comments.ts diff --git a/packages/workbox-build/src/lib/transform-manifest.ts b/packages/serwiss/build/src/lib/transform-manifest.ts similarity index 100% rename from packages/workbox-build/src/lib/transform-manifest.ts rename to packages/serwiss/build/src/lib/transform-manifest.ts diff --git a/packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts b/packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts similarity index 100% rename from packages/workbox-build/src/lib/translate-url-to-sourcemap-paths.ts rename to packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts diff --git a/packages/workbox-build/src/lib/validate-options.ts b/packages/serwiss/build/src/lib/validate-options.ts similarity index 100% rename from packages/workbox-build/src/lib/validate-options.ts rename to packages/serwiss/build/src/lib/validate-options.ts diff --git a/packages/workbox-build/src/lib/write-sw-using-default-template.ts b/packages/serwiss/build/src/lib/write-sw-using-default-template.ts similarity index 100% rename from packages/workbox-build/src/lib/write-sw-using-default-template.ts rename to packages/serwiss/build/src/lib/write-sw-using-default-template.ts diff --git a/packages/workbox-build/src/rollup-plugin-off-main-thread.d.ts b/packages/serwiss/build/src/rollup-plugin-off-main-thread.d.ts similarity index 100% rename from packages/workbox-build/src/rollup-plugin-off-main-thread.d.ts rename to packages/serwiss/build/src/rollup-plugin-off-main-thread.d.ts diff --git a/packages/workbox-build/src/schema/GenerateSWOptions.json b/packages/serwiss/build/src/schema/GenerateSWOptions.json similarity index 100% rename from packages/workbox-build/src/schema/GenerateSWOptions.json rename to packages/serwiss/build/src/schema/GenerateSWOptions.json diff --git a/packages/workbox-build/src/schema/GetManifestOptions.json b/packages/serwiss/build/src/schema/GetManifestOptions.json similarity index 100% rename from packages/workbox-build/src/schema/GetManifestOptions.json rename to packages/serwiss/build/src/schema/GetManifestOptions.json diff --git a/packages/workbox-build/src/schema/InjectManifestOptions.json b/packages/serwiss/build/src/schema/InjectManifestOptions.json similarity index 100% rename from packages/workbox-build/src/schema/InjectManifestOptions.json rename to packages/serwiss/build/src/schema/InjectManifestOptions.json diff --git a/packages/workbox-build/src/schema/WebpackGenerateSWOptions.json b/packages/serwiss/build/src/schema/WebpackGenerateSWOptions.json similarity index 100% rename from packages/workbox-build/src/schema/WebpackGenerateSWOptions.json rename to packages/serwiss/build/src/schema/WebpackGenerateSWOptions.json diff --git a/packages/workbox-build/src/schema/WebpackInjectManifestOptions.json b/packages/serwiss/build/src/schema/WebpackInjectManifestOptions.json similarity index 100% rename from packages/workbox-build/src/schema/WebpackInjectManifestOptions.json rename to packages/serwiss/build/src/schema/WebpackInjectManifestOptions.json diff --git a/packages/workbox-build/src/strip-comments.d.ts b/packages/serwiss/build/src/strip-comments.d.ts similarity index 100% rename from packages/workbox-build/src/strip-comments.d.ts rename to packages/serwiss/build/src/strip-comments.d.ts diff --git a/packages/workbox-build/src/templates/sw-template.ts b/packages/serwiss/build/src/templates/sw-template.ts similarity index 100% rename from packages/workbox-build/src/templates/sw-template.ts rename to packages/serwiss/build/src/templates/sw-template.ts diff --git a/packages/workbox-build/src/types.ts b/packages/serwiss/build/src/types.ts similarity index 100% rename from packages/workbox-build/src/types.ts rename to packages/serwiss/build/src/types.ts diff --git a/packages/serwiss/build/tsconfig.json b/packages/serwiss/build/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/build/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-cacheable-response/README.md b/packages/serwiss/cacheable-response/README.md similarity index 100% rename from packages/workbox-cacheable-response/README.md rename to packages/serwiss/cacheable-response/README.md diff --git a/packages/workbox-cacheable-response/package.json b/packages/serwiss/cacheable-response/package.json similarity index 82% rename from packages/workbox-cacheable-response/package.json rename to packages/serwiss/cacheable-response/package.json index c4bd7487..80834bcf 100755 --- a/packages/workbox-cacheable-response/package.json +++ b/packages/serwiss/cacheable-response/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-cacheable-response", + "name": "@serwiss/cacheable-response", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "This library takes a Response object and determines whether it's cacheable based on a specific configuration.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -22,6 +22,6 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "7.0.0" + "@serwiss/core": "7.0.0" } } diff --git a/packages/workbox-cacheable-response/src/CacheableResponse.ts b/packages/serwiss/cacheable-response/src/CacheableResponse.ts similarity index 100% rename from packages/workbox-cacheable-response/src/CacheableResponse.ts rename to packages/serwiss/cacheable-response/src/CacheableResponse.ts diff --git a/packages/workbox-cacheable-response/src/CacheableResponsePlugin.ts b/packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts similarity index 100% rename from packages/workbox-cacheable-response/src/CacheableResponsePlugin.ts rename to packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts diff --git a/packages/workbox-cacheable-response/src/_version.ts b/packages/serwiss/cacheable-response/src/_version.ts similarity index 100% rename from packages/workbox-cacheable-response/src/_version.ts rename to packages/serwiss/cacheable-response/src/_version.ts diff --git a/packages/workbox-cacheable-response/src/index.ts b/packages/serwiss/cacheable-response/src/index.ts similarity index 100% rename from packages/workbox-cacheable-response/src/index.ts rename to packages/serwiss/cacheable-response/src/index.ts diff --git a/packages/serwiss/cacheable-response/tsconfig.json b/packages/serwiss/cacheable-response/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/cacheable-response/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-cli/README.md b/packages/serwiss/cli/README.md similarity index 100% rename from packages/workbox-cli/README.md rename to packages/serwiss/cli/README.md diff --git a/packages/workbox-cli/package.json b/packages/serwiss/cli/package.json similarity index 90% rename from packages/workbox-cli/package.json rename to packages/serwiss/cli/package.json index f191192d..65f356ae 100644 --- a/packages/workbox-cli/package.json +++ b/packages/serwiss/cli/package.json @@ -1,5 +1,5 @@ { - "name": "@ducanh2912/workbox-cli", + "name": "@serwiss/cli", "version": "7.0.0", "description": "workbox-cli is the command line interface for Workbox.", "keywords": [ @@ -20,13 +20,13 @@ "engines": { "node": ">=16.0.0" }, - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "license": "MIT", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", "homepage": "https://github.com/GoogleChrome/workbox/tree/master/packages/workbox-cli", "dependencies": { - "@ducanh2912/workbox-build": "workspace:*", + "@serwiss/build": "workspace:*", "chalk": "5.3.0", "chokidar": "3.5.3", "common-tags": "1.8.2", diff --git a/packages/workbox-cli/src/app.ts b/packages/serwiss/cli/src/app.ts similarity index 100% rename from packages/workbox-cli/src/app.ts rename to packages/serwiss/cli/src/app.ts diff --git a/packages/workbox-cli/src/bin.ts b/packages/serwiss/cli/src/bin.ts similarity index 100% rename from packages/workbox-cli/src/bin.ts rename to packages/serwiss/cli/src/bin.ts diff --git a/packages/workbox-cli/src/lib/cleanup-stack-trace.ts b/packages/serwiss/cli/src/lib/cleanup-stack-trace.ts similarity index 100% rename from packages/workbox-cli/src/lib/cleanup-stack-trace.ts rename to packages/serwiss/cli/src/lib/cleanup-stack-trace.ts diff --git a/packages/workbox-cli/src/lib/constants.ts b/packages/serwiss/cli/src/lib/constants.ts similarity index 100% rename from packages/workbox-cli/src/lib/constants.ts rename to packages/serwiss/cli/src/lib/constants.ts diff --git a/packages/workbox-cli/src/lib/errors.ts b/packages/serwiss/cli/src/lib/errors.ts similarity index 100% rename from packages/workbox-cli/src/lib/errors.ts rename to packages/serwiss/cli/src/lib/errors.ts diff --git a/packages/workbox-cli/src/lib/help-text.ts b/packages/serwiss/cli/src/lib/help-text.ts similarity index 100% rename from packages/workbox-cli/src/lib/help-text.ts rename to packages/serwiss/cli/src/lib/help-text.ts diff --git a/packages/workbox-cli/src/lib/logger.ts b/packages/serwiss/cli/src/lib/logger.ts similarity index 100% rename from packages/workbox-cli/src/lib/logger.ts rename to packages/serwiss/cli/src/lib/logger.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-config-location.ts b/packages/serwiss/cli/src/lib/questions/ask-config-location.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-config-location.ts rename to packages/serwiss/cli/src/lib/questions/ask-config-location.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-extensions-to-cache.ts b/packages/serwiss/cli/src/lib/questions/ask-extensions-to-cache.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-extensions-to-cache.ts rename to packages/serwiss/cli/src/lib/questions/ask-extensions-to-cache.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-questions.ts b/packages/serwiss/cli/src/lib/questions/ask-questions.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-questions.ts rename to packages/serwiss/cli/src/lib/questions/ask-questions.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts b/packages/serwiss/cli/src/lib/questions/ask-root-of-web-app.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-root-of-web-app.ts rename to packages/serwiss/cli/src/lib/questions/ask-root-of-web-app.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-start_url-query-params.ts b/packages/serwiss/cli/src/lib/questions/ask-start_url-query-params.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-start_url-query-params.ts rename to packages/serwiss/cli/src/lib/questions/ask-start_url-query-params.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-sw-dest.ts b/packages/serwiss/cli/src/lib/questions/ask-sw-dest.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-sw-dest.ts rename to packages/serwiss/cli/src/lib/questions/ask-sw-dest.ts diff --git a/packages/workbox-cli/src/lib/questions/ask-sw-src.ts b/packages/serwiss/cli/src/lib/questions/ask-sw-src.ts similarity index 100% rename from packages/workbox-cli/src/lib/questions/ask-sw-src.ts rename to packages/serwiss/cli/src/lib/questions/ask-sw-src.ts diff --git a/packages/workbox-cli/src/lib/read-config.ts b/packages/serwiss/cli/src/lib/read-config.ts similarity index 100% rename from packages/workbox-cli/src/lib/read-config.ts rename to packages/serwiss/cli/src/lib/read-config.ts diff --git a/packages/workbox-cli/src/lib/run-wizard.ts b/packages/serwiss/cli/src/lib/run-wizard.ts similarity index 100% rename from packages/workbox-cli/src/lib/run-wizard.ts rename to packages/serwiss/cli/src/lib/run-wizard.ts diff --git a/packages/serwiss/cli/tsconfig.json b/packages/serwiss/cli/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/cli/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-core/README.md b/packages/serwiss/core/README.md similarity index 100% rename from packages/workbox-core/README.md rename to packages/serwiss/core/README.md diff --git a/packages/workbox-core/package.json b/packages/serwiss/core/package.json similarity index 87% rename from packages/workbox-core/package.json rename to packages/serwiss/core/package.json index f218ff9c..6b21f075 100644 --- a/packages/workbox-core/package.json +++ b/packages/serwiss/core/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-core", + "name": "@serwiss/core", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "This module is used by a number of the other Workbox modules to share common code.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", diff --git a/packages/workbox-core/src/_private.ts b/packages/serwiss/core/src/_private.ts similarity index 100% rename from packages/workbox-core/src/_private.ts rename to packages/serwiss/core/src/_private.ts diff --git a/packages/workbox-core/src/_private/Deferred.ts b/packages/serwiss/core/src/_private/Deferred.ts similarity index 100% rename from packages/workbox-core/src/_private/Deferred.ts rename to packages/serwiss/core/src/_private/Deferred.ts diff --git a/packages/workbox-core/src/_private/WorkboxError.ts b/packages/serwiss/core/src/_private/WorkboxError.ts similarity index 100% rename from packages/workbox-core/src/_private/WorkboxError.ts rename to packages/serwiss/core/src/_private/WorkboxError.ts diff --git a/packages/workbox-core/src/_private/assert.ts b/packages/serwiss/core/src/_private/assert.ts similarity index 100% rename from packages/workbox-core/src/_private/assert.ts rename to packages/serwiss/core/src/_private/assert.ts diff --git a/packages/workbox-core/src/_private/cacheMatchIgnoreParams.ts b/packages/serwiss/core/src/_private/cacheMatchIgnoreParams.ts similarity index 100% rename from packages/workbox-core/src/_private/cacheMatchIgnoreParams.ts rename to packages/serwiss/core/src/_private/cacheMatchIgnoreParams.ts diff --git a/packages/workbox-core/src/_private/cacheNames.ts b/packages/serwiss/core/src/_private/cacheNames.ts similarity index 100% rename from packages/workbox-core/src/_private/cacheNames.ts rename to packages/serwiss/core/src/_private/cacheNames.ts diff --git a/packages/workbox-core/src/_private/canConstructReadableStream.ts b/packages/serwiss/core/src/_private/canConstructReadableStream.ts similarity index 100% rename from packages/workbox-core/src/_private/canConstructReadableStream.ts rename to packages/serwiss/core/src/_private/canConstructReadableStream.ts diff --git a/packages/workbox-core/src/_private/canConstructResponseFromBodyStream.ts b/packages/serwiss/core/src/_private/canConstructResponseFromBodyStream.ts similarity index 100% rename from packages/workbox-core/src/_private/canConstructResponseFromBodyStream.ts rename to packages/serwiss/core/src/_private/canConstructResponseFromBodyStream.ts diff --git a/packages/workbox-core/src/_private/dontWaitFor.ts b/packages/serwiss/core/src/_private/dontWaitFor.ts similarity index 100% rename from packages/workbox-core/src/_private/dontWaitFor.ts rename to packages/serwiss/core/src/_private/dontWaitFor.ts diff --git a/packages/workbox-core/src/_private/executeQuotaErrorCallbacks.ts b/packages/serwiss/core/src/_private/executeQuotaErrorCallbacks.ts similarity index 100% rename from packages/workbox-core/src/_private/executeQuotaErrorCallbacks.ts rename to packages/serwiss/core/src/_private/executeQuotaErrorCallbacks.ts diff --git a/packages/workbox-core/src/_private/getFriendlyURL.ts b/packages/serwiss/core/src/_private/getFriendlyURL.ts similarity index 100% rename from packages/workbox-core/src/_private/getFriendlyURL.ts rename to packages/serwiss/core/src/_private/getFriendlyURL.ts diff --git a/packages/workbox-core/src/_private/logger.ts b/packages/serwiss/core/src/_private/logger.ts similarity index 100% rename from packages/workbox-core/src/_private/logger.ts rename to packages/serwiss/core/src/_private/logger.ts diff --git a/packages/workbox-core/src/_private/resultingClientExists.ts b/packages/serwiss/core/src/_private/resultingClientExists.ts similarity index 100% rename from packages/workbox-core/src/_private/resultingClientExists.ts rename to packages/serwiss/core/src/_private/resultingClientExists.ts diff --git a/packages/workbox-core/src/_private/timeout.ts b/packages/serwiss/core/src/_private/timeout.ts similarity index 100% rename from packages/workbox-core/src/_private/timeout.ts rename to packages/serwiss/core/src/_private/timeout.ts diff --git a/packages/workbox-core/src/_private/waitUntil.ts b/packages/serwiss/core/src/_private/waitUntil.ts similarity index 100% rename from packages/workbox-core/src/_private/waitUntil.ts rename to packages/serwiss/core/src/_private/waitUntil.ts diff --git a/packages/workbox-core/src/_version.ts b/packages/serwiss/core/src/_version.ts similarity index 100% rename from packages/workbox-core/src/_version.ts rename to packages/serwiss/core/src/_version.ts diff --git a/packages/workbox-core/src/cacheNames.ts b/packages/serwiss/core/src/cacheNames.ts similarity index 100% rename from packages/workbox-core/src/cacheNames.ts rename to packages/serwiss/core/src/cacheNames.ts diff --git a/packages/workbox-core/src/clientsClaim.ts b/packages/serwiss/core/src/clientsClaim.ts similarity index 100% rename from packages/workbox-core/src/clientsClaim.ts rename to packages/serwiss/core/src/clientsClaim.ts diff --git a/packages/workbox-core/src/copyResponse.ts b/packages/serwiss/core/src/copyResponse.ts similarity index 100% rename from packages/workbox-core/src/copyResponse.ts rename to packages/serwiss/core/src/copyResponse.ts diff --git a/packages/workbox-core/src/index.ts b/packages/serwiss/core/src/index.ts similarity index 100% rename from packages/workbox-core/src/index.ts rename to packages/serwiss/core/src/index.ts diff --git a/packages/workbox-core/src/models/messages/messageGenerator.ts b/packages/serwiss/core/src/models/messages/messageGenerator.ts similarity index 100% rename from packages/workbox-core/src/models/messages/messageGenerator.ts rename to packages/serwiss/core/src/models/messages/messageGenerator.ts diff --git a/packages/workbox-core/src/models/messages/messages.ts b/packages/serwiss/core/src/models/messages/messages.ts similarity index 100% rename from packages/workbox-core/src/models/messages/messages.ts rename to packages/serwiss/core/src/models/messages/messages.ts diff --git a/packages/workbox-core/src/models/pluginEvents.ts b/packages/serwiss/core/src/models/pluginEvents.ts similarity index 100% rename from packages/workbox-core/src/models/pluginEvents.ts rename to packages/serwiss/core/src/models/pluginEvents.ts diff --git a/packages/workbox-core/src/models/quotaErrorCallbacks.ts b/packages/serwiss/core/src/models/quotaErrorCallbacks.ts similarity index 100% rename from packages/workbox-core/src/models/quotaErrorCallbacks.ts rename to packages/serwiss/core/src/models/quotaErrorCallbacks.ts diff --git a/packages/workbox-core/src/registerQuotaErrorCallback.ts b/packages/serwiss/core/src/registerQuotaErrorCallback.ts similarity index 100% rename from packages/workbox-core/src/registerQuotaErrorCallback.ts rename to packages/serwiss/core/src/registerQuotaErrorCallback.ts diff --git a/packages/workbox-core/src/setCacheNameDetails.ts b/packages/serwiss/core/src/setCacheNameDetails.ts similarity index 100% rename from packages/workbox-core/src/setCacheNameDetails.ts rename to packages/serwiss/core/src/setCacheNameDetails.ts diff --git a/packages/workbox-core/src/skipWaiting.ts b/packages/serwiss/core/src/skipWaiting.ts similarity index 100% rename from packages/workbox-core/src/skipWaiting.ts rename to packages/serwiss/core/src/skipWaiting.ts diff --git a/packages/workbox-core/src/types.ts b/packages/serwiss/core/src/types.ts similarity index 100% rename from packages/workbox-core/src/types.ts rename to packages/serwiss/core/src/types.ts diff --git a/packages/workbox-core/src/utils/pluginUtils.ts b/packages/serwiss/core/src/utils/pluginUtils.ts similarity index 100% rename from packages/workbox-core/src/utils/pluginUtils.ts rename to packages/serwiss/core/src/utils/pluginUtils.ts diff --git a/packages/workbox-core/src/utils/welcome.ts b/packages/serwiss/core/src/utils/welcome.ts similarity index 100% rename from packages/workbox-core/src/utils/welcome.ts rename to packages/serwiss/core/src/utils/welcome.ts diff --git a/packages/serwiss/core/tsconfig.json b/packages/serwiss/core/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/core/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-expiration/README.md b/packages/serwiss/expiration/README.md similarity index 100% rename from packages/workbox-expiration/README.md rename to packages/serwiss/expiration/README.md diff --git a/packages/workbox-expiration/package.json b/packages/serwiss/expiration/package.json similarity index 82% rename from packages/workbox-expiration/package.json rename to packages/serwiss/expiration/package.json index 689e6158..3e0b7080 100644 --- a/packages/workbox-expiration/package.json +++ b/packages/serwiss/expiration/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-expiration", + "name": "@serwiss/expiration", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library that expires cached responses based on age or maximum number of entries.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -22,7 +22,7 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*", + "@serwiss/core": "workspace:*", "idb": "7.1.1" } } diff --git a/packages/workbox-expiration/src/CacheExpiration.ts b/packages/serwiss/expiration/src/CacheExpiration.ts similarity index 100% rename from packages/workbox-expiration/src/CacheExpiration.ts rename to packages/serwiss/expiration/src/CacheExpiration.ts diff --git a/packages/workbox-expiration/src/ExpirationPlugin.ts b/packages/serwiss/expiration/src/ExpirationPlugin.ts similarity index 100% rename from packages/workbox-expiration/src/ExpirationPlugin.ts rename to packages/serwiss/expiration/src/ExpirationPlugin.ts diff --git a/packages/workbox-expiration/src/_version.ts b/packages/serwiss/expiration/src/_version.ts similarity index 100% rename from packages/workbox-expiration/src/_version.ts rename to packages/serwiss/expiration/src/_version.ts diff --git a/packages/workbox-expiration/src/index.ts b/packages/serwiss/expiration/src/index.ts similarity index 100% rename from packages/workbox-expiration/src/index.ts rename to packages/serwiss/expiration/src/index.ts diff --git a/packages/workbox-expiration/src/models/CacheTimestampsModel.ts b/packages/serwiss/expiration/src/models/CacheTimestampsModel.ts similarity index 100% rename from packages/workbox-expiration/src/models/CacheTimestampsModel.ts rename to packages/serwiss/expiration/src/models/CacheTimestampsModel.ts diff --git a/packages/serwiss/expiration/tsconfig.json b/packages/serwiss/expiration/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/expiration/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-google-analytics/README.md b/packages/serwiss/google-analytics/README.md similarity index 100% rename from packages/workbox-google-analytics/README.md rename to packages/serwiss/google-analytics/README.md diff --git a/packages/workbox-google-analytics/package.json b/packages/serwiss/google-analytics/package.json similarity index 69% rename from packages/workbox-google-analytics/package.json rename to packages/serwiss/google-analytics/package.json index 1cf4f0dc..1e381a29 100644 --- a/packages/workbox-google-analytics/package.json +++ b/packages/serwiss/google-analytics/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-google-analytics", + "name": "@serwiss/google-analytics", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "Queues failed requests and uses the Background Sync API to replay them when the network is available", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -25,9 +25,9 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-background-sync": "workspace:*", - "@ducanh2912/workbox-core": "workspace:*", - "@ducanh2912/workbox-routing": "workspace:*", - "@ducanh2912/workbox-strategies": "workspace:*" + "@serwiss/background-sync": "workspace:*", + "@serwiss/core": "workspace:*", + "@serwiss/routing": "workspace:*", + "@serwiss/strategies": "workspace:*" } } diff --git a/packages/workbox-google-analytics/src/_version.ts b/packages/serwiss/google-analytics/src/_version.ts similarity index 100% rename from packages/workbox-google-analytics/src/_version.ts rename to packages/serwiss/google-analytics/src/_version.ts diff --git a/packages/workbox-google-analytics/src/index.ts b/packages/serwiss/google-analytics/src/index.ts similarity index 100% rename from packages/workbox-google-analytics/src/index.ts rename to packages/serwiss/google-analytics/src/index.ts diff --git a/packages/workbox-google-analytics/src/initialize.ts b/packages/serwiss/google-analytics/src/initialize.ts similarity index 100% rename from packages/workbox-google-analytics/src/initialize.ts rename to packages/serwiss/google-analytics/src/initialize.ts diff --git a/packages/workbox-google-analytics/src/utils/constants.ts b/packages/serwiss/google-analytics/src/utils/constants.ts similarity index 100% rename from packages/workbox-google-analytics/src/utils/constants.ts rename to packages/serwiss/google-analytics/src/utils/constants.ts diff --git a/packages/serwiss/google-analytics/tsconfig.json b/packages/serwiss/google-analytics/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/google-analytics/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-navigation-preload/README.md b/packages/serwiss/navigation-preload/README.md similarity index 100% rename from packages/workbox-navigation-preload/README.md rename to packages/serwiss/navigation-preload/README.md diff --git a/packages/workbox-navigation-preload/package.json b/packages/serwiss/navigation-preload/package.json similarity index 81% rename from packages/workbox-navigation-preload/package.json rename to packages/serwiss/navigation-preload/package.json index d995edc8..ab45c86e 100755 --- a/packages/workbox-navigation-preload/package.json +++ b/packages/serwiss/navigation-preload/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-navigation-preload", + "name": "@serwiss/navigation-preload", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "This library allows developers to opt-in to using Navigation Preload in their service worker.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -22,6 +22,6 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*" + "@serwiss/core": "workspace:*" } } diff --git a/packages/workbox-navigation-preload/src/_version.ts b/packages/serwiss/navigation-preload/src/_version.ts similarity index 100% rename from packages/workbox-navigation-preload/src/_version.ts rename to packages/serwiss/navigation-preload/src/_version.ts diff --git a/packages/workbox-navigation-preload/src/disable.ts b/packages/serwiss/navigation-preload/src/disable.ts similarity index 100% rename from packages/workbox-navigation-preload/src/disable.ts rename to packages/serwiss/navigation-preload/src/disable.ts diff --git a/packages/workbox-navigation-preload/src/enable.ts b/packages/serwiss/navigation-preload/src/enable.ts similarity index 100% rename from packages/workbox-navigation-preload/src/enable.ts rename to packages/serwiss/navigation-preload/src/enable.ts diff --git a/packages/workbox-navigation-preload/src/index.ts b/packages/serwiss/navigation-preload/src/index.ts similarity index 100% rename from packages/workbox-navigation-preload/src/index.ts rename to packages/serwiss/navigation-preload/src/index.ts diff --git a/packages/workbox-navigation-preload/src/isSupported.ts b/packages/serwiss/navigation-preload/src/isSupported.ts similarity index 100% rename from packages/workbox-navigation-preload/src/isSupported.ts rename to packages/serwiss/navigation-preload/src/isSupported.ts diff --git a/packages/serwiss/navigation-preload/tsconfig.json b/packages/serwiss/navigation-preload/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/navigation-preload/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-precaching/README.md b/packages/serwiss/precaching/README.md similarity index 100% rename from packages/workbox-precaching/README.md rename to packages/serwiss/precaching/README.md diff --git a/packages/workbox-precaching/package.json b/packages/serwiss/precaching/package.json similarity index 69% rename from packages/workbox-precaching/package.json rename to packages/serwiss/precaching/package.json index 7b5c2f13..d08d3c2c 100644 --- a/packages/workbox-precaching/package.json +++ b/packages/serwiss/precaching/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-precaching", + "name": "@serwiss/precaching", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "This module efficiently precaches assets.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -21,8 +21,8 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*", - "@ducanh2912/workbox-routing": "workspace:*", - "@ducanh2912/workbox-strategies": "workspace:*" + "@serwiss/core": "workspace:*", + "@serwiss/routing": "workspace:*", + "@serwiss/strategies": "workspace:*" } } diff --git a/packages/workbox-precaching/src/PrecacheController.ts b/packages/serwiss/precaching/src/PrecacheController.ts similarity index 100% rename from packages/workbox-precaching/src/PrecacheController.ts rename to packages/serwiss/precaching/src/PrecacheController.ts diff --git a/packages/workbox-precaching/src/PrecacheFallbackPlugin.ts b/packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts similarity index 100% rename from packages/workbox-precaching/src/PrecacheFallbackPlugin.ts rename to packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts diff --git a/packages/workbox-precaching/src/PrecacheRoute.ts b/packages/serwiss/precaching/src/PrecacheRoute.ts similarity index 100% rename from packages/workbox-precaching/src/PrecacheRoute.ts rename to packages/serwiss/precaching/src/PrecacheRoute.ts diff --git a/packages/workbox-precaching/src/PrecacheStrategy.ts b/packages/serwiss/precaching/src/PrecacheStrategy.ts similarity index 100% rename from packages/workbox-precaching/src/PrecacheStrategy.ts rename to packages/serwiss/precaching/src/PrecacheStrategy.ts diff --git a/packages/workbox-precaching/src/_types.ts b/packages/serwiss/precaching/src/_types.ts similarity index 100% rename from packages/workbox-precaching/src/_types.ts rename to packages/serwiss/precaching/src/_types.ts diff --git a/packages/workbox-precaching/src/_version.ts b/packages/serwiss/precaching/src/_version.ts similarity index 100% rename from packages/workbox-precaching/src/_version.ts rename to packages/serwiss/precaching/src/_version.ts diff --git a/packages/workbox-precaching/src/addPlugins.ts b/packages/serwiss/precaching/src/addPlugins.ts similarity index 100% rename from packages/workbox-precaching/src/addPlugins.ts rename to packages/serwiss/precaching/src/addPlugins.ts diff --git a/packages/workbox-precaching/src/addRoute.ts b/packages/serwiss/precaching/src/addRoute.ts similarity index 100% rename from packages/workbox-precaching/src/addRoute.ts rename to packages/serwiss/precaching/src/addRoute.ts diff --git a/packages/workbox-precaching/src/cleanupOutdatedCaches.ts b/packages/serwiss/precaching/src/cleanupOutdatedCaches.ts similarity index 100% rename from packages/workbox-precaching/src/cleanupOutdatedCaches.ts rename to packages/serwiss/precaching/src/cleanupOutdatedCaches.ts diff --git a/packages/workbox-precaching/src/createHandlerBoundToURL.ts b/packages/serwiss/precaching/src/createHandlerBoundToURL.ts similarity index 100% rename from packages/workbox-precaching/src/createHandlerBoundToURL.ts rename to packages/serwiss/precaching/src/createHandlerBoundToURL.ts diff --git a/packages/workbox-precaching/src/getCacheKeyForURL.ts b/packages/serwiss/precaching/src/getCacheKeyForURL.ts similarity index 100% rename from packages/workbox-precaching/src/getCacheKeyForURL.ts rename to packages/serwiss/precaching/src/getCacheKeyForURL.ts diff --git a/packages/workbox-precaching/src/index.ts b/packages/serwiss/precaching/src/index.ts similarity index 100% rename from packages/workbox-precaching/src/index.ts rename to packages/serwiss/precaching/src/index.ts diff --git a/packages/workbox-precaching/src/matchPrecache.ts b/packages/serwiss/precaching/src/matchPrecache.ts similarity index 100% rename from packages/workbox-precaching/src/matchPrecache.ts rename to packages/serwiss/precaching/src/matchPrecache.ts diff --git a/packages/workbox-precaching/src/precache.ts b/packages/serwiss/precaching/src/precache.ts similarity index 100% rename from packages/workbox-precaching/src/precache.ts rename to packages/serwiss/precaching/src/precache.ts diff --git a/packages/workbox-precaching/src/precacheAndRoute.ts b/packages/serwiss/precaching/src/precacheAndRoute.ts similarity index 100% rename from packages/workbox-precaching/src/precacheAndRoute.ts rename to packages/serwiss/precaching/src/precacheAndRoute.ts diff --git a/packages/workbox-precaching/src/utils/PrecacheCacheKeyPlugin.ts b/packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts similarity index 100% rename from packages/workbox-precaching/src/utils/PrecacheCacheKeyPlugin.ts rename to packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts diff --git a/packages/workbox-precaching/src/utils/PrecacheInstallReportPlugin.ts b/packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts similarity index 100% rename from packages/workbox-precaching/src/utils/PrecacheInstallReportPlugin.ts rename to packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts diff --git a/packages/workbox-precaching/src/utils/createCacheKey.ts b/packages/serwiss/precaching/src/utils/createCacheKey.ts similarity index 100% rename from packages/workbox-precaching/src/utils/createCacheKey.ts rename to packages/serwiss/precaching/src/utils/createCacheKey.ts diff --git a/packages/workbox-precaching/src/utils/deleteOutdatedCaches.ts b/packages/serwiss/precaching/src/utils/deleteOutdatedCaches.ts similarity index 100% rename from packages/workbox-precaching/src/utils/deleteOutdatedCaches.ts rename to packages/serwiss/precaching/src/utils/deleteOutdatedCaches.ts diff --git a/packages/workbox-precaching/src/utils/generateURLVariations.ts b/packages/serwiss/precaching/src/utils/generateURLVariations.ts similarity index 100% rename from packages/workbox-precaching/src/utils/generateURLVariations.ts rename to packages/serwiss/precaching/src/utils/generateURLVariations.ts diff --git a/packages/workbox-precaching/src/utils/getCacheKeyForURL.ts b/packages/serwiss/precaching/src/utils/getCacheKeyForURL.ts similarity index 100% rename from packages/workbox-precaching/src/utils/getCacheKeyForURL.ts rename to packages/serwiss/precaching/src/utils/getCacheKeyForURL.ts diff --git a/packages/workbox-precaching/src/utils/getOrCreatePrecacheController.ts b/packages/serwiss/precaching/src/utils/getOrCreatePrecacheController.ts similarity index 100% rename from packages/workbox-precaching/src/utils/getOrCreatePrecacheController.ts rename to packages/serwiss/precaching/src/utils/getOrCreatePrecacheController.ts diff --git a/packages/workbox-precaching/src/utils/printCleanupDetails.ts b/packages/serwiss/precaching/src/utils/printCleanupDetails.ts similarity index 100% rename from packages/workbox-precaching/src/utils/printCleanupDetails.ts rename to packages/serwiss/precaching/src/utils/printCleanupDetails.ts diff --git a/packages/workbox-precaching/src/utils/printInstallDetails.ts b/packages/serwiss/precaching/src/utils/printInstallDetails.ts similarity index 100% rename from packages/workbox-precaching/src/utils/printInstallDetails.ts rename to packages/serwiss/precaching/src/utils/printInstallDetails.ts diff --git a/packages/workbox-precaching/src/utils/removeIgnoredSearchParams.ts b/packages/serwiss/precaching/src/utils/removeIgnoredSearchParams.ts similarity index 100% rename from packages/workbox-precaching/src/utils/removeIgnoredSearchParams.ts rename to packages/serwiss/precaching/src/utils/removeIgnoredSearchParams.ts diff --git a/packages/serwiss/precaching/tsconfig.json b/packages/serwiss/precaching/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/precaching/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-range-requests/README.md b/packages/serwiss/range-requests/README.md similarity index 100% rename from packages/workbox-range-requests/README.md rename to packages/serwiss/range-requests/README.md diff --git a/packages/workbox-range-requests/package.json b/packages/serwiss/range-requests/package.json similarity index 82% rename from packages/workbox-range-requests/package.json rename to packages/serwiss/range-requests/package.json index 323fcabc..893158b2 100755 --- a/packages/workbox-range-requests/package.json +++ b/packages/serwiss/range-requests/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-range-requests", + "name": "@serwiss/range-requests", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "This library creates a new Response, given a source Response and a Range header value.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -26,6 +26,6 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*" + "@serwiss/core": "workspace:*" } } diff --git a/packages/workbox-range-requests/src/RangeRequestsPlugin.ts b/packages/serwiss/range-requests/src/RangeRequestsPlugin.ts similarity index 100% rename from packages/workbox-range-requests/src/RangeRequestsPlugin.ts rename to packages/serwiss/range-requests/src/RangeRequestsPlugin.ts diff --git a/packages/workbox-range-requests/src/_version.ts b/packages/serwiss/range-requests/src/_version.ts similarity index 100% rename from packages/workbox-range-requests/src/_version.ts rename to packages/serwiss/range-requests/src/_version.ts diff --git a/packages/workbox-range-requests/src/createPartialResponse.ts b/packages/serwiss/range-requests/src/createPartialResponse.ts similarity index 100% rename from packages/workbox-range-requests/src/createPartialResponse.ts rename to packages/serwiss/range-requests/src/createPartialResponse.ts diff --git a/packages/workbox-range-requests/src/index.ts b/packages/serwiss/range-requests/src/index.ts similarity index 100% rename from packages/workbox-range-requests/src/index.ts rename to packages/serwiss/range-requests/src/index.ts diff --git a/packages/workbox-range-requests/src/utils/calculateEffectiveBoundaries.ts b/packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts similarity index 100% rename from packages/workbox-range-requests/src/utils/calculateEffectiveBoundaries.ts rename to packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts diff --git a/packages/workbox-range-requests/src/utils/parseRangeHeader.ts b/packages/serwiss/range-requests/src/utils/parseRangeHeader.ts similarity index 100% rename from packages/workbox-range-requests/src/utils/parseRangeHeader.ts rename to packages/serwiss/range-requests/src/utils/parseRangeHeader.ts diff --git a/packages/serwiss/range-requests/tsconfig.json b/packages/serwiss/range-requests/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/range-requests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-recipes/README.md b/packages/serwiss/recipes/README.md similarity index 100% rename from packages/workbox-recipes/README.md rename to packages/serwiss/recipes/README.md diff --git a/packages/workbox-recipes/package.json b/packages/serwiss/recipes/package.json similarity index 59% rename from packages/workbox-recipes/package.json rename to packages/serwiss/recipes/package.json index c3747c84..d22e013e 100644 --- a/packages/workbox-recipes/package.json +++ b/packages/serwiss/recipes/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-recipes", + "name": "@serwiss/recipes", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library to manage common request and caching patterns", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -23,11 +23,11 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-cacheable-response": "workspace:*", - "@ducanh2912/workbox-core": "workspace:*", - "@ducanh2912/workbox-expiration": "workspace:*", - "@ducanh2912/workbox-precaching": "workspace:*", - "@ducanh2912/workbox-routing": "workspace:*", - "@ducanh2912/workbox-strategies": "workspace:*" + "@serwiss/cacheable-response": "workspace:*", + "@serwiss/core": "workspace:*", + "@serwiss/expiration": "workspace:*", + "@serwiss/precaching": "workspace:*", + "@serwiss/routing": "workspace:*", + "@serwiss/strategies": "workspace:*" } } diff --git a/packages/workbox-recipes/src/_version.ts b/packages/serwiss/recipes/src/_version.ts similarity index 100% rename from packages/workbox-recipes/src/_version.ts rename to packages/serwiss/recipes/src/_version.ts diff --git a/packages/workbox-recipes/src/googleFontsCache.ts b/packages/serwiss/recipes/src/googleFontsCache.ts similarity index 100% rename from packages/workbox-recipes/src/googleFontsCache.ts rename to packages/serwiss/recipes/src/googleFontsCache.ts diff --git a/packages/workbox-recipes/src/imageCache.ts b/packages/serwiss/recipes/src/imageCache.ts similarity index 100% rename from packages/workbox-recipes/src/imageCache.ts rename to packages/serwiss/recipes/src/imageCache.ts diff --git a/packages/workbox-recipes/src/index.ts b/packages/serwiss/recipes/src/index.ts similarity index 100% rename from packages/workbox-recipes/src/index.ts rename to packages/serwiss/recipes/src/index.ts diff --git a/packages/workbox-recipes/src/offlineFallback.ts b/packages/serwiss/recipes/src/offlineFallback.ts similarity index 100% rename from packages/workbox-recipes/src/offlineFallback.ts rename to packages/serwiss/recipes/src/offlineFallback.ts diff --git a/packages/workbox-recipes/src/pageCache.ts b/packages/serwiss/recipes/src/pageCache.ts similarity index 100% rename from packages/workbox-recipes/src/pageCache.ts rename to packages/serwiss/recipes/src/pageCache.ts diff --git a/packages/workbox-recipes/src/staticResourceCache.ts b/packages/serwiss/recipes/src/staticResourceCache.ts similarity index 100% rename from packages/workbox-recipes/src/staticResourceCache.ts rename to packages/serwiss/recipes/src/staticResourceCache.ts diff --git a/packages/workbox-recipes/src/warmStrategyCache.ts b/packages/serwiss/recipes/src/warmStrategyCache.ts similarity index 100% rename from packages/workbox-recipes/src/warmStrategyCache.ts rename to packages/serwiss/recipes/src/warmStrategyCache.ts diff --git a/packages/serwiss/recipes/tsconfig.json b/packages/serwiss/recipes/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/recipes/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-routing/README.md b/packages/serwiss/routing/README.md similarity index 100% rename from packages/workbox-routing/README.md rename to packages/serwiss/routing/README.md diff --git a/packages/workbox-routing/package.json b/packages/serwiss/routing/package.json similarity index 81% rename from packages/workbox-routing/package.json rename to packages/serwiss/routing/package.json index 03ee396b..aa520e2c 100644 --- a/packages/workbox-routing/package.json +++ b/packages/serwiss/routing/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-routing", + "name": "@serwiss/routing", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library to route request URLs to handlers.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -23,6 +23,6 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*" + "@serwiss/core": "workspace:*" } } diff --git a/packages/workbox-routing/src/NavigationRoute.ts b/packages/serwiss/routing/src/NavigationRoute.ts similarity index 100% rename from packages/workbox-routing/src/NavigationRoute.ts rename to packages/serwiss/routing/src/NavigationRoute.ts diff --git a/packages/workbox-routing/src/RegExpRoute.ts b/packages/serwiss/routing/src/RegExpRoute.ts similarity index 100% rename from packages/workbox-routing/src/RegExpRoute.ts rename to packages/serwiss/routing/src/RegExpRoute.ts diff --git a/packages/workbox-routing/src/Route.ts b/packages/serwiss/routing/src/Route.ts similarity index 100% rename from packages/workbox-routing/src/Route.ts rename to packages/serwiss/routing/src/Route.ts diff --git a/packages/workbox-routing/src/Router.ts b/packages/serwiss/routing/src/Router.ts similarity index 100% rename from packages/workbox-routing/src/Router.ts rename to packages/serwiss/routing/src/Router.ts diff --git a/packages/workbox-routing/src/_types.ts b/packages/serwiss/routing/src/_types.ts similarity index 100% rename from packages/workbox-routing/src/_types.ts rename to packages/serwiss/routing/src/_types.ts diff --git a/packages/workbox-routing/src/_version.ts b/packages/serwiss/routing/src/_version.ts similarity index 100% rename from packages/workbox-routing/src/_version.ts rename to packages/serwiss/routing/src/_version.ts diff --git a/packages/workbox-routing/src/index.ts b/packages/serwiss/routing/src/index.ts similarity index 100% rename from packages/workbox-routing/src/index.ts rename to packages/serwiss/routing/src/index.ts diff --git a/packages/workbox-routing/src/registerRoute.ts b/packages/serwiss/routing/src/registerRoute.ts similarity index 100% rename from packages/workbox-routing/src/registerRoute.ts rename to packages/serwiss/routing/src/registerRoute.ts diff --git a/packages/workbox-routing/src/setCatchHandler.ts b/packages/serwiss/routing/src/setCatchHandler.ts similarity index 100% rename from packages/workbox-routing/src/setCatchHandler.ts rename to packages/serwiss/routing/src/setCatchHandler.ts diff --git a/packages/workbox-routing/src/setDefaultHandler.ts b/packages/serwiss/routing/src/setDefaultHandler.ts similarity index 100% rename from packages/workbox-routing/src/setDefaultHandler.ts rename to packages/serwiss/routing/src/setDefaultHandler.ts diff --git a/packages/workbox-routing/src/utils/constants.ts b/packages/serwiss/routing/src/utils/constants.ts similarity index 100% rename from packages/workbox-routing/src/utils/constants.ts rename to packages/serwiss/routing/src/utils/constants.ts diff --git a/packages/workbox-routing/src/utils/getOrCreateDefaultRouter.ts b/packages/serwiss/routing/src/utils/getOrCreateDefaultRouter.ts similarity index 100% rename from packages/workbox-routing/src/utils/getOrCreateDefaultRouter.ts rename to packages/serwiss/routing/src/utils/getOrCreateDefaultRouter.ts diff --git a/packages/workbox-routing/src/utils/normalizeHandler.ts b/packages/serwiss/routing/src/utils/normalizeHandler.ts similarity index 100% rename from packages/workbox-routing/src/utils/normalizeHandler.ts rename to packages/serwiss/routing/src/utils/normalizeHandler.ts diff --git a/packages/serwiss/routing/tsconfig.json b/packages/serwiss/routing/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/routing/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-strategies/README.md b/packages/serwiss/strategies/README.md similarity index 100% rename from packages/workbox-strategies/README.md rename to packages/serwiss/strategies/README.md diff --git a/packages/workbox-strategies/package.json b/packages/serwiss/strategies/package.json similarity index 81% rename from packages/workbox-strategies/package.json rename to packages/serwiss/strategies/package.json index e17efdb5..90364480 100644 --- a/packages/workbox-strategies/package.json +++ b/packages/serwiss/strategies/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-strategies", + "name": "@serwiss/strategies", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library implementing common caching strategies.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -23,6 +23,6 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*" + "@serwiss/core": "workspace:*" } } diff --git a/packages/workbox-strategies/src/CacheFirst.ts b/packages/serwiss/strategies/src/CacheFirst.ts similarity index 100% rename from packages/workbox-strategies/src/CacheFirst.ts rename to packages/serwiss/strategies/src/CacheFirst.ts diff --git a/packages/workbox-strategies/src/CacheOnly.ts b/packages/serwiss/strategies/src/CacheOnly.ts similarity index 100% rename from packages/workbox-strategies/src/CacheOnly.ts rename to packages/serwiss/strategies/src/CacheOnly.ts diff --git a/packages/workbox-strategies/src/NetworkFirst.ts b/packages/serwiss/strategies/src/NetworkFirst.ts similarity index 100% rename from packages/workbox-strategies/src/NetworkFirst.ts rename to packages/serwiss/strategies/src/NetworkFirst.ts diff --git a/packages/workbox-strategies/src/NetworkOnly.ts b/packages/serwiss/strategies/src/NetworkOnly.ts similarity index 100% rename from packages/workbox-strategies/src/NetworkOnly.ts rename to packages/serwiss/strategies/src/NetworkOnly.ts diff --git a/packages/workbox-strategies/src/StaleWhileRevalidate.ts b/packages/serwiss/strategies/src/StaleWhileRevalidate.ts similarity index 100% rename from packages/workbox-strategies/src/StaleWhileRevalidate.ts rename to packages/serwiss/strategies/src/StaleWhileRevalidate.ts diff --git a/packages/workbox-strategies/src/Strategy.ts b/packages/serwiss/strategies/src/Strategy.ts similarity index 100% rename from packages/workbox-strategies/src/Strategy.ts rename to packages/serwiss/strategies/src/Strategy.ts diff --git a/packages/workbox-strategies/src/StrategyHandler.ts b/packages/serwiss/strategies/src/StrategyHandler.ts similarity index 100% rename from packages/workbox-strategies/src/StrategyHandler.ts rename to packages/serwiss/strategies/src/StrategyHandler.ts diff --git a/packages/workbox-strategies/src/_version.ts b/packages/serwiss/strategies/src/_version.ts similarity index 100% rename from packages/workbox-strategies/src/_version.ts rename to packages/serwiss/strategies/src/_version.ts diff --git a/packages/workbox-strategies/src/index.ts b/packages/serwiss/strategies/src/index.ts similarity index 100% rename from packages/workbox-strategies/src/index.ts rename to packages/serwiss/strategies/src/index.ts diff --git a/packages/workbox-strategies/src/plugins/cacheOkAndOpaquePlugin.ts b/packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts similarity index 100% rename from packages/workbox-strategies/src/plugins/cacheOkAndOpaquePlugin.ts rename to packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts diff --git a/packages/workbox-strategies/src/utils/messages.ts b/packages/serwiss/strategies/src/utils/messages.ts similarity index 100% rename from packages/workbox-strategies/src/utils/messages.ts rename to packages/serwiss/strategies/src/utils/messages.ts diff --git a/packages/serwiss/strategies/tsconfig.json b/packages/serwiss/strategies/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/strategies/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-streams/README.md b/packages/serwiss/streams/README.md similarity index 100% rename from packages/workbox-streams/README.md rename to packages/serwiss/streams/README.md diff --git a/packages/workbox-streams/package.json b/packages/serwiss/streams/package.json similarity index 76% rename from packages/workbox-streams/package.json rename to packages/serwiss/streams/package.json index 24b8183c..0caee0a6 100644 --- a/packages/workbox-streams/package.json +++ b/packages/serwiss/streams/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-streams", + "name": "@serwiss/streams", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "A library that makes it easier to work with Streams in the browser.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -23,7 +23,7 @@ "module": "index.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "workspace:*", - "@ducanh2912/workbox-routing": "workspace:*" + "@serwiss/core": "workspace:*", + "@serwiss/routing": "workspace:*" } } diff --git a/packages/workbox-streams/src/_types.ts b/packages/serwiss/streams/src/_types.ts similarity index 100% rename from packages/workbox-streams/src/_types.ts rename to packages/serwiss/streams/src/_types.ts diff --git a/packages/workbox-streams/src/_version.ts b/packages/serwiss/streams/src/_version.ts similarity index 100% rename from packages/workbox-streams/src/_version.ts rename to packages/serwiss/streams/src/_version.ts diff --git a/packages/workbox-streams/src/concatenate.ts b/packages/serwiss/streams/src/concatenate.ts similarity index 100% rename from packages/workbox-streams/src/concatenate.ts rename to packages/serwiss/streams/src/concatenate.ts diff --git a/packages/workbox-streams/src/concatenateToResponse.ts b/packages/serwiss/streams/src/concatenateToResponse.ts similarity index 100% rename from packages/workbox-streams/src/concatenateToResponse.ts rename to packages/serwiss/streams/src/concatenateToResponse.ts diff --git a/packages/workbox-streams/src/index.ts b/packages/serwiss/streams/src/index.ts similarity index 100% rename from packages/workbox-streams/src/index.ts rename to packages/serwiss/streams/src/index.ts diff --git a/packages/workbox-streams/src/isSupported.ts b/packages/serwiss/streams/src/isSupported.ts similarity index 100% rename from packages/workbox-streams/src/isSupported.ts rename to packages/serwiss/streams/src/isSupported.ts diff --git a/packages/workbox-streams/src/strategy.ts b/packages/serwiss/streams/src/strategy.ts similarity index 100% rename from packages/workbox-streams/src/strategy.ts rename to packages/serwiss/streams/src/strategy.ts diff --git a/packages/workbox-streams/src/utils/createHeaders.ts b/packages/serwiss/streams/src/utils/createHeaders.ts similarity index 100% rename from packages/workbox-streams/src/utils/createHeaders.ts rename to packages/serwiss/streams/src/utils/createHeaders.ts diff --git a/packages/serwiss/streams/tsconfig.json b/packages/serwiss/streams/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/streams/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-sw/README.md b/packages/serwiss/sw/README.md similarity index 100% rename from packages/workbox-sw/README.md rename to packages/serwiss/sw/README.md diff --git a/packages/workbox-sw/_types.mjs b/packages/serwiss/sw/_types.mjs similarity index 100% rename from packages/workbox-sw/_types.mjs rename to packages/serwiss/sw/_types.mjs diff --git a/packages/workbox-sw/_version.mjs b/packages/serwiss/sw/_version.mjs similarity index 100% rename from packages/workbox-sw/_version.mjs rename to packages/serwiss/sw/_version.mjs diff --git a/packages/workbox-sw/controllers/WorkboxSW.mjs b/packages/serwiss/sw/controllers/WorkboxSW.mjs similarity index 100% rename from packages/workbox-sw/controllers/WorkboxSW.mjs rename to packages/serwiss/sw/controllers/WorkboxSW.mjs diff --git a/packages/workbox-sw/index.mjs b/packages/serwiss/sw/index.mjs similarity index 100% rename from packages/workbox-sw/index.mjs rename to packages/serwiss/sw/index.mjs diff --git a/packages/workbox-sw/package.json b/packages/serwiss/sw/package.json similarity index 87% rename from packages/workbox-sw/package.json rename to packages/serwiss/sw/package.json index 7a2695fb..e315c0f7 100644 --- a/packages/workbox-sw/package.json +++ b/packages/serwiss/sw/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-sw", + "name": "@serwiss/sw", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "This module makes it easy to get started with the Workbox service worker libraries.", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", diff --git a/packages/workbox-webpack-plugin/README.md b/packages/serwiss/webpack-plugin/README.md similarity index 100% rename from packages/workbox-webpack-plugin/README.md rename to packages/serwiss/webpack-plugin/README.md diff --git a/packages/workbox-webpack-plugin/package.json b/packages/serwiss/webpack-plugin/package.json similarity index 87% rename from packages/workbox-webpack-plugin/package.json rename to packages/serwiss/webpack-plugin/package.json index 0011f3e6..8782176b 100644 --- a/packages/workbox-webpack-plugin/package.json +++ b/packages/serwiss/webpack-plugin/package.json @@ -1,5 +1,5 @@ { - "name": "@ducanh2912/workbox-webpack-plugin", + "name": "@serwiss/webpack-plugin", "version": "7.0.0", "description": "A plugin for your Webpack build process, helping you generate a manifest of local files that workbox-sw should precache.", "keywords": [ @@ -21,7 +21,7 @@ "node": ">=16.0.0" }, "dependencies": { - "@ducanh2912/workbox-build": "workspace:*", + "@serwiss/build": "workspace:*", "fast-json-stable-stringify": "2.1.0", "pretty-bytes": "6.1.1", "upath": "2.0.1", @@ -34,7 +34,7 @@ "@types/node": "20.8.7", "@types/webpack": "5.28.3" }, - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "license": "MIT", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", diff --git a/packages/workbox-webpack-plugin/src/generate-sw.ts b/packages/serwiss/webpack-plugin/src/generate-sw.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/generate-sw.ts rename to packages/serwiss/webpack-plugin/src/generate-sw.ts diff --git a/packages/workbox-webpack-plugin/src/index.ts b/packages/serwiss/webpack-plugin/src/index.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/index.ts rename to packages/serwiss/webpack-plugin/src/index.ts diff --git a/packages/workbox-webpack-plugin/src/inject-manifest.ts b/packages/serwiss/webpack-plugin/src/inject-manifest.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/inject-manifest.ts rename to packages/serwiss/webpack-plugin/src/inject-manifest.ts diff --git a/packages/workbox-webpack-plugin/src/lib/get-asset-hash.ts b/packages/serwiss/webpack-plugin/src/lib/get-asset-hash.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/lib/get-asset-hash.ts rename to packages/serwiss/webpack-plugin/src/lib/get-asset-hash.ts diff --git a/packages/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts b/packages/serwiss/webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts rename to packages/serwiss/webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts diff --git a/packages/workbox-webpack-plugin/src/lib/get-script-files-for-chunks.ts b/packages/serwiss/webpack-plugin/src/lib/get-script-files-for-chunks.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/lib/get-script-files-for-chunks.ts rename to packages/serwiss/webpack-plugin/src/lib/get-script-files-for-chunks.ts diff --git a/packages/workbox-webpack-plugin/src/lib/get-sourcemap-asset-name.ts b/packages/serwiss/webpack-plugin/src/lib/get-sourcemap-asset-name.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/lib/get-sourcemap-asset-name.ts rename to packages/serwiss/webpack-plugin/src/lib/get-sourcemap-asset-name.ts diff --git a/packages/workbox-webpack-plugin/src/lib/relative-to-output-path.ts b/packages/serwiss/webpack-plugin/src/lib/relative-to-output-path.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/lib/relative-to-output-path.ts rename to packages/serwiss/webpack-plugin/src/lib/relative-to-output-path.ts diff --git a/packages/workbox-webpack-plugin/src/lib/resolve-webpack-url.ts b/packages/serwiss/webpack-plugin/src/lib/resolve-webpack-url.ts similarity index 100% rename from packages/workbox-webpack-plugin/src/lib/resolve-webpack-url.ts rename to packages/serwiss/webpack-plugin/src/lib/resolve-webpack-url.ts diff --git a/packages/serwiss/webpack-plugin/tsconfig.json b/packages/serwiss/webpack-plugin/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/webpack-plugin/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-window/README.md b/packages/serwiss/window/README.md similarity index 100% rename from packages/workbox-window/README.md rename to packages/serwiss/window/README.md diff --git a/packages/workbox-window/package.json b/packages/serwiss/window/package.json similarity index 85% rename from packages/workbox-window/package.json rename to packages/serwiss/window/package.json index 8d113ff1..122473ce 100644 --- a/packages/workbox-window/package.json +++ b/packages/serwiss/window/package.json @@ -1,8 +1,8 @@ { - "name": "@ducanh2912/workbox-window", + "name": "@serwiss/window", "version": "7.0.0", "license": "MIT", - "author": "Google's Web DevRel Team", + "author": "Google's Web DevRel Team, DuCanhGH", "description": "Simplifies communications with Workbox packages running in the service worker", "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", @@ -24,7 +24,7 @@ "module": "build/workbox-window.prod.es5.mjs", "types": "index.d.ts", "dependencies": { - "@ducanh2912/workbox-core": "7.0.0", + "@serwiss/core": "7.0.0", "@types/trusted-types": "2.0.4" } } diff --git a/packages/workbox-window/src/Workbox.ts b/packages/serwiss/window/src/Workbox.ts similarity index 100% rename from packages/workbox-window/src/Workbox.ts rename to packages/serwiss/window/src/Workbox.ts diff --git a/packages/workbox-window/src/_version.ts b/packages/serwiss/window/src/_version.ts similarity index 100% rename from packages/workbox-window/src/_version.ts rename to packages/serwiss/window/src/_version.ts diff --git a/packages/workbox-window/src/index.ts b/packages/serwiss/window/src/index.ts similarity index 100% rename from packages/workbox-window/src/index.ts rename to packages/serwiss/window/src/index.ts diff --git a/packages/workbox-window/src/messageSW.ts b/packages/serwiss/window/src/messageSW.ts similarity index 100% rename from packages/workbox-window/src/messageSW.ts rename to packages/serwiss/window/src/messageSW.ts diff --git a/packages/workbox-window/src/utils/WorkboxEvent.ts b/packages/serwiss/window/src/utils/WorkboxEvent.ts similarity index 100% rename from packages/workbox-window/src/utils/WorkboxEvent.ts rename to packages/serwiss/window/src/utils/WorkboxEvent.ts diff --git a/packages/workbox-window/src/utils/WorkboxEventTarget.ts b/packages/serwiss/window/src/utils/WorkboxEventTarget.ts similarity index 100% rename from packages/workbox-window/src/utils/WorkboxEventTarget.ts rename to packages/serwiss/window/src/utils/WorkboxEventTarget.ts diff --git a/packages/workbox-window/src/utils/urlsMatch.ts b/packages/serwiss/window/src/utils/urlsMatch.ts similarity index 100% rename from packages/workbox-window/src/utils/urlsMatch.ts rename to packages/serwiss/window/src/utils/urlsMatch.ts diff --git a/packages/serwiss/window/tsconfig.json b/packages/serwiss/window/tsconfig.json new file mode 100644 index 00000000..2fc26116 --- /dev/null +++ b/packages/serwiss/window/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext" + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/workbox-background-sync/tsconfig.json b/packages/workbox-background-sync/tsconfig.json deleted file mode 100644 index 0468b457..00000000 --- a/packages/workbox-background-sync/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-broadcast-update/tsconfig.json b/packages/workbox-broadcast-update/tsconfig.json deleted file mode 100644 index 0468b457..00000000 --- a/packages/workbox-broadcast-update/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-build/tsconfig.json b/packages/workbox-build/tsconfig.json deleted file mode 100644 index c40643cf..00000000 --- a/packages/workbox-build/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "esModuleInterop": true, - "module": "CommonJS", - "moduleResolution": "Node", - "outDir": "./build", - "resolveJsonModule": true, - "rootDir": "./src", - "target": "ES2018" - }, - "files": ["src/cdn-details.json"], - "include": ["src/**/*.ts", "src/schema/*.json"] -} diff --git a/packages/workbox-cacheable-response/tsconfig.json b/packages/workbox-cacheable-response/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-cacheable-response/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-cli/tsconfig.json b/packages/workbox-cli/tsconfig.json deleted file mode 100644 index 51242135..00000000 --- a/packages/workbox-cli/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "esModuleInterop": true, - "module": "CommonJS", - "outDir": "build", - "rootDir": "src", - "target": "ES2018", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-build/"}] -} diff --git a/packages/workbox-core/tsconfig.json b/packages/workbox-core/tsconfig.json deleted file mode 100644 index 921c642c..00000000 --- a/packages/workbox-core/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"] -} diff --git a/packages/workbox-expiration/tsconfig.json b/packages/workbox-expiration/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-expiration/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-google-analytics/tsconfig.json b/packages/workbox-google-analytics/tsconfig.json deleted file mode 100644 index 7b7f3375..00000000 --- a/packages/workbox-google-analytics/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [ - {"path": "../workbox-background-sync/"}, - {"path": "../workbox-core/"}, - {"path": "../workbox-routing/"}, - {"path": "../workbox-strategies/"} - ] -} diff --git a/packages/workbox-navigation-preload/tsconfig.json b/packages/workbox-navigation-preload/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-navigation-preload/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-precaching/tsconfig.json b/packages/workbox-precaching/tsconfig.json deleted file mode 100644 index ff2b28d5..00000000 --- a/packages/workbox-precaching/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [ - {"path": "../workbox-core/"}, - {"path": "../workbox-routing/"}, - {"path": "../workbox-strategies/"} - ] -} diff --git a/packages/workbox-range-requests/tsconfig.json b/packages/workbox-range-requests/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-range-requests/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-recipes/tsconfig.json b/packages/workbox-recipes/tsconfig.json deleted file mode 100644 index 22f8f82b..00000000 --- a/packages/workbox-recipes/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [ - {"path": "../workbox-core/"}, - {"path": "../workbox-routing/"}, - {"path": "../workbox-strategies/"}, - {"path": "../workbox-cacheable-response/"}, - {"path": "../workbox-expiration/"}, - {"path": "../workbox-precaching/"} - ] -} diff --git a/packages/workbox-routing/tsconfig.json b/packages/workbox-routing/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-routing/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-strategies/tsconfig.json b/packages/workbox-strategies/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-strategies/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-streams/tsconfig.json b/packages/workbox-streams/tsconfig.json deleted file mode 100644 index 2457eadc..00000000 --- a/packages/workbox-streams/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-core/"}] -} diff --git a/packages/workbox-webpack-plugin/tsconfig.json b/packages/workbox-webpack-plugin/tsconfig.json deleted file mode 100644 index de55c750..00000000 --- a/packages/workbox-webpack-plugin/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "esModuleInterop": true, - "module": "CommonJS", - "outDir": "./build", - "resolveJsonModule": true, - "rootDir": "./src", - "target": "ES2018", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [{"path": "../workbox-build/"}] -} diff --git a/packages/workbox-window/tsconfig.json b/packages/workbox-window/tsconfig.json deleted file mode 100644 index 79279e16..00000000 --- a/packages/workbox-window/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "../../tsconfig", - "compilerOptions": { - "lib": ["es2017", "dom"], - "outDir": "./", - "rootDir": "./src", - "tsBuildInfoFile": "./tsconfig.tsbuildinfo" - }, - "include": ["src/**/*.ts"], - "references": [ - { - "path": "../workbox-core/" - } - ] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30ae8167..09a1d482 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -687,78 +687,22 @@ importers: specifier: 5.89.0 version: 5.89.0(@swc/core@1.3.93) - packages/test-utils: - dependencies: - cheerio: - specifier: 1.0.0-rc.12 - version: 1.0.0-rc.12 - fs-extra: - specifier: 11.1.1 - version: 11.1.1 - type-fest: - specifier: 4.4.0 - version: 4.4.0 - devDependencies: - '@types/fs-extra': - specifier: 11.0.2 - version: 11.0.2 - '@types/jest': - specifier: 29.5.6 - version: 29.5.6 - - packages/utils: - dependencies: - chalk: - specifier: 5.3.0 - version: 5.3.0 - semver: - specifier: 7.5.4 - version: 7.5.4 - devDependencies: - '@ducanh2912/constants': - specifier: workspace:* - version: link:../constants - '@rollup/plugin-node-resolve': - specifier: 15.2.3 - version: 15.2.3(rollup@3.28.1) - '@rollup/plugin-swc': - specifier: 0.2.1 - version: 0.2.1(@swc/core@1.3.93)(rollup@3.28.1) - '@swc/core': - specifier: 1.3.93 - version: 1.3.93 - '@types/semver': - specifier: 7.5.3 - version: 7.5.3 - rollup: - specifier: 3.28.1 - version: 3.28.1 - terser-webpack-plugin: - specifier: 5.3.9 - version: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0) - type-fest: - specifier: 4.4.0 - version: 4.4.0 - typescript: - specifier: 5.3.0-dev.20231018 - version: 5.3.0-dev.20231018 - - packages/workbox-background-sync: + packages/serwiss/background-sync: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core + version: link:../core idb: specifier: 7.1.1 version: 7.1.1 - packages/workbox-broadcast-update: + packages/serwiss/broadcast-update: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: 7.0.0 - version: link:../workbox-core + version: link:../core - packages/workbox-build: + packages/serwiss/build: dependencies: '@apideck/better-ajv-errors': specifier: 0.3.6 @@ -772,63 +716,63 @@ importers: '@babel/runtime': specifier: 7.23.2 version: 7.23.2 - '@ducanh2912/workbox-background-sync': + '@rollup/plugin-babel': + specifier: 6.0.4 + version: 6.0.4(@babel/core@7.23.2)(rollup@3.28.1) + '@rollup/plugin-node-resolve': + specifier: 15.2.3 + version: 15.2.3(rollup@3.28.1) + '@rollup/plugin-replace': + specifier: 5.0.4 + version: 5.0.4(rollup@3.28.1) + '@rollup/plugin-terser': + specifier: 0.4.4 + version: 0.4.4(rollup@3.28.1) + '@serwiss/background-sync': specifier: workspace:* - version: link:../workbox-background-sync - '@ducanh2912/workbox-broadcast-update': + version: link:../background-sync + '@serwiss/broadcast-update': specifier: workspace:* - version: link:../workbox-broadcast-update - '@ducanh2912/workbox-cacheable-response': + version: link:../broadcast-update + '@serwiss/cacheable-response': specifier: workspace:* - version: link:../workbox-cacheable-response - '@ducanh2912/workbox-core': + version: link:../cacheable-response + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core - '@ducanh2912/workbox-expiration': + version: link:../core + '@serwiss/expiration': specifier: workspace:* - version: link:../workbox-expiration - '@ducanh2912/workbox-google-analytics': + version: link:../expiration + '@serwiss/google-analytics': specifier: workspace:* - version: link:../workbox-google-analytics - '@ducanh2912/workbox-navigation-preload': + version: link:../google-analytics + '@serwiss/navigation-preload': specifier: workspace:* - version: link:../workbox-navigation-preload - '@ducanh2912/workbox-precaching': + version: link:../navigation-preload + '@serwiss/precaching': specifier: workspace:* - version: link:../workbox-precaching - '@ducanh2912/workbox-range-requests': + version: link:../precaching + '@serwiss/range-requests': specifier: workspace:* - version: link:../workbox-range-requests - '@ducanh2912/workbox-recipes': + version: link:../range-requests + '@serwiss/recipes': specifier: workspace:* - version: link:../workbox-recipes - '@ducanh2912/workbox-routing': + version: link:../recipes + '@serwiss/routing': specifier: workspace:* - version: link:../workbox-routing - '@ducanh2912/workbox-strategies': + version: link:../routing + '@serwiss/strategies': specifier: workspace:* - version: link:../workbox-strategies - '@ducanh2912/workbox-streams': + version: link:../strategies + '@serwiss/streams': specifier: workspace:* - version: link:../workbox-streams - '@ducanh2912/workbox-sw': + version: link:../streams + '@serwiss/sw': specifier: workspace:* - version: link:../workbox-sw - '@ducanh2912/workbox-window': + version: link:../sw + '@serwiss/window': specifier: workspace:* - version: link:../workbox-window - '@rollup/plugin-babel': - specifier: 6.0.4 - version: 6.0.4(@babel/core@7.23.2)(rollup@3.28.1) - '@rollup/plugin-node-resolve': - specifier: 15.2.3 - version: 15.2.3(rollup@3.28.1) - '@rollup/plugin-replace': - specifier: 5.0.4 - version: 5.0.4(rollup@3.28.1) - '@rollup/plugin-terser': - specifier: 0.4.4 - version: 0.4.4(rollup@3.28.1) + version: link:../window '@surma/rollup-plugin-off-main-thread': specifier: 2.2.3 version: 2.2.3 @@ -876,17 +820,17 @@ importers: specifier: 20.8.7 version: 20.8.7 - packages/workbox-cacheable-response: + packages/serwiss/cacheable-response: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: 7.0.0 - version: link:../workbox-core + version: link:../core - packages/workbox-cli: + packages/serwiss/cli: dependencies: - '@ducanh2912/workbox-build': + '@serwiss/build': specifier: workspace:* - version: link:../workbox-build + version: link:../build chalk: specifier: 5.3.0 version: 5.3.0 @@ -940,105 +884,105 @@ importers: specifier: 6.0.5 version: 6.0.5 - packages/workbox-core: {} + packages/serwiss/core: {} - packages/workbox-expiration: + packages/serwiss/expiration: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core + version: link:../core idb: specifier: 7.1.1 version: 7.1.1 - packages/workbox-google-analytics: + packages/serwiss/google-analytics: dependencies: - '@ducanh2912/workbox-background-sync': + '@serwiss/background-sync': specifier: workspace:* - version: link:../workbox-background-sync - '@ducanh2912/workbox-core': + version: link:../background-sync + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core - '@ducanh2912/workbox-routing': + version: link:../core + '@serwiss/routing': specifier: workspace:* - version: link:../workbox-routing - '@ducanh2912/workbox-strategies': + version: link:../routing + '@serwiss/strategies': specifier: workspace:* - version: link:../workbox-strategies + version: link:../strategies - packages/workbox-navigation-preload: + packages/serwiss/navigation-preload: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core + version: link:../core - packages/workbox-precaching: + packages/serwiss/precaching: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core - '@ducanh2912/workbox-routing': + version: link:../core + '@serwiss/routing': specifier: workspace:* - version: link:../workbox-routing - '@ducanh2912/workbox-strategies': + version: link:../routing + '@serwiss/strategies': specifier: workspace:* - version: link:../workbox-strategies + version: link:../strategies - packages/workbox-range-requests: + packages/serwiss/range-requests: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core + version: link:../core - packages/workbox-recipes: + packages/serwiss/recipes: dependencies: - '@ducanh2912/workbox-cacheable-response': + '@serwiss/cacheable-response': specifier: workspace:* - version: link:../workbox-cacheable-response - '@ducanh2912/workbox-core': + version: link:../cacheable-response + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core - '@ducanh2912/workbox-expiration': + version: link:../core + '@serwiss/expiration': specifier: workspace:* - version: link:../workbox-expiration - '@ducanh2912/workbox-precaching': + version: link:../expiration + '@serwiss/precaching': specifier: workspace:* - version: link:../workbox-precaching - '@ducanh2912/workbox-routing': + version: link:../precaching + '@serwiss/routing': specifier: workspace:* - version: link:../workbox-routing - '@ducanh2912/workbox-strategies': + version: link:../routing + '@serwiss/strategies': specifier: workspace:* - version: link:../workbox-strategies + version: link:../strategies - packages/workbox-routing: + packages/serwiss/routing: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core + version: link:../core - packages/workbox-strategies: + packages/serwiss/strategies: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core + version: link:../core - packages/workbox-streams: + packages/serwiss/streams: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: workspace:* - version: link:../workbox-core - '@ducanh2912/workbox-routing': + version: link:../core + '@serwiss/routing': specifier: workspace:* - version: link:../workbox-routing + version: link:../routing - packages/workbox-sw: {} + packages/serwiss/sw: {} - packages/workbox-webpack-plugin: + packages/serwiss/webpack-plugin: dependencies: - '@ducanh2912/workbox-build': + '@serwiss/build': specifier: workspace:* - version: link:../workbox-build + version: link:../build fast-json-stable-stringify: specifier: 2.1.0 version: 2.1.0 @@ -1062,15 +1006,71 @@ importers: specifier: 5.28.3 version: 5.28.3 - packages/workbox-window: + packages/serwiss/window: dependencies: - '@ducanh2912/workbox-core': + '@serwiss/core': specifier: 7.0.0 - version: link:../workbox-core + version: link:../core '@types/trusted-types': specifier: 2.0.4 version: 2.0.4 + packages/test-utils: + dependencies: + cheerio: + specifier: 1.0.0-rc.12 + version: 1.0.0-rc.12 + fs-extra: + specifier: 11.1.1 + version: 11.1.1 + type-fest: + specifier: 4.4.0 + version: 4.4.0 + devDependencies: + '@types/fs-extra': + specifier: 11.0.2 + version: 11.0.2 + '@types/jest': + specifier: 29.5.6 + version: 29.5.6 + + packages/utils: + dependencies: + chalk: + specifier: 5.3.0 + version: 5.3.0 + semver: + specifier: 7.5.4 + version: 7.5.4 + devDependencies: + '@ducanh2912/constants': + specifier: workspace:* + version: link:../constants + '@rollup/plugin-node-resolve': + specifier: 15.2.3 + version: 15.2.3(rollup@3.28.1) + '@rollup/plugin-swc': + specifier: 0.2.1 + version: 0.2.1(@swc/core@1.3.93)(rollup@3.28.1) + '@swc/core': + specifier: 1.3.93 + version: 1.3.93 + '@types/semver': + specifier: 7.5.3 + version: 7.5.3 + rollup: + specifier: 3.28.1 + version: 3.28.1 + terser-webpack-plugin: + specifier: 5.3.9 + version: 5.3.9(@swc/core@1.3.93)(webpack@5.89.0) + type-fest: + specifier: 4.4.0 + version: 4.4.0 + typescript: + specifier: 5.3.0-dev.20231018 + version: 5.3.0-dev.20231018 + packages: /@aashutoshrathi/word-wrap@1.2.6: @@ -1178,7 +1178,7 @@ packages: resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 '@jridgewell/gen-mapping': 0.3.2 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 @@ -1204,7 +1204,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: false /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: @@ -1232,7 +1232,7 @@ packages: dependencies: '@babel/compat-data': 7.23.2 '@babel/helper-validator-option': 7.22.15 - browserslist: 4.21.10 + browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -1244,8 +1244,8 @@ packages: dependencies: '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) @@ -1274,26 +1274,6 @@ packages: - supports-color dev: false - /@babel/helper-create-class-features-plugin@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-member-expression-to-functions': 7.22.5 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.5 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: false - /@babel/helper-create-regexp-features-plugin@7.20.5(@babel/core@7.20.5): resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} engines: {node: '>=6.9.0'} @@ -1305,17 +1285,6 @@ packages: regexpu-core: 5.2.2 dev: false - /@babel/helper-create-regexp-features-plugin@7.20.5(@babel/core@7.23.2): - resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.23.2 - '@babel/helper-annotate-as-pure': 7.22.5 - regexpu-core: 5.2.2 - dev: false - /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.2): resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} @@ -1334,7 +1303,7 @@ packages: '@babel/core': ^7.4.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 @@ -1371,14 +1340,14 @@ packages: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: false /@babel/helper-function-name@7.22.5: resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.5 + '@babel/template': 7.22.15 '@babel/types': 7.23.0 /@babel/helper-function-name@7.23.0: @@ -1398,7 +1367,7 @@ packages: resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: false /@babel/helper-member-expression-to-functions@7.23.0: @@ -1418,7 +1387,7 @@ packages: resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 /@babel/helper-module-transforms@7.20.2: resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} @@ -1429,12 +1398,26 @@ packages: '@babel/helper-simple-access': 7.20.2 '@babel/helper-split-export-declaration': 7.22.5 '@babel/helper-validator-identifier': 7.22.5 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms@7.23.0(@babel/core@7.20.5): + resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: false + /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2): resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} engines: {node: '>=6.9.0'} @@ -1469,7 +1452,7 @@ packages: '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.5 '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: false @@ -1502,11 +1485,11 @@ packages: resolution: {integrity: sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-member-expression-to-functions': 7.22.5 '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color @@ -1516,7 +1499,7 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} @@ -1567,10 +1550,10 @@ packages: resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-function-name': 7.22.5 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: false @@ -1579,7 +1562,7 @@ packages: resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-function-name': 7.22.5 + '@babel/helper-function-name': 7.23.0 '@babel/template': 7.22.15 '@babel/types': 7.23.0 dev: false @@ -1588,9 +1571,9 @@ packages: resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.5 - '@babel/types': 7.22.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.2 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color @@ -1618,7 +1601,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 /@babel/parser@7.23.0: resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} @@ -1797,7 +1780,7 @@ packages: dependencies: '@babel/compat-data': 7.20.5 '@babel/core': 7.20.5 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.20.5) '@babel/plugin-transform-parameters': 7.20.5(@babel/core@7.20.5) @@ -2201,7 +2184,7 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.23.2 - '@babel/helper-create-regexp-features-plugin': 7.20.5(@babel/core@7.23.2) + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 dev: false @@ -2259,7 +2242,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.2 - '@babel/helper-module-imports': 7.22.5 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.2) dev: false @@ -2311,10 +2294,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.2 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.23.2) + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-class-static-block@7.22.11(@babel/core@7.23.2): @@ -2337,7 +2318,7 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-environment-visitor': 7.22.5 '@babel/helper-function-name': 7.22.5 '@babel/helper-optimise-call-expression': 7.22.5 @@ -2358,8 +2339,8 @@ packages: '@babel/core': 7.23.2 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) @@ -2385,7 +2366,7 @@ packages: dependencies: '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/template': 7.22.5 + '@babel/template': 7.22.15 dev: false /@babel/plugin-transform-destructuring@7.20.2(@babel/core@7.20.5): @@ -2521,7 +2502,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.5) + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-function-name': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 dev: false @@ -2534,7 +2515,7 @@ packages: dependencies: '@babel/core': 7.23.2 '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-function-name': 7.22.5 + '@babel/helper-function-name': 7.23.0 '@babel/helper-plugin-utils': 7.22.5 dev: false @@ -2607,10 +2588,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.20.5) '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-modules-amd@7.23.0(@babel/core@7.23.2): @@ -2631,11 +2610,9 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.20.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-modules-commonjs@7.23.0(@babel/core@7.23.2): @@ -2658,11 +2635,9 @@ packages: dependencies: '@babel/core': 7.20.5 '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.20.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.2): @@ -2685,10 +2660,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.5 - '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-module-transforms': 7.23.0(@babel/core@7.20.5) '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.23.2): @@ -2801,9 +2774,7 @@ packages: dependencies: '@babel/core': 7.23.2 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.5 - transitivePeerDependencies: - - supports-color + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2) dev: false /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.2): @@ -2856,10 +2827,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.2 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.23.2) + '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2) '@babel/helper-plugin-utils': 7.22.5 - transitivePeerDependencies: - - supports-color dev: false /@babel/plugin-transform-private-property-in-object@7.22.11(@babel/core@7.23.2): @@ -3289,7 +3258,7 @@ packages: '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.20.5) '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.20.5) - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 esutils: 2.0.3 dev: false @@ -3340,7 +3309,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@babel/types': 7.23.0 /@babel/traverse@7.22.5: @@ -3348,12 +3317,12 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/generator': 7.22.5 + '@babel/generator': 7.23.0 '@babel/helper-environment-visitor': 7.22.5 '@babel/helper-function-name': 7.22.5 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.5 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@babel/types': 7.23.0 debug: 4.3.4 globals: 11.12.0 @@ -4947,7 +4916,7 @@ packages: optional: true dependencies: '@babel/core': 7.23.2 - '@babel/helper-module-imports': 7.22.5 + '@babel/helper-module-imports': 7.22.15 '@rollup/pluginutils': 5.0.2(rollup@3.28.1) rollup: 3.28.1 dev: false @@ -5313,8 +5282,8 @@ packages: /@types/babel__core@7.20.1: resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==} dependencies: - '@babel/parser': 7.22.5 - '@babel/types': 7.22.5 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.20.1 @@ -5323,20 +5292,20 @@ packages: /@types/babel__generator@7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.22.5 - '@babel/types': 7.22.5 + '@babel/parser': 7.23.0 + '@babel/types': 7.23.0 dev: true /@types/babel__traverse@7.20.1: resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 dev: true /@types/common-tags@1.8.3: @@ -6303,8 +6272,8 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.5 + '@babel/template': 7.22.15 + '@babel/types': 7.23.0 '@types/babel__core': 7.20.1 '@types/babel__traverse': 7.20.1 dev: true @@ -6542,7 +6511,6 @@ packages: electron-to-chromium: 1.4.557 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) - dev: false /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -6706,7 +6674,6 @@ packages: /caniuse-lite@1.0.30001550: resolution: {integrity: sha512-p82WjBYIypO0ukTsd/FG3Xxs+4tFeaY9pfT4amQL8KWtYH7H9nYwReGAbMTJ0hsmRO8IfDtsS6p3ZWj8+1c2RQ==} - dev: false /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -7523,7 +7490,6 @@ packages: /electron-to-chromium@1.4.557: resolution: {integrity: sha512-6x0zsxyMXpnMJnHrondrD3SuAeKcwij9S+83j2qHAQPXbGTDDfgImzzwgGlzrIcXbHQ42tkG4qA6U860cImNhw==} - dev: false /emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -9806,7 +9772,7 @@ packages: engines: {node: '>=8'} dependencies: '@babel/core': 7.23.2 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.1 @@ -9819,7 +9785,7 @@ packages: engines: {node: '>=10'} dependencies: '@babel/core': 7.23.2 - '@babel/parser': 7.22.5 + '@babel/parser': 7.23.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 7.5.4 @@ -10202,10 +10168,10 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.23.2 - '@babel/generator': 7.22.5 + '@babel/generator': 7.23.0 '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2) '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2) - '@babel/types': 7.22.5 + '@babel/types': 7.23.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 @@ -14987,7 +14953,6 @@ packages: browserslist: 4.22.1 escalade: 3.1.1 picocolors: 1.0.0 - dev: false /update-notifier@6.0.2: resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} @@ -15201,7 +15166,7 @@ packages: '@webassemblyjs/wasm-parser': 1.11.5 acorn: 8.10.0 acorn-import-assertions: 1.9.0(acorn@8.10.0) - browserslist: 4.21.10 + browserslist: 4.22.1 chrome-trace-event: 1.0.3 enhanced-resolve: 5.15.0 es-module-lexer: 1.2.1 From 36d8151d76bef9e6dbddb1b847f337dd283df68a Mon Sep 17 00:00:00 2001 From: DuCanhGH <75556609+DuCanhGH@users.noreply.github.com> Date: Wed, 18 Oct 2023 20:40:36 +0700 Subject: [PATCH 3/9] fixed various issues --- packages/serwiss/background-sync/package.json | 5 +++++ .../src/BackgroundSyncPlugin.ts | 12 +++++------ packages/serwiss/background-sync/src/Queue.ts | 8 ++++---- .../serwiss/background-sync/src/QueueStore.ts | 2 +- .../background-sync/src/StorableRequest.ts | 2 +- .../serwiss/background-sync/src/_version.ts | 2 +- packages/serwiss/background-sync/src/index.ts | 10 +++------- .../background-sync/src/lib/QueueStore.ts | 2 +- .../src/lib/StorableRequest.ts | 4 ++-- .../serwiss/broadcast-update/package.json | 4 ++++ .../src/BroadcastCacheUpdate.ts | 10 +++++----- .../src/BroadcastUpdatePlugin.ts | 4 ++-- .../serwiss/broadcast-update/src/index.ts | 9 +++------ .../broadcast-update/src/responsesAreSame.ts | 4 ++-- packages/serwiss/build/package.json | 16 ++++++++++----- packages/serwiss/build/src/generate-sw.ts | 10 +++++----- packages/serwiss/build/src/get-manifest.ts | 6 +++--- packages/serwiss/build/src/index.ts | 12 +++++------ packages/serwiss/build/src/inject-manifest.ts | 18 ++++++++--------- .../additional-manifest-entries-transform.ts | 4 ++-- packages/serwiss/build/src/lib/bundle.ts | 8 ++++---- packages/serwiss/build/src/lib/cdn-utils.ts | 6 +++--- .../build/src/lib/copy-workbox-libraries.ts | 4 ++-- .../build/src/lib/get-composite-details.ts | 2 +- .../serwiss/build/src/lib/get-file-details.ts | 12 +++++------ .../serwiss/build/src/lib/get-file-hash.ts | 4 ++-- .../src/lib/get-file-manifest-entries.ts | 12 +++++------ .../serwiss/build/src/lib/get-file-size.ts | 2 +- .../build/src/lib/get-string-details.ts | 4 ++-- .../build/src/lib/maximum-size-transform.ts | 2 +- .../src/lib/modify-url-prefix-transform.ts | 6 +++--- ...no-revision-for-urls-matching-transform.ts | 4 ++-- .../build/src/lib/populate-sw-template.ts | 14 ++++++------- .../src/lib/runtime-caching-converter.ts | 8 ++++---- .../build/src/lib/transform-manifest.ts | 12 +++++------ .../lib/translate-url-to-sourcemap-paths.ts | 2 +- .../serwiss/build/src/lib/validate-options.ts | 4 ++-- .../lib/write-sw-using-default-template.ts | 8 ++++---- packages/serwiss/build/src/types.ts | 16 +++++++-------- .../serwiss/cacheable-response/package.json | 4 ++++ .../src/CacheableResponse.ts | 8 ++++---- .../src/CacheableResponsePlugin.ts | 2 +- .../serwiss/cacheable-response/src/index.ts | 4 +++- packages/serwiss/core/package.json | 7 ++++++- packages/serwiss/expiration/package.json | 4 ++++ .../serwiss/expiration/src/CacheExpiration.ts | 8 ++++---- .../expiration/src/ExpirationPlugin.ts | 16 +++++++-------- packages/serwiss/expiration/src/index.ts | 4 +++- .../serwiss/google-analytics/package.json | 4 ++++ .../google-analytics/src/initialize.ts | 20 +++++++++---------- .../serwiss/navigation-preload/src/disable.ts | 2 +- .../serwiss/navigation-preload/src/enable.ts | 2 +- .../precaching/src/PrecacheController.ts | 14 ++++++------- .../precaching/src/PrecacheFallbackPlugin.ts | 2 +- .../serwiss/precaching/src/PrecacheRoute.ts | 8 ++++---- .../precaching/src/PrecacheStrategy.ts | 16 +++++++-------- packages/serwiss/precaching/src/addPlugins.ts | 2 +- packages/serwiss/precaching/src/addRoute.ts | 2 +- .../precaching/src/cleanupOutdatedCaches.ts | 4 ++-- .../precaching/src/createHandlerBoundToURL.ts | 2 +- .../src/utils/PrecacheCacheKeyPlugin.ts | 2 +- .../src/utils/PrecacheInstallReportPlugin.ts | 2 +- .../precaching/src/utils/createCacheKey.ts | 2 +- .../src/utils/printCleanupDetails.ts | 2 +- .../src/utils/printInstallDetails.ts | 2 +- .../range-requests/src/RangeRequestsPlugin.ts | 2 +- .../src/createPartialResponse.ts | 6 +++--- .../src/utils/calculateEffectiveBoundaries.ts | 4 ++-- .../src/utils/parseRangeHeader.ts | 4 ++-- .../serwiss/recipes/src/googleFontsCache.ts | 10 +++++----- packages/serwiss/recipes/src/imageCache.ts | 10 +++++----- .../serwiss/recipes/src/offlineFallback.ts | 6 +++--- packages/serwiss/recipes/src/pageCache.ts | 8 ++++---- .../recipes/src/staticResourceCache.ts | 8 ++++---- .../serwiss/recipes/src/warmStrategyCache.ts | 2 +- packages/serwiss/routing/package.json | 3 +++ .../serwiss/routing/src/NavigationRoute.ts | 6 +++--- packages/serwiss/routing/src/RegExpRoute.ts | 6 +++--- packages/serwiss/routing/src/Route.ts | 4 ++-- packages/serwiss/routing/src/Router.ts | 10 +++++----- packages/serwiss/routing/src/index.ts | 4 +++- packages/serwiss/routing/src/registerRoute.ts | 6 +++--- .../serwiss/routing/src/setCatchHandler.ts | 2 +- .../serwiss/routing/src/setDefaultHandler.ts | 2 +- .../routing/src/utils/normalizeHandler.ts | 4 ++-- packages/serwiss/strategies/src/CacheFirst.ts | 6 +++--- packages/serwiss/strategies/src/CacheOnly.ts | 6 +++--- .../serwiss/strategies/src/NetworkFirst.ts | 6 +++--- .../serwiss/strategies/src/NetworkOnly.ts | 8 ++++---- .../strategies/src/StaleWhileRevalidate.ts | 6 +++--- packages/serwiss/strategies/src/Strategy.ts | 10 +++++----- .../serwiss/strategies/src/StrategyHandler.ts | 18 ++++++++--------- .../src/plugins/cacheOkAndOpaquePlugin.ts | 2 +- .../serwiss/strategies/src/utils/messages.ts | 4 ++-- packages/serwiss/streams/src/concatenate.ts | 8 ++++---- packages/serwiss/streams/src/isSupported.ts | 2 +- packages/serwiss/streams/src/strategy.ts | 4 ++-- packages/serwiss/window/src/Workbox.ts | 6 +++--- pnpm-lock.yaml | 19 ++++++++++++++++++ 99 files changed, 341 insertions(+), 290 deletions(-) diff --git a/packages/serwiss/background-sync/package.json b/packages/serwiss/background-sync/package.json index 5c19b982..d24f4953 100644 --- a/packages/serwiss/background-sync/package.json +++ b/packages/serwiss/background-sync/package.json @@ -7,6 +7,7 @@ "repository": "DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", "homepage": "https://ducanh-next-pwa.vercel.app", + "type": "module", "keywords": [ "workbox", "workboxjs", @@ -26,5 +27,9 @@ "dependencies": { "@serwiss/core": "workspace:*", "idb": "7.1.1" + }, + "exports": { + ".": "./src/index.ts", + "./queue": "./src/Queue.ts" } } diff --git a/packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts b/packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts index 085c5cdf..2ac60423 100644 --- a/packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts +++ b/packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts @@ -6,7 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxPlugin } from "workbox-core/types.js"; +import { WorkboxPlugin } from "@serwiss/core/types"; + import { Queue, QueueOptions } from "./Queue.js"; import "./_version.js"; @@ -20,11 +21,10 @@ class BackgroundSyncPlugin implements WorkboxPlugin { private readonly _queue: Queue; /** - * @param {string} name See the {@link workbox-background-sync.Queue} - * documentation for parameter details. - * @param {Object} [options] See the - * {@link workbox-background-sync.Queue} documentation for - * parameter details. + * @param name See the {@link workbox-background-sync.Queue} + * documentation for parameter details. + * @param options See the {@link workbox-background-sync.Queue} + * documentation for parameter details. */ constructor(name: string, options?: QueueOptions) { this._queue = new Queue(name, options); diff --git a/packages/serwiss/background-sync/src/Queue.ts b/packages/serwiss/background-sync/src/Queue.ts index aed9f298..f8aa8ca6 100644 --- a/packages/serwiss/background-sync/src/Queue.ts +++ b/packages/serwiss/background-sync/src/Queue.ts @@ -6,10 +6,10 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { assert } from "workbox-core/_private/assert.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; import { QueueStore } from "./lib/QueueStore.js"; import { QueueStoreEntry, UnidentifiedQueueStoreEntry } from "./lib/QueueDb.js"; import { StorableRequest } from "./lib/StorableRequest.js"; diff --git a/packages/serwiss/background-sync/src/QueueStore.ts b/packages/serwiss/background-sync/src/QueueStore.ts index eb078d61..e11bf01e 100644 --- a/packages/serwiss/background-sync/src/QueueStore.ts +++ b/packages/serwiss/background-sync/src/QueueStore.ts @@ -11,4 +11,4 @@ import "./_version.js"; // This is a temporary workaround to expose something from ./lib/ via our // top-level public API. // TODO: In Workbox v7, move the actual code from ./lib/ to this file. -export { QueueStore } from "./lib/QueueStore"; +export { QueueStore } from "./lib/QueueStore.js"; diff --git a/packages/serwiss/background-sync/src/StorableRequest.ts b/packages/serwiss/background-sync/src/StorableRequest.ts index 75cfe78b..c6fdf57e 100644 --- a/packages/serwiss/background-sync/src/StorableRequest.ts +++ b/packages/serwiss/background-sync/src/StorableRequest.ts @@ -11,4 +11,4 @@ import "./_version.js"; // This is a temporary workaround to expose something from ./lib/ via our // top-level public API. // TODO: In Workbox v7, move the actual code from ./lib/ to this file. -export { StorableRequest } from "./lib/StorableRequest"; +export { StorableRequest } from "./lib/StorableRequest.js"; diff --git a/packages/serwiss/background-sync/src/_version.ts b/packages/serwiss/background-sync/src/_version.ts index a09900db..787057ab 100644 --- a/packages/serwiss/background-sync/src/_version.ts +++ b/packages/serwiss/background-sync/src/_version.ts @@ -1,4 +1,4 @@ -// @ts-ignore try { + // @ts-ignore self["workbox:background-sync:7.0.0"] && _(); } catch (e) {} diff --git a/packages/serwiss/background-sync/src/index.ts b/packages/serwiss/background-sync/src/index.ts index 12115875..bf98362d 100644 --- a/packages/serwiss/background-sync/src/index.ts +++ b/packages/serwiss/background-sync/src/index.ts @@ -37,10 +37,6 @@ declare global { /** * @module workbox-background-sync */ -export { - BackgroundSyncPlugin, - Queue, - QueueOptions, - QueueStore, - StorableRequest, -}; +export { BackgroundSyncPlugin, Queue, QueueStore, StorableRequest }; + +export type { QueueOptions }; diff --git a/packages/serwiss/background-sync/src/lib/QueueStore.ts b/packages/serwiss/background-sync/src/lib/QueueStore.ts index 3f3e0dbc..1e28a252 100644 --- a/packages/serwiss/background-sync/src/lib/QueueStore.ts +++ b/packages/serwiss/background-sync/src/lib/QueueStore.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; +import { assert } from "@serwiss/core/_private/assert.js"; import { UnidentifiedQueueStoreEntry, QueueStoreEntry, diff --git a/packages/serwiss/background-sync/src/lib/StorableRequest.ts b/packages/serwiss/background-sync/src/lib/StorableRequest.ts index c648965c..b86f6820 100644 --- a/packages/serwiss/background-sync/src/lib/StorableRequest.ts +++ b/packages/serwiss/background-sync/src/lib/StorableRequest.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { MapLikeObject } from "workbox-core/types.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { MapLikeObject } from "@serwiss/core/types"; import "../_version.js"; type SerializableProperties = diff --git a/packages/serwiss/broadcast-update/package.json b/packages/serwiss/broadcast-update/package.json index 2d25acdc..56d3becf 100644 --- a/packages/serwiss/broadcast-update/package.json +++ b/packages/serwiss/broadcast-update/package.json @@ -1,6 +1,7 @@ { "name": "@serwiss/broadcast-update", "version": "7.0.0", + "type": "module", "license": "MIT", "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library that uses the Broadcast Channel API to announce when a cached response has updated", @@ -23,5 +24,8 @@ "types": "index.d.ts", "dependencies": { "@serwiss/core": "7.0.0" + }, + "exports": { + ".": "./src/index.ts" } } diff --git a/packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts b/packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts index f2eca47b..569fb6f3 100644 --- a/packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts +++ b/packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts @@ -6,11 +6,11 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { timeout } from "workbox-core/_private/timeout.js"; -import { resultingClientExists } from "workbox-core/_private/resultingClientExists.js"; -import { CacheDidUpdateCallbackParam } from "workbox-core/types.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { timeout } from "@serwiss/core/_private/timeout.js"; +import { resultingClientExists } from "@serwiss/core/_private/resultingClientExists.js"; +import { CacheDidUpdateCallbackParam } from "@serwiss/core/types"; +import { logger } from "@serwiss/core/_private/logger.js"; import { responsesAreSame } from "./responsesAreSame.js"; import { CACHE_UPDATED_MESSAGE_META, diff --git a/packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts b/packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts index 9bbb967b..953f07e4 100644 --- a/packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts +++ b/packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; -import { WorkboxPlugin } from "workbox-core/types.js"; +import { dontWaitFor } from "@serwiss/core/_private/dontWaitFor.js"; +import { WorkboxPlugin } from "@serwiss/core/types"; import { BroadcastCacheUpdate, diff --git a/packages/serwiss/broadcast-update/src/index.ts b/packages/serwiss/broadcast-update/src/index.ts index 096647ab..75c12421 100644 --- a/packages/serwiss/broadcast-update/src/index.ts +++ b/packages/serwiss/broadcast-update/src/index.ts @@ -19,9 +19,6 @@ import "./_version.js"; * @module workbox-broadcast-update */ -export { - BroadcastCacheUpdate, - BroadcastCacheUpdateOptions, - BroadcastUpdatePlugin, - responsesAreSame, -}; +export { BroadcastCacheUpdate, BroadcastUpdatePlugin, responsesAreSame }; + +export type { BroadcastCacheUpdateOptions }; diff --git a/packages/serwiss/broadcast-update/src/responsesAreSame.ts b/packages/serwiss/broadcast-update/src/responsesAreSame.ts index ec4f49fc..9ce3e7f5 100644 --- a/packages/serwiss/broadcast-update/src/responsesAreSame.ts +++ b/packages/serwiss/broadcast-update/src/responsesAreSame.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import "./_version.js"; /** diff --git a/packages/serwiss/build/package.json b/packages/serwiss/build/package.json index f6d51167..05b24b89 100644 --- a/packages/serwiss/build/package.json +++ b/packages/serwiss/build/package.json @@ -1,6 +1,7 @@ { "name": "@serwiss/build", "version": "7.0.0", + "type": "module", "description": "A module that integrates into your build process, helping you generate a manifest of local files that workbox-sw should precache.", "keywords": [ "workbox", @@ -24,6 +25,10 @@ "@babel/core": "7.23.2", "@babel/preset-env": "7.23.2", "@babel/runtime": "7.23.2", + "@rollup/plugin-babel": "6.0.4", + "@rollup/plugin-node-resolve": "15.2.3", + "@rollup/plugin-replace": "5.0.4", + "@rollup/plugin-terser": "0.4.4", "@serwiss/background-sync": "workspace:*", "@serwiss/broadcast-update": "workspace:*", "@serwiss/cacheable-response": "workspace:*", @@ -40,10 +45,6 @@ "@serwiss/sw": "workspace:*", "@serwiss/window": "workspace:*", "@surma/rollup-plugin-off-main-thread": "2.2.3", - "@rollup/plugin-babel": "6.0.4", - "@rollup/plugin-node-resolve": "15.2.3", - "@rollup/plugin-replace": "5.0.4", - "@rollup/plugin-terser": "0.4.4", "ajv": "8.12.0", "common-tags": "1.8.2", "fast-json-stable-stringify": "2.1.0", @@ -64,6 +65,11 @@ }, "types": "build/index.d.ts", "devDependencies": { - "@types/node": "20.8.7" + "@types/common-tags": "1.8.3", + "@types/fs-extra": "11.0.2", + "@types/lodash": "4.14.200", + "@types/node": "20.8.7", + "@types/stringify-object": "4.0.3", + "type-fest": "4.4.0" } } diff --git a/packages/serwiss/build/src/generate-sw.ts b/packages/serwiss/build/src/generate-sw.ts index fde3e89d..1baa50bb 100644 --- a/packages/serwiss/build/src/generate-sw.ts +++ b/packages/serwiss/build/src/generate-sw.ts @@ -8,11 +8,11 @@ import upath from "upath"; -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"; -import type { BuildResult, GenerateSWOptions,GetManifestOptions } from "./types"; +import { getFileManifestEntries } from "./lib/get-file-manifest-entries.js"; +import { rebasePath } from "./lib/rebase-path.js"; +import { validateGenerateSWOptions } from "./lib/validate-options.js"; +import { writeSWUsingDefaultTemplate } from "./lib/write-sw-using-default-template.js"; +import type { BuildResult, GenerateSWOptions,GetManifestOptions } from "./types.js"; /** * This method creates a list of URLs to precache, referred to as a "precache diff --git a/packages/serwiss/build/src/get-manifest.ts b/packages/serwiss/build/src/get-manifest.ts index 9a7c038a..99416672 100644 --- a/packages/serwiss/build/src/get-manifest.ts +++ b/packages/serwiss/build/src/get-manifest.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { getFileManifestEntries } from "./lib/get-file-manifest-entries"; -import { validateGetManifestOptions } from "./lib/validate-options"; -import type { GetManifestOptions, GetManifestResult } from "./types"; +import { getFileManifestEntries } from "./lib/get-file-manifest-entries.js"; +import { validateGetManifestOptions } from "./lib/validate-options.js"; +import type { GetManifestOptions, GetManifestResult } from "./types.js"; /** * This method returns a list of URLs to precache, referred to as a "precache diff --git a/packages/serwiss/build/src/index.ts b/packages/serwiss/build/src/index.ts index 03d677b8..ae6be8d4 100644 --- a/packages/serwiss/build/src/index.ts +++ b/packages/serwiss/build/src/index.ts @@ -6,11 +6,11 @@ https://opensource.org/licenses/MIT. */ -import { generateSW } from "./generate-sw"; -import { getManifest } from "./get-manifest"; -import { injectManifest } from "./inject-manifest"; -import { getModuleURL } from "./lib/cdn-utils"; -import { copyWorkboxLibraries } from "./lib/copy-workbox-libraries"; +import { generateSW } from "./generate-sw.js"; +import { getManifest } from "./get-manifest.js"; +import { injectManifest } from "./inject-manifest.js"; +import { getModuleURL } from "./lib/cdn-utils.js"; +import { copyWorkboxLibraries } from "./lib/copy-workbox-libraries.js"; /** * @module workbox-build @@ -23,4 +23,4 @@ export { injectManifest, }; -export * from "./types"; +export * from "./types.js"; diff --git a/packages/serwiss/build/src/inject-manifest.ts b/packages/serwiss/build/src/inject-manifest.ts index 701ab938..22783e52 100644 --- a/packages/serwiss/build/src/inject-manifest.ts +++ b/packages/serwiss/build/src/inject-manifest.ts @@ -12,15 +12,15 @@ import fse from "fs-extra"; import type { RawSourceMap } from "source-map"; import upath from "upath"; -import { errors } from "./lib/errors"; -import { escapeRegExp } from "./lib/escape-regexp"; -import { getFileManifestEntries } from "./lib/get-file-manifest-entries"; -import { getSourceMapURL } from "./lib/get-source-map-url"; -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"; -import type { BuildResult, InjectManifestOptions } from "./types"; +import { errors } from "./lib/errors.js"; +import { escapeRegExp } from "./lib/escape-regexp.js"; +import { getFileManifestEntries } from "./lib/get-file-manifest-entries.js"; +import { getSourceMapURL } from "./lib/get-source-map-url.js"; +import { rebasePath } from "./lib/rebase-path.js"; +import { replaceAndUpdateSourceMap } from "./lib/replace-and-update-source-map.js"; +import { translateURLToSourcemapPaths } from "./lib/translate-url-to-sourcemap-paths.js"; +import { validateInjectManifestOptions } from "./lib/validate-options.js"; +import type { BuildResult, InjectManifestOptions } from "./types.js"; /** * This method creates a list of URLs to precache, referred to as a "precache diff --git a/packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts b/packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts index 3901bad2..9442d9ac 100644 --- a/packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts +++ b/packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import type { ManifestEntry } from "../types"; -import { errors } from "./errors"; +import type { ManifestEntry } from "../types.js"; +import { errors } from "./errors.js"; type AdditionalManifestEntriesTransform = { (manifest: Array): { diff --git a/packages/serwiss/build/src/lib/bundle.ts b/packages/serwiss/build/src/lib/bundle.ts index be53a82a..fc97efc4 100644 --- a/packages/serwiss/build/src/lib/bundle.ts +++ b/packages/serwiss/build/src/lib/bundle.ts @@ -12,10 +12,10 @@ import { nodeResolve } from "@rollup/plugin-node-resolve"; import replace from "@rollup/plugin-replace"; import omt from "@surma/rollup-plugin-off-main-thread"; import { writeFile } from "fs-extra"; -import type { Plugin} from "rollup"; -import {rollup } from "rollup"; -import { terser } from "rollup-plugin-terser"; -import tempy from "tempy"; +import type { Plugin } from "rollup"; +import { rollup } from "rollup"; +import terser from "@rollup/plugin-terser"; +import * as tempy from "tempy"; import upath from "upath"; import type { GeneratePartial, RequiredSWDestPartial } from "../types"; diff --git a/packages/serwiss/build/src/lib/cdn-utils.ts b/packages/serwiss/build/src/lib/cdn-utils.ts index 7a49bde0..f1201ba2 100644 --- a/packages/serwiss/build/src/lib/cdn-utils.ts +++ b/packages/serwiss/build/src/lib/cdn-utils.ts @@ -8,9 +8,9 @@ import { ok } from "assert"; -import * as cdn from "../cdn-details.json"; -import type { BuildType, WorkboxPackageJSON } from "../types"; -import { errors } from "./errors"; +import cdn from "../cdn-details.json"; +import type { BuildType, WorkboxPackageJSON } from "../types.js"; +import { errors } from "./errors.js"; function getVersionedURL(): string { return `${getCDNPrefix()}/${cdn.latestVersion}`; diff --git a/packages/serwiss/build/src/lib/copy-workbox-libraries.ts b/packages/serwiss/build/src/lib/copy-workbox-libraries.ts index 71232dcd..5dba4e86 100644 --- a/packages/serwiss/build/src/lib/copy-workbox-libraries.ts +++ b/packages/serwiss/build/src/lib/copy-workbox-libraries.ts @@ -9,8 +9,8 @@ import fse from "fs-extra"; import upath from "upath"; -import type { WorkboxPackageJSON } from "../types"; -import { errors } from "./errors"; +import type { WorkboxPackageJSON } from "../types.js"; +import { errors } from "./errors.js"; // Used to filter the libraries to copy based on our package.json dependencies. const WORKBOX_PREFIX = "workbox-"; diff --git a/packages/serwiss/build/src/lib/get-composite-details.ts b/packages/serwiss/build/src/lib/get-composite-details.ts index 8fe9c751..3d512f3a 100644 --- a/packages/serwiss/build/src/lib/get-composite-details.ts +++ b/packages/serwiss/build/src/lib/get-composite-details.ts @@ -8,7 +8,7 @@ import crypto from "crypto"; -import type { FileDetails } from "../types"; +import type { FileDetails } from "../types.js"; export function getCompositeDetails( compositeURL: string, diff --git a/packages/serwiss/build/src/lib/get-file-details.ts b/packages/serwiss/build/src/lib/get-file-details.ts index 97df8dd5..e8456c23 100644 --- a/packages/serwiss/build/src/lib/get-file-details.ts +++ b/packages/serwiss/build/src/lib/get-file-details.ts @@ -6,13 +6,13 @@ https://opensource.org/licenses/MIT. */ -import glob from "glob"; +import { glob } from "glob"; import upath from "upath"; -import type { GlobPartial } from "../types"; -import { errors } from "./errors"; -import { getFileHash } from "./get-file-hash"; -import { getFileSize } from "./get-file-size"; +import type { GlobPartial } from "../types.js"; +import { errors } from "./errors.js"; +import { getFileHash } from "./get-file-hash.js"; +import { getFileSize } from "./get-file-size.js"; interface FileDetails { file: string; @@ -25,7 +25,6 @@ export function getFileDetails({ globFollow, globIgnores, globPattern, - globStrict, }: Omit & { // This will only be called when globDirectory is not undefined. globDirectory: string; @@ -42,7 +41,6 @@ export function getFileDetails({ cwd: globDirectory, follow: globFollow, ignore: globIgnores, - strict: globStrict, }); } catch (err) { throw new Error( diff --git a/packages/serwiss/build/src/lib/get-file-hash.ts b/packages/serwiss/build/src/lib/get-file-hash.ts index fa6e873a..dc02b1fd 100644 --- a/packages/serwiss/build/src/lib/get-file-hash.ts +++ b/packages/serwiss/build/src/lib/get-file-hash.ts @@ -8,8 +8,8 @@ import fse from "fs-extra"; -import { errors } from "./errors"; -import { getStringHash } from "./get-string-hash"; +import { errors } from "./errors.js"; +import { getStringHash } from "./get-string-hash.js"; export function getFileHash(file: string): string { try { diff --git a/packages/serwiss/build/src/lib/get-file-manifest-entries.ts b/packages/serwiss/build/src/lib/get-file-manifest-entries.ts index 559aec26..926c728c 100644 --- a/packages/serwiss/build/src/lib/get-file-manifest-entries.ts +++ b/packages/serwiss/build/src/lib/get-file-manifest-entries.ts @@ -8,12 +8,12 @@ import assert from "assert"; -import type { FileDetails, GetManifestOptions,GetManifestResult } 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"; +import type { FileDetails, GetManifestOptions,GetManifestResult } from "../types.js"; +import { errors } from "./errors.js"; +import { getCompositeDetails } from "./get-composite-details.js"; +import { getFileDetails } from "./get-file-details.js"; +import { getStringDetails } from "./get-string-details.js"; +import { transformManifest } from "./transform-manifest.js"; export async function getFileManifestEntries({ additionalManifestEntries, diff --git a/packages/serwiss/build/src/lib/get-file-size.ts b/packages/serwiss/build/src/lib/get-file-size.ts index bc420037..625d9f93 100644 --- a/packages/serwiss/build/src/lib/get-file-size.ts +++ b/packages/serwiss/build/src/lib/get-file-size.ts @@ -8,7 +8,7 @@ import fse from "fs-extra"; -import { errors } from "./errors"; +import { errors } from "./errors.js"; export function getFileSize(file: string): number | null { try { diff --git a/packages/serwiss/build/src/lib/get-string-details.ts b/packages/serwiss/build/src/lib/get-string-details.ts index 4a52e0df..703637e9 100644 --- a/packages/serwiss/build/src/lib/get-string-details.ts +++ b/packages/serwiss/build/src/lib/get-string-details.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import type { FileDetails } from "../types"; -import { getStringHash } from "./get-string-hash"; +import type { FileDetails } from "../types.js"; +import { getStringHash } from "./get-string-hash.js"; export function getStringDetails(url: string, str: string): FileDetails { return { diff --git a/packages/serwiss/build/src/lib/maximum-size-transform.ts b/packages/serwiss/build/src/lib/maximum-size-transform.ts index 003d5794..5005fb61 100644 --- a/packages/serwiss/build/src/lib/maximum-size-transform.ts +++ b/packages/serwiss/build/src/lib/maximum-size-transform.ts @@ -8,7 +8,7 @@ import prettyBytes from "pretty-bytes"; -import type { ManifestTransform } from "../types"; +import type { ManifestTransform } from "../types.js"; export function maximumSizeTransform( maximumFileSizeToCacheInBytes: number diff --git a/packages/serwiss/build/src/lib/modify-url-prefix-transform.ts b/packages/serwiss/build/src/lib/modify-url-prefix-transform.ts index 506da1cb..ed6d8094 100644 --- a/packages/serwiss/build/src/lib/modify-url-prefix-transform.ts +++ b/packages/serwiss/build/src/lib/modify-url-prefix-transform.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import type { ManifestTransform } from "../types"; -import { errors } from "./errors"; -import { escapeRegExp } from "./escape-regexp"; +import type { ManifestTransform } from "../types.js"; +import { errors } from "./errors.js"; +import { escapeRegExp } from "./escape-regexp.js"; export function modifyURLPrefixTransform(modifyURLPrefix: { [key: string]: string; diff --git a/packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts b/packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts index 0b987cff..6fb0d5b4 100644 --- a/packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts +++ b/packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import type { ManifestTransform } from "../types"; -import { errors } from "./errors"; +import type { ManifestTransform } from "../types.js"; +import { errors } from "./errors.js"; export function noRevisionForURLsMatchingTransform( regexp: RegExp diff --git a/packages/serwiss/build/src/lib/populate-sw-template.ts b/packages/serwiss/build/src/lib/populate-sw-template.ts index 1b1c4f09..2066c44b 100644 --- a/packages/serwiss/build/src/lib/populate-sw-template.ts +++ b/packages/serwiss/build/src/lib/populate-sw-template.ts @@ -6,14 +6,14 @@ https://opensource.org/licenses/MIT. */ -import template from "lodash/template"; +import template from "lodash/template.js"; -import { swTemplate } from "../templates/sw-template"; -import type { GeneratePartial, ManifestEntry } from "../types"; -import { errors } from "./errors"; -import { ModuleRegistry } from "./module-registry"; -import { runtimeCachingConverter } from "./runtime-caching-converter"; -import { stringifyWithoutComments } from "./stringify-without-comments"; +import { swTemplate } from "../templates/sw-template.js"; +import type { GeneratePartial, ManifestEntry } from "../types.js"; +import { errors } from "./errors.js"; +import { ModuleRegistry } from "./module-registry.js"; +import { runtimeCachingConverter } from "./runtime-caching-converter.js"; +import { stringifyWithoutComments } from "./stringify-without-comments.js"; export function populateSWTemplate({ cacheId, diff --git a/packages/serwiss/build/src/lib/runtime-caching-converter.ts b/packages/serwiss/build/src/lib/runtime-caching-converter.ts index f0f6af99..b56325d7 100644 --- a/packages/serwiss/build/src/lib/runtime-caching-converter.ts +++ b/packages/serwiss/build/src/lib/runtime-caching-converter.ts @@ -8,10 +8,10 @@ import { oneLine as ol } from "common-tags"; -import type { RuntimeCaching } from "../types"; -import { errors } from "./errors"; -import type { ModuleRegistry } from "./module-registry"; -import { stringifyWithoutComments } from "./stringify-without-comments"; +import type { RuntimeCaching } from "../types.js"; +import { errors } from "./errors.js"; +import type { ModuleRegistry } from "./module-registry.js"; +import { stringifyWithoutComments } from "./stringify-without-comments.js"; /** * Given a set of options that configures runtime caching behavior, convert it diff --git a/packages/serwiss/build/src/lib/transform-manifest.ts b/packages/serwiss/build/src/lib/transform-manifest.ts index 994770a9..6c713112 100644 --- a/packages/serwiss/build/src/lib/transform-manifest.ts +++ b/packages/serwiss/build/src/lib/transform-manifest.ts @@ -11,12 +11,12 @@ import type { 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"; +} from "../types.js"; +import { additionalManifestEntriesTransform } from "./additional-manifest-entries-transform.js"; +import { errors } from "./errors.js"; +import { maximumSizeTransform } from "./maximum-size-transform.js"; +import { modifyURLPrefixTransform } from "./modify-url-prefix-transform.js"; +import { noRevisionForURLsMatchingTransform } from "./no-revision-for-urls-matching-transform.js"; /** * A `ManifestTransform` function can be used to modify the modify the `url` or diff --git a/packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts b/packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts index 44e1c131..d9a0cec8 100644 --- a/packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts +++ b/packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts @@ -9,7 +9,7 @@ import fse from "fs-extra"; import upath from "upath"; -import { errors } from "./errors"; +import { errors } from "./errors.js"; export function translateURLToSourcemapPaths( url: string | null, diff --git a/packages/serwiss/build/src/lib/validate-options.ts b/packages/serwiss/build/src/lib/validate-options.ts index 74f94310..4294d99b 100644 --- a/packages/serwiss/build/src/lib/validate-options.ts +++ b/packages/serwiss/build/src/lib/validate-options.ts @@ -17,8 +17,8 @@ import type { InjectManifestOptions, WebpackGenerateSWOptions, WebpackInjectManifestOptions, -} from "../types"; -import { errors } from "./errors"; +} from "../types.js"; +import { errors } from "./errors.js"; type MethodNames = | "GenerateSW" diff --git a/packages/serwiss/build/src/lib/write-sw-using-default-template.ts b/packages/serwiss/build/src/lib/write-sw-using-default-template.ts index f2f478a3..7d6f271b 100644 --- a/packages/serwiss/build/src/lib/write-sw-using-default-template.ts +++ b/packages/serwiss/build/src/lib/write-sw-using-default-template.ts @@ -9,10 +9,10 @@ import fse from "fs-extra"; import upath from "upath"; -import type { GenerateSWOptions, ManifestEntry } from "../types"; -import { bundle } from "./bundle"; -import { errors } from "./errors"; -import { populateSWTemplate } from "./populate-sw-template"; +import type { GenerateSWOptions, ManifestEntry } from "../types.js"; +import { bundle } from "./bundle.js"; +import { errors } from "./errors.js"; +import { populateSWTemplate } from "./populate-sw-template.js"; export async function writeSWUsingDefaultTemplate({ babelPresetEnvTargets, diff --git a/packages/serwiss/build/src/types.ts b/packages/serwiss/build/src/types.ts index 223c3617..1dac0198 100644 --- a/packages/serwiss/build/src/types.ts +++ b/packages/serwiss/build/src/types.ts @@ -1,11 +1,11 @@ import type { PackageJson } from "type-fest"; -import type { QueueOptions } from "workbox-background-sync/Queue"; -import type { BroadcastCacheUpdateOptions } from "workbox-broadcast-update/BroadcastCacheUpdate"; -import type { CacheableResponseOptions } from "workbox-cacheable-response/CacheableResponse"; -import type { RouteHandler, RouteMatchCallback , WorkboxPlugin } from "workbox-core/types"; -import type { ExpirationPluginOptions } from "workbox-expiration/ExpirationPlugin"; -import type { GoogleAnalyticsInitializeOptions } from "workbox-google-analytics/initialize"; -import type { HTTPMethod } from "workbox-routing/utils/constants"; +import type { QueueOptions } from "@serwiss/background-sync/queue"; +import type { BroadcastCacheUpdateOptions } from "@serwiss/broadcast-update"; +import type { CacheableResponseOptions } from "@serwiss/cacheable-response"; +import type { RouteHandler, RouteMatchCallback , WorkboxPlugin } from "@serwiss/core/types"; +import type { ExpirationPluginOptions } from "@serwiss/expiration"; +import type { GoogleAnalyticsInitializeOptions } from "@serwiss/google-analytics/initialize"; +import type { HTTPMethod } from "@serwiss/routing"; export interface ManifestEntry { integrity?: string; @@ -581,7 +581,7 @@ export type BuildType = "dev" | "prod"; /** * @private */ -export interface WorkboxPackageJSON extends PackageJson { +export type WorkboxPackageJSON = PackageJson & { workbox?: { browserNamespace?: string; packageType?: string; diff --git a/packages/serwiss/cacheable-response/package.json b/packages/serwiss/cacheable-response/package.json index 80834bcf..81213369 100755 --- a/packages/serwiss/cacheable-response/package.json +++ b/packages/serwiss/cacheable-response/package.json @@ -1,6 +1,7 @@ { "name": "@serwiss/cacheable-response", "version": "7.0.0", + "type": "module", "license": "MIT", "author": "Google's Web DevRel Team, DuCanhGH", "description": "This library takes a Response object and determines whether it's cacheable based on a specific configuration.", @@ -21,6 +22,9 @@ "main": "index.js", "module": "index.mjs", "types": "index.d.ts", + "exports": { + ".": "./src/index.ts" + }, "dependencies": { "@serwiss/core": "7.0.0" } diff --git a/packages/serwiss/cacheable-response/src/CacheableResponse.ts b/packages/serwiss/cacheable-response/src/CacheableResponse.ts index e4a1915c..168fe056 100644 --- a/packages/serwiss/cacheable-response/src/CacheableResponse.ts +++ b/packages/serwiss/cacheable-response/src/CacheableResponse.ts @@ -6,10 +6,10 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import "./_version.js"; export interface CacheableResponseOptions { diff --git a/packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts b/packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts index 1b3316d8..4213f9db 100644 --- a/packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts +++ b/packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxPlugin } from "workbox-core/types.js"; +import { WorkboxPlugin } from "@serwiss/core/types"; import { CacheableResponse, CacheableResponseOptions, diff --git a/packages/serwiss/cacheable-response/src/index.ts b/packages/serwiss/cacheable-response/src/index.ts index 74ccc4a0..b2532c90 100644 --- a/packages/serwiss/cacheable-response/src/index.ts +++ b/packages/serwiss/cacheable-response/src/index.ts @@ -18,4 +18,6 @@ import "./_version.js"; * @module workbox-cacheable-response */ -export { CacheableResponse, CacheableResponseOptions, CacheableResponsePlugin }; +export { CacheableResponse, CacheableResponsePlugin }; + +export type { CacheableResponseOptions }; diff --git a/packages/serwiss/core/package.json b/packages/serwiss/core/package.json index 6b21f075..96ceeb77 100644 --- a/packages/serwiss/core/package.json +++ b/packages/serwiss/core/package.json @@ -19,5 +19,10 @@ }, "main": "index.js", "module": "index.mjs", - "types": "index.d.ts" + "types": "index.d.ts", + "exports": { + ".": "./src/index.ts", + "./_private/*.js": "./src/_private/*.ts", + "./types": "./src/types.ts" + } } diff --git a/packages/serwiss/expiration/package.json b/packages/serwiss/expiration/package.json index 3e0b7080..f5abd2c1 100644 --- a/packages/serwiss/expiration/package.json +++ b/packages/serwiss/expiration/package.json @@ -1,6 +1,7 @@ { "name": "@serwiss/expiration", "version": "7.0.0", + "type": "module", "license": "MIT", "author": "Google's Web DevRel Team, DuCanhGH", "description": "A service worker helper library that expires cached responses based on age or maximum number of entries.", @@ -21,6 +22,9 @@ "main": "index.js", "module": "index.mjs", "types": "index.d.ts", + "exports": { + ".": "./src/index.ts" + }, "dependencies": { "@serwiss/core": "workspace:*", "idb": "7.1.1" diff --git a/packages/serwiss/expiration/src/CacheExpiration.ts b/packages/serwiss/expiration/src/CacheExpiration.ts index a2c0a4da..602aae4b 100644 --- a/packages/serwiss/expiration/src/CacheExpiration.ts +++ b/packages/serwiss/expiration/src/CacheExpiration.ts @@ -6,10 +6,10 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { dontWaitFor } from "@serwiss/core/_private/dontWaitFor.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { CacheTimestampsModel } from "./models/CacheTimestampsModel.js"; diff --git a/packages/serwiss/expiration/src/ExpirationPlugin.ts b/packages/serwiss/expiration/src/ExpirationPlugin.ts index 07eee351..af9d6f8e 100644 --- a/packages/serwiss/expiration/src/ExpirationPlugin.ts +++ b/packages/serwiss/expiration/src/ExpirationPlugin.ts @@ -6,14 +6,14 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { cacheNames } from "workbox-core/_private/cacheNames.js"; -import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { registerQuotaErrorCallback } from "workbox-core/registerQuotaErrorCallback.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { WorkboxPlugin } from "workbox-core/types.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { cacheNames } from "@serwiss/core/_private/cacheNames.js"; +import { dontWaitFor } from "@serwiss/core/_private/dontWaitFor.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { registerQuotaErrorCallback } from "@serwiss/core"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { WorkboxPlugin } from "@serwiss/core/types"; import { CacheExpiration } from "./CacheExpiration.js"; diff --git a/packages/serwiss/expiration/src/index.ts b/packages/serwiss/expiration/src/index.ts index d7d8ab42..bd3b295b 100644 --- a/packages/serwiss/expiration/src/index.ts +++ b/packages/serwiss/expiration/src/index.ts @@ -18,4 +18,6 @@ import "./_version.js"; * @module workbox-expiration */ -export { CacheExpiration, ExpirationPlugin, ExpirationPluginOptions }; +export { CacheExpiration, ExpirationPlugin }; + +export type { ExpirationPluginOptions }; diff --git a/packages/serwiss/google-analytics/package.json b/packages/serwiss/google-analytics/package.json index 1e381a29..16073e90 100644 --- a/packages/serwiss/google-analytics/package.json +++ b/packages/serwiss/google-analytics/package.json @@ -2,6 +2,7 @@ "name": "@serwiss/google-analytics", "version": "7.0.0", "license": "MIT", + "type": "module", "author": "Google's Web DevRel Team, DuCanhGH", "description": "Queues failed requests and uses the Background Sync API to replay them when the network is available", "repository": "DuCanhGH/next-pwa", @@ -24,6 +25,9 @@ "main": "index.js", "module": "index.mjs", "types": "index.d.ts", + "exports": { + "./initialize": "./src/initialize.ts" + }, "dependencies": { "@serwiss/background-sync": "workspace:*", "@serwiss/core": "workspace:*", diff --git a/packages/serwiss/google-analytics/src/initialize.ts b/packages/serwiss/google-analytics/src/initialize.ts index cdcc8903..847895f8 100644 --- a/packages/serwiss/google-analytics/src/initialize.ts +++ b/packages/serwiss/google-analytics/src/initialize.ts @@ -6,16 +6,16 @@ https://opensource.org/licenses/MIT. */ -import { BackgroundSyncPlugin } from "workbox-background-sync/BackgroundSyncPlugin.js"; -import { Queue } from "workbox-background-sync/Queue.js"; -import { cacheNames } from "workbox-core/_private/cacheNames.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { RouteMatchCallbackOptions } from "workbox-core/types.js"; -import { Route } from "workbox-routing/Route.js"; -import { Router } from "workbox-routing/Router.js"; -import { NetworkFirst } from "workbox-strategies/NetworkFirst.js"; -import { NetworkOnly } from "workbox-strategies/NetworkOnly.js"; +import { BackgroundSyncPlugin } from "@serwiss/background-sync"; +import { Queue } from "@serwiss/background-sync/queue"; +import { cacheNames } from "@serwiss/core/_private/cacheNames.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { RouteMatchCallbackOptions } from "@serwiss/core/types"; +import { Route } from "@serwiss/routing/Route.js"; +import { Router } from "@serwiss/routing/Router.js"; +import { NetworkFirst } from "@serwiss/strategies/NetworkFirst.js"; +import { NetworkOnly } from "@serwiss/strategies/NetworkOnly.js"; import { QUEUE_NAME, MAX_RETENTION_TIME, diff --git a/packages/serwiss/navigation-preload/src/disable.ts b/packages/serwiss/navigation-preload/src/disable.ts index 654b0435..414eb4b8 100644 --- a/packages/serwiss/navigation-preload/src/disable.ts +++ b/packages/serwiss/navigation-preload/src/disable.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { isSupported } from "./isSupported.js"; import "./_version.js"; diff --git a/packages/serwiss/navigation-preload/src/enable.ts b/packages/serwiss/navigation-preload/src/enable.ts index 31b1fa78..f5a622bb 100644 --- a/packages/serwiss/navigation-preload/src/enable.ts +++ b/packages/serwiss/navigation-preload/src/enable.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { isSupported } from "./isSupported.js"; import "./_version.js"; diff --git a/packages/serwiss/precaching/src/PrecacheController.ts b/packages/serwiss/precaching/src/PrecacheController.ts index 6e2cca4a..d45c3e60 100644 --- a/packages/serwiss/precaching/src/PrecacheController.ts +++ b/packages/serwiss/precaching/src/PrecacheController.ts @@ -6,13 +6,13 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { cacheNames } from "workbox-core/_private/cacheNames.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { waitUntil } from "workbox-core/_private/waitUntil.js"; -import { Strategy } from "workbox-strategies/Strategy.js"; -import { RouteHandlerCallback, WorkboxPlugin } from "workbox-core/types.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { cacheNames } from "@serwiss/core/_private/cacheNames.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { waitUntil } from "@serwiss/core/_private/waitUntil.js"; +import { Strategy } from "@serwiss/strategies/Strategy.js"; +import { RouteHandlerCallback, WorkboxPlugin } from "@serwiss/core/types.js"; import { createCacheKey } from "./utils/createCacheKey.js"; import { PrecacheInstallReportPlugin } from "./utils/PrecacheInstallReportPlugin.js"; diff --git a/packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts b/packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts index 0768bafd..54de237d 100644 --- a/packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts +++ b/packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxPlugin } from "workbox-core/types.js"; +import { WorkboxPlugin } from "@serwiss/core/types.js"; import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; import { PrecacheController } from "./PrecacheController.js"; diff --git a/packages/serwiss/precaching/src/PrecacheRoute.ts b/packages/serwiss/precaching/src/PrecacheRoute.ts index 3c63f786..05748d1b 100644 --- a/packages/serwiss/precaching/src/PrecacheRoute.ts +++ b/packages/serwiss/precaching/src/PrecacheRoute.ts @@ -6,13 +6,13 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; import { RouteMatchCallback, RouteMatchCallbackOptions, -} from "workbox-core/types.js"; -import { Route } from "workbox-routing/Route.js"; +} from "@serwiss/core/types.js"; +import { Route } from "@serwiss/routing/Route.js"; import { PrecacheRouteOptions } from "./_types.js"; import { PrecacheController } from "./PrecacheController.js"; diff --git a/packages/serwiss/precaching/src/PrecacheStrategy.ts b/packages/serwiss/precaching/src/PrecacheStrategy.ts index 5ce2ef10..d707b2c4 100644 --- a/packages/serwiss/precaching/src/PrecacheStrategy.ts +++ b/packages/serwiss/precaching/src/PrecacheStrategy.ts @@ -6,14 +6,14 @@ https://opensource.org/licenses/MIT. */ -import { copyResponse } from "workbox-core/copyResponse.js"; -import { cacheNames } from "workbox-core/_private/cacheNames.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { WorkboxPlugin } from "workbox-core/types.js"; -import { Strategy, StrategyOptions } from "workbox-strategies/Strategy.js"; -import { StrategyHandler } from "workbox-strategies/StrategyHandler.js"; +import { copyResponse } from "@serwiss/core/copyResponse.js"; +import { cacheNames } from "@serwiss/core/_private/cacheNames.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { WorkboxPlugin } from "@serwiss/core/types.js"; +import { Strategy, StrategyOptions } from "@serwiss/strategies/Strategy.js"; +import { StrategyHandler } from "@serwiss/strategies/StrategyHandler.js"; import "./_version.js"; diff --git a/packages/serwiss/precaching/src/addPlugins.ts b/packages/serwiss/precaching/src/addPlugins.ts index b1b5e668..0c6750f9 100644 --- a/packages/serwiss/precaching/src/addPlugins.ts +++ b/packages/serwiss/precaching/src/addPlugins.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxPlugin } from "workbox-core/types.js"; +import { WorkboxPlugin } from "@serwiss/core/types.js"; import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; import "./_version.js"; diff --git a/packages/serwiss/precaching/src/addRoute.ts b/packages/serwiss/precaching/src/addRoute.ts index 236c3de9..2fbf8ac0 100644 --- a/packages/serwiss/precaching/src/addRoute.ts +++ b/packages/serwiss/precaching/src/addRoute.ts @@ -5,7 +5,7 @@ https://opensource.org/licenses/MIT. */ -import { registerRoute } from "workbox-routing/registerRoute.js"; +import { registerRoute } from "@serwiss/routing/registerRoute.js"; import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; import { PrecacheRoute } from "./PrecacheRoute.js"; diff --git a/packages/serwiss/precaching/src/cleanupOutdatedCaches.ts b/packages/serwiss/precaching/src/cleanupOutdatedCaches.ts index b887cdcb..a2c4992c 100644 --- a/packages/serwiss/precaching/src/cleanupOutdatedCaches.ts +++ b/packages/serwiss/precaching/src/cleanupOutdatedCaches.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { cacheNames } from "workbox-core/_private/cacheNames.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { cacheNames } from "@serwiss/core/_private/cacheNames.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { deleteOutdatedCaches } from "./utils/deleteOutdatedCaches.js"; import "./_version.js"; diff --git a/packages/serwiss/precaching/src/createHandlerBoundToURL.ts b/packages/serwiss/precaching/src/createHandlerBoundToURL.ts index 8b55e6cc..f10290fe 100644 --- a/packages/serwiss/precaching/src/createHandlerBoundToURL.ts +++ b/packages/serwiss/precaching/src/createHandlerBoundToURL.ts @@ -7,7 +7,7 @@ */ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js"; -import { RouteHandlerCallback } from "workbox-core/types.js"; +import { RouteHandlerCallback } from "@serwiss/core/types.js"; import "./_version.js"; /** diff --git a/packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts b/packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts index 9233894f..0eed22a0 100644 --- a/packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts +++ b/packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts @@ -9,7 +9,7 @@ import { WorkboxPlugin, WorkboxPluginCallbackParam, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import { PrecacheController } from "../PrecacheController.js"; diff --git a/packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts b/packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts index 473fdcde..8c5e16d8 100644 --- a/packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts +++ b/packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts @@ -9,7 +9,7 @@ import { WorkboxPlugin, WorkboxPluginCallbackParam, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import "../_version.js"; diff --git a/packages/serwiss/precaching/src/utils/createCacheKey.ts b/packages/serwiss/precaching/src/utils/createCacheKey.ts index 5a92da2a..7055fd23 100644 --- a/packages/serwiss/precaching/src/utils/createCacheKey.ts +++ b/packages/serwiss/precaching/src/utils/createCacheKey.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { PrecacheEntry } from "../_types.js"; import "../_version.js"; diff --git a/packages/serwiss/precaching/src/utils/printCleanupDetails.ts b/packages/serwiss/precaching/src/utils/printCleanupDetails.ts index 070a809e..77da0910 100644 --- a/packages/serwiss/precaching/src/utils/printCleanupDetails.ts +++ b/packages/serwiss/precaching/src/utils/printCleanupDetails.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import "../_version.js"; /** diff --git a/packages/serwiss/precaching/src/utils/printInstallDetails.ts b/packages/serwiss/precaching/src/utils/printInstallDetails.ts index 88e99002..3f465a69 100644 --- a/packages/serwiss/precaching/src/utils/printInstallDetails.ts +++ b/packages/serwiss/precaching/src/utils/printInstallDetails.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import "../_version.js"; /** diff --git a/packages/serwiss/range-requests/src/RangeRequestsPlugin.ts b/packages/serwiss/range-requests/src/RangeRequestsPlugin.ts index 8549b384..6b24525e 100644 --- a/packages/serwiss/range-requests/src/RangeRequestsPlugin.ts +++ b/packages/serwiss/range-requests/src/RangeRequestsPlugin.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxPlugin } from "workbox-core/types.js"; +import { WorkboxPlugin } from "@serwiss/core/types.js"; import { createPartialResponse } from "./createPartialResponse.js"; import "./_version.js"; diff --git a/packages/serwiss/range-requests/src/createPartialResponse.ts b/packages/serwiss/range-requests/src/createPartialResponse.ts index ba567fcf..b270f864 100644 --- a/packages/serwiss/range-requests/src/createPartialResponse.ts +++ b/packages/serwiss/range-requests/src/createPartialResponse.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { calculateEffectiveBoundaries } from "./utils/calculateEffectiveBoundaries.js"; import { parseRangeHeader } from "./utils/parseRangeHeader.js"; import "./_version.js"; diff --git a/packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts b/packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts index 3b940900..0da313be 100644 --- a/packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts +++ b/packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { assert } from "workbox-core/_private/assert.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; import "../_version.js"; /** diff --git a/packages/serwiss/range-requests/src/utils/parseRangeHeader.ts b/packages/serwiss/range-requests/src/utils/parseRangeHeader.ts index 17f99ac3..2da8d4cc 100644 --- a/packages/serwiss/range-requests/src/utils/parseRangeHeader.ts +++ b/packages/serwiss/range-requests/src/utils/parseRangeHeader.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { assert } from "workbox-core/_private/assert.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; import "../_version.js"; /** diff --git a/packages/serwiss/recipes/src/googleFontsCache.ts b/packages/serwiss/recipes/src/googleFontsCache.ts index 04213339..b15d10e9 100644 --- a/packages/serwiss/recipes/src/googleFontsCache.ts +++ b/packages/serwiss/recipes/src/googleFontsCache.ts @@ -5,11 +5,11 @@ license that can be found in the LICENSE file or at https://opensource.org/licenses/MIT. */ -import { registerRoute } from "workbox-routing/registerRoute.js"; -import { StaleWhileRevalidate } from "workbox-strategies/StaleWhileRevalidate.js"; -import { CacheFirst } from "workbox-strategies/CacheFirst.js"; -import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; -import { ExpirationPlugin } from "workbox-expiration/ExpirationPlugin.js"; +import { registerRoute } from "@serwiss/routing/registerRoute.js"; +import { StaleWhileRevalidate } from "@serwiss/strategies/StaleWhileRevalidate.js"; +import { CacheFirst } from "@serwiss/strategies/CacheFirst.js"; +import { CacheableResponsePlugin } from "@serwiss/cacheable-response/CacheableResponsePlugin.js"; +import { ExpirationPlugin } from "@serwiss/expiration/ExpirationPlugin.js"; import "./_version.js"; diff --git a/packages/serwiss/recipes/src/imageCache.ts b/packages/serwiss/recipes/src/imageCache.ts index 66f04d9a..c44f46b8 100644 --- a/packages/serwiss/recipes/src/imageCache.ts +++ b/packages/serwiss/recipes/src/imageCache.ts @@ -6,15 +6,15 @@ https://opensource.org/licenses/MIT. */ import { warmStrategyCache } from "./warmStrategyCache"; -import { registerRoute } from "workbox-routing/registerRoute.js"; -import { CacheFirst } from "workbox-strategies/CacheFirst.js"; -import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; -import { ExpirationPlugin } from "workbox-expiration/ExpirationPlugin.js"; +import { registerRoute } from "@serwiss/routing/registerRoute.js"; +import { CacheFirst } from "@serwiss/strategies/CacheFirst.js"; +import { CacheableResponsePlugin } from "@serwiss/cacheable-response/CacheableResponsePlugin.js"; +import { ExpirationPlugin } from "@serwiss/expiration/ExpirationPlugin.js"; import { RouteMatchCallback, RouteMatchCallbackOptions, WorkboxPlugin, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import "./_version.js"; diff --git a/packages/serwiss/recipes/src/offlineFallback.ts b/packages/serwiss/recipes/src/offlineFallback.ts index 29ddf016..988e8c9a 100644 --- a/packages/serwiss/recipes/src/offlineFallback.ts +++ b/packages/serwiss/recipes/src/offlineFallback.ts @@ -5,12 +5,12 @@ license that can be found in the LICENSE file or at https://opensource.org/licenses/MIT. */ -import { setCatchHandler } from "workbox-routing/setCatchHandler.js"; -import { matchPrecache } from "workbox-precaching/matchPrecache.js"; +import { setCatchHandler } from "@serwiss/routing/setCatchHandler.js"; +import { matchPrecache } from "@serwiss/precaching/matchPrecache.js"; import { RouteHandler, RouteHandlerCallbackOptions, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import "./_version.js"; diff --git a/packages/serwiss/recipes/src/pageCache.ts b/packages/serwiss/recipes/src/pageCache.ts index 4190fe91..3d09311e 100644 --- a/packages/serwiss/recipes/src/pageCache.ts +++ b/packages/serwiss/recipes/src/pageCache.ts @@ -6,14 +6,14 @@ https://opensource.org/licenses/MIT. */ import { warmStrategyCache } from "./warmStrategyCache"; -import { registerRoute } from "workbox-routing/registerRoute.js"; -import { NetworkFirst } from "workbox-strategies/NetworkFirst.js"; -import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; +import { registerRoute } from "@serwiss/routing/registerRoute.js"; +import { NetworkFirst } from "@serwiss/strategies/NetworkFirst.js"; +import { CacheableResponsePlugin } from "@serwiss/cacheable-response/CacheableResponsePlugin.js"; import { RouteMatchCallback, RouteMatchCallbackOptions, WorkboxPlugin, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import "./_version.js"; diff --git a/packages/serwiss/recipes/src/staticResourceCache.ts b/packages/serwiss/recipes/src/staticResourceCache.ts index 118eeff8..86f17e53 100644 --- a/packages/serwiss/recipes/src/staticResourceCache.ts +++ b/packages/serwiss/recipes/src/staticResourceCache.ts @@ -6,14 +6,14 @@ https://opensource.org/licenses/MIT. */ import { warmStrategyCache } from "./warmStrategyCache"; -import { registerRoute } from "workbox-routing/registerRoute.js"; -import { StaleWhileRevalidate } from "workbox-strategies/StaleWhileRevalidate.js"; -import { CacheableResponsePlugin } from "workbox-cacheable-response/CacheableResponsePlugin.js"; +import { registerRoute } from "@serwiss/routing/registerRoute.js"; +import { StaleWhileRevalidate } from "@serwiss/strategies/StaleWhileRevalidate.js"; +import { CacheableResponsePlugin } from "@serwiss/cacheable-response/CacheableResponsePlugin.js"; import { RouteMatchCallback, RouteMatchCallbackOptions, WorkboxPlugin, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import "./_version.js"; diff --git a/packages/serwiss/recipes/src/warmStrategyCache.ts b/packages/serwiss/recipes/src/warmStrategyCache.ts index bf6a4dc5..d299079a 100644 --- a/packages/serwiss/recipes/src/warmStrategyCache.ts +++ b/packages/serwiss/recipes/src/warmStrategyCache.ts @@ -1,4 +1,4 @@ -import { Strategy } from "workbox-strategies/Strategy.js"; +import { Strategy } from "@serwiss/strategies/Strategy.js"; import "./_version.js"; diff --git a/packages/serwiss/routing/package.json b/packages/serwiss/routing/package.json index aa520e2c..9f415891 100644 --- a/packages/serwiss/routing/package.json +++ b/packages/serwiss/routing/package.json @@ -22,6 +22,9 @@ "main": "index.js", "module": "index.mjs", "types": "index.d.ts", + "exports": { + ".": "./src/index.ts" + }, "dependencies": { "@serwiss/core": "workspace:*" } diff --git a/packages/serwiss/routing/src/NavigationRoute.ts b/packages/serwiss/routing/src/NavigationRoute.ts index a1fc9f63..46a169cf 100644 --- a/packages/serwiss/routing/src/NavigationRoute.ts +++ b/packages/serwiss/routing/src/NavigationRoute.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { RouteHandler, RouteMatchCallbackOptions } from "workbox-core/types.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { RouteHandler, RouteMatchCallbackOptions } from "@serwiss/core/types"; import { Route } from "./Route.js"; diff --git a/packages/serwiss/routing/src/RegExpRoute.ts b/packages/serwiss/routing/src/RegExpRoute.ts index 5480377e..1f3a31da 100644 --- a/packages/serwiss/routing/src/RegExpRoute.ts +++ b/packages/serwiss/routing/src/RegExpRoute.ts @@ -6,13 +6,13 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { RouteHandler, RouteMatchCallback, RouteMatchCallbackOptions, -} from "workbox-core/types.js"; +} from "@serwiss/core/types"; import { HTTPMethod } from "./utils/constants.js"; import { Route } from "./Route.js"; diff --git a/packages/serwiss/routing/src/Route.ts b/packages/serwiss/routing/src/Route.ts index 3866279a..020e7b0a 100644 --- a/packages/serwiss/routing/src/Route.ts +++ b/packages/serwiss/routing/src/Route.ts @@ -6,14 +6,14 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; +import { assert } from "@serwiss/core/_private/assert.js"; import { HTTPMethod, defaultMethod, validMethods } from "./utils/constants.js"; import { normalizeHandler } from "./utils/normalizeHandler.js"; import { RouteHandler, RouteHandlerObject, RouteMatchCallback, -} from "workbox-core/types.js"; +} from "@serwiss/core/types"; import "./_version.js"; /** diff --git a/packages/serwiss/routing/src/Router.ts b/packages/serwiss/routing/src/Router.ts index 23148c3e..3c43b5be 100644 --- a/packages/serwiss/routing/src/Router.ts +++ b/packages/serwiss/routing/src/Router.ts @@ -6,19 +6,19 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; import { RouteHandler, RouteHandlerObject, RouteHandlerCallbackOptions, RouteMatchCallbackOptions, -} from "workbox-core/types.js"; +} from "@serwiss/core/types"; import { HTTPMethod, defaultMethod } from "./utils/constants.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { normalizeHandler } from "./utils/normalizeHandler.js"; import { Route } from "./Route.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import "./_version.js"; diff --git a/packages/serwiss/routing/src/index.ts b/packages/serwiss/routing/src/index.ts index 389b313e..a3191315 100644 --- a/packages/serwiss/routing/src/index.ts +++ b/packages/serwiss/routing/src/index.ts @@ -16,6 +16,7 @@ import { Route } from "./Route.js"; import { Router } from "./Router.js"; import { setCatchHandler } from "./setCatchHandler.js"; import { setDefaultHandler } from "./setDefaultHandler.js"; +import type { HTTPMethod } from "./utils/constants.js"; import "./_version.js"; @@ -31,5 +32,6 @@ export { Router, setCatchHandler, setDefaultHandler, - NavigationRouteMatchOptions, }; + +export type { NavigationRouteMatchOptions, HTTPMethod }; diff --git a/packages/serwiss/routing/src/registerRoute.ts b/packages/serwiss/routing/src/registerRoute.ts index 97bdb68c..0278b246 100644 --- a/packages/serwiss/routing/src/registerRoute.ts +++ b/packages/serwiss/routing/src/registerRoute.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { RouteHandler, RouteMatchCallback } from "workbox-core/types.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { RouteHandler, RouteMatchCallback } from "@serwiss/core/types"; import { Route } from "./Route.js"; import { RegExpRoute } from "./RegExpRoute.js"; diff --git a/packages/serwiss/routing/src/setCatchHandler.ts b/packages/serwiss/routing/src/setCatchHandler.ts index 24d586cd..65e95292 100644 --- a/packages/serwiss/routing/src/setCatchHandler.ts +++ b/packages/serwiss/routing/src/setCatchHandler.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { RouteHandler } from "workbox-core/types.js"; +import { RouteHandler } from "@serwiss/core/types"; import { getOrCreateDefaultRouter } from "./utils/getOrCreateDefaultRouter.js"; diff --git a/packages/serwiss/routing/src/setDefaultHandler.ts b/packages/serwiss/routing/src/setDefaultHandler.ts index a125ef44..419b8871 100644 --- a/packages/serwiss/routing/src/setDefaultHandler.ts +++ b/packages/serwiss/routing/src/setDefaultHandler.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { RouteHandler } from "workbox-core/types.js"; +import { RouteHandler } from "@serwiss/core/types"; import { getOrCreateDefaultRouter } from "./utils/getOrCreateDefaultRouter.js"; diff --git a/packages/serwiss/routing/src/utils/normalizeHandler.ts b/packages/serwiss/routing/src/utils/normalizeHandler.ts index 8924ce51..6a0f8db6 100644 --- a/packages/serwiss/routing/src/utils/normalizeHandler.ts +++ b/packages/serwiss/routing/src/utils/normalizeHandler.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { RouteHandler, RouteHandlerObject } from "workbox-core/types.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { RouteHandler, RouteHandlerObject } from "@serwiss/core/types"; import "../_version.js"; diff --git a/packages/serwiss/strategies/src/CacheFirst.ts b/packages/serwiss/strategies/src/CacheFirst.ts index 511b8381..4e709bf9 100644 --- a/packages/serwiss/strategies/src/CacheFirst.ts +++ b/packages/serwiss/strategies/src/CacheFirst.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { Strategy } from "./Strategy.js"; import { StrategyHandler } from "./StrategyHandler.js"; diff --git a/packages/serwiss/strategies/src/CacheOnly.ts b/packages/serwiss/strategies/src/CacheOnly.ts index 3c211e95..a762c128 100644 --- a/packages/serwiss/strategies/src/CacheOnly.ts +++ b/packages/serwiss/strategies/src/CacheOnly.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { Strategy } from "./Strategy.js"; import { StrategyHandler } from "./StrategyHandler.js"; diff --git a/packages/serwiss/strategies/src/NetworkFirst.ts b/packages/serwiss/strategies/src/NetworkFirst.ts index 83e79039..176bb011 100644 --- a/packages/serwiss/strategies/src/NetworkFirst.ts +++ b/packages/serwiss/strategies/src/NetworkFirst.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { cacheOkAndOpaquePlugin } from "./plugins/cacheOkAndOpaquePlugin.js"; import { Strategy, StrategyOptions } from "./Strategy.js"; diff --git a/packages/serwiss/strategies/src/NetworkOnly.ts b/packages/serwiss/strategies/src/NetworkOnly.ts index a18ace0a..b8593b2b 100644 --- a/packages/serwiss/strategies/src/NetworkOnly.ts +++ b/packages/serwiss/strategies/src/NetworkOnly.ts @@ -6,10 +6,10 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { timeout } from "workbox-core/_private/timeout.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { timeout } from "@serwiss/core/_private/timeout.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { Strategy, StrategyOptions } from "./Strategy.js"; import { StrategyHandler } from "./StrategyHandler.js"; diff --git a/packages/serwiss/strategies/src/StaleWhileRevalidate.ts b/packages/serwiss/strategies/src/StaleWhileRevalidate.ts index 40fa28e6..43a45d1f 100644 --- a/packages/serwiss/strategies/src/StaleWhileRevalidate.ts +++ b/packages/serwiss/strategies/src/StaleWhileRevalidate.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { cacheOkAndOpaquePlugin } from "./plugins/cacheOkAndOpaquePlugin.js"; import { Strategy, StrategyOptions } from "./Strategy.js"; diff --git a/packages/serwiss/strategies/src/Strategy.ts b/packages/serwiss/strategies/src/Strategy.ts index e38dc839..b858e03c 100644 --- a/packages/serwiss/strategies/src/Strategy.ts +++ b/packages/serwiss/strategies/src/Strategy.ts @@ -6,15 +6,15 @@ https://opensource.org/licenses/MIT. */ -import { cacheNames } from "workbox-core/_private/cacheNames.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { cacheNames } from "@serwiss/core/_private/cacheNames.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; import { HandlerCallbackOptions, RouteHandlerObject, WorkboxPlugin, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import { StrategyHandler } from "./StrategyHandler.js"; diff --git a/packages/serwiss/strategies/src/StrategyHandler.ts b/packages/serwiss/strategies/src/StrategyHandler.ts index 87bc26b2..c825c08e 100644 --- a/packages/serwiss/strategies/src/StrategyHandler.ts +++ b/packages/serwiss/strategies/src/StrategyHandler.ts @@ -6,20 +6,20 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { cacheMatchIgnoreParams } from "workbox-core/_private/cacheMatchIgnoreParams.js"; -import { Deferred } from "workbox-core/_private/Deferred.js"; -import { executeQuotaErrorCallbacks } from "workbox-core/_private/executeQuotaErrorCallbacks.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; -import { logger } from "workbox-core/_private/logger.js"; -import { timeout } from "workbox-core/_private/timeout.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { cacheMatchIgnoreParams } from "@serwiss/core/_private/cacheMatchIgnoreParams.js"; +import { Deferred } from "@serwiss/core/_private/Deferred.js"; +import { executeQuotaErrorCallbacks } from "@serwiss/core/_private/executeQuotaErrorCallbacks.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { timeout } from "@serwiss/core/_private/timeout.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import { HandlerCallbackOptions, MapLikeObject, WorkboxPlugin, WorkboxPluginCallbackParam, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import { Strategy } from "./Strategy.js"; import "./_version.js"; diff --git a/packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts b/packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts index 298330bb..f1ce8652 100644 --- a/packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts +++ b/packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { WorkboxPlugin } from "workbox-core/types.js"; +import { WorkboxPlugin } from "@serwiss/core/types.js"; import "../_version.js"; export const cacheOkAndOpaquePlugin: WorkboxPlugin = { diff --git a/packages/serwiss/strategies/src/utils/messages.ts b/packages/serwiss/strategies/src/utils/messages.ts index 7c353fea..102a90df 100644 --- a/packages/serwiss/strategies/src/utils/messages.ts +++ b/packages/serwiss/strategies/src/utils/messages.ts @@ -6,8 +6,8 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; -import { getFriendlyURL } from "workbox-core/_private/getFriendlyURL.js"; +import { logger } from "@serwiss/core/_private/logger.js"; +import { getFriendlyURL } from "@serwiss/core/_private/getFriendlyURL.js"; import "../_version.js"; export const messages = { diff --git a/packages/serwiss/streams/src/concatenate.ts b/packages/serwiss/streams/src/concatenate.ts index 39cb555e..a406c467 100644 --- a/packages/serwiss/streams/src/concatenate.ts +++ b/packages/serwiss/streams/src/concatenate.ts @@ -6,11 +6,11 @@ https://opensource.org/licenses/MIT. */ -import { assert } from "workbox-core/_private/assert.js"; -import { Deferred } from "workbox-core/_private/Deferred.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { assert } from "@serwiss/core/_private/assert.js"; +import { Deferred } from "@serwiss/core/_private/Deferred.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { StreamSource } from "./_types.js"; -import { WorkboxError } from "workbox-core/_private/WorkboxError.js"; +import { WorkboxError } from "@serwiss/core/_private/WorkboxError.js"; import "./_version.js"; diff --git a/packages/serwiss/streams/src/isSupported.ts b/packages/serwiss/streams/src/isSupported.ts index 81e138df..e92e5692 100644 --- a/packages/serwiss/streams/src/isSupported.ts +++ b/packages/serwiss/streams/src/isSupported.ts @@ -6,7 +6,7 @@ https://opensource.org/licenses/MIT. */ -import { canConstructReadableStream } from "workbox-core/_private/canConstructReadableStream.js"; +import { canConstructReadableStream } from "@serwiss/core/_private/canConstructReadableStream.js"; import "./_version.js"; /** diff --git a/packages/serwiss/streams/src/strategy.ts b/packages/serwiss/streams/src/strategy.ts index 7d888fbb..24474b3f 100644 --- a/packages/serwiss/streams/src/strategy.ts +++ b/packages/serwiss/streams/src/strategy.ts @@ -6,11 +6,11 @@ https://opensource.org/licenses/MIT. */ -import { logger } from "workbox-core/_private/logger.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { RouteHandlerCallback, RouteHandlerCallbackOptions, -} from "workbox-core/types.js"; +} from "@serwiss/core/types.js"; import { createHeaders } from "./utils/createHeaders.js"; import { concatenateToResponse } from "./concatenateToResponse.js"; import { isSupported } from "./isSupported.js"; diff --git a/packages/serwiss/window/src/Workbox.ts b/packages/serwiss/window/src/Workbox.ts index 40326c4a..9a522aab 100644 --- a/packages/serwiss/window/src/Workbox.ts +++ b/packages/serwiss/window/src/Workbox.ts @@ -6,9 +6,9 @@ https://opensource.org/licenses/MIT. */ -import { Deferred } from "workbox-core/_private/Deferred.js"; -import { dontWaitFor } from "workbox-core/_private/dontWaitFor.js"; -import { logger } from "workbox-core/_private/logger.js"; +import { Deferred } from "@serwiss/core/_private/Deferred.js"; +import { dontWaitFor } from "@serwiss/core/_private/dontWaitFor.js"; +import { logger } from "@serwiss/core/_private/logger.js"; import { TrustedScriptURL } from "trusted-types/lib"; import { messageSW } from "./messageSW.js"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09a1d482..fbb2f2af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -816,9 +816,24 @@ importers: specifier: 2.0.1 version: 2.0.1 devDependencies: + '@types/common-tags': + specifier: 1.8.3 + version: 1.8.3 + '@types/fs-extra': + specifier: 11.0.2 + version: 11.0.2 + '@types/lodash': + specifier: 4.14.200 + version: 4.14.200 '@types/node': specifier: 20.8.7 version: 20.8.7 + '@types/stringify-object': + specifier: 4.0.3 + version: 4.0.3 + type-fest: + specifier: 4.4.0 + version: 4.4.0 packages/serwiss/cacheable-response: dependencies: @@ -5439,6 +5454,10 @@ packages: '@types/node': 20.8.7 dev: true + /@types/lodash@4.14.200: + resolution: {integrity: sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==} + dev: true + /@types/long@4.0.2: resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} dev: false From 75b1ab529894e350ac4a0c8b6f61dae604bd69b5 Mon Sep 17 00:00:00 2001 From: DuCanhGH <75556609+DuCanhGH@users.noreply.github.com> Date: Wed, 18 Oct 2023 22:56:35 +0700 Subject: [PATCH 4/9] chore: remove next-sw --- examples/workboxless/.gitignore | 44 - examples/workboxless/README.md | 35 - .../workboxless/app/appdir/about/Button.tsx | 7 - .../workboxless/app/appdir/about/page.tsx | 13 - examples/workboxless/app/appdir/page.tsx | 15 - examples/workboxless/app/layout.tsx | 49 - examples/workboxless/app/~offline/page.tsx | 14 - examples/workboxless/next.config.js | 8 - examples/workboxless/package.json | 23 - examples/workboxless/pages/_app.tsx | 31 - examples/workboxless/pages/_document.tsx | 25 - examples/workboxless/pages/api/hello.ts | 13 - examples/workboxless/pages/index.tsx | 12 - examples/workboxless/public/favicon.ico | Bin 25931 -> 0 bytes .../public/icons/android-chrome-192x192.png | Bin 5629 -> 0 bytes .../public/icons/apple-touch-icon.png | Bin 3996 -> 0 bytes .../workboxless/public/icons/icon-512x512.png | Bin 14584 -> 0 bytes examples/workboxless/public/manifest.json | 22 - examples/workboxless/tsconfig.json | 25 - package.json | 1 - packages/next-sw/CHANGELOG.md | 34 - packages/next-sw/README.md | 37 - packages/next-sw/globals.d.ts | 10 - packages/next-sw/package.json | 66 - packages/next-sw/rollup.config.js | 122 - packages/next-sw/src/.swcrc.json | 24 - .../src/build/generate-sw/base-sw-utils.ts | 113 - .../next-sw/src/build/generate-sw/base-sw.ts | 132 -- .../src/build/generate-sw/core-utils.ts | 113 - .../next-sw/src/build/generate-sw/core.ts | 139 -- .../generate-sw/default-runtime-caching.ts | 183 -- .../get-manifest-entries-from-compilation.ts | 120 - .../next-sw/src/build/generate-sw/index.ts | 2 - .../generate-sw/runtime-caching-converter.ts | 58 - .../src/build/generate-sw/webpack-plugin.ts | 89 - packages/next-sw/src/index.ts | 174 -- packages/next-sw/src/private-types.ts | 10 - packages/next-sw/src/sw-entry.ts | 37 - packages/next-sw/src/swc-loader.ts | 1 - packages/next-sw/src/types.ts | 181 -- packages/next-sw/tsconfig.json | 9 - packages/serwiss/README.md | 17 - packages/serwiss/background-sync/README.md | 1 - packages/serwiss/background-sync/package.json | 35 - .../src/BackgroundSyncPlugin.ts | 43 - packages/serwiss/background-sync/src/Queue.ts | 487 ---- .../serwiss/background-sync/src/QueueStore.ts | 14 - .../background-sync/src/StorableRequest.ts | 14 - .../serwiss/background-sync/src/_version.ts | 4 - packages/serwiss/background-sync/src/index.ts | 42 - .../background-sync/src/lib/QueueDb.ts | 200 -- .../background-sync/src/lib/QueueStore.ts | 179 -- .../src/lib/StorableRequest.ts | 156 -- .../serwiss/background-sync/tsconfig.json | 7 - packages/serwiss/broadcast-update/README.md | 1 - .../serwiss/broadcast-update/package.json | 31 - .../src/BroadcastCacheUpdate.ts | 215 -- .../src/BroadcastUpdatePlugin.ts | 63 - .../serwiss/broadcast-update/src/_version.ts | 4 - .../serwiss/broadcast-update/src/index.ts | 24 - .../broadcast-update/src/responsesAreSame.ts | 72 - .../broadcast-update/src/utils/constants.ts | 18 - .../serwiss/broadcast-update/tsconfig.json | 7 - packages/serwiss/build/README.md | 1 - packages/serwiss/build/package.json | 75 - packages/serwiss/build/src/_types.js | 120 - packages/serwiss/build/src/cdn-details.json | 6 - packages/serwiss/build/src/generate-sw.ts | 117 - packages/serwiss/build/src/get-manifest.ts | 37 - packages/serwiss/build/src/index.ts | 26 - packages/serwiss/build/src/inject-manifest.ts | 162 -- .../additional-manifest-entries-transform.ts | 58 - packages/serwiss/build/src/lib/bundle.ts | 153 -- packages/serwiss/build/src/lib/cdn-utils.ts | 37 - .../build/src/lib/copy-workbox-libraries.ts | 84 - packages/serwiss/build/src/lib/errors.ts | 124 - .../serwiss/build/src/lib/escape-regexp.ts | 12 - .../build/src/lib/get-composite-details.ts | 34 - .../serwiss/build/src/lib/get-file-details.ts | 74 - .../serwiss/build/src/lib/get-file-hash.ts | 24 - .../src/lib/get-file-manifest-entries.ts | 121 - .../serwiss/build/src/lib/get-file-size.ts | 26 - .../build/src/lib/get-source-map-url.ts | 32 - .../build/src/lib/get-string-details.ts | 18 - .../serwiss/build/src/lib/get-string-hash.ts | 15 - .../build/src/lib/maximum-size-transform.ts | 33 - .../src/lib/modify-url-prefix-transform.ts | 61 - .../serwiss/build/src/lib/module-registry.ts | 76 - ...no-revision-for-urls-matching-transform.ts | 34 - .../build/src/lib/populate-sw-template.ts | 105 - packages/serwiss/build/src/lib/rebase-path.ts | 28 - .../src/lib/replace-and-update-source-map.ts | 127 -- .../src/lib/runtime-caching-converter.ts | 215 -- .../src/lib/stringify-without-comments.ts | 23 - .../build/src/lib/transform-manifest.ts | 162 -- .../lib/translate-url-to-sourcemap-paths.ts | 38 - .../serwiss/build/src/lib/validate-options.ts | 237 -- .../lib/write-sw-using-default-template.ts | 96 - .../src/rollup-plugin-off-main-thread.d.ts | 1 - .../build/src/schema/GenerateSWOptions.json | 872 -------- .../build/src/schema/GetManifestOptions.json | 164 -- .../src/schema/InjectManifestOptions.json | 179 -- .../src/schema/WebpackGenerateSWOptions.json | 850 ------- .../schema/WebpackInjectManifestOptions.json | 167 -- .../serwiss/build/src/strip-comments.d.ts | 1 - .../build/src/templates/sw-template.ts | 60 - packages/serwiss/build/src/types.ts | 590 ----- packages/serwiss/build/tsconfig.json | 7 - packages/serwiss/cacheable-response/README.md | 1 - .../serwiss/cacheable-response/package.json | 31 - .../src/CacheableResponse.ts | 150 -- .../src/CacheableResponsePlugin.ts | 58 - .../cacheable-response/src/_version.ts | 4 - .../serwiss/cacheable-response/src/index.ts | 23 - .../serwiss/cacheable-response/tsconfig.json | 7 - packages/serwiss/cli/README.md | 1 - packages/serwiss/cli/package.json | 53 - packages/serwiss/cli/src/app.ts | 156 -- packages/serwiss/cli/src/bin.ts | 46 - .../cli/src/lib/cleanup-stack-trace.ts | 30 - packages/serwiss/cli/src/lib/constants.ts | 14 - packages/serwiss/cli/src/lib/errors.ts | 35 - packages/serwiss/cli/src/lib/help-text.ts | 57 - packages/serwiss/cli/src/lib/logger.ts | 16 - .../src/lib/questions/ask-config-location.ts | 42 - .../lib/questions/ask-extensions-to-cache.ts | 109 - .../cli/src/lib/questions/ask-questions.ts | 56 - .../src/lib/questions/ask-root-of-web-app.ts | 100 - .../questions/ask-start_url-query-params.ts | 84 - .../cli/src/lib/questions/ask-sw-dest.ts | 43 - .../cli/src/lib/questions/ask-sw-src.ts | 35 - packages/serwiss/cli/src/lib/read-config.ts | 17 - packages/serwiss/cli/src/lib/run-wizard.ts | 37 - packages/serwiss/cli/tsconfig.json | 7 - packages/serwiss/core/README.md | 1 - packages/serwiss/core/package.json | 28 - packages/serwiss/core/src/_private.ts | 42 - .../serwiss/core/src/_private/Deferred.ts | 35 - .../serwiss/core/src/_private/WorkboxError.ts | 43 - packages/serwiss/core/src/_private/assert.ts | 100 - .../src/_private/cacheMatchIgnoreParams.ts | 56 - .../serwiss/core/src/_private/cacheNames.ts | 75 - .../_private/canConstructReadableStream.ts | 37 - .../canConstructResponseFromBodyStream.ts | 40 - .../serwiss/core/src/_private/dontWaitFor.ts | 18 - .../_private/executeQuotaErrorCallbacks.ts | 40 - .../core/src/_private/getFriendlyURL.ts | 18 - packages/serwiss/core/src/_private/logger.ts | 100 - .../src/_private/resultingClientExists.ts | 62 - packages/serwiss/core/src/_private/timeout.ts | 21 - .../serwiss/core/src/_private/waitUntil.ts | 28 - packages/serwiss/core/src/_version.ts | 4 - packages/serwiss/core/src/cacheNames.ts | 45 - packages/serwiss/core/src/clientsClaim.ts | 24 - packages/serwiss/core/src/copyResponse.ts | 70 - packages/serwiss/core/src/index.ts | 35 - .../src/models/messages/messageGenerator.ts | 30 - .../core/src/models/messages/messages.ts | 387 ---- .../serwiss/core/src/models/pluginEvents.ts | 19 - .../core/src/models/quotaErrorCallbacks.ts | 16 - .../core/src/registerQuotaErrorCallback.ts | 39 - .../serwiss/core/src/setCacheNameDetails.ts | 69 - packages/serwiss/core/src/skipWaiting.ts | 37 - packages/serwiss/core/src/types.ts | 282 --- .../serwiss/core/src/utils/pluginUtils.ts | 16 - packages/serwiss/core/src/utils/welcome.ts | 35 - packages/serwiss/core/tsconfig.json | 7 - packages/serwiss/expiration/README.md | 1 - packages/serwiss/expiration/package.json | 32 - .../serwiss/expiration/src/CacheExpiration.ts | 205 -- .../expiration/src/ExpirationPlugin.ts | 302 --- packages/serwiss/expiration/src/_version.ts | 4 - packages/serwiss/expiration/src/index.ts | 23 - .../src/models/CacheTimestampsModel.ts | 226 -- packages/serwiss/expiration/tsconfig.json | 7 - packages/serwiss/google-analytics/README.md | 1 - .../serwiss/google-analytics/package.json | 37 - .../serwiss/google-analytics/src/_version.ts | 4 - .../serwiss/google-analytics/src/index.ts | 17 - .../google-analytics/src/initialize.ts | 233 -- .../google-analytics/src/utils/constants.ts | 24 - .../serwiss/google-analytics/tsconfig.json | 7 - packages/serwiss/navigation-preload/README.md | 1 - .../serwiss/navigation-preload/package.json | 27 - .../navigation-preload/src/_version.ts | 4 - .../serwiss/navigation-preload/src/disable.ts | 39 - .../serwiss/navigation-preload/src/enable.ts | 51 - .../serwiss/navigation-preload/src/index.ts | 37 - .../navigation-preload/src/isSupported.ts | 24 - .../serwiss/navigation-preload/tsconfig.json | 7 - packages/serwiss/precaching/README.md | 1 - packages/serwiss/precaching/package.json | 28 - .../precaching/src/PrecacheController.ts | 366 --- .../precaching/src/PrecacheFallbackPlugin.ts | 65 - .../serwiss/precaching/src/PrecacheRoute.ts | 77 - .../precaching/src/PrecacheStrategy.ts | 287 --- packages/serwiss/precaching/src/_types.ts | 85 - packages/serwiss/precaching/src/_version.ts | 4 - packages/serwiss/precaching/src/addPlugins.ts | 25 - packages/serwiss/precaching/src/addRoute.ts | 38 - .../precaching/src/cleanupOutdatedCaches.ts | 41 - .../precaching/src/createHandlerBoundToURL.ts | 35 - .../precaching/src/getCacheKeyForURL.ts | 36 - packages/serwiss/precaching/src/index.ts | 52 - .../serwiss/precaching/src/matchPrecache.ts | 35 - packages/serwiss/precaching/src/precache.ts | 37 - .../precaching/src/precacheAndRoute.ts | 36 - .../src/utils/PrecacheCacheKeyPlugin.ts | 52 - .../src/utils/PrecacheInstallReportPlugin.ts | 61 - .../precaching/src/utils/createCacheKey.ts | 69 - .../src/utils/deleteOutdatedCaches.ts | 55 - .../src/utils/generateURLVariations.ts | 60 - .../precaching/src/utils/getCacheKeyForURL.ts | 38 - .../utils/getOrCreatePrecacheController.ts | 23 - .../src/utils/printCleanupDetails.ts | 45 - .../src/utils/printInstallDetails.ts | 63 - .../src/utils/removeIgnoredSearchParams.ts | 36 - packages/serwiss/precaching/tsconfig.json | 7 - packages/serwiss/range-requests/README.md | 1 - packages/serwiss/range-requests/package.json | 31 - .../range-requests/src/RangeRequestsPlugin.ts | 50 - .../serwiss/range-requests/src/_version.ts | 4 - .../src/createPartialResponse.ts | 115 - packages/serwiss/range-requests/src/index.ts | 17 - .../src/utils/calculateEffectiveBoundaries.ts | 67 - .../src/utils/parseRangeHeader.ts | 57 - packages/serwiss/range-requests/tsconfig.json | 7 - packages/serwiss/recipes/README.md | 1 - packages/serwiss/recipes/package.json | 33 - packages/serwiss/recipes/src/_version.ts | 4 - .../serwiss/recipes/src/googleFontsCache.ts | 64 - packages/serwiss/recipes/src/imageCache.ts | 77 - packages/serwiss/recipes/src/index.ts | 41 - .../serwiss/recipes/src/offlineFallback.ts | 90 - packages/serwiss/recipes/src/pageCache.ts | 69 - .../recipes/src/staticResourceCache.ts | 66 - .../serwiss/recipes/src/warmStrategyCache.ts | 34 - packages/serwiss/recipes/tsconfig.json | 7 - packages/serwiss/routing/README.md | 1 - packages/serwiss/routing/package.json | 31 - .../serwiss/routing/src/NavigationRoute.ts | 143 -- packages/serwiss/routing/src/RegExpRoute.ts | 92 - packages/serwiss/routing/src/Route.ts | 80 - packages/serwiss/routing/src/Router.ts | 487 ---- packages/serwiss/routing/src/_types.ts | 66 - packages/serwiss/routing/src/_version.ts | 4 - packages/serwiss/routing/src/index.ts | 37 - packages/serwiss/routing/src/registerRoute.ts | 115 - .../serwiss/routing/src/setCatchHandler.ts | 29 - .../serwiss/routing/src/setDefaultHandler.ts | 32 - .../serwiss/routing/src/utils/constants.ts | 37 - .../src/utils/getOrCreateDefaultRouter.ts | 30 - .../routing/src/utils/normalizeHandler.ts | 43 - packages/serwiss/routing/tsconfig.json | 7 - packages/serwiss/strategies/README.md | 1 - packages/serwiss/strategies/package.json | 28 - packages/serwiss/strategies/src/CacheFirst.ts | 101 - packages/serwiss/strategies/src/CacheOnly.ts | 72 - .../serwiss/strategies/src/NetworkFirst.ts | 263 --- .../serwiss/strategies/src/NetworkOnly.ts | 122 - .../strategies/src/StaleWhileRevalidate.ts | 135 -- packages/serwiss/strategies/src/Strategy.ts | 289 --- .../serwiss/strategies/src/StrategyHandler.ts | 636 ------ packages/serwiss/strategies/src/_version.ts | 4 - packages/serwiss/strategies/src/index.ts | 44 - .../src/plugins/cacheOkAndOpaquePlugin.ts | 29 - .../serwiss/strategies/src/utils/messages.ts | 23 - packages/serwiss/strategies/tsconfig.json | 7 - packages/serwiss/streams/README.md | 1 - packages/serwiss/streams/package.json | 29 - packages/serwiss/streams/src/_types.ts | 23 - packages/serwiss/streams/src/_version.ts | 4 - packages/serwiss/streams/src/concatenate.ts | 146 -- .../streams/src/concatenateToResponse.ts | 43 - packages/serwiss/streams/src/index.ts | 28 - packages/serwiss/streams/src/isSupported.ts | 27 - packages/serwiss/streams/src/strategy.ts | 102 - .../streams/src/utils/createHeaders.ts | 34 - packages/serwiss/streams/tsconfig.json | 7 - packages/serwiss/sw/README.md | 1 - packages/serwiss/sw/_types.mjs | 24 - packages/serwiss/sw/_version.mjs | 3 - packages/serwiss/sw/controllers/WorkboxSW.mjs | 221 -- packages/serwiss/sw/index.mjs | 17 - packages/serwiss/sw/package.json | 23 - packages/serwiss/webpack-plugin/README.md | 1 - packages/serwiss/webpack-plugin/package.json | 42 - .../serwiss/webpack-plugin/src/generate-sw.ts | 244 -- packages/serwiss/webpack-plugin/src/index.ts | 19 - .../webpack-plugin/src/inject-manifest.ts | 371 --- .../webpack-plugin/src/lib/get-asset-hash.ts | 30 - .../get-manifest-entries-from-compilation.ts | 253 --- .../src/lib/get-script-files-for-chunks.ts | 51 - .../src/lib/get-sourcemap-asset-name.ts | 54 - .../src/lib/relative-to-output-path.ts | 32 - .../src/lib/resolve-webpack-url.ts | 33 - packages/serwiss/webpack-plugin/tsconfig.json | 7 - packages/serwiss/window/README.md | 1 - packages/serwiss/window/package.json | 30 - packages/serwiss/window/src/Workbox.ts | 743 ------ packages/serwiss/window/src/_version.ts | 4 - packages/serwiss/window/src/index.ts | 20 - packages/serwiss/window/src/messageSW.ts | 37 - .../serwiss/window/src/utils/WorkboxEvent.ts | 59 - .../window/src/utils/WorkboxEventTarget.ts | 77 - .../serwiss/window/src/utils/urlsMatch.ts | 23 - packages/serwiss/window/tsconfig.json | 7 - pnpm-lock.yaml | 1993 ++--------------- 308 files changed, 190 insertions(+), 23745 deletions(-) delete mode 100644 examples/workboxless/.gitignore delete mode 100644 examples/workboxless/README.md delete mode 100644 examples/workboxless/app/appdir/about/Button.tsx delete mode 100644 examples/workboxless/app/appdir/about/page.tsx delete mode 100644 examples/workboxless/app/appdir/page.tsx delete mode 100644 examples/workboxless/app/layout.tsx delete mode 100644 examples/workboxless/app/~offline/page.tsx delete mode 100644 examples/workboxless/next.config.js delete mode 100644 examples/workboxless/package.json delete mode 100644 examples/workboxless/pages/_app.tsx delete mode 100644 examples/workboxless/pages/_document.tsx delete mode 100644 examples/workboxless/pages/api/hello.ts delete mode 100644 examples/workboxless/pages/index.tsx delete mode 100644 examples/workboxless/public/favicon.ico delete mode 100644 examples/workboxless/public/icons/android-chrome-192x192.png delete mode 100644 examples/workboxless/public/icons/apple-touch-icon.png delete mode 100644 examples/workboxless/public/icons/icon-512x512.png delete mode 100644 examples/workboxless/public/manifest.json delete mode 100644 examples/workboxless/tsconfig.json delete mode 100644 packages/next-sw/CHANGELOG.md delete mode 100644 packages/next-sw/README.md delete mode 100644 packages/next-sw/globals.d.ts delete mode 100644 packages/next-sw/package.json delete mode 100644 packages/next-sw/rollup.config.js delete mode 100644 packages/next-sw/src/.swcrc.json delete mode 100644 packages/next-sw/src/build/generate-sw/base-sw-utils.ts delete mode 100644 packages/next-sw/src/build/generate-sw/base-sw.ts delete mode 100644 packages/next-sw/src/build/generate-sw/core-utils.ts delete mode 100644 packages/next-sw/src/build/generate-sw/core.ts delete mode 100644 packages/next-sw/src/build/generate-sw/default-runtime-caching.ts delete mode 100644 packages/next-sw/src/build/generate-sw/get-manifest-entries-from-compilation.ts delete mode 100644 packages/next-sw/src/build/generate-sw/index.ts delete mode 100644 packages/next-sw/src/build/generate-sw/runtime-caching-converter.ts delete mode 100644 packages/next-sw/src/build/generate-sw/webpack-plugin.ts delete mode 100644 packages/next-sw/src/index.ts delete mode 100644 packages/next-sw/src/private-types.ts delete mode 100644 packages/next-sw/src/sw-entry.ts delete mode 100644 packages/next-sw/src/swc-loader.ts delete mode 100644 packages/next-sw/src/types.ts delete mode 100644 packages/next-sw/tsconfig.json delete mode 100644 packages/serwiss/README.md delete mode 100644 packages/serwiss/background-sync/README.md delete mode 100644 packages/serwiss/background-sync/package.json delete mode 100644 packages/serwiss/background-sync/src/BackgroundSyncPlugin.ts delete mode 100644 packages/serwiss/background-sync/src/Queue.ts delete mode 100644 packages/serwiss/background-sync/src/QueueStore.ts delete mode 100644 packages/serwiss/background-sync/src/StorableRequest.ts delete mode 100644 packages/serwiss/background-sync/src/_version.ts delete mode 100644 packages/serwiss/background-sync/src/index.ts delete mode 100644 packages/serwiss/background-sync/src/lib/QueueDb.ts delete mode 100644 packages/serwiss/background-sync/src/lib/QueueStore.ts delete mode 100644 packages/serwiss/background-sync/src/lib/StorableRequest.ts delete mode 100644 packages/serwiss/background-sync/tsconfig.json delete mode 100644 packages/serwiss/broadcast-update/README.md delete mode 100644 packages/serwiss/broadcast-update/package.json delete mode 100644 packages/serwiss/broadcast-update/src/BroadcastCacheUpdate.ts delete mode 100644 packages/serwiss/broadcast-update/src/BroadcastUpdatePlugin.ts delete mode 100644 packages/serwiss/broadcast-update/src/_version.ts delete mode 100644 packages/serwiss/broadcast-update/src/index.ts delete mode 100644 packages/serwiss/broadcast-update/src/responsesAreSame.ts delete mode 100644 packages/serwiss/broadcast-update/src/utils/constants.ts delete mode 100644 packages/serwiss/broadcast-update/tsconfig.json delete mode 100644 packages/serwiss/build/README.md delete mode 100644 packages/serwiss/build/package.json delete mode 100644 packages/serwiss/build/src/_types.js delete mode 100644 packages/serwiss/build/src/cdn-details.json delete mode 100644 packages/serwiss/build/src/generate-sw.ts delete mode 100644 packages/serwiss/build/src/get-manifest.ts delete mode 100644 packages/serwiss/build/src/index.ts delete mode 100644 packages/serwiss/build/src/inject-manifest.ts delete mode 100644 packages/serwiss/build/src/lib/additional-manifest-entries-transform.ts delete mode 100644 packages/serwiss/build/src/lib/bundle.ts delete mode 100644 packages/serwiss/build/src/lib/cdn-utils.ts delete mode 100644 packages/serwiss/build/src/lib/copy-workbox-libraries.ts delete mode 100644 packages/serwiss/build/src/lib/errors.ts delete mode 100644 packages/serwiss/build/src/lib/escape-regexp.ts delete mode 100644 packages/serwiss/build/src/lib/get-composite-details.ts delete mode 100644 packages/serwiss/build/src/lib/get-file-details.ts delete mode 100644 packages/serwiss/build/src/lib/get-file-hash.ts delete mode 100644 packages/serwiss/build/src/lib/get-file-manifest-entries.ts delete mode 100644 packages/serwiss/build/src/lib/get-file-size.ts delete mode 100644 packages/serwiss/build/src/lib/get-source-map-url.ts delete mode 100644 packages/serwiss/build/src/lib/get-string-details.ts delete mode 100644 packages/serwiss/build/src/lib/get-string-hash.ts delete mode 100644 packages/serwiss/build/src/lib/maximum-size-transform.ts delete mode 100644 packages/serwiss/build/src/lib/modify-url-prefix-transform.ts delete mode 100644 packages/serwiss/build/src/lib/module-registry.ts delete mode 100644 packages/serwiss/build/src/lib/no-revision-for-urls-matching-transform.ts delete mode 100644 packages/serwiss/build/src/lib/populate-sw-template.ts delete mode 100644 packages/serwiss/build/src/lib/rebase-path.ts delete mode 100644 packages/serwiss/build/src/lib/replace-and-update-source-map.ts delete mode 100644 packages/serwiss/build/src/lib/runtime-caching-converter.ts delete mode 100644 packages/serwiss/build/src/lib/stringify-without-comments.ts delete mode 100644 packages/serwiss/build/src/lib/transform-manifest.ts delete mode 100644 packages/serwiss/build/src/lib/translate-url-to-sourcemap-paths.ts delete mode 100644 packages/serwiss/build/src/lib/validate-options.ts delete mode 100644 packages/serwiss/build/src/lib/write-sw-using-default-template.ts delete mode 100644 packages/serwiss/build/src/rollup-plugin-off-main-thread.d.ts delete mode 100644 packages/serwiss/build/src/schema/GenerateSWOptions.json delete mode 100644 packages/serwiss/build/src/schema/GetManifestOptions.json delete mode 100644 packages/serwiss/build/src/schema/InjectManifestOptions.json delete mode 100644 packages/serwiss/build/src/schema/WebpackGenerateSWOptions.json delete mode 100644 packages/serwiss/build/src/schema/WebpackInjectManifestOptions.json delete mode 100644 packages/serwiss/build/src/strip-comments.d.ts delete mode 100644 packages/serwiss/build/src/templates/sw-template.ts delete mode 100644 packages/serwiss/build/src/types.ts delete mode 100644 packages/serwiss/build/tsconfig.json delete mode 100644 packages/serwiss/cacheable-response/README.md delete mode 100755 packages/serwiss/cacheable-response/package.json delete mode 100644 packages/serwiss/cacheable-response/src/CacheableResponse.ts delete mode 100644 packages/serwiss/cacheable-response/src/CacheableResponsePlugin.ts delete mode 100644 packages/serwiss/cacheable-response/src/_version.ts delete mode 100644 packages/serwiss/cacheable-response/src/index.ts delete mode 100644 packages/serwiss/cacheable-response/tsconfig.json delete mode 100644 packages/serwiss/cli/README.md delete mode 100644 packages/serwiss/cli/package.json delete mode 100644 packages/serwiss/cli/src/app.ts delete mode 100755 packages/serwiss/cli/src/bin.ts delete mode 100644 packages/serwiss/cli/src/lib/cleanup-stack-trace.ts delete mode 100644 packages/serwiss/cli/src/lib/constants.ts delete mode 100644 packages/serwiss/cli/src/lib/errors.ts delete mode 100644 packages/serwiss/cli/src/lib/help-text.ts delete mode 100644 packages/serwiss/cli/src/lib/logger.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-config-location.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-extensions-to-cache.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-questions.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-root-of-web-app.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-start_url-query-params.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-sw-dest.ts delete mode 100644 packages/serwiss/cli/src/lib/questions/ask-sw-src.ts delete mode 100644 packages/serwiss/cli/src/lib/read-config.ts delete mode 100644 packages/serwiss/cli/src/lib/run-wizard.ts delete mode 100644 packages/serwiss/cli/tsconfig.json delete mode 100644 packages/serwiss/core/README.md delete mode 100644 packages/serwiss/core/package.json delete mode 100644 packages/serwiss/core/src/_private.ts delete mode 100644 packages/serwiss/core/src/_private/Deferred.ts delete mode 100644 packages/serwiss/core/src/_private/WorkboxError.ts delete mode 100644 packages/serwiss/core/src/_private/assert.ts delete mode 100644 packages/serwiss/core/src/_private/cacheMatchIgnoreParams.ts delete mode 100644 packages/serwiss/core/src/_private/cacheNames.ts delete mode 100644 packages/serwiss/core/src/_private/canConstructReadableStream.ts delete mode 100644 packages/serwiss/core/src/_private/canConstructResponseFromBodyStream.ts delete mode 100644 packages/serwiss/core/src/_private/dontWaitFor.ts delete mode 100644 packages/serwiss/core/src/_private/executeQuotaErrorCallbacks.ts delete mode 100644 packages/serwiss/core/src/_private/getFriendlyURL.ts delete mode 100644 packages/serwiss/core/src/_private/logger.ts delete mode 100644 packages/serwiss/core/src/_private/resultingClientExists.ts delete mode 100644 packages/serwiss/core/src/_private/timeout.ts delete mode 100644 packages/serwiss/core/src/_private/waitUntil.ts delete mode 100644 packages/serwiss/core/src/_version.ts delete mode 100644 packages/serwiss/core/src/cacheNames.ts delete mode 100644 packages/serwiss/core/src/clientsClaim.ts delete mode 100644 packages/serwiss/core/src/copyResponse.ts delete mode 100644 packages/serwiss/core/src/index.ts delete mode 100644 packages/serwiss/core/src/models/messages/messageGenerator.ts delete mode 100644 packages/serwiss/core/src/models/messages/messages.ts delete mode 100644 packages/serwiss/core/src/models/pluginEvents.ts delete mode 100644 packages/serwiss/core/src/models/quotaErrorCallbacks.ts delete mode 100644 packages/serwiss/core/src/registerQuotaErrorCallback.ts delete mode 100644 packages/serwiss/core/src/setCacheNameDetails.ts delete mode 100644 packages/serwiss/core/src/skipWaiting.ts delete mode 100644 packages/serwiss/core/src/types.ts delete mode 100644 packages/serwiss/core/src/utils/pluginUtils.ts delete mode 100644 packages/serwiss/core/src/utils/welcome.ts delete mode 100644 packages/serwiss/core/tsconfig.json delete mode 100644 packages/serwiss/expiration/README.md delete mode 100644 packages/serwiss/expiration/package.json delete mode 100644 packages/serwiss/expiration/src/CacheExpiration.ts delete mode 100644 packages/serwiss/expiration/src/ExpirationPlugin.ts delete mode 100644 packages/serwiss/expiration/src/_version.ts delete mode 100644 packages/serwiss/expiration/src/index.ts delete mode 100644 packages/serwiss/expiration/src/models/CacheTimestampsModel.ts delete mode 100644 packages/serwiss/expiration/tsconfig.json delete mode 100644 packages/serwiss/google-analytics/README.md delete mode 100644 packages/serwiss/google-analytics/package.json delete mode 100644 packages/serwiss/google-analytics/src/_version.ts delete mode 100644 packages/serwiss/google-analytics/src/index.ts delete mode 100644 packages/serwiss/google-analytics/src/initialize.ts delete mode 100644 packages/serwiss/google-analytics/src/utils/constants.ts delete mode 100644 packages/serwiss/google-analytics/tsconfig.json delete mode 100644 packages/serwiss/navigation-preload/README.md delete mode 100755 packages/serwiss/navigation-preload/package.json delete mode 100644 packages/serwiss/navigation-preload/src/_version.ts delete mode 100644 packages/serwiss/navigation-preload/src/disable.ts delete mode 100644 packages/serwiss/navigation-preload/src/enable.ts delete mode 100644 packages/serwiss/navigation-preload/src/index.ts delete mode 100644 packages/serwiss/navigation-preload/src/isSupported.ts delete mode 100644 packages/serwiss/navigation-preload/tsconfig.json delete mode 100644 packages/serwiss/precaching/README.md delete mode 100644 packages/serwiss/precaching/package.json delete mode 100644 packages/serwiss/precaching/src/PrecacheController.ts delete mode 100644 packages/serwiss/precaching/src/PrecacheFallbackPlugin.ts delete mode 100644 packages/serwiss/precaching/src/PrecacheRoute.ts delete mode 100644 packages/serwiss/precaching/src/PrecacheStrategy.ts delete mode 100644 packages/serwiss/precaching/src/_types.ts delete mode 100644 packages/serwiss/precaching/src/_version.ts delete mode 100644 packages/serwiss/precaching/src/addPlugins.ts delete mode 100644 packages/serwiss/precaching/src/addRoute.ts delete mode 100644 packages/serwiss/precaching/src/cleanupOutdatedCaches.ts delete mode 100644 packages/serwiss/precaching/src/createHandlerBoundToURL.ts delete mode 100644 packages/serwiss/precaching/src/getCacheKeyForURL.ts delete mode 100644 packages/serwiss/precaching/src/index.ts delete mode 100644 packages/serwiss/precaching/src/matchPrecache.ts delete mode 100644 packages/serwiss/precaching/src/precache.ts delete mode 100644 packages/serwiss/precaching/src/precacheAndRoute.ts delete mode 100644 packages/serwiss/precaching/src/utils/PrecacheCacheKeyPlugin.ts delete mode 100644 packages/serwiss/precaching/src/utils/PrecacheInstallReportPlugin.ts delete mode 100644 packages/serwiss/precaching/src/utils/createCacheKey.ts delete mode 100644 packages/serwiss/precaching/src/utils/deleteOutdatedCaches.ts delete mode 100644 packages/serwiss/precaching/src/utils/generateURLVariations.ts delete mode 100644 packages/serwiss/precaching/src/utils/getCacheKeyForURL.ts delete mode 100644 packages/serwiss/precaching/src/utils/getOrCreatePrecacheController.ts delete mode 100644 packages/serwiss/precaching/src/utils/printCleanupDetails.ts delete mode 100644 packages/serwiss/precaching/src/utils/printInstallDetails.ts delete mode 100644 packages/serwiss/precaching/src/utils/removeIgnoredSearchParams.ts delete mode 100644 packages/serwiss/precaching/tsconfig.json delete mode 100644 packages/serwiss/range-requests/README.md delete mode 100755 packages/serwiss/range-requests/package.json delete mode 100644 packages/serwiss/range-requests/src/RangeRequestsPlugin.ts delete mode 100644 packages/serwiss/range-requests/src/_version.ts delete mode 100644 packages/serwiss/range-requests/src/createPartialResponse.ts delete mode 100644 packages/serwiss/range-requests/src/index.ts delete mode 100644 packages/serwiss/range-requests/src/utils/calculateEffectiveBoundaries.ts delete mode 100644 packages/serwiss/range-requests/src/utils/parseRangeHeader.ts delete mode 100644 packages/serwiss/range-requests/tsconfig.json delete mode 100644 packages/serwiss/recipes/README.md delete mode 100644 packages/serwiss/recipes/package.json delete mode 100644 packages/serwiss/recipes/src/_version.ts delete mode 100644 packages/serwiss/recipes/src/googleFontsCache.ts delete mode 100644 packages/serwiss/recipes/src/imageCache.ts delete mode 100644 packages/serwiss/recipes/src/index.ts delete mode 100644 packages/serwiss/recipes/src/offlineFallback.ts delete mode 100644 packages/serwiss/recipes/src/pageCache.ts delete mode 100644 packages/serwiss/recipes/src/staticResourceCache.ts delete mode 100644 packages/serwiss/recipes/src/warmStrategyCache.ts delete mode 100644 packages/serwiss/recipes/tsconfig.json delete mode 100644 packages/serwiss/routing/README.md delete mode 100644 packages/serwiss/routing/package.json delete mode 100644 packages/serwiss/routing/src/NavigationRoute.ts delete mode 100644 packages/serwiss/routing/src/RegExpRoute.ts delete mode 100644 packages/serwiss/routing/src/Route.ts delete mode 100644 packages/serwiss/routing/src/Router.ts delete mode 100644 packages/serwiss/routing/src/_types.ts delete mode 100644 packages/serwiss/routing/src/_version.ts delete mode 100644 packages/serwiss/routing/src/index.ts delete mode 100644 packages/serwiss/routing/src/registerRoute.ts delete mode 100644 packages/serwiss/routing/src/setCatchHandler.ts delete mode 100644 packages/serwiss/routing/src/setDefaultHandler.ts delete mode 100644 packages/serwiss/routing/src/utils/constants.ts delete mode 100644 packages/serwiss/routing/src/utils/getOrCreateDefaultRouter.ts delete mode 100644 packages/serwiss/routing/src/utils/normalizeHandler.ts delete mode 100644 packages/serwiss/routing/tsconfig.json delete mode 100644 packages/serwiss/strategies/README.md delete mode 100644 packages/serwiss/strategies/package.json delete mode 100644 packages/serwiss/strategies/src/CacheFirst.ts delete mode 100644 packages/serwiss/strategies/src/CacheOnly.ts delete mode 100644 packages/serwiss/strategies/src/NetworkFirst.ts delete mode 100644 packages/serwiss/strategies/src/NetworkOnly.ts delete mode 100644 packages/serwiss/strategies/src/StaleWhileRevalidate.ts delete mode 100644 packages/serwiss/strategies/src/Strategy.ts delete mode 100644 packages/serwiss/strategies/src/StrategyHandler.ts delete mode 100644 packages/serwiss/strategies/src/_version.ts delete mode 100644 packages/serwiss/strategies/src/index.ts delete mode 100644 packages/serwiss/strategies/src/plugins/cacheOkAndOpaquePlugin.ts delete mode 100644 packages/serwiss/strategies/src/utils/messages.ts delete mode 100644 packages/serwiss/strategies/tsconfig.json delete mode 100644 packages/serwiss/streams/README.md delete mode 100644 packages/serwiss/streams/package.json delete mode 100644 packages/serwiss/streams/src/_types.ts delete mode 100644 packages/serwiss/streams/src/_version.ts delete mode 100644 packages/serwiss/streams/src/concatenate.ts delete mode 100644 packages/serwiss/streams/src/concatenateToResponse.ts delete mode 100644 packages/serwiss/streams/src/index.ts delete mode 100644 packages/serwiss/streams/src/isSupported.ts delete mode 100644 packages/serwiss/streams/src/strategy.ts delete mode 100644 packages/serwiss/streams/src/utils/createHeaders.ts delete mode 100644 packages/serwiss/streams/tsconfig.json delete mode 100644 packages/serwiss/sw/README.md delete mode 100644 packages/serwiss/sw/_types.mjs delete mode 100644 packages/serwiss/sw/_version.mjs delete mode 100644 packages/serwiss/sw/controllers/WorkboxSW.mjs delete mode 100644 packages/serwiss/sw/index.mjs delete mode 100644 packages/serwiss/sw/package.json delete mode 100644 packages/serwiss/webpack-plugin/README.md delete mode 100644 packages/serwiss/webpack-plugin/package.json delete mode 100644 packages/serwiss/webpack-plugin/src/generate-sw.ts delete mode 100644 packages/serwiss/webpack-plugin/src/index.ts delete mode 100644 packages/serwiss/webpack-plugin/src/inject-manifest.ts delete mode 100644 packages/serwiss/webpack-plugin/src/lib/get-asset-hash.ts delete mode 100644 packages/serwiss/webpack-plugin/src/lib/get-manifest-entries-from-compilation.ts delete mode 100644 packages/serwiss/webpack-plugin/src/lib/get-script-files-for-chunks.ts delete mode 100644 packages/serwiss/webpack-plugin/src/lib/get-sourcemap-asset-name.ts delete mode 100644 packages/serwiss/webpack-plugin/src/lib/relative-to-output-path.ts delete mode 100644 packages/serwiss/webpack-plugin/src/lib/resolve-webpack-url.ts delete mode 100644 packages/serwiss/webpack-plugin/tsconfig.json delete mode 100644 packages/serwiss/window/README.md delete mode 100644 packages/serwiss/window/package.json delete mode 100644 packages/serwiss/window/src/Workbox.ts delete mode 100644 packages/serwiss/window/src/_version.ts delete mode 100644 packages/serwiss/window/src/index.ts delete mode 100644 packages/serwiss/window/src/messageSW.ts delete mode 100644 packages/serwiss/window/src/utils/WorkboxEvent.ts delete mode 100644 packages/serwiss/window/src/utils/WorkboxEventTarget.ts delete mode 100644 packages/serwiss/window/src/utils/urlsMatch.ts delete mode 100644 packages/serwiss/window/tsconfig.json diff --git a/examples/workboxless/.gitignore b/examples/workboxless/.gitignore deleted file mode 100644 index 8434d7db..00000000 --- a/examples/workboxless/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ -.vscode - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -# next-pwa -**/public/workbox** -**/public/sw** -**/public/worker** -**/public/fallback** -**/public/precache** \ No newline at end of file diff --git a/examples/workboxless/README.md b/examples/workboxless/README.md deleted file mode 100644 index edb99a68..00000000 --- a/examples/workboxless/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# next-pwa - basic example - -This example demonstrates how to use `next-sw`, which is an unstable package and does not use Workbox. - -## Usage - -[![Open in Gitpod and run](https://img.shields.io/badge/Open%20In-Gitpod.io-%231966D2?style=for-the-badge&logo=gitpod)](https://gitpod.io/#https://github.com/DuCanhGH/next-pwa/) - -```bash -cd examples/workboxless -pnpm build -pnpm start -``` - -or - -Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: - -```bash -npx create-next-app --example https://github.com/DuCanhGH/next-pwa/tree/master/examples/workboxless workboxless-app -``` - -```bash -yarn create next-app --example https://github.com/DuCanhGH/next-pwa/tree/master/examples/workboxless workboxless-app -``` - -```bash -pnpm create next-app --example https://github.com/DuCanhGH/next-pwa/tree/master/examples/workboxless workboxless-app -``` - -## Recommended `.gitignore` - -```gitignore -**/public/sw.js -``` diff --git a/examples/workboxless/app/appdir/about/Button.tsx b/examples/workboxless/app/appdir/about/Button.tsx deleted file mode 100644 index 40976d25..00000000 --- a/examples/workboxless/app/appdir/about/Button.tsx +++ /dev/null @@ -1,7 +0,0 @@ -"use client"; -import { useState } from "react"; - -export function Button() { - const [count, setCount] = useState(0); - return ; -} diff --git a/examples/workboxless/app/appdir/about/page.tsx b/examples/workboxless/app/appdir/about/page.tsx deleted file mode 100644 index c068ecb1..00000000 --- a/examples/workboxless/app/appdir/about/page.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import Link from "next/link"; - -import { Button } from "./Button"; - -export default function Page() { - return ( - <> -

This is the basic example.

- Home page -