diff --git a/.changeset/sharp-papayas-grab.md b/.changeset/sharp-papayas-grab.md new file mode 100644 index 0000000000..b5953434f0 --- /dev/null +++ b/.changeset/sharp-papayas-grab.md @@ -0,0 +1,5 @@ +--- +"stylelint": major +--- + +Changed: type definitions to reorganize diff --git a/lib/augmentConfig.js b/lib/augmentConfig.js index 5265648d02..c7b8850b33 100644 --- a/lib/augmentConfig.js +++ b/lib/augmentConfig.js @@ -8,10 +8,6 @@ const normalizeAllRuleSettings = require('./normalizeAllRuleSettings'); const normalizePath = require('normalize-path'); const path = require('path'); -/** @typedef {import('stylelint').ConfigExtends} StyleLintConfigExtends */ -/** @typedef {import('stylelint').ConfigPlugins} StylelintConfigPlugins */ -/** @typedef {import('stylelint').ConfigRules} StylelintConfigRules */ -/** @typedef {import('stylelint').ConfigOverride} StylelintConfigOverride */ /** @typedef {import('stylelint').InternalApi} StylelintInternalApi */ /** @typedef {import('stylelint').Config} StylelintConfig */ /** @typedef {import('stylelint').CosmiconfigResult} StylelintCosmiconfigResult */ @@ -220,7 +216,7 @@ function loadExtendedConfig(stylelint, configDir, extendLookup) { * @returns {StylelintConfig} */ function mergeConfigs(a, b) { - /** @type {{plugins: StylelintConfigPlugins}} */ + /** @type {Pick} */ const pluginMerger = {}; if (a.plugins || b.plugins) { @@ -235,7 +231,7 @@ function mergeConfigs(a, b) { } } - /** @type {{overrides: StylelintConfigOverride[]}} */ + /** @type {Pick} */ const overridesMerger = {}; if (a.overrides || b.overrides) { @@ -250,7 +246,7 @@ function mergeConfigs(a, b) { } } - /** @type {{extends: StyleLintConfigExtends}} */ + /** @type {Pick} */ const extendsMerger = {}; if (a.extends || b.extends) { diff --git a/lib/createPlugin.js b/lib/createPlugin.js index 0aa1f9b9f8..47c19a7ae8 100644 --- a/lib/createPlugin.js +++ b/lib/createPlugin.js @@ -1,7 +1,7 @@ 'use strict'; /** - * @type {typeof import('stylelint').createPlugin} + * @type {import('stylelint').default['createPlugin']} */ module.exports = function createPlugin(ruleName, rule) { return { diff --git a/lib/createStylelint.js b/lib/createStylelint.js index 15c37114c6..059dcff802 100644 --- a/lib/createStylelint.js +++ b/lib/createStylelint.js @@ -8,14 +8,8 @@ const FileCache = require('./utils/FileCache'); const IS_TEST = process.env.NODE_ENV === 'test'; const STOP_DIR = IS_TEST ? process.cwd() : undefined; -/** @typedef {import('stylelint').InternalApi} StylelintInternalApi */ - /** - * The stylelint "internal API" is passed among functions - * so that methods on a stylelint instance can invoke - * each other while sharing options and caches. - * - * @type {import('stylelint')['createLinter']} + * @type {import('stylelint').default['_createLinter']} */ module.exports = function createStylelint(options = {}) { const cwd = options.cwd || process.cwd(); diff --git a/lib/descriptionlessDisables.js b/lib/descriptionlessDisables.js index f844f921d4..4c8d7b1c17 100644 --- a/lib/descriptionlessDisables.js +++ b/lib/descriptionlessDisables.js @@ -4,7 +4,6 @@ const optionsMatches = require('./utils/optionsMatches'); const validateDisableSettings = require('./validateDisableSettings'); /** @typedef {import('postcss').Comment} PostcssComment */ -/** @typedef {import('stylelint').RangeType} RangeType */ /** @typedef {import('stylelint').DisableReportRange} DisableReportRange */ /** @typedef {import('stylelint').DisableOptionsReport} StylelintDisableOptionsReport */ diff --git a/lib/formatters/index.js b/lib/formatters/index.js index ae1ccfc0d0..ae2a5732b2 100644 --- a/lib/formatters/index.js +++ b/lib/formatters/index.js @@ -2,7 +2,7 @@ const importLazy = require('import-lazy'); -/** @type {typeof import('stylelint').formatters} */ +/** @type {import('stylelint').default['formatters']} */ const formatters = { compact: importLazy(() => require('./compactFormatter'))(), github: importLazy(() => require('./githubFormatter'))(), diff --git a/lib/index.js b/lib/index.js index 5073dd6473..30d08c3e3a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,14 +13,14 @@ const { longhandSubPropertiesOfShorthandProperties } = require('./reference/prop const standalone = require('./standalone'); const validateOptions = require('./utils/validateOptions'); -/** @type {import('stylelint').PublicApi} */ +/** @type {import('stylelint').default} */ const stylelint = Object.assign(postcssPlugin, { lint: standalone, rules, formatters, createPlugin, resolveConfig, - createLinter: createStylelint, + _createLinter: createStylelint, utils: { report, ruleMessages, diff --git a/lib/invalidScopeDisables.js b/lib/invalidScopeDisables.js index e8b269bd8a..7aad8e724b 100644 --- a/lib/invalidScopeDisables.js +++ b/lib/invalidScopeDisables.js @@ -3,8 +3,6 @@ const optionsMatches = require('./utils/optionsMatches'); const validateDisableSettings = require('./validateDisableSettings'); -/** @typedef {import('stylelint').RangeType} RangeType */ - /** * @param {import('stylelint').LintResult[]} results */ diff --git a/lib/needlessDisables.js b/lib/needlessDisables.js index 3a1da997ea..9431e16a7a 100644 --- a/lib/needlessDisables.js +++ b/lib/needlessDisables.js @@ -6,7 +6,6 @@ const validateDisableSettings = require('./validateDisableSettings'); /** @typedef {import('postcss').Comment} PostcssComment */ /** @typedef {import('stylelint').DisabledRange} DisabledRange */ -/** @typedef {import('stylelint').RangeType} RangeType */ /** @typedef {import('stylelint').DisableReportRange} DisableReportRange */ /** @@ -88,7 +87,7 @@ module.exports = function needlessDisables(results) { /** * @param {import('stylelint').DisabledWarning} warning - * @param {RangeType} range + * @param {DisabledRange} range * @return {boolean} */ function isWarningInRange(warning, range) { diff --git a/lib/normalizeAllRuleSettings.js b/lib/normalizeAllRuleSettings.js index e9ea800c90..6562efaa37 100644 --- a/lib/normalizeAllRuleSettings.js +++ b/lib/normalizeAllRuleSettings.js @@ -3,7 +3,6 @@ const normalizeRuleSettings = require('./normalizeRuleSettings'); const getStylelintRule = require('./utils/getStylelintRule'); -/** @typedef {import('stylelint').ConfigRules} StylelintConfigRules */ /** @typedef {import('stylelint').Config} StylelintConfig */ /** @@ -13,7 +12,7 @@ const getStylelintRule = require('./utils/getStylelintRule'); function normalizeAllRuleSettings(config) { if (!config.rules) return config; - /** @type {StylelintConfigRules} */ + /** @type {StylelintConfig['rules']} */ const normalizedRules = {}; for (const [ruleName, rawRuleSettings] of Object.entries(config.rules)) { diff --git a/lib/reportDisables.js b/lib/reportDisables.js index e0fe313d97..1abf008ffc 100644 --- a/lib/reportDisables.js +++ b/lib/reportDisables.js @@ -1,6 +1,5 @@ 'use strict'; -/** @typedef {import('stylelint').RangeType} RangeType */ /** @typedef {import('stylelint').DisableReportRange} DisabledRange */ /** @typedef {import('stylelint').LintResult} StylelintResult */ /** @typedef {import('stylelint').ConfigRuleSettings} StylelintConfigRuleSettings */ @@ -18,7 +17,6 @@ module.exports = function reportDisables(results) { continue; } - /** @type {{[ruleName: string]: Array}} */ const rangeData = result._postcssResult.stylelint.disabledRanges; if (!rangeData) continue; diff --git a/lib/resolveConfig.js b/lib/resolveConfig.js index b2ea88e127..5ca3486957 100644 --- a/lib/resolveConfig.js +++ b/lib/resolveConfig.js @@ -6,17 +6,7 @@ const createStylelint = require('./createStylelint'); const getConfigForFile = require('./getConfigForFile'); /** - * Resolves the effective configuration for a given file. Resolves to `undefined` - * if no config is found. - * @param {string} filePath - The path to the file to get the config for. - * @param {Pick< - * import('stylelint').LinterOptions, - * | 'cwd' - * | 'config' - * | 'configBasedir' - * | 'configFile' - * >} options - The options to use when creating the Stylelint instance. - * @returns {Promise} + * @type {import('stylelint').default['resolveConfig']} */ module.exports = async function resolveConfig( filePath, diff --git a/lib/rules/index.js b/lib/rules/index.js index df7cefaf70..e0118bd01d 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -2,7 +2,7 @@ const importLazy = require('import-lazy'); -/** @type {typeof import('stylelint').rules} */ +/** @type {import('stylelint').default['rules']} */ const rules = { 'alpha-value-notation': importLazy(() => require('./alpha-value-notation'))(), 'annotation-no-unknown': importLazy(() => require('./annotation-no-unknown'))(), diff --git a/lib/standalone.js b/lib/standalone.js index 66fe3f6002..a9cf2d636b 100644 --- a/lib/standalone.js +++ b/lib/standalone.js @@ -22,16 +22,11 @@ const prepareReturnValue = require('./prepareReturnValue'); const ALWAYS_IGNORED_GLOBS = ['**/node_modules/**']; const writeFileAtomic = require('write-file-atomic'); -/** @typedef {import('stylelint').LinterOptions} LinterOptions */ -/** @typedef {import('stylelint').LinterResult} LinterResult */ -/** @typedef {import('stylelint').LintResult} StylelintResult */ /** @typedef {import('stylelint').Formatter} Formatter */ /** @typedef {import('stylelint').FormatterType} FormatterType */ /** - * - * @param {LinterOptions} options - * @returns {Promise} + * @type {import('stylelint').default['lint']} */ async function standalone({ allowEmptyInput = false, @@ -304,7 +299,7 @@ function getFormatterFunction(selected) { * @typedef {import('stylelint').CssSyntaxError} CssSyntaxError * * @param {unknown} error - * @return {StylelintResult} + * @return {import('stylelint').LintResult} */ function handleError(error) { if (error instanceof Error && error.name === 'CssSyntaxError') { @@ -314,4 +309,4 @@ function handleError(error) { throw error; } -module.exports = /** @type {typeof import('stylelint').lint} */ (standalone); +module.exports = standalone; diff --git a/lib/utils/checkAgainstRule.js b/lib/utils/checkAgainstRule.js index 8a138954fe..fda20d4375 100644 --- a/lib/utils/checkAgainstRule.js +++ b/lib/utils/checkAgainstRule.js @@ -6,10 +6,7 @@ const { isPlainObject } = require('./validateTypes'); const getStylelintRule = require('./getStylelintRule'); /** - * Useful for third-party code (e.g. plugins) to run a PostCSS Root - * against a specific rule and do something with the warnings - * - * @type {typeof import('stylelint').utils.checkAgainstRule} + * @type {import('stylelint').Utils['checkAgainstRule']} */ function checkAgainstRule(options, callback) { if (!isPlainObject(options)) throw new Error('Expected an options object'); diff --git a/lib/utils/configurationError.js b/lib/utils/configurationError.js index 4b3b308a65..2d662ba06a 100644 --- a/lib/utils/configurationError.js +++ b/lib/utils/configurationError.js @@ -1,9 +1,10 @@ 'use strict'; -/** @typedef {import('stylelint').ConfigurationError} ConfigurationError */ +/** @typedef {Error & { code: number }} ConfigurationError */ /** - * Create configurationError from text and set CLI exit code + * Create configurationError from text and set CLI exit code. + * * @param {string} text * @returns {ConfigurationError} */ diff --git a/lib/utils/report.js b/lib/utils/report.js index 3aed256a6a..c9a7e814a9 100644 --- a/lib/utils/report.js +++ b/lib/utils/report.js @@ -12,7 +12,7 @@ * * You *must* pass *either* a node or a line number. * - * @type {typeof import('stylelint').utils.report} + * @type {import('stylelint').Utils['report']} */ module.exports = function report(problem) { const { ruleName, result, message, messageArgs, line, node, index, endIndex, word, severity } = diff --git a/lib/utils/ruleMessages.js b/lib/utils/ruleMessages.js index ef847d1f93..765fe4da12 100644 --- a/lib/utils/ruleMessages.js +++ b/lib/utils/ruleMessages.js @@ -1,32 +1,20 @@ 'use strict'; /** - * Given an object of problem messages, return another - * that provides the same messages postfixed with the rule - * that has been violated. - * - * @template {import('stylelint').RuleMessages} T - * @template {{[K in keyof T]: T[K]}} R - * @param {string} ruleName - * @param {T} messages - Object whose keys are message identifiers - * and values are either message strings or functions that return message strings - * @returns {R} New message object, whose messages will be marked with the rule name + * @type {import('stylelint').Utils['ruleMessages']} */ -function ruleMessages(ruleName, messages) { - /** @typedef {keyof T} K */ - const newMessages = /** @type {R} */ ({}); +module.exports = function ruleMessages(ruleName, messages) { + /** @type {import('stylelint').RuleMessages} */ + const newMessages = {}; - for (const [messageId, messageText] of /** @type {[K, T[K]][]} */ (Object.entries(messages))) { + for (const [messageId, messageText] of Object.entries(messages)) { if (typeof messageText === 'string') { - newMessages[messageId] = /** @type {R[K]} */ (`${messageText} (${ruleName})`); + newMessages[messageId] = `${messageText} (${ruleName})`; } else { - newMessages[messageId] = /** @type {R[K]} */ ( - (...args) => `${messageText(...args)} (${ruleName})` - ); + newMessages[messageId] = (...args) => `${messageText(...args)} (${ruleName})`; } } + // @ts-expect-error -- TS2322: Type 'RuleMessages' is not assignable to type 'R'. return newMessages; -} - -module.exports = /** @type {typeof import('stylelint').utils.ruleMessages} */ (ruleMessages); +}; diff --git a/lib/utils/validateOptions.js b/lib/utils/validateOptions.js index 4fe9d8251c..964d2bf69b 100644 --- a/lib/utils/validateOptions.js +++ b/lib/utils/validateOptions.js @@ -6,30 +6,12 @@ const { isPlainObject } = require('./validateTypes'); const IGNORED_OPTIONS = new Set(['severity', 'message', 'reportDisables', 'disableFix']); /** @typedef {import('stylelint').RuleOptions} RuleOptions */ -/** @typedef {import('stylelint').RuleOptionsPossible} Possible */ -/** @typedef {import('stylelint').RuleOptionsPossibleFunc} PossibleFunc */ +/** @typedef {import('stylelint').RuleOptionsPossible} RuleOptionsPossible */ /** - * Validate a rule's options. - * - * See existing rules for examples. - * - * @param {import('stylelint').PostcssResult} result - postcss result - * @param {string} ruleName - * @param {...RuleOptions} optionDescriptions - Each optionDescription can - * have the following properties: - * - `actual` (required): the actual passed option value or object. - * - `possible` (required): a schema representation of what values are - * valid for those options. `possible` should be an object if the - * options are an object, with corresponding keys; if the options are not an - * object, `possible` isn't, either. All `possible` value representations - * should be **arrays of either values or functions**. Values are === checked - * against `actual`. Functions are fed `actual` as an argument and their - * return value is interpreted: truthy = valid, falsy = invalid. - * - `optional` (optional): If this is `true`, `actual` can be undefined. - * @return {boolean} Whether or not the options are valid (true = valid) + * @type {import('stylelint').Utils['validateOptions']} */ -function validateOptions(result, ruleName, ...optionDescriptions) { +module.exports = function validateOptions(result, ruleName, ...optionDescriptions) { let noErrors = true; for (const optionDescription of optionDescriptions) { @@ -54,7 +36,7 @@ function validateOptions(result, ruleName, ...optionDescriptions) { } return noErrors; -} +}; /** * @param {RuleOptions} opts @@ -161,7 +143,7 @@ function validate(opts, ruleName, complain) { } /** - * @param {Possible | Possible[]} possible + * @param {RuleOptionsPossible | RuleOptionsPossible[]} possible * @param {unknown} actual * @returns {boolean} */ @@ -190,5 +172,3 @@ function stringify(value) { return `"${JSON.stringify(value)}"`; } - -module.exports = /** @type {typeof import('stylelint').utils.validateOptions} */ (validateOptions); diff --git a/types/stylelint/index.d.ts b/types/stylelint/index.d.ts index f4547460f2..eaf833713d 100644 --- a/types/stylelint/index.d.ts +++ b/types/stylelint/index.d.ts @@ -1,541 +1,623 @@ declare module 'stylelint' { import type * as PostCSS from 'postcss'; import type { GlobbyOptions } from 'globby'; - import type { cosmiconfig } from 'cosmiconfig'; - - namespace stylelint { - export type Severity = 'warning' | 'error'; - - export type ConfigExtends = string | string[]; - export type Plugin = - | { default?: { ruleName: string; rule: Rule } } - | { ruleName: string; rule: Rule }; - export type ConfigPlugins = string | Plugin | (string | Plugin)[]; - export type ConfigProcessor = string | [string, Object]; - export type ConfigProcessors = string | ConfigProcessor[]; - export type ConfigIgnoreFiles = string | string[]; - export type ConfigRuleSettings = - | null - | undefined - | NonNullable - | [NonNullable] - | [NonNullable, O]; - export type ConfigRules = { - [ruleName: string]: ConfigRuleSettings; + import type { cosmiconfig, TransformSync as CosmiconfigTransformSync } from 'cosmiconfig'; + + /** + * Rule severity. + */ + export type Severity = 'warning' | 'error'; + + type ConfigExtends = string | string[]; + type Plugin = { default?: { ruleName: string; rule: Rule } } | { ruleName: string; rule: Rule }; + type ConfigPlugins = string | Plugin | (string | Plugin)[]; + type ConfigIgnoreFiles = string | string[]; + + /** @internal */ + export type ConfigRuleSettings = + | null + | undefined + | NonNullable + | [NonNullable] + | [NonNullable, O]; + + type ConfigRules = { + [ruleName: string]: ConfigRuleSettings; + }; + type ConfigOverride = Omit & { + files: string | string[]; + }; + + /** @internal */ + export type DisableOptions = { + except?: (string | RegExp)[]; + severity?: Severity; + }; + type DisableSettings = ConfigRuleSettings; + + /** + * Configuration. + */ + export type Config = { + extends?: ConfigExtends; + plugins?: ConfigPlugins; + pluginFunctions?: { + [pluginName: string]: Rule; }; - export type ConfigOverride = Omit & { - files: string | string[]; - }; - - export type DisableOptions = { - except?: (string | RegExp)[]; - severity?: Severity; - }; - export type DisableSettings = ConfigRuleSettings; - - export type Config = { - extends?: ConfigExtends; - plugins?: ConfigPlugins; - pluginFunctions?: { - [pluginName: string]: Rule; - }; - ignoreFiles?: ConfigIgnoreFiles; - ignorePatterns?: string; - rules?: ConfigRules; - quiet?: boolean; - defaultSeverity?: Severity; - ignoreDisables?: DisableSettings; - reportNeedlessDisables?: DisableSettings; - reportInvalidScopeDisables?: DisableSettings; - reportDescriptionlessDisables?: DisableSettings; - overrides?: ConfigOverride[]; - customSyntax?: CustomSyntax; - }; - - // A meta-type that returns a union over all properties of `T` whose values - // have type `U`. - type PropertyNamesOfType = { - [K in keyof T]-?: T[K] extends U ? K : never; - }[keyof T]; - export type DisablePropertyName = PropertyNamesOfType; - - // This type has the same properties as `CosmiconfigResult` from `cosmiconfig`. - export type CosmiconfigResult = { - config: Config; - filepath: string; - isEmpty?: boolean; - } | null; - - export type ConfigurationError = Error & { code: 78 }; - - export type DisabledRange = { - comment: PostCSS.Comment; - start: number; - strictStart: boolean; - end?: number; - strictEnd?: boolean; - rules?: string[]; - description?: string; - }; - - export type DisabledRangeObject = { - [ruleName: string]: DisabledRange[]; - }; - - export type DisabledWarning = { line: number; rule: string }; - - type FileCache = { - calcHashOfConfig: (config: Config) => void; - hasFileChanged: (absoluteFilepath: string) => boolean; - reconcile: () => void; - destroy: () => void; - removeEntry: (absoluteFilepath: string) => void; - }; - - export type StylelintPostcssResult = { - ruleSeverities: { [ruleName: string]: Severity }; - customMessages: { [ruleName: string]: RuleMessage }; - ruleMetadata: { [ruleName: string]: Partial }; - quiet?: boolean; - disabledRanges: DisabledRangeObject; - disabledWarnings?: DisabledWarning[]; - ignored?: boolean; - stylelintError?: boolean; - stylelintWarning?: boolean; - disableWritingFix?: boolean; - config?: Config; - ruleDisableFix?: boolean; - }; - - type EmptyResult = { - root: { - nodes?: undefined; - source: { - lang?: undefined; - input: { - file?: string; - }; + ignoreFiles?: ConfigIgnoreFiles; + ignorePatterns?: string; + rules?: ConfigRules; + quiet?: boolean; + defaultSeverity?: Severity; + ignoreDisables?: DisableSettings; + reportNeedlessDisables?: DisableSettings; + reportInvalidScopeDisables?: DisableSettings; + reportDescriptionlessDisables?: DisableSettings; + overrides?: ConfigOverride[]; + customSyntax?: CustomSyntax; + }; + + // A meta-type that returns a union over all properties of `T` whose values + // have type `U`. + type PropertyNamesOfType = { + [K in keyof T]-?: T[K] extends U ? K : never; + }[keyof T]; + + /** @internal */ + export type DisablePropertyName = PropertyNamesOfType; + + /** @internal */ + export type CosmiconfigResult = + | (ReturnType & { config: Config }) + | null; + + /** @internal */ + export type DisabledRange = { + comment: PostCSS.Comment; + start: number; + strictStart: boolean; + end?: number; + strictEnd?: boolean; + rules?: string[]; + description?: string; + }; + + /** @internal */ + export type DisabledRangeObject = { + [ruleName: string]: DisabledRange[]; + }; + + /** @internal */ + export type DisabledWarning = { line: number; rule: string }; + + type FileCache = { + calcHashOfConfig: (config: Config) => void; + hasFileChanged: (absoluteFilepath: string) => boolean; + reconcile: () => void; + destroy: () => void; + removeEntry: (absoluteFilepath: string) => void; + }; + + /** @internal */ + export type StylelintPostcssResult = { + ruleSeverities: { [ruleName: string]: Severity }; + customMessages: { [ruleName: string]: RuleMessage }; + ruleMetadata: { [ruleName: string]: Partial }; + quiet?: boolean; + disabledRanges: DisabledRangeObject; + disabledWarnings?: DisabledWarning[]; + ignored?: boolean; + stylelintError?: boolean; + stylelintWarning?: boolean; + disableWritingFix?: boolean; + config?: Config; + ruleDisableFix?: boolean; + }; + + type EmptyResult = { + root: { + nodes?: undefined; + source: { + lang?: undefined; + input: { + file?: string; }; }; - messages: PostCSS.Message[]; - opts: undefined; - }; - - export type WarningOptions = PostCSS.WarningOptions & { - stylelintType?: string; - severity?: Severity; - rule?: string; - }; - - export type PostcssResult = (PostCSS.Result | EmptyResult) & { - stylelint: StylelintPostcssResult; - warn(message: string, options?: WarningOptions): void; - }; - - export type Formatter = (results: LintResult[], returnValue: LinterResult) => string; - - export type FormatterType = - | 'compact' - | 'github' - | 'json' - | 'string' - | 'tap' - | 'unix' - | 'verbose'; - - export type CustomSyntax = string | PostCSS.Syntax; - - // Note: With strict function types enabled, function signatures are checked contravariantly. - // This means that it would not be possible for rule authors to narrow the message function - // parameters to e.g. just `string`. Declaring the type for rule message functions through - // method declarations tricks TypeScript into bivariant signature checking. More details can - // be found here: https://stackoverflow.com/questions/52667959/what-is-the-purpose-of-bivariancehack-in-typescript-types. - // and in the original discussion: https://github.com/stylelint/stylelint/pull/6147#issuecomment-1155337016. - export type RuleMessageFunc = { - bivariance(...args: (string | number | boolean | RegExp)[]): string; - }['bivariance']; - - export type RuleMessage = string | RuleMessageFunc; - - export type RuleMessages = { [message: string]: RuleMessage }; - - export type RuleOptionsPossibleFunc = (value: unknown) => boolean; - - export type RuleOptionsPossible = boolean | number | string | RuleOptionsPossibleFunc; - - export type RuleOptions = { - actual: unknown; - possible?: - | RuleOptionsPossibleFunc - | RuleOptionsPossible[] - | Record; - optional?: boolean; - }; - - export type RuleContext = { - fix?: boolean | undefined; - newline?: string | undefined; }; - - export type RuleBase

= ( - primaryOption: P, - secondaryOptions: Record, - context: RuleContext, - ) => (root: PostCSS.Root, result: PostcssResult) => Promise | void; - - export type RuleMeta = { - url: string; - deprecated?: boolean; - fixable?: boolean; - }; - - export type Rule

= RuleBase & { - ruleName: string; - messages: RuleMessages; - primaryOptionArray?: boolean; - meta?: RuleMeta; - }; - - export type GetPostcssOptions = { - code?: string; - codeFilename?: string; - filePath?: string; - customSyntax?: CustomSyntax; - }; - - export type GetLintSourceOptions = GetPostcssOptions & { - existingPostcssResult?: PostCSS.Result; - cache?: boolean; - }; - - export type LinterOptions = { - files?: string | string[]; - globbyOptions?: GlobbyOptions; - cache?: boolean; - cacheLocation?: string; - cacheStrategy?: string; - code?: string; - codeFilename?: string; - config?: Config; - configFile?: string; - configBasedir?: string; - /** - * The working directory to resolve files from. Defaults to the - * current working directory. - */ - cwd?: string; - ignoreDisables?: boolean; - ignorePath?: string | string[]; - ignorePattern?: string[]; - reportDescriptionlessDisables?: boolean; - reportNeedlessDisables?: boolean; - reportInvalidScopeDisables?: boolean; - maxWarnings?: number; - customSyntax?: CustomSyntax; - formatter?: FormatterType | Formatter; - disableDefaultIgnores?: boolean; - fix?: boolean; - allowEmptyInput?: boolean; - quiet?: boolean; - }; - - export type CssSyntaxError = { + messages: PostCSS.Message[]; + opts: undefined; + }; + + /** @internal */ + export type WarningOptions = PostCSS.WarningOptions & { + stylelintType?: string; + severity?: Severity; + rule?: string; + }; + + /** @internal */ + export type PostcssResult = (PostCSS.Result | EmptyResult) & { + stylelint: StylelintPostcssResult; + warn(message: string, options?: WarningOptions): void; + }; + + /** @internal */ + export type Formatter = (results: LintResult[], returnValue: LinterResult) => string; + + /** @internal */ + export type FormatterType = 'compact' | 'github' | 'json' | 'string' | 'tap' | 'unix' | 'verbose'; + + /** @internal */ + export type CustomSyntax = string | PostCSS.Syntax; + + // Note: With strict function types enabled, function signatures are checked contravariantly. + // This means that it would not be possible for rule authors to narrow the message function + // parameters to e.g. just `string`. Declaring the type for rule message functions through + // method declarations tricks TypeScript into bivariant signature checking. More details can + // be found here: https://stackoverflow.com/questions/52667959/what-is-the-purpose-of-bivariancehack-in-typescript-types. + // and in the original discussion: https://github.com/stylelint/stylelint/pull/6147#issuecomment-1155337016. + type RuleMessageFunc = { + bivariance(...args: (string | number | boolean | RegExp)[]): string; + }['bivariance']; + + /** @internal */ + export type RuleMessage = string | RuleMessageFunc; + + /** @internal */ + export type RuleMessages = { [message: string]: RuleMessage }; + + type RuleOptionsPossibleFunc = (value: unknown) => boolean; + + /** @internal */ + export type RuleOptionsPossible = boolean | number | string | RuleOptionsPossibleFunc; + + /** @internal */ + export type RuleOptions = { + actual: unknown; + possible?: + | RuleOptionsPossibleFunc + | RuleOptionsPossible[] + | Record; + optional?: boolean; + }; + + type RuleContext = { + fix?: boolean | undefined; + newline?: string | undefined; + }; + + /** @internal */ + export type RuleBase

= ( + primaryOption: P, + secondaryOptions: Record, + context: RuleContext, + ) => (root: PostCSS.Root, result: PostcssResult) => Promise | void; + + /** @internal */ + export type RuleMeta = { + url: string; + deprecated?: boolean; + fixable?: boolean; + }; + + /** + * A rule. + */ + export type Rule

= RuleBase & { + ruleName: string; + messages: RuleMessages; + primaryOptionArray?: boolean; + meta?: RuleMeta; + }; + + /** @internal */ + export type GetPostcssOptions = { + code?: string; + codeFilename?: string; + filePath?: string; + customSyntax?: CustomSyntax; + }; + + /** @internal */ + export type GetLintSourceOptions = GetPostcssOptions & { + existingPostcssResult?: PostCSS.Result; + cache?: boolean; + }; + + /** + * Linter options. + */ + export type LinterOptions = { + files?: string | string[]; + globbyOptions?: GlobbyOptions; + cache?: boolean; + cacheLocation?: string; + cacheStrategy?: string; + code?: string; + codeFilename?: string; + config?: Config; + configFile?: string; + configBasedir?: string; + /** + * The working directory to resolve files from. Defaults to the + * current working directory. + */ + cwd?: string; + ignoreDisables?: boolean; + ignorePath?: string | string[]; + ignorePattern?: string[]; + reportDescriptionlessDisables?: boolean; + reportNeedlessDisables?: boolean; + reportInvalidScopeDisables?: boolean; + maxWarnings?: number; + customSyntax?: CustomSyntax; + formatter?: FormatterType | Formatter; + disableDefaultIgnores?: boolean; + fix?: boolean; + allowEmptyInput?: boolean; + quiet?: boolean; + }; + + /** + * A CSS syntax error. + */ + export type CssSyntaxError = { + file?: string; + input: { + column: number; file?: string; - input: { - column: number; - file?: string; - line: number; - source: string; - }; - /** - * The line of the inclusive start position of the error. - */ line: number; - /** - * The column of the inclusive start position of the error. - */ - column: number; - /** - * The line of the exclusive end position of the error. - */ - endLine?: number; - /** - * The column of the exclusive end position of the error. - */ - endColumn?: number; - message: string; - name: string; - reason: string; source: string; }; - - export type Warning = { - /** - * The line of the inclusive start position of the warning. - */ + /** + * The line of the inclusive start position of the error. + */ + line: number; + /** + * The column of the inclusive start position of the error. + */ + column: number; + /** + * The line of the exclusive end position of the error. + */ + endLine?: number; + /** + * The column of the exclusive end position of the error. + */ + endColumn?: number; + message: string; + name: string; + reason: string; + source: string; + }; + + /** + * A lint warning. + */ + export type Warning = { + /** + * The line of the inclusive start position of the warning. + */ + line: number; + /** + * The column of the inclusive start position of the warning. + */ + column: number; + /** + * The line of the exclusive end position of the warning. + */ + endLine?: number; + /** + * The column of the exclusive end position of the warning. + */ + endColumn?: number; + rule: string; + severity: Severity; + text: string; + stylelintType?: string; + }; + + /** + * A lint result. + */ + export type LintResult = { + source?: string; + deprecations: { + text: string; + reference: string; + }[]; + invalidOptionWarnings: { + text: string; + }[]; + parseErrors: (PostCSS.Warning & { stylelintType: string })[]; + errored?: boolean; + warnings: Warning[]; + ignored?: boolean; + /** + * Internal use only. Do not use or rely on this property. It may + * change at any time. + * @internal + */ + _postcssResult?: PostcssResult; + }; + + /** @internal */ + export type DisableReportRange = { + rule: string; + start: number; + end?: number; + }; + + type DisableReportEntry = { + source?: string; + ranges: DisableReportRange[]; + }; + + /** + * A linter result. + */ + export type LinterResult = { + /** + * The working directory from which the linter was run when the + * results were generated. + */ + cwd: string; + results: LintResult[]; + errored: boolean; + output: any; + maxWarningsExceeded?: { + maxWarnings: number; + foundWarnings: number; + }; + reportedDisables: DisableOptionsReport; + descriptionlessDisables?: DisableOptionsReport; + needlessDisables?: DisableOptionsReport; + invalidScopeDisables?: DisableOptionsReport; + /** + * Each rule metadata by name. + */ + ruleMetadata: { [ruleName: string]: Partial }; + }; + + /** + * A lint problem. + */ + export type Problem = { + ruleName: string; + result: PostcssResult; + message: RuleMessage; + messageArgs?: Parameters | undefined; + node: PostCSS.Node; + /** + * The inclusive start index of the problem, relative to the node's + * source text. + */ + index?: number; + /** + * The exclusive end index of the problem, relative to the node's + * source text. + */ + endIndex?: number; + /** + * The inclusive start position of the problem, relative to the + * node's source text. If provided, this will be used instead of + * `index`. + */ + start?: { line: number; - /** - * The column of the inclusive start position of the warning. - */ column: number; - /** - * The line of the exclusive end position of the warning. - */ - endLine?: number; - /** - * The column of the exclusive end position of the warning. - */ - endColumn?: number; - rule: string; - severity: Severity; - text: string; - stylelintType?: string; }; - - export type LintResult = { - source?: string; - deprecations: { - text: string; - reference: string; - }[]; - invalidOptionWarnings: { - text: string; - }[]; - parseErrors: (PostCSS.Warning & { stylelintType: string })[]; - errored?: boolean; - warnings: Warning[]; - ignored?: boolean; - /** - * Internal use only. Do not use or rely on this property. It may - * change at any time. - * @internal - */ - _postcssResult?: PostcssResult; + /** + * The exclusive end position of the problem, relative to the + * node's source text. If provided, this will be used instead of + * `endIndex`. + */ + end?: { + line: number; + column: number; }; + word?: string; + line?: number; + /** + * Optional severity override for the problem. + */ + severity?: Severity; + }; + + /** @internal */ + export type LonghandSubPropertiesOfShorthandProperties = ReadonlyMap< + | 'animation' + | 'background' + | 'border' + | 'border-block-end' + | 'border-block-start' + | 'border-bottom' + | 'border-color' + | 'border-image' + | 'border-inline-end' + | 'border-inline-start' + | 'border-left' + | 'border-radius' + | 'border-right' + | 'border-style' + | 'border-top' + | 'border-width' + | 'column-rule' + | 'columns' + | 'flex' + | 'flex-flow' + | 'font' + | 'grid' + | 'grid-area' + | 'grid-column' + | 'grid-gap' + | 'grid-row' + | 'grid-template' + | 'list-style' + | 'margin' + | 'mask' + | 'outline' + | 'padding' + | 'text-decoration' + | 'text-emphasis' + | 'transition', + ReadonlySet + >; + + /** + * Utility functions. + */ + export type Utils = { + /** + * Report a problem. + * + * This function accounts for `disabledRanges` attached to the result. + * That is, if the reported problem is within a disabledRange, + * it is ignored. Otherwise, it is attached to the result as a + * postcss warning. + * + * It also accounts for the rule's severity. + * + * You *must* pass *either* a node or a line number. + * + * @param problem - A problem + */ + report: (problem: Problem) => void; - export type DisableReportRange = { - rule: string; - start: number; - end?: number; - }; + /** + * Given an object of problem messages, return another + * that provides the same messages postfixed with the rule + * that has been violated. + * + * @param ruleName - A rule name + * @param messages - An object whose keys are message identifiers + * and values are either message strings or functions that return message strings + * @returns New message object, whose messages will be marked with the rule name + */ + ruleMessages: ( + ruleName: string, + messages: T, + ) => R; - export type RangeType = DisabledRange & { used?: boolean }; + /** + * Validate a rule's options. + * + * See existing rules for examples. + * + * @param result - PostCSS result + * @param ruleName - A rule name + * @param optionDescriptions - Each optionDescription can have the following properties: + * - `actual` (required): the actual passed option value or object. + * - `possible` (required): a schema representation of what values are + * valid for those options. `possible` should be an object if the + * options are an object, with corresponding keys; if the options are not an + * object, `possible` isn't, either. All `possible` value representations + * should be **arrays of either values or functions**. Values are === checked + * against `actual`. Functions are fed `actual` as an argument and their + * return value is interpreted: truthy = valid, falsy = invalid. + * - `optional` (optional): If this is `true`, `actual` can be undefined. + * @returns Whether or not the options are valid (`true` = valid) + */ + validateOptions: ( + result: PostcssResult, + ruleName: string, + ...optionDescriptions: RuleOptions[] + ) => boolean; - export type DisableReportEntry = { - source?: string; - ranges: DisableReportRange[]; - }; + /** + * Useful for third-party code (e.g. plugins) to run a PostCSS Root + * against a specific rule and do something with the warnings. + */ + checkAgainstRule: ( + options: { + ruleName: string; + ruleSettings: ConfigRuleSettings; + root: PostCSS.Root; + result?: PostcssResult; + context?: RuleContext; + }, + callback: (warning: PostCSS.Warning) => void, + ) => void; + }; + + /** + * Internal use only. Do not use or rely on this type. It may change at + * any time. + * @internal + */ + export type InternalApi = { + _options: LinterOptions & { cwd: string }; + _extendExplorer: ReturnType; + _specifiedConfigCache: Map>; + _postcssResultCache: Map; + _fileCache: FileCache; + }; + + export type DisableOptionsReport = DisableReportEntry[]; + + export type PostcssPluginOptions = Omit | Config; + + type PublicApi = PostCSS.PluginCreator & { + /** + * Runs Stylelint with the given options and returns a Promise that + * resolves to the results. + * + * @param options - A lint options object + * @returns A lint result + */ + lint: (options: LinterOptions) => Promise; - export type LinterResult = { - /** - * The working directory from which the linter was run when the - * results were generated. - */ - cwd: string; - results: LintResult[]; - errored: boolean; - output: any; - maxWarningsExceeded?: { - maxWarnings: number; - foundWarnings: number; - }; - reportedDisables: DisableOptionsReport; - descriptionlessDisables?: DisableOptionsReport; - needlessDisables?: DisableOptionsReport; - invalidScopeDisables?: DisableOptionsReport; - /** - * Each rule metadata by name. - */ - ruleMetadata: { [ruleName: string]: Partial }; - }; + /** + * Available rules. + */ + rules: { [k: string]: Rule }; - export type Problem = { - ruleName: string; - result: PostcssResult; - message: RuleMessage; - messageArgs?: Parameters | undefined; - node: PostCSS.Node; - /** - * The inclusive start index of the problem, relative to the node's - * source text. - */ - index?: number; - /** - * The exclusive end index of the problem, relative to the node's - * source text. - */ - endIndex?: number; - /** - * The inclusive start position of the problem, relative to the - * node's source text. If provided, this will be used instead of - * `index`. - */ - start?: { - line: number; - column: number; - }; - /** - * The exclusive end position of the problem, relative to the - * node's source text. If provided, this will be used instead of - * `endIndex`. - */ - end?: { - line: number; - column: number; - }; - word?: string; - line?: number; - /** - * Optional severity override for the problem. - */ - severity?: Severity; - }; + /** + * Result report formatters by name. + */ + formatters: { [k: string]: Formatter }; - export type LonghandSubPropertiesOfShorthandProperties = ReadonlyMap< - | 'animation' - | 'background' - | 'border' - | 'border-block-end' - | 'border-block-start' - | 'border-bottom' - | 'border-color' - | 'border-image' - | 'border-inline-end' - | 'border-inline-start' - | 'border-left' - | 'border-radius' - | 'border-right' - | 'border-style' - | 'border-top' - | 'border-width' - | 'column-rule' - | 'columns' - | 'flex' - | 'flex-flow' - | 'font' - | 'grid' - | 'grid-area' - | 'grid-column' - | 'grid-gap' - | 'grid-row' - | 'grid-template' - | 'list-style' - | 'margin' - | 'mask' - | 'outline' - | 'padding' - | 'text-decoration' - | 'text-emphasis' - | 'transition', - ReadonlySet - >; - - export type PublicApi = PostCSS.PluginCreator & { - /** - * Runs stylelint with the given options and returns a Promise that - * resolves to the results. - */ - lint: (options: LinterOptions) => Promise; - /** - * Available rules. - */ - rules: { [k: string]: Rule }; - /** - * Result report formatters by name. - */ - formatters: { [k: string]: Formatter }; - /** - * Creates a Stylelint plugin. - */ - createPlugin: (ruleName: string, rule: Rule) => Plugin; - /** - * Internal use only. Do not use or rely on this method. It may - * change at any time. - * @internal - */ - createLinter: (options: LinterOptions) => InternalApi; - /** - * Resolves the effective configuration for a given file. Resolves to - * `undefined` if no config is found. - * @param filePath - The path to the file to get the config for. - * @param options - The options to use when creating the Stylelint instance. - */ - resolveConfig: ( - filePath: string, - options?: Pick, - ) => Promise; - utils: { - /** - * Report a problem. - * - * This function accounts for `disabledRanges` attached to the result. - * That is, if the reported problem is within a disabledRange, - * it is ignored. Otherwise, it is attached to the result as a - * postcss warning. - * - * It also accounts for the rule's severity. - * - * You *must* pass *either* a node or a line number. - */ - report: (problem: Problem) => void; - /** - * Given an object of problem messages, return another - * that provides the same messages postfixed with the rule - * that has been violated. - */ - ruleMessages: ( - ruleName: string, - messages: T, - ) => R; - /** - * Validate a rule's options. - * - * See existing rules for examples. - */ - validateOptions: ( - result: PostcssResult, - ruleName: string, - ...optionDescriptions: RuleOptions[] - ) => boolean; - /** - * Useful for third-party code (e.g. plugins) to run a PostCSS Root - * against a specific rule and do something with the warnings - */ - checkAgainstRule: ( - options: { - ruleName: string; - ruleSettings: ConfigRuleSettings; - root: PostCSS.Root; - result?: PostcssResult; - context?: RuleContext; - }, - callback: (warning: PostCSS.Warning) => void, - ) => void; - }; - reference: { - longhandSubPropertiesOfShorthandProperties: LonghandSubPropertiesOfShorthandProperties; - }; - }; + /** + * Creates a Stylelint plugin. + */ + createPlugin: (ruleName: string, rule: Rule) => Plugin; /** - * Internal use only. Do not use or rely on this type. It may change at - * any time. + * The Stylelint "internal API" is passed among functions + * so that methods on a Stylelint instance can invoke + * each other while sharing options and caches. + * * @internal */ - export type InternalApi = { - _options: LinterOptions & { cwd: string }; - _extendExplorer: ReturnType; - _specifiedConfigCache: Map>; - _postcssResultCache: Map; - _fileCache: FileCache; - }; + _createLinter: (options: LinterOptions) => InternalApi; - export type DisableOptionsReport = DisableReportEntry[]; + /** + * Resolves the effective configuration for a given file. Resolves to + * `undefined` if no config is found. + * + * @param filePath - The path to the file to get the config for. + * @param options - The options to use when creating the Stylelint instance. + * @returns A resolved config or `undefined`. + */ + resolveConfig: ( + filePath: string, + options?: Pick, + ) => Promise; + + /** + * Utility functions. + */ + utils: Utils; - export type PostcssPluginOptions = Omit | Config; - } + /** + * Reference objects. + */ + reference: { + longhandSubPropertiesOfShorthandProperties: LonghandSubPropertiesOfShorthandProperties; + }; + }; - const stylelint: stylelint.PublicApi; + const stylelint: PublicApi; - export = stylelint; + export default stylelint; }