{"version":3,"file":"index.mjs","names":[],"sources":["../../src/stylelint/index.ts"],"sourcesContent":["\nimport type { Config } from 'stylelint'\n\nimport { PathResolver } from '@/utils/resolver.ts'\n\n// types ======================================================================\n\n/**\n * Configuration options for StyleLint code style rules.\n */\nexport interface StylisticOptions {\n\n  /**\n   * Default indentation size (number of space characters).\n   *\n   * @default 2\n   */\n  indent?: number\n\n  /**\n   * The type of the string delimiter character.\n   *\n   * @default 'single'\n   */\n  quotes?: 'single' | 'double' | 'off'\n}\n\n// ----------------------------------------------------------------------------\n\n/**\n * Configuration options for linting the entire project with StyleLint.\n */\nexport interface ProjectOptions {\n\n  /**\n   * The URL of the project root containing the StyleLint configuration file.\n   * Should usually be set to `import.meta.url`.\n   */\n  root: string\n\n  /**\n   * Glob patterns for all files to be ignored by StyleLint (the patterns must\n   * match files, plain directory names are not supported).\n   */\n  ignores?: string[]\n\n  /**\n   * Path to the template file containing the license header to be used in all\n   * source files. May be a path relative to the project root.\n   */\n  license?: string\n\n  /**\n   * Configuration options for code style.\n   */\n  stylistic?: StylisticOptions\n\n  /**\n   * Additional linter rules to be added to the global configuration.\n   */\n  rules?: Config['rules']\n}\n\n// functions ==================================================================\n\n/**\n * Generates a StyleLint configuration object targeting the source files in the\n * entire project.\n *\n * @param options\n *  Plugin configuration options.\n *\n * @returns\n *  The configuration object to be exported from `stylelint.config.js`.\n */\nexport function defineConfig(options: ProjectOptions): Config {\n\n  const ignoreFiles: string[] = [\n    'node_modules/**/*',\n    'dist/**/*',\n    'output/**/*',\n    'coverage/**/*',  // Vitest\n    '.nuxt/**/*',     // NuxtJS\n    '.output/**/*',   // NuxtJS\n    ...(options.ignores ?? []),\n  ]\n\n  // resolve stylistic configuration options\n  const stylistic: StylisticOptions = {\n    indent: 2,\n    quotes: 'single',\n    ...options.stylistic,\n  }\n\n  // group custom rules by language plugins\n  type RuleRec = NonNullable<Config['rules']>\n  const rules: Record<string, RuleRec> = { base: {}, scss: {}, less: {} }\n  for (const [rule, value] of Object.entries(options.rules ?? {})) {\n    const key = rule.split('/')[0];\n    (rules[key] ?? rules.base)[rule] = value as unknown\n  }\n\n  // predefined rules for SCSS (used in '.scss' and '.vue' files)\n  rules.scss = {\n    'scss/dollar-variable-empty-line-before': null,\n    'scss/double-slash-comment-empty-line-before': null,\n    ...rules.scss,\n  }\n\n  // the resolver for relative file paths\n  const resolver = new PathResolver(options.root)\n\n  return {\n\n    // ignore certain files and folders\n    ignoreFiles,\n\n    // add the stylistic plugin\n    plugins: [\n      'stylelint-plugin-license-header',\n      '@stylistic/stylelint-plugin',\n    ],\n\n    // add recommended configurations\n    extends: [\n      '@stylistic/stylelint-config',\n    ],\n\n    // check inline directives\n    reportDescriptionlessDisables: null,\n    reportInvalidScopeDisables: true,\n    reportNeedlessDisables: true,\n    reportUnscopedDisables: true,\n\n    // reconfigure linter rules\n    rules: {\n\n      // core rules\n      'at-rule-empty-line-before': null,\n      'color-function-notation': ['modern', { ignore: ['with-var-inside'] }],\n      'color-hex-length': null,\n      'comment-empty-line-before': null,\n      'custom-property-empty-line-before': null,\n      'declaration-block-no-redundant-longhand-properties': [true, { ignoreShorthands: ['inset'] }], // Safari does not support 'inset'\n      'declaration-block-single-line-max-declarations': null,\n      'declaration-empty-line-before': null,\n      'function-url-no-scheme-relative': true,\n      'function-url-scheme-allowed-list': ['data'],\n      'media-feature-range-notation': 'prefix', // Safari 16.3 does not work with this notation\n      'no-descending-specificity': null,\n      'no-unknown-animations': true,\n      'rule-empty-line-before': null,\n      'shorthand-property-no-redundant-values': [true, { ignore: ['four-into-three-edge-values'] }],\n\n      // license-header plugin\n      ...(options.license ? { 'plugin/license-header': [true, { license: resolver.path(options.license) }] } : null),\n\n      // stylistic plugin\n      '@stylistic/declaration-colon-newline-after': null,\n      '@stylistic/indentation': [stylistic.indent, { ignore: ['inside-parens'] }],\n      '@stylistic/max-line-length': null,\n      '@stylistic/no-empty-first-line': null,\n      '@stylistic/selector-list-comma-newline-after': null,\n      '@stylistic/string-quotes': (stylistic.quotes === 'off') ? null : [stylistic.quotes, { avoidEscape: true }],\n\n      // custom rules\n      ...rules.base,\n    },\n\n    // overrides for custom languages\n    overrides: [\n\n      // '.scss' files\n      {\n        files: ['**/*.scss'],\n        extends: ['stylelint-config-standard-scss'],\n        rules: rules.scss,\n      },\n\n      // '.less' files\n      {\n        files: ['**/*.less'],\n        extends: ['stylelint-config-standard-less'],\n        rules: rules.less,\n      },\n\n      // '.vue' files (for now, only with SCSS)\n      {\n        files: ['**/*.vue'],\n        extends: ['stylelint-config-standard-scss', 'stylelint-config-standard-vue/scss'],\n        rules: rules.scss,\n      },\n    ],\n  }\n}\n"],"mappings":";;;;;;;;;;;;AA2EA,SAAgB,aAAa,SAAiC;CAE5D,MAAM,cAAwB;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA,GAAI,QAAQ,WAAW,CAAC;CAC1B;CAGA,MAAM,YAA8B;EAClC,QAAQ;EACR,QAAQ;EACR,GAAG,QAAQ;CACb;CAIA,MAAM,QAAiC;EAAE,MAAM,CAAC;EAAG,MAAM,CAAC;EAAG,MAAM,CAAC;CAAE;CACtE,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,GAAG;EAC/D,MAAM,MAAM,KAAK,MAAM,GAAG,CAAC,CAAC;EAC5B,CAAC,MAAM,QAAQ,MAAM,KAAA,CAAM,QAAQ;CACrC;CAGA,MAAM,OAAO;EACX,0CAA0C;EAC1C,+CAA+C;EAC/C,GAAG,MAAM;CACX;CAGA,MAAM,WAAW,IAAI,aAAa,QAAQ,IAAI;CAE9C,OAAO;EAGL;EAGA,SAAS,CACP,mCACA,6BACF;EAGA,SAAS,CACP,6BACF;EAGA,+BAA+B;EAC/B,4BAA4B;EAC5B,wBAAwB;EACxB,wBAAwB;EAGxB,OAAO;GAGL,6BAA6B;GAC7B,2BAA2B,CAAC,UAAU,EAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAC;GACrE,oBAAoB;GACpB,6BAA6B;GAC7B,qCAAqC;GACrC,sDAAsD,CAAC,MAAM,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC;GAC5F,kDAAkD;GAClD,iCAAiC;GACjC,mCAAmC;GACnC,oCAAoC,CAAC,MAAM;GAC3C,gCAAgC;GAChC,6BAA6B;GAC7B,yBAAyB;GACzB,0BAA0B;GAC1B,0CAA0C,CAAC,MAAM,EAAE,QAAQ,CAAC,6BAA6B,EAAE,CAAC;GAG5F,GAAI,QAAQ,UAAU,EAAE,yBAAyB,CAAC,MAAM,EAAE,SAAS,SAAS,KAAK,QAAQ,OAAO,EAAE,CAAC,EAAE,IAAI;GAGzG,8CAA8C;GAC9C,0BAA0B,CAAC,UAAU,QAAQ,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC;GAC1E,8BAA8B;GAC9B,kCAAkC;GAClC,gDAAgD;GAChD,4BAA6B,UAAU,WAAW,QAAS,OAAO,CAAC,UAAU,QAAQ,EAAE,aAAa,KAAK,CAAC;GAG1G,GAAG,MAAM;EACX;EAGA,WAAW;GAGT;IACE,OAAO,CAAC,WAAW;IACnB,SAAS,CAAC,gCAAgC;IAC1C,OAAO,MAAM;GACf;GAGA;IACE,OAAO,CAAC,WAAW;IACnB,SAAS,CAAC,gCAAgC;IAC1C,OAAO,MAAM;GACf;GAGA;IACE,OAAO,CAAC,UAAU;IAClB,SAAS,CAAC,kCAAkC,oCAAoC;IAChF,OAAO,MAAM;GACf;EACF;CACF;AACF"}