From 23eeb22b8def6b16e4f03532f6a078a085db12be Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Sat, 8 Mar 2025 19:21:43 +0100 Subject: [PATCH 01/10] Bump required node version, remove npm-run-all --- .github/workflows/tests.yaml | 2 +- package.json | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e1b6302..b702ff6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -7,7 +7,7 @@ jobs: strategy: matrix: node-version: - - 18.x + - 20.x - 22.x - latest steps: diff --git a/package.json b/package.json index d6c5a77..4c81ce5 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "static files for faucet-pipeline", "main": "index.js", "scripts": { - "test": "npm-run-all --parallel lint test:cli", + "test": "npm run lint && npm run test:cli", "test:cli": "./test/run", "lint": "eslint --cache index.js test && echo ✓" }, @@ -19,7 +19,7 @@ }, "homepage": "https://www.faucet-pipeline.org", "engines": { - "node": ">= 18" + "node": ">= 20" }, "dependencies": { "faucet-pipeline-core": "^3.0.0" @@ -27,7 +27,6 @@ "devDependencies": { "eslint-config-fnd": "^1.13.0", "json-diff": "^1.0.0", - "npm-run-all": "^4.1.5", "release-util-fnd": "^3.0.0" } } From e3f330eabc0bc6006cb279fbbdf26aed5b69d2d0 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Sat, 8 Mar 2025 21:13:36 +0100 Subject: [PATCH 02/10] Vendor FileFinder to make this dual compatible, type the code --- index.js | 81 ++++++++++++++++++++++++++++++++++------ lib.js | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 11 ++++-- tsconfig.json | 13 +++++++ types.ts | 61 ++++++++++++++++++++++++++++++ 5 files changed, 250 insertions(+), 16 deletions(-) create mode 100644 lib.js create mode 100644 tsconfig.json create mode 100644 types.ts diff --git a/index.js b/index.js index 40833ac..de41d70 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,17 @@ -let { readFile, stat } = require("fs").promises; -let path = require("path"); -let { FileFinder } = require("faucet-pipeline-core/lib/util/files/finder"); +let { readFile, stat } = require("node:fs/promises"); +let path = require("node:path"); +let { FileFinder } = require("./lib.js"); +/** @import { + * Config, + * AssetManager, + * FaucetPlugin, + * FaucetPluginOptions, + * FaucetPluginFunc, + * CompactorMap, + * WriteFileOpts, + * ProcessFile + * } from "./types.ts" + **/ module.exports = { key: "static", @@ -8,6 +19,11 @@ module.exports = { plugin: faucetStatic }; +/** + * The static plugin copies files with an option to define compaction functions + * + * @type FaucetPlugin + */ function faucetStatic(config, assetManager, { compact } = {}) { let copiers = config.map(copyConfig => makeCopier(copyConfig, assetManager, { compact })); @@ -15,6 +31,14 @@ function faucetStatic(config, assetManager, { compact } = {}) { return filepaths => Promise.all(copiers.map(copy => copy(filepaths))); } +/** + * Create a copier for a single configuration + * + * @param {Config} copyConfig + * @param {AssetManager} assetManager + * @param {FaucetPluginOptions} options + * @returns {FaucetPluginFunc} + */ function makeCopier(copyConfig, assetManager, { compact } = {}) { let source = assetManager.resolvePath(copyConfig.source); let target = assetManager.resolvePath(copyConfig.target, { @@ -25,7 +49,7 @@ function makeCopier(copyConfig, assetManager, { compact } = {}) { filter: copyConfig.filter }); let { fingerprint } = copyConfig; - let plugins = determinePlugins(compact, copyConfig); + let compactors = determineCompactors(compact, copyConfig); return filepaths => { return Promise.all([ @@ -33,13 +57,20 @@ function makeCopier(copyConfig, assetManager, { compact } = {}) { determineTargetDir(source, target) ]).then(([fileNames, targetDir]) => { return processFiles(fileNames, { - assetManager, source, target, targetDir, plugins, fingerprint + assetManager, source, target, targetDir, compactors, fingerprint }); }); }; } -function determinePlugins(compact, copyConfig) { +/** + * Determine which compactors should be used + * + * @param {boolean | undefined} compact + * @param {Config} copyConfig + * @returns {CompactorMap} + */ +function determineCompactors(compact, copyConfig) { if(!compact) { return {}; } @@ -47,25 +78,42 @@ function determinePlugins(compact, copyConfig) { return copyConfig.compact || {}; } -// If `source` is a directory, `target` is used as target directory - -// otherwise, `target`'s parent directory is used +/** + * If `source` is a directory, `target` is used as target directory - + * otherwise, `target`'s parent directory is used + * + * @param {string} source + * @param {string} target + * @returns {Promise} + */ function determineTargetDir(source, target) { return stat(source). then(results => results.isDirectory() ? target : path.dirname(target)); } +/** + * @param {string[]} fileNames + * @param {ProcessFile} config + * @returns {Promise} + */ function processFiles(fileNames, config) { return Promise.all(fileNames.map(fileName => processFile(fileName, config))); } +/** + * @param {string} fileName + * @param {ProcessFile} opts + * @returns {Promise} + */ async function processFile(fileName, - { source, target, targetDir, fingerprint, assetManager, plugins }) { + { source, target, targetDir, fingerprint, assetManager, compactors }) { let sourcePath = path.join(source, fileName); let targetPath = path.join(target, fileName); try { var content = await readFile(sourcePath); // eslint-disable-line no-var } catch(err) { + // @ts-ignore if(err.code !== "ENOENT") { throw err; } @@ -74,11 +122,14 @@ async function processFile(fileName, } let type = determineFileType(sourcePath); - if(type && plugins[type]) { - let plugin = plugins[type]; - content = await plugin(content); + if(type && compactors[type]) { + let compactor = compactors[type]; + content = await compactor(content); } + /** + * @type WriteFileOpts + */ let options = { targetDir }; if(fingerprint !== undefined) { options.fingerprint = fingerprint; @@ -86,6 +137,12 @@ async function processFile(fileName, return assetManager.writeFile(targetPath, content, options); } +/** + * The filetype is the lower case file extension + * + * @param {string} sourcePath + * @returns {string} + */ function determineFileType(sourcePath) { return path.extname(sourcePath).substr(1).toLowerCase(); } diff --git a/lib.js b/lib.js new file mode 100644 index 0000000..10e31ec --- /dev/null +++ b/lib.js @@ -0,0 +1,100 @@ +let { readdir, stat } = require("node:fs/promises"); +let path = require("node:path"); +/** @import { FileFinderOptions } from "./types.ts" */ + +exports.FileFinder = class FileFinder { + /** + * @param {string} directory + * @param {FileFinderOptions} options? + */ + constructor(directory, { skipDotfiles, filter = () => true } = {}) { + this.directory = directory; + /** + * @param {string} filename + * @return {boolean} + */ + this.filter = filename => { + if(skipDotfiles && isDotfile(filename)) { + return false; + } + return filter(filename); + }; + } + + /** + * a list of relative file paths within the respective directory + * + * @returns {Promise} + */ + all() { + return tree(this.directory). + then(filenames => filenames.filter(this.filter)); + } + + /** + * all file paths that match the filter function + * + * @param {string[]} filepaths + * @returns {Promise} + */ + match(filepaths) { + return filesWithinDirectory(this.directory, filepaths). + then(filepaths => filepaths.filter(this.filter)); + } +}; + +/** + * @param {string} filepath + * @param {string} referenceDir + * @returns {Promise} + */ +function tree(filepath, referenceDir = filepath) { + return stat(filepath). + then(res => { + if(!res.isDirectory()) { + return [path.relative(referenceDir, filepath)]; + } + + return readdir(filepath). + then(entries => { + let res = Promise.all(entries.map(entry => { + return tree(path.join(filepath, entry), referenceDir); + })); + return res.then(flatten); + }); + }); +} + +/** + * @param {string} directory + * @param {string[]} files + * @returns {Promise} + */ +function filesWithinDirectory(directory, files) { + return new Promise(resolve => { + resolve(files. + map(filepath => path.relative(directory, filepath)). + filter(filename => !filename.startsWith(".."))); + }); +} + +/** + * @param {string} filename + * @returns {boolean} + */ +function isDotfile(filename) { + return path.basename(filename).startsWith("."); +} + +/** + * @param {string[][]} arr + * @returns {string[]} + */ +function flatten(arr) { + /** + * I'm deeply sorry for this + * @type string[] + */ + const akwardlyTypedStringArray = []; + return akwardlyTypedStringArray.concat.apply([], arr); +} diff --git a/package.json b/package.json index 4c81ce5..21616bd 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,10 @@ "description": "static files for faucet-pipeline", "main": "index.js", "scripts": { - "test": "npm run lint && npm run test:cli", + "test": "npm run lint && npm run typecheck && npm run test:cli", "test:cli": "./test/run", - "lint": "eslint --cache index.js test && echo ✓" + "lint": "eslint --cache index.js test && echo ✓", + "typecheck": "tsc" }, "repository": { "type": "git", @@ -22,11 +23,13 @@ "node": ">= 20" }, "dependencies": { - "faucet-pipeline-core": "^3.0.0" + "faucet-pipeline-core": "^2.0.0 || ^3.0.0" }, "devDependencies": { + "@types/node": "^22.13.10", "eslint-config-fnd": "^1.13.0", "json-diff": "^1.0.0", - "release-util-fnd": "^3.0.0" + "release-util-fnd": "^3.0.0", + "typescript": "^5.8.2" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8470e45 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "noEmit": true, + "strict": true, + "allowImportingTsExtensions": true, + "lib": ["dom", "es2023"], + }, + "exclude": [ + "./test/**", + ] +} diff --git a/types.ts b/types.ts new file mode 100644 index 0000000..2a9f94c --- /dev/null +++ b/types.ts @@ -0,0 +1,61 @@ +// faucet-pipeline-core types +export interface FaucetPlugin { + (config: T[], assetManager: AssetManager, options: FaucetPluginOptions): FaucetPluginFunc +} + +export interface FaucetPluginFunc { + (filepaths: string[]): Promise +} + +export interface FaucetPluginOptions { + browsers?: string[], + sourcemaps?: boolean, + compact?: boolean +} + +export interface AssetManager { + resolvePath: (path: string, opts?: ResolvePathOpts) => string + writeFile: (targetPath: string, content: Buffer, options: WriteFileOpts) => Promise +} + +export interface ResolvePathOpts { + enforceRelative?: boolean +} + +export interface WriteFileOpts { + targetDir: string, + fingerprint?: boolean +} + +// faucet-pipeline-static types +export interface Config { + source: string, + target: string, + targetDir: string, + fingerprint?: boolean, + compact?: CompactorMap, + assetManager: AssetManager, + filter?: (fileName: string) => boolean +} + +export interface CompactorMap { + [fileExtension: string]: Compactor +} + +export interface Compactor { + (contact: Buffer): Promise +} + +export interface ProcessFile { + source: string, + target: string, + targetDir: string, + fingerprint?: boolean, + compactors: CompactorMap, + assetManager: AssetManager, +} + +export interface FileFinderOptions { + skipDotfiles?: boolean, + filter?: (filename: string) => boolean +} From b5f35be10c15ea11b111fc8e368a9b0de00163e9 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Sat, 8 Mar 2025 21:57:02 +0100 Subject: [PATCH 03/10] Apply FND's suggestions * Improvements to FileFinder * Doc improvement * fileName => filename * determineCompactors * Inline processFiles * Code organization * Remove last `then` * Inline isDotfile --- lib.js | 100 --------------------------------------- index.js => lib/index.js | 99 +++++++++++++------------------------- lib/types.ts | 62 ++++++++++++++++++++++++ lib/util.js | 67 ++++++++++++++++++++++++++ package.json | 4 +- types.ts | 61 ------------------------ 6 files changed, 163 insertions(+), 230 deletions(-) delete mode 100644 lib.js rename index.js => lib/index.js (59%) create mode 100644 lib/types.ts create mode 100644 lib/util.js delete mode 100644 types.ts diff --git a/lib.js b/lib.js deleted file mode 100644 index 10e31ec..0000000 --- a/lib.js +++ /dev/null @@ -1,100 +0,0 @@ -let { readdir, stat } = require("node:fs/promises"); -let path = require("node:path"); -/** @import { FileFinderOptions } from "./types.ts" */ - -exports.FileFinder = class FileFinder { - /** - * @param {string} directory - * @param {FileFinderOptions} options? - */ - constructor(directory, { skipDotfiles, filter = () => true } = {}) { - this.directory = directory; - /** - * @param {string} filename - * @return {boolean} - */ - this.filter = filename => { - if(skipDotfiles && isDotfile(filename)) { - return false; - } - return filter(filename); - }; - } - - /** - * a list of relative file paths within the respective directory - * - * @returns {Promise} - */ - all() { - return tree(this.directory). - then(filenames => filenames.filter(this.filter)); - } - - /** - * all file paths that match the filter function - * - * @param {string[]} filepaths - * @returns {Promise} - */ - match(filepaths) { - return filesWithinDirectory(this.directory, filepaths). - then(filepaths => filepaths.filter(this.filter)); - } -}; - -/** - * @param {string} filepath - * @param {string} referenceDir - * @returns {Promise} - */ -function tree(filepath, referenceDir = filepath) { - return stat(filepath). - then(res => { - if(!res.isDirectory()) { - return [path.relative(referenceDir, filepath)]; - } - - return readdir(filepath). - then(entries => { - let res = Promise.all(entries.map(entry => { - return tree(path.join(filepath, entry), referenceDir); - })); - return res.then(flatten); - }); - }); -} - -/** - * @param {string} directory - * @param {string[]} files - * @returns {Promise} - */ -function filesWithinDirectory(directory, files) { - return new Promise(resolve => { - resolve(files. - map(filepath => path.relative(directory, filepath)). - filter(filename => !filename.startsWith(".."))); - }); -} - -/** - * @param {string} filename - * @returns {boolean} - */ -function isDotfile(filename) { - return path.basename(filename).startsWith("."); -} - -/** - * @param {string[][]} arr - * @returns {string[]} - */ -function flatten(arr) { - /** - * I'm deeply sorry for this - * @type string[] - */ - const akwardlyTypedStringArray = []; - return akwardlyTypedStringArray.concat.apply([], arr); -} diff --git a/index.js b/lib/index.js similarity index 59% rename from index.js rename to lib/index.js index de41d70..62c2370 100644 --- a/index.js +++ b/lib/index.js @@ -1,17 +1,6 @@ +let { FileFinder } = require("./util.js"); let { readFile, stat } = require("node:fs/promises"); let path = require("node:path"); -let { FileFinder } = require("./lib.js"); -/** @import { - * Config, - * AssetManager, - * FaucetPlugin, - * FaucetPluginOptions, - * FaucetPluginFunc, - * CompactorMap, - * WriteFileOpts, - * ProcessFile - * } from "./types.ts" - **/ module.exports = { key: "static", @@ -49,33 +38,18 @@ function makeCopier(copyConfig, assetManager, { compact } = {}) { filter: copyConfig.filter }); let { fingerprint } = copyConfig; - let compactors = determineCompactors(compact, copyConfig); + let compactors = (compact && copyConfig.compact) || {}; - return filepaths => { - return Promise.all([ + return async filepaths => { + let [filenames, targetDir] = await Promise.all([ (filepaths ? fileFinder.match(filepaths) : fileFinder.all()), determineTargetDir(source, target) - ]).then(([fileNames, targetDir]) => { - return processFiles(fileNames, { - assetManager, source, target, targetDir, compactors, fingerprint - }); - }); - }; -} - -/** - * Determine which compactors should be used - * - * @param {boolean | undefined} compact - * @param {Config} copyConfig - * @returns {CompactorMap} - */ -function determineCompactors(compact, copyConfig) { - if(!compact) { - return {}; - } + ]); - return copyConfig.compact || {}; + return Promise.all(filenames.map(filename => processFile(filename, { + assetManager, source, target, targetDir, compactors, fingerprint + }))); + }; } /** @@ -86,34 +60,25 @@ function determineCompactors(compact, copyConfig) { * @param {string} target * @returns {Promise} */ -function determineTargetDir(source, target) { - return stat(source). - then(results => results.isDirectory() ? target : path.dirname(target)); +async function determineTargetDir(source, target) { + let results = await stat(source); + return results.isDirectory() ? target : path.dirname(target); } /** - * @param {string[]} fileNames - * @param {ProcessFile} config - * @returns {Promise} - */ -function processFiles(fileNames, config) { - return Promise.all(fileNames.map(fileName => processFile(fileName, config))); -} - -/** - * @param {string} fileName + * @param {string} filename * @param {ProcessFile} opts * @returns {Promise} */ -async function processFile(fileName, +async function processFile(filename, { source, target, targetDir, fingerprint, assetManager, compactors }) { - let sourcePath = path.join(source, fileName); - let targetPath = path.join(target, fileName); + let sourcePath = path.join(source, filename); + let targetPath = path.join(target, filename); try { var content = await readFile(sourcePath); // eslint-disable-line no-var } catch(err) { - // @ts-ignore + // @ts-expect-error TS2345 if(err.code !== "ENOENT") { throw err; } @@ -121,15 +86,13 @@ async function processFile(fileName, return; } - let type = determineFileType(sourcePath); - if(type && compactors[type]) { - let compactor = compactors[type]; + let fileExtension = path.extname(sourcePath).substr(1).toLowerCase(); + if(fileExtension && compactors[fileExtension]) { + let compactor = compactors[fileExtension]; content = await compactor(content); } - /** - * @type WriteFileOpts - */ + /** @type WriteFileOpts */ let options = { targetDir }; if(fingerprint !== undefined) { options.fingerprint = fingerprint; @@ -137,12 +100,14 @@ async function processFile(fileName, return assetManager.writeFile(targetPath, content, options); } -/** - * The filetype is the lower case file extension - * - * @param {string} sourcePath - * @returns {string} - */ -function determineFileType(sourcePath) { - return path.extname(sourcePath).substr(1).toLowerCase(); -} +/** @import { + * Config, + * AssetManager, + * FaucetPlugin, + * FaucetPluginOptions, + * FaucetPluginFunc, + * CompactorMap, + * WriteFileOpts, + * ProcessFile + * } from "./types.ts" + **/ diff --git a/lib/types.ts b/lib/types.ts new file mode 100644 index 0000000..18584d2 --- /dev/null +++ b/lib/types.ts @@ -0,0 +1,62 @@ +// faucet-pipeline-core types +export interface FaucetPlugin { + (config: T[], assetManager: AssetManager, options: FaucetPluginOptions): FaucetPluginFunc +} + +export interface FaucetPluginFunc { + (filepaths: string[]): Promise +} + +export interface FaucetPluginOptions { + browsers?: string[], + sourcemaps?: boolean, + compact?: boolean +} + +export interface AssetManager { + resolvePath: (path: string, opts?: ResolvePathOpts) => string + writeFile: (targetPath: string, content: Buffer, options: WriteFileOpts) => Promise +} + +export interface ResolvePathOpts { + enforceRelative?: boolean +} + +export interface WriteFileOpts { + targetDir: string, + fingerprint?: boolean +} + +// faucet-pipeline-static types +export interface Config { + source: string, + target: string, + targetDir: string, + fingerprint?: boolean, + compact?: CompactorMap, + assetManager: AssetManager, + filter?: (filename: string) => boolean +} + +export interface CompactorMap { + [fileExtension: string]: Compactor +} + +export interface Compactor { + (contact: Buffer): Promise +} + +export interface ProcessFile { + source: string, + target: string, + targetDir: string, + fingerprint?: boolean, + compactors: CompactorMap, + assetManager: AssetManager, + filter?: (filename: string) => boolean +} + +export interface FileFinderOptions { + skipDotfiles: boolean, + filter?: (filename: string) => boolean +} diff --git a/lib/util.js b/lib/util.js new file mode 100644 index 0000000..c60351b --- /dev/null +++ b/lib/util.js @@ -0,0 +1,67 @@ +let { readdir, stat } = require("node:fs/promises"); +let path = require("node:path"); + +exports.FileFinder = class FileFinder { + /** + * @param {string} root + * @param {FileFinderOptions} options + */ + constructor(root, { skipDotfiles, filter }) { + this._root = root; + + /** + * @param {string} filename + * @return {boolean} + */ + this._filter = filename => { + if(skipDotfiles && path.basename(filename).startsWith(".")) { + return false; + } + return filter ? filter(filename) : true; + }; + } + + /** + * a list of relative file paths within the respective directory + * + * @returns {Promise} + */ + async all() { + let filenames = await tree(this._root); + return filenames.filter(this._filter); + } + + /** + * all file paths that match the filter function + * + * @param {string[]} filepaths + * @returns {Promise} + */ + async match(filepaths) { + return filepaths.map(filepath => path.relative(this._root, filepath)). + filter(filename => !filename.startsWith("..")). + filter(this._filter); + } +}; + +/** + * flat list of all files of a directory tree + * + * @param {string} filepath + * @param {string} referenceDir + * @returns {Promise} + */ +async function tree(filepath, referenceDir = filepath) { + let stats = await stat(filepath); + + if(!stats.isDirectory()) { + return [path.relative(referenceDir, filepath)]; + } + + let entries = await Promise.all((await readdir(filepath)).map(entry => { + return tree(path.join(filepath, entry), referenceDir); + })); + return entries.flat(); +} + +/** @import { FileFinderOptions } from "./types.ts" */ diff --git a/package.json b/package.json index 21616bd..ba03b6b 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,11 @@ "name": "faucet-pipeline-static", "version": "2.1.0", "description": "static files for faucet-pipeline", - "main": "index.js", + "main": "lib/index.js", "scripts": { "test": "npm run lint && npm run typecheck && npm run test:cli", "test:cli": "./test/run", - "lint": "eslint --cache index.js test && echo ✓", + "lint": "eslint --cache lib test && echo ✓", "typecheck": "tsc" }, "repository": { diff --git a/types.ts b/types.ts deleted file mode 100644 index 2a9f94c..0000000 --- a/types.ts +++ /dev/null @@ -1,61 +0,0 @@ -// faucet-pipeline-core types -export interface FaucetPlugin { - (config: T[], assetManager: AssetManager, options: FaucetPluginOptions): FaucetPluginFunc -} - -export interface FaucetPluginFunc { - (filepaths: string[]): Promise -} - -export interface FaucetPluginOptions { - browsers?: string[], - sourcemaps?: boolean, - compact?: boolean -} - -export interface AssetManager { - resolvePath: (path: string, opts?: ResolvePathOpts) => string - writeFile: (targetPath: string, content: Buffer, options: WriteFileOpts) => Promise -} - -export interface ResolvePathOpts { - enforceRelative?: boolean -} - -export interface WriteFileOpts { - targetDir: string, - fingerprint?: boolean -} - -// faucet-pipeline-static types -export interface Config { - source: string, - target: string, - targetDir: string, - fingerprint?: boolean, - compact?: CompactorMap, - assetManager: AssetManager, - filter?: (fileName: string) => boolean -} - -export interface CompactorMap { - [fileExtension: string]: Compactor -} - -export interface Compactor { - (contact: Buffer): Promise -} - -export interface ProcessFile { - source: string, - target: string, - targetDir: string, - fingerprint?: boolean, - compactors: CompactorMap, - assetManager: AssetManager, -} - -export interface FileFinderOptions { - skipDotfiles?: boolean, - filter?: (filename: string) => boolean -} From ac3bda670e96269219478842d4f54cb481a37f84 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Sat, 15 Mar 2025 17:57:13 +0100 Subject: [PATCH 04/10] Set the minimum Node version to 20.19.0 --- .github/workflows/tests.yaml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b702ff6..c6eea5a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -7,7 +7,7 @@ jobs: strategy: matrix: node-version: - - 20.x + - 20.19 - 22.x - latest steps: diff --git a/package.json b/package.json index ba03b6b..c3a9f27 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "homepage": "https://www.faucet-pipeline.org", "engines": { - "node": ">= 20" + "node": ">= 20.19.0" }, "dependencies": { "faucet-pipeline-core": "^2.0.0 || ^3.0.0" From c9522ba8f2a46a1a0a856b5d2aa8b678fcef4912 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Sat, 15 Mar 2025 18:26:17 +0100 Subject: [PATCH 05/10] ESM --- lib/index.js | 21 ++++++---------- lib/util.js | 8 +++--- package.json | 1 + test/test_basic/faucet.config.js | 17 ++++++------- test/test_fingerprint/faucet.config.js | 22 ++++++++-------- test/test_key_config/faucet.config.js | 24 +++++++++--------- .../test_key_for_single_file/faucet.config.js | 24 +++++++++--------- test/test_manifest_base_uri/faucet.config.js | 24 +++++++++--------- test/test_match_dirname/faucet.config.js | 19 +++++++------- test/test_match_extension/faucet.config.js | 19 +++++++------- test/test_match_multiple/faucet.config.js | 19 +++++++------- test/test_match_negation/faucet.config.js | 19 +++++++------- test/test_no_fingerprint/faucet.config.js | 25 +++++++++---------- test/test_single/faucet.config.js | 17 ++++++------- tsconfig.json | 1 + 15 files changed, 124 insertions(+), 136 deletions(-) diff --git a/lib/index.js b/lib/index.js index 62c2370..a60deb3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,19 +1,12 @@ -let { FileFinder } = require("./util.js"); -let { readFile, stat } = require("node:fs/promises"); -let path = require("node:path"); +import { FileFinder } from "./util.js"; +import { readFile, stat } from "node:fs/promises"; +import * as path from "node:path"; -module.exports = { - key: "static", - bucket: "static", - plugin: faucetStatic -}; +export const key = "static"; +export const bucket = "static"; -/** - * The static plugin copies files with an option to define compaction functions - * - * @type FaucetPlugin - */ -function faucetStatic(config, assetManager, { compact } = {}) { +/** @type FaucetPlugin */ +export function plugin(config, assetManager, { compact } = {}) { let copiers = config.map(copyConfig => makeCopier(copyConfig, assetManager, { compact })); diff --git a/lib/util.js b/lib/util.js index c60351b..1e3ff17 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,7 +1,7 @@ -let { readdir, stat } = require("node:fs/promises"); -let path = require("node:path"); +import { readdir, stat } from "node:fs/promises"; +import * as path from "node:path"; -exports.FileFinder = class FileFinder { +export class FileFinder { /** * @param {string} root * @param {FileFinderOptions} options @@ -42,7 +42,7 @@ exports.FileFinder = class FileFinder { filter(filename => !filename.startsWith("..")). filter(this._filter); } -}; +} /** * flat list of all files of a directory tree diff --git a/package.json b/package.json index c3a9f27..11dab25 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "2.1.0", "description": "static files for faucet-pipeline", "main": "lib/index.js", + "type": "module", "scripts": { "test": "npm run lint && npm run typecheck && npm run test:cli", "test:cli": "./test/run", diff --git a/test/test_basic/faucet.config.js b/test/test_basic/faucet.config.js index c075370..7e9350c 100644 --- a/test/test_basic/faucet.config.js +++ b/test/test_basic/faucet.config.js @@ -1,10 +1,9 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist" - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src", + target: "./dist" +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_fingerprint/faucet.config.js b/test/test_fingerprint/faucet.config.js index 1bd7f28..340eab5 100644 --- a/test/test_fingerprint/faucet.config.js +++ b/test/test_fingerprint/faucet.config.js @@ -1,13 +1,13 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist" - }], - manifest: { - target: "./dist/manifest.json" - }, - plugins: [path.resolve(__dirname, "../..")] +const config = [{ + source: "./src", + target: "./dist" +}]; +export { config as static }; + +export const manifest = { + target: "./dist/manifest.json" }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_key_config/faucet.config.js b/test/test_key_config/faucet.config.js index 3ff6f64..6a1a831 100644 --- a/test/test_key_config/faucet.config.js +++ b/test/test_key_config/faucet.config.js @@ -1,14 +1,14 @@ -"use strict"; -let path = require("path"); +import { resolve, relative } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist" - }], - manifest: { - target: "./dist/manifest.json", - key: (f, targetDir) => path.relative(targetDir, f) - }, - plugins: [path.resolve(__dirname, "../..")] +const config = [{ + source: "./src", + target: "./dist" +}]; +export { config as static }; + +export const manifest = { + target: "./dist/manifest.json", + key: (f, targetDir) => relative(targetDir, f) }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_key_for_single_file/faucet.config.js b/test/test_key_for_single_file/faucet.config.js index 4642185..df75818 100644 --- a/test/test_key_for_single_file/faucet.config.js +++ b/test/test_key_for_single_file/faucet.config.js @@ -1,14 +1,14 @@ -"use strict"; -let path = require("path"); +import { resolve, relative } from "node:path"; -module.exports = { - static: [{ - source: "./src/test.txt", - target: "./dist/test.txt" - }], - manifest: { - target: "./dist/manifest.json", - key: (f, targetDir) => path.relative(targetDir, f) - }, - plugins: [path.resolve(__dirname, "../..")] +const config = [{ + source: "./src/test.txt", + target: "./dist/test.txt" +}]; +export { config as static }; + +export const manifest = { + target: "./dist/manifest.json", + key: (f, targetDir) => relative(targetDir, f) }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_manifest_base_uri/faucet.config.js b/test/test_manifest_base_uri/faucet.config.js index 1dd1fca..dbd6b42 100644 --- a/test/test_manifest_base_uri/faucet.config.js +++ b/test/test_manifest_base_uri/faucet.config.js @@ -1,14 +1,14 @@ -"use strict"; -let path = require("path"); +import { resolve, relative } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist" - }], - manifest: { - target: "./dist/manifest.json", - value: f => `/assets/${path.relative("./dist", f)}` - }, - plugins: [path.resolve(__dirname, "../..")] +const config = [{ + source: "./src", + target: "./dist" +}]; +export { config as static }; + +export const manifest = { + target: "./dist/manifest.json", + value: f => `/assets/${relative("./dist", f)}` }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_match_dirname/faucet.config.js b/test/test_match_dirname/faucet.config.js index d17a793..92ac275 100644 --- a/test/test_match_dirname/faucet.config.js +++ b/test/test_match_dirname/faucet.config.js @@ -1,11 +1,10 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist", - filter: path => path.startsWith("inner/") - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src", + target: "./dist", + filter: path => path.startsWith("inner/") +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_match_extension/faucet.config.js b/test/test_match_extension/faucet.config.js index ca52325..4637f00 100644 --- a/test/test_match_extension/faucet.config.js +++ b/test/test_match_extension/faucet.config.js @@ -1,11 +1,10 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist", - filter: path => path.endsWith(".txt") - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src", + target: "./dist", + filter: path => path.endsWith(".txt") +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_match_multiple/faucet.config.js b/test/test_match_multiple/faucet.config.js index 10c5111..d8e6288 100644 --- a/test/test_match_multiple/faucet.config.js +++ b/test/test_match_multiple/faucet.config.js @@ -1,11 +1,10 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist", - filter: path => path.endsWith(".txt") && !path.startsWith("inner/") - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src", + target: "./dist", + filter: path => path.endsWith(".txt") && !path.startsWith("inner/") +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_match_negation/faucet.config.js b/test/test_match_negation/faucet.config.js index ec5b8cf..7ba2216 100644 --- a/test/test_match_negation/faucet.config.js +++ b/test/test_match_negation/faucet.config.js @@ -1,11 +1,10 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist", - filter: path => !path.endsWith("/test2.txt") - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src", + target: "./dist", + filter: path => !path.endsWith("/test2.txt") +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_no_fingerprint/faucet.config.js b/test/test_no_fingerprint/faucet.config.js index f46b3cf..0731458 100644 --- a/test/test_no_fingerprint/faucet.config.js +++ b/test/test_no_fingerprint/faucet.config.js @@ -1,14 +1,13 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src", - target: "./dist/no-fingerprint", - fingerprint: false - }, { - source: "./src", - target: "./dist/fingerprint" - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src", + target: "./dist/no-fingerprint", + fingerprint: false +}, { + source: "./src", + target: "./dist/fingerprint" +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/test/test_single/faucet.config.js b/test/test_single/faucet.config.js index 4fac638..e6ae6c4 100644 --- a/test/test_single/faucet.config.js +++ b/test/test_single/faucet.config.js @@ -1,10 +1,9 @@ -"use strict"; -let path = require("path"); +import { resolve } from "node:path"; -module.exports = { - static: [{ - source: "./src.txt", - target: "./dist/dist.txt" - }], - plugins: [path.resolve(__dirname, "../..")] -}; +const config = [{ + source: "./src.txt", + target: "./dist/dist.txt" +}]; +export { config as static }; + +export const plugins = [resolve(import.meta.dirname, "../..")]; diff --git a/tsconfig.json b/tsconfig.json index 8470e45..56eb02c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "strict": true, "allowImportingTsExtensions": true, "lib": ["dom", "es2023"], + "module": "nodenext" }, "exclude": [ "./test/**", From 4e0bbb3202f1fed2cf8e1105ec2b5e885cf373f0 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Sun, 9 Mar 2025 19:35:39 +0100 Subject: [PATCH 06/10] Make this pipeline the basis for other file processors --- lib/index.js | 116 +++++++++++++++++---------------------------------- lib/types.ts | 15 ++++--- lib/util.js | 62 ++++++++++++++++++++++++--- 3 files changed, 106 insertions(+), 87 deletions(-) diff --git a/lib/index.js b/lib/index.js index a60deb3..ba3c969 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,105 +1,67 @@ -import { FileFinder } from "./util.js"; -import { readFile, stat } from "node:fs/promises"; +import { buildProcessPipeline } from "./util.js"; +import { readFile } from "node:fs/promises"; import * as path from "node:path"; export const key = "static"; export const bucket = "static"; /** @type FaucetPlugin */ -export function plugin(config, assetManager, { compact } = {}) { - let copiers = config.map(copyConfig => - makeCopier(copyConfig, assetManager, { compact })); +export function plugin(config, assetManager, options) { + let pipeline = config.map(copyConfig => { + let processFile = buildProcessFile(copyConfig, options); + let { source, target, filter } = copyConfig; + return buildProcessPipeline(source, target, processFile, assetManager, filter); + }); - return filepaths => Promise.all(copiers.map(copy => copy(filepaths))); + return filepaths => Promise.all(pipeline.map(copy => copy(filepaths))); } /** - * Create a copier for a single configuration + * Returns a function that copies a single file with optional compactor * * @param {Config} copyConfig - * @param {AssetManager} assetManager * @param {FaucetPluginOptions} options - * @returns {FaucetPluginFunc} + * @returns {ProcessFile} */ -function makeCopier(copyConfig, assetManager, { compact } = {}) { - let source = assetManager.resolvePath(copyConfig.source); - let target = assetManager.resolvePath(copyConfig.target, { - enforceRelative: true - }); - let fileFinder = new FileFinder(source, { - skipDotfiles: true, - filter: copyConfig.filter - }); - let { fingerprint } = copyConfig; - let compactors = (compact && copyConfig.compact) || {}; +function buildProcessFile(copyConfig, options) { + let compactors = (options.compact && copyConfig.compact) || {}; - return async filepaths => { - let [filenames, targetDir] = await Promise.all([ - (filepaths ? fileFinder.match(filepaths) : fileFinder.all()), - determineTargetDir(source, target) - ]); + return async function(filename, + { source, target, targetDir, assetManager }) { + let sourcePath = path.join(source, filename); + let targetPath = path.join(target, filename); + let content; - return Promise.all(filenames.map(filename => processFile(filename, { - assetManager, source, target, targetDir, compactors, fingerprint - }))); - }; -} - -/** - * If `source` is a directory, `target` is used as target directory - - * otherwise, `target`'s parent directory is used - * - * @param {string} source - * @param {string} target - * @returns {Promise} - */ -async function determineTargetDir(source, target) { - let results = await stat(source); - return results.isDirectory() ? target : path.dirname(target); -} - -/** - * @param {string} filename - * @param {ProcessFile} opts - * @returns {Promise} - */ -async function processFile(filename, - { source, target, targetDir, fingerprint, assetManager, compactors }) { - let sourcePath = path.join(source, filename); - let targetPath = path.join(target, filename); - - try { - var content = await readFile(sourcePath); // eslint-disable-line no-var - } catch(err) { - // @ts-expect-error TS2345 - if(err.code !== "ENOENT") { - throw err; + try { + content = await readFile(sourcePath); + } catch(err) { + // @ts-expect-error TS2345 + if(err.code !== "ENOENT") { + throw err; + } + console.error(`WARNING: \`${sourcePath}\` no longer exists`); + return; } - console.error(`WARNING: \`${sourcePath}\` no longer exists`); - return; - } - let fileExtension = path.extname(sourcePath).substr(1).toLowerCase(); - if(fileExtension && compactors[fileExtension]) { - let compactor = compactors[fileExtension]; - content = await compactor(content); - } + let fileExtension = path.extname(sourcePath).substr(1).toLowerCase(); + if(fileExtension && compactors[fileExtension]) { + let compactor = compactors[fileExtension]; + content = await compactor(content); + } - /** @type WriteFileOpts */ - let options = { targetDir }; - if(fingerprint !== undefined) { - options.fingerprint = fingerprint; - } - return assetManager.writeFile(targetPath, content, options); + /** @type WriteFileOpts */ + let options = { targetDir }; + if(copyConfig.fingerprint !== undefined) { + options.fingerprint = copyConfig.fingerprint; + } + return assetManager.writeFile(targetPath, content, options); + }; } /** @import { * Config, - * AssetManager, * FaucetPlugin, * FaucetPluginOptions, - * FaucetPluginFunc, - * CompactorMap, * WriteFileOpts, * ProcessFile * } from "./types.ts" diff --git a/lib/types.ts b/lib/types.ts index 18584d2..1a0b768 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -35,7 +35,7 @@ export interface Config { fingerprint?: boolean, compact?: CompactorMap, assetManager: AssetManager, - filter?: (filename: string) => boolean + filter?: Filter } export interface CompactorMap { @@ -47,16 +47,21 @@ export interface Compactor { } export interface ProcessFile { + (filename: string, opts: ProcessFileOptions): Promise +} + +export interface ProcessFileOptions { source: string, target: string, targetDir: string, - fingerprint?: boolean, - compactors: CompactorMap, assetManager: AssetManager, - filter?: (filename: string) => boolean } export interface FileFinderOptions { skipDotfiles: boolean, - filter?: (filename: string) => boolean + filter?: Filter +} + +export interface Filter { + (filename: string): boolean } diff --git a/lib/util.js b/lib/util.js index 1e3ff17..79eef80 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,7 +1,52 @@ import { readdir, stat } from "node:fs/promises"; import * as path from "node:path"; -export class FileFinder { +/** + * Creates a processor for a single configuration + * + * @param {string} source - the source folder or file for this pipeline + * @param {string} target - the target folder or file for this pipeline + * @param {ProcessFile} processFile - process a single file + * @param {AssetManager} assetManager + * @param {Filter} [filter] - optional filter based on filenames + * @returns {FaucetPluginFunc} + */ +export function buildProcessPipeline(source, target, processFile, assetManager, filter) { + source = assetManager.resolvePath(source); + target = assetManager.resolvePath(target, { + enforceRelative: true + }); + let fileFinder = new FileFinder(source, { + skipDotfiles: true, + filter + }); + + return async filepaths => { + let [filenames, targetDir] = await Promise.all([ + (filepaths ? fileFinder.match(filepaths) : fileFinder.all()), + determineTargetDir(source, target) + ]); + + return Promise.all(filenames.map(filename => processFile(filename, { + assetManager, source, target, targetDir + }))); + }; +} + +/** + * If `source` is a directory, `target` is used as target directory - + * otherwise, `target`'s parent directory is used + * + * @param {string} source + * @param {string} target + * @returns {Promise} + */ +async function determineTargetDir(source, target) { + let results = await stat(source); + return results.isDirectory() ? target : path.dirname(target); +} + +class FileFinder { /** * @param {string} root * @param {FileFinderOptions} options @@ -22,7 +67,7 @@ export class FileFinder { } /** - * a list of relative file paths within the respective directory + * A list of relative file paths within the respective directory * * @returns {Promise} */ @@ -32,7 +77,7 @@ export class FileFinder { } /** - * all file paths that match the filter function + * All file paths that match the filter function * * @param {string[]} filepaths * @returns {Promise} @@ -45,7 +90,7 @@ export class FileFinder { } /** - * flat list of all files of a directory tree + * Flat list of all files of a directory tree * * @param {string} filepath * @param {string} referenceDir @@ -64,4 +109,11 @@ async function tree(filepath, referenceDir = filepath) { return entries.flat(); } -/** @import { FileFinderOptions } from "./types.ts" */ +/** @import { + * AssetManager, + * FaucetPluginFunc, + * Filter, + * FileFinderOptions, + * ProcessFile + * } from "./types.ts" + **/ From 5f5e8f0038b78e6e42dc970662796a6ef20ddfd3 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Tue, 22 Apr 2025 13:34:04 +0200 Subject: [PATCH 07/10] FND appeasements --- lib/index.js | 21 +++++++++++---------- lib/types.ts | 2 +- lib/util.js | 19 ++++++++++--------- package.json | 4 ++-- tsconfig.json | 4 +--- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lib/index.js b/lib/index.js index ba3c969..1dc39ca 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,6 @@ import { buildProcessPipeline } from "./util.js"; import { readFile } from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; export const key = "static"; export const bucket = "static"; @@ -30,8 +30,8 @@ function buildProcessFile(copyConfig, options) { { source, target, targetDir, assetManager }) { let sourcePath = path.join(source, filename); let targetPath = path.join(target, filename); - let content; + let content; try { content = await readFile(sourcePath); } catch(err) { @@ -58,11 +58,12 @@ function buildProcessFile(copyConfig, options) { }; } -/** @import { - * Config, - * FaucetPlugin, - * FaucetPluginOptions, - * WriteFileOpts, - * ProcessFile - * } from "./types.ts" - **/ +/** + * @import { + * Config, + * FaucetPlugin, + * FaucetPluginOptions, + * WriteFileOpts, + * ProcessFile + * } from "./types.ts" +*/ diff --git a/lib/types.ts b/lib/types.ts index 1a0b768..3e6a0af 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -15,7 +15,7 @@ export interface FaucetPluginOptions { export interface AssetManager { resolvePath: (path: string, opts?: ResolvePathOpts) => string - writeFile: (targetPath: string, content: Buffer, options: WriteFileOpts) => Promise + writeFile: (targetPath: string, content: Buffer, options: WriteFileOpts) => Promise } export interface ResolvePathOpts { diff --git a/lib/util.js b/lib/util.js index 79eef80..b14189d 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,5 +1,5 @@ import { readdir, stat } from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; /** * Creates a processor for a single configuration @@ -109,11 +109,12 @@ async function tree(filepath, referenceDir = filepath) { return entries.flat(); } -/** @import { - * AssetManager, - * FaucetPluginFunc, - * Filter, - * FileFinderOptions, - * ProcessFile - * } from "./types.ts" - **/ +/** + * @import { + * AssetManager, + * FaucetPluginFunc, + * Filter, + * FileFinderOptions, + * ProcessFile + * } from "./types.ts" +*/ diff --git a/package.json b/package.json index 11dab25..7f10295 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,12 @@ "name": "faucet-pipeline-static", "version": "2.1.0", "description": "static files for faucet-pipeline", - "main": "lib/index.js", + "main": "./lib/index.js", "type": "module", "scripts": { "test": "npm run lint && npm run typecheck && npm run test:cli", "test:cli": "./test/run", - "lint": "eslint --cache lib test && echo ✓", + "lint": "eslint --cache ./lib ./test && echo ✓", "typecheck": "tsc" }, "repository": { diff --git a/tsconfig.json b/tsconfig.json index 56eb02c..048f8cf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,5 @@ "lib": ["dom", "es2023"], "module": "nodenext" }, - "exclude": [ - "./test/**", - ] + "exclude": ["./test/**"] } From 25e8ef9f7d4dfb68744d088aeac8dfc730b319df Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Tue, 22 Apr 2025 13:47:09 +0200 Subject: [PATCH 08/10] Improve tsconfig --- tsconfig.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 048f8cf..c09dc11 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,9 @@ "strict": true, "allowImportingTsExtensions": true, "lib": ["dom", "es2023"], - "module": "nodenext" + "module": "nodenext", + "isolatedModules": true, + "erasableSyntaxOnly": true }, "exclude": ["./test/**"] } From 06b436b85d2ba434945f2c83c3e46bfeb5086ad8 Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Wed, 23 Apr 2025 11:18:44 +0200 Subject: [PATCH 09/10] v2.2.0 --- .github/workflows/tests.yaml | 2 +- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c6eea5a..b702ff6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -7,7 +7,7 @@ jobs: strategy: matrix: node-version: - - 20.19 + - 20.x - 22.x - latest steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b12557..650a902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ faucet-pipeline-static version history ====================================== +v2.2.0 +------ + +_TBD_ + +maintenance release to update dependencies; no significant changes + +improvements for developers: + +* it now exposes `buildProcessPipeline` for other pipelines that convert directories of files instead of single files + + v2.1.0 ------ diff --git a/package.json b/package.json index 7f10295..876599e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "faucet-pipeline-static", - "version": "2.1.0", + "version": "2.2.0", "description": "static files for faucet-pipeline", "main": "./lib/index.js", "type": "module", From cd249cb16f81f5fbd3a0b9745a8d029c1e2e865b Mon Sep 17 00:00:00 2001 From: Lucas Dohmen Date: Mon, 19 May 2025 09:36:08 +0200 Subject: [PATCH 10/10] Use the types.ts from core --- lib/index.js | 7 +++++-- lib/types.ts | 30 +----------------------------- lib/util.js | 7 +++++-- package.json | 2 +- 4 files changed, 12 insertions(+), 34 deletions(-) diff --git a/lib/index.js b/lib/index.js index 1dc39ca..a2ad2a7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -61,9 +61,12 @@ function buildProcessFile(copyConfig, options) { /** * @import { * Config, + * ProcessFile + * } from "./types.ts" + * + * @import { * FaucetPlugin, * FaucetPluginOptions, * WriteFileOpts, - * ProcessFile - * } from "./types.ts" + * } from "faucet-pipeline-core/lib/types.ts" */ diff --git a/lib/types.ts b/lib/types.ts index 3e6a0af..357269a 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,33 +1,5 @@ -// faucet-pipeline-core types -export interface FaucetPlugin { - (config: T[], assetManager: AssetManager, options: FaucetPluginOptions): FaucetPluginFunc -} - -export interface FaucetPluginFunc { - (filepaths: string[]): Promise -} - -export interface FaucetPluginOptions { - browsers?: string[], - sourcemaps?: boolean, - compact?: boolean -} - -export interface AssetManager { - resolvePath: (path: string, opts?: ResolvePathOpts) => string - writeFile: (targetPath: string, content: Buffer, options: WriteFileOpts) => Promise -} - -export interface ResolvePathOpts { - enforceRelative?: boolean -} - -export interface WriteFileOpts { - targetDir: string, - fingerprint?: boolean -} +import { AssetManager } from "faucet-pipeline-core/lib/types.ts" -// faucet-pipeline-static types export interface Config { source: string, target: string, diff --git a/lib/util.js b/lib/util.js index b14189d..2084d9d 100644 --- a/lib/util.js +++ b/lib/util.js @@ -111,10 +111,13 @@ async function tree(filepath, referenceDir = filepath) { /** * @import { - * AssetManager, - * FaucetPluginFunc, * Filter, * FileFinderOptions, * ProcessFile * } from "./types.ts" + * + * @import { + * AssetManager, + * FaucetPluginFunc, + * } from "faucet-pipeline-core/lib/types.ts" */ diff --git a/package.json b/package.json index 876599e..c64c1e5 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "node": ">= 20.19.0" }, "dependencies": { - "faucet-pipeline-core": "^2.0.0 || ^3.0.0" + "faucet-pipeline-core": "git+https://github.com/faucet-pipeline/faucet-pipeline-core.git#util-cleanup" }, "devDependencies": { "@types/node": "^22.13.10",