feat: init

This commit is contained in:
2026-02-13 22:02:30 +01:00
commit 8f9ff830fb
16711 changed files with 3307340 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
declare function parseArgsStringToArgv(value: string, env?: string, file?: string): string[];
export { parseArgsStringToArgv as default, parseArgsStringToArgv };

View File

@@ -0,0 +1,36 @@
function parseArgsStringToArgv(value, env, file) {
const myRegexp = (
// @ts-expect-error Bypass typescript validation
// biome-ignore lint/complexity/noUselessEscapeInRegex: Bypass validation
/([^\s'"]([^\s'"]*(['"])([^\3]*?)\3)+[^\s'"]*)|[^\s'"]+|(['"])([^\5]*?)\5/gi
);
const myString = value;
const myArray = [];
if (env) {
myArray.push(env);
}
if (file) {
myArray.push(file);
}
let match;
do {
match = myRegexp.exec(myString);
if (match !== null) {
myArray.push(firstString(match[1], match[6], match[0]));
}
} while (match !== null);
return myArray;
}
function firstString(...args) {
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (typeof arg === "string") {
return arg;
}
}
}
export {
parseArgsStringToArgv as default,
parseArgsStringToArgv
};
//# sourceMappingURL=argv.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/stylelint/argv.ts"],"sourcesContent":["// copied from https://github.com/jonschlinkert/is-plain-object/blob/master/is-plain-object.js\n// to make less breaking change, we'll make it a dependency before v1.0.0\n\nexport { parseArgsStringToArgv as default, parseArgsStringToArgv }\nfunction parseArgsStringToArgv(\n value: string,\n env?: string,\n file?: string,\n): string[] {\n // ([^\\s'\"]([^\\s'\"]*(['\"])([^\\3]*?)\\3)+[^\\s'\"]*) Matches nested quotes until the first space outside of quotes\n\n // [^\\s'\"]+ or Match if not a space ' or \"\n\n // (['\"])([^\\5]*?)\\5 or Match \"quoted text\" without quotes\n // `\\3` and `\\5` are a backreference to the quote style (' or \") captured\n const myRegexp =\n // @ts-expect-error Bypass typescript validation\n // biome-ignore lint/complexity/noUselessEscapeInRegex: Bypass validation\n /([^\\s'\"]([^\\s'\"]*(['\"])([^\\3]*?)\\3)+[^\\s'\"]*)|[^\\s'\"]+|(['\"])([^\\5]*?)\\5/gi\n const myString = value\n const myArray: string[] = []\n if (env) {\n myArray.push(env)\n }\n if (file) {\n myArray.push(file)\n }\n let match: RegExpExecArray | null\n do {\n // Each call to exec returns the next regex match as an array\n match = myRegexp.exec(myString)\n if (match !== null) {\n // Index 1 in the array is the captured group if it exists\n // Index 0 is the matched text, which we use if no captured group exists\n myArray.push(firstString(match[1], match[6], match[0])!)\n }\n } while (match !== null)\n\n return myArray\n}\n\n// Accepts any number of arguments, and returns the first one that is a string\n// (even an empty string)\n// @ts-ignore\nfunction firstString(...args: Array<any>): string | undefined {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (typeof arg === 'string') {\n return arg\n }\n }\n}\n"],"mappings":"AAIA,SAAS,sBACP,OACA,KACA,MACU;AAOV,QAAM;AAAA;AAAA;AAAA,IAGJ;AAAA;AACF,QAAM,WAAW;AACjB,QAAM,UAAoB,CAAC;AAC3B,MAAI,KAAK;AACP,YAAQ,KAAK,GAAG;AAAA,EAClB;AACA,MAAI,MAAM;AACR,YAAQ,KAAK,IAAI;AAAA,EACnB;AACA,MAAI;AACJ,KAAG;AAED,YAAQ,SAAS,KAAK,QAAQ;AAC9B,QAAI,UAAU,MAAM;AAGlB,cAAQ,KAAK,YAAY,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE;AAAA,IACzD;AAAA,EACF,SAAS,UAAU;AAEnB,SAAO;AACT;AAKA,SAAS,eAAe,MAAsC;AAE5D,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,OAAO,QAAQ,UAAU;AAC3B,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}

View File

@@ -0,0 +1,18 @@
import { Checker } from '../../Checker.js';
import 'vite';
import '../../types.js';
import 'node:worker_threads';
import 'eslint';
import 'stylelint';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
import '../../worker.js';
declare let createServeAndBuild: any;
declare class StylelintChecker extends Checker<'stylelint'> {
constructor();
init(): void;
}
export { StylelintChecker, createServeAndBuild };

View File

@@ -0,0 +1,161 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parentPort } from "node:worker_threads";
import chokidar from "chokidar";
import stylelint from "stylelint";
import { Checker } from "../../Checker.js";
import { FileDiagnosticManager } from "../../FileDiagnosticManager.js";
import { createIgnore } from "../../glob.js";
import {
composeCheckerSummary,
consoleLog,
diagnosticToConsoleLevel,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
filterLogLevel,
normalizeStylelintDiagnostic,
toClientPayload
} from "../../logger.js";
import { ACTION_TYPES, DiagnosticLevel } from "../../types.js";
import { translateOptions } from "./options.js";
const manager = new FileDiagnosticManager();
let createServeAndBuild;
const __filename = fileURLToPath(import.meta.url);
const createDiagnostic = (pluginConfig) => {
let overlay = true;
let terminal = true;
return {
config: async ({ enableOverlay, enableTerminal }) => {
overlay = enableOverlay;
terminal = enableTerminal;
},
async configureServer({ root }) {
var _a;
if (!pluginConfig.stylelint) return;
const translatedOptions = await translateOptions(
pluginConfig.stylelint.lintCommand
);
const baseConfig = {
cwd: root,
...translatedOptions
};
const logLevel = (() => {
var _a2;
if (typeof pluginConfig.stylelint !== "object") return void 0;
const userLogLevel = (_a2 = pluginConfig.stylelint.dev) == null ? void 0 : _a2.logLevel;
if (!userLogLevel) return void 0;
const map = {
error: DiagnosticLevel.Error,
warning: DiagnosticLevel.Warning
};
return userLogLevel.map((l) => map[l]);
})();
const dispatchDiagnostics = () => {
var _a2;
const diagnostics2 = filterLogLevel(manager.getDiagnostics(), logLevel);
if (terminal) {
for (const d of diagnostics2) {
consoleLog(
diagnosticToTerminalLog(d, "Stylelint"),
diagnosticToConsoleLevel(d)
);
}
const errorCount = diagnostics2.filter(
(d) => d.level === DiagnosticLevel.Error
).length;
const warningCount = diagnostics2.filter(
(d) => d.level === DiagnosticLevel.Warning
).length;
consoleLog(
composeCheckerSummary("Stylelint", errorCount, warningCount),
errorCount ? "error" : warningCount ? "warn" : "info"
);
}
if (overlay) {
(_a2 = parentPort) == null ? void 0 : _a2.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload(
"stylelint",
diagnostics2.map((d) => diagnosticToRuntimeError(d))
)
});
}
};
const handleFileChange = async (filePath, type) => {
const absPath = path.resolve(root, filePath);
if (type === "unlink") {
manager.updateByFileId(absPath, []);
} else if (type === "change") {
const { results: diagnosticsOfChangedFile } = await stylelint.lint({
...baseConfig,
files: filePath
});
const newDiagnostics = diagnosticsOfChangedFile.flatMap(
(d) => normalizeStylelintDiagnostic(d)
);
manager.updateByFileId(absPath, newDiagnostics);
}
dispatchDiagnostics();
};
const { results: diagnostics } = await stylelint.lint({
...baseConfig,
...(_a = pluginConfig.stylelint.dev) == null ? void 0 : _a.overrideConfig
});
manager.initWith(
diagnostics.flatMap((p) => normalizeStylelintDiagnostic(p))
);
dispatchDiagnostics();
let watchTarget = root;
if (pluginConfig.stylelint.watchPath) {
if (Array.isArray(pluginConfig.stylelint.watchPath)) {
watchTarget = pluginConfig.stylelint.watchPath.map(
(p) => path.resolve(root, p)
);
} else {
watchTarget = path.resolve(root, pluginConfig.stylelint.watchPath);
}
}
const watcher = chokidar.watch(watchTarget, {
cwd: root,
ignored: createIgnore(root, translatedOptions.files)
});
watcher.on("change", async (filePath) => {
handleFileChange(filePath, "change");
});
watcher.on("unlink", async (filePath) => {
handleFileChange(filePath, "unlink");
});
}
};
};
class StylelintChecker extends Checker {
constructor() {
super({
name: "stylelint",
absFilePath: __filename,
build: {
buildBin: (pluginConfig) => {
if (pluginConfig.stylelint) {
const { lintCommand } = pluginConfig.stylelint;
return ["stylelint", lintCommand.split(" ").slice(1)];
}
return ["stylelint", [""]];
}
},
createDiagnostic
});
}
init() {
const _createServeAndBuild = super.initMainThread();
createServeAndBuild = _createServeAndBuild;
super.initWorkerThread();
}
}
const stylelintChecker = new StylelintChecker();
stylelintChecker.prepare();
stylelintChecker.init();
export {
StylelintChecker,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
import Stylelint__default from 'stylelint';
declare const translateOptions: (command: string) => Promise<Stylelint__default.LinterOptions>;
export { translateOptions };

View File

@@ -0,0 +1,233 @@
import meow from "meow";
import { parseArgsStringToArgv } from "./argv.js";
const EXIT_CODE_ERROR = 2;
const translateOptions = async (command) => {
const result = meow({
autoHelp: false,
autoVersion: false,
importMeta: import.meta,
help: `
Usage: stylelint [input] [options]
Input: Files(s), glob(s), or nothing to use stdin.
If an input argument is wrapped in quotation marks, it will be passed to
globby for cross-platform glob support. node_modules are always ignored.
You can also pass no input and use stdin, instead.
Options:
--config
Path to a specific configuration file (JSON, YAML, or CommonJS), or the
name of a module in node_modules that points to one. If no --config
argument is provided, stylelint will search for configuration files in
the following places, in this order:
- a stylelint property in package.json
- a .stylelintrc file (with or without filename extension:
.json, .yaml, .yml, and .js are available)
- a stylelint.config.js file exporting a JS object
The search will begin in the working directory and move up the directory
tree until a configuration file is found.
--config-basedir
An absolute path to the directory that relative paths defining "extends"
and "plugins" are *relative to*. Only necessary if these values are
relative paths.
--print-config
Print the configuration for the given path.
--ignore-path, -i
Path to a file containing patterns that describe files to ignore. The
path can be absolute or relative to process.cwd(). By default, stylelint
looks for .stylelintignore in process.cwd().
--ignore-pattern, --ip
Pattern of files to ignore (in addition to those in .stylelintignore)
--fix
Automatically fix problems of certain rules.
--custom-syntax
Module name or path to a JS file exporting a PostCSS-compatible syntax.
--stdin
Accept stdin input even if it is empty.
--stdin-filename
A filename to assign stdin input.
--ignore-disables, --id
Ignore stylelint-disable comments.
--disable-default-ignores, --di
Allow linting of node_modules.
--cache [default: false]
Store the info about processed files in order to only operate on the
changed ones the next time you run stylelint. By default, the cache
is stored in "./.stylelintcache". To adjust this, use --cache-location.
--cache-location [default: '.stylelintcache']
Path to a file or directory to be used for the cache location.
Default is "./.stylelintcache". If a directory is specified, a cache
file will be created inside the specified folder, with a name derived
from a hash of the current working directory.
If the directory for the cache does not exist, make sure you add a trailing "/"
on *nix systems or "\\" on Windows. Otherwise the path will be assumed to be a file.
--formatter, -f [default: "string"]
The output formatter: "compact", "json", "tap", "unix" or "verbose"
--custom-formatter
Path to a JS file exporting a custom formatting function.
--quiet, -q
Only register problems for rules with an "error"-level severity (ignore
"warning"-level).
--color
--no-color
Force enabling/disabling of color.
--report-needless-disables, --rd
Also report errors for stylelint-disable comments that are not blocking a lint warning.
The process will exit with code ${EXIT_CODE_ERROR} if needless disables are found.
--report-invalid-scope-disables, --risd
Report stylelint-disable comments that used for rules that don't exist within the configuration object.
The process will exit with code ${EXIT_CODE_ERROR} if invalid scope disables are found.
--report-descriptionless-disables, --rdd
Report stylelint-disable comments without a description.
The process will exit with code ${EXIT_CODE_ERROR} if descriptionless disables are found.
--max-warnings, --mw
Number of warnings above which the process will exit with code ${EXIT_CODE_ERROR}.
Useful when setting "defaultSeverity" to "warning" and expecting the
process to fail on warnings (e.g. CI build).
--output-file, -o
Path of file to write report.
--version, -v
Show the currently installed version of stylelint.
--allow-empty-input, --aei
When glob pattern matches no files, the process will exit without throwing an error.
`,
flags: {
allowEmptyInput: {
shortFlag: "aei",
type: "boolean"
},
cache: {
type: "boolean"
},
cacheLocation: {
type: "string"
},
cacheStrategy: {
type: "string"
},
color: {
type: "boolean"
},
config: {
type: "string"
},
configBasedir: {
type: "string"
},
customFormatter: {
type: "string"
},
customSyntax: {
type: "string"
},
disableDefaultIgnores: {
shortFlag: "di",
type: "boolean"
},
fix: {
type: "boolean"
},
formatter: {
shortFlag: "f",
default: "string",
type: "string"
},
help: {
shortFlag: "h",
type: "boolean"
},
ignoreDisables: {
shortFlag: "id",
type: "boolean"
},
ignorePath: {
shortFlag: "i",
type: "string",
isMultiple: true
},
ignorePattern: {
shortFlag: "ip",
type: "string",
isMultiple: true
},
maxWarnings: {
shortFlag: "mw",
type: "number"
},
outputFile: {
shortFlag: "o",
type: "string"
},
printConfig: {
type: "boolean"
},
quiet: {
shortFlag: "q",
type: "boolean"
},
reportDescriptionlessDisables: {
shortFlag: "rdd",
type: "boolean"
},
reportInvalidScopeDisables: {
shortFlag: "risd",
type: "boolean"
},
reportNeedlessDisables: {
shortFlag: "rd",
type: "boolean"
},
stdin: {
type: "boolean"
},
stdinFilename: {
type: "string"
},
version: {
shortFlag: "v",
type: "boolean"
},
globbyOptions: {
shortFlag: "go",
type: "string"
}
},
argv: parseArgsStringToArgv(command)
});
const optionsBase = {
...Object.fromEntries(
Object.entries(result.flags).filter(
([key]) => [
"files",
"globbyOptions",
"cache",
"cacheLocation",
"code",
"codeFilename",
"config",
"configFile",
"configBasedir",
"cwd",
"ignoreDisables",
"ignorePath",
"ignorePattern",
"reportDescriptionlessDisables",
"reportNeedlessDisables",
"reportInvalidScopeDisables",
"maxWarnings",
"customSyntax",
"formatter",
"disableDefaultIgnores",
"fix",
"allowEmptyInput",
"quiet"
].includes(key)
)
),
formatter: result.flags.formatter === "string" ? "json" : result.flags.formatter,
files: result.input[1]
};
return optionsBase;
};
export {
translateOptions
};
//# sourceMappingURL=options.js.map

File diff suppressed because one or more lines are too long