Comparing version 1.0.0 to 1.0.1
@@ -1,29 +0,1 @@ | ||
import { writeTextFile } from 'fs-utils-sync'; | ||
import { buildOutputPath, buildPrecacheAssetPaths, generateCacheName, readConfigFile, } from '../utils/index.js'; | ||
import { buildTemplate } from '../template/index.js'; | ||
/* ************************************************************************************************ | ||
* IMPLEMENTATION * | ||
************************************************************************************************ */ | ||
/** | ||
* Executes the sw-builder script and builds the Service Worker based on the configuration. | ||
* @param args | ||
* @throws | ||
* - NOT_A_FILE: if the path is not recognized by the OS as a file or if it doesn't exist | ||
* - FILE_CONTENT_IS_EMPTY_OR_INVALID: if the content of the file is empty or invalid or the JSON | ||
* content cannot be parsed | ||
* - INVALID_CONFIG_VALUE: if any of the essential config values is invalid | ||
* - INVALID_TEMPLATE_NAME: if the provided template name is not supported | ||
* - NOT_A_PATH_ELEMENT: if the provided path doesn't exist or is not a valid path element | ||
*/ | ||
const run = ({ config = 'sw-builder.config.json' }) => { | ||
// load the configuration file | ||
const configuration = readConfigFile(config); | ||
// build the Service Worker's Template | ||
const template = buildTemplate(configuration.template, generateCacheName(), buildPrecacheAssetPaths(configuration.outDir, configuration.includeToPrecache, configuration.excludeFilesFromPrecache)); | ||
// finally, save the file in the specified path | ||
writeTextFile(buildOutputPath(configuration.outDir), template); | ||
}; | ||
/* ************************************************************************************************ | ||
* MODULE EXPORTS * | ||
************************************************************************************************ */ | ||
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"})=>{var e=readConfigFile(e),t=buildTemplate(e.template,generateCacheName(),buildPrecacheAssetPaths(e.outDir,e.includeToPrecache,e.excludeFilesFromPrecache));writeTextFile(buildOutputPath(e.outDir),t)};export{run}; |
@@ -1,1 +0,1 @@ | ||
export * from './build.js'; | ||
export*from"./build.js"; |
#! /usr/bin/env node | ||
import process from 'node:process'; | ||
import { parseArgs } from 'argv-utils'; | ||
import { run } from './build/index.js'; | ||
(() => { | ||
try { | ||
run(parseArgs(process.argv)); | ||
process.exit(0); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
process.exit(1); | ||
} | ||
})(); | ||
import process from"node:process";import{parseArgs}from"argv-utils";import{run}from"./build/index.js";try{run(parseArgs(process.argv)),process.exit(0)}catch(r){console.error(r),process.exit(1)} |
@@ -1,17 +0,1 @@ | ||
/* ************************************************************************************************ | ||
* IMPLEMENTATION * | ||
************************************************************************************************ */ | ||
/** | ||
* Errors | ||
* The list of errors that can occur in any of the modules. | ||
*/ | ||
var ERRORS; | ||
(function (ERRORS) { | ||
ERRORS["INVALID_TEMPLATE_NAME"] = "INVALID_TEMPLATE_NAME"; | ||
ERRORS["INVALID_CONFIG_VALUE"] = "INVALID_CONFIG_VALUE"; | ||
ERRORS["NOT_A_PATH_ELEMENT"] = "NOT_A_PATH_ELEMENT"; | ||
})(ERRORS || (ERRORS = {})); | ||
/* ************************************************************************************************ | ||
* MODULE EXPORTS * | ||
************************************************************************************************ */ | ||
export { ERRORS, }; | ||
var ERRORS;!function(E){E.INVALID_TEMPLATE_NAME="INVALID_TEMPLATE_NAME",E.INVALID_CONFIG_VALUE="INVALID_CONFIG_VALUE",E.NOT_A_PATH_ELEMENT="NOT_A_PATH_ELEMENT"}(ERRORS=ERRORS||{});export{ERRORS}; |
@@ -1,2 +0,1 @@ | ||
export * from './types.js'; | ||
export * from './errors.js'; | ||
export*from"./types.js";export*from"./errors.js"; |
@@ -1,1 +0,1 @@ | ||
export * from './template.js'; | ||
export*from"./template.js"; |
@@ -1,75 +0,1 @@ | ||
import { encodeError } from 'error-message-utils'; | ||
import { readTextFile } from 'fs-utils-sync'; | ||
import { ERRORS } from '../shared/index.js'; | ||
/* ************************************************************************************************ | ||
* HELPERS * | ||
************************************************************************************************ */ | ||
/** | ||
* Reads the raw content for a given template name. | ||
* @param name | ||
* @returns string | ||
* @throws | ||
* - NOT_A_FILE: if the path is not recognized by the OS as a file or if it doesn't exist | ||
* - FILE_CONTENT_IS_EMPTY_OR_INVALID: if the content of the file is empty or invalid | ||
*/ | ||
const __getRawTemplate = (name) => readTextFile(`raw/sw.${name}.js`); | ||
/** | ||
* Inserts the freshly generated cacheName into the raw template. | ||
* @param rawTemplate | ||
* @param cacheName | ||
* @returns string | ||
*/ | ||
const __insertCacheName = (rawTemplate, cacheName) => (rawTemplate.replace('const CACHE_NAME = \'\';', `const CACHE_NAME = '${cacheName}';`)); | ||
/** | ||
* Stringifies a given list of asset paths that will be pre-cached. | ||
* @param precacheAssets | ||
* @returns string | ||
*/ | ||
const __stringifyPrecacheAssets = (precacheAssets) => { | ||
let assets = 'const PRECACHE_ASSETS = [\n'; | ||
assets += precacheAssets.reduce((prev, current, index) => `${prev} '${current}'${index < precacheAssets.length - 1 ? ',\n' : ','}`, ''); | ||
assets += '\n];'; | ||
return assets; | ||
}; | ||
/** | ||
* Inserts the pre-cache assets content into the raw template. | ||
* @param rawTemplate | ||
* @param precacheAssets | ||
* @returns string | ||
*/ | ||
const __insertPrecacheAssets = (rawTemplate, precacheAssets) => (rawTemplate.replace('const PRECACHE_ASSETS = [];', __stringifyPrecacheAssets(precacheAssets))); | ||
/* ************************************************************************************************ | ||
* IMPLEMENTATION * | ||
************************************************************************************************ */ | ||
/** | ||
* Builds the base template ready to be saved. | ||
* @param cacheName | ||
* @param precacheAssets | ||
* @returns string | ||
*/ | ||
const __buildBaseTemplate = (cacheName, precacheAssets) => __insertPrecacheAssets(__insertCacheName(__getRawTemplate('base'), cacheName), precacheAssets); | ||
/** | ||
* Builds a Service Worker Template by name. | ||
* @param template | ||
* @param cacheName | ||
* @param precacheAssets | ||
* @returns string | ||
* @throws | ||
* - INVALID_TEMPLATE_NAME: if the provided template name is not supported | ||
* - NOT_A_FILE: if the path is not recognized by the OS as a file or if it doesn't exist | ||
* - FILE_CONTENT_IS_EMPTY_OR_INVALID: if the content of the file is empty or invalid | ||
*/ | ||
const buildTemplate = (template, cacheName, precacheAssets) => { | ||
switch (template) { | ||
case 'base': { | ||
return __buildBaseTemplate(cacheName, precacheAssets); | ||
} | ||
default: { | ||
throw new Error(encodeError(`The template name '${template}' is not supported.`, ERRORS.INVALID_TEMPLATE_NAME)); | ||
} | ||
} | ||
}; | ||
/* ************************************************************************************************ | ||
* MODULE EXPORTS * | ||
************************************************************************************************ */ | ||
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}';`),__stringifyPrecacheAssets=t=>{var e="const PRECACHE_ASSETS = [\n";return e+t.reduce((e,r,s)=>e+` '${r}'`+(s<t.length-1?",\n":","),"")+"\n];"},__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)throw new Error(encodeError(`The template name '${e}' is not supported.`,ERRORS.INVALID_TEMPLATE_NAME));return __buildBaseTemplate(r,s)};export{buildTemplate}; |
@@ -1,1 +0,1 @@ | ||
export * from './utils.js'; | ||
export*from"./utils.js"; |
@@ -1,148 +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'; | ||
/* ************************************************************************************************ | ||
* CONSTANTS * | ||
************************************************************************************************ */ | ||
// the characters that can be used to generate cache names | ||
const CACHE_NAME_CHARACTERS = 'abcdefghijklmnopqrstuvwxyz0123456789'; | ||
// the number of characters that will comprise the cache names | ||
const CACHE_NAME_LENGTH = 10; | ||
// the name of the file that is built and placed in the outDir | ||
const OUTPUT_NAME = 'sw.js'; | ||
/* ************************************************************************************************ | ||
* HELPERS * | ||
************************************************************************************************ */ | ||
/** | ||
* Performs the essential validations on the configuration file. Note it doesn't get into template | ||
* specific validations. | ||
* @param config | ||
* @throws | ||
* - INVALID_CONFIG_VALUE: if any of the essential config values is invalid | ||
*/ | ||
const __validateConfigFile = (config) => { | ||
if (!config || typeof config !== 'object') { | ||
console.log(config); | ||
throw new Error(encodeError('The extracted configuration is not a valid object.', ERRORS.INVALID_CONFIG_VALUE)); | ||
} | ||
if (typeof config.outDir !== 'string' || !config.outDir.length || !isDirectory(config.outDir)) { | ||
throw new Error(encodeError(`The outDir '${config.outDir}' is not a directory or doesn't exist.`, ERRORS.INVALID_CONFIG_VALUE)); | ||
} | ||
if (typeof config.template !== 'string' || !config.template.length) { | ||
throw new Error(encodeError(`The template '${config.template}' is not a valid template name.`, ERRORS.INVALID_CONFIG_VALUE)); | ||
} | ||
if (!Array.isArray(config.includeToPrecache) || !config.includeToPrecache.length) { | ||
console.log(config.includeToPrecache); | ||
throw new Error(encodeError(`The includeToPrecache '${config.includeToPrecache}' list is invalid or empty.`, ERRORS.INVALID_CONFIG_VALUE)); | ||
} | ||
if (!Array.isArray(config.excludeFilesFromPrecache)) { | ||
console.log(config.excludeFilesFromPrecache); | ||
throw new Error(encodeError(`The excludeFilesFromPrecache '${config.excludeFilesFromPrecache}' list is invalid.`, ERRORS.INVALID_CONFIG_VALUE)); | ||
} | ||
}; | ||
/** | ||
* Extracts the path element from a given path. | ||
* @param path | ||
* @returns IPathElement | ||
* @throws | ||
* - NOT_A_PATH_ELEMENT: if the provided path doesn't exist or is not a valid path element | ||
*/ | ||
const __getPathElement = (path) => { | ||
const el = getPathElement(path); | ||
if (el === null || (!el.isDirectory && !el.isFile)) { | ||
throw new Error(encodeError(`The asset '${path}' is not a path element.`, ERRORS.NOT_A_PATH_ELEMENT)); | ||
} | ||
return el; | ||
}; | ||
/** | ||
* Fully reads a given directory path and returns the files that are cacheable. | ||
* @param outDir | ||
* @param path | ||
* @param excludeFilesFromPrecache | ||
* @returns string[] | ||
*/ | ||
const __extractCacheableFilesFromDirectory = (outDir, path, excludeFilesFromPrecache) => { | ||
// read all the directory contents | ||
let content = readDirectory(path, true); | ||
// filter those paths that are not cacheable | ||
content = content.filter((p) => { | ||
const el = __getPathElement(p); | ||
return el.isFile && !excludeFilesFromPrecache.includes(el.baseName); | ||
}); | ||
// finally, remove the outDir from the path | ||
return content.map((filePath) => filePath.replace(outDir, '')); | ||
}; | ||
/* ************************************************************************************************ | ||
* IMPLEMENTATION * | ||
************************************************************************************************ */ | ||
/** | ||
* Reads, validates and returns the configuration file. | ||
* @param configPath | ||
* @returns IBaseConfig | ||
* @throws | ||
* - NOT_A_FILE: if the path is not recognized by the OS as a file or if it doesn't exist | ||
* - FILE_CONTENT_IS_EMPTY_OR_INVALID: if the content of the file is empty or invalid | ||
* - FILE_CONTENT_IS_EMPTY_OR_INVALID: if the file's JSON content cannot be parsed | ||
* - INVALID_CONFIG_VALUE: if any of the essential config values is invalid | ||
*/ | ||
const readConfigFile = (configPath) => { | ||
const config = readJSONFile(configPath); | ||
__validateConfigFile(config); | ||
return config; | ||
}; | ||
/** | ||
* Generates a randomly generated name to be used for the CacheStorage | ||
* @returns string | ||
*/ | ||
const generateCacheName = () => { | ||
let nm = ''; | ||
let counter = 0; | ||
while (counter < CACHE_NAME_LENGTH) { | ||
nm += CACHE_NAME_CHARACTERS.charAt(Math.floor(Math.random() * CACHE_NAME_CHARACTERS.length)); | ||
counter += 1; | ||
} | ||
return nm; | ||
}; | ||
/** | ||
* Puts the list of all the assets that must be cached based on the include and exclude lists. | ||
* @param outDir | ||
* @param includeToPrecache | ||
* @param excludeFilesFromPrecache | ||
* @returns string[] | ||
* @throws | ||
* - NOT_A_PATH_ELEMENT: if the provided path doesn't exist or is not a valid path element | ||
*/ | ||
const buildPrecacheAssetPaths = (outDir, includeToPrecache, excludeFilesFromPrecache) => { | ||
// init the list of assets | ||
const assets = ['/']; | ||
// iterate over each asset that will be precached. Ensure to avoid the root path and files that | ||
// should be excluded | ||
includeToPrecache.forEach((path) => { | ||
if (path !== '/') { | ||
const el = __getPathElement(join(outDir, path)); | ||
if (el.isFile && !excludeFilesFromPrecache.includes(el.baseName)) { | ||
assets.push(path); | ||
} | ||
else { | ||
assets.push(...__extractCacheableFilesFromDirectory(outDir, el.path, excludeFilesFromPrecache)); | ||
} | ||
} | ||
}); | ||
// finally, return the completed list | ||
return assets; | ||
}; | ||
/** | ||
* Builds the binary's output build based on the config's outDir. | ||
* @param outDir | ||
* @returns string | ||
*/ | ||
const buildOutputPath = (outDir) => join(outDir, OUTPUT_NAME); | ||
/* ************************************************************************************************ | ||
* MODULE EXPORTS * | ||
************************************************************************************************ */ | ||
export { | ||
// constants | ||
CACHE_NAME_CHARACTERS, CACHE_NAME_LENGTH, OUTPUT_NAME, | ||
// implementation | ||
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))},__getPathElement=e=>{var 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=(r,e,t)=>{let o=readDirectory(e,!0);return(o=o.filter(e=>{e=__getPathElement(e);return e.isFile&&!t.includes(e.baseName)})).map(e=>e.replace(r,""))},readConfigFile=e=>{e=readJSONFile(e);return __validateConfigFile(e),e},generateCacheName=()=>{let e="",r=0;for(;r<CACHE_NAME_LENGTH;)e+=CACHE_NAME_CHARACTERS.charAt(Math.floor(Math.random()*CACHE_NAME_CHARACTERS.length)),r+=1;return e},buildPrecacheAssetPaths=(t,e,o)=>{const i=["/"];return e.forEach(e=>{var r;"/"!==e&&((r=__getPathElement(join(t,e))).isFile&&!o.includes(r.baseName)?i.push(e):i.push(...__extractCacheableFilesFromDirectory(t,r.path,o)))}),i},buildOutputPath=e=>join(e,OUTPUT_NAME);export{CACHE_NAME_CHARACTERS,CACHE_NAME_LENGTH,OUTPUT_NAME,readConfigFile,generateCacheName,buildPrecacheAssetPaths,buildOutputPath}; |
{ | ||
"name": "sw-builder", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"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.", | ||
@@ -9,3 +9,3 @@ "main": "dist/index.js", | ||
"scripts": { | ||
"start": "rm -r -f dist && tsc --project tsconfig.build.json", | ||
"start": "ts-lib-builder --tsconfigPath=tsconfig.build.json", | ||
"test": "echo \"Error: tests are executed with npm run test:(integration|unit)\" && exit 1", | ||
@@ -50,2 +50,3 @@ "test:integration": "vitest run --config vitest.test-integration.config.ts", | ||
"eslint-config-airbnb-typescript": "^18.0.0", | ||
"ts-lib-builder": "^1.0.2", | ||
"typescript": "^5.4.5", | ||
@@ -52,0 +53,0 @@ "vitest": "^1.6.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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
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
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
27
2
16783
7
206