import path from "node:path"; import process from "node:process"; import chalk from "chalk"; /** * @param {import('rollup').RollupBuild} bundle * @param {import('rollup').OutputOptions} [outputOptions] */ export const getCode = async (bundle, outputOptions, allFiles = false) => { const { output } = await bundle.generate(outputOptions || { format: 'cjs', exports: 'auto' }); if (allFiles) { return output.sort((a,b)=> { if(a.fileName === b.fileName && a.source !== b.source){ return a.source b.fileName? 1 : 0); }).map(({ code, fileName, source, map }) => { return { code, fileName, source, map }; }); } const [{ code }] = output; return code; }; export const debugPrintOutput = async (header, files) => { const out = []; const headFn = chalk.bgCyan; const headPadding = header.split('').map(x=>'#').join(''); out.push(...[ headFn(`##${headPadding}##`), headFn(`# ${header} #`), headFn(`##${headPadding}##`), ]); const fileHeadFn = chalk.blue; const fileContentFn = chalk.blackBright; out.push(...(files.map(file=>{ return [ fileHeadFn(`${file.fileName}:`), fileContentFn(`${file.code??file.source}`), '', ] }).flat())); out.push(...[ headFn(`##${headPadding}##`), ]); process.env.DEBUG? console.log(out.join('\n')) : null; }; /** * @param {import('rollup').RollupBuild} bundle * @param {import('rollup').OutputOptions} [outputOptions] */ export const getFiles = async (bundle, outputOptions) => { if (!outputOptions.dir && !outputOptions.file) throw new Error('You must specify "output.file" or "output.dir" for the build.'); const { output } = await bundle.generate(outputOptions || { format: 'cjs', exports: 'auto' }); return output.map(({ code, fileName, source }) => { const absPath = path.resolve(outputOptions.dir || path.dirname(outputOptions.file), fileName); return { fileName: path.relative(process.cwd(), absPath).split(path.sep).join('/'), content: code || source }; }); }; export const getImports = async (bundle) => { if (bundle.imports) { return bundle.imports; } const { output } = await bundle.generate({ format: 'es' }); const [{ imports }] = output; return imports; }; export const getResolvedModules = async (bundle) => { const { output: [{ modules }] } = await bundle.generate({ format: 'es' }); return modules; }; // eslint-disable-next-line no-console export const onwarn = (warning) => console.warn(warning.toString()); /** * @param {import('ava').Assertions} t * @param {import('rollup').RollupBuild} bundle * @param {object} args */ export const testBundle = async (t, bundle, { inject = {}, options = {} } = {}) => { const { output } = await bundle.generate({ format: 'cjs', exports: 'auto', ...options }); const [{ code }] = output; const module = { exports: {} }; // as of 1/2/2020 Github Actions + Windows has changed in a way that we must now escape backslashes const cwd = process.cwd().replace(/\\/g, '\\\\'); const params = ['module', 'exports', 'require', 't', ...Object.keys(inject)].concat( `process.chdir('${cwd}'); let result;\n\n${code}\n\nreturn result;` ); // eslint-disable-next-line no-new-func const func = new Function(...params); let error; let result; try { result = func(...[module, module.exports, require, t, ...Object.values(inject)]); } catch (e) { error = e; } return { code, error, module, result }; }; export const evaluateBundle = async (bundle) => { const { module } = await testBundle(null, bundle); return module.exports; };