UNPKG

@rollup-extras/plugin-clean

Version:
137 lines (133 loc) 4.75 kB
'use strict'; var fs = require('fs/promises'); var path = require('path'); var logger = require('@niceties/logger'); var options = require('@rollup-extras/utils/options'); var mutliConfigPluginBase = require('@rollup-extras/utils/mutli-config-plugin-base'); function index (options$1 = {}) { const inProgress = new Map(); const hasChildrenInProgress = new Map(); let deleted = false; const normalizedOptions = options.getOptions(options$1, { pluginName: '@rollup-extras/plugin-clean', deleteOnce: true, verbose: false, outputPlugin: true }, 'targets'); const { pluginName, deleteOnce, verbose, outputPlugin } = normalizedOptions; let { targets } = normalizedOptions; const instance = mutliConfigPluginBase.multiConfigPluginBase(false, pluginName, cleanup); const baseAddInstance = instance.api.addInstance; const baseRenderStart = instance.renderStart; if (outputPlugin) { instance.renderStart = async function (options, inputOptions) { baseRenderStart.call(this, options, inputOptions); await renderStart(options); }; } else { instance.buildStart = buildStart; instance.options = optionsHook; } instance.api.addInstance = () => { const instance = baseAddInstance(); const baseRenderStart = instance.renderStart; if (outputPlugin) { instance.renderStart = async function (options, inputOptions) { baseRenderStart.call(this, options, inputOptions); await renderStart(options); }; } else { instance.buildStart = buildStart; instance.options = optionsHook; } return instance; }; return instance; async function optionsHook(config) { if (!targets && config) { targets = (Array.isArray(config.output) ? config.output.map(item => item.dir) : [config.output?.dir]) .filter(Boolean); } return null; } async function buildStart() { if (deleted) { return; } if (targets) { await Promise.all(targets.map(removeDir)); } } async function renderStart(options) { if (deleted) { return; } if (!targets) { if (options.dir) { await removeDir(options.dir); } } else { await Promise.all(targets.map(removeDir)); } } async function removeDir(dir) { const normalizedDir = normalizeSlash(path.normalize(dir)); if (inProgress.has(normalizedDir)) { return outputPlugin && inProgress.get(normalizedDir); } let removePromise; let parentsInProgress; if (hasChildrenInProgress.has(dir)) { removePromise = Promise.resolve(hasChildrenInProgress.get(dir)) .then(() => doRemove(normalizedDir)); } else if ((parentsInProgress = Array.from(parentDirs(dir)).filter(item => inProgress.has(item))).length > 0) { return inProgress.get(parentsInProgress[0]); } else { removePromise = doRemove(normalizedDir); } inProgress.set(normalizedDir, removePromise); for (const parentDir of parentDirs(dir)) { if (!hasChildrenInProgress.has(parentDir)) { hasChildrenInProgress.set(parentDir, removePromise); } else { hasChildrenInProgress.set(parentDir, Promise.all([removePromise, hasChildrenInProgress.get(parentDir)])); } } return removePromise; } async function doRemove(normalizedDir) { const logger$1 = logger.createLogger(pluginName); try { logger$1.start(`cleaning '${normalizedDir}'`, verbose ? 1 /* LogLevel.info */ : 0 /* LogLevel.verbose */); await fs.rm(normalizedDir, { recursive: true }); logger$1.finish(`cleaned '${normalizedDir}'`); } catch (e) { // eslint-disable-line @typescript-eslint/no-explicit-any const loglevel = e['code'] === 'ENOENT' ? undefined : 2 /* LogLevel.warn */; logger$1.finish(`failed cleaning '${normalizedDir}'`, loglevel, e); } } function cleanup() { inProgress.clear(); hasChildrenInProgress.clear(); deleted = deleteOnce; } } function normalizeSlash(dir) { if (dir.endsWith('/')) { return `${dir.substring(0, dir.length - 1)}`; } return dir; } function* parentDirs(dir) { while (((dir = path.dirname(dir)) !== '.') && (dir !== '/')) { yield dir; } } module.exports = index;