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,22 @@
import { NormalizedDiagnostic } from '../../logger.js';
import { DiagnosticLevel } from '../../types.js';
import '@babel/code-frame';
import 'eslint';
import 'stylelint';
import 'typescript';
import 'vscode-languageclient/node';
import 'node:worker_threads';
import 'vite';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
declare const severityMap: {
readonly error: DiagnosticLevel.Error;
readonly warning: DiagnosticLevel.Warning;
readonly info: DiagnosticLevel.Suggestion;
};
declare function getBiomeCommand(command: string, flags: string, files: string): string;
declare function runBiome(command: string, cwd: string): Promise<NormalizedDiagnostic[]>;
export { getBiomeCommand, runBiome, severityMap };

View File

@@ -0,0 +1,87 @@
import { exec } from "node:child_process";
import path from "node:path";
import { stripVTControlCharacters as strip } from "node:util";
import { createFrame } from "../../codeFrame.js";
import { DiagnosticLevel } from "../../types.js";
const severityMap = {
error: DiagnosticLevel.Error,
warning: DiagnosticLevel.Warning,
info: DiagnosticLevel.Suggestion
};
function getBiomeCommand(command, flags, files) {
const defaultFlags = "--reporter json";
if (flags.includes("--flags")) {
throw Error(
`vite-plugin-checker will force append "--reporter json" to the flags in dev mode, please don't use "--flags" in "config.biome.flags".
If you need to customize "--flags" in build mode, please use "config.biome.build.flags" instead.`
);
}
return ["biome", command, flags, defaultFlags, files].filter(Boolean).join(" ");
}
function runBiome(command, cwd) {
return new Promise((resolve, _reject) => {
exec(
command,
{
cwd,
maxBuffer: Number.POSITIVE_INFINITY
},
(_error, stdout, _stderr) => {
resolve([...parseBiomeOutput(stdout, cwd)]);
}
);
});
}
function parseBiomeOutput(output, cwd) {
let parsed;
try {
parsed = JSON.parse(output);
} catch {
return [];
}
const diagnostics = parsed.diagnostics.map((d) => {
var _a, _b, _c;
let file = (_a = d.location.path) == null ? void 0 : _a.file;
if (file) {
file = path.isAbsolute(file) ? file : path.resolve(cwd, file);
file = path.normalize(file);
}
const loc = {
file: file || "",
start: getLineAndColumn(d.location.sourceCode, (_b = d.location.span) == null ? void 0 : _b[0]),
end: getLineAndColumn(d.location.sourceCode, (_c = d.location.span) == null ? void 0 : _c[1])
};
const codeFrame = createFrame(d.location.sourceCode || "", loc);
return {
message: `[${d.category}] ${d.description}`,
conclusion: "",
level: severityMap[d.severity] ?? DiagnosticLevel.Error,
checker: "Biome",
id: file,
codeFrame,
stripedCodeFrame: codeFrame && strip(codeFrame),
loc
};
});
return diagnostics;
}
function getLineAndColumn(text, offset) {
if (!text || !offset) return { line: 0, column: 0 };
let line = 1;
let column = 1;
for (let i = 0; i < offset; i++) {
if (text[i] === "\n") {
line++;
column = 1;
} else {
column++;
}
}
return { line, column };
}
export {
getBiomeCommand,
runBiome,
severityMap
};
//# sourceMappingURL=cli.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/biome/cli.ts"],"sourcesContent":["import { exec } from 'node:child_process'\nimport path from 'node:path'\nimport { stripVTControlCharacters as strip } from 'node:util'\nimport { createFrame } from '../../codeFrame.js'\nimport type { NormalizedDiagnostic } from '../../logger.js'\nimport { DiagnosticLevel } from '../../types.js'\nimport type { BiomeOutput } from './types.js'\n\nexport const severityMap = {\n error: DiagnosticLevel.Error,\n warning: DiagnosticLevel.Warning,\n info: DiagnosticLevel.Suggestion,\n} as const\n\nexport function getBiomeCommand(command: string, flags: string, files: string) {\n const defaultFlags = '--reporter json'\n if (flags.includes('--flags')) {\n throw Error(\n `vite-plugin-checker will force append \"--reporter json\" to the flags in dev mode, please don't use \"--flags\" in \"config.biome.flags\".\nIf you need to customize \"--flags\" in build mode, please use \"config.biome.build.flags\" instead.`,\n )\n }\n return ['biome', command, flags, defaultFlags, files]\n .filter(Boolean)\n .join(' ')\n}\n\nexport function runBiome(command: string, cwd: string) {\n return new Promise<NormalizedDiagnostic[]>((resolve, _reject) => {\n exec(\n command,\n {\n cwd,\n maxBuffer: Number.POSITIVE_INFINITY,\n },\n (_error, stdout, _stderr) => {\n resolve([...parseBiomeOutput(stdout, cwd)])\n },\n )\n })\n}\n\nfunction parseBiomeOutput(output: string, cwd: string) {\n let parsed: BiomeOutput\n try {\n parsed = JSON.parse(output)\n } catch {\n return []\n }\n\n const diagnostics: NormalizedDiagnostic[] = parsed.diagnostics.map((d) => {\n let file = d.location.path?.file\n if (file) {\n // Convert relative path to absolute path\n file = path.isAbsolute(file) ? file : path.resolve(cwd, file)\n file = path.normalize(file)\n }\n\n const loc = {\n file: file || '',\n start: getLineAndColumn(d.location.sourceCode, d.location.span?.[0]),\n end: getLineAndColumn(d.location.sourceCode, d.location.span?.[1]),\n }\n\n const codeFrame = createFrame(d.location.sourceCode || '', loc)\n\n return {\n message: `[${d.category}] ${d.description}`,\n conclusion: '',\n level:\n severityMap[d.severity as keyof typeof severityMap] ??\n DiagnosticLevel.Error,\n checker: 'Biome',\n id: file,\n codeFrame,\n stripedCodeFrame: codeFrame && strip(codeFrame),\n loc,\n }\n })\n\n return diagnostics\n}\n\nfunction getLineAndColumn(text?: string, offset?: number) {\n if (!text || !offset) return { line: 0, column: 0 }\n\n let line = 1\n let column = 1\n\n for (let i = 0; i < offset; i++) {\n if (text[i] === '\\n') {\n line++\n column = 1\n } else {\n column++\n }\n }\n\n return { line, column }\n}\n"],"mappings":"AAAA,SAAS,YAAY;AACrB,OAAO,UAAU;AACjB,SAAS,4BAA4B,aAAa;AAClD,SAAS,mBAAmB;AAE5B,SAAS,uBAAuB;AAGzB,MAAM,cAAc;AAAA,EACzB,OAAO,gBAAgB;AAAA,EACvB,SAAS,gBAAgB;AAAA,EACzB,MAAM,gBAAgB;AACxB;AAEO,SAAS,gBAAgB,SAAiB,OAAe,OAAe;AAC7E,QAAM,eAAe;AACrB,MAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,UAAM;AAAA,MACJ;AAAA;AAAA,IAEF;AAAA,EACF;AACA,SAAO,CAAC,SAAS,SAAS,OAAO,cAAc,KAAK,EACjD,OAAO,OAAO,EACd,KAAK,GAAG;AACb;AAEO,SAAS,SAAS,SAAiB,KAAa;AACrD,SAAO,IAAI,QAAgC,CAAC,SAAS,YAAY;AAC/D;AAAA,MACE;AAAA,MACA;AAAA,QACE;AAAA,QACA,WAAW,OAAO;AAAA,MACpB;AAAA,MACA,CAAC,QAAQ,QAAQ,YAAY;AAC3B,gBAAQ,CAAC,GAAG,iBAAiB,QAAQ,GAAG,CAAC,CAAC;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,iBAAiB,QAAgB,KAAa;AACrD,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,MAAM;AAAA,EAC5B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,cAAsC,OAAO,YAAY,IAAI,CAAC,MAAM;AAlD5E;AAmDI,QAAI,QAAO,OAAE,SAAS,SAAX,mBAAiB;AAC5B,QAAI,MAAM;AAER,aAAO,KAAK,WAAW,IAAI,IAAI,OAAO,KAAK,QAAQ,KAAK,IAAI;AAC5D,aAAO,KAAK,UAAU,IAAI;AAAA,IAC5B;AAEA,UAAM,MAAM;AAAA,MACV,MAAM,QAAQ;AAAA,MACd,OAAO,iBAAiB,EAAE,SAAS,aAAY,OAAE,SAAS,SAAX,mBAAkB,EAAE;AAAA,MACnE,KAAK,iBAAiB,EAAE,SAAS,aAAY,OAAE,SAAS,SAAX,mBAAkB,EAAE;AAAA,IACnE;AAEA,UAAM,YAAY,YAAY,EAAE,SAAS,cAAc,IAAI,GAAG;AAE9D,WAAO;AAAA,MACL,SAAS,IAAI,EAAE,QAAQ,KAAK,EAAE,WAAW;AAAA,MACzC,YAAY;AAAA,MACZ,OACE,YAAY,EAAE,QAAoC,KAClD,gBAAgB;AAAA,MAClB,SAAS;AAAA,MACT,IAAI;AAAA,MACJ;AAAA,MACA,kBAAkB,aAAa,MAAM,SAAS;AAAA,MAC9C;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAe,QAAiB;AACxD,MAAI,CAAC,QAAQ,CAAC,OAAQ,QAAO,EAAE,MAAM,GAAG,QAAQ,EAAE;AAElD,MAAI,OAAO;AACX,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,QAAI,KAAK,CAAC,MAAM,MAAM;AACpB;AACA,eAAS;AAAA,IACX,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,OAAO;AACxB;","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 BiomeChecker extends Checker<'biome'> {
constructor();
init(): void;
}
export { BiomeChecker, createServeAndBuild };

View File

@@ -0,0 +1,153 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parentPort } from "node:worker_threads";
import chokidar from "chokidar";
import { Checker } from "../../Checker.js";
import { FileDiagnosticManager } from "../../FileDiagnosticManager.js";
import {
composeCheckerSummary,
consoleLog,
diagnosticToConsoleLevel,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
filterLogLevel,
toClientPayload
} from "../../logger.js";
import {
ACTION_TYPES,
DiagnosticLevel
} from "../../types.js";
import { getBiomeCommand, runBiome, severityMap } from "./cli.js";
const __filename = fileURLToPath(import.meta.url);
const manager = new FileDiagnosticManager();
let createServeAndBuild;
const createDiagnostic = (pluginConfig) => {
var _a, _b;
const biomeConfig = pluginConfig.biome;
let overlay = true;
let terminal = true;
let command = "lint";
let flags = "";
if (typeof biomeConfig === "object") {
command = ((_a = biomeConfig == null ? void 0 : biomeConfig.dev) == null ? void 0 : _a.command) || (biomeConfig == null ? void 0 : biomeConfig.command) || "lint";
flags = ((_b = biomeConfig == null ? void 0 : biomeConfig.dev) == null ? void 0 : _b.flags) || (biomeConfig == null ? void 0 : biomeConfig.flags) || "";
}
return {
config: async ({ enableOverlay, enableTerminal }) => {
overlay = enableOverlay;
terminal = enableTerminal;
},
async configureServer({ root }) {
if (!biomeConfig) return;
const logLevel = (() => {
var _a2;
if (typeof biomeConfig !== "object") return void 0;
const userLogLevel = (_a2 = biomeConfig.dev) == null ? void 0 : _a2.logLevel;
if (!userLogLevel) return void 0;
return userLogLevel.map((l) => severityMap[l]);
})();
const dispatchDiagnostics = () => {
var _a2;
const diagnostics2 = filterLogLevel(manager.getDiagnostics(), logLevel);
if (terminal) {
for (const d of diagnostics2) {
consoleLog(
diagnosticToTerminalLog(d, "Biome"),
diagnosticToConsoleLevel(d)
);
}
const errorCount = diagnostics2.filter(
(d) => d.level === DiagnosticLevel.Error
).length;
const warningCount = diagnostics2.filter(
(d) => d.level === DiagnosticLevel.Warning
).length;
consoleLog(
composeCheckerSummary("Biome", errorCount, warningCount),
errorCount ? "error" : warningCount ? "warn" : "info"
);
}
if (overlay) {
(_a2 = parentPort) == null ? void 0 : _a2.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload(
"biome",
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 isConfigFile = path.basename(absPath) === "biome.json";
if (isConfigFile) {
const runCommand2 = getBiomeCommand(command, flags, root);
const diagnostics2 = await runBiome(runCommand2, root);
manager.initWith(diagnostics2);
} else {
const runCommand2 = getBiomeCommand(command, flags, absPath);
const diagnosticsOfChangedFile = await runBiome(runCommand2, root);
manager.updateByFileId(absPath, diagnosticsOfChangedFile);
}
}
dispatchDiagnostics();
};
const runCommand = getBiomeCommand(command, flags, root);
const diagnostics = await runBiome(runCommand, root);
manager.initWith(diagnostics);
dispatchDiagnostics();
let watchTarget = root;
if (typeof biomeConfig === "object" && biomeConfig.watchPath) {
if (Array.isArray(biomeConfig.watchPath)) {
watchTarget = biomeConfig.watchPath.map((p) => path.resolve(root, p));
} else {
watchTarget = path.resolve(root, biomeConfig.watchPath);
}
}
const watcher = chokidar.watch(watchTarget, {
cwd: root,
ignored: (path2) => path2.includes("node_modules")
});
watcher.on("change", async (filePath) => {
handleFileChange(filePath, "change");
});
watcher.on("unlink", async (filePath) => {
handleFileChange(filePath, "unlink");
});
}
};
};
class BiomeChecker extends Checker {
constructor() {
super({
name: "biome",
absFilePath: __filename,
build: {
buildBin: (pluginConfig) => {
if (typeof pluginConfig.biome === "object") {
const { command, flags } = pluginConfig.biome;
return ["biome", [command || "check", flags || ""]];
}
return ["biome", ["check"]];
}
},
createDiagnostic
});
}
init() {
const _createServeAndBuild = super.initMainThread();
createServeAndBuild = _createServeAndBuild;
super.initWorkerThread();
}
}
const biomeChecker = new BiomeChecker();
biomeChecker.prepare();
biomeChecker.init();
export {
BiomeChecker,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}

View File

@@ -0,0 +1,28 @@
declare function translateOptions({ cache, cacheFile, cacheLocation, cacheStrategy, config, env, errorOnUnmatchedPattern, eslintrc, ext, fix, fixDryRun, fixType, global, ignore, ignorePath, ignorePattern, inlineConfig, parser, parserOptions, plugin, quiet, reportUnusedDisableDirectives, resolvePluginsRelativeTo, rule, rulesdir, }: any): {
allowInlineConfig: any;
cache: any;
cacheLocation: any;
cacheStrategy: any;
errorOnUnmatchedPattern: any;
extensions: any;
fix: any;
fixTypes: any;
ignore: any;
ignorePath: any;
overrideConfig: {
env: any;
globals: any;
ignorePatterns: any;
parser: any;
parserOptions: any;
plugins: any;
rules: any;
};
overrideConfigFile: any;
reportUnusedDisableDirectives: string | undefined;
resolvePluginsRelativeTo: any;
rulePaths: any;
useEslintrc: any;
};
export { translateOptions };

View File

@@ -0,0 +1,75 @@
function quietFixPredicate(message) {
return message.severity === 2;
}
function translateOptions({
cache,
cacheFile,
cacheLocation,
cacheStrategy,
config,
env,
errorOnUnmatchedPattern,
eslintrc,
ext,
fix,
fixDryRun,
fixType,
global,
ignore,
ignorePath,
ignorePattern,
inlineConfig,
parser,
parserOptions,
plugin,
quiet,
reportUnusedDisableDirectives,
resolvePluginsRelativeTo,
rule,
rulesdir
}) {
return {
allowInlineConfig: inlineConfig,
cache,
cacheLocation: cacheLocation || cacheFile,
cacheStrategy,
errorOnUnmatchedPattern,
extensions: ext,
fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true),
fixTypes: fixType,
ignore,
ignorePath,
overrideConfig: {
env: (
// @ts-expect-error
env == null ? void 0 : env.reduce((obj, name) => {
obj[name] = true;
return obj;
}, {})
),
// @ts-expect-error
globals: global == null ? void 0 : global.reduce((obj, name) => {
if (name.endsWith(":true")) {
obj[name.slice(0, -5)] = "writable";
} else {
obj[name] = "readonly";
}
return obj;
}, {}),
ignorePatterns: ignorePattern,
parser,
parserOptions,
plugins: plugin,
rules: rule
},
overrideConfigFile: config,
reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0,
resolvePluginsRelativeTo,
rulePaths: rulesdir,
useEslintrc: eslintrc
};
}
export {
translateOptions
};
//# sourceMappingURL=cli.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/eslint/cli.ts"],"sourcesContent":["/* eslint-disable */\n\n/**\n * This file is directly copied from https://github.com/eslint/eslint/blob/6f940c3ce715327f282c197d0f71b91848e5d83d/lib/cli.js\n *\n * Usually, developer rarely use JS programming API to run ESLint. So we let\n * developers to write their own ESLint commands just like in CI or lint-staged.\n * And the config will be translated and pass to `new ESLint(translatedOptions)`.\n * So in build mode, it's the same as the command you pass in.\n * In dev mode, some flag will be ignored (such as `max-warnings`) because it\n * will be only respected in ESLint CLI.\n */\n\n// @ts-expect-error\nfunction quietFixPredicate(message) {\n return message.severity === 2\n}\n\nexport function translateOptions({\n cache,\n cacheFile,\n cacheLocation,\n cacheStrategy,\n config,\n env,\n errorOnUnmatchedPattern,\n eslintrc,\n ext,\n fix,\n fixDryRun,\n fixType,\n global,\n ignore,\n ignorePath,\n ignorePattern,\n inlineConfig,\n parser,\n parserOptions,\n plugin,\n quiet,\n reportUnusedDisableDirectives,\n resolvePluginsRelativeTo,\n rule,\n rulesdir,\n}: any) {\n return {\n allowInlineConfig: inlineConfig,\n cache,\n cacheLocation: cacheLocation || cacheFile,\n cacheStrategy,\n errorOnUnmatchedPattern,\n extensions: ext,\n fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true),\n fixTypes: fixType,\n ignore,\n ignorePath,\n overrideConfig: {\n env:\n // @ts-expect-error\n env?.reduce((obj, name) => {\n obj[name] = true\n return obj\n }, {}),\n // @ts-expect-error\n globals: global?.reduce((obj, name) => {\n if (name.endsWith(':true')) {\n obj[name.slice(0, -5)] = 'writable'\n } else {\n obj[name] = 'readonly'\n }\n return obj\n }, {}),\n ignorePatterns: ignorePattern,\n parser,\n parserOptions,\n plugins: plugin,\n rules: rule,\n },\n overrideConfigFile: config,\n reportUnusedDisableDirectives: reportUnusedDisableDirectives\n ? 'error'\n : void 0,\n resolvePluginsRelativeTo,\n rulePaths: rulesdir,\n useEslintrc: eslintrc,\n }\n}\n"],"mappings":"AAcA,SAAS,kBAAkB,SAAS;AAClC,SAAO,QAAQ,aAAa;AAC9B;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAQ;AACN,SAAO;AAAA,IACL,mBAAmB;AAAA,IACnB;AAAA,IACA,eAAe,iBAAiB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,MAAM,OAAO,eAAe,QAAQ,oBAAoB;AAAA,IACxD,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,MACd;AAAA;AAAA,QAEE,2BAAK,OAAO,CAAC,KAAK,SAAS;AACzB,cAAI,IAAI,IAAI;AACZ,iBAAO;AAAA,QACT,GAAG,CAAC;AAAA;AAAA;AAAA,MAEN,SAAS,iCAAQ,OAAO,CAAC,KAAK,SAAS;AACrC,YAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,cAAI,KAAK,MAAM,GAAG,EAAE,CAAC,IAAI;AAAA,QAC3B,OAAO;AACL,cAAI,IAAI,IAAI;AAAA,QACd;AACA,eAAO;AAAA,MACT,GAAG,CAAC;AAAA,MACJ,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,IACA,oBAAoB;AAAA,IACpB,+BAA+B,gCAC3B,UACA;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,aAAa;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 EslintChecker extends Checker<'eslint'> {
constructor();
init(): void;
}
export { EslintChecker, createServeAndBuild };

View File

@@ -0,0 +1,186 @@
import Module from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parentPort } from "node:worker_threads";
import chokidar from "chokidar";
import { ESLint } from "eslint";
import invariant from "tiny-invariant";
import { Checker } from "../../Checker.js";
import { FileDiagnosticManager } from "../../FileDiagnosticManager.js";
import { createIgnore } from "../../glob.js";
import {
composeCheckerSummary,
consoleLog,
diagnosticToConsoleLevel,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
filterLogLevel,
normalizeEslintDiagnostic,
toClientPayload
} from "../../logger.js";
import { ACTION_TYPES, DiagnosticLevel } from "../../types.js";
import { translateOptions } from "./cli.js";
import { options as optionator } from "./options.js";
const __filename = fileURLToPath(import.meta.url);
const require2 = Module.createRequire(import.meta.url);
const manager = new FileDiagnosticManager();
let createServeAndBuild;
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.eslint) return;
const options = optionator.parse(pluginConfig.eslint.lintCommand);
invariant(
!options.fix,
"Using `--fix` in `config.eslint.lintCommand` is not allowed in vite-plugin-checker, you could using `--fix` with editor."
);
const translatedOptions = translateOptions(options);
const logLevel = (() => {
var _a2;
if (typeof pluginConfig.eslint !== "object") return void 0;
const userLogLevel = (_a2 = pluginConfig.eslint.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 eslintOptions = {
cwd: root,
...translatedOptions,
...(_a = pluginConfig.eslint.dev) == null ? void 0 : _a.overrideConfig
};
let eslint;
if (pluginConfig.eslint.useFlatConfig) {
const {
FlatESLint,
shouldUseFlatConfig
} = require2("eslint/use-at-your-own-risk");
if (shouldUseFlatConfig == null ? void 0 : shouldUseFlatConfig()) {
eslint = new FlatESLint({
cwd: root
});
} else {
throw Error(
"Please upgrade your eslint to latest version to use `useFlatConfig` option."
);
}
} else {
eslint = new ESLint(eslintOptions);
}
const dispatchDiagnostics = () => {
var _a2;
const diagnostics2 = filterLogLevel(manager.getDiagnostics(), logLevel);
if (terminal) {
for (const d of diagnostics2) {
consoleLog(
diagnosticToTerminalLog(d, "ESLint"),
diagnosticToConsoleLevel(d)
);
}
const errorCount = diagnostics2.filter(
(d) => d.level === DiagnosticLevel.Error
).length;
const warningCount = diagnostics2.filter(
(d) => d.level === DiagnosticLevel.Warning
).length;
consoleLog(
composeCheckerSummary("ESLint", errorCount, warningCount),
errorCount ? "error" : warningCount ? "warn" : "info"
);
}
if (overlay) {
(_a2 = parentPort) == null ? void 0 : _a2.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload(
"eslint",
diagnostics2.map((d) => diagnosticToRuntimeError(d))
)
});
}
};
const handleFileChange = async (filePath, type) => {
const extension = path.extname(filePath);
const { extensions } = eslintOptions;
const hasExtensionsConfig = Array.isArray(extensions);
if (hasExtensionsConfig && !extensions.includes(extension)) return;
const isChangedFileIgnored = await eslint.isPathIgnored(filePath);
if (isChangedFileIgnored) return;
const absPath = path.resolve(root, filePath);
if (type === "unlink") {
manager.updateByFileId(absPath, []);
} else if (type === "change") {
const diagnosticsOfChangedFile = await eslint.lintFiles(filePath);
const newDiagnostics = diagnosticsOfChangedFile.flatMap(
(d) => normalizeEslintDiagnostic(d)
);
manager.updateByFileId(absPath, newDiagnostics);
}
dispatchDiagnostics();
};
const files = options._.slice(1);
const diagnostics = await eslint.lintFiles(files);
manager.initWith(diagnostics.flatMap((p) => normalizeEslintDiagnostic(p)));
dispatchDiagnostics();
let watchTarget = root;
if (pluginConfig.eslint.watchPath) {
if (Array.isArray(pluginConfig.eslint.watchPath)) {
watchTarget = pluginConfig.eslint.watchPath.map(
(p) => path.resolve(root, p)
);
} else {
watchTarget = path.resolve(root, pluginConfig.eslint.watchPath);
}
}
const watcher = chokidar.watch(watchTarget, {
cwd: root,
ignored: createIgnore(root, files)
});
watcher.on("change", async (filePath) => {
handleFileChange(filePath, "change");
});
watcher.on("unlink", async (filePath) => {
handleFileChange(filePath, "unlink");
});
}
};
};
class EslintChecker extends Checker {
constructor() {
super({
name: "eslint",
absFilePath: __filename,
build: {
buildBin: (pluginConfig) => {
if (pluginConfig.eslint) {
const { lintCommand } = pluginConfig.eslint;
return ["eslint", lintCommand.split(" ").slice(1)];
}
return ["eslint", [""]];
}
},
createDiagnostic
});
}
init() {
const _createServeAndBuild = super.initMainThread();
createServeAndBuild = _createServeAndBuild;
super.initWorkerThread();
}
}
const eslintChecker = new EslintChecker();
eslintChecker.prepare();
eslintChecker.init();
export {
EslintChecker,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,45 @@
/**
* The options object parsed by Optionator.
* @typedef {Object} ParsedCLIOptions
* @property {boolean} cache Only check changed files
* @property {string} cacheFile Path to the cache file. Deprecated: use --cache-location
* @property {string} [cacheLocation] Path to the cache file or directory
* @property {"metadata" | "content"} cacheStrategy Strategy to use for detecting changed files in the cache
* @property {boolean} [color] Force enabling/disabling of color
* @property {string} [config] Use this configuration, overriding .eslintrc.* config options if present
* @property {boolean} debug Output debugging information
* @property {string[]} [env] Specify environments
* @property {boolean} envInfo Output execution environment information
* @property {boolean} errorOnUnmatchedPattern Prevent errors when pattern is unmatched
* @property {boolean} eslintrc Disable use of configuration from .eslintrc.*
* @property {string[]} [ext] Specify JavaScript file extensions
* @property {boolean} fix Automatically fix problems
* @property {boolean} fixDryRun Automatically fix problems without saving the changes to the file system
* @property {("directive" | "problem" | "suggestion" | "layout")[]} [fixType] Specify the types of fixes to apply (directive, problem, suggestion, layout)
* @property {string} format Use a specific output format
* @property {string[]} [global] Define global variables
* @property {boolean} [help] Show help
* @property {boolean} ignore Disable use of ignore files and patterns
* @property {string} [ignorePath] Specify path of ignore file
* @property {string[]} [ignorePattern] Pattern of files to ignore (in addition to those in .eslintignore)
* @property {boolean} init Run config initialization wizard
* @property {boolean} inlineConfig Prevent comments from changing config or rules
* @property {number} maxWarnings Number of warnings to trigger nonzero exit code
* @property {string} [outputFile] Specify file to write report to
* @property {string} [parser] Specify the parser to be used
* @property {Object} [parserOptions] Specify parser options
* @property {string[]} [plugin] Specify plugins
* @property {string} [printConfig] Print the configuration for the given file
* @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable directives
* @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default
* @property {Object} [rule] Specify rules
* @property {string[]} [rulesdir] Load additional rules from this directory. Deprecated: Use rules from plugins
* @property {boolean} stdin Lint code provided on <STDIN>
* @property {string} [stdinFilename] Specify filename to process STDIN as
* @property {boolean} quiet Report errors only
* @property {boolean} [version] Output the version number
* @property {string[]} _ Positional filenames or patterns
*/
declare const options: any;
export { options };

View File

@@ -0,0 +1,273 @@
import { createRequire } from "node:module";
const _require = createRequire(import.meta.url);
import { dirname } from "node:path";
const eslintDir = dirname(_require.resolve("eslint/package.json"));
const optionatorPath = _require.resolve("optionator", {
paths: [eslintDir]
});
const optionator = _require(optionatorPath);
const options = optionator({
prepend: "eslint [options] file.js [file.js] [dir]",
defaults: {
concatRepeatedArrays: true,
mergeRepeatedObjects: true
},
options: [
{
heading: "Basic configuration"
},
{
option: "eslintrc",
type: "Boolean",
default: "true",
description: "Disable use of configuration from .eslintrc.*"
},
{
option: "config",
alias: "c",
type: "path::String",
description: "Use this configuration, overriding .eslintrc.* config options if present"
},
{
option: "env",
type: "[String]",
description: "Specify environments"
},
{
option: "ext",
type: "[String]",
description: "Specify JavaScript file extensions"
},
{
option: "global",
type: "[String]",
description: "Define global variables"
},
{
option: "parser",
type: "String",
description: "Specify the parser to be used"
},
{
option: "parser-options",
type: "Object",
description: "Specify parser options"
},
{
option: "resolve-plugins-relative-to",
type: "path::String",
description: "A folder where plugins should be resolved from, CWD by default"
},
{
heading: "Specifying rules and plugins"
},
{
option: "plugin",
type: "[String]",
description: "Specify plugins"
},
{
option: "rule",
type: "Object",
description: "Specify rules"
},
{
option: "rulesdir",
type: "[path::String]",
description: "Load additional rules from this directory. Deprecated: Use rules from plugins"
},
{
heading: "Fixing problems"
},
{
option: "fix",
type: "Boolean",
default: false,
description: "Automatically fix problems"
},
{
option: "fix-dry-run",
type: "Boolean",
default: false,
description: "Automatically fix problems without saving the changes to the file system"
},
{
option: "fix-type",
type: "Array",
description: "Specify the types of fixes to apply (directive, problem, suggestion, layout)"
},
{
heading: "Ignoring files"
},
{
option: "ignore-path",
type: "path::String",
description: "Specify path of ignore file"
},
{
option: "ignore",
type: "Boolean",
default: "true",
description: "Disable use of ignore files and patterns"
},
{
option: "ignore-pattern",
type: "[String]",
description: "Pattern of files to ignore (in addition to those in .eslintignore)",
concatRepeatedArrays: [
true,
{
oneValuePerFlag: true
}
]
},
{
heading: "Using stdin"
},
{
option: "stdin",
type: "Boolean",
default: "false",
description: "Lint code provided on <STDIN>"
},
{
option: "stdin-filename",
type: "String",
description: "Specify filename to process STDIN as"
},
{
heading: "Handling warnings"
},
{
option: "quiet",
type: "Boolean",
default: "false",
description: "Report errors only"
},
{
option: "max-warnings",
type: "Int",
default: "-1",
description: "Number of warnings to trigger nonzero exit code"
},
{
heading: "Output"
},
{
option: "output-file",
alias: "o",
type: "path::String",
description: "Specify file to write report to"
},
{
option: "format",
alias: "f",
type: "String",
default: "stylish",
description: "Use a specific output format"
},
{
option: "color",
type: "Boolean",
alias: "no-color",
description: "Force enabling/disabling of color"
},
{
heading: "Inline configuration comments"
},
{
option: "inline-config",
type: "Boolean",
default: "true",
description: "Prevent comments from changing config or rules"
},
{
option: "report-unused-disable-directives",
type: "Boolean",
default: void 0,
description: "Adds reported errors for unused eslint-disable directives"
},
{
heading: "Caching"
},
{
option: "cache",
type: "Boolean",
default: "false",
description: "Only check changed files"
},
{
option: "cache-file",
type: "path::String",
default: ".eslintcache",
description: "Path to the cache file. Deprecated: use --cache-location"
},
{
option: "cache-location",
type: "path::String",
description: "Path to the cache file or directory"
},
{
option: "cache-strategy",
dependsOn: ["cache"],
type: "String",
default: "metadata",
enum: ["metadata", "content"],
description: "Strategy to use for detecting changed files in the cache"
},
{
heading: "Miscellaneous"
},
{
option: "init",
type: "Boolean",
default: "false",
description: "Run config initialization wizard"
},
{
option: "env-info",
type: "Boolean",
default: "false",
description: "Output execution environment information"
},
{
option: "error-on-unmatched-pattern",
type: "Boolean",
default: "true",
description: "Prevent errors when pattern is unmatched"
},
{
option: "exit-on-fatal-error",
type: "Boolean",
default: "false",
description: "Exit with exit code 2 in case of fatal error"
},
{
option: "debug",
type: "Boolean",
default: false,
description: "Output debugging information"
},
{
option: "help",
alias: "h",
type: "Boolean",
description: "Show help"
},
{
option: "version",
alias: "v",
type: "Boolean",
description: "Output the version number"
},
{
option: "print-config",
type: "path::String",
description: "Print the configuration for the given file"
}
]
});
export {
options
};
//# sourceMappingURL=options.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
import { NormalizedDiagnostic } from '../../logger.js';
import { DiagnosticLevel } from '../../types.js';
import '@babel/code-frame';
import 'eslint';
import 'stylelint';
import 'typescript';
import 'vscode-languageclient/node';
import 'node:worker_threads';
import 'vite';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
declare function mapSeverity(s: string): DiagnosticLevel;
declare function getOxlintCommand(command: string): string[];
declare function runOxlint(command: string, cwd: string): Promise<NormalizedDiagnostic[]>;
export { getOxlintCommand, mapSeverity, runOxlint };

View File

@@ -0,0 +1,135 @@
import { exec } from "node:child_process";
import fs from "node:fs/promises";
import path from "node:path";
import { stripVTControlCharacters as strip } from "node:util";
import colors from "picocolors";
import { createFrame, offsetRangeToBabelLocation } from "../../codeFrame.js";
import { consoleLog } from "../../logger.js";
import { DiagnosticLevel } from "../../types.js";
import { parseArgsStringToArgv } from "../stylelint/argv.js";
const severityMap = {
error: DiagnosticLevel.Error,
warning: DiagnosticLevel.Warning,
info: DiagnosticLevel.Suggestion
};
function mapSeverity(s) {
return severityMap[s] ?? DiagnosticLevel.Error;
}
function getOxlintCommand(command) {
const parsed = parseArgsStringToArgv(command);
const index = parsed.findIndex((p) => p === "--format" || p === "-f");
if (index === -1) {
parsed.push("--format", "json");
} else {
consoleLog(
colors.yellow(
`vite-plugin-checker will force append "--format json" to the flags in dev mode, please don't use "--format" or "-f" flag in "config.oxlint.lintCommand".`
),
"warn"
);
parsed.splice(index, 2, "--format", "json");
}
return parsed;
}
function runOxlint(command, cwd) {
return new Promise((resolve, _reject) => {
exec(
command,
{
cwd,
maxBuffer: Number.POSITIVE_INFINITY
},
(_error, stdout, _stderr) => {
parseOxlintOutput(stdout, cwd).then(resolve).catch(() => resolve([]));
}
);
});
}
async function parseOxlintOutput(output, cwd) {
const parsed = safeParseOxlint(output);
if (!parsed) return [];
const entries = getEntries(parsed, cwd);
if (entries.length === 0) return [];
const files = getUniqueFiles(entries);
const sourceCache = await readSources(files);
return buildDiagnostics(entries, sourceCache);
}
function safeParseOxlint(output) {
try {
return JSON.parse(output);
} catch {
return null;
}
}
function getEntries(parsed, cwd) {
return parsed.diagnostics.flatMap(
({ filename, labels, code, message, severity }) => {
const file = normalizePath(filename, cwd);
const [label] = labels;
if (!label) return [];
return [
{
file,
span: label.span,
code,
message,
severity
}
];
}
);
}
function getUniqueFiles(entries) {
return [...new Set(entries.map((e) => e.file))];
}
async function readSources(files) {
const cache = /* @__PURE__ */ new Map();
await Promise.all(
files.map(async (file) => {
try {
const source = await fs.readFile(file, "utf8");
cache.set(file, source);
} catch {
}
})
);
return cache;
}
function buildDiagnostics(entries, sources) {
return entries.flatMap((entry) => {
const source = sources.get(entry.file);
if (!source) return [];
const loc = offsetRangeToBabelLocation(
source,
entry.span.offset,
entry.span.length
);
const codeFrame = createFrame(source, loc);
return [
{
message: `${entry.code}: ${entry.message}`,
conclusion: "",
level: mapSeverity(entry.severity),
checker: "oxlint",
id: entry.file,
codeFrame,
stripedCodeFrame: codeFrame && strip(codeFrame),
loc
}
];
});
}
function normalizePath(p, cwd) {
let filename = p;
if (filename) {
filename = path.isAbsolute(filename) ? filename : path.resolve(cwd, filename);
filename = path.normalize(filename);
}
return filename;
}
export {
getOxlintCommand,
mapSeverity,
runOxlint
};
//# sourceMappingURL=cli.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
import { NormalizedDiagnostic } from '../../logger.js';
import { CreateDiagnostic } from '../../types.js';
import { DisplayTarget } from './types.js';
import '@babel/code-frame';
import 'eslint';
import 'stylelint';
import 'typescript';
import 'vscode-languageclient/node';
import 'node:worker_threads';
import 'vite';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
declare const createDiagnostic: CreateDiagnostic<'oxlint'>;
declare function dispatchDiagnostics(diagnostics: NormalizedDiagnostic[], targets: Set<DisplayTarget>): void;
export { createDiagnostic, dispatchDiagnostics };

View File

@@ -0,0 +1,75 @@
import { parentPort } from "node:worker_threads";
import { FileDiagnosticManager } from "../../FileDiagnosticManager.js";
import {
composeCheckerSummary,
consoleLog,
diagnosticToConsoleLevel,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
toClientPayload
} from "../../logger.js";
import {
ACTION_TYPES,
DiagnosticLevel
} from "../../types.js";
import { resolveOptions } from "./options.js";
import { setupDevServer } from "./server.js";
const createDiagnostic = (pluginConfig) => {
const manager = new FileDiagnosticManager();
const oxlintConfig = pluginConfig.oxlint;
const displayTargets = /* @__PURE__ */ new Set();
return {
config: async ({ enableOverlay, enableTerminal }) => {
displayTargets.clear();
if (enableOverlay) displayTargets.add("overlay");
if (enableTerminal) displayTargets.add("terminal");
},
async configureServer({ root }) {
if (!oxlintConfig) return;
const options = resolveOptions(root, oxlintConfig);
await setupDevServer(root, options, manager, displayTargets);
}
};
};
function dispatchDiagnostics(diagnostics, targets) {
if (targets.size === 0) return;
if (targets.has("terminal")) {
dispatchTerminalDiagnostics(diagnostics);
}
if (targets.has("overlay")) {
dispatchOverlayDiagnostics(diagnostics);
}
}
function dispatchTerminalDiagnostics(diagnostics) {
for (const d of diagnostics) {
consoleLog(
diagnosticToTerminalLog(d, "oxlint"),
diagnosticToConsoleLevel(d)
);
}
const errorCount = diagnostics.filter(
(d) => d.level === DiagnosticLevel.Error
).length;
const warningCount = diagnostics.filter(
(d) => d.level === DiagnosticLevel.Warning
).length;
consoleLog(
composeCheckerSummary("oxlint", errorCount, warningCount),
errorCount ? "error" : warningCount ? "warn" : "info"
);
}
function dispatchOverlayDiagnostics(diagnostics) {
var _a;
(_a = parentPort) == null ? void 0 : _a.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload(
"oxlint",
diagnostics.map((d) => diagnosticToRuntimeError(d))
)
});
}
export {
createDiagnostic,
dispatchDiagnostics
};
//# sourceMappingURL=diagnostics.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/oxlint/diagnostics.ts"],"sourcesContent":["import { parentPort } from 'node:worker_threads'\nimport { FileDiagnosticManager } from '../../FileDiagnosticManager.js'\nimport {\n composeCheckerSummary,\n consoleLog,\n diagnosticToConsoleLevel,\n diagnosticToRuntimeError,\n diagnosticToTerminalLog,\n type NormalizedDiagnostic,\n toClientPayload,\n} from '../../logger.js'\nimport {\n ACTION_TYPES,\n type CreateDiagnostic,\n DiagnosticLevel,\n} from '../../types.js'\nimport { resolveOptions } from './options.js'\nimport { setupDevServer } from './server.js'\nimport type { DisplayTarget } from './types'\n\nexport const createDiagnostic: CreateDiagnostic<'oxlint'> = (pluginConfig) => {\n const manager = new FileDiagnosticManager()\n\n const oxlintConfig = pluginConfig.oxlint\n const displayTargets = new Set<DisplayTarget>()\n\n return {\n config: async ({ enableOverlay, enableTerminal }) => {\n displayTargets.clear()\n if (enableOverlay) displayTargets.add('overlay')\n if (enableTerminal) displayTargets.add('terminal')\n },\n async configureServer({ root }) {\n if (!oxlintConfig) return\n\n const options = resolveOptions(root, oxlintConfig)\n await setupDevServer(root, options, manager, displayTargets)\n },\n }\n}\n\nexport function dispatchDiagnostics(\n diagnostics: NormalizedDiagnostic[],\n targets: Set<DisplayTarget>,\n) {\n if (targets.size === 0) return\n\n if (targets.has('terminal')) {\n dispatchTerminalDiagnostics(diagnostics)\n }\n if (targets.has('overlay')) {\n dispatchOverlayDiagnostics(diagnostics)\n }\n}\n\nfunction dispatchTerminalDiagnostics(diagnostics: NormalizedDiagnostic[]) {\n for (const d of diagnostics) {\n consoleLog(\n diagnosticToTerminalLog(d, 'oxlint'),\n diagnosticToConsoleLevel(d),\n )\n }\n\n const errorCount = diagnostics.filter(\n (d) => d.level === DiagnosticLevel.Error,\n ).length\n const warningCount = diagnostics.filter(\n (d) => d.level === DiagnosticLevel.Warning,\n ).length\n consoleLog(\n composeCheckerSummary('oxlint', errorCount, warningCount),\n errorCount ? 'error' : warningCount ? 'warn' : 'info',\n )\n}\n\nfunction dispatchOverlayDiagnostics(diagnostics: NormalizedDiagnostic[]) {\n parentPort?.postMessage({\n type: ACTION_TYPES.overlayError,\n payload: toClientPayload(\n 'oxlint',\n diagnostics.map((d) => diagnosticToRuntimeError(d)),\n ),\n })\n}\n"],"mappings":"AAAA,SAAS,kBAAkB;AAC3B,SAAS,6BAA6B;AACtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAGxB,MAAM,mBAA+C,CAAC,iBAAiB;AAC5E,QAAM,UAAU,IAAI,sBAAsB;AAE1C,QAAM,eAAe,aAAa;AAClC,QAAM,iBAAiB,oBAAI,IAAmB;AAE9C,SAAO;AAAA,IACL,QAAQ,OAAO,EAAE,eAAe,eAAe,MAAM;AACnD,qBAAe,MAAM;AACrB,UAAI,cAAe,gBAAe,IAAI,SAAS;AAC/C,UAAI,eAAgB,gBAAe,IAAI,UAAU;AAAA,IACnD;AAAA,IACA,MAAM,gBAAgB,EAAE,KAAK,GAAG;AAC9B,UAAI,CAAC,aAAc;AAEnB,YAAM,UAAU,eAAe,MAAM,YAAY;AACjD,YAAM,eAAe,MAAM,SAAS,SAAS,cAAc;AAAA,IAC7D;AAAA,EACF;AACF;AAEO,SAAS,oBACd,aACA,SACA;AACA,MAAI,QAAQ,SAAS,EAAG;AAExB,MAAI,QAAQ,IAAI,UAAU,GAAG;AAC3B,gCAA4B,WAAW;AAAA,EACzC;AACA,MAAI,QAAQ,IAAI,SAAS,GAAG;AAC1B,+BAA2B,WAAW;AAAA,EACxC;AACF;AAEA,SAAS,4BAA4B,aAAqC;AACxE,aAAW,KAAK,aAAa;AAC3B;AAAA,MACE,wBAAwB,GAAG,QAAQ;AAAA,MACnC,yBAAyB,CAAC;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,aAAa,YAAY;AAAA,IAC7B,CAAC,MAAM,EAAE,UAAU,gBAAgB;AAAA,EACrC,EAAE;AACF,QAAM,eAAe,YAAY;AAAA,IAC/B,CAAC,MAAM,EAAE,UAAU,gBAAgB;AAAA,EACrC,EAAE;AACF;AAAA,IACE,sBAAsB,UAAU,YAAY,YAAY;AAAA,IACxD,aAAa,UAAU,eAAe,SAAS;AAAA,EACjD;AACF;AAEA,SAAS,2BAA2B,aAAqC;AA3EzE;AA4EE,0CAAY,YAAY;AAAA,IACtB,MAAM,aAAa;AAAA,IACnB,SAAS;AAAA,MACP;AAAA,MACA,YAAY,IAAI,CAAC,MAAM,yBAAyB,CAAC,CAAC;AAAA,IACpD;AAAA,EACF;AACF;","names":[]}

View File

@@ -0,0 +1,17 @@
import { ServeAndBuildChecker } from '../../types.js';
import * as vite from 'vite';
import { Checker } from '../../Checker.js';
import 'node:worker_threads';
import 'eslint';
import 'stylelint';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
import '../../worker.js';
declare class OxlintChecker extends Checker<'oxlint'> {
constructor();
}
declare const createServeAndBuild: ((config: any, env: vite.ConfigEnv) => ServeAndBuildChecker) | undefined;
export { OxlintChecker, createServeAndBuild };

View File

@@ -0,0 +1,30 @@
import { fileURLToPath } from "node:url";
import { Checker } from "../../Checker.js";
import parseArgsStringToArgv from "../stylelint/argv.js";
import { createDiagnostic } from "./diagnostics.js";
const __filename = fileURLToPath(import.meta.url);
class OxlintChecker extends Checker {
constructor() {
super({
name: "oxlint",
absFilePath: __filename,
build: {
buildBin: ({ oxlint: oxlint2 }) => {
const commandStr = typeof oxlint2 === "boolean" ? "oxlint" : (oxlint2 == null ? void 0 : oxlint2.lintCommand) ?? "oxlint";
const command = parseArgsStringToArgv(commandStr);
return [command[0], command.slice(1)];
}
},
createDiagnostic
});
}
}
const oxlint = new OxlintChecker();
oxlint.prepare();
oxlint.initWorkerThread();
const createServeAndBuild = oxlint.initMainThread();
export {
OxlintChecker,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/oxlint/main.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\nimport { Checker } from '../../Checker.js'\nimport parseArgsStringToArgv from '../stylelint/argv.js'\nimport { createDiagnostic } from './diagnostics.js'\n\nconst __filename = fileURLToPath(import.meta.url)\n\nexport class OxlintChecker extends Checker<'oxlint'> {\n public constructor() {\n super({\n name: 'oxlint',\n absFilePath: __filename,\n build: {\n buildBin: ({ oxlint }) => {\n const commandStr =\n typeof oxlint === 'boolean'\n ? 'oxlint'\n : (oxlint?.lintCommand ?? 'oxlint')\n const command = parseArgsStringToArgv(commandStr)\n return [command[0]!, command.slice(1)]\n },\n },\n createDiagnostic,\n })\n }\n}\n\nconst oxlint = new OxlintChecker()\noxlint.prepare()\noxlint.initWorkerThread()\n\nexport const createServeAndBuild = oxlint.initMainThread()\n"],"mappings":"AAAA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,OAAO,2BAA2B;AAClC,SAAS,wBAAwB;AAEjC,MAAM,aAAa,cAAc,YAAY,GAAG;AAEzC,MAAM,sBAAsB,QAAkB;AAAA,EAC5C,cAAc;AACnB,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,QACL,UAAU,CAAC,EAAE,QAAAA,QAAO,MAAM;AACxB,gBAAM,aACJ,OAAOA,YAAW,YACd,YACCA,WAAA,gBAAAA,QAAQ,gBAAe;AAC9B,gBAAM,UAAU,sBAAsB,UAAU;AAChD,iBAAO,CAAC,QAAQ,CAAC,GAAI,QAAQ,MAAM,CAAC,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,MAAM,SAAS,IAAI,cAAc;AACjC,OAAO,QAAQ;AACf,OAAO,iBAAiB;AAEjB,MAAM,sBAAsB,OAAO,eAAe;","names":["oxlint"]}

View File

@@ -0,0 +1,17 @@
import { DiagnosticLevel, OxlintConfig } from '../../types.js';
import 'node:worker_threads';
import 'eslint';
import 'stylelint';
import 'vite';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
interface ResolvedOptions {
watchTarget: string | string[];
logLevel?: DiagnosticLevel[];
command: string;
}
declare function resolveOptions(root: string, config: Exclude<OxlintConfig, false>): ResolvedOptions;
export { type ResolvedOptions, resolveOptions };

View File

@@ -0,0 +1,22 @@
import path from "node:path";
import { DiagnosticLevel } from "../../types.js";
import { getOxlintCommand, mapSeverity } from "./cli.js";
function resolveOptions(root, config) {
var _a, _b;
const options = config === true ? { lintCommand: "oxlint" } : config;
return {
watchTarget: resolveWatchTarget(root, options.watchPath),
logLevel: ((_b = (_a = options.dev) == null ? void 0 : _a.logLevel) == null ? void 0 : _b.map((l) => mapSeverity(l))) ?? [
DiagnosticLevel.Warning,
DiagnosticLevel.Error
],
command: getOxlintCommand(options.lintCommand ?? "oxlint").join(" ")
};
}
function resolveWatchTarget(root, watchPath) {
return Array.isArray(watchPath) ? watchPath.map((p) => path.resolve(root, p)) : typeof watchPath === "string" ? path.resolve(root, watchPath) : root;
}
export {
resolveOptions
};
//# sourceMappingURL=options.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/oxlint/options.ts"],"sourcesContent":["import path from 'node:path'\nimport { DiagnosticLevel, type OxlintConfig } from '../../types.js'\nimport { getOxlintCommand, mapSeverity } from './cli.js'\n\nexport interface ResolvedOptions {\n watchTarget: string | string[]\n logLevel?: DiagnosticLevel[]\n command: string\n}\n\nexport function resolveOptions(\n root: string,\n config: Exclude<OxlintConfig, false>,\n): ResolvedOptions {\n const options = config === true ? { lintCommand: 'oxlint' } : config\n return {\n watchTarget: resolveWatchTarget(root, options.watchPath),\n logLevel: options.dev?.logLevel?.map((l) => mapSeverity(l)) ?? [\n DiagnosticLevel.Warning,\n DiagnosticLevel.Error,\n ],\n command: getOxlintCommand(options.lintCommand ?? 'oxlint').join(' '),\n }\n}\n\nfunction resolveWatchTarget(\n root: string,\n watchPath?: string | string[],\n): string | string[] {\n return Array.isArray(watchPath)\n ? watchPath.map((p) => path.resolve(root, p))\n : typeof watchPath === 'string'\n ? path.resolve(root, watchPath)\n : root\n}\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,SAAS,uBAA0C;AACnD,SAAS,kBAAkB,mBAAmB;AAQvC,SAAS,eACd,MACA,QACiB;AAbnB;AAcE,QAAM,UAAU,WAAW,OAAO,EAAE,aAAa,SAAS,IAAI;AAC9D,SAAO;AAAA,IACL,aAAa,mBAAmB,MAAM,QAAQ,SAAS;AAAA,IACvD,YAAU,mBAAQ,QAAR,mBAAa,aAAb,mBAAuB,IAAI,CAAC,MAAM,YAAY,CAAC,OAAM;AAAA,MAC7D,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAClB;AAAA,IACA,SAAS,iBAAiB,QAAQ,eAAe,QAAQ,EAAE,KAAK,GAAG;AAAA,EACrE;AACF;AAEA,SAAS,mBACP,MACA,WACmB;AACnB,SAAO,MAAM,QAAQ,SAAS,IAC1B,UAAU,IAAI,CAAC,MAAM,KAAK,QAAQ,MAAM,CAAC,CAAC,IAC1C,OAAO,cAAc,WACnB,KAAK,QAAQ,MAAM,SAAS,IAC5B;AACR;","names":[]}

View File

@@ -0,0 +1,19 @@
import { FileDiagnosticManager } from '../../FileDiagnosticManager.js';
import { ResolvedOptions } from './options.js';
import { DisplayTarget } from './types.js';
import '../../logger.js';
import '@babel/code-frame';
import '../../types.js';
import 'node:worker_threads';
import 'eslint';
import 'stylelint';
import 'vite';
import '../vls/initParams.js';
import 'vscode-languageserver/node';
import 'vscode-uri';
import 'typescript';
import 'vscode-languageclient/node';
declare function setupDevServer(root: string, options: ResolvedOptions, manager: FileDiagnosticManager, displayTargets: Set<DisplayTarget>): Promise<void>;
export { setupDevServer };

View File

@@ -0,0 +1,51 @@
import path from "node:path";
import chokidar from "chokidar";
import { filterLogLevel } from "../../logger.js";
import { runOxlint } from "./cli.js";
import { dispatchDiagnostics } from "./diagnostics.js";
async function setupDevServer(root, options, manager, displayTargets) {
const initial = await runOxlint(options.command, root);
manager.initWith(initial);
dispatchDiagnostics(
filterLogLevel(manager.getDiagnostics(), options.logLevel),
displayTargets
);
const watcher = chokidar.watch(options.watchTarget, {
cwd: root,
ignored: (path2) => path2.includes("node_modules")
});
watcher.on("change", async (filePath) => {
await handleFileChange(root, options.command, filePath, manager);
dispatchDiagnostics(
filterLogLevel(manager.getDiagnostics(), options.logLevel),
displayTargets
);
});
watcher.on("unlink", (filePath) => {
handleFileUnlink(root, filePath, manager);
dispatchDiagnostics(
filterLogLevel(manager.getDiagnostics(), options.logLevel),
displayTargets
);
});
watcher.add(".");
}
function handleFileUnlink(root, filePath, manager) {
const absPath = path.resolve(root, filePath);
manager.updateByFileId(absPath, []);
}
async function handleFileChange(root, command, filePath, manager) {
const absPath = path.resolve(root, filePath);
const isConfigFile = path.basename(absPath) === ".oxlintrc.json";
if (isConfigFile) {
const diagnostics = await runOxlint(`${command} ${root}`, root);
manager.initWith(diagnostics);
} else {
const diagnostics = await runOxlint(`${command} ${absPath}`, root);
manager.updateByFileId(absPath, diagnostics);
}
}
export {
setupDevServer
};
//# sourceMappingURL=server.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/oxlint/server.ts"],"sourcesContent":["import path from 'node:path'\nimport chokidar from 'chokidar'\nimport type { FileDiagnosticManager } from '../../FileDiagnosticManager.js'\nimport { filterLogLevel } from '../../logger.js'\nimport { runOxlint } from './cli.js'\nimport { dispatchDiagnostics } from './diagnostics.js'\nimport type { ResolvedOptions } from './options.js'\nimport type { DisplayTarget } from './types'\n\nexport async function setupDevServer(\n root: string,\n options: ResolvedOptions,\n manager: FileDiagnosticManager,\n displayTargets: Set<DisplayTarget>,\n): Promise<void> {\n const initial = await runOxlint(options.command, root)\n manager.initWith(initial)\n dispatchDiagnostics(\n filterLogLevel(manager.getDiagnostics(), options.logLevel),\n displayTargets,\n )\n\n const watcher = chokidar.watch(options.watchTarget, {\n cwd: root,\n ignored: (path: string) => path.includes('node_modules'),\n })\n\n watcher.on('change', async (filePath) => {\n await handleFileChange(root, options.command, filePath, manager)\n dispatchDiagnostics(\n filterLogLevel(manager.getDiagnostics(), options.logLevel),\n displayTargets,\n )\n })\n\n watcher.on('unlink', (filePath) => {\n handleFileUnlink(root, filePath, manager)\n dispatchDiagnostics(\n filterLogLevel(manager.getDiagnostics(), options.logLevel),\n displayTargets,\n )\n })\n\n watcher.add('.')\n}\n\nfunction handleFileUnlink(\n root: string,\n filePath: string,\n manager: FileDiagnosticManager,\n) {\n const absPath = path.resolve(root, filePath)\n manager.updateByFileId(absPath, [])\n}\n\nasync function handleFileChange(\n root: string,\n command: string,\n filePath: string,\n manager: FileDiagnosticManager,\n) {\n const absPath = path.resolve(root, filePath)\n\n const isConfigFile = path.basename(absPath) === '.oxlintrc.json'\n if (isConfigFile) {\n const diagnostics = await runOxlint(`${command} ${root}`, root)\n manager.initWith(diagnostics)\n } else {\n const diagnostics = await runOxlint(`${command} ${absPath}`, root)\n manager.updateByFileId(absPath, diagnostics)\n }\n}\n"],"mappings":"AAAA,OAAO,UAAU;AACjB,OAAO,cAAc;AAErB,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AAIpC,eAAsB,eACpB,MACA,SACA,SACA,gBACe;AACf,QAAM,UAAU,MAAM,UAAU,QAAQ,SAAS,IAAI;AACrD,UAAQ,SAAS,OAAO;AACxB;AAAA,IACE,eAAe,QAAQ,eAAe,GAAG,QAAQ,QAAQ;AAAA,IACzD;AAAA,EACF;AAEA,QAAM,UAAU,SAAS,MAAM,QAAQ,aAAa;AAAA,IAClD,KAAK;AAAA,IACL,SAAS,CAACA,UAAiBA,MAAK,SAAS,cAAc;AAAA,EACzD,CAAC;AAED,UAAQ,GAAG,UAAU,OAAO,aAAa;AACvC,UAAM,iBAAiB,MAAM,QAAQ,SAAS,UAAU,OAAO;AAC/D;AAAA,MACE,eAAe,QAAQ,eAAe,GAAG,QAAQ,QAAQ;AAAA,MACzD;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,GAAG,UAAU,CAAC,aAAa;AACjC,qBAAiB,MAAM,UAAU,OAAO;AACxC;AAAA,MACE,eAAe,QAAQ,eAAe,GAAG,QAAQ,QAAQ;AAAA,MACzD;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,IAAI,GAAG;AACjB;AAEA,SAAS,iBACP,MACA,UACA,SACA;AACA,QAAM,UAAU,KAAK,QAAQ,MAAM,QAAQ;AAC3C,UAAQ,eAAe,SAAS,CAAC,CAAC;AACpC;AAEA,eAAe,iBACb,MACA,SACA,UACA,SACA;AACA,QAAM,UAAU,KAAK,QAAQ,MAAM,QAAQ;AAE3C,QAAM,eAAe,KAAK,SAAS,OAAO,MAAM;AAChD,MAAI,cAAc;AAChB,UAAM,cAAc,MAAM,UAAU,GAAG,OAAO,IAAI,IAAI,IAAI,IAAI;AAC9D,YAAQ,SAAS,WAAW;AAAA,EAC9B,OAAO;AACL,UAAM,cAAc,MAAM,UAAU,GAAG,OAAO,IAAI,OAAO,IAAI,IAAI;AACjE,YAAQ,eAAe,SAAS,WAAW;AAAA,EAC7C;AACF;","names":["path"]}

View File

@@ -0,0 +1,3 @@
type DisplayTarget = 'overlay' | 'terminal';
export type { DisplayTarget };

View File

@@ -0,0 +1 @@
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}

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

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 TscChecker extends Checker<'typescript'> {
constructor();
init(): void;
}
export { TscChecker, createServeAndBuild };

View File

@@ -0,0 +1,170 @@
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parentPort } from "node:worker_threads";
import colors from "picocolors";
import invariant from "tiny-invariant";
import { Checker } from "../../Checker.js";
import {
consoleLog,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
ensureCall,
normalizeTsDiagnostic,
toClientPayload,
wrapCheckerSummary
} from "../../logger.js";
import {
ACTION_TYPES
} from "../../types.js";
const __filename = fileURLToPath(import.meta.url);
let createServeAndBuild;
const createDiagnostic = (pluginConfig) => {
let overlay = true;
let terminal = true;
let currDiagnostics = [];
return {
config: async ({ enableOverlay, enableTerminal }) => {
overlay = enableOverlay;
terminal = enableTerminal;
},
async configureServer({ root }) {
invariant(pluginConfig.typescript, "config.typescript should be `false`");
const finalConfig = pluginConfig.typescript === true ? {
root,
tsconfigPath: "tsconfig.json",
typescriptPath: "typescript"
} : {
root: pluginConfig.typescript.root ?? root,
tsconfigPath: pluginConfig.typescript.tsconfigPath ?? "tsconfig.json",
typescriptPath: pluginConfig.typescript.typescriptPath ?? "typescript"
};
let configFile;
const ts = await import(finalConfig.typescriptPath).then((r) => r.default || r);
configFile = ts.findConfigFile(
finalConfig.root,
ts.sys.fileExists,
finalConfig.tsconfigPath
);
if (configFile === void 0) {
throw Error(
`Failed to find a valid tsconfig.json: ${finalConfig.tsconfigPath} at ${finalConfig.root} is not a valid tsconfig`
);
}
let logChunk = "";
const reportDiagnostic = (diagnostic) => {
const normalizedDiagnostic = normalizeTsDiagnostic(diagnostic);
if (normalizedDiagnostic === null) {
return;
}
currDiagnostics.push(diagnosticToRuntimeError(normalizedDiagnostic));
logChunk += os.EOL + diagnosticToTerminalLog(normalizedDiagnostic, "TypeScript");
};
const reportWatchStatusChanged = (diagnostic, _newLine, _options, errorCount) => {
var _a;
if (diagnostic.code === 6031) return;
switch (diagnostic.code) {
case 6031:
case 6032:
logChunk = "";
currDiagnostics = [];
return;
case 6193:
// 1 Error
case 6194:
if (overlay) {
(_a = parentPort) == null ? void 0 : _a.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload("typescript", currDiagnostics)
});
}
}
ensureCall(() => {
if (errorCount === 0) {
logChunk = "";
}
if (terminal) {
const color = errorCount && errorCount > 0 ? "red" : "green";
consoleLog(
colors[color](
logChunk + os.EOL + wrapCheckerSummary(
"TypeScript",
diagnostic.messageText.toString()
)
),
errorCount ? "error" : "info"
);
}
});
};
const createProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram;
if (typeof pluginConfig.typescript === "object" && pluginConfig.typescript.buildMode) {
const host = ts.createSolutionBuilderWithWatchHost(
ts.sys,
createProgram,
reportDiagnostic,
void 0,
reportWatchStatusChanged
);
ts.createSolutionBuilderWithWatch(host, [configFile], {}).build();
} else {
const host = ts.createWatchCompilerHost(
configFile,
{ noEmit: true },
ts.sys,
createProgram,
reportDiagnostic,
reportWatchStatusChanged
);
ts.createWatchProgram(host);
}
}
};
};
class TscChecker extends Checker {
constructor() {
super({
name: "typescript",
absFilePath: __filename,
build: {
buildBin: (config) => {
if (typeof config.typescript === "object") {
const {
root = "",
tsconfigPath = "",
buildMode
} = config.typescript;
const args = [buildMode ? "-b" : "--noEmit"];
let projectPath = "";
if (root || tsconfigPath) {
projectPath = root ? path.join(root, tsconfigPath) : tsconfigPath;
}
if (projectPath) {
if (buildMode) {
args.push(projectPath);
} else {
args.push("-p", projectPath);
}
}
return ["tsc", args];
}
return ["tsc", ["--noEmit"]];
}
},
createDiagnostic
});
}
init() {
const _createServeAndBuild = super.initMainThread();
createServeAndBuild = _createServeAndBuild;
super.initWorkerThread();
}
}
const tscChecker = new TscChecker();
tscChecker.prepare();
tscChecker.init();
export {
TscChecker,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,53 @@
import * as vscode_languageserver from 'vscode-languageserver';
import { Duplex } from 'node:stream';
import { VLS } from 'vls';
import { DiagnosticSeverity, Logger } from 'vscode-languageserver/node.js';
import { URI } from 'vscode-uri';
import { NormalizedDiagnostic } from '../../logger.js';
import { DeepPartial } from '../../types.js';
import { VlsOptions } from './initParams.js';
import '@babel/code-frame';
import 'eslint';
import 'stylelint';
import 'typescript';
import 'vscode-languageclient/node';
import 'node:worker_threads';
import 'vite';
import 'vscode-languageserver/node';
type LogLevel = (typeof logLevels)[number];
declare const logLevels: readonly ["ERROR", "WARN", "INFO", "HINT"];
declare const logLevel2Severity: {
ERROR: 1;
WARN: 2;
INFO: 3;
HINT: 4;
};
interface DiagnosticOptions {
watch: boolean;
verbose: boolean;
config: DeepPartial<VlsOptions> | null;
onDispatchDiagnostics?: (normalized: NormalizedDiagnostic[]) => void;
onDispatchDiagnosticsSummary?: (errorCount: number, warningCount: number) => void;
}
declare function diagnostics(workspace: string | null, logLevel: LogLevel, options?: DiagnosticOptions): Promise<void>;
declare class NullLogger implements Logger {
error(_message: string): void;
warn(_message: string): void;
info(_message: string): void;
log(_message: string): void;
}
declare class TestStream extends Duplex {
_write(chunk: string, _encoding: string, done: () => void): void;
_read(_size: number): void;
}
declare function prepareClientConnection(workspaceUri: URI, severity: DiagnosticSeverity, options: DiagnosticOptions): Promise<{
clientConnection: vscode_languageserver.ProtocolConnection;
serverConnection: vscode_languageserver.Connection;
vls: VLS;
up: TestStream;
down: TestStream;
logger: NullLogger;
}>;
export { type DiagnosticOptions, TestStream, diagnostics, logLevel2Severity, logLevels, prepareClientConnection };

View File

@@ -0,0 +1,330 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { Duplex } from "node:stream";
import chokidar from "chokidar";
import colors from "picocolors";
import { globSync } from "tinyglobby";
import { VLS } from "vls";
import {
createConnection,
createProtocolConnection,
DiagnosticSeverity,
DidChangeTextDocumentNotification,
DidChangeWatchedFilesNotification,
DidOpenTextDocumentNotification,
InitializeRequest,
StreamMessageReader,
StreamMessageWriter
} from "vscode-languageserver/node.js";
import { URI } from "vscode-uri";
import { FileDiagnosticManager } from "../../FileDiagnosticManager.js";
import {
diagnosticToTerminalLog,
normalizeLspDiagnostic,
normalizePublishDiagnosticParams
} from "../../logger.js";
import { getInitParams } from "./initParams.js";
var DOC_VERSION = /* @__PURE__ */ ((DOC_VERSION2) => {
DOC_VERSION2[DOC_VERSION2["init"] = -1] = "init";
return DOC_VERSION2;
})(DOC_VERSION || {});
const logLevels = ["ERROR", "WARN", "INFO", "HINT"];
let disposeSuppressConsole;
let initialVueFilesCount = 0;
let initialVueFilesTick = 0;
const fileDiagnosticManager = new FileDiagnosticManager();
const logLevel2Severity = {
ERROR: DiagnosticSeverity.Error,
WARN: DiagnosticSeverity.Warning,
INFO: DiagnosticSeverity.Information,
HINT: DiagnosticSeverity.Hint
};
async function diagnostics(workspace, logLevel, options = { watch: false, verbose: false, config: null }) {
var _a;
if (options.verbose) {
console.log("====================================");
console.log("Getting Vetur diagnostics");
}
let workspaceUri;
if (workspace) {
const absPath = path.resolve(process.cwd(), workspace);
console.log(`Loading Vetur in workspace path: ${colors.green(absPath)}`);
workspaceUri = URI.file(absPath);
} else {
console.log(
`Loading Vetur in current directory: ${colors.green(process.cwd())}`
);
workspaceUri = URI.file(process.cwd());
}
const result = await getDiagnostics(
workspaceUri,
logLevel2Severity[logLevel],
options
);
if (options.verbose) {
console.log("====================================");
}
if (!options.watch && typeof result === "object" && result !== null) {
const { initialErrorCount, initialWarningCount } = result;
(_a = options == null ? void 0 : options.onDispatchDiagnosticsSummary) == null ? void 0 : _a.call(
options,
initialErrorCount,
initialWarningCount
);
process.exit(initialErrorCount > 0 ? 1 : 0);
}
}
class NullLogger {
error(_message) {
}
warn(_message) {
}
info(_message) {
}
log(_message) {
}
}
class TestStream extends Duplex {
_write(chunk, _encoding, done) {
this.emit("data", chunk);
done();
}
_read(_size) {
}
}
function suppressConsole() {
let disposed = false;
const rawConsoleLog = console.log;
console.log = () => {
};
return () => {
if (disposed) return;
disposed = true;
console.log = rawConsoleLog;
};
}
async function prepareClientConnection(workspaceUri, severity, options) {
const up = new TestStream();
const down = new TestStream();
const logger = new NullLogger();
const clientConnection = createProtocolConnection(
new StreamMessageReader(down),
new StreamMessageWriter(up),
logger
);
const serverConnection = createConnection(
new StreamMessageReader(up),
new StreamMessageWriter(down)
);
serverConnection.sendDiagnostics = async (publishDiagnostics) => {
var _a, _b;
disposeSuppressConsole == null ? void 0 : disposeSuppressConsole();
if (publishDiagnostics.version === -1 /* init */) {
return;
}
const absFilePath = URI.parse(publishDiagnostics.uri).fsPath;
publishDiagnostics.diagnostics = filterDiagnostics(
publishDiagnostics.diagnostics,
severity
);
const nextDiagnosticInFile = await normalizePublishDiagnosticParams(publishDiagnostics);
fileDiagnosticManager.updateByFileId(absFilePath, nextDiagnosticInFile);
const normalized = fileDiagnosticManager.getDiagnostics();
const errorCount = normalized.filter(
(d) => d.level === DiagnosticSeverity.Error
).length;
const warningCount = normalized.filter(
(d) => d.level === DiagnosticSeverity.Warning
).length;
initialVueFilesTick++;
if (initialVueFilesTick >= initialVueFilesCount) {
(_a = options.onDispatchDiagnostics) == null ? void 0 : _a.call(options, normalized);
(_b = options.onDispatchDiagnosticsSummary) == null ? void 0 : _b.call(options, errorCount, warningCount);
}
};
const vls = new VLS(serverConnection);
vls.validateTextDocument = async (textDocument, cancellationToken) => {
const diagnostics2 = await vls.doValidate(textDocument, cancellationToken);
if (diagnostics2) {
vls.lspConnection.sendDiagnostics({
uri: textDocument.uri,
version: textDocument.version,
diagnostics: diagnostics2
});
}
};
serverConnection.onInitialize(
async (params) => {
await vls.init(params);
if (options.verbose) {
console.log("Vetur initialized");
console.log("====================================");
}
return {
capabilities: vls.capabilities
};
}
);
vls.listen();
clientConnection.listen();
const initParams = getInitParams(workspaceUri);
if (options.config) {
mergeDeep(initParams.initializationOptions.config, options.config);
}
await clientConnection.sendRequest(InitializeRequest.type, initParams);
return { clientConnection, serverConnection, vls, up, down, logger };
}
function extToGlobs(exts) {
return exts.map((e) => `**/*${e}`);
}
const watchedDidChangeContent = [".vue"];
const watchedDidChangeWatchedFiles = [".js", ".ts", ".json"];
const watchedDidChangeContentGlob = extToGlobs(watchedDidChangeContent);
async function getDiagnostics(workspaceUri, severity, options) {
const { clientConnection } = await prepareClientConnection(
workspaceUri,
severity,
options
);
const files = globSync([...watchedDidChangeContentGlob], {
cwd: workspaceUri.fsPath,
ignore: ["node_modules/**"]
});
if (files.length === 0) {
console.log("[VLS checker] No input files");
return { initialWarningCount: 0, initialErrorCount: 0 };
}
if (options.verbose) {
console.log("");
console.log("Getting diagnostics from: ", files, "\n");
}
const absFilePaths = files.map((f) => path.resolve(workspaceUri.fsPath, f));
disposeSuppressConsole = suppressConsole();
initialVueFilesCount = absFilePaths.length;
let initialErrorCount = 0;
let initialWarningCount = 0;
await Promise.all(
absFilePaths.map(async (absFilePath) => {
const fileText = await fs.promises.readFile(absFilePath, "utf-8");
clientConnection.sendNotification(DidOpenTextDocumentNotification.type, {
textDocument: {
languageId: "vue",
uri: URI.file(absFilePath).toString(),
version: -1 /* init */,
text: fileText
}
});
if (options.watch) return;
try {
let diagnostics2 = await clientConnection.sendRequest(
"$/getDiagnostics",
{
uri: URI.file(absFilePath).toString(),
version: -1 /* init */
}
);
diagnostics2 = filterDiagnostics(diagnostics2, severity);
let logChunk = "";
if (diagnostics2.length > 0) {
logChunk += os.EOL + diagnostics2.map(
(d) => diagnosticToTerminalLog(
normalizeLspDiagnostic({
diagnostic: d,
absFilePath,
fileText
}),
"VLS"
)
).join(os.EOL);
for (const d of diagnostics2) {
if (d.severity === DiagnosticSeverity.Error) {
initialErrorCount++;
}
if (d.severity === DiagnosticSeverity.Warning) {
initialWarningCount++;
}
}
}
console.log(logChunk);
return { initialErrorCount, initialWarningCount };
} catch (err) {
console.error(err.stack);
return { initialErrorCount, initialWarningCount };
}
})
);
if (!options.watch) {
return { initialErrorCount, initialWarningCount };
}
await Promise.all(
absFilePaths.map(async (absFilePath) => {
const fileText = await fs.promises.readFile(absFilePath, "utf-8");
clientConnection.sendNotification(DidOpenTextDocumentNotification.type, {
textDocument: {
languageId: "vue",
uri: URI.file(absFilePath).toString(),
version: -1 /* init */,
text: fileText
}
});
})
);
const watcher = chokidar.watch([], {
ignored: (path2) => path2.includes("node_modules")
});
watcher.add(workspaceUri.fsPath);
watcher.on("all", async (event, filePath) => {
const extname = path.extname(filePath);
if (!filePath.endsWith(".vue")) return;
const fileContent = await fs.promises.readFile(filePath, "utf-8");
clientConnection.sendNotification(DidChangeTextDocumentNotification.type, {
textDocument: {
uri: URI.file(filePath).toString(),
version: Date.now()
},
contentChanges: [{ text: fileContent }]
});
if (watchedDidChangeWatchedFiles.includes(extname)) {
clientConnection.sendNotification(
DidChangeWatchedFilesNotification.type,
{
changes: [
{
uri: URI.file(filePath).toString(),
type: event === "add" ? 1 : event === "unlink" ? 3 : 2
}
]
}
);
}
});
return null;
}
function isObject(item) {
return item && typeof item === "object" && !Array.isArray(item);
}
function mergeDeep(target, source) {
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return target;
}
function filterDiagnostics(diagnostics2, severity) {
return diagnostics2.filter((r) => r.source !== "eslint-plugin-vue").filter((r) => r.severity && r.severity <= severity);
}
export {
TestStream,
diagnostics,
logLevel2Severity,
logLevels,
prepareClientConnection
};
//# sourceMappingURL=diagnostics.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,72 @@
import { InitializeParams } from 'vscode-languageserver/node';
import { URI } from 'vscode-uri';
type VlsOptions = ReturnType<typeof getDefaultVLSConfig>;
declare function getInitParams(workspaceUri: URI): InitializeParams;
declare function getDefaultVLSConfig(): {
vetur: {
ignoreProjectWarning: boolean;
useWorkspaceDependencies: boolean;
validation: {
template: boolean;
templateProps: boolean;
interpolation: boolean;
style: boolean;
script: boolean;
};
completion: {
autoImport: boolean;
tagCasing: string;
scaffoldSnippetSources: {
workspace: string;
user: string;
vetur: string;
};
};
grammar: {
customBlocks: {};
};
format: {
enable: boolean;
options: {
tabSize: number;
useTabs: boolean;
};
defaultFormatter: {};
defaultFormatterOptions: {};
scriptInitialIndent: boolean;
styleInitialIndent: boolean;
};
languageFeatures: {
codeActions: boolean;
updateImportOnFileMove: boolean;
semanticTokens: boolean;
};
trace: {
server: string;
};
dev: {
vlsPath: string;
vlsPort: number;
logLevel: string;
};
experimental: {
templateInterpolationService: boolean;
};
};
css: {};
html: {
suggest: {};
};
javascript: {
format: {};
};
typescript: {
tsdk: null;
format: {};
};
emmet: {};
stylusSupremacy: {};
};
export { type VlsOptions, getDefaultVLSConfig, getInitParams };

View File

@@ -0,0 +1,95 @@
function getInitParams(workspaceUri) {
const defaultVLSConfig = getDefaultVLSConfig();
defaultVLSConfig.vetur.validation = {
template: true,
style: true,
script: true,
interpolation: true,
templateProps: true
};
defaultVLSConfig.vetur.experimental = {
templateInterpolationService: true
};
const init = {
rootPath: workspaceUri.fsPath,
rootUri: workspaceUri.toString(),
processId: process.pid,
capabilities: {},
initializationOptions: {
config: defaultVLSConfig
}
};
return init;
}
function getDefaultVLSConfig() {
return {
vetur: {
ignoreProjectWarning: false,
useWorkspaceDependencies: false,
validation: {
template: true,
templateProps: true,
interpolation: true,
style: true,
script: true
},
completion: {
autoImport: false,
tagCasing: "initial",
scaffoldSnippetSources: {
workspace: "\u{1F4BC}",
user: "\u{1F5D2}\uFE0F",
vetur: "\u270C"
}
},
grammar: {
customBlocks: {}
},
format: {
enable: true,
options: {
tabSize: 2,
useTabs: false
},
defaultFormatter: {},
defaultFormatterOptions: {},
scriptInitialIndent: false,
styleInitialIndent: false
},
languageFeatures: {
codeActions: true,
updateImportOnFileMove: true,
semanticTokens: true
},
trace: {
server: "off"
},
dev: {
vlsPath: "",
vlsPort: -1,
logLevel: "INFO"
},
experimental: {
templateInterpolationService: false
}
},
css: {},
html: {
suggest: {}
},
javascript: {
format: {}
},
typescript: {
tsdk: null,
format: {}
},
emmet: {},
stylusSupremacy: {}
};
}
export {
getDefaultVLSConfig,
getInitParams
};
//# sourceMappingURL=initParams.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/vls/initParams.ts"],"sourcesContent":["import type { InitializeParams } from 'vscode-languageserver/node'\nimport type { URI } from 'vscode-uri'\n\nexport type VlsOptions = ReturnType<typeof getDefaultVLSConfig>\n\nexport function getInitParams(workspaceUri: URI): InitializeParams {\n const defaultVLSConfig = getDefaultVLSConfig()\n\n defaultVLSConfig.vetur.validation = {\n template: true,\n style: true,\n script: true,\n interpolation: true,\n templateProps: true,\n }\n defaultVLSConfig.vetur.experimental = {\n templateInterpolationService: true,\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const init: InitializeParams = {\n rootPath: workspaceUri.fsPath,\n rootUri: workspaceUri.toString(),\n processId: process.pid,\n capabilities: {},\n initializationOptions: {\n config: defaultVLSConfig,\n },\n } as InitializeParams\n\n return init\n}\n\nexport function getDefaultVLSConfig() {\n return {\n vetur: {\n ignoreProjectWarning: false,\n useWorkspaceDependencies: false,\n validation: {\n template: true,\n templateProps: true,\n interpolation: true,\n style: true,\n script: true,\n },\n completion: {\n autoImport: false,\n tagCasing: 'initial',\n scaffoldSnippetSources: {\n workspace: '💼',\n user: '🗒️',\n vetur: '✌',\n },\n },\n grammar: {\n customBlocks: {},\n },\n format: {\n enable: true,\n options: {\n tabSize: 2,\n useTabs: false,\n },\n defaultFormatter: {},\n defaultFormatterOptions: {},\n scriptInitialIndent: false,\n styleInitialIndent: false,\n },\n languageFeatures: {\n codeActions: true,\n updateImportOnFileMove: true,\n semanticTokens: true,\n },\n trace: {\n server: 'off',\n },\n dev: {\n vlsPath: '',\n vlsPort: -1,\n logLevel: 'INFO',\n },\n experimental: {\n templateInterpolationService: false,\n },\n },\n css: {},\n html: {\n suggest: {},\n },\n javascript: {\n format: {},\n },\n typescript: {\n tsdk: null,\n format: {},\n },\n emmet: {},\n stylusSupremacy: {},\n }\n}\n"],"mappings":"AAKO,SAAS,cAAc,cAAqC;AACjE,QAAM,mBAAmB,oBAAoB;AAE7C,mBAAiB,MAAM,aAAa;AAAA,IAClC,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,eAAe;AAAA,EACjB;AACA,mBAAiB,MAAM,eAAe;AAAA,IACpC,8BAA8B;AAAA,EAChC;AAGA,QAAM,OAAyB;AAAA,IAC7B,UAAU,aAAa;AAAA,IACvB,SAAS,aAAa,SAAS;AAAA,IAC/B,WAAW,QAAQ;AAAA,IACnB,cAAc,CAAC;AAAA,IACf,uBAAuB;AAAA,MACrB,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,sBAAsB;AACpC,SAAO;AAAA,IACL,OAAO;AAAA,MACL,sBAAsB;AAAA,MACtB,0BAA0B;AAAA,MAC1B,YAAY;AAAA,QACV,UAAU;AAAA,QACV,eAAe;AAAA,QACf,eAAe;AAAA,QACf,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MACA,YAAY;AAAA,QACV,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,wBAAwB;AAAA,UACtB,WAAW;AAAA,UACX,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP,cAAc,CAAC;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,QACA,kBAAkB,CAAC;AAAA,QACnB,yBAAyB,CAAC;AAAA,QAC1B,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,MACtB;AAAA,MACA,kBAAkB;AAAA,QAChB,aAAa;AAAA,QACb,wBAAwB;AAAA,QACxB,gBAAgB;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,QACL,QAAQ;AAAA,MACV;AAAA,MACA,KAAK;AAAA,QACH,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MACA,cAAc;AAAA,QACZ,8BAA8B;AAAA,MAChC;AAAA,IACF;AAAA,IACA,KAAK,CAAC;AAAA,IACN,MAAM;AAAA,MACJ,SAAS,CAAC;AAAA,IACZ;AAAA,IACA,YAAY;AAAA,MACV,QAAQ,CAAC;AAAA,IACX;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,IACX;AAAA,IACA,OAAO,CAAC;AAAA,IACR,iBAAiB,CAAC;AAAA,EACpB;AACF;","names":[]}

View File

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

View File

@@ -0,0 +1,103 @@
import { fileURLToPath } from "node:url";
import { parentPort } from "node:worker_threads";
import { Checker } from "../../Checker.js";
import {
composeCheckerSummary,
consoleLog,
diagnosticToConsoleLevel,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
toClientPayload
} from "../../logger.js";
import { ACTION_TYPES } from "../../types.js";
import { diagnostics } from "./diagnostics.js";
const __filename = fileURLToPath(import.meta.url);
let createServeAndBuild;
const createDiagnostic = (pluginConfig) => {
let overlay = true;
let terminal = true;
let command;
return {
config: ({ enableOverlay, enableTerminal, env }) => {
overlay = enableOverlay;
terminal = enableTerminal;
command = env.command;
},
async configureServer({ root }) {
const workDir = root;
const onDispatchDiagnosticsSummary = (errorCount, warningCount) => {
if (!terminal) return;
consoleLog(
composeCheckerSummary("VLS", errorCount, warningCount),
errorCount ? "error" : warningCount ? "warn" : "info"
);
};
const onDispatchDiagnostics = (normalized) => {
var _a;
if (overlay && command === "serve") {
(_a = parentPort) == null ? void 0 : _a.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload(
"vls",
diagnosticToRuntimeError(normalized)
)
});
}
if (terminal) {
for (const d of normalized) {
consoleLog(
diagnosticToTerminalLog(d, "VLS"),
diagnosticToConsoleLevel(d)
);
}
}
};
const vlsConfig = pluginConfig == null ? void 0 : pluginConfig.vls;
await diagnostics(workDir, "WARN", {
onDispatchDiagnostics,
onDispatchDiagnosticsSummary,
watch: true,
verbose: false,
config: typeof vlsConfig === "object" ? vlsConfig : null
});
}
};
};
class VlsChecker extends Checker {
constructor() {
super({
name: "vls",
absFilePath: __filename,
build: {
buildBin: (config) => {
if (typeof config.vls === "object") {
return [
"vti",
[
"diagnostics",
// Escape quotes so that the system shell doesn't strip them out:
`"${JSON.stringify(config.vls).replace(/[\\"]/g, "\\$&")}"`
]
];
}
return ["vti", ["diagnostics"]];
}
},
createDiagnostic
});
}
init() {
const _createServeAndBuild = super.initMainThread();
createServeAndBuild = _createServeAndBuild;
super.initWorkerThread();
}
}
const vlsChecker = new VlsChecker();
vlsChecker.prepare();
vlsChecker.init();
export {
VlsChecker,
createDiagnostic,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/checkers/vls/main.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\nimport { parentPort } from 'node:worker_threads'\nimport type { ConfigEnv } from 'vite'\nimport { Checker } from '../../Checker.js'\nimport {\n composeCheckerSummary,\n consoleLog,\n diagnosticToConsoleLevel,\n diagnosticToRuntimeError,\n diagnosticToTerminalLog,\n toClientPayload,\n} from '../../logger.js'\nimport type { CreateDiagnostic } from '../../types.js'\nimport { ACTION_TYPES } from '../../types.js'\nimport { type DiagnosticOptions, diagnostics } from './diagnostics.js'\n\nconst __filename = fileURLToPath(import.meta.url)\n\nlet createServeAndBuild: any\n\nexport const createDiagnostic: CreateDiagnostic<'vls'> = (pluginConfig) => {\n let overlay = true\n let terminal = true\n let command: ConfigEnv['command']\n\n return {\n config: ({ enableOverlay, enableTerminal, env }) => {\n overlay = enableOverlay\n terminal = enableTerminal\n command = env.command\n },\n async configureServer({ root }) {\n const workDir: string = root\n\n const onDispatchDiagnosticsSummary: DiagnosticOptions['onDispatchDiagnosticsSummary'] =\n (errorCount, warningCount) => {\n if (!terminal) return\n\n consoleLog(\n composeCheckerSummary('VLS', errorCount, warningCount),\n errorCount ? 'error' : warningCount ? 'warn' : 'info',\n )\n }\n\n const onDispatchDiagnostics: DiagnosticOptions['onDispatchDiagnostics'] =\n (normalized) => {\n if (overlay && command === 'serve') {\n parentPort?.postMessage({\n type: ACTION_TYPES.overlayError,\n payload: toClientPayload(\n 'vls',\n diagnosticToRuntimeError(normalized),\n ),\n })\n }\n\n if (terminal) {\n for (const d of normalized) {\n consoleLog(\n diagnosticToTerminalLog(d, 'VLS'),\n diagnosticToConsoleLevel(d),\n )\n }\n }\n }\n\n const vlsConfig = pluginConfig?.vls\n await diagnostics(workDir, 'WARN', {\n onDispatchDiagnostics,\n onDispatchDiagnosticsSummary,\n watch: true,\n verbose: false,\n config: typeof vlsConfig === 'object' ? vlsConfig : null,\n })\n },\n }\n}\n\nexport class VlsChecker extends Checker<'vls'> {\n public constructor() {\n super({\n name: 'vls',\n absFilePath: __filename,\n build: {\n buildBin: (config) => {\n if (typeof config.vls === 'object') {\n return [\n 'vti',\n [\n 'diagnostics',\n // Escape quotes so that the system shell doesn't strip them out:\n `\"${JSON.stringify(config.vls).replace(/[\\\\\"]/g, '\\\\$&')}\"`,\n ],\n ]\n }\n\n return ['vti', ['diagnostics']]\n },\n },\n createDiagnostic,\n })\n }\n\n public init() {\n const _createServeAndBuild = super.initMainThread()\n createServeAndBuild = _createServeAndBuild\n super.initWorkerThread()\n }\n}\n\nexport { createServeAndBuild }\nconst vlsChecker = new VlsChecker()\nvlsChecker.prepare()\nvlsChecker.init()\n"],"mappings":"AAAA,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAE3B,SAAS,eAAe;AACxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,oBAAoB;AAC7B,SAAiC,mBAAmB;AAEpD,MAAM,aAAa,cAAc,YAAY,GAAG;AAEhD,IAAI;AAEG,MAAM,mBAA4C,CAAC,iBAAiB;AACzE,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI;AAEJ,SAAO;AAAA,IACL,QAAQ,CAAC,EAAE,eAAe,gBAAgB,IAAI,MAAM;AAClD,gBAAU;AACV,iBAAW;AACX,gBAAU,IAAI;AAAA,IAChB;AAAA,IACA,MAAM,gBAAgB,EAAE,KAAK,GAAG;AAC9B,YAAM,UAAkB;AAExB,YAAM,+BACJ,CAAC,YAAY,iBAAiB;AAC5B,YAAI,CAAC,SAAU;AAEf;AAAA,UACE,sBAAsB,OAAO,YAAY,YAAY;AAAA,UACrD,aAAa,UAAU,eAAe,SAAS;AAAA,QACjD;AAAA,MACF;AAEF,YAAM,wBACJ,CAAC,eAAe;AA7CxB;AA8CU,YAAI,WAAW,YAAY,SAAS;AAClC,kDAAY,YAAY;AAAA,YACtB,MAAM,aAAa;AAAA,YACnB,SAAS;AAAA,cACP;AAAA,cACA,yBAAyB,UAAU;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAEA,YAAI,UAAU;AACZ,qBAAW,KAAK,YAAY;AAC1B;AAAA,cACE,wBAAwB,GAAG,KAAK;AAAA,cAChC,yBAAyB,CAAC;AAAA,YAC5B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEF,YAAM,YAAY,6CAAc;AAChC,YAAM,YAAY,SAAS,QAAQ;AAAA,QACjC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ,OAAO,cAAc,WAAW,YAAY;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,MAAM,mBAAmB,QAAe;AAAA,EACtC,cAAc;AACnB,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,QACL,UAAU,CAAC,WAAW;AACpB,cAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,mBAAO;AAAA,cACL;AAAA,cACA;AAAA,gBACE;AAAA;AAAA,gBAEA,IAAI,KAAK,UAAU,OAAO,GAAG,EAAE,QAAQ,UAAU,MAAM,CAAC;AAAA,cAC1D;AAAA,YACF;AAAA,UACF;AAEA,iBAAO,CAAC,OAAO,CAAC,aAAa,CAAC;AAAA,QAChC;AAAA,MACF;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEO,OAAO;AACZ,UAAM,uBAAuB,MAAM,eAAe;AAClD,0BAAsB;AACtB,UAAM,iBAAiB;AAAA,EACzB;AACF;AAGA,MAAM,aAAa,IAAI,WAAW;AAClC,WAAW,QAAQ;AACnB,WAAW,KAAK;","names":[]}

View File

@@ -0,0 +1,2 @@
export { }

View File

@@ -0,0 +1 @@
//# sourceMappingURL=typings.d.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}

View File

@@ -0,0 +1,57 @@
const path = require('node:path')
const vueTscDir = path.dirname(require.resolve('vue-tsc/package.json'))
const vue =
/** @type {typeof import('@vue/language-core') & { resolveVueCompilerOptions?: any }} */ (
require(require.resolve('@vue/language-core', { paths: [vueTscDir] }))
)
const windowsPathReg = /\\/g
const removeEmitGlobalTypesRegexp =
/^[^\n]*__VLS_globalTypesStart[\w\W]*__VLS_globalTypesEnd[^\n]*\n?$/gm
/**
* @param dts {string}
* @returns {string}
*/
function removeEmitGlobalTypes(dts) {
return dts.replace(removeEmitGlobalTypesRegexp, '')
}
const getDefaultCompilerOptions =
vue.getDefaultCompilerOptions || (() => vue.resolveVueCompilerOptions({}))
// #region copied from https://github.com/vuejs/language-tools/blob/0781998a29f176ad52c30d3139d5c78a5688bd5d/packages/tsc/index.ts
/**
* @param {typeof import('typescript')} ts
* @param {import('typescript').CreateProgramOptions} options
*/
exports.getLanguagePlugins = (ts, options) => {
const { configFilePath } = options.options
const vueOptions =
typeof configFilePath === 'string'
? vue.createParsedCommandLine(
ts,
ts.sys,
configFilePath.replace(windowsPathReg, '/'),
).vueOptions
: getDefaultCompilerOptions()
if (vue.writeGlobalTypes) {
vue.writeGlobalTypes(vueOptions, ts.sys.writeFile)
} else {
const host = /** @type {import('typescript').CompilerHost} */ (options.host)
const writeFile = host.writeFile.bind(host)
host.writeFile = (fileName, contents, ...args) => {
return writeFile(fileName, removeEmitGlobalTypes(contents), ...args)
}
}
const vueLanguagePlugin = vue.createVueLanguagePlugin(
ts,
options.options,
vueOptions,
(id) => id,
)
return [vueLanguagePlugin]
}
// #endregion

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 VueTscChecker extends Checker<'vueTsc'> {
constructor();
init(): void;
}
export { VueTscChecker, createServeAndBuild };

View File

@@ -0,0 +1,160 @@
import { createRequire } from "node:module";
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parentPort } from "node:worker_threads";
import invariant from "tiny-invariant";
import { Checker } from "../../Checker.js";
import {
consoleLog,
diagnosticToRuntimeError,
diagnosticToTerminalLog,
ensureCall,
normalizeVueTscDiagnostic,
toClientPayload,
wrapCheckerSummary
} from "../../logger.js";
import {
ACTION_TYPES
} from "../../types.js";
import { prepareVueTsc } from "./prepareVueTsc.js";
const _require = createRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
let createServeAndBuild;
const createDiagnostic = (pluginConfig) => {
let overlay = true;
let terminal = true;
let currDiagnostics = [];
return {
config: ({ enableOverlay, enableTerminal }) => {
overlay = enableOverlay;
terminal = enableTerminal;
},
async configureServer({ root }) {
invariant(pluginConfig.vueTsc, "config.vueTsc should be `false`");
const { targetTsDir } = await prepareVueTsc();
const vueTs = _require(path.resolve(targetTsDir, "lib/typescript.js"));
const finalConfig = pluginConfig.vueTsc === true ? { root, tsconfigPath: "tsconfig.json" } : {
root: pluginConfig.vueTsc.root ?? root,
tsconfigPath: pluginConfig.vueTsc.tsconfigPath ?? "tsconfig.json"
};
const configFile = vueTs.findConfigFile(
finalConfig.root,
vueTs.sys.fileExists,
finalConfig.tsconfigPath
);
if (configFile === void 0) {
throw Error(
`Failed to find a valid tsconfig.json: ${finalConfig.tsconfigPath} at ${finalConfig.root} is not a valid tsconfig`
);
}
let logChunk = "";
let prevLogChunk = "";
const reportDiagnostic = (diagnostic) => {
const normalizedDiagnostic = normalizeVueTscDiagnostic(diagnostic);
if (normalizedDiagnostic === null) {
return;
}
currDiagnostics.push(diagnosticToRuntimeError(normalizedDiagnostic));
logChunk += os.EOL + diagnosticToTerminalLog(normalizedDiagnostic, "vue-tsc");
};
const reportWatchStatusChanged = (diagnostic, _newLine, _options, errorCount) => {
var _a;
if (diagnostic.code === 6031) return;
switch (diagnostic.code) {
case 6031:
case 6032:
logChunk = "";
currDiagnostics = [];
return;
case 6193:
// 1 Error
case 6194:
if (overlay) {
(_a = parentPort) == null ? void 0 : _a.postMessage({
type: ACTION_TYPES.overlayError,
payload: toClientPayload("vue-tsc", currDiagnostics)
});
}
}
ensureCall(() => {
if (errorCount === 0) {
logChunk = "";
}
if (terminal) {
logChunk = logChunk + os.EOL + wrapCheckerSummary("vue-tsc", diagnostic.messageText.toString());
if (logChunk === prevLogChunk) {
return;
}
prevLogChunk = logChunk;
consoleLog(logChunk, errorCount ? "error" : "info");
}
});
};
const createProgram = vueTs.createEmitAndSemanticDiagnosticsBuilderProgram;
if (typeof pluginConfig.vueTsc === "object" && pluginConfig.vueTsc.buildMode) {
const host = vueTs.createSolutionBuilderWithWatchHost(
vueTs.sys,
createProgram,
reportDiagnostic,
void 0,
reportWatchStatusChanged
);
vueTs.createSolutionBuilderWithWatch(host, [configFile], {}).build();
} else {
const host = vueTs.createWatchCompilerHost(
configFile,
{ noEmit: true },
vueTs.sys,
createProgram,
reportDiagnostic,
reportWatchStatusChanged
);
vueTs.createWatchProgram(host);
}
}
};
};
class VueTscChecker extends Checker {
constructor() {
super({
name: "vueTsc",
absFilePath: __filename,
build: {
buildBin: (config) => {
if (typeof config.vueTsc === "object") {
const { root = "", tsconfigPath = "", buildMode } = config.vueTsc;
const args = [buildMode ? "-b" : "--noEmit"];
let projectPath = "";
if (root || tsconfigPath) {
projectPath = root ? path.join(root, tsconfigPath) : tsconfigPath;
}
if (projectPath) {
if (buildMode) {
args.push(projectPath);
} else {
args.push("-p", projectPath);
}
}
return ["vue-tsc", args];
}
return ["vue-tsc", ["--noEmit"]];
}
},
createDiagnostic
});
}
init() {
const _createServeAndBuild = super.initMainThread();
createServeAndBuild = _createServeAndBuild;
super.initWorkerThread();
}
}
const tscChecker = new VueTscChecker();
tscChecker.prepare();
tscChecker.init();
export {
VueTscChecker,
createServeAndBuild
};
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
declare function prepareVueTsc(): Promise<{
targetTsDir: string;
}>;
export { prepareVueTsc };

View File

@@ -0,0 +1,108 @@
import { access, cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
import { createRequire } from "node:module";
import path, { dirname } from "node:path";
import { fileURLToPath } from "node:url";
const _require = createRequire(import.meta.url);
const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename);
const vueTscDir = dirname(_require.resolve("vue-tsc/package.json"));
const proxyApiPath = _require.resolve(
"@volar/typescript/lib/node/proxyCreateProgram",
{
paths: [vueTscDir]
}
);
const extraSupportedExtensions = [".vue"];
async function prepareVueTsc() {
const targetTsDir = path.resolve(_dirname, "typescript-vue-tsc");
const vueTscFlagFile = path.resolve(targetTsDir, "vue-tsc-resolve-path");
const currTsVersion = _require("typescript/package.json").version;
const tsMajorVersion = Number(currTsVersion.split(".")[0]);
if (tsMajorVersion < 5) {
throw new Error(
"\x1B[35m[vite-plugin-checker] Since 0.7.0, vue-tsc checkers requires TypeScript 5.0.0 or newer version.\nPlease upgrade TypeScript, or use v0.6.4 which works with vue-tsc^1 if you can't upgrade. Check the pull request https://github.com/fi3ework/vite-plugin-checker/pull/327 for detail.\x1B[39m\n"
);
}
let shouldBuildFixture = true;
try {
await access(targetTsDir);
const targetTsVersion = _require(
path.resolve(targetTsDir, "package.json")
).version;
await access(vueTscFlagFile);
const fixtureFlagContent = await readFile(vueTscFlagFile, "utf8");
if (targetTsVersion === currTsVersion && fixtureFlagContent === proxyApiPath) {
shouldBuildFixture = false;
}
} catch {
shouldBuildFixture = true;
}
if (shouldBuildFixture) {
await rm(targetTsDir, { force: true, recursive: true });
await mkdir(targetTsDir, { recursive: true });
const sourceTsDir = path.resolve(_require.resolve("typescript"), "../..");
await cp(sourceTsDir, targetTsDir, { recursive: true });
await writeFile(vueTscFlagFile, proxyApiPath);
await overrideTscJs(
_require.resolve(path.resolve(targetTsDir, "lib/typescript.js"))
);
}
return { targetTsDir };
}
async function overrideTscJs(tscJsPath) {
const languagePluginsFile = path.resolve(_dirname, "languagePlugins.cjs");
let tsc = await readFile(tscJsPath, "utf8");
const extsText = extraSupportedExtensions.map((ext) => `"${ext}"`).join(", ");
tsc = replace(
tsc,
/supportedTSExtensions = .*(?=;)/,
(s) => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`
);
tsc = replace(
tsc,
/supportedJSExtensions = .*(?=;)/,
(s) => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`
);
tsc = replace(
tsc,
/allSupportedExtensions = .*(?=;)/,
(s) => s + `.map((group, i) => i === 0 ? group.splice(0, 0, ${extsText}) && group : group)`
);
const extsText2 = extraSupportedExtensions.map((ext) => `"${ext}"`).join(", ");
tsc = replace(
tsc,
/function changeExtension\(/,
(s) => `function changeExtension(path, newExtension) {
return [${extsText2}].some(ext => path.endsWith(ext))
? path + newExtension
: _changeExtension(path, newExtension)
}
${s.replace("changeExtension", "_changeExtension")}`
);
tsc = replace(
tsc,
/function createProgram\(.+\) {/,
(s) => `var createProgram = require(${JSON.stringify(
proxyApiPath
)}).proxyCreateProgram(${[
"new Proxy({}, { get(_target, p, _receiver) { return eval(p); } } )",
"_createProgram",
`require(${JSON.stringify(languagePluginsFile)}).getLanguagePlugins`
].join(", ")});
${s.replace("createProgram", "_createProgram")}`
);
function replace(_text, ...[search, replace2]) {
const before = _text;
const text = _text.replace(search, replace2);
const after = text;
if (after === before) {
throw `Search string not found: ${JSON.stringify(search.toString())}`;
}
return after;
}
await writeFile(tscJsPath, tsc);
}
export {
prepareVueTsc
};
//# sourceMappingURL=prepareVueTsc.js.map

File diff suppressed because one or more lines are too long