@salesforce-ux/slds-linter 0.5.2 → 1.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@ SLDS Linter checks your Aura and Lightning web components' CSS and markup files
8
8
 
9
9
  ## Features
10
10
 
11
- SLDS Linter is a custom-built linting solution based on open source [Stylelint](https://stylelint.io/) and [ESLint](https://eslint.org/) projects. It supports linting for both types of Lightning components.
11
+ SLDS Linter is a custom-built linting solution based on open source [ESLint](https://eslint.org/) with CSS support. It supports linting for both types of Lightning components.
12
12
 
13
13
  SLDS Linter runs on these types of files.
14
14
 
@@ -100,7 +100,6 @@ These options are available on SLDS Linter commands.
100
100
  | `-d, --directory <path>` | Target directory to scan (defaults to current directory). Supports glob patterns. | `lint`, `report` |
101
101
  | `-o, --output <path>` | Output directory for reports (defaults to current directory) | `report` |
102
102
  | `--fix` | Automatically fix problems | `lint` |
103
- | `--config-stylelint <path>` | Path to stylelint config file | `lint`, `report`|
104
103
  | `--config-eslint <path>` | Path to eslint config file | `lint`, `report`|
105
104
  | `--editor <editor>` | Editor to open files with (e.g., vscode, atom, sublime). Auto-detects if not specified | `lint` |
106
105
  | `--format <type>` | Output format (sarif, csv). Defaults to sarif | `report` |
@@ -112,8 +111,7 @@ To view help for these options, add `--help` to each command. For example, run `
112
111
 
113
112
  To enhance your linting and error analysis experience, we recommend that you install these VS Code extensions. These extensions significantly improve your development workflow and make it easier to navigate and address linting issues.
114
113
 
115
- - *[ESLint Extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)*: Essential for JavaScript and TypeScript linting, it checks your code and flags any violations of the ESLint rules with squiggly lines to show you what to fix.
116
- - *[Stylelint Extension](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)*: When linting CSS, SCSS, or other stylesheets, this tool highlights errors with squiggly lines.
114
+ - *[ESLint Extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)*: Essential for JavaScript, TypeScript, HTML, and CSS linting, it checks your code and flags any violations of the ESLint rules with squiggly lines to show you what to fix.
117
115
 
118
116
  ## Best Practices
119
117
 
@@ -3,8 +3,7 @@ import chalk from "chalk";
3
3
  import { Logger } from "../utils/logger.js";
4
4
  import { normalizeCliOptions } from "../utils/config-utils.js";
5
5
  import {
6
- DEFAULT_ESLINT_CONFIG_PATH,
7
- DEFAULT_STYLELINT_CONFIG_PATH
6
+ DEFAULT_ESLINT_CONFIG_PATH
8
7
  } from "../services/config.resolver.js";
9
8
  import path from "path";
10
9
  import { copyFile } from "fs/promises";
@@ -16,17 +15,8 @@ function registerEmitCommand(program) {
16
15
  try {
17
16
  Logger.info(chalk.blue("Emitting configuration files..."));
18
17
  const normalizedOptions = normalizeCliOptions(options, {
19
- configStylelint: DEFAULT_STYLELINT_CONFIG_PATH,
20
18
  configEslint: DEFAULT_ESLINT_CONFIG_PATH
21
19
  });
22
- const destStyleConfigPath = path.join(
23
- normalizedOptions.directory,
24
- "stylelint.config.mjs"
25
- );
26
- await copyFile(normalizedOptions.configStylelint, destStyleConfigPath);
27
- Logger.success(chalk.green(`Stylelint configuration created at:
28
- ${destStyleConfigPath}
29
- `));
30
20
  const destESLintConfigPath = path.join(
31
21
  normalizedOptions.directory,
32
22
  path.basename(normalizedOptions.configEslint)
@@ -4,19 +4,18 @@ import chalk from "chalk";
4
4
  import { printLintResults } from "../utils/lintResultsUtil.js";
5
5
  import { normalizeCliOptions, normalizeDirectoryPath } from "../utils/config-utils.js";
6
6
  import { Logger } from "../utils/logger.js";
7
- import { DEFAULT_ESLINT_CONFIG_PATH, DEFAULT_STYLELINT_CONFIG_PATH } from "../services/config.resolver.js";
7
+ import { DEFAULT_ESLINT_CONFIG_PATH } from "../services/config.resolver.js";
8
8
  import { lint } from "../executor/index.js";
9
9
  function registerLintCommand(program) {
10
10
  program.command("lint").aliases(["lint:styles", "lint:components"]).configureHelp({
11
11
  commandUsage: () => {
12
12
  return `${program.name()} lint [directory] [options]`;
13
13
  }
14
- }).description("Run both style and component linting").argument("[directory]", "Target directory to scan (defaults to current directory). Support glob patterns").addOption(new Option("-d, --directory <path>", "Target directory to scan (defaults to current directory). Support glob patterns").hideHelp()).option("--fix", "Automatically fix problems").option("--config-stylelint <path>", "Path to stylelint config file").option("--config-eslint <path>", "Path to eslint config file").option("--editor <editor>", "Editor to open files with (e.g., vscode, atom, sublime). Auto-detects if not specified").action(async (directory, options) => {
14
+ }).description("Run both style and component linting").argument("[directory]", "Target directory to scan (defaults to current directory). Support glob patterns").addOption(new Option("-d, --directory <path>", "Target directory to scan (defaults to current directory). Support glob patterns").hideHelp()).option("--fix", "Automatically fix problems").option("--config-eslint <path>", "Path to eslint config file").option("--editor <editor>", "Editor to open files with (e.g., vscode, atom, sublime). Auto-detects if not specified").action(async (directory, options) => {
15
15
  const startTime = Date.now();
16
16
  try {
17
17
  Logger.info(chalk.blue("Starting lint process..."));
18
18
  const normalizedOptions = normalizeCliOptions(options, {
19
- configStylelint: DEFAULT_STYLELINT_CONFIG_PATH,
20
19
  configEslint: DEFAULT_ESLINT_CONFIG_PATH
21
20
  });
22
21
  if (directory) {
@@ -6,14 +6,13 @@ import chalk from "chalk";
6
6
  import fs from "fs";
7
7
  import { normalizeAndValidatePath, normalizeCliOptions, normalizeDirectoryPath } from "../utils/config-utils.js";
8
8
  import { Logger } from "../utils/logger.js";
9
- import { DEFAULT_ESLINT_CONFIG_PATH, DEFAULT_STYLELINT_CONFIG_PATH } from "../services/config.resolver.js";
9
+ import { DEFAULT_ESLINT_CONFIG_PATH } from "../services/config.resolver.js";
10
10
  import { report, lint } from "../executor/index.js";
11
11
  function registerReportCommand(program) {
12
- program.command("report").description("Generate report from linting results").argument("[directory]", "Target directory to scan (defaults to current directory). Support glob patterns").addOption(new Option("-d, --directory <path>", "Target directory to scan (defaults to current directory). Support glob patterns").hideHelp()).option("-o, --output <path>", "Output directory for reports (defaults to current directory)").option("--config-stylelint <path>", "Path to stylelint config file").option("--config-eslint <path>", "Path to eslint config file").addOption(new Option("--format <type>", "Output format").choices(["sarif", "csv"]).default("sarif")).action(async (directory, options) => {
12
+ program.command("report").description("Generate report from linting results").argument("[directory]", "Target directory to scan (defaults to current directory). Support glob patterns").addOption(new Option("-d, --directory <path>", "Target directory to scan (defaults to current directory). Support glob patterns").hideHelp()).option("-o, --output <path>", "Output directory for reports (defaults to current directory)").option("--config-eslint <path>", "Path to eslint config file").addOption(new Option("--format <type>", "Output format").choices(["sarif", "csv"]).default("sarif")).action(async (directory, options) => {
13
13
  const spinner = ora("Starting report generation...");
14
14
  try {
15
15
  const normalizedOptions = normalizeCliOptions(options, {
16
- configStylelint: DEFAULT_STYLELINT_CONFIG_PATH,
17
16
  configEslint: DEFAULT_ESLINT_CONFIG_PATH,
18
17
  output: normalizeAndValidatePath(options.output)
19
18
  });
@@ -4,15 +4,14 @@ import { FileScanner } from "../services/file-scanner.js";
4
4
  import { LintRunner } from "../services/lint-runner.js";
5
5
  import { StyleFilePatterns, ComponentFilePatterns } from "../services/file-patterns.js";
6
6
  import { ReportGenerator, CsvReportGenerator } from "../services/report-generator.js";
7
- import { DEFAULT_ESLINT_CONFIG_PATH, DEFAULT_STYLELINT_CONFIG_PATH, LINTER_CLI_VERSION } from "../services/config.resolver.js";
7
+ import { DEFAULT_ESLINT_CONFIG_PATH, LINTER_CLI_VERSION } from "../services/config.resolver.js";
8
8
  import { normalizeCliOptions } from "../utils/config-utils.js";
9
9
  import { Logger } from "../utils/logger.js";
10
10
  async function lint(config) {
11
11
  try {
12
12
  Logger.debug("Starting linting with Node API");
13
13
  const normalizedConfig = normalizeCliOptions(config, {
14
- configEslint: DEFAULT_ESLINT_CONFIG_PATH,
15
- configStylelint: DEFAULT_STYLELINT_CONFIG_PATH
14
+ configEslint: DEFAULT_ESLINT_CONFIG_PATH
16
15
  });
17
16
  const styleFiles = await FileScanner.scanFiles(normalizedConfig.directory, {
18
17
  patterns: StyleFilePatterns,
@@ -22,17 +21,12 @@ async function lint(config) {
22
21
  patterns: ComponentFilePatterns,
23
22
  batchSize: 100
24
23
  });
25
- const { fix, configStylelint, configEslint } = normalizedConfig;
26
- const styleResults = await LintRunner.runLinting(styleFiles, "style", {
27
- fix,
28
- configPath: configStylelint
29
- });
30
- const componentResults = await LintRunner.runLinting(componentFiles, "component", {
24
+ const { fix, configEslint } = normalizedConfig;
25
+ const lintResults = await LintRunner.runLinting([...styleFiles, ...componentFiles], "component", {
31
26
  fix,
32
27
  configPath: configEslint
33
28
  });
34
- const combinedResults = [...styleResults, ...componentResults];
35
- return standardizeLintMessages(combinedResults);
29
+ return standardizeLintMessages(lintResults);
36
30
  } catch (error) {
37
31
  const errorMessage = `Linting failed: ${error.message}`;
38
32
  Logger.error(errorMessage);
@@ -43,7 +37,6 @@ async function report(config, results) {
43
37
  try {
44
38
  Logger.debug("Starting report generation with Node API");
45
39
  const normalizedConfig = normalizeCliOptions(config, {
46
- configStylelint: DEFAULT_STYLELINT_CONFIG_PATH,
47
40
  configEslint: DEFAULT_ESLINT_CONFIG_PATH
48
41
  });
49
42
  const format = normalizedConfig.format || "sarif";
package/build/index.js CHANGED
@@ -19,7 +19,7 @@ process.on("uncaughtException", (error) => {
19
19
  var program = new Command();
20
20
  program.name("npx @salesforce-ux/slds-linter@latest").showHelpAfterError();
21
21
  function registerVersion() {
22
- program.description("SLDS Linter CLI tool for linting styles and components").version("0.5.2");
22
+ program.description("SLDS Linter CLI tool for linting styles and components").version("1.0.0-alpha.0");
23
23
  }
24
24
  registerLintCommand(program);
25
25
  registerReportCommand(program);
@@ -1,6 +1,7 @@
1
1
  export declare const DEFAULT_ESLINT_CONFIG_PATH: string;
2
- export declare const DEFAULT_STYLELINT_CONFIG_PATH: string;
3
- export declare const STYLELINT_VERSION: string;
4
2
  export declare const ESLINT_VERSION: string;
5
3
  export declare const LINTER_CLI_VERSION: string;
4
+ /**
5
+ * Get rule description from metadata
6
+ */
6
7
  export declare const getRuleDescription: (ruleId: string) => string;
@@ -1,20 +1,170 @@
1
1
  // src/services/config.resolver.ts
2
- import { ruleMetadata } from "@salesforce-ux/stylelint-plugin-slds";
3
2
  import { resolvePath } from "../utils/nodeVersionUtil.js";
3
+
4
+ // yaml-file:/Users/ritesh.kumar2/Documents/projects/stylelint-sds/packages/eslint-plugin-slds/src/config/rule-messages.yml
5
+ var rule_messages_default = {
6
+ "no-slds-class-overrides": {
7
+ "description": "Create new custom CSS classes instead of overriding SLDS selectors",
8
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-class-overrides",
9
+ "type": "problem",
10
+ "messages": {
11
+ "sldsClassOverride": "Overriding .{{className}} isn't supported. To differentiate SLDS and custom classes, create a CSS class in your namespace. Examples: myapp-input, myapp-button."
12
+ }
13
+ },
14
+ "no-deprecated-slds-classes": {
15
+ "description": "Please replace the deprecated classes with a modern equivalent",
16
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-slds-classes",
17
+ "type": "problem",
18
+ "messages": {
19
+ "deprecatedClass": "The class {{className}} is deprecated and not available in SLDS2. Please update to a supported class."
20
+ }
21
+ },
22
+ "no-deprecated-tokens-slds1": {
23
+ "description": "Update outdated design tokens to SLDS 2 styling hooks with similar values. For more information, see Styling Hooks on lightningdesignsystem.com.",
24
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-tokens-slds1",
25
+ "type": "problem",
26
+ "messages": {
27
+ "deprecatedToken": "Consider removing {{oldValue}} or replacing it with {{newValue}}. Set the fallback to {{oldValue}}. For more info, see Styling Hooks on lightningdesignsystem.com.",
28
+ "noReplacement": "Update outdated design tokens to SLDS 2 styling hooks with similar values. For more information, see Styling Hooks on lightningdesignsystem.com."
29
+ }
30
+ },
31
+ "enforce-sds-to-slds-hooks": {
32
+ "description": "Convert your existing --sds styling hooks to --slds styling hooks. See lightningdesignsystem.com for more info.",
33
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-sds-to-slds-hooks",
34
+ "type": "problem",
35
+ "messages": {
36
+ "replaceSdsWithSlds": "Replace {{oldValue}} with {{suggestedMatch}} styling hook."
37
+ }
38
+ },
39
+ "enforce-bem-usage": {
40
+ "description": "Replace BEM double-dash syntax in class names with single underscore syntax",
41
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-bem-usage",
42
+ "type": "problem",
43
+ "messages": {
44
+ "bemDoubleDash": "{{actual}} has been retired. Update it to the new name {{newValue}}.",
45
+ "fixBemNaming": "Update to correct BEM naming convention"
46
+ }
47
+ },
48
+ "modal-close-button-issue": {
49
+ "description": "Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint",
50
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#modal-close-button-issue",
51
+ "type": "problem",
52
+ "messages": {
53
+ "modalCloseButtonIssue": "Update component attributes or CSS classes for the modal close button to comply with the modal component blueprint.",
54
+ "removeClass": "Remove the slds-button_icon-inverse class from the modal close button in components that use the SLDS modal blueprint.",
55
+ "changeVariant": "Change the variant attribute value from bare-inverse to bare in <lightning-button-icon> or <lightning-icon>.",
56
+ "removeVariant": "Remove the variant attribute from the <lightning-icon> component inside the <button> element.",
57
+ "ensureButtonClasses": "Add or move slds-button and slds-button_icon to the class attribute of the <button> element or <lightning-button-icon> component.",
58
+ "ensureSizeAttribute": "To size icons properly, set the size attribute \u200Cto large in the <lightning-icon> and <lightning-button-icon> components."
59
+ }
60
+ },
61
+ "no-deprecated-classes-slds2": {
62
+ "description": "Replace classes that aren't available with SLDS 2 classes",
63
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-deprecated-classes-slds2",
64
+ "type": "problem",
65
+ "messages": {
66
+ "deprecatedClass": "The class {{className}} isn't available in SLDS 2. Update it to a class supported in SLDS 2. See lightningdesignsystem.com for more information.",
67
+ "updateToModernClass": "Replace deprecated class with modern equivalent",
68
+ "checkDocumentation": "See lightningdesignsystem.com for SLDS 2 class alternatives"
69
+ }
70
+ },
71
+ "lwc-token-to-slds-hook": {
72
+ "description": "Replace the deprecated --lwc tokens with the latest --slds tokens. See lightningdesignsystem.com for more info.",
73
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#lwc-token-to-slds-hook",
74
+ "type": "problem",
75
+ "messages": {
76
+ "errorWithReplacement": "The '{{oldValue}}' design token is deprecated. Replace it with '{{newValue}}'. For more info, see Global Styling Hooks on lightningdesignsystem.com.",
77
+ "errorWithStyleHooks": "The '{{oldValue}}' design token is deprecated. Replace it with the SLDS 2 '{{newValue}}' styling hook and set the fallback to '{{oldValue}}'. For more info, see Global Styling Hooks on lightningdesignsystem.com.",
78
+ "errorWithNoRecommendation": "The '{{oldValue}}' design token is deprecated. For more info, see the New Global Styling Hook Guidance on lightningdesignsystem.com."
79
+ }
80
+ },
81
+ "no-sldshook-fallback-for-lwctoken": {
82
+ "description": "Avoid using --slds styling hooks as fallback values for --lwc tokens.",
83
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-sldshook-fallback-for-lwctoken",
84
+ "type": "problem",
85
+ "messages": {
86
+ "unsupportedFallback": "Remove the {{sldsToken}} styling hook that is used as a fallback value for {{lwcToken}}."
87
+ }
88
+ },
89
+ "no-unsupported-hooks-slds2": {
90
+ "description": "Identifies styling hooks that aren't present in SLDS 2. They must be replaced with styling hooks that have a similar effect, or they must be removed.",
91
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-unsupported-hooks-slds2",
92
+ "type": "problem",
93
+ "messages": {
94
+ "deprecated": "The {{token}} styling hook isn't present in SLDS 2 and there's no equivalent replacement. Remove it or replace it with a styling hook with a similar effect."
95
+ }
96
+ },
97
+ "no-slds-var-without-fallback": {
98
+ "description": "Add fallback values to SLDS styling hooks. The fallback values are used in Salesforce environments where styling hooks are unavailable.",
99
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-var-without-fallback",
100
+ "type": "problem",
101
+ "messages": {
102
+ "varWithoutFallback": "Your code uses the {{cssVar}} styling hook without a fallback value. Styling hooks are unavailable in some Salesforce environments. To render your component correctly in all environments, add this fallback value: var({{cssVar}}, {{recommendation}}). To make this fallback value brand-aware, use a branded design token instead of a static value. See Design Tokens on v1.lightningdesignsystem.com."
103
+ }
104
+ },
105
+ "no-slds-namespace-for-custom-hooks": {
106
+ "description": "To differentiate custom styling hooks from SLDS styling hooks, create custom styling hooks in your namespace.",
107
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-namespace-for-custom-hooks",
108
+ "type": "problem",
109
+ "messages": {
110
+ "customHookNamespace": "Using the --slds namespace for {{token}} isn't supported. Create the custom styling hook in your namespace. Example: --myapp-{{tokenWithoutNamespace}}"
111
+ }
112
+ },
113
+ "no-slds-private-var": {
114
+ "description": "Some SLDS styling hooks are private and reserved only for internal Salesforce use. Private SLDS styling hooks have prefixes --_slds- and --slds-s-. For more information, look up private CSS in lightningdesignsystem.com.",
115
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-slds-private-var",
116
+ "type": "problem",
117
+ "messages": {
118
+ "privateVar": "This styling hook is reserved for internal Salesforce use. Remove the --_slds- or \u2013slds-s private variable within selector {{prop}}. For more information, look up private CSS in lightningdesignsystem.com."
119
+ }
120
+ },
121
+ "enforce-component-hook-naming-convention": {
122
+ "description": "Replace component styling hooks that use a deprecated naming convention.",
123
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#enforce-component-hook-naming-convention",
124
+ "type": "problem",
125
+ "messages": {
126
+ "replace": "Replace the deprecated {{oldValue}} component styling hook with {{suggestedMatch}}."
127
+ }
128
+ },
129
+ "no-hardcoded-values-slds1": {
130
+ "description": "Replace static values with SLDS 1 design tokens. For more information, look up design tokens on lightningdesignsystem.com.",
131
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-value",
132
+ "type": "suggestion",
133
+ "messages": {
134
+ "hardcodedValue": "Replace the {{oldValue}} static value with an SLDS 1 styling hook: {{newValue}}.",
135
+ "noReplacement": "There's no replacement styling hook for the {{oldValue}} static value. Remove the static value."
136
+ }
137
+ },
138
+ "no-hardcoded-values-slds2": {
139
+ "description": "Replace static values with SLDS 2 styling hooks. For more information, look up design tokens on lightningdesignsystem.com.",
140
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#no-hardcoded-value",
141
+ "type": "suggestion",
142
+ "messages": {
143
+ "hardcodedValue": "Consider replacing the {{oldValue}} static value with an SLDS 2 styling hook that has a similar value: {{newValue}}.",
144
+ "noReplacement": "There's no replacement styling hook for the {{oldValue}} static value. Remove the static value."
145
+ }
146
+ },
147
+ "reduce-annotations": {
148
+ "description": "Remove your annotations and update your code.",
149
+ "url": "https://developer.salesforce.com/docs/platform/slds-linter/guide/reference-rules.html#reduce-annotations",
150
+ "type": "problem",
151
+ "messages": {
152
+ "removeAnnotation": "Remove this annotation and update the code to SLDS best practices. For help, file an issue at https://github.com/salesforce-ux/slds-linter/"
153
+ }
154
+ }
155
+ };
156
+
157
+ // src/services/config.resolver.ts
4
158
  var DEFAULT_ESLINT_CONFIG_PATH = resolvePath("@salesforce-ux/eslint-plugin-slds/config", import.meta);
5
- var DEFAULT_STYLELINT_CONFIG_PATH = resolvePath("@salesforce-ux/stylelint-plugin-slds/.stylelintrc.mjs", import.meta);
6
- var STYLELINT_VERSION = "16.14.1";
7
- var ESLINT_VERSION = "9.30.1";
8
- var LINTER_CLI_VERSION = "0.5.2";
159
+ var ESLINT_VERSION = "9.35.0";
160
+ var LINTER_CLI_VERSION = "1.0.0-alpha.0";
9
161
  var getRuleDescription = (ruleId) => {
10
- const ruleIdWithoutNameSpace = `${ruleId}`.replace(/\@salesforce-ux\//, "");
11
- return ruleMetadata(ruleIdWithoutNameSpace)?.ruleDesc || "--";
162
+ const ruleIdWithoutNameSpace = `${ruleId}`.replace(/\@salesforce-ux\//, "").replace(/^slds\//, "");
163
+ return rule_messages_default[ruleIdWithoutNameSpace]?.description || "--";
12
164
  };
13
165
  export {
14
166
  DEFAULT_ESLINT_CONFIG_PATH,
15
- DEFAULT_STYLELINT_CONFIG_PATH,
16
167
  ESLINT_VERSION,
17
168
  LINTER_CLI_VERSION,
18
- STYLELINT_VERSION,
19
169
  getRuleDescription
20
170
  };
@@ -5,6 +5,7 @@ export interface FilePattern {
5
5
  export interface ScanOptions {
6
6
  patterns: FilePattern;
7
7
  batchSize?: number;
8
+ gitignore?: boolean;
8
9
  }
9
10
  export declare class FileScanner {
10
11
  private static DEFAULT_BATCH_SIZE;
@@ -1,8 +1,9 @@
1
1
  // src/services/file-scanner.ts
2
2
  import { promises as fs } from "fs";
3
3
  import { Logger } from "../utils/logger.js";
4
- import { globby } from "globby";
4
+ import { globby, isDynamicPattern } from "globby";
5
5
  import { extname } from "path";
6
+ import path from "path";
6
7
  var FileScanner = class {
7
8
  static DEFAULT_BATCH_SIZE = 100;
8
9
  /**
@@ -14,16 +15,43 @@ var FileScanner = class {
14
15
  static async scanFiles(directory, options) {
15
16
  try {
16
17
  Logger.debug(`Scanning directory: ${directory}`);
17
- const allFiles = await globby(directory, {
18
- cwd: process.cwd(),
19
- expandDirectories: true,
18
+ const normalizedPath = directory.replace(/\\/g, "/");
19
+ let workingDirectory;
20
+ let globPattern;
21
+ if (!isDynamicPattern(normalizedPath)) {
22
+ const hasExtension = path.extname(normalizedPath) !== "";
23
+ if (hasExtension) {
24
+ const directory2 = path.dirname(normalizedPath);
25
+ workingDirectory = path.isAbsolute(directory2) ? directory2 : path.join(process.cwd(), directory2);
26
+ globPattern = path.basename(normalizedPath);
27
+ } else {
28
+ workingDirectory = path.isAbsolute(normalizedPath) ? normalizedPath : path.join(process.cwd(), normalizedPath);
29
+ const extensions = options.patterns.extensions.join(",");
30
+ globPattern = `**/*.{${extensions}}`;
31
+ }
32
+ } else {
33
+ const firstGlobIndex = normalizedPath.search(/[*?{}[\]!+@()]/);
34
+ const lastDirectoryIndex = normalizedPath.substring(0, firstGlobIndex).lastIndexOf("/");
35
+ if (lastDirectoryIndex === -1) {
36
+ workingDirectory = process.cwd();
37
+ globPattern = normalizedPath;
38
+ } else {
39
+ const basePath = normalizedPath.substring(0, lastDirectoryIndex);
40
+ workingDirectory = path.isAbsolute(basePath) ? basePath : path.join(process.cwd(), basePath);
41
+ globPattern = normalizedPath.substring(lastDirectoryIndex + 1);
42
+ }
43
+ }
44
+ const allFiles = await globby(globPattern, {
45
+ cwd: workingDirectory,
46
+ expandDirectories: false,
47
+ // Disable for optimum performance - avoid unintended file discovery
20
48
  unique: true,
21
49
  ignore: options.patterns.exclude,
22
50
  onlyFiles: true,
23
51
  dot: true,
24
52
  // Include.dot files
25
53
  absolute: true,
26
- gitignore: true
54
+ gitignore: options.gitignore !== false
27
55
  }).then((matches) => matches.filter((match) => {
28
56
  const fileExt = extname(match).substring(1);
29
57
  return options.patterns.extensions.includes(fileExt);
@@ -3,7 +3,7 @@ export declare class LintRunner {
3
3
  /**
4
4
  * Run linting on batches of files
5
5
  */
6
- static runLinting(fileBatches: string[][], workerType: 'style' | 'component', options?: LintRunnerOptions): Promise<LintResult[]>;
6
+ static runLinting(fileBatches: string[][], workerType: 'component', options?: LintRunnerOptions): Promise<LintResult[]>;
7
7
  /**
8
8
  * Process and normalize worker results
9
9
  */
@@ -12,7 +12,7 @@ var LintRunner = class {
12
12
  const workerScript = path.resolve(
13
13
  resolveDirName(import.meta),
14
14
  "../workers",
15
- workerType === "style" ? "stylelint.worker.js" : "eslint.worker.js"
15
+ "eslint.worker.js"
16
16
  );
17
17
  const workerConfig = {
18
18
  configPath: options.configPath,
@@ -1,7 +1,6 @@
1
1
  export interface BaseConfig {
2
2
  directory?: string;
3
3
  files?: string[];
4
- configStylelint?: string;
5
4
  configEslint?: string;
6
5
  }
7
6
  /**
File without changes
@@ -35,7 +35,6 @@ function normalizeDirectoryPath(directory) {
35
35
  function normalizeCliOptions(options, defaultOptions = {}) {
36
36
  const baseDefaults = {
37
37
  files: [],
38
- configStylelint: "",
39
38
  configEslint: "",
40
39
  fix: false,
41
40
  editor: detectCurrentEditor(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce-ux/slds-linter",
3
- "version": "0.5.2",
3
+ "version": "1.0.0-alpha.0",
4
4
  "description": "SLDS Linter CLI tool for linting styles and components",
5
5
  "keywords": [
6
6
  "lightning design system linter",
@@ -29,8 +29,7 @@
29
29
  ],
30
30
  "bin": "build/index.js",
31
31
  "dependencies": {
32
- "@salesforce-ux/eslint-plugin-slds": "0.5.2",
33
- "@salesforce-ux/stylelint-plugin-slds": "0.5.2",
32
+ "@salesforce-ux/eslint-plugin-slds": "1.0.0-alpha.0",
34
33
  "@typescript-eslint/eslint-plugin": "^8.36.0",
35
34
  "@typescript-eslint/parser": "^8.36.0",
36
35
  "chalk": "^4.1.2",
@@ -42,8 +41,7 @@
42
41
  "json-stream-stringify": "^3.1.6",
43
42
  "node-sarif-builder": "^3.2.0",
44
43
  "ora": "^5.4.1",
45
- "semver": "^7.7.1",
46
- "stylelint": "16.14.1"
44
+ "semver": "^7.7.1"
47
45
  },
48
46
  "engines": {
49
47
  "node": ">=18.18.0"
@@ -1 +0,0 @@
1
- export {};
@@ -1,40 +0,0 @@
1
- // src/workers/stylelint.worker.ts
2
- import stylelint from "stylelint";
3
- import { BaseWorker } from "./base.worker.js";
4
- var StylelintWorker = class extends BaseWorker {
5
- async processFile(filePath) {
6
- try {
7
- const options = {
8
- files: filePath,
9
- fix: this.task.config.fix
10
- };
11
- if (this.task.config.configPath) {
12
- options.configFile = this.task.config.configPath;
13
- }
14
- const result = await stylelint.lint(options);
15
- const fileResult = result.results[0];
16
- return {
17
- file: filePath,
18
- warnings: fileResult.warnings.map((warning) => ({
19
- line: warning.line,
20
- column: warning.column,
21
- endColumn: warning.endColumn,
22
- message: warning.text,
23
- ruleId: warning.rule
24
- })).sort((a, b) => a.line - b.line),
25
- errors: []
26
- // Stylelint doesn't differentiate between warnings and errors
27
- };
28
- } catch (error) {
29
- return {
30
- file: filePath,
31
- error: error.message
32
- };
33
- }
34
- }
35
- };
36
- var worker = new StylelintWorker();
37
- worker.process().catch((error) => {
38
- console.error("Worker failed:", error);
39
- process.exit(1);
40
- });