UNPKG

broccoli-merge-files

Version:

Broccoli plugin to merge multiple files into one or multiple files

111 lines 4.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const broccoli_plugin_1 = __importDefault(require("broccoli-plugin")); const lodash_defaults_1 = __importDefault(require("lodash.defaults")); const fast_glob_1 = __importDefault(require("fast-glob")); const p_event_1 = __importDefault(require("p-event")); const path_1 = require("path"); const util_1 = require("util"); const fs_1 = require("fs"); const readFile = util_1.promisify(fs_1.readFile); const writeFile = util_1.promisify(fs_1.writeFile); var DuplicateStrategy; (function (DuplicateStrategy) { DuplicateStrategy["Prohibit"] = "prohibit"; DuplicateStrategy["KeepFirst"] = "keep-first"; DuplicateStrategy["KeepLast"] = "keep-last"; DuplicateStrategy["KeepAll"] = "keep-all"; })(DuplicateStrategy = exports.DuplicateStrategy || (exports.DuplicateStrategy = {})); const DEFAULT_OPTIONS = { patterns: '**/*', duplicates: DuplicateStrategy.Prohibit, encoding: 'utf8', sort: true }; class BroccoliMergeFiles extends broccoli_plugin_1.default { constructor(inputNodes, options) { super(inputNodes, { annotation: options.annotation, persistentOutput: false, needsCache: false }); this.options = lodash_defaults_1.default({}, options, DEFAULT_OPTIONS); } async build() { const entries = await this.readFiles(); const sorted = this.sort(entries); const deduplicated = this.deduplicate(sorted); const merged = await this.options.merge(deduplicated); await this.writeOutput(merged); } async readFiles() { const streams = this.inputPaths.map((path) => [ path, fast_glob_1.default.stream(this.options.patterns, Object.assign({}, this.options.globOptions, { cwd: path, absolute: false, unique: true, onlyFiles: true, onlyDirectories: false, transform: null, stats: false })) ]); const waiters = []; const entries = []; for (const [i, [cwd, stream]] of streams.entries()) { stream.on('data', path => entries.push(this.processFile(i, cwd, path))); waiters.push(p_event_1.default(stream, 'end')); } await Promise.all(waiters); return Promise.all(entries); } async processFile(i, cwd, path) { const absolutePath = path_1.resolve(cwd, path); const content = await readFile(absolutePath, { encoding: this.options.encoding }); if (typeof this.options.transformFile === 'function') { return [i, path, await this.options.transformFile(path, content)]; } return [i, path, content]; } sort(entries) { if (typeof this.options.sort === 'function') { return entries.sort(this.options.sort); } if (this.options.sort === true) { return entries.sort((a, b) => a[0] - b[0] || a[1].localeCompare(b[1])); } return entries; } deduplicate(entries) { if (this.options.duplicates === DuplicateStrategy.KeepAll) return entries.map(([, fileName, contents]) => [fileName, contents]); const map = new Map(); for (const [node, fileName, contents] of entries) { if (map.has(fileName)) { if (this.options.duplicates === DuplicateStrategy.Prohibit) throw new Error(`File '${fileName}' appears in node ${node}, but was already seen in a previous node.`); if (this.options.duplicates === DuplicateStrategy.KeepFirst) continue; } map.set(fileName, contents); } return [...map.entries()]; } async writeOutput(merged) { if (typeof this.options.outputFileName === 'string') { if (Array.isArray(merged)) throw new TypeError(`Expected 'merge' to return file contents for a single file, since 'outputFileName' has been specified.`); await this.writeOutputFile(this.options.outputFileName, merged); } else { if (!Array.isArray(merged)) throw new TypeError(`Expected 'merge' to return multiple file contents, since 'outputFileName' has not been specified.`); await Promise.all(merged.map(([fileName, contents]) => this.writeOutputFile(fileName, contents))); } } async writeOutputFile(fileName, contents) { await writeFile(path_1.resolve(this.outputPath, fileName), contents, { encoding: this.options.encoding }); } } exports.BroccoliMergeFiles = BroccoliMergeFiles; //# sourceMappingURL=index.js.map