mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-12-29 03:20:46 +08:00
Merge branch 'master' into bye-jquery-all-other-pages
This commit is contained in:
commit
cd38248e3c
9 changed files with 504 additions and 98 deletions
|
|
@ -91,7 +91,6 @@
|
|||
"unplugin-inject-preload": "3.0.0",
|
||||
"vite": "7.1.12",
|
||||
"vite-bundle-visualizer": "1.2.1",
|
||||
"vite-plugin-checker": "0.11.0",
|
||||
"vite-plugin-filter-replace": "0.1.14",
|
||||
"vite-plugin-html-inject": "1.1.2",
|
||||
"vite-plugin-inspect": "11.3.3",
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@
|
|||
<div class="buttons">
|
||||
<button data-config-value="false">off</button>
|
||||
<button data-config-value="true">
|
||||
⠀
|
||||
 
|
||||
<!-- On is missing on purpose. -->
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export function show(action: string, id?: string, name?: string): void {
|
|||
$("#editPresetModal .modal .text").addClass("hidden");
|
||||
addCheckBoxes();
|
||||
presetNameEl ??= new ValidatedHtmlInputElement(
|
||||
qsr("#editPresetModal .modal input"),
|
||||
qsr("#editPresetModal .modal input[type=text]"),
|
||||
{
|
||||
schema: PresetNameSchema,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1212,7 +1212,7 @@ list.devGenerateData = new SimpleModal({
|
|||
const span = document.querySelector(
|
||||
"#devGenerateData_1 + span",
|
||||
) as HTMLInputElement;
|
||||
span.innerHTML = `if checked, user will be created with ${target.value}@example.com and password: password`;
|
||||
span.innerText = `if checked, user will be created with ${target.value}@example.com and password: password`;
|
||||
return;
|
||||
},
|
||||
validation: {
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ export class Caret {
|
|||
if (options.letterIndex >= letters.length) {
|
||||
side = "afterLetter";
|
||||
|
||||
if (Config.blindMode) {
|
||||
if (Config.blindMode || Config.hideExtraLetters) {
|
||||
options.letterIndex = wordText?.length - 1;
|
||||
} else {
|
||||
options.letterIndex = letters.length - 1;
|
||||
|
|
|
|||
312
frontend/vite-plugins/oxlint-checker.ts
Normal file
312
frontend/vite-plugins/oxlint-checker.ts
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
import { Plugin, ViteDevServer, normalizePath } from "vite";
|
||||
import { spawn, execSync, ChildProcess } from "child_process";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
export type OxlintCheckerOptions = {
|
||||
/** Debounce delay in milliseconds before running lint after file changes. @default 125 */
|
||||
debounceDelay?: number;
|
||||
/** Run type-aware checks (slower but more thorough). @default true */
|
||||
typeAware?: boolean;
|
||||
/** Show browser overlay with lint status. @default true */
|
||||
overlay?: boolean;
|
||||
/** File extensions to watch for changes. @default ['.ts', '.tsx', '.js', '.jsx'] */
|
||||
extensions?: string[];
|
||||
};
|
||||
|
||||
type LintResult = {
|
||||
errorCount: number;
|
||||
warningCount: number;
|
||||
running: boolean;
|
||||
hadIssues: boolean;
|
||||
typeAware?: boolean;
|
||||
};
|
||||
|
||||
const OXLINT_SUMMARY_REGEX = /Found (\d+) warnings? and (\d+) errors?/;
|
||||
|
||||
export function oxlintChecker(options: OxlintCheckerOptions = {}): Plugin {
|
||||
const {
|
||||
debounceDelay = 125,
|
||||
typeAware = true,
|
||||
overlay = true,
|
||||
extensions = [".ts", ".tsx", ".js", ".jsx"],
|
||||
} = options;
|
||||
|
||||
let currentProcess: ChildProcess | null = null;
|
||||
let debounceTimer: NodeJS.Timeout | null = null;
|
||||
let server: ViteDevServer | null = null;
|
||||
let isProduction = false;
|
||||
let currentRunId = 0;
|
||||
let lastLintResult: LintResult = {
|
||||
errorCount: 0,
|
||||
warningCount: 0,
|
||||
running: false,
|
||||
hadIssues: false,
|
||||
};
|
||||
|
||||
const killCurrentProcess = (): boolean => {
|
||||
if ((currentProcess && !currentProcess.killed) || currentProcess !== null) {
|
||||
currentProcess.kill();
|
||||
currentProcess = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const clearDebounceTimer = (): void => {
|
||||
if (debounceTimer) {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
const parseLintOutput = (
|
||||
output: string,
|
||||
): Pick<LintResult, "errorCount" | "warningCount"> => {
|
||||
const summaryMatch = output.match(OXLINT_SUMMARY_REGEX);
|
||||
if (summaryMatch?.[1] !== undefined && summaryMatch?.[2] !== undefined) {
|
||||
return {
|
||||
warningCount: parseInt(summaryMatch[1], 10),
|
||||
errorCount: parseInt(summaryMatch[2], 10),
|
||||
};
|
||||
}
|
||||
return { errorCount: 0, warningCount: 0 };
|
||||
};
|
||||
|
||||
const sendLintResult = (result: Partial<LintResult>): void => {
|
||||
const previousHadIssues = lastLintResult.hadIssues;
|
||||
|
||||
const payload: LintResult = {
|
||||
errorCount: result.errorCount ?? lastLintResult.errorCount,
|
||||
warningCount: result.warningCount ?? lastLintResult.warningCount,
|
||||
running: result.running ?? false,
|
||||
hadIssues: previousHadIssues,
|
||||
typeAware: result.typeAware,
|
||||
};
|
||||
|
||||
// Only update hadIssues when we have actual lint results (not just running status)
|
||||
if (result.running === false) {
|
||||
const currentHasIssues =
|
||||
(result.errorCount ?? 0) > 0 || (result.warningCount ?? 0) > 0;
|
||||
lastLintResult = { ...payload, hadIssues: currentHasIssues };
|
||||
} else {
|
||||
// Keep hadIssues unchanged when just updating running status
|
||||
lastLintResult = { ...payload, hadIssues: previousHadIssues };
|
||||
}
|
||||
|
||||
if (server) {
|
||||
server.ws.send("vite-plugin-oxlint", payload);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs an oxlint process with the given arguments and captures its combined output.
|
||||
*
|
||||
* This function is responsible for managing the lifecycle of the current lint process:
|
||||
* - It spawns a new child process via `npx oxlint . ...args`.
|
||||
* - It assigns the spawned process to the shared {@link currentProcess} variable so that
|
||||
* other parts of the plugin can cancel or track the active lint run.
|
||||
* - On process termination (either "error" or "close"), it clears {@link currentProcess}
|
||||
* if it still refers to this child, avoiding interference with any newer process that
|
||||
* may have started in the meantime.
|
||||
*
|
||||
* @param args Additional command-line arguments to pass to `oxlint`.
|
||||
* @returns A promise that resolves with the process exit code (or `null` if
|
||||
* the process exited due to a signal) and the full stdout/stderr output
|
||||
* produced by the lint run.
|
||||
*/
|
||||
const runLintProcess = async (
|
||||
args: string[],
|
||||
): Promise<{ code: number | null; output: string }> => {
|
||||
return new Promise((resolve) => {
|
||||
const childProcess = spawn("npx", ["oxlint", ".", ...args], {
|
||||
cwd: process.cwd(),
|
||||
shell: true,
|
||||
env: { ...process.env, FORCE_COLOR: "3" },
|
||||
});
|
||||
|
||||
currentProcess = childProcess;
|
||||
let output = "";
|
||||
|
||||
childProcess.stdout?.on("data", (data: Buffer) => {
|
||||
output += data.toString();
|
||||
});
|
||||
|
||||
childProcess.stderr?.on("data", (data: Buffer) => {
|
||||
output += data.toString();
|
||||
});
|
||||
|
||||
childProcess.on("error", (error: Error) => {
|
||||
output += `\nError: ${error.message}`;
|
||||
if (currentProcess === childProcess) {
|
||||
currentProcess = null;
|
||||
}
|
||||
resolve({ code: 1, output });
|
||||
});
|
||||
|
||||
childProcess.on("close", (code: number | null) => {
|
||||
if (currentProcess === childProcess) {
|
||||
currentProcess = null;
|
||||
}
|
||||
resolve({ code, output });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const runOxlint = async (): Promise<void> => {
|
||||
const wasKilled = killCurrentProcess();
|
||||
const runId = ++currentRunId;
|
||||
|
||||
console.log(
|
||||
wasKilled
|
||||
? "\x1b[36mRunning oxlint...\x1b[0m \x1b[90m(killed previous process)\x1b[0m"
|
||||
: "\x1b[36mRunning oxlint...\x1b[0m",
|
||||
);
|
||||
|
||||
sendLintResult({ running: true });
|
||||
|
||||
// First pass: fast oxlint without type checking
|
||||
const { code, output } = await runLintProcess([]);
|
||||
|
||||
// Check if we were superseded by a newer run
|
||||
if (runId !== currentRunId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (output) {
|
||||
console.log(output);
|
||||
}
|
||||
|
||||
// If first pass had errors, send them immediately (fast-fail)
|
||||
if (code !== 0) {
|
||||
const counts = parseLintOutput(output);
|
||||
if (counts.errorCount > 0 || counts.warningCount > 0) {
|
||||
sendLintResult({ ...counts, running: false });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// First pass clean - run type-aware check if enabled
|
||||
if (!typeAware) {
|
||||
sendLintResult({ errorCount: 0, warningCount: 0, running: false });
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("\x1b[36mRunning type-aware checks...\x1b[0m");
|
||||
sendLintResult({ running: true, typeAware: true });
|
||||
const typeResult = await runLintProcess(["--type-check", "--type-aware"]);
|
||||
|
||||
// Check if we were superseded by a newer run
|
||||
if (runId !== currentRunId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeResult.output) {
|
||||
console.log(typeResult.output);
|
||||
}
|
||||
|
||||
const counts =
|
||||
typeResult.code !== 0
|
||||
? parseLintOutput(typeResult.output)
|
||||
: { errorCount: 0, warningCount: 0 };
|
||||
sendLintResult({ ...counts, running: false });
|
||||
};
|
||||
|
||||
const debouncedLint = (): void => {
|
||||
clearDebounceTimer();
|
||||
sendLintResult({ running: true });
|
||||
debounceTimer = setTimeout(() => void runOxlint(), debounceDelay);
|
||||
};
|
||||
|
||||
return {
|
||||
name: "vite-plugin-oxlint-checker",
|
||||
|
||||
config(_, { command }) {
|
||||
isProduction = command === "build";
|
||||
},
|
||||
|
||||
configureServer(devServer: ViteDevServer) {
|
||||
server = devServer;
|
||||
|
||||
// Send current lint status to new clients on connection
|
||||
devServer.ws.on("connection", () => {
|
||||
devServer.ws.send("vite-plugin-oxlint", lastLintResult);
|
||||
});
|
||||
|
||||
// Run initial lint
|
||||
void runOxlint();
|
||||
|
||||
// Listen for file changes
|
||||
devServer.watcher.on("change", (file: string) => {
|
||||
// Only lint on relevant file changes
|
||||
if (extensions.some((ext) => file.endsWith(ext))) {
|
||||
debouncedLint();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
transformIndexHtml() {
|
||||
if (!overlay) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Inject import to the overlay module (actual .ts file processed by Vite)
|
||||
const overlayPath = normalizePath(
|
||||
fileURLToPath(new URL("./oxlint-overlay.ts", import.meta.url)),
|
||||
);
|
||||
return [
|
||||
{
|
||||
tag: "script",
|
||||
attrs: {
|
||||
type: "module",
|
||||
src: `/@fs${overlayPath}`,
|
||||
},
|
||||
injectTo: "body-prepend",
|
||||
},
|
||||
];
|
||||
},
|
||||
|
||||
buildStart() {
|
||||
// Only run during production builds, not dev server startup
|
||||
if (!isProduction) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run oxlint synchronously during build
|
||||
console.log("\n\x1b[1mRunning oxlint...\x1b[0m");
|
||||
|
||||
try {
|
||||
const output = execSync(
|
||||
"npx oxlint . && npx oxlint . --type-aware --type-check",
|
||||
{
|
||||
cwd: process.cwd(),
|
||||
encoding: "utf-8",
|
||||
env: { ...process.env, FORCE_COLOR: "3" },
|
||||
},
|
||||
);
|
||||
|
||||
if (output) {
|
||||
console.log(output);
|
||||
}
|
||||
console.log(` \x1b[32m✓ No linting issues found\x1b[0m\n`);
|
||||
} catch (error) {
|
||||
// execSync throws on non-zero exit code (linting errors found)
|
||||
if (error instanceof Error && "stdout" in error) {
|
||||
const execError = error as Error & {
|
||||
stdout?: string;
|
||||
stderr?: string;
|
||||
};
|
||||
if (execError.stdout !== undefined) console.log(execError.stdout);
|
||||
if (execError.stderr !== undefined) console.error(execError.stderr);
|
||||
}
|
||||
console.error("\n\x1b[31mBuild aborted due to linting errors\x1b[0m\n");
|
||||
process.exit(1);
|
||||
}
|
||||
},
|
||||
|
||||
closeBundle() {
|
||||
// Cleanup on server close
|
||||
killCurrentProcess();
|
||||
clearDebounceTimer();
|
||||
},
|
||||
};
|
||||
}
|
||||
126
frontend/vite-plugins/oxlint-overlay.ts
Normal file
126
frontend/vite-plugins/oxlint-overlay.ts
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
// Oxlint overlay client-side code
|
||||
let overlay: HTMLDivElement | null = null;
|
||||
let hideTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
function createOverlay(): HTMLDivElement {
|
||||
if (overlay) return overlay;
|
||||
|
||||
overlay = document.createElement("div");
|
||||
overlay.id = "oxlint-error-overlay";
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
background: #323437;
|
||||
color: #e4dec8ff;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
z-index: 10000;
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s ease;
|
||||
`;
|
||||
|
||||
overlay.addEventListener("mouseenter", () => {
|
||||
if (overlay) overlay.style.opacity = "0.5";
|
||||
});
|
||||
|
||||
overlay.addEventListener("mouseleave", () => {
|
||||
if (overlay) overlay.style.opacity = "1";
|
||||
});
|
||||
|
||||
overlay.addEventListener("click", () => {
|
||||
if (overlay) overlay.style.display = "none";
|
||||
});
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
function updateOverlay(data: {
|
||||
errorCount?: number;
|
||||
warningCount?: number;
|
||||
running?: boolean;
|
||||
hadIssues?: boolean;
|
||||
typeAware?: boolean;
|
||||
}): void {
|
||||
const overlayEl = createOverlay();
|
||||
|
||||
// Clear any pending hide timeout
|
||||
if (hideTimeout !== null) {
|
||||
clearTimeout(hideTimeout);
|
||||
hideTimeout = null;
|
||||
}
|
||||
|
||||
// Show running icon if linting is running and there were issues before
|
||||
if (data.running) {
|
||||
if (data.hadIssues) {
|
||||
const message = data.typeAware ? "checking type aware..." : "checking...";
|
||||
overlayEl.innerHTML = `
|
||||
<span style="font-size: 18px;">⏳</span>
|
||||
<span>oxlint: ${message}</span>
|
||||
`;
|
||||
overlayEl.style.display = "flex";
|
||||
overlayEl.style.color = "#e4dec8ff";
|
||||
} else {
|
||||
overlayEl.style.display = "none";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const { errorCount = 0, warningCount = 0, hadIssues = false } = data;
|
||||
const total = errorCount + warningCount;
|
||||
|
||||
if (total > 0) {
|
||||
overlayEl.innerHTML = `
|
||||
<span style="font-size: 18px;">🚨</span>
|
||||
<span>oxlint: ${errorCount} error${errorCount !== 1 ? "s" : ""}, ${warningCount} warning${warningCount !== 1 ? "s" : ""}</span>
|
||||
`;
|
||||
overlayEl.style.display = "flex";
|
||||
|
||||
if (errorCount > 0) {
|
||||
overlayEl.style.color = "#e4dec8ff";
|
||||
}
|
||||
} else {
|
||||
// Only show success if the previous lint had issues
|
||||
if (hadIssues) {
|
||||
overlayEl.innerHTML = `
|
||||
<span style="font-size: 18px;">✅</span>
|
||||
<span>oxlint: ok</span>
|
||||
`;
|
||||
overlayEl.style.display = "flex";
|
||||
overlayEl.style.color = "#e4dec8ff";
|
||||
|
||||
// Hide after 3 seconds
|
||||
hideTimeout = setTimeout(() => {
|
||||
overlayEl.style.display = "none";
|
||||
hideTimeout = null;
|
||||
}, 3000);
|
||||
} else {
|
||||
// Two good lints in a row - don't show anything
|
||||
overlayEl.style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize overlay on load
|
||||
createOverlay();
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.on(
|
||||
"vite-plugin-oxlint",
|
||||
(data: {
|
||||
errorCount?: number;
|
||||
warningCount?: number;
|
||||
running?: boolean;
|
||||
hadIssues?: boolean;
|
||||
}) => {
|
||||
updateOverlay(data);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ import { languageHashes } from "./vite-plugins/language-hashes";
|
|||
import { minifyJson } from "./vite-plugins/minify-json";
|
||||
import { versionFile } from "./vite-plugins/version-file";
|
||||
import { jqueryInject } from "./vite-plugins/jquery-inject";
|
||||
import { checker } from "vite-plugin-checker";
|
||||
import { oxlintChecker } from "./vite-plugins/oxlint-checker";
|
||||
import Inspect from "vite-plugin-inspect";
|
||||
import { ViteMinifyPlugin } from "vite-plugin-minify";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
|
|
@ -81,13 +81,10 @@ function getPlugins({
|
|||
const plugins: PluginOption[] = [
|
||||
envConfig({ isDevelopment, clientVersion, env }),
|
||||
languageHashes({ skip: isDevelopment }),
|
||||
checker({
|
||||
oxlint: {
|
||||
lintCommand: "oxlint . --type-aware --type-check",
|
||||
},
|
||||
overlay: {
|
||||
initialIsOpen: false,
|
||||
},
|
||||
oxlintChecker({
|
||||
debounceDelay: 125,
|
||||
typeAware: true,
|
||||
overlay: true,
|
||||
}),
|
||||
jqueryInject(),
|
||||
injectHTML(),
|
||||
|
|
|
|||
142
pnpm-lock.yaml
generated
142
pnpm-lock.yaml
generated
|
|
@ -399,7 +399,7 @@ importers:
|
|||
version: 5.0.2
|
||||
'@vitest/coverage-v8':
|
||||
specifier: 4.0.15
|
||||
version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
|
||||
version: 4.0.15(vitest@4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
|
||||
autoprefixer:
|
||||
specifier: 10.4.20
|
||||
version: 10.4.20(postcss@8.4.31)
|
||||
|
|
@ -460,9 +460,6 @@ importers:
|
|||
vite-bundle-visualizer:
|
||||
specifier: 1.2.1
|
||||
version: 1.2.1(rollup@2.79.2)
|
||||
vite-plugin-checker:
|
||||
specifier: 0.11.0
|
||||
version: 0.11.0(eslint@9.39.1)(meow@13.2.0)(optionator@0.9.4)(oxlint@1.34.0(oxlint-tsgolint@0.9.2))(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
|
||||
vite-plugin-filter-replace:
|
||||
specifier: 0.1.14
|
||||
version: 0.1.14
|
||||
|
|
@ -480,7 +477,7 @@ importers:
|
|||
version: 1.1.0(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))(workbox-build@7.1.1)(workbox-window@7.1.0)
|
||||
vitest:
|
||||
specifier: 4.0.15
|
||||
version: 4.0.15(@opentelemetry/api@1.8.0)(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
|
||||
version: 4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
|
||||
|
||||
packages/contracts:
|
||||
dependencies:
|
||||
|
|
@ -7090,10 +7087,6 @@ packages:
|
|||
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
npm-run-path@6.0.0:
|
||||
resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
npmlog@5.0.1:
|
||||
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
|
||||
deprecated: This package is no longer supported.
|
||||
|
|
@ -8632,9 +8625,6 @@ packages:
|
|||
through@2.3.8:
|
||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||
|
||||
tiny-invariant@1.3.3:
|
||||
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
||||
|
||||
tiny-lru@8.0.2:
|
||||
resolution: {integrity: sha512-ApGvZ6vVvTNdsmt676grvCkUCGwzG9IqXma5Z07xJgiC5L7akUMof5U8G2JTI9Rz/ovtVhJBlY6mNhEvtjzOIg==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -8959,10 +8949,6 @@ packages:
|
|||
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
unicorn-magic@0.3.0:
|
||||
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
unique-filename@3.0.0:
|
||||
resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==}
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
|
|
@ -9107,43 +9093,6 @@ packages:
|
|||
peerDependencies:
|
||||
vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0
|
||||
|
||||
vite-plugin-checker@0.11.0:
|
||||
resolution: {integrity: sha512-iUdO9Pl9UIBRPAragwi3as/BXXTtRu4G12L3CMrjx+WVTd9g/MsqNakreib9M/2YRVkhZYiTEwdH2j4Dm0w7lw==}
|
||||
engines: {node: '>=16.11'}
|
||||
peerDependencies:
|
||||
'@biomejs/biome': '>=1.7'
|
||||
eslint: '>=7'
|
||||
meow: ^13.2.0
|
||||
optionator: ^0.9.4
|
||||
oxlint: '>=1'
|
||||
stylelint: '>=16'
|
||||
typescript: '*'
|
||||
vite: '>=5.4.20'
|
||||
vls: '*'
|
||||
vti: '*'
|
||||
vue-tsc: ~2.2.10 || ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
'@biomejs/biome':
|
||||
optional: true
|
||||
eslint:
|
||||
optional: true
|
||||
meow:
|
||||
optional: true
|
||||
optionator:
|
||||
optional: true
|
||||
oxlint:
|
||||
optional: true
|
||||
stylelint:
|
||||
optional: true
|
||||
typescript:
|
||||
optional: true
|
||||
vls:
|
||||
optional: true
|
||||
vti:
|
||||
optional: true
|
||||
vue-tsc:
|
||||
optional: true
|
||||
|
||||
vite-plugin-filter-replace@0.1.14:
|
||||
resolution: {integrity: sha512-3onEAYgjJQTCJN+/f8+1vOUH3X/tRmXsfxmgH3QtpReGKi+xtP1jMpAEnYsNqw9mI2shZmxFm3LS+n52XczwYQ==}
|
||||
|
||||
|
|
@ -9254,9 +9203,6 @@ packages:
|
|||
vlq@0.2.3:
|
||||
resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==}
|
||||
|
||||
vscode-uri@3.1.0:
|
||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||
|
||||
walkdir@0.4.1:
|
||||
resolution: {integrity: sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
|
@ -12589,6 +12535,23 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))':
|
||||
dependencies:
|
||||
'@bcoe/v8-coverage': 1.0.2
|
||||
'@vitest/utils': 4.0.15
|
||||
ast-v8-to-istanbul: 0.3.8
|
||||
istanbul-lib-coverage: 3.2.2
|
||||
istanbul-lib-report: 3.0.1
|
||||
istanbul-lib-source-maps: 5.0.6
|
||||
istanbul-reports: 3.2.0
|
||||
magicast: 0.5.1
|
||||
obug: 2.1.1
|
||||
std-env: 3.10.0
|
||||
tinyrainbow: 3.0.3
|
||||
vitest: 4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitest/expect@4.0.15':
|
||||
dependencies:
|
||||
'@standard-schema/spec': 1.0.0
|
||||
|
|
@ -17021,11 +16984,6 @@ snapshots:
|
|||
dependencies:
|
||||
path-key: 4.0.0
|
||||
|
||||
npm-run-path@6.0.0:
|
||||
dependencies:
|
||||
path-key: 4.0.0
|
||||
unicorn-magic: 0.3.0
|
||||
|
||||
npmlog@5.0.1:
|
||||
dependencies:
|
||||
are-we-there-yet: 2.0.0
|
||||
|
|
@ -18904,8 +18862,6 @@ snapshots:
|
|||
|
||||
through@2.3.8: {}
|
||||
|
||||
tiny-invariant@1.3.3: {}
|
||||
|
||||
tiny-lru@8.0.2: {}
|
||||
|
||||
tinybench@2.9.0: {}
|
||||
|
|
@ -19196,8 +19152,6 @@ snapshots:
|
|||
|
||||
unicorn-magic@0.1.0: {}
|
||||
|
||||
unicorn-magic@0.3.0: {}
|
||||
|
||||
unique-filename@3.0.0:
|
||||
dependencies:
|
||||
unique-slug: 4.0.0
|
||||
|
|
@ -19349,24 +19303,6 @@ snapshots:
|
|||
dependencies:
|
||||
vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
|
||||
|
||||
vite-plugin-checker@0.11.0(eslint@9.39.1)(meow@13.2.0)(optionator@0.9.4)(oxlint@1.34.0(oxlint-tsgolint@0.9.2))(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
chokidar: 4.0.3
|
||||
npm-run-path: 6.0.0
|
||||
picocolors: 1.1.1
|
||||
picomatch: 4.0.3
|
||||
tiny-invariant: 1.3.3
|
||||
tinyglobby: 0.2.15
|
||||
vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
|
||||
vscode-uri: 3.1.0
|
||||
optionalDependencies:
|
||||
eslint: 9.39.1
|
||||
meow: 13.2.0
|
||||
optionator: 0.9.4
|
||||
oxlint: 1.34.0(oxlint-tsgolint@0.9.2)
|
||||
typescript: 5.9.3
|
||||
|
||||
vite-plugin-filter-replace@0.1.14:
|
||||
dependencies:
|
||||
magic-string: 0.30.17
|
||||
|
|
@ -19514,9 +19450,45 @@ snapshots:
|
|||
- tsx
|
||||
- yaml
|
||||
|
||||
vlq@0.2.3: {}
|
||||
vitest@4.0.15(@types/node@24.9.1)(happy-dom@20.0.10)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1):
|
||||
dependencies:
|
||||
'@vitest/expect': 4.0.15
|
||||
'@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1))
|
||||
'@vitest/pretty-format': 4.0.15
|
||||
'@vitest/runner': 4.0.15
|
||||
'@vitest/snapshot': 4.0.15
|
||||
'@vitest/spy': 4.0.15
|
||||
'@vitest/utils': 4.0.15
|
||||
es-module-lexer: 1.7.0
|
||||
expect-type: 1.2.2
|
||||
magic-string: 0.30.21
|
||||
obug: 2.1.1
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.3
|
||||
std-env: 3.10.0
|
||||
tinybench: 2.9.0
|
||||
tinyexec: 1.0.2
|
||||
tinyglobby: 0.2.15
|
||||
tinyrainbow: 3.0.3
|
||||
vite: 7.1.12(@types/node@24.9.1)(sass@1.70.0)(terser@5.44.1)(tsx@4.16.2)(yaml@2.8.1)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 24.9.1
|
||||
happy-dom: 20.0.10
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
- less
|
||||
- lightningcss
|
||||
- msw
|
||||
- sass
|
||||
- sass-embedded
|
||||
- stylus
|
||||
- sugarss
|
||||
- terser
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vscode-uri@3.1.0: {}
|
||||
vlq@0.2.3: {}
|
||||
|
||||
walkdir@0.4.1: {}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue