eslint-plugin-text
Version:
An incredible ESLint plugin for retext or textlint
103 lines • 3.89 kB
JavaScript
import path from 'node:path';
import { loadConfig } from '@textlint/config-loader';
import { loadModule, requirePkg } from 'eslint-plugin-utils';
import { lilconfig } from 'lilconfig';
import retextStringify from 'retext-stringify';
import { extractProperties, runAsWorker } from 'synckit';
import { createLinter, loadTextlintrc } from 'textlint';
import { unified } from 'unified';
import { VFile } from 'vfile';
import { arrayify } from "./helpers.js";
const explorer = lilconfig('retext', {
packageProp: 'retextConfig',
loaders: {
'.js': loadModule,
},
});
export const processorCache = new Map();
export const getRetextProcessor = async (searchFrom, ignoreRetextConfig) => {
const initCacheKey = searchFrom;
let cachedProcessor = processorCache.get(initCacheKey);
if (cachedProcessor) {
return cachedProcessor;
}
const result = ignoreRetextConfig
? null
: await explorer.search(searchFrom);
const cacheKey = result ? result.filepath : '';
cachedProcessor = processorCache.get(cacheKey);
if (cachedProcessor) {
return cachedProcessor;
}
if (result) {
const { plugins = [], settings } = (result.config || {});
const reducedProcessor = await plugins.reduce(async (processor_, pluginWithSettings) => {
const [plugin, ...pluginSettings] = arrayify(pluginWithSettings);
const processor = await processor_;
return processor.use(typeof plugin === 'string'
? await requirePkg(plugin, 'retext', result.filepath)
: plugin, ...pluginSettings);
}, Promise.resolve(unified().use({ settings })));
cachedProcessor = reducedProcessor.use(retextStringify).freeze();
}
else {
cachedProcessor = unified().use(retextStringify).freeze();
}
processorCache
.set(initCacheKey, cachedProcessor)
.set(cacheKey, cachedProcessor);
return cachedProcessor;
};
export const isTextlintFixResult = (result) => 'output' in result;
const textlintCache = new Map();
runAsWorker(async ({ text, filename, linter, fix, ignoreRetextConfig, }) => {
switch (linter) {
case 'retext': {
const processor = await getRetextProcessor(filename, ignoreRetextConfig);
const file = new VFile({
value: text,
path: filename,
});
try {
await processor.process(file);
}
catch (err) {
const error = err;
if (!file.messages.includes(error)) {
file.message(error).fatal = true;
}
}
return {
messages: file.messages.map(message => extractProperties(message)),
content: file.toString(),
};
}
case 'textlint': {
let textlint;
if (textlintCache.has(filename)) {
textlint = textlintCache.get(filename);
}
else {
const cwd = path.dirname(filename);
const config = await loadConfig({ cwd });
const textlintrcDescriptor = await loadTextlintrc({
configFilePath: config.configFilePath,
});
textlint = createLinter({
descriptor: textlintrcDescriptor,
cwd,
});
textlintCache.set(filename, textlint);
}
const result = await textlint[fix ? 'fixText' : 'lintText'](text, filename);
return {
messages: result.messages,
content: isTextlintFixResult(result) ? result.output : text,
};
}
default: {
throw new RangeError(`Unknown linter: ${linter}`);
}
}
});
//# sourceMappingURL=worker.js.map