diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afc8e8d2..f7b266d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,12 +100,11 @@ jobs: tools: dprint,cargo-shear components: clippy rust-docs rustfmt - - run: | - dprint check - cargo shear - cargo fmt --check - # cargo clippy --all-targets --all-features -- -D warnings - RUSTDOCFLAGS='-D warnings' cargo doc --no-deps --document-private-items + - run: dprint check + - run: cargo shear + - run: cargo fmt --check + # - run: cargo clippy --all-targets --all-features -- -D warnings + - run: RUSTDOCFLAGS='-D warnings' cargo doc --no-deps --document-private-items - uses: crate-ci/typos@85f62a8a84f939ae994ab3763f01a0296d61a7ee # v1.36.2 with: diff --git a/Cargo.lock b/Cargo.lock index e498ad7d..7c4b8a5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2131,6 +2131,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -2803,6 +2813,15 @@ dependencies = [ "windows-sys 0.61.1", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "test-log" version = "0.2.18" @@ -3037,6 +3056,28 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "ts-rs" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4994acea2522cd2b3b85c1d9529a55991e3ad5e25cdcd3de9d505972c4379424" +dependencies = [ + "thiserror 2.0.17", + "ts-rs-macros", +] + +[[package]] +name = "ts-rs-macros" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6ff59666c9cbaec3533964505d39154dc4e0a56151fdea30a09ed0301f62e2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "termcolor", +] + [[package]] name = "tui-term" version = "0.2.0" @@ -3208,6 +3249,7 @@ dependencies = [ "ref-cast", "serde", "thiserror 2.0.17", + "ts-rs", "vite_str", ] @@ -3231,6 +3273,7 @@ dependencies = [ "compact_str 0.9.0", "diff-struct", "serde", + "ts-rs", ] [[package]] @@ -3276,7 +3319,6 @@ dependencies = [ "copy_dir", "cow-utils", "insta", - "monostate", "regex", "serde", "tempfile", @@ -3298,15 +3340,18 @@ dependencies = [ "clap", "monostate", "petgraph", + "pretty_assertions", "serde", "serde_json", "thiserror 2.0.17", "tokio", + "ts-rs", "vec1", "vite_graph_ser", "vite_path", "vite_str", "vite_workspace", + "which", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b928c23b..4595da9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,7 @@ passfd = { git = "https://github.com/polachok/passfd", rev = "d55881752c16aced1a petgraph = "0.8.2" phf = { version = "0.11.3", features = ["macros"] } portable-pty = "0.9.0" +pretty_assertions = "1.4.1" rand = "0.9.1" ratatui = "0.29.0" rayon = "1.10.0" @@ -116,6 +117,7 @@ toml = "0.9.5" tracing = "0.1.43" tracing-error = "0.2.1" tracing-subscriber = { version = "0.3.19", features = ["env-filter", "serde"] } +ts-rs = { version = "11.1.0" } tui-term = "0.2.0" twox-hash = "2.1.1" uuid = "1.18.1" diff --git a/crates/vite_path/Cargo.toml b/crates/vite_path/Cargo.toml index 5184a749..207f05e0 100644 --- a/crates/vite_path/Cargo.toml +++ b/crates/vite_path/Cargo.toml @@ -12,10 +12,12 @@ diff-struct = { workspace = true } ref-cast = { workspace = true } serde = { workspace = true, features = ["derive", "rc"] } thiserror = { workspace = true } +ts-rs = { workspace = true, optional = true } vite_str = { workspace = true } [features] absolute-redaction = [] +ts-rs = ["dep:ts-rs", "vite_str/ts-rs"] [lints] workspace = true diff --git a/crates/vite_path/src/relative.rs b/crates/vite_path/src/relative.rs index 87f2bc25..de76ca1f 100644 --- a/crates/vite_path/src/relative.rs +++ b/crates/vite_path/src/relative.rs @@ -263,6 +263,38 @@ pub enum FromPathError { InvalidPathData(#[from] InvalidPathDataError), } +#[cfg(feature = "ts-rs")] +mod ts_impl { + use ts_rs::TS; + + use super::RelativePathBuf; + + impl TS for RelativePathBuf { + type OptionInnerType = Self; + type WithoutGenerics = Self; + + fn name() -> String { + "string".to_owned() + } + + fn inline() -> String { + "string".to_owned() + } + + fn inline_flattened() -> String { + panic!("RelativePathBuf cannot be flattened") + } + + fn decl() -> String { + panic!("RelativePathBuf is a primitive type") + } + + fn decl_concrete() -> String { + panic!("RelativePathBuf is a primitive type") + } + } +} + #[cfg(test)] mod tests { diff --git a/crates/vite_str/Cargo.toml b/crates/vite_str/Cargo.toml index d8ef5583..7159106c 100644 --- a/crates/vite_str/Cargo.toml +++ b/crates/vite_str/Cargo.toml @@ -11,6 +11,10 @@ bincode = { workspace = true } compact_str = { workspace = true, features = ["serde"] } diff-struct = { workspace = true } serde = { workspace = true, features = ["derive"] } +ts-rs = { workspace = true, optional = true } + +[features] +ts-rs = ["dep:ts-rs"] [lints] workspace = true diff --git a/crates/vite_str/src/lib.rs b/crates/vite_str/src/lib.rs index 318c7b1d..eee7882f 100644 --- a/crates/vite_str/src/lib.rs +++ b/crates/vite_str/src/lib.rs @@ -176,6 +176,38 @@ impl PartialEq for Str { } } +#[cfg(feature = "ts-rs")] +mod ts_impl { + use ts_rs::TS; + + use super::Str; + + impl TS for Str { + type OptionInnerType = Self; + type WithoutGenerics = Self; + + fn name() -> String { + "string".to_owned() + } + + fn inline() -> String { + "string".to_owned() + } + + fn inline_flattened() -> String { + panic!("Str cannot be flattened") + } + + fn decl() -> String { + panic!("Str is a primitive type") + } + + fn decl_concrete() -> String { + panic!("Str is a primitive type") + } + } +} + #[cfg(test)] mod tests { use bincode::{config::standard, decode_from_slice, encode_to_vec}; diff --git a/crates/vite_task_bin/Cargo.toml b/crates/vite_task_bin/Cargo.toml index 59d984dd..879a468b 100644 --- a/crates/vite_task_bin/Cargo.toml +++ b/crates/vite_task_bin/Cargo.toml @@ -14,7 +14,6 @@ path = "src/main.rs" anyhow = { workspace = true } async-trait = { workspace = true } clap = { workspace = true, features = ["derive"] } -monostate = { workspace = true } tokio = { workspace = true, features = ["full"] } vite_path = { workspace = true } vite_str = { workspace = true } diff --git a/crates/vite_task_bin/src/lib.rs b/crates/vite_task_bin/src/lib.rs index 7921136a..1284f415 100644 --- a/crates/vite_task_bin/src/lib.rs +++ b/crates/vite_task_bin/src/lib.rs @@ -8,7 +8,6 @@ use std::{ }; use clap::Subcommand; -use monostate::MustBe; use vite_path::AbsolutePath; use vite_str::Str; use vite_task::{ @@ -120,10 +119,10 @@ impl vite_task::TaskSynthesizer for TaskSynthesizer { args: [name.clone()].into(), task_options: UserTaskOptions { cache_config: UserCacheConfig::Enabled { - cache: MustBe!(true), + cache: None, enabled_cache_config: EnabledCacheConfig { - envs: Box::new([]), - pass_through_envs: vec![name], + envs: None, + pass_through_envs: Some(vec![name]), }, }, ..Default::default() diff --git a/crates/vite_task_graph/Cargo.toml b/crates/vite_task_graph/Cargo.toml index 80ef4955..17fc8225 100644 --- a/crates/vite_task_graph/Cargo.toml +++ b/crates/vite_task_graph/Cargo.toml @@ -23,7 +23,12 @@ vite_str = { workspace = true } vite_workspace = { workspace = true } [dev-dependencies] +pretty_assertions = { workspace = true } tokio = { workspace = true, features = ["fs", "rt-multi-thread"] } +ts-rs = { workspace = true } +vite_path = { workspace = true, features = ["ts-rs"] } +vite_str = { workspace = true, features = ["ts-rs"] } +which = { workspace = true } [lints] workspace = true diff --git a/crates/vite_task_graph/src/config/mod.rs b/crates/vite_task_graph/src/config/mod.rs index 2a468a0a..e9bc1a78 100644 --- a/crates/vite_task_graph/src/config/mod.rs +++ b/crates/vite_task_graph/src/config/mod.rs @@ -41,21 +41,23 @@ pub struct ResolvedTaskOptions { impl ResolvedTaskOptions { /// Resolves from user-defined options and the directory path where the options are defined. pub fn resolve(user_options: UserTaskOptions, dir: &Arc) -> Self { - let cwd: Arc = if user_options.cwd_relative_to_package.as_str().is_empty() { - Arc::clone(dir) - } else { - dir.join(user_options.cwd_relative_to_package).into() + let cwd: Arc = match user_options.cwd_relative_to_package { + Some(ref cwd) if !cwd.as_str().is_empty() => dir.join(cwd).into(), + _ => Arc::clone(dir), }; let cache_config = match user_options.cache_config { UserCacheConfig::Disabled { cache: MustBe!(false) } => None, - UserCacheConfig::Enabled { cache: MustBe!(true), mut enabled_cache_config } => { - enabled_cache_config - .pass_through_envs - .extend(DEFAULT_PASSTHROUGH_ENVS.iter().copied().map(Str::from)); + UserCacheConfig::Enabled { cache: _, enabled_cache_config } => { + let mut pass_through_envs = + enabled_cache_config.pass_through_envs.unwrap_or_default(); + pass_through_envs.extend(DEFAULT_PASSTHROUGH_ENVS.iter().copied().map(Str::from)); Some(CacheConfig { env_config: EnvConfig { - fingerprinted_envs: enabled_cache_config.envs.into_iter().collect(), - pass_through_envs: enabled_cache_config.pass_through_envs.into(), + fingerprinted_envs: enabled_cache_config + .envs + .map(|e| e.into_vec().into_iter().collect()) + .unwrap_or_default(), + pass_through_envs: pass_through_envs.into(), }, }) } diff --git a/crates/vite_task_graph/src/config/user.rs b/crates/vite_task_graph/src/config/user.rs index 9f213eb5..394453fa 100644 --- a/crates/vite_task_graph/src/config/user.rs +++ b/crates/vite_task_graph/src/config/user.rs @@ -4,54 +4,56 @@ use std::{collections::HashMap, sync::Arc}; use monostate::MustBe; use serde::Deserialize; +#[cfg(test)] +use ts_rs::TS; use vite_path::RelativePathBuf; use vite_str::Str; /// Cache-related fields of a task defined by user in `vite.config.*` #[derive(Debug, Deserialize, PartialEq, Eq)] +#[cfg_attr(test, derive(TS), ts(optional_fields))] #[serde(untagged, deny_unknown_fields, rename_all = "camelCase")] pub enum UserCacheConfig { /// Cache is enabled Enabled { - /// The `cache` field must be true or omitted - #[serde(default)] - cache: MustBe!(true), + /// Whether to cache the task + #[cfg_attr(test, ts(type = "true", optional))] + cache: Option, #[serde(flatten)] enabled_cache_config: EnabledCacheConfig, }, /// Cache is disabled Disabled { - /// The `cache` field must be false + /// Whether to cache the task + #[cfg_attr(test, ts(type = "false"))] cache: MustBe!(false), }, } /// Cache configuration fields when caching is enabled #[derive(Debug, Deserialize, PartialEq, Eq)] +#[cfg_attr(test, derive(TS), ts(optional_fields))] #[serde(rename_all = "camelCase")] pub struct EnabledCacheConfig { /// Environment variable names to be fingerprinted and passed to the task. - #[serde(default)] // default to empty if omitted - pub envs: Box<[Str]>, + pub envs: Option>, /// Environment variable names to be passed to the task without fingerprinting. - #[serde(default)] // default to empty if omitted - pub pass_through_envs: Vec, + pub pass_through_envs: Option>, } /// Options for user-defined tasks in `vite.config.*`, excluding the command. #[derive(Debug, Deserialize, PartialEq, Eq)] +#[cfg_attr(test, derive(TS), ts(optional_fields))] #[serde(rename_all = "camelCase")] pub struct UserTaskOptions { /// The working directory for the task, relative to the package root (not workspace root). - #[serde(default)] // default to empty if omitted #[serde(rename = "cwd")] - pub cwd_relative_to_package: RelativePathBuf, + pub cwd_relative_to_package: Option, - /// Explicit dependencies of this task. - #[serde(default)] // default to empty if omitted - pub depends_on: Arc<[Str]>, + /// Dependencies of this task. Use `package-name#task-name` to refer to tasks in other packages. + pub depends_on: Option>, /// Cache-related fields #[serde(flatten)] @@ -63,16 +65,13 @@ impl Default for UserTaskOptions { fn default() -> Self { Self { // Runs in the package root - cwd_relative_to_package: RelativePathBuf::default(), + cwd_relative_to_package: None, // No dependencies - depends_on: Arc::new([]), + depends_on: None, // Caching enabled with no fingerprinted envs cache_config: UserCacheConfig::Enabled { - cache: MustBe!(true), - enabled_cache_config: EnabledCacheConfig { - envs: Box::new([]), - pass_through_envs: Vec::new(), - }, + cache: None, + enabled_cache_config: EnabledCacheConfig { envs: None, pass_through_envs: None }, }, } } @@ -80,9 +79,12 @@ impl Default for UserTaskOptions { /// Full user-defined task configuration in `vite.config.*`, including the command and options. #[derive(Debug, Deserialize, PartialEq, Eq)] +#[cfg_attr(test, derive(TS), ts(optional_fields, rename = "Task"))] #[serde(rename_all = "camelCase")] pub struct UserTaskConfig { - /// If None, the script from `package.json` with the same name will be used + /// The command to run for the task. + /// + /// If omitted, the script from `package.json` with the same name will be used pub command: Option>, /// Fields other than the command @@ -93,7 +95,110 @@ pub struct UserTaskConfig { /// User configuration file structure for `vite.config.*` #[derive(Debug, Deserialize)] pub struct UserConfigFile { - pub tasks: HashMap, + pub tasks: UserConfigTasks, +} + +/// Type of the `tasks` field in `vite.config.*` +#[derive(Debug, Default, Deserialize)] +#[cfg_attr(test, derive(TS))] +#[serde(transparent)] +#[cfg_attr(test, ts(rename = "Tasks"))] +pub struct UserConfigTasks(pub HashMap); + +impl UserConfigTasks { + /// TypeScript type definitions for user task configuration. + pub const TS_TYPE: &str = include_str!("../../task-config.ts"); + + /// Generates TypeScript type definitions for user task configuration. + #[cfg(test)] + pub fn generate_ts_definition() -> String { + use std::{ + io::Write, + process::{Command, Stdio}, + }; + + use ts_rs::TypeVisitor; + + struct DeclCollector(Vec); + + impl TypeVisitor for DeclCollector { + fn visit(&mut self) { + // Only collect declarations from types that are exportable + // (i.e., have an output path - built-in types like HashMap don't) + if T::output_path().is_some() { + self.0.push(T::decl()); + } + } + } + + let mut collector = DeclCollector(Vec::new()); + Self::visit_dependencies(&mut collector); + + // Export all types + let mut types: String = collector + .0 + .iter() + .map(|decl| vite_str::format!("export {decl}")) + .collect::>() + .join("\n\n"); + + // Export the main type + types.push_str("\n\nexport "); + types.push_str(&Self::decl()); + + // Format using oxfmt from packages/tools + let workspace_root = + std::path::Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); + let tools_path = workspace_root.join("packages/tools/node_modules/.bin"); + + let oxfmt_path = which::which_in("oxfmt", Some(&tools_path), &tools_path) + .expect("oxfmt not found in packages/tools"); + + let mut child = Command::new(oxfmt_path) + .arg("--stdin-filepath=task-config.ts") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("failed to spawn oxfmt"); + + child + .stdin + .take() + .unwrap() + .write_all(types.as_bytes()) + .expect("failed to write to oxfmt stdin"); + + let output = child.wait_with_output().expect("failed to read oxfmt output"); + assert!(output.status.success(), "oxfmt failed"); + + String::from_utf8(output.stdout).expect("oxfmt output is not valid UTF-8") + } +} + +#[cfg(test)] +mod ts_tests { + use std::{env, path::PathBuf}; + + use super::UserConfigTasks; + + #[test] + fn typescript_generation() { + let file_path = + PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()).join("task-config.ts"); + let ts = UserConfigTasks::generate_ts_definition().replace("\r", ""); + + if env::var("VT_UPDATE_TS_TYPES").unwrap_or_default() == "1" { + std::fs::write(&file_path, ts).unwrap(); + } else { + let existing_ts = + std::fs::read_to_string(&file_path).unwrap_or_default().replace('\r', ""); + pretty_assertions::assert_eq!( + ts, + existing_ts, + "Generated TypeScript types do not match the existing ones. If you made changes to the types, please set VT_UPDATE_TS_TYPES=1 and run the tests again to update the TypeScript definitions." + ); + } + } } #[cfg(test)] @@ -122,7 +227,7 @@ mod tests { "cwd": "src" }); let user_config: UserTaskConfig = serde_json::from_value(user_config_json).unwrap(); - assert_eq!(user_config.options.cwd_relative_to_package.as_str(), "src"); + assert_eq!(user_config.options.cwd_relative_to_package.as_ref().unwrap().as_str(), "src"); } #[test] @@ -147,10 +252,10 @@ mod tests { assert_eq!( serde_json::from_value::(user_config_json).unwrap(), UserCacheConfig::Enabled { - cache: MustBe!(true), + cache: Some(MustBe!(true)), enabled_cache_config: EnabledCacheConfig { - envs: ["NODE_ENV".into()].into_iter().collect(), - pass_through_envs: ["FOO".into()].into_iter().collect(), + envs: Some(["NODE_ENV".into()].into_iter().collect()), + pass_through_envs: Some(["FOO".into()].into_iter().collect()), } }, ); diff --git a/crates/vite_task_graph/src/lib.rs b/crates/vite_task_graph/src/lib.rs index a71b8beb..5190a571 100644 --- a/crates/vite_task_graph/src/lib.rs +++ b/crates/vite_task_graph/src/lib.rs @@ -192,7 +192,7 @@ impl IndexedTaskGraph { let package_graph = vite_workspace::load_package_graph(workspace_root)?; // Record dependency specifiers for each task node to add explicit dependencies later - let mut task_ids_with_dependency_specifiers: Vec<(TaskId, Arc<[Str]>)> = Vec::new(); + let mut task_ids_with_dependency_specifiers: Vec<(TaskId, Option>)> = Vec::new(); // index tasks by ids let mut node_indices_by_task_id: HashMap = @@ -217,13 +217,13 @@ impl IndexedTaskGraph { TaskGraphLoadError::ConfigLoadError { error, package_path: package_dir.clone() } })?; - for (task_name, task_user_config) in user_config.tasks { + for (task_name, task_user_config) in user_config.tasks.0 { // For each task defined in vite.config.*, look up the corresponding package.json script (if any) let package_json_script = package_json_scripts.remove(task_name.as_str()); let task_id = TaskId { task_name: task_name.clone(), package_index }; - let dependency_specifiers = Arc::clone(&task_user_config.options.depends_on); + let dependency_specifiers = task_user_config.options.depends_on.clone(); // Resolve the task configuration combining vite.config.* and package.json script let resolved_config = ResolvedTaskConfig::resolve( @@ -298,7 +298,7 @@ impl IndexedTaskGraph { // Add explicit dependencies for (from_task_id, dependency_specifiers) in task_ids_with_dependency_specifiers { let from_node_index = me.node_indices_by_task_id[&from_task_id]; - for specifier in dependency_specifiers.iter().cloned() { + for specifier in dependency_specifiers.iter().flat_map(|s| s.iter()).cloned() { let to_node_index = me .get_task_index_by_specifier::( TaskSpecifier::parse_raw(&specifier), diff --git a/crates/vite_task_graph/task-config.ts b/crates/vite_task_graph/task-config.ts new file mode 100644 index 00000000..0c3db044 --- /dev/null +++ b/crates/vite_task_graph/task-config.ts @@ -0,0 +1,39 @@ +export type Task = { + /** + * The command to run for the task. + * + * If omitted, the script from `package.json` with the same name will be used + */ + command?: string; + /** + * The working directory for the task, relative to the package root (not workspace root). + */ + cwd?: string; + /** + * Dependencies of this task. Use `package-name#task-name` to refer to tasks in other packages. + */ + dependsOn?: Array; +} & ( + | { + /** + * Whether to cache the task + */ + cache?: true; + /** + * Environment variable names to be fingerprinted and passed to the task. + */ + envs?: Array; + /** + * Environment variable names to be passed to the task without fingerprinting. + */ + passThroughEnvs?: Array; + } + | { + /** + * Whether to cache the task + */ + cache: false; + } +); + +export type Tasks = { [key in string]?: Task }; diff --git a/crates/vite_task_plan/Cargo.toml b/crates/vite_task_plan/Cargo.toml index 571bcadc..2cdd741f 100644 --- a/crates/vite_task_plan/Cargo.toml +++ b/crates/vite_task_plan/Cargo.toml @@ -39,7 +39,7 @@ tempfile = { workspace = true } tokio = { workspace = true, features = ["rt", "macros"] } toml = { workspace = true } vite_task = { workspace = true } -vite_task_bin = { path = "../vite_task_bin" } +vite_task_bin = { workspace = true } vite_workspace = { workspace = true } [[test]] diff --git a/dprint.json b/dprint.json index 16a591a5..0484a32c 100644 --- a/dprint.json +++ b/dprint.json @@ -14,7 +14,8 @@ }, "excludes": [ "crates/fspy_detours_sys/detours", - "pnpm-lock.yaml" + "pnpm-lock.yaml", + "crates/vite_task_graph/task-config.ts" ], "plugins": [ "https://plugins.dprint.dev/typescript-0.94.0.wasm", diff --git a/packages/tools/package.json b/packages/tools/package.json index 7e746efe..e770356f 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "cross-env": "^10.1.0", + "oxfmt": "0.26.0", "oxlint": "catalog:", "oxlint-tsgolint": "catalog:", "vite-task-tools": "link:" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 200a128a..5ca50755 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: cross-env: specifier: ^10.1.0 version: 10.1.0 + oxfmt: + specifier: 0.26.0 + version: 0.26.0 oxlint: specifier: 'catalog:' version: 1.38.0(oxlint-tsgolint@0.10.1) @@ -62,6 +65,50 @@ packages: '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} + '@oxfmt/darwin-arm64@0.26.0': + resolution: {integrity: sha512-AAGc+8CffkiWeVgtWf4dPfQwHEE5c/j/8NWH7VGVxxJRCZFdmWcqCXprvL2H6qZFewvDLrFbuSPRCqYCpYGaTQ==} + cpu: [arm64] + os: [darwin] + + '@oxfmt/darwin-x64@0.26.0': + resolution: {integrity: sha512-xFx5ijCTjw577wJvFlZEMmKDnp3HSCcbYdCsLRmC5i3TZZiDe9DEYh3P46uqhzj8BkEw1Vm1ZCWdl48aEYAzvQ==} + cpu: [x64] + os: [darwin] + + '@oxfmt/linux-arm64-gnu@0.26.0': + resolution: {integrity: sha512-GubkQeQT5d3B/Jx/IiR7NMkSmXrCZcVI0BPh1i7mpFi8HgD1hQ/LbhiBKAMsMqs5bbugdQOgBEl8bOhe8JhW1g==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/linux-arm64-musl@0.26.0': + resolution: {integrity: sha512-OEypUwK69bFPj+aa3/LYCnlIUPgoOLu//WNcriwpnWNmt47808Ht7RJSg+MNK8a7pSZHpXJ5/E6CRK/OTwFdaQ==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/linux-x64-gnu@0.26.0': + resolution: {integrity: sha512-xO6iEW2bC6ZHyOTPmPWrg/nM6xgzyRPaS84rATy6F8d79wz69LdRdJ3l/PXlkqhi7XoxhvX4ExysA0Nf10ZZEQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxfmt/linux-x64-musl@0.26.0': + resolution: {integrity: sha512-Z3KuZFC+MIuAyFCXBHY71kCsdRq1ulbsbzTe71v+hrEv7zVBn6yzql+/AZcgfIaKzWO9OXNuz5WWLWDmVALwow==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxfmt/win32-arm64@0.26.0': + resolution: {integrity: sha512-3zRbqwVWK1mDhRhTknlQFpRFL9GhEB5GfU6U7wawnuEwpvi39q91kJ+SRJvJnhyPCARkjZBd1V8XnweN5IFd1g==} + cpu: [arm64] + os: [win32] + + '@oxfmt/win32-x64@0.26.0': + resolution: {integrity: sha512-m8TfIljU22i9UEIkD+slGPifTFeaCwIUfxszN3E6ABWP1KQbtwSw9Ak0TdoikibvukF/dtbeyG3WW63jv9DnEg==} + cpu: [x64] + os: [win32] + '@oxlint-tsgolint/darwin-arm64@0.10.1': resolution: {integrity: sha512-KGC4++BeEqrIcmDHiJt/e6/860PWJmUJjjp0mE+smpBmRXMjmOFFjrPmN+ZyCyVgf1WdmhPkQXsRSPeTR+2omw==} cpu: [arm64] @@ -242,6 +289,11 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + oxfmt@0.26.0: + resolution: {integrity: sha512-UDD1wFNwfeorMm2ZY0xy1KRAAvJ5NjKBfbDmiMwGP7baEHTq65cYpC0aPP+BGHc8weXUbSZaK8MdGyvuRUvS4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + oxlint-tsgolint@0.10.1: resolution: {integrity: sha512-EEHNdo5cW2w1xwYdBQ7d3IXDqWAtMkfVFrh+9gQ4kYbYJwygY4QXSh1eH80/xVipZdVKujAwBgg/nNNHk56kxQ==} hasBin: true @@ -308,6 +360,10 @@ packages: resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} + tinypool@2.0.0: + resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} + engines: {node: ^20.0.0 || >=22.0.0} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -333,6 +389,30 @@ snapshots: '@epic-web/invariant@1.0.0': {} + '@oxfmt/darwin-arm64@0.26.0': + optional: true + + '@oxfmt/darwin-x64@0.26.0': + optional: true + + '@oxfmt/linux-arm64-gnu@0.26.0': + optional: true + + '@oxfmt/linux-arm64-musl@0.26.0': + optional: true + + '@oxfmt/linux-x64-gnu@0.26.0': + optional: true + + '@oxfmt/linux-x64-musl@0.26.0': + optional: true + + '@oxfmt/win32-arm64@0.26.0': + optional: true + + '@oxfmt/win32-x64@0.26.0': + optional: true + '@oxlint-tsgolint/darwin-arm64@0.10.1': optional: true @@ -477,6 +557,19 @@ snapshots: dependencies: mimic-function: 5.0.1 + oxfmt@0.26.0: + dependencies: + tinypool: 2.0.0 + optionalDependencies: + '@oxfmt/darwin-arm64': 0.26.0 + '@oxfmt/darwin-x64': 0.26.0 + '@oxfmt/linux-arm64-gnu': 0.26.0 + '@oxfmt/linux-arm64-musl': 0.26.0 + '@oxfmt/linux-x64-gnu': 0.26.0 + '@oxfmt/linux-x64-musl': 0.26.0 + '@oxfmt/win32-arm64': 0.26.0 + '@oxfmt/win32-x64': 0.26.0 + oxlint-tsgolint@0.10.1: optionalDependencies: '@oxlint-tsgolint/darwin-arm64': 0.10.1 @@ -541,6 +634,8 @@ snapshots: dependencies: ansi-regex: 6.2.2 + tinypool@2.0.0: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0