diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index c5188ad..b31c7a0 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -34,6 +34,9 @@ jobs: targets: wasm32-unknown-unknown bins: cargo-codspeed, wasm-bindgen-cli, just, wasm-opt + - name: Install dependencies + run: just install + - name: Build (WASM) run: just build-wasm benchmark diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6e1c26d..24bb6d3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -98,6 +98,12 @@ jobs: targets: wasm32-unknown-unknown bins: wasm-bindgen-cli, just, wasm-opt + - name: Install dependencies + run: just install + + - name: Build + run: just build + - name: Build (WASM) run: just build-wasm diff --git a/crates/weblsp/src/css.rs b/crates/weblsp/src/css.rs index c3aadbd..53294d5 100644 --- a/crates/weblsp/src/css.rs +++ b/crates/weblsp/src/css.rs @@ -1,8 +1,12 @@ -use crate::cast; use csslsrs::service::LanguageService; use lsp_server::{Connection, Message, Request, Response}; +use lsp_types::request::{ + ColorPresentationRequest, DocumentColor, FoldingRangeRequest, HoverRequest, +}; use std::error::Error; +use crate::requests::cast; + /// Initialize our CSS Language Service (CSSlsrs). /// Used once at the start of the main loop, so the document store stays alive throughout the server's lifetime. pub fn init_language_service() -> LanguageService { @@ -18,13 +22,13 @@ pub fn handle_request( ) -> Result<(), Box> { match req.method.as_str() { "textDocument/documentColor" => { - let (id, params) = cast::(req)?; + let (id, params) = cast::(req)?; let colors = language_service .get_document_colors(get_text_document(params.text_document, language_service)?); send_result(connection, id, serde_json::to_value(&colors).unwrap())?; } "textDocument/colorPresentation" => { - let (id, params) = cast::(req)?; + let (id, params) = cast::(req)?; let presentations = language_service.get_color_presentations(lsp_types::ColorInformation { color: params.color, @@ -37,13 +41,13 @@ pub fn handle_request( )?; } "textDocument/foldingRange" => { - let (id, params) = cast::(req)?; + let (id, params) = cast::(req)?; let ranges = language_service .get_folding_ranges(get_text_document(params.text_document, language_service)?); send_result(connection, id, serde_json::to_value(&ranges).unwrap())?; } "textDocument/hover" => { - let (id, params) = cast::(req)?; + let (id, params) = cast::(req)?; let hover = language_service.get_hover( get_text_document( params.text_document_position_params.text_document, @@ -69,6 +73,7 @@ fn get_text_document( None => return Err(Box::from("Document not found")), }; + // TODO: It'd be great to avoid cloning the document here, might need to refactor methods to take a reference instead. Ok(text_document.document.clone()) } diff --git a/crates/weblsp/src/main.rs b/crates/weblsp/src/main.rs index 901911b..eb6d7b0 100644 --- a/crates/weblsp/src/main.rs +++ b/crates/weblsp/src/main.rs @@ -1,13 +1,16 @@ -pub mod css; -pub mod notifications; -pub mod requests; -use lsp_server::{Connection, ExtractError, Message, Request, RequestId}; -use lsp_types::{InitializeParams, ServerCapabilities, TextDocumentSyncCapability}; -use std::error::Error; +mod css; +mod notifications; +mod requests; +mod response; +mod server; +use lsp_server::{Connection, Message}; +use lsp_types::{notification::Notification, InitializeParams}; +use server::get_server_capabilities; +use std::{error::Error, process::ExitCode}; /// Entry point for our WEBlsp server. /// Heavily inspired by -> https://github.com/rust-lang/rust-analyzer/blob/master/lib/lsp-server/examples/goto_def.rs -fn main() -> Result<(), Box> { +fn main() -> Result> { // Note that we must have our logging only write out to stderr. eprintln!("starting server"); @@ -15,19 +18,8 @@ fn main() -> Result<(), Box> { // also be implemented to use sockets or HTTP. let (connection, io_threads) = Connection::stdio(); - // Run the server and wait for the two threads to end (typically by trigger LSP Exit event). - let server_capabilities = serde_json::to_value(&ServerCapabilities { - hover_provider: Some(lsp_types::HoverProviderCapability::Simple(true)), - color_provider: Some(lsp_types::ColorProviderCapability::Simple(true)), - folding_range_provider: Some(lsp_types::FoldingRangeProviderCapability::Simple(true)), - text_document_sync: Some(TextDocumentSyncCapability::Kind( - lsp_types::TextDocumentSyncKind::FULL, - )), - ..Default::default() - }) - .unwrap(); - let initialization_params = match connection.initialize(server_capabilities) { - Ok(it) => it, + let initialization_params = match connection.initialize(get_server_capabilities()) { + Ok(params) => params, Err(e) => { if e.channel_is_disconnected() { io_threads.join()?; @@ -35,56 +27,65 @@ fn main() -> Result<(), Box> { return Err(e.into()); } }; + // Init language services and start the main loop. let css_language_service = css::init_language_service(); - main_loop(connection, initialization_params, css_language_service)?; + + // Run the server and wait for the two threads to end (typically by shutdown then exit messages). + let exit_code = main_loop(connection, initialization_params, css_language_service)?; + // Joins the IO threads to ensure all communication is properly finished. io_threads.join()?; + // Shut down gracefully. eprintln!("shutting down server"); - Ok(()) + + Ok(exit_code) } /// Main loop of our WEBlsp server. Handles all incoming messages, and dispatches them to the appropriate language handler. fn main_loop( connection: Connection, - params: serde_json::Value, + init_params: serde_json::Value, mut css_language_service: csslsrs::service::LanguageService, -) -> Result<(), Box> { - let _params: InitializeParams = serde_json::from_value(params).unwrap(); +) -> Result> { + let mut awaiting_exit = false; + let _init_params: InitializeParams = serde_json::from_value(init_params).unwrap(); + for msg in &connection.receiver { - eprintln!("new msg: {msg:?}"); + // TODO: Handle trace levels and notifications instead of just printing them to stderr. + eprintln!("new msg: {:?}", msg); + + // If we're waiting for an exit notification, any message other than it is an error, and will cause the server to exit with a failure exit code. + // As such, we can handle this outside of the match statement. + if awaiting_exit { + if let Message::Notification(not) = &msg { + if not.method == lsp_types::notification::Exit::METHOD { + return Ok(ExitCode::SUCCESS); + } + } + eprintln!("Shutting down without receiving `Exit` notification."); + return Ok(ExitCode::FAILURE); + } + + // Handle the rest of the messages. match msg { Message::Request(req) => { - requests::handle_request(req, &mut css_language_service, &connection)?; - continue; + let request = + requests::handle_request(req, &mut css_language_service, &connection)?; + + if request.is_shutdown { + awaiting_exit = true; + } } Message::Response(resp) => { - handle_response(resp)?; - continue; + response::handle_response(resp)?; } Message::Notification(not) => { notifications::handle_notification(not, &mut css_language_service, &connection)?; - continue; } } } - Ok(()) -} - -/// TMP: log the response. -fn handle_response(resp: lsp_server::Response) -> Result<(), Box> { - eprintln!("handle_response: got {resp:?}"); - Ok(()) -} -/// Attempts to cast a request to a specific LSP request type. -/// If the request is not of the specified type, an error will be returned. -/// If the request is of the specified type, the request ID and parameters will be returned. -pub fn cast(req: Request) -> Result<(RequestId, R::Params), ExtractError> -where - R: lsp_types::request::Request, - R::Params: serde::de::DeserializeOwned, -{ - req.extract(R::METHOD) + Ok(ExitCode::SUCCESS) } diff --git a/crates/weblsp/src/notifications.rs b/crates/weblsp/src/notifications.rs index 86b90f0..7f88261 100644 --- a/crates/weblsp/src/notifications.rs +++ b/crates/weblsp/src/notifications.rs @@ -1,6 +1,6 @@ use lsp_server::Connection; use lsp_types::{DidChangeTextDocumentParams, DidOpenTextDocumentParams, TextDocumentItem}; -use std::error::Error; +use std::{error::Error, process::exit}; /// Used by the main loop to handle notifications. Notifications are messages that the client sends to the server. /// Notable notifications include `exit`, `textDocument/didOpen`, and `textDocument/didChange`. @@ -10,9 +10,10 @@ pub fn handle_notification( _connection: &Connection, ) -> Result<(), Box> { match notification.method.as_str() { + // Proper shutdown is handled directly by the main loop, so if we get an `exit` notification here, it's an invalid one and we should exit with an error. "exit" => { - eprintln!("exit: shutting down server"); - std::process::exit(0); + eprintln!("Shutting down without receiving `Shutdown` request."); + exit(1); } "textDocument/didOpen" => { // didOpen notification carry a textDocument item, which contains the document's URI and languageId. diff --git a/crates/weblsp/src/requests.rs b/crates/weblsp/src/requests.rs index 4411a3c..c5b3da6 100644 --- a/crates/weblsp/src/requests.rs +++ b/crates/weblsp/src/requests.rs @@ -1,16 +1,33 @@ -use lsp_server::Connection; +use lsp_server::{Connection, ExtractError, Request, RequestId}; +use lsp_types::request::Request as _; use std::error::Error; use std::str::FromStr; use crate::css; +#[derive(Default)] +pub struct RequestOutcome { + pub(crate) is_shutdown: bool, +} + /// Used by the main loop. Based on the document's language, this function will dispatch the request to the appropriate language handler. /// Requests are LSP features that the client wants to use, and the server must respond to each request. pub fn handle_request( req: lsp_server::Request, css_language_service: &mut csslsrs::service::LanguageService, connection: &Connection, -) -> Result<(), Box> { +) -> Result> { + if req.method == lsp_types::request::Shutdown::METHOD { + connection + .sender + .send(lsp_server::Message::Response(lsp_server::Response::new_ok( + req.id, + (), + )))?; + + return Ok(RequestOutcome { is_shutdown: true }); + } + let language_id = get_language_id(&req, css_language_service)?; match language_id.as_str() { "css" => { @@ -20,7 +37,8 @@ pub fn handle_request( eprintln!("unsupported language: {}", language_id); } } - Ok(()) + + Ok(RequestOutcome::default()) } // TMP: TODO: For now, we use CSSlsrs' store, because we only support CSS. So I can just retrieve the document from this store from its URI. @@ -36,12 +54,10 @@ fn get_language_id( .get("textDocument") .and_then(|td| td.get("uri")) .and_then(|uri| uri.as_str()) + .and_then(|uri| lsp_types::Uri::from_str(uri).ok()) .ok_or("Missing or invalid 'textDocument.uri' in request parameters")?; - let text_document_uri = lsp_types::Uri::from_str(text_document_identifier) - .map_err(|_| "Invalid 'textDocument.uri' in request parameters")?; - - let store_entry = match css_language_service.get_document(&text_document_uri) { + let store_entry = match css_language_service.get_document(&text_document_identifier) { Some(doc) => doc, None => return Err(Box::from("Document not found")), }; @@ -52,3 +68,14 @@ fn get_language_id( // The immutable borrow ends here Ok(language_id) } + +/// Attempts to cast a request to a specific LSP request type. +/// If the request is not of the specified type, an error will be returned. +/// If the request is of the specified type, the request ID and parameters will be returned. +pub fn cast(req: Request) -> Result<(RequestId, R::Params), ExtractError> +where + R: lsp_types::request::Request, + R::Params: serde::de::DeserializeOwned, +{ + req.extract(R::METHOD) +} diff --git a/crates/weblsp/src/response.rs b/crates/weblsp/src/response.rs new file mode 100644 index 0000000..ca8847d --- /dev/null +++ b/crates/weblsp/src/response.rs @@ -0,0 +1,7 @@ +use std::error::Error; + +/// TMP: log the response. +pub fn handle_response(resp: lsp_server::Response) -> Result<(), Box> { + eprintln!("handle_response: got {resp:?}"); + Ok(()) +} diff --git a/crates/weblsp/src/server.rs b/crates/weblsp/src/server.rs new file mode 100644 index 0000000..66c939b --- /dev/null +++ b/crates/weblsp/src/server.rs @@ -0,0 +1,15 @@ +use lsp_types::{ServerCapabilities, TextDocumentSyncCapability}; + +pub(crate) fn get_server_capabilities() -> serde_json::Value { + let capabilities = ServerCapabilities { + hover_provider: Some(lsp_types::HoverProviderCapability::Simple(true)), + color_provider: Some(lsp_types::ColorProviderCapability::Simple(true)), + folding_range_provider: Some(lsp_types::FoldingRangeProviderCapability::Simple(true)), + text_document_sync: Some(TextDocumentSyncCapability::Kind( + lsp_types::TextDocumentSyncKind::FULL, + )), + ..Default::default() + }; + + serde_json::to_value(capabilities).unwrap() +} diff --git a/justfile b/justfile index 6fa9b82..8738b4f 100644 --- a/justfile +++ b/justfile @@ -1,9 +1,16 @@ alias b := build +alias bw := build-wasm +alias t := test +alias bm := benchmark +alias i := install default: build default_mode := "debug" +install: + pnpm install + build mode=default_mode: just fetch-data echo "Building to native target..." @@ -15,7 +22,6 @@ build-wasm mode=default_mode: cargo build --package csslsrs --target wasm32-unknown-unknown {{ if mode == "release" {"--release"} else if mode == "benchmark" {"--profile benchmark"} else {""} }} --features wasm wasm-bindgen ./target/wasm32-unknown-unknown/{{mode}}/csslsrs.wasm --out-dir ./packages/csslsrs/src/generated --target=experimental-nodejs-module {{ if mode == "release" { "" } else { "--keep-debug" } }} {{ if mode == "release" { "wasm-opt -O4 ./packages/csslsrs/src/generated/csslsrs_bg.wasm -o ./packages/csslsrs/src/generated/csslsrs_bg.wasm" } else { "" } }} - pnpm -C ./packages/csslsrs install pnpm -C ./packages/csslsrs run build fetch-data: @@ -27,11 +33,10 @@ test: echo "Running Rust tests..." cargo test echo "Running JS tests..." - pnpm -C ./packages/csslsrs run test + pnpm -r run test --run benchmark: echo "Running Native benchmarks..." cargo bench echo "Running WASM benchmarks..." - just build-wasm release - pnpm -C ./packages/benchmark-wasm run benchmark + pnpm -C ./packages/benchmark-wasm run benchmark --run diff --git a/packages/benchmark-wasm/benchmarks/hover.bench.ts b/packages/benchmark-wasm/benchmarks/hover.bench.ts index a10398c..2327940 100644 --- a/packages/benchmark-wasm/benchmarks/hover.bench.ts +++ b/packages/benchmark-wasm/benchmarks/hover.bench.ts @@ -1,11 +1,10 @@ -import { LanguageService } from "../../csslsrs/dist/index.js"; +import { LanguageService } from "csslsrs"; import { getCSSLanguageService } from "vscode-css-languageservice"; import { TextDocument } from "vscode-languageserver-textdocument"; import { bench, describe } from "vitest"; -describe("Hover", async () => { - const vscodeLanguageService = getCSSLanguageService(); - const content = ` +const vscodeLanguageService = getCSSLanguageService(); +const content = ` body { background-color: #fff; } @@ -23,17 +22,13 @@ h1 > span { } `; - const textDocument = TextDocument.create( - "file:///test.css", - "css", - 0, - content - ); - const ls = new LanguageService({ - include_base_css_custom_data: true, - }); - ls.upsertDocument(textDocument); +const textDocument = TextDocument.create("file:///test.css", "css", 0, content); +const ls = new LanguageService({ + include_base_css_custom_data: true, +}); +ls.upsertDocument(textDocument); +describe("Hover", async () => { bench("CSSLSRS(WASM) - Hover", () => { ls.getHover(textDocument.uri, { line: 14, diff --git a/packages/benchmark-wasm/vitest.config.ts b/packages/benchmark-wasm/vitest.config.ts index bf1f52f..68b94ee 100644 --- a/packages/benchmark-wasm/vitest.config.ts +++ b/packages/benchmark-wasm/vitest.config.ts @@ -5,4 +5,11 @@ const plugins = process.env.CODSPEED ? [codspeedPlugin()] : []; export default defineConfig({ plugins, + test: { + forceRerunTriggers: [ + "**/package.json/**", + "**/{vitest,vite}.config.*/**", + "**/csslsrs_bg.wasm", + ], + }, }); diff --git a/packages/csslsrs/package.json b/packages/csslsrs/package.json index ae22fa1..cdaca32 100644 --- a/packages/csslsrs/package.json +++ b/packages/csslsrs/package.json @@ -12,7 +12,7 @@ "scripts": { "prepublishOnly": "just build-wasm release && pnpm run build", "build": "node ./build.js && tsc", - "test": "mocha --require tsx test/**/*.test.ts" + "test": "vitest" }, "files": [ "dist" @@ -26,12 +26,8 @@ "vscode-languageserver-types": "^3.17.5" }, "devDependencies": { - "@types/chai": "^5.0.0", - "@types/mocha": "^10.0.9", "@types/node": "^22.8.0", - "chai": "^5.1.2", - "mocha": "^10.7.3", - "tsx": "^4.19.1", - "typescript": "^5.6.3" + "typescript": "^5.6.3", + "vitest": "^2.1.8" } } diff --git a/packages/csslsrs/test/features/colors.test.ts b/packages/csslsrs/test/features/colors.test.ts index 7e6eb3c..dc38f52 100644 --- a/packages/csslsrs/test/features/colors.test.ts +++ b/packages/csslsrs/test/features/colors.test.ts @@ -1,5 +1,4 @@ -import { describe, it } from "mocha"; -import { expect } from "chai"; +import { describe, it, expect, beforeAll } from "vitest"; import { TextDocument } from "vscode-languageserver-textdocument"; import { LanguageService } from "../../dist"; @@ -7,7 +6,7 @@ describe("Colors", () => { let ls: LanguageService; let document: TextDocument; - before(() => { + beforeAll(() => { ls = new LanguageService({ include_base_css_custom_data: true, }); diff --git a/packages/csslsrs/test/features/folding.test.ts b/packages/csslsrs/test/features/folding.test.ts index 6ffe98a..6769540 100644 --- a/packages/csslsrs/test/features/folding.test.ts +++ b/packages/csslsrs/test/features/folding.test.ts @@ -1,5 +1,4 @@ -import { describe, it } from "mocha"; -import { expect } from "chai"; +import { describe, it, expect } from "vitest"; import { LanguageService } from "../../dist/index.js"; import { TextDocument } from "vscode-languageserver-textdocument"; import type { FoldingRange } from "vscode-languageserver-types"; diff --git a/packages/csslsrs/test/features/hover.test.ts b/packages/csslsrs/test/features/hover.test.ts index 8739e45..680bf69 100644 --- a/packages/csslsrs/test/features/hover.test.ts +++ b/packages/csslsrs/test/features/hover.test.ts @@ -1,5 +1,4 @@ -import { describe, it } from "mocha"; -import { expect } from "chai"; +import { describe, it, expect, beforeAll } from "vitest"; import { TextDocument } from "vscode-languageserver-textdocument"; import { LanguageService } from "../../../csslsrs/dist/index"; @@ -7,7 +6,7 @@ describe("Hover", () => { let ls: LanguageService; let document: TextDocument; - before(() => { + beforeAll(() => { ls = new LanguageService({ include_base_css_custom_data: true, }); diff --git a/packages/language-server-tests/fixture/.gitkeep b/packages/language-server-tests/fixture/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/packages/language-server-tests/package.json b/packages/language-server-tests/package.json new file mode 100644 index 0000000..a1a3bfb --- /dev/null +++ b/packages/language-server-tests/package.json @@ -0,0 +1,16 @@ +{ + "name": "language-server-tests", + "type": "module", + "private": true, + "scripts": { + "test": "vitest" + }, + "dependencies": { + "@types/node": "^22.10.1", + "vitest": "^2.1.8", + "vscode-languageclient": "^9.0.1", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-uri": "^3.0.8" + } +} diff --git a/packages/language-server-tests/tests/css/colors.test.ts b/packages/language-server-tests/tests/css/colors.test.ts new file mode 100644 index 0000000..3c1510c --- /dev/null +++ b/packages/language-server-tests/tests/css/colors.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from "vitest"; + +describe("CSS - Colors", () => { + it("should return something for a document colors request", async () => { + const doc = await languageServer.openFakeDocument( + `h1 { color: red; }`, + "css" + ); + + const colors = await languageServer.sendDocumentColorRequest(doc.uri); + + expect(colors).toBeDefined(); + + const colorPresentations = + await languageServer.sendColorPresentationRequest( + doc.uri, + colors[0].color, + colors[0].range + ); + + expect(colorPresentations).toBeDefined(); + }); +}); diff --git a/packages/language-server-tests/tests/css/folding.test.ts b/packages/language-server-tests/tests/css/folding.test.ts new file mode 100644 index 0000000..e84f48d --- /dev/null +++ b/packages/language-server-tests/tests/css/folding.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from "vitest"; + +describe("CSS - Folding Ranges", () => { + it("should return something for a folding ranges request", async () => { + const doc = await languageServer.openFakeDocument( + `h1 { color: red; }`, + "css" + ); + + const foldingRanges = await languageServer.sendFoldingRangesRequest( + doc.uri + ); + + expect(foldingRanges).toBeDefined(); + }); +}); diff --git a/packages/language-server-tests/tests/css/hover.test.ts b/packages/language-server-tests/tests/css/hover.test.ts new file mode 100644 index 0000000..66ad14a --- /dev/null +++ b/packages/language-server-tests/tests/css/hover.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; +import { Position } from "vscode-languageserver-protocol"; + +describe("CSS - Hover", () => { + it("should return something for a hover request", async () => { + const doc = await languageServer.openFakeDocument( + `h1 { color: red; }`, + "css" + ); + + const hover = await languageServer.sendHoverRequest( + doc.uri, + Position.create(0, 5) + ); + + expect(hover).toBeDefined(); + }); +}); diff --git a/packages/language-server-tests/tests/init.test.ts b/packages/language-server-tests/tests/init.test.ts new file mode 100644 index 0000000..3b4697a --- /dev/null +++ b/packages/language-server-tests/tests/init.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from "vitest"; +import { ServerCapabilities } from "vscode-languageserver-protocol/node"; + +describe("Language server initilization", () => { + it("Can init server", async () => { + expect(languageServer).toBeDefined(); + }); + + it("Has proper capabilities", async () => { + const capabilities: ServerCapabilities = { + colorProvider: true, + foldingRangeProvider: true, + hoverProvider: true, + textDocumentSync: 1, + }; + + expect(languageServer.initializeResult.capabilities).to.deep.equal( + capabilities + ); + }); +}); diff --git a/packages/language-server-tests/tests/server.ts b/packages/language-server-tests/tests/server.ts new file mode 100644 index 0000000..c9a5db8 --- /dev/null +++ b/packages/language-server-tests/tests/server.ts @@ -0,0 +1,476 @@ +// Adapted from https://github.com/volarjs/volar.js/blob/bdbd555a7fed6e084a454d64ba0b98aac1d85241/packages/test-utils/index.ts to remove Volar-specific code and adapt it for a non-Node language server +// See https://github.com/volarjs/volar.js/blob/bdbd555a7fed6e084a454d64ba0b98aac1d85241/LICENSE#L1 for license information + +import * as cp from "node:child_process"; +import * as fs from "node:fs"; +import * as _ from "vscode-languageserver-protocol/node"; +import { TextDocument } from "vscode-languageserver-textdocument"; +import { URI } from "vscode-uri"; +import * as assert from "node:assert/strict"; +import { fileURLToPath } from "node:url"; +import { createHash, randomBytes } from "node:crypto"; + +const pathToBinary = fileURLToPath( + new URL("../../../target/debug/weblsp", import.meta.url) +); + +export const fixtureDir = URI.file( + fileURLToPath(new URL("./fixture", import.meta.url)) +).toString(); + +export type LanguageServerHandle = ReturnType; + +export async function startLanguageServer(cwd?: string | undefined) { + console.info(`Starting language server at ${pathToBinary}`); + const childProcess = cp.spawn(pathToBinary, [], { + env: process.env, + cwd, + stdio: "pipe", + }); + + if (!childProcess.stdout || !childProcess.stdin) { + throw new Error("Bad stdio configuration, should be pipe"); + } + + if (process.env.DEBUG) { + childProcess.stderr?.on("data", (data) => { + console.error(data.toString()); + }); + } + + const connection = _.createProtocolConnection( + childProcess.stdout, + childProcess.stdin + ); + + connection.listen(); + + connection.onClose((e) => console.log("Closed", e)); + + connection.onUnhandledNotification((e) => + console.log("Unhandled notificaiton", e) + ); + + connection.onError((e) => console.log("Error:", e)); + + connection.onRequest(_.InitializeRequest.method, (params) => { + console.log("InitializeRequest", params); + }); + + connection.onNotification(_.LogMessageNotification.type, (e) => { + if (e.type === _.MessageType.Error || e.type === _.MessageType.Warning) { + console.error(e.message); + } else { + console.log(e.message); + } + }); + + connection.onDispose(() => { + connection.end(); + }); + + connection.onRequest(_.ConfigurationRequest.type, ({ items }) => { + return items.map((item) => { + if (item.section) { + return getConfiguration(item.section); + } + }); + }); + + const documentVersions = new Map(); + const openedDocuments = new Map(); + const settings: any = {}; + + let untitledCounter = 0; + let running = false; + + function getConfiguration(section: string) { + if (section in settings) { + return settings[section]; + } + let result: any; + for (const settingKey in settings) { + if (settingKey.startsWith(`${section}.`)) { + const value = settings[settingKey]; + const props = settingKey.substring(section.length + 1).split("."); + result ??= {}; + let current = result; + while (props.length > 1) { + const prop = props.shift()!; + if (typeof current[prop] !== "object") { + current[prop] = {}; + } + current = current[prop]; + } + current[props.shift()!] = value; + } + } + return result; + } + + async function initialize( + rootUri: string | _.WorkspaceFolder[], + initializationOptions: _._InitializeParams["initializationOptions"], + capabilities: _.ClientCapabilities = {}, + locale?: string + ) { + const result = await connection.sendRequest(_.InitializeRequest.type, { + processId: childProcess.pid ?? null, + rootUri: typeof rootUri === "string" ? rootUri : null, + workspaceFolders: Array.isArray(rootUri) ? rootUri : null, + initializationOptions, + capabilities, + locale, + } satisfies _.InitializeParams); + await connection.sendNotification( + _.InitializedNotification.type, + {} satisfies _.InitializedParams + ); + running = true; + return result; + } + + const initResult = await initialize( + fixtureDir, + { + // No init options + }, + { + textDocument: { + definition: { + linkSupport: true, + }, + }, + workspace: { + // Needed for tests that use didChangeWatchedFiles + didChangeWatchedFiles: {}, + configuration: true, + }, + } + ); + + return { + process: childProcess, + connection, + initializeResult: initResult, + async shutdown() { + running = false; + await connection.sendRequest(_.ShutdownRequest.type); + openedDocuments.clear(); + }, + async exit() { + await connection.sendNotification(_.ExitNotification.type); + }, + async openTextDocument(fileName: string, languageId: string) { + const uri = URI.file(fileName).toString(); + if (!openedDocuments.has(uri)) { + const document = TextDocument.create( + uri, + languageId, + (documentVersions.get(uri) ?? 0) + 1, + fs.readFileSync(fileName, "utf-8") + ); + documentVersions.set(uri, document.version); + openedDocuments.set(uri, document); + await connection.sendNotification( + _.DidOpenTextDocumentNotification.type, + { + textDocument: { + uri, + languageId, + version: document.version, + text: document.getText(), + }, + } satisfies _.DidOpenTextDocumentParams + ); + } + return openedDocuments.get(uri)!; + }, + async openUntitledDocument(languageId: string, content: string) { + const uri = URI.from({ + scheme: "untitled", + path: `Untitled-${untitledCounter++}`, + }).toString(); + const document = TextDocument.create( + uri, + languageId, + (documentVersions.get(uri) ?? 0) + 1, + content + ); + documentVersions.set(uri, document.version); + openedDocuments.set(uri, document); + await connection.sendNotification( + _.DidOpenTextDocumentNotification.type, + { + textDocument: { + uri, + languageId, + version: document.version, + text: document.getText(), + }, + } satisfies _.DidOpenTextDocumentParams + ); + return document; + }, + async openFakeDocument(content: string, languageId: string) { + const hash = randomBytes(10).toString("hex"); + const uri = URI.file(`does-not-exists-${hash}`).toString(); + const textDocument = await this.openInMemoryDocument( + uri, + languageId, + content + ); + + return textDocument; + }, + async openInMemoryDocument( + uri: string, + languageId: string, + content: string + ) { + const oldDocument = openedDocuments.get(uri); + if (oldDocument) { + await this.closeTextDocument(uri); + } + const document = TextDocument.create( + uri, + languageId, + (documentVersions.get(uri) ?? 0) + 1, + content + ); + documentVersions.set(uri, document.version); + openedDocuments.set(uri, document); + await connection.sendNotification( + _.DidOpenTextDocumentNotification.type, + { + textDocument: { + uri, + languageId, + version: document.version, + text: document.getText(), + }, + } satisfies _.DidOpenTextDocumentParams + ); + return document; + }, + closeTextDocument(uri: string) { + assert(openedDocuments.has(uri)); + openedDocuments.delete(uri); + return connection.sendNotification( + _.DidCloseTextDocumentNotification.type, + { + textDocument: { uri }, + } satisfies _.DidCloseTextDocumentParams + ); + }, + async updateTextDocument(uri: string, edits: _.TextEdit[]) { + let document = openedDocuments.get(uri); + assert(document); + const newText = TextDocument.applyEdits(document, edits); + document = TextDocument.create( + uri, + document.languageId, + document.version + 1, + newText + ); + documentVersions.set(uri, document.version); + openedDocuments.set(uri, document); + await connection.sendNotification( + _.DidChangeTextDocumentNotification.type, + { + textDocument: { + uri: document.uri, + version: document.version, + }, + contentChanges: [{ text: document.getText() }], + } satisfies _.DidChangeTextDocumentParams + ); + return document; + }, + async updateConfiguration(newSettings: any) { + Object.assign(settings, newSettings); + if (running) { + await connection.sendNotification( + _.DidChangeConfigurationNotification.type, + { settings } satisfies _.DidChangeConfigurationParams + ); + } + }, + didChangeWatchedFiles(changes: _.FileEvent[]) { + return connection.sendNotification( + _.DidChangeWatchedFilesNotification.type, + { changes } satisfies _.DidChangeWatchedFilesParams + ); + }, + async sendCompletionRequest(uri: string, position: _.Position) { + const result = await connection.sendRequest(_.CompletionRequest.type, { + textDocument: { uri }, + position, + } satisfies _.CompletionParams); + // @volar/language-server only returns CompletionList + assert(!Array.isArray(result)); + return result; + }, + sendCompletionResolveRequest(item: _.CompletionItem) { + return connection.sendRequest( + _.CompletionResolveRequest.type, + item satisfies _.CompletionItem + ); + }, + sendDocumentDiagnosticRequest(uri: string) { + return connection.sendRequest(_.DocumentDiagnosticRequest.type, { + textDocument: { uri }, + } satisfies _.DocumentDiagnosticParams); + }, + sendHoverRequest(uri: string, position: _.Position) { + return connection.sendRequest(_.HoverRequest.type, { + textDocument: { uri }, + position, + } satisfies _.HoverParams); + }, + sendDocumentFormattingRequest(uri: string, options: _.FormattingOptions) { + return connection.sendRequest(_.DocumentFormattingRequest.type, { + textDocument: { uri }, + options, + } satisfies _.DocumentFormattingParams); + }, + sendDocumentRangeFormattingRequestRequest( + uri: string, + range: _.Range, + options: _.FormattingOptions + ) { + return connection.sendRequest(_.DocumentRangeFormattingRequest.type, { + textDocument: { uri }, + range, + options, + } satisfies _.DocumentRangeFormattingParams); + }, + sendRenameRequest(uri: string, position: _.Position, newName: string) { + return connection.sendRequest(_.RenameRequest.type, { + textDocument: { uri }, + position, + newName, + } satisfies _.RenameParams); + }, + sendPrepareRenameRequest(uri: string, position: _.Position) { + return connection.sendRequest(_.PrepareRenameRequest.type, { + textDocument: { uri }, + position, + } satisfies _.PrepareRenameParams); + }, + sendFoldingRangesRequest(uri: string) { + return connection.sendRequest(_.FoldingRangeRequest.type, { + textDocument: { uri }, + } satisfies _.FoldingRangeParams); + }, + sendDocumentSymbolRequest(uri: string) { + return connection.sendRequest(_.DocumentSymbolRequest.type, { + textDocument: { uri }, + } satisfies _.DocumentSymbolParams); + }, + sendDocumentColorRequest(uri: string) { + return connection.sendRequest(_.DocumentColorRequest.type, { + textDocument: { uri }, + } satisfies _.DocumentColorParams); + }, + sendDefinitionRequest(uri: string, position: _.Position) { + return connection.sendRequest(_.DefinitionRequest.type, { + textDocument: { uri }, + position, + } satisfies _.DefinitionParams); + }, + sendTypeDefinitionRequest(uri: string, position: _.Position) { + return connection.sendRequest(_.TypeDefinitionRequest.type, { + textDocument: { uri }, + position, + } satisfies _.TypeDefinitionParams); + }, + sendReferencesRequest( + uri: string, + position: _.Position, + context: _.ReferenceContext + ) { + return connection.sendRequest(_.ReferencesRequest.type, { + textDocument: { uri }, + position, + context, + } satisfies _.ReferenceParams); + }, + sendSignatureHelpRequest(uri: string, position: _.Position) { + return connection.sendRequest(_.SignatureHelpRequest.type, { + textDocument: { uri }, + position, + } satisfies _.SignatureHelpParams); + }, + sendSelectionRangesRequest(uri: string, positions: _.Position[]) { + return connection.sendRequest(_.SelectionRangeRequest.type, { + textDocument: { uri }, + positions, + } satisfies _.SelectionRangeParams); + }, + sendCodeActionsRequest( + uri: string, + range: _.Range, + context: _.CodeActionContext + ) { + return connection.sendRequest(_.CodeActionRequest.type, { + textDocument: { uri }, + range, + context, + } satisfies _.CodeActionParams); + }, + sendCodeActionResolveRequest(codeAction: _.CodeAction) { + return connection.sendRequest( + _.CodeActionResolveRequest.type, + codeAction satisfies _.CodeAction + ); + }, + sendExecuteCommandRequest(command: string, args?: any[]) { + return connection.sendRequest(_.ExecuteCommandRequest.type, { + command, + arguments: args, + } satisfies _.ExecuteCommandParams); + }, + sendSemanticTokensRequest(uri: string) { + return connection.sendRequest(_.SemanticTokensRequest.type, { + textDocument: { uri }, + } satisfies _.SemanticTokensParams); + }, + sendSemanticTokensRangeRequest(uri: string, range: _.Range) { + return connection.sendRequest(_.SemanticTokensRangeRequest.type, { + textDocument: { uri }, + range, + } satisfies _.SemanticTokensRangeParams); + }, + sendColorPresentationRequest(uri: string, color: _.Color, range: _.Range) { + return connection.sendRequest(_.ColorPresentationRequest.type, { + textDocument: { uri }, + color, + range, + } satisfies _.ColorPresentationParams); + }, + sendDocumentLinkRequest(uri: string) { + return connection.sendRequest(_.DocumentLinkRequest.type, { + textDocument: { uri }, + } satisfies _.DocumentLinkParams); + }, + sendDocumentLinkResolveRequest(link: _.DocumentLink) { + return connection.sendRequest( + _.DocumentLinkResolveRequest.type, + link satisfies _.DocumentLink + ); + }, + sendInlayHintRequest(uri: string, range: _.Range) { + return connection.sendRequest(_.InlayHintRequest.type, { + textDocument: { uri }, + range, + } satisfies _.InlayHintParams); + }, + sendInlayHintResolveRequest(hint: _.InlayHint) { + return connection.sendRequest( + _.InlayHintResolveRequest.type, + hint satisfies _.InlayHint + ); + }, + }; +} diff --git a/packages/language-server-tests/tests/setup.ts b/packages/language-server-tests/tests/setup.ts new file mode 100644 index 0000000..41e934e --- /dev/null +++ b/packages/language-server-tests/tests/setup.ts @@ -0,0 +1,9 @@ +import { startLanguageServer } from "./server"; + +declare global { + var languageServer: Awaited; +} + +if (!globalThis.languageServer) { + globalThis.languageServer = await startLanguageServer(); +} diff --git a/packages/language-server-tests/tests/shutdown.test.ts b/packages/language-server-tests/tests/shutdown.test.ts new file mode 100644 index 0000000..3790c9d --- /dev/null +++ b/packages/language-server-tests/tests/shutdown.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from "vitest"; +import { ServerCapabilities } from "vscode-languageserver-protocol/node"; + +describe("Language server initilization", () => { + it("Can shutdown server", async () => { + await languageServer.shutdown(); + await languageServer.exit(); + + await new Promise((resolve) => { + languageServer.process.on("exit", resolve); + }); + + expect(languageServer.process.exitCode).toBe(0); + }); +}); diff --git a/packages/language-server-tests/tsconfig.json b/packages/language-server-tests/tsconfig.json new file mode 100644 index 0000000..0883f66 --- /dev/null +++ b/packages/language-server-tests/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "lib": ["ESNext"], + "moduleResolution": "bundler" + } +} diff --git a/packages/language-server-tests/vitest.config.ts b/packages/language-server-tests/vitest.config.ts new file mode 100644 index 0000000..cd3d53b --- /dev/null +++ b/packages/language-server-tests/vitest.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from "vitest/config"; +import { BaseSequencer, WorkspaceSpec } from "vitest/node"; + +class Sequencer extends BaseSequencer { + async sort(files: WorkspaceSpec[]): Promise { + const init = files.find((f) => f.moduleId.endsWith("init.test.ts")); + const shutdown = files.find((f) => f.moduleId.endsWith("shutdown.test.ts")); + + const tests = files.filter( + (f) => + !f.moduleId.endsWith("init.test.ts") && + !f.moduleId.endsWith("shutdown.test.ts") + ); + + return [init, ...tests, shutdown].filter(Boolean) as WorkspaceSpec[]; + } +} + +export default defineConfig({ + test: { + dir: "tests", + watch: false, + isolate: false, + fileParallelism: false, + setupFiles: ["./tests/setup.ts"], + sequence: { + sequencer: Sequencer, + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74aaf3e..ac11bed 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,10 +12,10 @@ importers: dependencies: '@codspeed/vitest-plugin': specifier: ^3.1.1 - version: 3.1.1(vite@5.4.11(@types/node@22.9.3))(vitest@2.1.8(@types/node@22.9.3)) + version: 3.1.1(vite@5.4.11(@types/node@22.10.1))(vitest@2.1.8(@types/node@22.10.1)) vitest: specifier: ^2.1.8 - version: 2.1.8(@types/node@22.9.3) + version: 2.1.8(@types/node@22.10.1) devDependencies: csslsrs: specifier: workspace:* @@ -36,27 +36,36 @@ importers: specifier: ^3.17.5 version: 3.17.5 devDependencies: - '@types/chai': - specifier: ^5.0.0 - version: 5.0.1 - '@types/mocha': - specifier: ^10.0.9 - version: 10.0.10 '@types/node': specifier: ^22.8.0 version: 22.9.3 - chai: - specifier: ^5.1.2 - version: 5.1.2 - mocha: - specifier: ^10.7.3 - version: 10.8.2 - tsx: - specifier: ^4.19.1 - version: 4.19.2 typescript: specifier: ^5.6.3 version: 5.7.2 + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@22.9.3) + + packages/language-server-tests: + dependencies: + '@types/node': + specifier: ^22.10.1 + version: 22.10.1 + vitest: + specifier: ^2.1.8 + version: 2.1.8(@types/node@22.10.1) + vscode-languageclient: + specifier: ^9.0.1 + version: 9.0.1 + vscode-languageserver-protocol: + specifier: ^3.17.5 + version: 3.17.5 + vscode-languageserver-textdocument: + specifier: ^1.0.12 + version: 1.0.12 + vscode-uri: + specifier: ^3.0.8 + version: 3.0.8 packages/vscode: dependencies: @@ -91,282 +100,138 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.23.1': - resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.23.1': - resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-arm@0.23.1': - resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/android-x64@0.23.1': - resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.23.1': - resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.23.1': - resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.23.1': - resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.23.1': - resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.23.1': - resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.23.1': - resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.23.1': - resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.23.1': - resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.23.1': - resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.23.1': - resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.23.1': - resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.23.1': - resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.23.1': - resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.23.1': - resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.23.1': - resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.23.1': - resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.23.1': - resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.23.1': - resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.23.1': - resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.23.1': - resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} @@ -460,17 +325,11 @@ packages: cpu: [x64] os: [win32] - '@types/chai@5.0.1': - resolution: {integrity: sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/mocha@10.0.10': - resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + '@types/node@22.10.1': + resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} '@types/node@22.9.3': resolution: {integrity: sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==} @@ -510,25 +369,6 @@ packages: '@vscode/l10n@0.0.18': resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -542,54 +382,21 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -603,10 +410,6 @@ packages: supports-color: optional: true - decamelize@4.0.0: - resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} - engines: {node: '>=10'} - deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -615,13 +418,6 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - diff@5.2.0: - resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} - engines: {node: '>=0.3.1'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} @@ -630,19 +426,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.23.1: - resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -650,22 +433,10 @@ packages: resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} engines: {node: '>=12.0.0'} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - find-up@6.3.0: resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -679,89 +450,15 @@ packages: resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-tsconfig@4.8.1: - resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - locate-path@7.2.0: resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} @@ -780,11 +477,6 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} - mocha@10.8.2: - resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} - engines: {node: '>= 14.0.0'} - hasBin: true - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -797,33 +489,14 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - p-limit@4.0.0: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - p-locate@6.0.0: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - path-exists@5.0.0: resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -838,10 +511,6 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - postcss@8.4.49: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} @@ -849,36 +518,16 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - rollup@4.28.0: resolution: {integrity: sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -892,26 +541,6 @@ packages: std-env@3.8.0: resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -930,15 +559,6 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - tsx@4.19.2: - resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} - engines: {node: '>=18.0.0'} - hasBin: true - typescript@5.7.2: resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} engines: {node: '>=14.17'} @@ -947,6 +567,9 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + vite-node@2.1.8: resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1036,36 +659,6 @@ packages: engines: {node: '>=8'} hasBin: true - workerpool@6.5.1: - resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - - yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} - engines: {node: '>=10'} - - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - yocto-queue@1.1.1: resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} engines: {node: '>=12.20'} @@ -1081,155 +674,83 @@ snapshots: transitivePeerDependencies: - debug - '@codspeed/vitest-plugin@3.1.1(vite@5.4.11(@types/node@22.9.3))(vitest@2.1.8(@types/node@22.9.3))': + '@codspeed/vitest-plugin@3.1.1(vite@5.4.11(@types/node@22.10.1))(vitest@2.1.8(@types/node@22.10.1))': dependencies: '@codspeed/core': 3.1.1 - vite: 5.4.11(@types/node@22.9.3) - vitest: 2.1.8(@types/node@22.9.3) + vite: 5.4.11(@types/node@22.10.1) + vitest: 2.1.8(@types/node@22.10.1) transitivePeerDependencies: - debug '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/aix-ppc64@0.23.1': - optional: true - '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm64@0.23.1': - optional: true - '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-arm@0.23.1': - optional: true - '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/android-x64@0.23.1': - optional: true - '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.23.1': - optional: true - '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/darwin-x64@0.23.1': - optional: true - '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.23.1': - optional: true - '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.23.1': - optional: true - '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm64@0.23.1': - optional: true - '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-arm@0.23.1': - optional: true - '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-ia32@0.23.1': - optional: true - '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-loong64@0.23.1': - optional: true - '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-mips64el@0.23.1': - optional: true - '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.23.1': - optional: true - '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.23.1': - optional: true - '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-s390x@0.23.1': - optional: true - '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/linux-x64@0.23.1': - optional: true - '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.23.1': - optional: true - - '@esbuild/openbsd-arm64@0.23.1': - optional: true - '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.23.1': - optional: true - '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.23.1': - optional: true - '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-arm64@0.23.1': - optional: true - '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-ia32@0.23.1': - optional: true - '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-x64@0.23.1': - optional: true - '@jridgewell/sourcemap-codec@1.5.0': {} '@rollup/rollup-android-arm-eabi@4.28.0': @@ -1286,15 +807,11 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.28.0': optional: true - '@types/chai@5.0.1': - dependencies: - '@types/deep-eql': 4.0.2 - - '@types/deep-eql@4.0.2': {} - '@types/estree@1.0.6': {} - '@types/mocha@10.0.10': {} + '@types/node@22.10.1': + dependencies: + undici-types: 6.20.0 '@types/node@22.9.3': dependencies: @@ -1309,6 +826,14 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.1))': + dependencies: + '@vitest/spy': 2.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.14 + optionalDependencies: + vite: 5.4.11(@types/node@22.10.1) + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.9.3))': dependencies: '@vitest/spy': 2.1.8 @@ -1344,21 +869,6 @@ snapshots: '@vscode/l10n@0.0.18': {} - ansi-colors@4.1.3: {} - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - argparse@2.0.1: {} - assertion-error@2.0.1: {} asynckit@0.4.0: {} @@ -1373,22 +883,12 @@ snapshots: balanced-match@1.0.2: {} - binary-extensions@2.3.0: {} - brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browser-stdout@1.3.1: {} - cac@6.7.14: {} - camelcase@6.3.0: {} - chai@5.1.2: dependencies: assertion-error: 2.0.1 @@ -1397,57 +897,20 @@ snapshots: loupe: 3.1.2 pathval: 2.0.0 - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - check-error@2.1.1: {} - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - debug@4.3.7(supports-color@8.1.1): + debug@4.3.7: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 - - decamelize@4.0.0: {} deep-eql@5.0.2: {} delayed-stream@1.0.0: {} - diff@5.2.0: {} - - emoji-regex@8.0.0: {} - es-module-lexer@1.5.4: {} esbuild@0.21.5: @@ -1476,59 +939,17 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - esbuild@0.23.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.23.1 - '@esbuild/android-arm': 0.23.1 - '@esbuild/android-arm64': 0.23.1 - '@esbuild/android-x64': 0.23.1 - '@esbuild/darwin-arm64': 0.23.1 - '@esbuild/darwin-x64': 0.23.1 - '@esbuild/freebsd-arm64': 0.23.1 - '@esbuild/freebsd-x64': 0.23.1 - '@esbuild/linux-arm': 0.23.1 - '@esbuild/linux-arm64': 0.23.1 - '@esbuild/linux-ia32': 0.23.1 - '@esbuild/linux-loong64': 0.23.1 - '@esbuild/linux-mips64el': 0.23.1 - '@esbuild/linux-ppc64': 0.23.1 - '@esbuild/linux-riscv64': 0.23.1 - '@esbuild/linux-s390x': 0.23.1 - '@esbuild/linux-x64': 0.23.1 - '@esbuild/netbsd-x64': 0.23.1 - '@esbuild/openbsd-arm64': 0.23.1 - '@esbuild/openbsd-x64': 0.23.1 - '@esbuild/sunos-x64': 0.23.1 - '@esbuild/win32-arm64': 0.23.1 - '@esbuild/win32-ia32': 0.23.1 - '@esbuild/win32-x64': 0.23.1 - - escalade@3.2.0: {} - - escape-string-regexp@4.0.0: {} - estree-walker@3.0.3: dependencies: '@types/estree': 1.0.6 expect-type@1.1.0: {} - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - find-up@6.3.0: dependencies: locate-path: 7.2.0 path-exists: 5.0.0 - flat@5.0.2: {} - follow-redirects@1.15.9: {} form-data@4.0.1: @@ -1537,75 +958,13 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true - get-caller-file@2.0.5: {} - - get-tsconfig@4.8.1: - dependencies: - resolve-pkg-maps: 1.0.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob@8.1.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 - - has-flag@4.0.0: {} - - he@1.2.0: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - is-plain-obj@2.1.0: {} - - is-unicode-supported@0.1.0: {} - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - locate-path@7.2.0: dependencies: p-locate: 6.0.0 - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - loupe@3.1.2: {} magic-string@0.30.14: @@ -1622,59 +981,20 @@ snapshots: dependencies: brace-expansion: 2.0.1 - mocha@10.8.2: - dependencies: - ansi-colors: 4.1.3 - browser-stdout: 1.3.1 - chokidar: 3.6.0 - debug: 4.3.7(supports-color@8.1.1) - diff: 5.2.0 - escape-string-regexp: 4.0.0 - find-up: 5.0.0 - glob: 8.1.0 - he: 1.2.0 - js-yaml: 4.1.0 - log-symbols: 4.1.0 - minimatch: 5.1.6 - ms: 2.1.3 - serialize-javascript: 6.0.2 - strip-json-comments: 3.1.1 - supports-color: 8.1.1 - workerpool: 6.5.1 - yargs: 16.2.0 - yargs-parser: 20.2.9 - yargs-unparser: 2.0.0 - ms@2.1.3: {} nanoid@3.3.8: {} node-gyp-build@4.8.4: {} - normalize-path@3.0.0: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - p-limit@4.0.0: dependencies: yocto-queue: 1.1.1 - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - p-locate@6.0.0: dependencies: p-limit: 4.0.0 - path-exists@4.0.0: {} - path-exists@5.0.0: {} pathe@1.1.2: {} @@ -1683,8 +1003,6 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.1: {} - postcss@8.4.49: dependencies: nanoid: 3.3.8 @@ -1693,18 +1011,6 @@ snapshots: proxy-from-env@1.1.0: {} - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - require-directory@2.1.1: {} - - resolve-pkg-maps@1.0.0: {} - rollup@4.28.0: dependencies: '@types/estree': 1.0.6 @@ -1729,14 +1035,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.28.0 fsevents: 2.3.3 - safe-buffer@5.2.1: {} - semver@7.6.3: {} - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - siginfo@2.0.0: {} source-map-js@1.2.1: {} @@ -1745,26 +1045,6 @@ snapshots: std-env@3.8.0: {} - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-json-comments@3.1.1: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - tinybench@2.9.0: {} tinyexec@0.3.1: {} @@ -1775,25 +1055,34 @@ snapshots: tinyspy@3.0.2: {} - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - tsx@4.19.2: - dependencies: - esbuild: 0.23.1 - get-tsconfig: 4.8.1 - optionalDependencies: - fsevents: 2.3.3 - typescript@5.7.2: {} undici-types@6.19.8: {} + undici-types@6.20.0: {} + + vite-node@2.1.8(@types/node@22.10.1): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.4.11(@types/node@22.10.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@2.1.8(@types/node@22.9.3): dependencies: cac: 6.7.14 - debug: 4.3.7(supports-color@8.1.1) + debug: 4.3.7 es-module-lexer: 1.5.4 pathe: 1.1.2 vite: 5.4.11(@types/node@22.9.3) @@ -1808,6 +1097,15 @@ snapshots: - supports-color - terser + vite@5.4.11(@types/node@22.10.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.28.0 + optionalDependencies: + '@types/node': 22.10.1 + fsevents: 2.3.3 + vite@5.4.11(@types/node@22.9.3): dependencies: esbuild: 0.21.5 @@ -1817,6 +1115,41 @@ snapshots: '@types/node': 22.9.3 fsevents: 2.3.3 + vitest@2.1.8(@types/node@22.10.1): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.1)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.14 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@22.10.1) + vite-node: 2.1.8(@types/node@22.10.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.1 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@2.1.8(@types/node@22.9.3): dependencies: '@vitest/expect': 2.1.8 @@ -1827,7 +1160,7 @@ snapshots: '@vitest/spy': 2.1.8 '@vitest/utils': 2.1.8 chai: 5.1.2 - debug: 4.3.7(supports-color@8.1.1) + debug: 4.3.7 expect-type: 1.1.0 magic-string: 0.30.14 pathe: 1.1.2 @@ -1883,37 +1216,4 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 - workerpool@6.5.1: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrappy@1.0.2: {} - - y18n@5.0.8: {} - - yargs-parser@20.2.9: {} - - yargs-unparser@2.0.0: - dependencies: - camelcase: 6.3.0 - decamelize: 4.0.0 - flat: 5.0.2 - is-plain-obj: 2.1.0 - - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - - yocto-queue@0.1.0: {} - yocto-queue@1.1.1: {}