<commit_before>import type { Declaration, Root, Result, AtRule } from 'postcss';
import stylelint from 'stylelint';
import shortCSS from 'shortcss';
import list from 'shortcss/lib/list';
import cssValues from 'css-values';

import {
  validProperties,
  validOptions,
  expected,
  getTypes,
  getIgnoredVariablesOrFunctions,
  getIgnoredKeywords,
  getIgnoredValues,
  getAutoFixFunc,
} from './lib/validation';
import defaults, {
  ISecondaryOptions,
  TIgnoreValue,
  TRegExpString,
} from './defaults';

/**
 * Rule Name.
 */
const ruleName = 'scale-unlimited/declaration-strict-value';
const { utils } = stylelint;
const messages = utils.ruleMessages(ruleName, {
  expected,
});
/**
 * RegExp to skip non-CSS properties.
 *
 * @internal
 */
const reSkipProp = /^(?:@|\$|--).+$/;
/**
 * RegExp to parse CSS, SCSS and less variables.
 * - allowing CSS variables to be multi line
 * - Sass namespaces and CSS <ident-token> supported
 *
 * @internal
 * @see https://github.com/sass/sass/blob/master/accepted/module-system.md#member-references
 * @see  https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
 */
// eslint-disable-next-line no-control-regex
const reVar = /^-?(?:@.+|(?:(?:[a-zA-Z_-]|[^\x00-\x7F])+(?:[a-zA-Z0-9_-]|[^\x00-\x7F])*\.)?\$.+|var\(\s*--[\s\S]+\))$/;
/**
 * RegExp to parse functions.
 * - irgnoring CSS variables `var(--*)`
 * - allow multi line arguments
 *
 * @internal
 */
const reFunc = /^(?!var\(\s*--)[\s\S]+\([\s\S]*\)$/;
/**
 * RegExp to parse regular expressions.
 * - supporting patterns
 * - and optional flags
 *
 * @internal
 */
const reRegex = /^\/(.*)\/([a-zA-Z]*)$/;
/**
 * @internal
 */
type TRegExpArray = [string, string?];
/**
 * Checks if string is a Regular Expression.
 *
 * @internal
 * @param value - Any string.
 */
const isRegexString = (value: string): value is TRegExpString =>
  reRegex.test(value);
/**
 * Get pattern and flags of a Regular Expression string.
 *
 * @internal
 * @param value - Any string representing a Regular Expression.
 * @returns An Array of pattern and flags of a Regular Expression string.
 */
const getRegexString = (value: string): TRegExpArray =>
  value.match(reRegex)!.slice(1) as TRegExpArray;
/**
 * Convert a Regular Expression string to an RegExp object.
 *
 * @internal
 * @param value - Any string representing a Regular Expression.
 * @returns A Regular Expression object.
 */
const stringToRegex = (value: TRegExpString) => {
  const [pattern, flags] = getRegexString(value);
  return new RegExp(pattern, flags);
};
/**
 * Map ignored value config to a Regular expression.
 *
 * @internal
 * @param ignoreValue - A ignored value property.
 * @returns A Regular Expression to match ignored values.
 */
const mapIgnoreValue = (ignoreValue: TIgnoreValue) =>
  isRegexString(`${ignoreValue}`)
    ? stringToRegex(`${ignoreValue}`)
    : new RegExp(`^${ignoreValue}$`);

/**
 * A rule function essentially returns a little PostCSS plugin.
 * It will report violations of this rule.
 *
 * @param root - PostCSS root (the parsed AST).
 * @param result - PostCSS lazy result.
 */
type PostCSSPlugin = (root: Root, result: Result) => void | PromiseLike<void>;

/**
 * Third Stylelint plugin context parameter.
 */
interface StylelintContext {
  /**
   * Wheter or not stylelint was executed with `--fix` option.
   *
   * @defaultValue false
   */
  fix?: boolean;
}

/**
 * Stylelint declaration strict value rule function.
 *
 * @see https://stylelint.io/developer-guide/plugins
 * @param properties - Primary options, a CSS property or list of CSS properties to lint.
 * @param options- Secondary options, configure edge cases.
 * @param context - Only used for autofixing.
 *
 * @returns Returns a PostCSS Plugin.
 */
interface StylelintRuleFunction {
  (
    primaryOption: string | string[],
    secondaryOptions?: ISecondaryOptions,
    context?: StylelintContext
  ): PostCSSPlugin;
  primaryOptionArray: boolean;
}
const ruleFunction: StylelintRuleFunction = (
  properties: string | string[],
  options: ISecondaryOptions,
  context: StylelintContext = {}
) => (root: Root, result: Result) => {
  // validate stylelint plugin options
  const hasValidOptions = utils.validateOptions(
    result,
    ruleName,
    {
      actual: properties,
      possible: validProperties,
    },
    {
      actual: options,
      possible: validOptions,
      optional: true,
    }
  );

  if (!hasValidOptions) return;

  // normalize options<commit_msg>docs: add type for primary optoin<commit_after>import type { Declaration, Root, Result, AtRule } from 'postcss';
import stylelint from 'stylelint';
import shortCSS from 'shortcss';
import list from 'shortcss/lib/list';
import cssValues from 'css-values';

import {
  validProperties,
  validOptions,
  expected,
  getTypes,
  getIgnoredVariablesOrFunctions,
  getIgnoredKeywords,
  getIgnoredValues,
  getAutoFixFunc,
} from './lib/validation';
import defaults, {
  ISecondaryOptions,
  TIgnoreValue,
  TRegExpString,
} from './defaults';

/**
 * Rule Name.
 */
const ruleName = 'scale-unlimited/declaration-strict-value';
const { utils } = stylelint;
const messages = utils.ruleMessages(ruleName, {
  expected,
});
/**
 * RegExp to skip non-CSS properties.
 *
 * @internal
 */
const reSkipProp = /^(?:@|\$|--).+$/;
/**
 * RegExp to parse CSS, SCSS and less variables.
 * - allowing CSS variables to be multi line
 * - Sass namespaces and CSS <ident-token> supported
 *
 * @internal
 * @see https://github.com/sass/sass/blob/master/accepted/module-system.md#member-references
 * @see  https://drafts.csswg.org/css-syntax-3/#ident-token-diagram
 */
// eslint-disable-next-line no-control-regex
const reVar = /^-?(?:@.+|(?:(?:[a-zA-Z_-]|[^\x00-\x7F])+(?:[a-zA-Z0-9_-]|[^\x00-\x7F])*\.)?\$.+|var\(\s*--[\s\S]+\))$/;
/**
 * RegExp to parse functions.
 * - irgnoring CSS variables `var(--*)`
 * - allow multi line arguments
 *
 * @internal
 */
const reFunc = /^(?!var\(\s*--)[\s\S]+\([\s\S]*\)$/;
/**
 * RegExp to parse regular expressions.
 * - supporting patterns
 * - and optional flags
 *
 * @internal
 */
const reRegex = /^\/(.*)\/([a-zA-Z]*)$/;
/**
 * @internal
 */
type TRegExpArray = [string, string?];
/**
 * Checks if string is a Regular Expression.
 *
 * @internal
 * @param value - Any string.
 */
const isRegexString = (value: string): value is TRegExpString =>
  reRegex.test(value);
/**
 * Get pattern and flags of a Regular Expression string.
 *
 * @internal
 * @param value - Any string representing a Regular Expression.
 * @returns An Array of pattern and flags of a Regular Expression string.
 */
const getRegexString = (value: string): TRegExpArray =>
  value.match(reRegex)!.slice(1) as TRegExpArray;
/**
 * Convert a Regular Expression string to an RegExp object.
 *
 * @internal
 * @param value - Any string representing a Regular Expression.
 * @returns A Regular Expression object.
 */
const stringToRegex = (value: TRegExpString) => {
  const [pattern, flags] = getRegexString(value);
  return new RegExp(pattern, flags);
};
/**
 * Map ignored value config to a Regular expression.
 *
 * @internal
 * @param ignoreValue - A ignored value property.
 * @returns A Regular Expression to match ignored values.
 */
const mapIgnoreValue = (ignoreValue: TIgnoreValue) =>
  isRegexString(`${ignoreValue}`)
    ? stringToRegex(`${ignoreValue}`)
    : new RegExp(`^${ignoreValue}$`);

/**
 * A rule function essentially returns a little PostCSS plugin.
 * It will report violations of this rule.
 *
 * @param root - PostCSS root (the parsed AST).
 * @param result - PostCSS lazy result.
 */
type PostCSSPlugin = (root: Root, result: Result) => void | PromiseLike<void>;

/**
 * Third Stylelint plugin context parameter.
 */
interface StylelintContext {
  /**
   * Wheter or not stylelint was executed with `--fix` option.
   *
   * @defaultValue false
   */
  fix?: boolean;
}

/**
 * Primary options, a CSS property or list of CSS properties to lint.
 * - Regular Expression strings are supported
 */
type TPrimaryOptions = string | TRegExpString | TPrimaryOptions[];

/**
 * Stylelint declaration strict value rule function.
 *
 * @see https://stylelint.io/developer-guide/plugins
 * @param properties - Primary options, a CSS property or list of CSS properties to lint.
 * @param options- Secondary options, configure edge cases.
 * @param context - Only used for autofixing.
 *
 * @returns Returns a PostCSS Plugin.
 */
interface StylelintRuleFunction {
  (
    primaryOption: TPrimaryOptions,
    secondaryOptions?: ISecondaryOptions,
    context?: StylelintContext
  ): PostCSSPlugin;
  primaryOptionArray: boolean;
}
const ruleFunction: StylelintRuleFunction = (
  properties: string | string[],
  options: ISecondaryOptions,
  context: StylelintContext = {}
) => (root: Root, result: Result) => {
  // validate stylelint plugin options
  const hasValidOptions = utils.validateOptions(
    result,
    ruleName,
    {
      actual: properties,
      possible: validProperties,
    },
    {
      actual: options,
      possible: validOptions,
      optional: true,
    }
  );

  if (!hasValidOptions) return;

  // normalize options
{'fraction_non_alphanumeric': 0.14452265728112626, 'fraction_numerical': 0.002199736031676199, 'mean_word_length': 3.606382978723404, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 21, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3982433', 'n_tokens_mistral': 2803, 'n_tokens_neox': 2774, 'n_words': 821}