You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.6 KiB
133 lines
3.6 KiB
'use strict'; |
|
|
|
const lintPostcssResult = require('./lintPostcssResult'); |
|
const path = require('path'); |
|
|
|
/** @typedef {import('stylelint').StylelintInternalApi} StylelintInternalApi */ |
|
/** @typedef {import('stylelint').GetLintSourceOptions} Options */ |
|
/** @typedef {import('postcss').Result} Result */ |
|
/** @typedef {import('stylelint').PostcssResult} PostcssResult */ |
|
/** @typedef {import('stylelint').StylelintPostcssResult} StylelintPostcssResult */ |
|
|
|
/** |
|
* Run stylelint on a PostCSS Result, either one that is provided |
|
* or one that we create |
|
* @param {StylelintInternalApi} stylelint |
|
* @param {Options} options |
|
* @returns {Promise<PostcssResult>} |
|
*/ |
|
module.exports = function lintSource(stylelint, options = {}) { |
|
if (!options.filePath && options.code === undefined && !options.existingPostcssResult) { |
|
return Promise.reject(new Error('You must provide filePath, code, or existingPostcssResult')); |
|
} |
|
|
|
const isCodeNotFile = options.code !== undefined; |
|
|
|
const inputFilePath = isCodeNotFile ? options.codeFilename : options.filePath; |
|
|
|
if (inputFilePath !== undefined && !path.isAbsolute(inputFilePath)) { |
|
if (isCodeNotFile) { |
|
return Promise.reject(new Error('codeFilename must be an absolute path')); |
|
} |
|
|
|
return Promise.reject(new Error('filePath must be an absolute path')); |
|
} |
|
|
|
const getIsIgnored = stylelint.isPathIgnored(inputFilePath).catch((err) => { |
|
if (isCodeNotFile && err.code === 'ENOENT') return false; |
|
|
|
throw err; |
|
}); |
|
|
|
return getIsIgnored.then((isIgnored) => { |
|
if (isIgnored) { |
|
/** @type {PostcssResult} */ |
|
|
|
return options.existingPostcssResult |
|
? Object.assign(options.existingPostcssResult, { |
|
stylelint: createEmptyStylelintPostcssResult(), |
|
}) |
|
: createEmptyPostcssResult(inputFilePath); |
|
} |
|
|
|
const configSearchPath = stylelint._options.configFile || inputFilePath; |
|
|
|
const getConfig = stylelint.getConfigForFile(configSearchPath).catch((err) => { |
|
if (isCodeNotFile && err.code === 'ENOENT') return stylelint.getConfigForFile(process.cwd()); |
|
|
|
throw err; |
|
}); |
|
|
|
return getConfig.then((result) => { |
|
if (!result) { |
|
throw new Error('Config file not found'); |
|
} |
|
|
|
const config = result.config; |
|
const existingPostcssResult = options.existingPostcssResult; |
|
const stylelintResult = { |
|
ruleSeverities: {}, |
|
customMessages: {}, |
|
disabledRanges: {}, |
|
}; |
|
|
|
if (existingPostcssResult) { |
|
const stylelintPostcssResult = Object.assign(existingPostcssResult, { |
|
stylelint: stylelintResult, |
|
}); |
|
|
|
return lintPostcssResult(stylelint._options, stylelintPostcssResult, config).then( |
|
() => stylelintPostcssResult, |
|
); |
|
} |
|
|
|
return stylelint |
|
._getPostcssResult({ |
|
code: options.code, |
|
codeFilename: options.codeFilename, |
|
filePath: inputFilePath, |
|
codeProcessors: config.codeProcessors, |
|
}) |
|
.then((postcssResult) => { |
|
const stylelintPostcssResult = Object.assign(postcssResult, { |
|
stylelint: stylelintResult, |
|
}); |
|
|
|
return lintPostcssResult(stylelint._options, stylelintPostcssResult, config).then( |
|
() => stylelintPostcssResult, |
|
); |
|
}); |
|
}); |
|
}); |
|
}; |
|
|
|
/** |
|
* @returns {StylelintPostcssResult} |
|
*/ |
|
function createEmptyStylelintPostcssResult() { |
|
return { |
|
ruleSeverities: {}, |
|
customMessages: {}, |
|
disabledRanges: {}, |
|
ignored: true, |
|
stylelintError: false, |
|
}; |
|
} |
|
|
|
/** |
|
* @param {string} [filePath] |
|
* @returns {PostcssResult} |
|
*/ |
|
function createEmptyPostcssResult(filePath) { |
|
return { |
|
root: { |
|
source: { |
|
input: { file: filePath }, |
|
}, |
|
}, |
|
messages: [], |
|
opts: undefined, |
|
stylelint: createEmptyStylelintPostcssResult(), |
|
warn: () => {}, |
|
}; |
|
}
|
|
|