stylelint-webpack-plugin
Advanced tools
Comparing version 3.3.0 to 4.0.0
@@ -6,8 +6,7 @@ "use strict"; | ||
} = require('os'); | ||
const { | ||
Worker: JestWorker | ||
} = require('jest-worker'); // @ts-ignore | ||
} = require('jest-worker'); | ||
// @ts-ignore | ||
const { | ||
@@ -17,26 +16,19 @@ setup, | ||
} = require('./worker'); | ||
const { | ||
jsonStringifyReplacerSortKeys | ||
} = require('./utils'); | ||
const { | ||
getStylelintOptions | ||
} = require('./options'); | ||
/** @type {{[key: string]: any}} */ | ||
const cache = {}; | ||
const cache = {}; | ||
/** @typedef {import('stylelint')} Stylelint */ | ||
/** @typedef {import('stylelint').LintResult} LintResult */ | ||
/** @typedef {import('./options').Options} Options */ | ||
/** @typedef {(stylelint: Stylelint, filePath: string) => Promise<boolean>} isPathIgnored */ | ||
/** @typedef {() => Promise<void>} AsyncTask */ | ||
/** @typedef {(files: string|string[]) => Promise<LintResult[]>} LintTask */ | ||
/** @typedef {{api: import('stylelint').InternalApi, stylelint: Stylelint, lintFiles: LintTask, cleanup: AsyncTask, threads: number, }} Linter */ | ||
/** @typedef {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lintFiles: LintTask, cleanup: AsyncTask, threads: number }} Linter */ | ||
/** @typedef {JestWorker & {lintFiles: LintTask}} Worker */ | ||
@@ -48,9 +40,21 @@ | ||
*/ | ||
function loadStylelint(options) { | ||
const stylelintOptions = getStylelintOptions(options); | ||
const stylelint = setup(options, stylelintOptions); | ||
/** @type {isPathIgnored} */ | ||
let isPathIgnored; | ||
try { | ||
isPathIgnored = require(`${options.stylelintPath}/lib/isPathIgnored`); | ||
} catch (e) { | ||
try { | ||
// @ts-ignore | ||
isPathIgnored = require('stylelint/lib/isPathIgnored'); | ||
} catch (_) { | ||
isPathIgnored = () => Promise.resolve(false); | ||
} | ||
} | ||
return { | ||
stylelint, | ||
api: stylelint.createLinter(stylelintOptions), | ||
isPathIgnored, | ||
lintFiles, | ||
@@ -61,2 +65,3 @@ cleanup: async () => {}, | ||
} | ||
/** | ||
@@ -68,9 +73,5 @@ * @param {string|undefined} key | ||
*/ | ||
function loadStylelintThreaded(key, poolSize, options) { | ||
const cacheKey = getCacheKey(key, options); | ||
const source = require.resolve('./worker'); | ||
const workerOptions = { | ||
@@ -82,19 +83,14 @@ enableWorkerThreads: true, | ||
const local = loadStylelint(options); | ||
let worker = | ||
/** @type {Worker?} */ | ||
new JestWorker(source, workerOptions); | ||
let worker = /** @type {Worker?} */new JestWorker(source, workerOptions); | ||
/** @type {Linter} */ | ||
const context = { ...local, | ||
const context = { | ||
...local, | ||
threads: poolSize, | ||
lintFiles: async files => | ||
/* istanbul ignore next */ | ||
lintFiles: async files => /* istanbul ignore next */ | ||
worker ? worker.lintFiles(files) : local.lintFiles(files), | ||
cleanup: async () => { | ||
cache[cacheKey] = local; | ||
context.lintFiles = files => local.lintFiles(files); | ||
/* istanbul ignore next */ | ||
if (worker) { | ||
@@ -108,2 +104,3 @@ worker.end(); | ||
} | ||
/** | ||
@@ -114,4 +111,2 @@ * @param {string|undefined} key | ||
*/ | ||
function getStylelint(key, { | ||
@@ -126,9 +121,8 @@ threads, | ||
}); | ||
if (!cache[cacheKey]) { | ||
cache[cacheKey] = max > 1 ? loadStylelintThreaded(key, max, options) : loadStylelint(options); | ||
} | ||
return cache[cacheKey]; | ||
} | ||
/** | ||
@@ -139,4 +133,2 @@ * @param {string|undefined} key | ||
*/ | ||
function getCacheKey(key, options) { | ||
@@ -148,3 +140,2 @@ return JSON.stringify({ | ||
} | ||
module.exports = getStylelint; |
@@ -7,15 +7,10 @@ "use strict"; | ||
} = require('path'); | ||
const globby = require('globby'); | ||
const { | ||
isMatch | ||
} = require('micromatch'); | ||
const { | ||
getOptions | ||
} = require('./options'); | ||
const linter = require('./linter'); | ||
const { | ||
@@ -26,14 +21,10 @@ arrify, | ||
} = require('./utils'); | ||
/** @typedef {import('webpack').Compiler} Compiler */ | ||
/** @typedef {import('webpack').Module} Module */ | ||
/** @typedef {import('./options').Options} Options */ | ||
/** @typedef {Partial<{timestamp:number} | number>} FileSystemInfoEntry */ | ||
const STYLELINT_PLUGIN = 'StylelintWebpackPlugin'; | ||
let counter = 0; | ||
class StylelintWebpackPlugin { | ||
@@ -50,2 +41,3 @@ /** | ||
} | ||
/** | ||
@@ -55,4 +47,2 @@ * @param {Compiler} compiler | ||
*/ | ||
apply(compiler) { | ||
@@ -64,3 +54,4 @@ // Generate key for each compilation, | ||
const excludeDefault = ['**/node_modules/**', String(compiler.options.output.path)]; | ||
const options = { ...this.options, | ||
const options = { | ||
...this.options, | ||
context, | ||
@@ -72,9 +63,9 @@ exclude: parseFiles(this.options.exclude || excludeDefault, context), | ||
const wanted = parseFoldersToGlobs(options.files, options.extensions); | ||
const exclude = parseFoldersToGlobs(options.exclude); // If `lintDirtyModulesOnly` is disabled, | ||
const exclude = parseFoldersToGlobs(options.exclude); | ||
// If `lintDirtyModulesOnly` is disabled, | ||
// execute the linter on the build | ||
if (!this.options.lintDirtyModulesOnly) { | ||
compiler.hooks.run.tapPromise(this.key, c => this.run(c, options, wanted, exclude)); | ||
} | ||
let isFirstRun = this.options.lintDirtyModulesOnly; | ||
@@ -86,6 +77,6 @@ compiler.hooks.watchRun.tapPromise(this.key, c => { | ||
} | ||
return this.run(c, options, wanted, exclude); | ||
}); | ||
} | ||
/** | ||
@@ -97,9 +88,7 @@ * @param {Compiler} compiler | ||
*/ | ||
async run(compiler, options, wanted, exclude) { | ||
// Do not re-hook | ||
/* istanbul ignore if */ | ||
if ( // @ts-ignore | ||
if ( | ||
// @ts-ignore | ||
compiler.hooks.thisCompilation.taps.find(({ | ||
@@ -110,20 +99,22 @@ name | ||
} | ||
compiler.hooks.thisCompilation.tap(this.key, compilation => { | ||
/** @type {import('stylelint')} */ | ||
let stylelint; | ||
compiler.hooks.thisCompilation.tap(this.key, compilation => { | ||
/** @type {import('./linter').Linter} */ | ||
let lint; | ||
/** @type {import('stylelint').InternalApi} */ | ||
let api; | ||
/** @type {import('./linter').isPathIgnored} */ | ||
let isPathIgnored; | ||
/** @type {import('./linter').Reporter} */ | ||
let report; | ||
let report; | ||
/** @type number */ | ||
let threads; | ||
try { | ||
({ | ||
stylelint, | ||
lint, | ||
api, | ||
isPathIgnored, | ||
report, | ||
@@ -136,3 +127,2 @@ threads | ||
} | ||
compilation.hooks.finishModules.tapPromise(this.key, async () => { | ||
@@ -150,3 +140,3 @@ /** @type {string[]} */ | ||
try { | ||
return (await api.isPathIgnored(file)) ? false : file; | ||
return (await isPathIgnored(stylelint, file)) ? false : file; | ||
} catch (e) { | ||
@@ -156,14 +146,13 @@ return file; | ||
}))).filter(file => file !== false); | ||
if (threads > 1) { | ||
for (const file of files) { | ||
lint(parseFiles(file, options.context || '')); | ||
lint(parseFiles(file, String(options.context))); | ||
} | ||
} else if (files.length > 0) { | ||
lint(parseFiles(files, options.context || '')); | ||
lint(parseFiles(files, String(options.context))); | ||
} | ||
}); // await and interpret results | ||
}); | ||
// await and interpret results | ||
compilation.hooks.additionalAssets.tapPromise(this.key, processResults); | ||
async function processResults() { | ||
@@ -175,3 +164,2 @@ const { | ||
} = await report(); | ||
if (warnings && !options.failOnWarning) { | ||
@@ -184,3 +172,2 @@ // @ts-ignore | ||
} | ||
if (errors && options.failOnError) { | ||
@@ -193,3 +180,2 @@ // @ts-ignore | ||
} | ||
if (generateReportAsset) { | ||
@@ -201,2 +187,3 @@ await generateReportAsset(compilation); | ||
} | ||
/** | ||
@@ -207,4 +194,2 @@ * | ||
*/ | ||
getContext(compiler) { | ||
@@ -214,12 +199,8 @@ if (!this.options.context) { | ||
} | ||
if (!isAbsolute(this.options.context)) { | ||
return join(String(compiler.options.context), this.options.context); | ||
} | ||
return this.options.context; | ||
} | ||
} | ||
module.exports = StylelintWebpackPlugin; |
@@ -8,40 +8,26 @@ "use strict"; | ||
} = require('path'); | ||
const StylelintError = require('./StylelintError'); | ||
const getStylelint = require('./getStylelint'); | ||
const { | ||
arrify | ||
} = require('./utils'); | ||
/** @typedef {import('stylelint')} Stylelint */ | ||
/** @typedef {import('stylelint').LintResult} LintResult */ | ||
/** @typedef {import('stylelint').InternalApi} InternalApi */ | ||
/** @typedef {import('stylelint').LinterResult} LinterResult */ | ||
/** @typedef {import('stylelint').Formatter} Formatter */ | ||
/** @typedef {import('stylelint').FormatterType} FormatterType */ | ||
/** @typedef {import('webpack').Compiler} Compiler */ | ||
/** @typedef {import('webpack').Compilation} Compilation */ | ||
/** @typedef {import('./options').Options} Options */ | ||
/** @typedef {import('./options').FormatterType} FormatterType */ | ||
/** @typedef {((results: LintResult[]) => string)} FormatterFunction */ | ||
/** @typedef {import('./getStylelint').isPathIgnored} isPathIgnored */ | ||
/** @typedef {(compilation: Compilation) => Promise<void>} GenerateReport */ | ||
/** @typedef {{errors?: StylelintError, warnings?: StylelintError, generateReportAsset?: GenerateReport}} Report */ | ||
/** @typedef {() => Promise<Report>} Reporter */ | ||
/** @typedef {(files: string|string[]) => void} Linter */ | ||
/** @typedef {{[files: string]: LintResult}} LintResultMap */ | ||
/** @type {WeakMap<Compiler, LintResultMap>} */ | ||
const resultStorage = new WeakMap(); | ||
const resultStorage = new WeakMap(); | ||
/** | ||
@@ -51,29 +37,27 @@ * @param {string|undefined} key | ||
* @param {Compilation} compilation | ||
* @returns {{api: InternalApi, lint: Linter, report: Reporter, threads: number}} | ||
* @returns {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lint: Linter, report: Reporter, threads: number}} | ||
*/ | ||
function linter(key, options, compilation) { | ||
/** @type {Stylelint} */ | ||
let stylelint; | ||
/** @type {InternalApi} */ | ||
let api; | ||
/** @type {isPathIgnored} */ | ||
let isPathIgnored; | ||
/** @type {(files: string|string[]) => Promise<LintResult[]>} */ | ||
let lintFiles; | ||
let lintFiles; | ||
/** @type {() => Promise<void>} */ | ||
let cleanup; | ||
let cleanup; | ||
/** @type number */ | ||
let threads; | ||
let threads; | ||
/** @type {Promise<LintResult[]>[]} */ | ||
const rawResults = []; | ||
const crossRunResultStorage = getResultStorage(compilation); | ||
try { | ||
({ | ||
stylelint, | ||
api, | ||
isPathIgnored, | ||
lintFiles, | ||
@@ -86,13 +70,13 @@ cleanup, | ||
} | ||
return { | ||
stylelint, | ||
lint, | ||
api, | ||
isPathIgnored, | ||
report, | ||
threads | ||
}; | ||
/** | ||
* @param {string | string[]} files | ||
*/ | ||
function lint(files) { | ||
@@ -102,3 +86,2 @@ for (const file of arrify(files)) { | ||
} | ||
rawResults.push(lintFiles(files).catch(e => { | ||
@@ -110,24 +93,33 @@ // @ts-ignore | ||
} | ||
async function report() { | ||
// Filter out ignored files. | ||
let results = removeIgnoredWarnings( // Get the current results, resetting the rawResults to empty | ||
let results = removeIgnoredWarnings( | ||
// Get the current results, resetting the rawResults to empty | ||
await flatten(rawResults.splice(0, rawResults.length))); | ||
await cleanup(); | ||
for (const result of results) { | ||
crossRunResultStorage[String(result.source)] = result; | ||
} | ||
results = Object.values(crossRunResultStorage); | ||
results = Object.values(crossRunResultStorage); // do not analyze if there are no results or stylelint config | ||
// do not analyze if there are no results or stylelint config | ||
if (!results || results.length < 1) { | ||
return {}; | ||
} | ||
const formatter = loadFormatter(stylelint, options.formatter); | ||
const formatter = loadFormatter(stylelint, options.formatter); | ||
/** @type {LinterResult} */ | ||
const returnValue = { | ||
// @ts-ignore | ||
cwd: options.cwd, | ||
errored: false, | ||
results: [], | ||
output: '', | ||
reportedDisables: [], | ||
ruleMetadata: getRuleMetadata(results) | ||
}; | ||
const { | ||
errors, | ||
warnings | ||
} = formatResults(formatter, parseResults(options, results)); | ||
} = formatResults(formatter, parseResults(options, results), returnValue); | ||
return { | ||
@@ -138,2 +130,3 @@ errors, | ||
}; | ||
/** | ||
@@ -143,3 +136,2 @@ * @param {Compilation} compilation | ||
*/ | ||
async function generateReportAsset({ | ||
@@ -155,5 +147,3 @@ compiler | ||
*/ | ||
const save = (name, content) => | ||
/** @type {Promise<void>} */ | ||
const save = (name, content) => /** @type {Promise<void>} */ | ||
new Promise((finish, bail) => { | ||
@@ -163,5 +153,5 @@ const { | ||
writeFile | ||
} = compiler.outputFileSystem; // ensure directory exists | ||
} = compiler.outputFileSystem; | ||
// ensure directory exists | ||
// @ts-ignore - the types for `outputFileSystem` are missing the 3 arg overload | ||
mkdir(dirname(name), { | ||
@@ -177,39 +167,34 @@ recursive: true | ||
}); | ||
if (!outputReport || !outputReport.filePath) { | ||
return; | ||
} | ||
const content = outputReport.formatter ? loadFormatter(stylelint, outputReport.formatter)(results) : formatter(results); | ||
const content = outputReport.formatter; | ||
loadFormatter(stylelint, outputReport.formatter)(results, returnValue); | ||
formatter(results, returnValue); | ||
let { | ||
filePath | ||
} = outputReport; | ||
if (!isAbsolute(filePath)) { | ||
filePath = join(compiler.outputPath, filePath); | ||
} | ||
await save(filePath, content); | ||
await save(filePath, String(content)); | ||
} | ||
} | ||
} | ||
/** | ||
* @param {FormatterFunction} formatter | ||
* @param {Formatter} formatter | ||
* @param {{ errors: LintResult[]; warnings: LintResult[]; }} results | ||
* @param {LinterResult} returnValue | ||
* @returns {{errors?: StylelintError, warnings?: StylelintError}} | ||
*/ | ||
function formatResults(formatter, results) { | ||
function formatResults(formatter, results, returnValue) { | ||
let errors; | ||
let warnings; | ||
if (results.warnings.length > 0) { | ||
warnings = new StylelintError(formatter(results.warnings)); | ||
warnings = new StylelintError(formatter(results.warnings, returnValue)); | ||
} | ||
if (results.errors.length > 0) { | ||
errors = new StylelintError(formatter(results.errors)); | ||
errors = new StylelintError(formatter(results.errors, returnValue)); | ||
} | ||
return { | ||
@@ -220,2 +205,3 @@ errors, | ||
} | ||
/** | ||
@@ -226,23 +212,20 @@ * @param {Options} options | ||
*/ | ||
function parseResults(options, results) { | ||
/** @type {LintResult[]} */ | ||
const errors = []; | ||
/** @type {LintResult[]} */ | ||
const warnings = []; | ||
results.forEach(file => { | ||
const fileErrors = file.warnings.filter(message => options.emitError && message.severity === 'error'); | ||
if (fileErrors.length > 0) { | ||
errors.push({ ...file, | ||
errors.push({ | ||
...file, | ||
warnings: fileErrors | ||
}); | ||
} | ||
const fileWarnings = file.warnings.filter(message => options.emitWarning && message.severity === 'warning'); | ||
if (fileWarnings.length > 0) { | ||
warnings.push({ ...file, | ||
warnings.push({ | ||
...file, | ||
warnings: fileWarnings | ||
@@ -257,9 +240,8 @@ }); | ||
} | ||
/** | ||
* @param {Stylelint} stylelint | ||
* @param {FormatterType=} formatter | ||
* @returns {FormatterFunction} | ||
* @returns {Formatter} | ||
*/ | ||
function loadFormatter(stylelint, formatter) { | ||
@@ -269,12 +251,12 @@ if (typeof formatter === 'function') { | ||
} | ||
if (typeof formatter === 'string') { | ||
try { | ||
return stylelint.formatters[formatter]; | ||
} catch (_) {// Load the default formatter. | ||
} catch (_) { | ||
// Load the default formatter. | ||
} | ||
} | ||
return stylelint.formatters.string; | ||
} | ||
/** | ||
@@ -284,7 +266,6 @@ * @param {LintResult[]} results | ||
*/ | ||
function removeIgnoredWarnings(results) { | ||
return results.filter(result => !result.ignored); | ||
} | ||
/** | ||
@@ -294,4 +275,2 @@ * @param {Promise<LintResult[]>[]} results | ||
*/ | ||
async function flatten(results) { | ||
@@ -303,5 +282,5 @@ /** | ||
const flat = (acc, list) => [...acc, ...list]; | ||
return (await Promise.all(results)).reduce(flat, []); | ||
} | ||
/** | ||
@@ -311,4 +290,2 @@ * @param {Compilation} compilation | ||
*/ | ||
function getResultStorage({ | ||
@@ -318,10 +295,24 @@ compiler | ||
let storage = resultStorage.get(compiler); | ||
if (!storage) { | ||
resultStorage.set(compiler, storage = {}); | ||
} | ||
return storage; | ||
} | ||
/** | ||
* @param {LintResult[]} lintResults | ||
*/ | ||
/* istanbul ignore next */ | ||
function getRuleMetadata(lintResults) { | ||
const [lintResult] = lintResults; | ||
// eslint-disable-next-line no-undefined | ||
if (lintResult === undefined) return {}; | ||
// eslint-disable-next-line no-underscore-dangle, no-undefined | ||
if (lintResult._postcssResult === undefined) return {}; | ||
// eslint-disable-next-line no-underscore-dangle | ||
return lintResult._postcssResult.stylelint.ruleMetadata; | ||
} | ||
module.exports = linter; |
@@ -6,8 +6,6 @@ "use strict"; | ||
} = require('schema-utils'); | ||
const schema = require('./options.json'); | ||
const schema = require('./options.json'); | ||
/** @typedef {import("stylelint")} stylelint */ | ||
/** @typedef {import("stylelint").LinterOptions} StylelintOptions */ | ||
/** @typedef {import("stylelint").FormatterType} FormatterType */ | ||
@@ -45,4 +43,2 @@ | ||
*/ | ||
function getOptions(pluginOptions) { | ||
@@ -59,4 +55,5 @@ const options = { | ||
} : {}) | ||
}; // @ts-ignore | ||
}; | ||
// @ts-ignore | ||
validate(schema, options, { | ||
@@ -68,2 +65,3 @@ name: 'Stylelint Webpack Plugin', | ||
} | ||
/** | ||
@@ -73,8 +71,8 @@ * @param {Options} pluginOptions | ||
*/ | ||
function getStylelintOptions(pluginOptions) { | ||
const stylelintOptions = { ...pluginOptions | ||
}; // Keep the files and formatter option because it is common to both the plugin and Stylelint. | ||
const stylelintOptions = { | ||
...pluginOptions | ||
}; | ||
// Keep the files and formatter option because it is common to both the plugin and Stylelint. | ||
const { | ||
@@ -84,5 +82,6 @@ files, | ||
...stylelintOnlyOptions | ||
} = schema.properties; // No need to guard the for-in because schema.properties has hardcoded keys. | ||
} = schema.properties; | ||
// No need to guard the for-in because schema.properties has hardcoded keys. | ||
// eslint-disable-next-line guard-for-in | ||
for (const option in stylelintOnlyOptions) { | ||
@@ -92,6 +91,4 @@ // @ts-ignore | ||
} | ||
return stylelintOptions; | ||
} | ||
module.exports = { | ||
@@ -98,0 +95,0 @@ getOptions, |
@@ -34,3 +34,3 @@ { | ||
"files": { | ||
"description": "Specify directories, files, or globs. Must be relative to `options.context`. Directories are traveresed recursively looking for files matching `options.extensions`. File and glob patterns ignore `options.extensions`.", | ||
"description": "Specify directories, files, or globs. Must be relative to `options.context`. Directories are traversed recursively looking for files matching `options.extensions`. File and glob patterns ignore `options.extensions`.", | ||
"anyOf": [{ "type": "string" }, { "type": "array" }] | ||
@@ -37,0 +37,0 @@ }, |
@@ -12,5 +12,3 @@ "use strict"; | ||
} | ||
} | ||
module.exports = StylelintError; |
@@ -6,8 +6,7 @@ "use strict"; | ||
} = require('path'); | ||
const { | ||
statSync | ||
} = require('fs'); | ||
const normalizePath = require('normalize-path'); | ||
const normalizePath = require('normalize-path'); | ||
/** | ||
@@ -28,6 +27,3 @@ * @template T | ||
*/ | ||
/* istanbul ignore next */ | ||
function arrify(value) { | ||
@@ -39,3 +35,2 @@ // eslint-disable-next-line no-undefined | ||
} | ||
if (Array.isArray(value)) { | ||
@@ -45,17 +40,17 @@ // @ts-ignore | ||
} | ||
if (typeof value === 'string') { | ||
// @ts-ignore | ||
return [value]; | ||
} // @ts-ignore | ||
} | ||
// @ts-ignore | ||
if (typeof value[Symbol.iterator] === 'function') { | ||
// @ts-ignore | ||
return [...value]; | ||
} // @ts-ignore | ||
} | ||
// @ts-ignore | ||
return [value]; | ||
} | ||
/** | ||
@@ -66,9 +61,6 @@ * @param {string|string[]} files | ||
*/ | ||
function parseFiles(files, context) { | ||
return arrify(files).map(( | ||
/** @type {string} */ | ||
file) => normalizePath(resolve(context, file))); | ||
return arrify(files).map(( /** @type {string} */file) => normalizePath(resolve(context, file))); | ||
} | ||
/** | ||
@@ -79,13 +71,7 @@ * @param {string|string[]} patterns | ||
*/ | ||
function parseFoldersToGlobs(patterns, extensions = []) { | ||
const extensionsList = arrify(extensions); | ||
const [prefix, postfix] = extensionsList.length > 1 ? ['{', '}'] : ['', '']; | ||
const extensionsGlob = extensionsList.map(( | ||
/** @type {string} */ | ||
extension) => extension.replace(/^\./u, '')).join(','); | ||
return arrify(patterns).map(( | ||
/** @type {string} */ | ||
pattern) => { | ||
const extensionsGlob = extensionsList.map(( /** @type {string} */extension) => extension.replace(/^\./u, '')).join(','); | ||
return arrify(patterns).map(( /** @type {string} */pattern) => { | ||
try { | ||
@@ -95,12 +81,12 @@ // The patterns are absolute because they are prepended with the context. | ||
/* istanbul ignore else */ | ||
if (stats.isDirectory()) { | ||
return pattern.replace(/[/\\]*?$/u, `/**${extensionsGlob ? `/*.${prefix + extensionsGlob + postfix}` : ''}`); | ||
} | ||
} catch (_) {// Return the pattern as is on error. | ||
} catch (_) { | ||
// Return the pattern as is on error. | ||
} | ||
return pattern; | ||
}); | ||
} | ||
/** | ||
@@ -111,4 +97,2 @@ * | ||
*/ | ||
const jsonStringifyReplacerSortKeys = (_, value) => { | ||
@@ -124,6 +108,4 @@ /** | ||
}; | ||
return value instanceof Object && !(value instanceof Array) ? Object.keys(value).sort().reduce(insert, {}) : value; | ||
}; | ||
module.exports = { | ||
@@ -130,0 +112,0 @@ arrify, |
"use strict"; | ||
/** @typedef {import('stylelint')} Stylelint */ | ||
/** @typedef {import("stylelint").LinterOptions} StylelintOptions */ | ||
/** @typedef {import('./options').Options} Options */ | ||
/** @typedef {import('./options').Options} Options */ | ||
Object.assign(module.exports, { | ||
@@ -12,8 +11,9 @@ lintFiles, | ||
}); | ||
/** @type {Stylelint} */ | ||
let stylelint; | ||
let stylelint; | ||
/** @type {Partial<StylelintOptions>} */ | ||
let linterOptions; | ||
let linterOptions; | ||
/** | ||
@@ -23,3 +23,2 @@ * @param {Options} options | ||
*/ | ||
function setup(options, stylelintOptions) { | ||
@@ -30,14 +29,15 @@ stylelint = require(options.stylelintPath || 'stylelint'); | ||
} | ||
/** | ||
* @param {string | string[]} files | ||
*/ | ||
async function lintFiles(files) { | ||
const { | ||
results | ||
} = await stylelint.lint({ ...linterOptions, | ||
} = await stylelint.lint({ | ||
...linterOptions, | ||
files | ||
}); // Reset result to work with worker | ||
}); | ||
// Reset result to work with worker | ||
return results.map(result => { | ||
@@ -44,0 +44,0 @@ return { |
{ | ||
"name": "stylelint-webpack-plugin", | ||
"version": "3.3.0", | ||
"version": "4.0.0", | ||
"description": "A Stylelint plugin for webpack", | ||
@@ -17,3 +17,3 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">= 12.13.0" | ||
"node": ">= 14.15.0" | ||
}, | ||
@@ -31,2 +31,3 @@ "scripts": { | ||
"lint:js": "eslint --cache .", | ||
"lint:spelling": "cspell \"**/*.*\"", | ||
"lint:types": "tsc --pretty --noEmit", | ||
@@ -51,4 +52,4 @@ "lint": "npm-run-all -l -p \"lint:**\"", | ||
"dependencies": { | ||
"jest-worker": "^28.1.0", | ||
"globby": "^11.1.0", | ||
"jest-worker": "^29.4.1", | ||
"micromatch": "^4.0.5", | ||
@@ -59,9 +60,11 @@ "normalize-path": "^3.0.0", | ||
"devDependencies": { | ||
"@babel/cli": "^7.17.10", | ||
"@babel/core": "^7.18.0", | ||
"@babel/preset-env": "^7.18.0", | ||
"@commitlint/cli": "^16.2.3", | ||
"@commitlint/config-conventional": "^16.2.1", | ||
"@babel/cli": "^7.20.7", | ||
"@babel/core": "^7.20.12", | ||
"@babel/preset-env": "^7.20.2", | ||
"@commitlint/cli": "^17.4.2", | ||
"@commitlint/config-conventional": "^17.4.2", | ||
"@types/file-entry-cache": "^5.0.2", | ||
"@types/fs-extra": "^9.0.13", | ||
"@types/micromatch": "^4.0.2", | ||
"@types/node": "^18.11.18", | ||
"@types/normalize-path": "^3.0.0", | ||
@@ -71,22 +74,23 @@ "@types/webpack": "^5.28.0", | ||
"babel-eslint": "^10.1.0", | ||
"babel-jest": "^28.1.0", | ||
"babel-jest": "^29.4.1", | ||
"chokidar": "^3.5.3", | ||
"cross-env": "^7.0.3", | ||
"del": "^6.1.0", | ||
"cspell": "^6.20.1", | ||
"del": "^6.1.1", | ||
"del-cli": "^4.0.1", | ||
"eslint": "^8.15.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-import": "^2.26.0", | ||
"eslint": "^8.33.0", | ||
"eslint-config-prettier": "^8.6.0", | ||
"eslint-plugin-import": "^2.27.5", | ||
"file-loader": "^6.2.0", | ||
"fs-extra": "^10.1.0", | ||
"husky": "^7.0.4", | ||
"jest": "^28.1.0", | ||
"lint-staged": "^12.4.1", | ||
"husky": "^8.0.3", | ||
"jest": "^29.4.1", | ||
"lint-staged": "^13.1.0", | ||
"npm-run-all": "^4.1.5", | ||
"postcss-scss": "^4.0.4", | ||
"prettier": "^2.6.2", | ||
"postcss-scss": "^4.0.6", | ||
"prettier": "^2.8.3", | ||
"standard-version": "^9.5.0", | ||
"stylelint": "^14.8.2", | ||
"typescript": "^4.6.2", | ||
"webpack": "^5.72.1" | ||
"stylelint": "^14.16.1", | ||
"typescript": "^4.9.5", | ||
"webpack": "^5.75.0" | ||
}, | ||
@@ -93,0 +97,0 @@ "keywords": [ |
@@ -8,3 +8,2 @@ <div align="center"> | ||
[![node][node]][node-url] | ||
[![deps][deps]][deps-url] | ||
[![tests][tests]][tests-url] | ||
@@ -41,3 +40,5 @@ [![coverage][cover]][cover-url] | ||
**Note**: You also need to install `stylelint >= 13` from npm, if you haven't already: | ||
> **Note**: | ||
> | ||
> You also need to install `stylelint >= 13` from npm, if you haven't already: | ||
@@ -60,3 +61,5 @@ ```console | ||
**Note**: If you are using Stylelint 13 rather than 14+, you might also need to install `@types/stylelint` as a dev dependency if getting stylelint related type errors. | ||
> **Note**: | ||
> | ||
> If you are using Stylelint 13 rather than 14+, you might also need to install `@types/stylelint` as a dev dependency if getting stylelint related type errors. | ||
@@ -91,3 +94,5 @@ Then add the plugin to your webpack config. For example: | ||
**Note:** By default this is [handled by `stylelint`](https://stylelint.io/user-guide/configure). | ||
> **Note:** | ||
> | ||
> By default this is [handled by `stylelint`](https://stylelint.io/user-guide/configure). | ||
@@ -312,4 +317,2 @@ ### `context` | ||
[node-url]: https://nodejs.org | ||
[deps]: https://david-dm.org/webpack-contrib/stylelint-webpack-plugin.svg | ||
[deps-url]: https://david-dm.org/webpack-contrib/stylelint-webpack-plugin | ||
[tests]: https://github.com/webpack-contrib/stylelint-webpack-plugin/workflows/stylelint-webpack-plugin/badge.svg | ||
@@ -316,0 +319,0 @@ [tests-url]: https://github.com/webpack-contrib/stylelint-webpack-plugin/actions |
@@ -17,2 +17,3 @@ /// <reference types="stylelint" /> | ||
Options, | ||
isPathIgnored, | ||
AsyncTask, | ||
@@ -26,4 +27,4 @@ LintTask, | ||
type Linter = { | ||
api: import('stylelint').InternalApi; | ||
stylelint: Stylelint; | ||
isPathIgnored: isPathIgnored; | ||
lintFiles: LintTask; | ||
@@ -47,3 +48,3 @@ cleanup: AsyncTask; | ||
ruleName: string, | ||
plugin: import('stylelint').Plugin<any, any> | ||
rule: import('stylelint').Rule<any, any> | ||
) => { | ||
@@ -84,2 +85,4 @@ ruleName: string; | ||
root: import('postcss').Root; | ||
result?: import('stylelint').PostcssResult | undefined; | ||
context?: import('stylelint').RuleContext | undefined; | ||
}, | ||
@@ -89,4 +92,11 @@ callback: (warning: import('postcss').Warning) => void | ||
}; | ||
reference: { | ||
longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties; | ||
}; | ||
}; | ||
type LintResult = import('stylelint').LintResult; | ||
type isPathIgnored = ( | ||
stylelint: Stylelint, | ||
filePath: string | ||
) => Promise<boolean>; | ||
type AsyncTask = () => Promise<void>; | ||
@@ -93,0 +103,0 @@ type LintTask = (files: string | string[]) => Promise<LintResult[]>; |
@@ -7,3 +7,3 @@ /// <reference types="stylelint" /> | ||
* @param {Compilation} compilation | ||
* @returns {{api: InternalApi, lint: Linter, report: Reporter, threads: number}} | ||
* @returns {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lint: Linter, report: Reporter, threads: number}} | ||
*/ | ||
@@ -15,3 +15,4 @@ declare function linter( | ||
): { | ||
api: InternalApi; | ||
stylelint: Stylelint; | ||
isPathIgnored: getStylelint.isPathIgnored; | ||
lint: Linter; | ||
@@ -25,8 +26,9 @@ report: Reporter; | ||
LintResult, | ||
InternalApi, | ||
LinterResult, | ||
Formatter, | ||
FormatterType, | ||
Compiler, | ||
Compilation, | ||
Options, | ||
FormatterType, | ||
FormatterFunction, | ||
isPathIgnored, | ||
GenerateReport, | ||
@@ -41,5 +43,2 @@ Report, | ||
type Compilation = import('webpack').Compilation; | ||
type InternalApi = import('stylelint').InternalApi; | ||
type Linter = (files: string | string[]) => void; | ||
type Reporter = () => Promise<Report>; | ||
type Stylelint = import('postcss').PluginCreator< | ||
@@ -59,3 +58,3 @@ import('stylelint').PostcssPluginOptions | ||
ruleName: string, | ||
plugin: import('stylelint').Plugin<any, any> | ||
rule: import('stylelint').Rule<any, any> | ||
) => { | ||
@@ -96,2 +95,4 @@ ruleName: string; | ||
root: import('postcss').Root; | ||
result?: import('stylelint').PostcssResult | undefined; | ||
context?: import('stylelint').RuleContext | undefined; | ||
}, | ||
@@ -101,7 +102,15 @@ callback: (warning: import('postcss').Warning) => void | ||
}; | ||
reference: { | ||
longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties; | ||
}; | ||
}; | ||
type Linter = (files: string | string[]) => void; | ||
type Reporter = () => Promise<Report>; | ||
import getStylelint = require('./getStylelint'); | ||
type LintResult = import('stylelint').LintResult; | ||
type LinterResult = import('stylelint').LinterResult; | ||
type Formatter = import('stylelint').Formatter; | ||
type FormatterType = import('stylelint').FormatterType; | ||
type Compiler = import('webpack').Compiler; | ||
type FormatterType = import('./options').FormatterType; | ||
type FormatterFunction = (results: LintResult[]) => string; | ||
type isPathIgnored = import('./getStylelint').isPathIgnored; | ||
type GenerateReport = (compilation: Compilation) => Promise<void>; | ||
@@ -108,0 +117,0 @@ type Report = { |
@@ -16,3 +16,3 @@ /// <reference types="stylelint" /> | ||
ruleName: string, | ||
plugin: import('stylelint').Plugin<any, any> | ||
rule: import('stylelint').Rule<any, any> | ||
) => { | ||
@@ -53,2 +53,4 @@ ruleName: string; | ||
root: import('postcss').Root; | ||
result?: import('stylelint').PostcssResult | undefined; | ||
context?: import('stylelint').RuleContext | undefined; | ||
}, | ||
@@ -58,2 +60,5 @@ callback: (warning: import('postcss').Warning) => void | ||
}; | ||
reference: { | ||
longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties; | ||
}; | ||
}; | ||
@@ -60,0 +65,0 @@ export type StylelintOptions = import('stylelint').LinterOptions; |
@@ -16,3 +16,3 @@ /// <reference types="stylelint" /> | ||
ruleName: string, | ||
plugin: import('stylelint').Plugin<any, any> | ||
rule: import('stylelint').Rule<any, any> | ||
) => { | ||
@@ -53,2 +53,4 @@ ruleName: string; | ||
root: import('postcss').Root; | ||
result?: import('stylelint').PostcssResult | undefined; | ||
context?: import('stylelint').RuleContext | undefined; | ||
}, | ||
@@ -58,4 +60,7 @@ callback: (warning: import('postcss').Warning) => void | ||
}; | ||
reference: { | ||
longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties; | ||
}; | ||
}; | ||
export type StylelintOptions = import('stylelint').LinterOptions; | ||
export type Options = import('./options').Options; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
51241
1385
321
34
4
+ Added@jest/schemas@29.6.3(transitive)
+ Added@jest/types@29.6.3(transitive)
+ Added@sinclair/typebox@0.27.8(transitive)
+ Added@types/istanbul-lib-coverage@2.0.6(transitive)
+ Added@types/istanbul-lib-report@3.0.3(transitive)
+ Added@types/istanbul-reports@3.0.4(transitive)
+ Added@types/yargs@17.0.33(transitive)
+ Added@types/yargs-parser@21.0.3(transitive)
+ Addedcaniuse-lite@1.0.30001680(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedci-info@3.9.0(transitive)
+ Addedelectron-to-chromium@1.5.63(transitive)
+ Addedjest-util@29.7.0(transitive)
+ Addedjest-worker@29.7.0(transitive)
- Removedcaniuse-lite@1.0.30001683(transitive)
- Removedelectron-to-chromium@1.5.64(transitive)
- Removedjest-worker@28.1.3(transitive)
Updatedjest-worker@^29.4.1