rsbuild-plugin-publint
Version:
74 lines (73 loc) • 3.92 kB
JavaScript
import promises from "node:fs/promises";
import { join } from "node:path";
import { styleText } from "node:util";
import { logger } from "@rsbuild/core";
const formatCountMessage = (color, count, singular, plural)=>[
styleText(color, 'Publint found '),
styleText([
color,
'bold'
], String(count)),
styleText(color, ` ${1 === count ? singular : plural}:`)
].join('');
const pluginPublint = (options = {})=>({
name: 'plugin-publint',
setup (api) {
const { enable = true, throwOn = 'error' } = options;
if (!enable) return;
api.onAfterBuild({
handler: async ({ isFirstCompile, isWatch })=>{
if (!isFirstCompile) return;
const { publint } = await import("publint");
const { formatMessage } = await import("publint/utils");
const mergedOptions = {
pkgDir: api.context.rootPath,
...options.publintOptions
};
const { messages } = await publint(mergedOptions);
const pkg = JSON.parse(await promises.readFile(join(mergedOptions.pkgDir, 'package.json'), 'utf8'));
const formatted = {
errors: [],
warnings: [],
suggestions: []
};
for (const message of messages)if ('error' === message.type) formatted.errors.push(formatMessage(message, pkg));
else if ('warning' === message.type) formatted.warnings.push(formatMessage(message, pkg));
else formatted.suggestions.push(formatMessage(message, pkg));
if (0 === formatted.errors.length && 0 === formatted.warnings.length && 0 === formatted.suggestions.length) logger.info(styleText('green', 'Publint passed.'));
const errorsCount = formatted.errors.length;
if (errorsCount > 0) {
logger.error(formatCountMessage('red', errorsCount, 'error', 'errors'));
for (const message of formatted.errors)if (message) logger.error(message);
console.log();
}
const warningsCount = formatted.warnings.length;
if (warningsCount > 0) {
logger.warn(formatCountMessage('yellow', warningsCount, 'warning', 'warnings'));
for (const message of formatted.warnings)if (message) logger.warn(message);
console.log();
}
const suggestionsCount = formatted.suggestions.length;
if (suggestionsCount > 0) {
logger.info(formatCountMessage('cyan', suggestionsCount, 'suggestion', 'suggestions'));
for (const message of formatted.suggestions)if (message) logger.info(message);
}
const shouldThrow = ()=>{
switch(throwOn){
case 'suggestion':
return formatted.suggestions.length > 0 || formatted.warnings.length > 0 || formatted.errors.length > 0;
case 'warning':
return formatted.warnings.length > 0 || formatted.errors.length > 0;
case 'error':
return formatted.errors.length > 0;
case 'never':
return false;
}
};
if (shouldThrow() && !isWatch) throw new Error('Publint failed!');
},
order: 'post'
});
}
});
export { pluginPublint };