| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 | 'use strict';const LazyResult = require('postcss/lib/lazy-result').default;const path = require('path');const { default: postcss } = require('postcss');const { promises: fs } = require('fs');/** @typedef {import('postcss').Result} Result *//** @typedef {import('postcss').Syntax} Syntax *//** @typedef {import('stylelint').CustomSyntax} CustomSyntax *//** @typedef {import('stylelint').GetPostcssOptions} GetPostcssOptions *//** @typedef {import('stylelint').InternalApi} StylelintInternalApi */const postcssProcessor = postcss();/** * @param {StylelintInternalApi} stylelint * @param {GetPostcssOptions} options * * @returns {Promise<Result>} */module.exports = async function getPostcssResult(stylelint, options = {}) {	const cached = options.filePath ? stylelint._postcssResultCache.get(options.filePath) : undefined;	if (cached) {		return cached;	}	if (stylelint._options.syntax) {		let error = 'The "syntax" option is no longer available. ';		error +=			stylelint._options.syntax === 'css'				? 'You can remove the "--syntax" CLI flag as stylelint will now parse files as CSS by default'				: `You should install an appropriate syntax, e.g. postcss-scss, and use the "customSyntax" option`;		return Promise.reject(new Error(error));	}	const syntax = options.customSyntax		? getCustomSyntax(options.customSyntax)		: cssSyntax(stylelint, options.filePath);	const postcssOptions = {		from: options.filePath,		syntax,	};	/** @type {string | undefined} */	let getCode;	if (options.code !== undefined) {		getCode = options.code;	} else if (options.filePath) {		getCode = await fs.readFile(options.filePath, 'utf8');	}	if (getCode === undefined) {		return Promise.reject(new Error('code or filePath required'));	}	if (options.codeProcessors && options.codeProcessors.length) {		if (stylelint._options.fix) {			console.warn(				'Autofix is incompatible with processors and will be disabled. Are you sure you need a processor?',			);			stylelint._options.fix = false;		}		const sourceName = options.code ? options.codeFilename : options.filePath;		for (const codeProcessor of options.codeProcessors) {			getCode = codeProcessor(getCode, sourceName);		}	}	const postcssResult = await new LazyResult(postcssProcessor, getCode, postcssOptions);	if (options.filePath) {		stylelint._postcssResultCache.set(options.filePath, postcssResult);	}	return postcssResult;};/** * @param {CustomSyntax} customSyntax * @returns {Syntax} */function getCustomSyntax(customSyntax) {	let resolved;	if (typeof customSyntax === 'string') {		try {			resolved = require(customSyntax);		} catch (error) {			if (				error &&				typeof error === 'object' &&				// @ts-expect-error -- TS2571: Object is of type 'unknown'.				error.code === 'MODULE_NOT_FOUND' &&				// @ts-expect-error -- TS2571: Object is of type 'unknown'.				error.message.includes(customSyntax)			) {				throw new Error(					`Cannot resolve custom syntax module "${customSyntax}". Check that module "${customSyntax}" is available and spelled correctly.\n\nCaused by: ${error}`,				);			}			throw error;		}		/*		 * PostCSS allows for syntaxes that only contain a parser, however,		 * it then expects the syntax to be set as the `parse` option.		 */		if (!resolved.parse) {			resolved = {				parse: resolved,				stringify: postcss.stringify,			};		}		return resolved;	}	if (typeof customSyntax === 'object') {		if (typeof customSyntax.parse === 'function') {			resolved = { ...customSyntax };		} else {			throw new TypeError(				`An object provided to the "customSyntax" option must have a "parse" property. Ensure the "parse" property exists and its value is a function.`,			);		}		return resolved;	}	throw new Error(`Custom syntax must be a string or a Syntax object`);}/** @type {{ [key: string]: string }} */const previouslyInferredExtensions = {	html: 'postcss-html',	js: '@stylelint/postcss-css-in-js',	jsx: '@stylelint/postcss-css-in-js',	less: 'postcss-less',	md: 'postcss-markdown',	sass: 'postcss-sass',	sss: 'sugarss',	scss: 'postcss-scss',	svelte: 'postcss-html',	ts: '@stylelint/postcss-css-in-js',	tsx: '@stylelint/postcss-css-in-js',	vue: 'postcss-html',	xml: 'postcss-html',	xst: 'postcss-html',};/** * @param {StylelintInternalApi} stylelint * @param {string|undefined} filePath * @returns {Syntax} */function cssSyntax(stylelint, filePath) {	const fileExtension = filePath ? path.extname(filePath).slice(1).toLowerCase() : '';	const extensions = ['css', 'pcss', 'postcss'];	if (previouslyInferredExtensions[fileExtension]) {		console.warn(			`${filePath}: When linting something other than CSS, you should install an appropriate syntax, e.g. "${previouslyInferredExtensions[fileExtension]}", and use the "customSyntax" option`,		);	}	return {		parse:			stylelint._options.fix && extensions.includes(fileExtension)				? require('postcss-safe-parser')				: postcss.parse,		stringify: postcss.stringify,	};}
 |