Comparing version 1.0.5 to 1.0.6
@@ -1,1 +0,1 @@ | ||
import{writeTextFile}from"fs-utils-sync";import{buildOutputPath,buildPrecacheAssetPaths,generateCacheName,readConfigFile}from"../utils/index.js";import{buildTemplate}from"../template/index.js";const run=({config:e="sw-builder.config.json"})=>{const t=readConfigFile(e),i=buildTemplate(t.template,generateCacheName(),buildPrecacheAssetPaths(t.outDir,t.includeToPrecache,t.excludeFilesFromPrecache));writeTextFile(buildOutputPath(t.outDir),i)};export{run}; | ||
import{writeTextFile}from"fs-utils-sync";import{buildOutputPath,buildPrecacheAssetPaths,generateCacheName,readConfigFile}from"../utils/index.js";import{buildTemplate}from"../template/index.js";const run=({config:e="sw-builder.config.json"})=>{const t=readConfigFile(e),i=buildTemplate(t.template,generateCacheName(),buildPrecacheAssetPaths(t.outDir,t.includeToPrecache,t.excludeFilesFromPrecache),t.excludeMIMETypesFromCache);writeTextFile(buildOutputPath(t.outDir),i)};export{run}; |
@@ -24,3 +24,4 @@ import { IBaseParsedArgs } from 'argv-utils'; | ||
excludeFilesFromPrecache: string[]; | ||
excludeMIMETypesFromCache: string[]; | ||
} | ||
export type { IModuleArgs, ITemplateName, IBaseConfig, }; |
import { ITemplateName } from '../shared/index.js'; | ||
/** | ||
* Stringifies a constant variable that contains an array. | ||
* @param constantName | ||
* @param elements | ||
* @returns string | ||
*/ | ||
declare const stringifyArrayConstant: (constantName: string, elements: string[]) => string; | ||
/** | ||
* Builds a Service Worker Template by name. | ||
@@ -13,3 +20,3 @@ * @param template | ||
*/ | ||
declare const buildTemplate: (template: ITemplateName, cacheName: string, precacheAssets: string[]) => string; | ||
export { buildTemplate, }; | ||
declare const buildTemplate: (template: ITemplateName, cacheName: string, precacheAssets: string[], excludeMIMETypes: string[]) => string; | ||
export { stringifyArrayConstant, buildTemplate, }; |
@@ -1,1 +0,1 @@ | ||
import{encodeError}from"error-message-utils";import{ERRORS}from"../shared/index.js";import{BASE_TEMPLATE}from"./templates/index.js";const __insertCacheName=(e,r)=>e.replace("const CACHE_NAME = '';",`const CACHE_NAME = '${r}';`),__stringifyPrecacheAssets=e=>{let r="const PRECACHE_ASSETS = [\n";return r+=e.reduce(((r,s,t)=>`${r} '${s}'${t<e.length-1?",\n":","}`),""),r+="\n];",r},__insertPrecacheAssets=(e,r)=>e.replace("const PRECACHE_ASSETS = [];",__stringifyPrecacheAssets(r)),__buildBaseTemplate=(e,r)=>__insertPrecacheAssets(__insertCacheName(BASE_TEMPLATE,e),r),buildTemplate=(e,r,s)=>{if("base"===e)return __buildBaseTemplate(r,s);throw new Error(encodeError(`The template name '${e}' is not supported.`,ERRORS.INVALID_TEMPLATE_NAME))};export{buildTemplate}; | ||
import{encodeError}from"error-message-utils";import{ERRORS}from"../shared/index.js";import{BASE_TEMPLATE}from"./templates/index.js";const __insertCacheName=(e,r)=>e.replace("const CACHE_NAME = '';",`const CACHE_NAME = '${r}';`),stringifyArrayConstant=(e,r)=>{let t=`const ${e} = [\n`;return t+=r.reduce(((e,t,s)=>`${e} '${t}'${s<r.length-1?",\n":","}`),""),t+="\n];",t},__insertPrecacheAssets=(e,r)=>e.replace("const PRECACHE_ASSETS = [];",stringifyArrayConstant("PRECACHE_ASSETS",r)),__insertExcludeMIMETypes=(e,r)=>e.replace("const EXCLUDE_MIME_TYPES = [];",stringifyArrayConstant("EXCLUDE_MIME_TYPES",r)),__buildBaseTemplate=(e,r,t)=>{let s=__insertCacheName(BASE_TEMPLATE,e);return s=__insertPrecacheAssets(s,r),s=__insertExcludeMIMETypes(s,t),s},buildTemplate=(e,r,t,s)=>{if("base"===e)return __buildBaseTemplate(r,t,s);throw new Error(encodeError(`The template name '${e}' is not supported.`,ERRORS.INVALID_TEMPLATE_NAME))};export{stringifyArrayConstant,buildTemplate}; |
@@ -1,1 +0,1 @@ | ||
const BASE_TEMPLATE="/* ************************************************************************************************\n* CONSTANTS *\n************************************************************************************************ */\n\n// the current version of the cache\nconst CACHE_NAME = '';\n\n// assets that will be cached once the service worker is installed\nconst PRECACHE_ASSETS = [];\n\n\n\n\n\n/* ************************************************************************************************\n* MAIN CACHE ACTIONS *\n************************************************************************************************ */\n\n/**\n* Adds the given list of resource URLs to the cache.\n* @param {*} resources\n* @returns Promise<void>\n*/\nconst addResourcesToCache = async (resources) => {\n const cache = await caches.open(CACHE_NAME);\n await cache.addAll(resources);\n};\n\n/**\n* All requests should be cached except for:\n* - Non-GET requests\n* - Requests with accept: application/json | text/plain (HTTP long-polling requests)\n* - Resposes with content-type: application/json | text/plain (HTTP long-polling requests)\n* @param {*} request\n* @param {*} response\n* @returns boolean\n*/\nconst canRequestBeCached = (request, response) => {\n const accept = request.headers.get('accept');\n const contentType = response.headers.get('content-type');\n return request.method === 'GET'\n && (\n accept === null\n || (\n !accept.includes('application/json') && !accept.includes('text/plain')\n )\n )\n && (\n contentType === null\n || (\n !contentType.includes('application/json') && !contentType.includes('text/plain')\n )\n );\n};\n\n/**\n* Adds the request and its response to the cache.\n* @param {*} request\n* @param {*} response\n* @returns Promise<void>\n*/\nconst putInCache = async (request, response) => {\n if (canRequestBeCached(request, response)) {\n const cache = await caches.open(CACHE_NAME);\n await cache.put(request, response);\n }\n};\n\n/**\n* Intercepts the fetch requests and attempts to fill them with data from the cache. If not present,\n* it will perform the request and store the data in cache.\n* Note: the Response stored in cache is a clone as it can only be read once.\n* @param {*} request\n* @returns Promise<Response>\n*/\nconst cacheFirst = async (request) => {\n // first, try to get the resource from the cache\n const responseFromCache = await caches.match(request);\n if (responseFromCache) {\n return responseFromCache;\n }\n\n // next, try to get the resource from the network\n try {\n const responseFromNetwork = await fetch(request);\n putInCache(request, responseFromNetwork.clone());\n return responseFromNetwork;\n } catch (error) {\n return new Response('Network error happened', {\n status: 408,\n headers: { 'Content-Type': 'text/plain' },\n });\n }\n};\n\n\n\n\n\n/* ************************************************************************************************\n* CACHE CLEAN UP ACTIONS *\n************************************************************************************************ */\n\n/**\n* Deletes everything stored in cache that doesn't match the current version.\n* @returns Promise<void>\n*/\nconst deleteOldCaches = async () => {\n const keyList = await caches.keys();\n const cachesToDelete = keyList.filter((key) => key !== CACHE_NAME);\n await Promise.all(cachesToDelete.map((key) => caches.delete(key)));\n};\n\n\n\n\n\n/* ************************************************************************************************\n* EVENTS *\n************************************************************************************************ */\n\n/**\n* Triggers when the Service Worker has been fetched and registered.\n* It takes care of adding the base resources to the cache.\n*/\nself.addEventListener('install', (event) => {\n event.waitUntil(addResourcesToCache(PRECACHE_ASSETS));\n});\n\n/**\n* Triggers after the Service Worker is installed and it has taken control of the app.\n* It takes care of enabling navigation preload (if supported) and it also takes control of any\n* pages that were controlled by the previous version of the worker (if any).\n*/\nself.addEventListener('activate', (event) => {\n event.waitUntil(Promise.all([\n self.clients.claim(),\n deleteOldCaches(),\n ]));\n});\n\n/**\n* Triggers when the app thread makes a network request.\n* It intercepts the request and checks if it can be filled with data from cache. Otherwise, it\n* resumes the network request and then stores it cache for future requests.\n*/\nself.addEventListener('fetch', (event) => {\n event.respondWith(cacheFirst(event.request));\n});\n";export{BASE_TEMPLATE}; | ||
const BASE_TEMPLATE="/* ************************************************************************************************\n* CONSTANTS *\n************************************************************************************************ */\n\n// the current version of the cache\nconst CACHE_NAME = '';\n\n// assets that will be cached once the service worker is installed\nconst PRECACHE_ASSETS = [];\n\n// the list of MIME Types that won't be cached when the app sends HTTP GET requests\nconst EXCLUDE_MIME_TYPES = [];\n\n\n\n\n\n/* ************************************************************************************************\n* MAIN CACHE ACTIONS *\n************************************************************************************************ */\n\n/**\n* Adds the given list of resource URLs to the cache.\n* @param {*} resources\n* @returns Promise<void>\n*/\nconst addResourcesToCache = async (resources) => {\n const cache = await caches.open(CACHE_NAME);\n await cache.addAll(resources);\n};\n\n/**\n * Verifies if the value of the 'Accept' or 'Content-Type' header is cacheable.\n * @param {*} contentTypeHeader\n * @returns boolean\n */\nconst isMIMETypeCacheable = (contentTypeHeader) => (\n contentTypeHeader === null\n || EXCLUDE_MIME_TYPES.every((type) => !contentTypeHeader.includes(type))\n);\n\n/**\n* All requests should be cached except for:\n* - Non-GET requests\n* - Requests with MIME Types that are not included in EXCLUDE_MIME_TYPES\n* @param {*} request\n* @param {*} response\n* @returns boolean\n*/\nconst canRequestBeCached = (request, response) => (\n request.method === 'GET'\n && isMIMETypeCacheable(request.headers.get('accept'))\n && isMIMETypeCacheable(response.headers.get('content-type'))\n);\n\n/**\n* Adds the request and its response to the cache.\n* @param {*} request\n* @param {*} response\n* @returns Promise<void>\n*/\nconst putInCache = async (request, response) => {\n if (canRequestBeCached(request, response)) {\n const cache = await caches.open(CACHE_NAME);\n await cache.put(request, response);\n }\n};\n\n/**\n* Intercepts the fetch requests and attempts to fill them with data from the cache. If not present,\n* it will perform the request and store the data in cache.\n* Note: the Response stored in cache is a clone as it can only be read once.\n* @param {*} request\n* @returns Promise<Response>\n*/\nconst cacheFirst = async (request) => {\n // first, try to get the resource from the cache\n const responseFromCache = await caches.match(request);\n if (responseFromCache) {\n return responseFromCache;\n }\n\n // next, try to get the resource from the network\n try {\n const responseFromNetwork = await fetch(request);\n putInCache(request, responseFromNetwork.clone());\n return responseFromNetwork;\n } catch (error) {\n return new Response('Network error happened', {\n status: 408,\n headers: { 'Content-Type': 'text/plain' },\n });\n }\n};\n\n\n\n\n\n/* ************************************************************************************************\n* CACHE CLEAN UP ACTIONS *\n************************************************************************************************ */\n\n/**\n* Deletes everything stored in cache that doesn't match the current version.\n* @returns Promise<void>\n*/\nconst deleteOldCaches = async () => {\n const keyList = await caches.keys();\n const cachesToDelete = keyList.filter((key) => key !== CACHE_NAME);\n if (cachesToDelete.length) {\n await Promise.all(cachesToDelete.map((key) => caches.delete(key)));\n }\n};\n\n\n\n\n\n/* ************************************************************************************************\n* EVENTS *\n************************************************************************************************ */\n\n/**\n* Triggers when the Service Worker has been fetched and registered.\n* It takes care of adding the base resources to the cache.\n*/\nself.addEventListener('install', (event) => {\n event.waitUntil(addResourcesToCache(PRECACHE_ASSETS));\n});\n\n/**\n* Triggers after the Service Worker is installed and it has taken control of the app.\n* It takes care of enabling navigation preload (if supported) and it also takes control of any\n* pages that were controlled by the previous version of the worker (if any).\n*/\nself.addEventListener('activate', (event) => {\n event.waitUntil(Promise.all([\n self.clients.claim(),\n deleteOldCaches(),\n ]));\n});\n\n/**\n* Triggers when the app thread makes a network request.\n* It intercepts the request and checks if it can be filled with data from cache. Otherwise, it\n* resumes the network request and then stores it cache for future requests.\n*/\nself.addEventListener('fetch', (event) => {\n event.respondWith(cacheFirst(event.request));\n});\n";export{BASE_TEMPLATE}; |
@@ -1,1 +0,1 @@ | ||
import{join}from"node:path";import{encodeError}from"error-message-utils";import{isDirectory,readJSONFile,getPathElement,readDirectory}from"fs-utils-sync";import{ERRORS}from"../shared/index.js";const CACHE_NAME_CHARACTERS="abcdefghijklmnopqrstuvwxyz0123456789",CACHE_NAME_LENGTH=10,OUTPUT_NAME="sw.js",__validateConfigFile=e=>{if(!e||"object"!=typeof e)throw console.log(e),new Error(encodeError("The extracted configuration is not a valid object.",ERRORS.INVALID_CONFIG_VALUE));if("string"!=typeof e.outDir||!e.outDir.length||!isDirectory(e.outDir))throw new Error(encodeError(`The outDir '${e.outDir}' is not a directory or doesn't exist.`,ERRORS.INVALID_CONFIG_VALUE));if("string"!=typeof e.template||!e.template.length)throw new Error(encodeError(`The template '${e.template}' is not a valid template name.`,ERRORS.INVALID_CONFIG_VALUE));if(!Array.isArray(e.includeToPrecache)||!e.includeToPrecache.length)throw console.log(e.includeToPrecache),new Error(encodeError(`The includeToPrecache '${e.includeToPrecache}' list is invalid or empty.`,ERRORS.INVALID_CONFIG_VALUE));if(!Array.isArray(e.excludeFilesFromPrecache))throw console.log(e.excludeFilesFromPrecache),new Error(encodeError(`The excludeFilesFromPrecache '${e.excludeFilesFromPrecache}' list is invalid.`,ERRORS.INVALID_CONFIG_VALUE))},__getPathElement=e=>{const r=getPathElement(e);if(null===r||!r.isDirectory&&!r.isFile)throw new Error(encodeError(`The asset '${e}' is not a path element.`,ERRORS.NOT_A_PATH_ELEMENT));return r},__extractCacheableFilesFromDirectory=(e,r,t)=>{let o=readDirectory(r,!0);return o=o.filter((e=>{const r=__getPathElement(e);return r.isFile&&!t.includes(r.baseName)})),o.map((r=>r.replace(e,"")))},readConfigFile=e=>{const r=readJSONFile(e);return __validateConfigFile(r),r},generateCacheName=()=>{let e="",r=0;for(;r<10;)e+=CACHE_NAME_CHARACTERS.charAt(Math.floor(36*Math.random())),r+=1;return e},buildPrecacheAssetPaths=(e,r,t)=>{const o=["/"];return r.forEach((r=>{if("/"!==r){const i=__getPathElement(join(e,r));i.isFile&&!t.includes(i.baseName)?o.push(r):o.push(...__extractCacheableFilesFromDirectory(e,i.path,t))}})),o},buildOutputPath=e=>join(e,"sw.js");export{CACHE_NAME_CHARACTERS,CACHE_NAME_LENGTH,OUTPUT_NAME,readConfigFile,generateCacheName,buildPrecacheAssetPaths,buildOutputPath}; | ||
import{join}from"node:path";import{encodeError}from"error-message-utils";import{isDirectory,readJSONFile,getPathElement,readDirectory}from"fs-utils-sync";import{ERRORS}from"../shared/index.js";const CACHE_NAME_CHARACTERS="abcdefghijklmnopqrstuvwxyz0123456789",CACHE_NAME_LENGTH=10,OUTPUT_NAME="sw.js",__validateConfigFile=e=>{if(!e||"object"!=typeof e)throw console.log(e),new Error(encodeError("The extracted configuration is not a valid object.",ERRORS.INVALID_CONFIG_VALUE));if("string"!=typeof e.outDir||!e.outDir.length||!isDirectory(e.outDir))throw new Error(encodeError(`The outDir '${e.outDir}' is not a directory or doesn't exist.`,ERRORS.INVALID_CONFIG_VALUE));if("string"!=typeof e.template||!e.template.length)throw new Error(encodeError(`The template '${e.template}' is not a valid template name.`,ERRORS.INVALID_CONFIG_VALUE));if(!Array.isArray(e.includeToPrecache)||!e.includeToPrecache.length)throw console.log(e.includeToPrecache),new Error(encodeError(`The includeToPrecache '${e.includeToPrecache}' list is invalid or empty.`,ERRORS.INVALID_CONFIG_VALUE));if(!Array.isArray(e.excludeFilesFromPrecache))throw console.log(e.excludeFilesFromPrecache),new Error(encodeError(`The excludeFilesFromPrecache '${e.excludeFilesFromPrecache}' list is invalid.`,ERRORS.INVALID_CONFIG_VALUE));if(!Array.isArray(e.excludeMIMETypesFromCache))throw console.log(e.excludeMIMETypesFromCache),new Error(encodeError(`The excludeMIMETypesFromCache '${e.excludeMIMETypesFromCache}' list is invalid.`,ERRORS.INVALID_CONFIG_VALUE))},__getPathElement=e=>{const r=getPathElement(e);if(null===r||!r.isDirectory&&!r.isFile)throw new Error(encodeError(`The asset '${e}' is not a path element.`,ERRORS.NOT_A_PATH_ELEMENT));return r},__extractCacheableFilesFromDirectory=(e,r,t)=>{let o=readDirectory(r,!0);return o=o.filter((e=>{const r=__getPathElement(e);return r.isFile&&!t.includes(r.baseName)})),o.map((r=>r.replace(e,"")))},readConfigFile=e=>{const r=readJSONFile(e);return __validateConfigFile(r),r},generateCacheName=()=>{let e="",r=0;for(;r<10;)e+=CACHE_NAME_CHARACTERS.charAt(Math.floor(36*Math.random())),r+=1;return e},buildPrecacheAssetPaths=(e,r,t)=>{const o=["/"];return r.forEach((r=>{if("/"!==r){const i=__getPathElement(join(e,r));i.isFile&&!t.includes(i.baseName)?o.push(r):o.push(...__extractCacheableFilesFromDirectory(e,i.path,t))}})),o},buildOutputPath=e=>join(e,"sw.js");export{CACHE_NAME_CHARACTERS,CACHE_NAME_LENGTH,OUTPUT_NAME,readConfigFile,generateCacheName,buildPrecacheAssetPaths,buildOutputPath}; |
{ | ||
"name": "sw-builder", | ||
"version": "1.0.5", | ||
"version": "1.0.6", | ||
"description": "The sw-builder package automates the creation of your Application's Service Worker, which pre-caches your build. This leads to a better overall performance and enables users to access your PWA without an Internet connection.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -27,3 +27,7 @@ # Service Worker Builder | ||
"excludeFilesFromPrecache": [ | ||
"some-ignorable-file.woff2", | ||
"some-ignorable-file.woff2" | ||
], | ||
"excludeMIMETypesFromCache": [ | ||
"application/json", | ||
"text/plain" | ||
] | ||
@@ -30,0 +34,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18936
119
119