From 1dd5bd667cb61fc21bee6ef0a701cf46a4ed0991 Mon Sep 17 00:00:00 2001 From: Rajhans Jadhao Date: Fri, 10 Jan 2025 18:21:50 +0530 Subject: [PATCH 01/38] fix(ext/node): use primordials in `ext/node/polyfills/_fs_common.ts` (#27589) Related to #24236 --- ext/node/polyfills/_fs/_fs_common.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/ext/node/polyfills/_fs/_fs_common.ts b/ext/node/polyfills/_fs/_fs_common.ts index 9ec474afa9..8358f0271c 100644 --- a/ext/node/polyfills/_fs/_fs_common.ts +++ b/ext/node/polyfills/_fs/_fs_common.ts @@ -1,8 +1,12 @@ // Copyright 2018-2025 the Deno authors. MIT license. -// TODO(petamoriken): enable prefer-primordials for node polyfills -// deno-lint-ignore-file prefer-primordials - +import { primordials } from "ext:core/mod.js"; +const { + StringPrototypeToLowerCase, + ArrayPrototypeIncludes, + ReflectApply, + Error, +} = primordials; import { O_APPEND, O_CREAT, @@ -85,8 +89,10 @@ export function getEncoding( export function checkEncoding(encoding: Encodings | null): Encodings | null { if (!encoding) return null; - encoding = encoding.toLowerCase() as Encodings; - if (["utf8", "hex", "base64", "ascii"].includes(encoding)) return encoding; + encoding = StringPrototypeToLowerCase(encoding) as Encodings; + if (ArrayPrototypeIncludes(["utf8", "hex", "base64", "ascii"], encoding)) { + return encoding; + } if (encoding === "utf-8") { return "utf8"; @@ -99,7 +105,7 @@ export function checkEncoding(encoding: Encodings | null): Encodings | null { const notImplementedEncodings = ["utf16le", "latin1", "ucs2"]; - if (notImplementedEncodings.includes(encoding as string)) { + if (ArrayPrototypeIncludes(notImplementedEncodings, encoding as string)) { notImplemented(`"${encoding}" encoding`); } @@ -241,5 +247,5 @@ export function makeCallback( ) { validateFunction(cb, "cb"); - return (...args: unknown[]) => Reflect.apply(cb!, this, args); + return (...args: unknown[]) => ReflectApply(cb!, this, args); } From c27248a8f36155d1677385998e36028a01fea02d Mon Sep 17 00:00:00 2001 From: David Sherret Date: Fri, 10 Jan 2025 14:48:43 -0500 Subject: [PATCH 02/38] refactor: remove `CliNpmReqResolver` trait in deno_resolver (#27616) --- Cargo.lock | 1 + cli/factory.rs | 3 +- cli/lsp/resolver.rs | 3 +- cli/npm/byonm.rs | 26 +++- cli/npm/managed/mod.rs | 176 +++++++++-------------- cli/npm/mod.rs | 19 ++- cli/standalone/mod.rs | 3 +- resolvers/deno/Cargo.toml | 1 + resolvers/deno/npm/byonm.rs | 30 +--- resolvers/deno/npm/managed/common.rs | 16 +-- resolvers/deno/npm/managed/local.rs | 16 ++- resolvers/deno/npm/managed/mod.rs | 176 ++++++++++++++++++++--- resolvers/deno/npm/managed/resolution.rs | 2 +- resolvers/deno/npm/mod.rs | 60 +++++--- resolvers/deno/sync.rs | 8 +- 15 files changed, 324 insertions(+), 216 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71979d448a..1f13898fe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2207,6 +2207,7 @@ dependencies = [ "deno_package_json", "deno_path_util", "deno_semver", + "log", "node_resolver", "parking_lot", "sys_traits", diff --git a/cli/factory.rs b/cli/factory.rs index d545fd6ddf..5cc99830bc 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -720,11 +720,10 @@ impl CliFactory { .get_or_try_init_async(async { let npm_resolver = self.npm_resolver().await?; Ok(Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions { - byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(), sys: self.sys(), in_npm_pkg_checker: self.in_npm_pkg_checker()?.clone(), node_resolver: self.node_resolver().await?.clone(), - npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(), + npm_resolver: npm_resolver.clone().into_byonm_or_managed(), }))) }) .await diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 9ae28405bf..57ef2e6a3c 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -796,10 +796,9 @@ impl<'a> ResolverFactory<'a> { let node_resolver = self.node_resolver()?; let npm_resolver = self.npm_resolver()?; Some(Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions { - byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(), in_npm_pkg_checker: self.in_npm_pkg_checker().clone(), node_resolver: node_resolver.clone(), - npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(), + npm_resolver: npm_resolver.clone().into_byonm_or_managed(), sys: self.sys.clone(), }))) }) diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index 2c11a417f3..bd29a6ec72 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -1,13 +1,17 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::path::Path; +use std::path::PathBuf; use std::sync::Arc; use deno_core::serde_json; +use deno_core::url::Url; use deno_resolver::npm::ByonmNpmResolver; use deno_resolver::npm::ByonmNpmResolverCreateOptions; -use deno_resolver::npm::CliNpmReqResolver; +use deno_resolver::npm::ByonmOrManagedNpmResolver; +use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_runtime::ops::process::NpmProcessStateProvider; +use deno_semver::package::PackageReq; use node_resolver::NpmPackageFolderResolver; use super::CliNpmResolver; @@ -44,18 +48,16 @@ impl CliNpmResolver for CliByonmNpmResolver { self } - fn into_npm_req_resolver(self: Arc) -> Arc { - self - } - fn into_process_state_provider( self: Arc, ) -> Arc { Arc::new(CliByonmWrapper(self)) } - fn into_maybe_byonm(self: Arc) -> Option> { - Some(self) + fn into_byonm_or_managed( + self: Arc, + ) -> ByonmOrManagedNpmResolver { + ByonmOrManagedNpmResolver::Byonm(self) } fn clone_snapshotted(&self) -> Arc { @@ -75,4 +77,14 @@ impl CliNpmResolver for CliByonmNpmResolver { // so we just return None to signify check caching is not supported None } + + fn resolve_pkg_folder_from_deno_module_req( + &self, + req: &PackageReq, + referrer: &Url, + ) -> Result { + self + .resolve_pkg_folder_from_deno_module_req(req, referrer) + .map_err(ResolvePkgFolderFromDenoReqError::Byonm) + } } diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs index 3f4390988a..8d2ede7e67 100644 --- a/cli/npm/managed/mod.rs +++ b/cli/npm/managed/mod.rs @@ -22,12 +22,11 @@ use deno_npm::NpmPackageId; use deno_npm::NpmResolutionPackage; use deno_npm::NpmSystemInfo; use deno_npm_cache::NpmCacheSetting; -use deno_path_util::fs::canonicalize_path_maybe_not_exists; -use deno_resolver::npm::managed::create_npm_fs_resolver; -use deno_resolver::npm::managed::NpmPackageFsResolver; -use deno_resolver::npm::managed::NpmPackageFsResolverPackageFolderError; use deno_resolver::npm::managed::NpmResolution; -use deno_resolver::npm::CliNpmReqResolver; +use deno_resolver::npm::managed::ResolvePkgFolderFromPkgIdError; +use deno_resolver::npm::ByonmOrManagedNpmResolver; +use deno_resolver::npm::ManagedNpmResolver; +use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_runtime::colors; use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageNv; @@ -36,8 +35,6 @@ use installer::AddPkgReqsResult; use installer::NpmResolutionInstaller; use installers::create_npm_fs_installer; use installers::NpmPackageFsInstaller; -use node_resolver::errors::PackageFolderResolveError; -use node_resolver::errors::PackageFolderResolveIoError; use node_resolver::NpmPackageFolderResolver; use super::CliNpmCache; @@ -46,7 +43,6 @@ use super::CliNpmRegistryInfoProvider; use super::CliNpmResolver; use super::CliNpmTarballCache; use super::InnerCliNpmResolverRef; -use super::ResolvePkgFolderFromDenoReqError; use crate::args::CliLockfile; use crate::args::LifecycleScriptsConfig; use crate::args::NpmInstallDepsProvider; @@ -181,22 +177,23 @@ fn create_inner( npm_system_info.clone(), lifecycle_scripts.clone(), ); - let fs_resolver = create_npm_fs_resolver( - &npm_cache_dir, - &npm_rc, - resolution.clone(), - sys.clone(), - node_modules_dir_path, - ); + let managed_npm_resolver = + Arc::new(ManagedNpmResolver::::new::( + &npm_cache_dir, + &npm_rc, + resolution.clone(), + sys.clone(), + node_modules_dir_path, + )); Arc::new(ManagedCliNpmResolver::new( fs_installer, - fs_resolver, maybe_lockfile, - registry_info_provider, + managed_npm_resolver, npm_cache, npm_cache_dir, npm_install_deps_provider, npm_rc, + registry_info_provider, resolution, sys, tarball_cache, @@ -281,13 +278,23 @@ pub enum PackageCaching<'a> { All, } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum ResolvePkgFolderFromDenoModuleError { + #[class(inherit)] + #[error(transparent)] + PackageNvNotFound(#[from] deno_npm::resolution::PackageNvNotFoundError), + #[class(inherit)] + #[error(transparent)] + ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError), +} + /// An npm resolver where the resolution is managed by Deno rather than /// the user bringing their own node_modules (BYONM) on the file system. pub struct ManagedCliNpmResolver { fs_installer: Arc, - fs_resolver: Arc, maybe_lockfile: Option>, registry_info_provider: Arc, + managed_npm_resolver: Arc>, npm_cache: Arc, npm_cache_dir: Arc, npm_install_deps_provider: Arc, @@ -304,45 +311,23 @@ pub struct ManagedCliNpmResolver { impl std::fmt::Debug for ManagedCliNpmResolver { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ManagedNpmResolver") + f.debug_struct("ManagedCliNpmResolver") .field("", &"") .finish() } } -#[derive(Debug, thiserror::Error, deno_error::JsError)] -pub enum ResolvePkgFolderFromPkgIdError { - #[class(inherit)] - #[error("{0}")] - NpmPackageFsResolverPackageFolder( - #[from] NpmPackageFsResolverPackageFolderError, - ), - #[class(inherit)] - #[error("{0}")] - Io(#[from] std::io::Error), -} - -#[derive(Debug, thiserror::Error, deno_error::JsError)] -pub enum ResolvePkgFolderFromDenoModuleError { - #[class(inherit)] - #[error("{0}")] - PackageNvNotFound(#[from] deno_npm::resolution::PackageNvNotFoundError), - #[class(inherit)] - #[error("{0}")] - ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError), -} - impl ManagedCliNpmResolver { #[allow(clippy::too_many_arguments)] pub fn new( fs_installer: Arc, - fs_resolver: Arc, maybe_lockfile: Option>, - registry_info_provider: Arc, + managed_npm_resolver: Arc>, npm_cache: Arc, npm_cache_dir: Arc, npm_install_deps_provider: Arc, npm_rc: Arc, + registry_info_provider: Arc, resolution: Arc, sys: CliSys, tarball_cache: Arc, @@ -357,13 +342,13 @@ impl ManagedCliNpmResolver { ); Self { fs_installer, - fs_resolver, maybe_lockfile, - registry_info_provider, + managed_npm_resolver, npm_cache, npm_cache_dir, npm_install_deps_provider, npm_rc, + registry_info_provider, text_only_progress_bar, resolution, resolution_installer, @@ -379,14 +364,9 @@ impl ManagedCliNpmResolver { &self, pkg_id: &NpmPackageId, ) -> Result { - let path = self.fs_resolver.package_folder(pkg_id)?; - let path = canonicalize_path_maybe_not_exists(&self.sys, &path)?; - log::debug!( - "Resolved package folder of {} to {}", - pkg_id.as_serialized(), - path.display() - ); - Ok(path) + self + .managed_npm_resolver + .resolve_pkg_folder_from_pkg_id(pkg_id) } /// Resolves the package id from the provided specifier. @@ -395,7 +375,7 @@ impl ManagedCliNpmResolver { specifier: &ModuleSpecifier, ) -> Result, AnyError> { let Some(cache_folder_id) = self - .fs_resolver + .managed_npm_resolver .resolve_package_cache_folder_id_from_specifier(specifier)? else { return Ok(None); @@ -419,7 +399,9 @@ impl ManagedCliNpmResolver { &self, package_id: &NpmPackageId, ) -> Result { - let package_folder = self.fs_resolver.package_folder(package_id)?; + let package_folder = self + .managed_npm_resolver + .resolve_pkg_folder_from_pkg_id(package_id)?; Ok(crate::util::fs::dir_size(&package_folder)?) } @@ -435,7 +417,12 @@ impl ManagedCliNpmResolver { self .resolve_pkg_id_from_pkg_req(req) .ok() - .and_then(|id| self.fs_resolver.package_folder(&id).ok()) + .and_then(|id| { + self + .managed_npm_resolver + .resolve_pkg_folder_from_pkg_id(&id) + .ok() + }) .map(|folder| folder.exists()) .unwrap_or(false) } @@ -648,7 +635,7 @@ impl ManagedCliNpmResolver { } pub fn maybe_node_modules_path(&self) -> Option<&Path> { - self.fs_resolver.node_modules_path() + self.managed_npm_resolver.node_modules_path() } pub fn global_cache_root_path(&self) -> &Path { @@ -672,61 +659,20 @@ fn npm_process_state( .unwrap() } -impl NpmPackageFolderResolver for ManagedCliNpmResolver { - fn resolve_package_folder_from_package( - &self, - name: &str, - referrer: &ModuleSpecifier, - ) -> Result { - let path = self - .fs_resolver - .resolve_package_folder_from_package(name, referrer)?; - let path = - canonicalize_path_maybe_not_exists(&self.sys, &path).map_err(|err| { - PackageFolderResolveIoError { - package_name: name.to_string(), - referrer: referrer.clone(), - source: err, - } - })?; - log::debug!("Resolved {} from {} to {}", name, referrer, path.display()); - Ok(path) - } -} - impl NpmProcessStateProvider for ManagedCliNpmResolver { fn get_npm_process_state(&self) -> String { npm_process_state( self.resolution.serialized_valid_snapshot(), - self.fs_resolver.node_modules_path(), + self.managed_npm_resolver.node_modules_path(), ) } } -impl CliNpmReqResolver for ManagedCliNpmResolver { - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - _referrer: &ModuleSpecifier, - ) -> Result { - let pkg_id = self.resolve_pkg_id_from_pkg_req(req).map_err(|err| { - ResolvePkgFolderFromDenoReqError::Managed(Box::new(err)) - })?; - self - .resolve_pkg_folder_from_pkg_id(&pkg_id) - .map_err(|err| ResolvePkgFolderFromDenoReqError::Managed(Box::new(err))) - } -} - impl CliNpmResolver for ManagedCliNpmResolver { fn into_npm_pkg_folder_resolver( self: Arc, ) -> Arc { - self - } - - fn into_npm_req_resolver(self: Arc) -> Arc { - self + self.managed_npm_resolver.clone() } fn into_process_state_provider( @@ -735,6 +681,12 @@ impl CliNpmResolver for ManagedCliNpmResolver { self } + fn into_byonm_or_managed( + self: Arc, + ) -> ByonmOrManagedNpmResolver { + ByonmOrManagedNpmResolver::Managed(self.managed_npm_resolver.clone()) + } + fn clone_snapshotted(&self) -> Arc { // create a new snapshotted npm resolution and resolver let npm_resolution = @@ -752,19 +704,19 @@ impl CliNpmResolver for ManagedCliNpmResolver { self.npm_system_info.clone(), self.lifecycle_scripts.clone(), ), - create_npm_fs_resolver( + self.maybe_lockfile.clone(), + Arc::new(ManagedNpmResolver::::new::( &self.npm_cache_dir, &self.npm_rc, npm_resolution.clone(), self.sys.clone(), self.root_node_modules_path().map(ToOwned::to_owned), - ), - self.maybe_lockfile.clone(), - self.registry_info_provider.clone(), + )), self.npm_cache.clone(), self.npm_cache_dir.clone(), self.npm_install_deps_provider.clone(), self.npm_rc.clone(), + self.registry_info_provider.clone(), npm_resolution, self.sys.clone(), self.tarball_cache.clone(), @@ -779,7 +731,7 @@ impl CliNpmResolver for ManagedCliNpmResolver { } fn root_node_modules_path(&self) -> Option<&Path> { - self.fs_resolver.node_modules_path() + self.managed_npm_resolver.node_modules_path() } fn check_state_hash(&self) -> Option { @@ -794,11 +746,23 @@ impl CliNpmResolver for ManagedCliNpmResolver { let mut hasher = FastInsecureHasher::new_without_deno_version(); // ensure the cache gets busted when turning nodeModulesDir on or off // as this could cause changes in resolution - hasher.write_hashable(self.fs_resolver.node_modules_path().is_some()); + hasher + .write_hashable(self.managed_npm_resolver.node_modules_path().is_some()); for (pkg_req, pkg_nv) in package_reqs { hasher.write_hashable(&pkg_req); hasher.write_hashable(&pkg_nv); } Some(hasher.finish()) } + + fn resolve_pkg_folder_from_deno_module_req( + &self, + req: &PackageReq, + referrer: &Url, + ) -> Result { + self + .managed_npm_resolver + .resolve_pkg_folder_from_deno_module_req(req, referrer) + .map_err(ResolvePkgFolderFromDenoReqError::Managed) + } } diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 837fe26cf9..052a98e6cf 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -5,6 +5,7 @@ mod managed; mod permission_checker; use std::path::Path; +use std::path::PathBuf; use std::sync::Arc; use dashmap::DashMap; @@ -15,7 +16,7 @@ use deno_error::JsErrorBox; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageInfo; use deno_resolver::npm::ByonmNpmResolver; -use deno_resolver::npm::CliNpmReqResolver; +use deno_resolver::npm::ByonmOrManagedNpmResolver; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_runtime::ops::process::NpmProcessStateProvider; use deno_semver::package::PackageNv; @@ -136,17 +137,17 @@ pub enum InnerCliNpmResolverRef<'a> { Byonm(&'a CliByonmNpmResolver), } -pub trait CliNpmResolver: CliNpmReqResolver { +// todo(dsherret): replace with an enum +pub trait CliNpmResolver: Send + Sync + std::fmt::Debug { fn into_npm_pkg_folder_resolver( self: Arc, ) -> Arc; - fn into_npm_req_resolver(self: Arc) -> Arc; fn into_process_state_provider( self: Arc, ) -> Arc; - fn into_maybe_byonm(self: Arc) -> Option> { - None - } + fn into_byonm_or_managed( + self: Arc, + ) -> ByonmOrManagedNpmResolver; fn clone_snapshotted(&self) -> Arc; @@ -166,6 +167,12 @@ pub trait CliNpmResolver: CliNpmReqResolver { } } + fn resolve_pkg_folder_from_deno_module_req( + &self, + req: &PackageReq, + referrer: &Url, + ) -> Result; + fn root_node_modules_path(&self) -> Option<&Path>; /// Returns a hash returning the state of the npm resolver diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index ecf9805b2d..961e8d6b51 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -849,11 +849,10 @@ pub async fn run( let node_analysis_cache = NodeAnalysisCache::new(cache_db.node_analysis_db()); let npm_req_resolver = Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions { - byonm_resolver: (npm_resolver.clone()).into_maybe_byonm(), sys: sys.clone(), in_npm_pkg_checker: in_npm_pkg_checker.clone(), node_resolver: node_resolver.clone(), - npm_req_resolver: npm_resolver.clone().into_npm_req_resolver(), + npm_resolver: npm_resolver.clone().into_byonm_or_managed(), })); let cjs_esm_code_analyzer = CliCjsCodeAnalyzer::new( node_analysis_cache, diff --git a/resolvers/deno/Cargo.toml b/resolvers/deno/Cargo.toml index 1c603ecaed..534a07ccf2 100644 --- a/resolvers/deno/Cargo.toml +++ b/resolvers/deno/Cargo.toml @@ -30,6 +30,7 @@ deno_npm.workspace = true deno_package_json.workspace = true deno_path_util.workspace = true deno_semver.workspace = true +log.workspace = true node_resolver.workspace = true parking_lot.workspace = true sys_traits.workspace = true diff --git a/resolvers/deno/npm/byonm.rs b/resolvers/deno/npm/byonm.rs index 710608490a..bf25ba5646 100644 --- a/resolvers/deno/npm/byonm.rs +++ b/resolvers/deno/npm/byonm.rs @@ -27,8 +27,8 @@ use thiserror::Error; use url::Url; use super::local::normalize_pkg_name_for_node_modules_deno_folder; -use super::CliNpmReqResolver; -use super::ResolvePkgFolderFromDenoReqError; +use crate::sync::MaybeSend; +use crate::sync::MaybeSync; #[derive(Debug, Error, deno_error::JsError)] pub enum ByonmResolvePkgFolderFromDenoReqError { @@ -377,35 +377,13 @@ impl } } -impl< - Sys: FsCanonicalize - + FsMetadata - + FsRead - + FsReadDir - + Send - + Sync - + std::fmt::Debug, - > CliNpmReqResolver for ByonmNpmResolver -{ - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - referrer: &Url, - ) -> Result { - ByonmNpmResolver::resolve_pkg_folder_from_deno_module_req( - self, req, referrer, - ) - .map_err(ResolvePkgFolderFromDenoReqError::Byonm) - } -} - impl< TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir - + Send - + Sync + + MaybeSend + + MaybeSync + std::fmt::Debug, > NpmPackageFolderResolver for ByonmNpmResolver { diff --git a/resolvers/deno/npm/managed/common.rs b/resolvers/deno/npm/managed/common.rs index 8a523f3ea4..6569a4594f 100644 --- a/resolvers/deno/npm/managed/common.rs +++ b/resolvers/deno/npm/managed/common.rs @@ -12,14 +12,9 @@ use crate::sync::MaybeSend; use crate::sync::MaybeSync; #[allow(clippy::disallowed_types)] -pub(super) type NpmPackageFsResolverRc = +pub type NpmPackageFsResolverRc = crate::sync::MaybeArc; -#[derive(Debug, thiserror::Error, deno_error::JsError)] -#[class(generic)] -#[error("Package folder not found for '{0}'")] -pub struct NpmPackageFsResolverPackageFolderError(deno_semver::StackString); - /// Part of the resolution that interacts with the file system. pub trait NpmPackageFsResolver: NpmPackageFolderResolver + MaybeSend + MaybeSync @@ -29,15 +24,6 @@ pub trait NpmPackageFsResolver: fn maybe_package_folder(&self, package_id: &NpmPackageId) -> Option; - fn package_folder( - &self, - package_id: &NpmPackageId, - ) -> Result { - self.maybe_package_folder(package_id).ok_or_else(|| { - NpmPackageFsResolverPackageFolderError(package_id.as_serialized()) - }) - } - fn resolve_package_cache_folder_id_from_specifier( &self, specifier: &Url, diff --git a/resolvers/deno/npm/managed/local.rs b/resolvers/deno/npm/managed/local.rs index f23f7bd591..3aa1275d66 100644 --- a/resolvers/deno/npm/managed/local.rs +++ b/resolvers/deno/npm/managed/local.rs @@ -23,12 +23,14 @@ use super::resolution::NpmResolutionRc; use super::NpmPackageFsResolver; use crate::npm::local::get_package_folder_id_folder_name_from_parts; use crate::npm::local::get_package_folder_id_from_folder_name; +use crate::sync::MaybeSend; +use crate::sync::MaybeSync; /// Resolver that creates a local node_modules directory /// and resolves packages from it. #[derive(Debug)] pub struct LocalNpmPackageResolver< - TSys: FsCanonicalize + FsMetadata + Send + Sync, + TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync, > { resolution: NpmResolutionRc, sys: TSys, @@ -36,7 +38,7 @@ pub struct LocalNpmPackageResolver< root_node_modules_url: Url, } -impl +impl LocalNpmPackageResolver { #[allow(clippy::too_many_arguments)] @@ -99,8 +101,9 @@ impl } } -impl - NpmPackageFolderResolver for LocalNpmPackageResolver +impl< + TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync + std::fmt::Debug, + > NpmPackageFolderResolver for LocalNpmPackageResolver { fn resolve_package_folder_from_package( &self, @@ -160,8 +163,9 @@ impl } } -impl - NpmPackageFsResolver for LocalNpmPackageResolver +impl< + TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync + std::fmt::Debug, + > NpmPackageFsResolver for LocalNpmPackageResolver { fn node_modules_path(&self) -> Option<&Path> { Some(self.root_node_modules_path.as_ref()) diff --git a/resolvers/deno/npm/managed/mod.rs b/resolvers/deno/npm/managed/mod.rs index d08ee07d6a..a9775ee374 100644 --- a/resolvers/deno/npm/managed/mod.rs +++ b/resolvers/deno/npm/managed/mod.rs @@ -8,42 +8,180 @@ mod resolution; use std::path::Path; use std::path::PathBuf; +use deno_npm::resolution::PackageReqNotFoundError; +use deno_npm::NpmPackageCacheFolderId; +use deno_npm::NpmPackageId; +use deno_path_util::fs::canonicalize_path_maybe_not_exists; +use deno_semver::package::PackageReq; use node_resolver::InNpmPackageChecker; +use node_resolver::NpmPackageFolderResolver; use sys_traits::FsCanonicalize; use sys_traits::FsMetadata; use url::Url; -pub use self::common::NpmPackageFsResolver; -pub use self::common::NpmPackageFsResolverPackageFolderError; +use self::common::NpmPackageFsResolver; use self::common::NpmPackageFsResolverRc; use self::global::GlobalNpmPackageResolver; use self::local::LocalNpmPackageResolver; pub use self::resolution::NpmResolution; -use self::resolution::NpmResolutionRc; +pub use self::resolution::NpmResolutionRc; use crate::sync::new_rc; +use crate::sync::MaybeSend; +use crate::sync::MaybeSync; use crate::NpmCacheDirRc; use crate::ResolvedNpmRcRc; -pub fn create_npm_fs_resolver< - TSys: FsCanonicalize + FsMetadata + std::fmt::Debug + Send + Sync + 'static, ->( - npm_cache_dir: &NpmCacheDirRc, - npm_rc: &ResolvedNpmRcRc, +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[error(transparent)] +pub enum ResolvePkgFolderFromPkgIdError { + #[class(inherit)] + #[error(transparent)] + NotFound(#[from] NpmManagedPackageFolderNotFoundError), + #[class(inherit)] + #[error(transparent)] + FailedCanonicalizing(#[from] FailedCanonicalizingError), +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[class(generic)] +#[error("Package folder not found for '{0}'")] +pub struct NpmManagedPackageFolderNotFoundError(deno_semver::StackString); + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[class(generic)] +#[error("Failed canonicalizing '{}'", path.display())] +pub struct FailedCanonicalizingError { + path: PathBuf, + #[source] + source: std::io::Error, +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum ManagedResolvePkgFolderFromDenoReqError { + #[class(inherit)] + #[error(transparent)] + PackageReqNotFound(#[from] PackageReqNotFoundError), + #[class(inherit)] + #[error(transparent)] + ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError), +} + +#[allow(clippy::disallowed_types)] +pub type ManagedNpmResolverRc = + crate::sync::MaybeArc>; + +#[derive(Debug)] +pub struct ManagedNpmResolver { + fs_resolver: NpmPackageFsResolverRc, resolution: NpmResolutionRc, sys: TSys, - maybe_node_modules_path: Option, -) -> NpmPackageFsResolverRc { - match maybe_node_modules_path { - Some(node_modules_folder) => new_rc(LocalNpmPackageResolver::new( - resolution, +} + +impl ManagedNpmResolver { + pub fn new< + TCreateSys: FsCanonicalize + + FsMetadata + + std::fmt::Debug + + MaybeSend + + MaybeSync + + Clone + + 'static, + >( + npm_cache_dir: &NpmCacheDirRc, + npm_rc: &ResolvedNpmRcRc, + resolution: NpmResolutionRc, + sys: TCreateSys, + maybe_node_modules_path: Option, + ) -> ManagedNpmResolver { + let fs_resolver: NpmPackageFsResolverRc = match maybe_node_modules_path { + Some(node_modules_folder) => new_rc(LocalNpmPackageResolver::new( + resolution.clone(), + sys.clone(), + node_modules_folder, + )), + None => new_rc(GlobalNpmPackageResolver::new( + npm_cache_dir.clone(), + npm_rc.clone(), + resolution.clone(), + )), + }; + + ManagedNpmResolver { + fs_resolver, sys, - node_modules_folder, - )), - None => new_rc(GlobalNpmPackageResolver::new( - npm_cache_dir.clone(), - npm_rc.clone(), resolution, - )), + } + } + + #[inline] + pub fn node_modules_path(&self) -> Option<&Path> { + self.fs_resolver.node_modules_path() + } + + pub fn resolve_pkg_folder_from_pkg_id( + &self, + package_id: &NpmPackageId, + ) -> Result { + let path = self + .fs_resolver + .maybe_package_folder(package_id) + .ok_or_else(|| { + NpmManagedPackageFolderNotFoundError(package_id.as_serialized()) + })?; + // todo(dsherret): investigate if this canonicalization is always + // necessary. For example, maybe it's not necessary for the global cache + let path = canonicalize_path_maybe_not_exists(&self.sys, &path).map_err( + |source| FailedCanonicalizingError { + path: path.to_path_buf(), + source, + }, + )?; + log::debug!( + "Resolved package folder of {} to {}", + package_id.as_serialized(), + path.display() + ); + Ok(path) + } + + pub fn resolve_pkg_folder_from_deno_module_req( + &self, + req: &PackageReq, + _referrer: &Url, + ) -> Result { + let pkg_id = self.resolution.resolve_pkg_id_from_pkg_req(req)?; + Ok(self.resolve_pkg_folder_from_pkg_id(&pkg_id)?) + } + + #[inline] + pub fn resolve_package_cache_folder_id_from_specifier( + &self, + specifier: &Url, + ) -> Result, std::io::Error> { + self + .fs_resolver + .resolve_package_cache_folder_id_from_specifier(specifier) + } +} + +impl + NpmPackageFolderResolver for ManagedNpmResolver +{ + fn resolve_package_folder_from_package( + &self, + specifier: &str, + referrer: &Url, + ) -> Result { + let path = self + .fs_resolver + .resolve_package_folder_from_package(specifier, referrer)?; + log::debug!( + "Resolved {} from {} to {}", + specifier, + referrer, + path.display() + ); + Ok(path) } } diff --git a/resolvers/deno/npm/managed/resolution.rs b/resolvers/deno/npm/managed/resolution.rs index 40ab91202c..8ddd1ac70f 100644 --- a/resolvers/deno/npm/managed/resolution.rs +++ b/resolvers/deno/npm/managed/resolution.rs @@ -18,7 +18,7 @@ use deno_semver::package::PackageReq; use parking_lot::RwLock; #[allow(clippy::disallowed_types)] -pub(super) type NpmResolutionRc = crate::sync::MaybeArc; +pub type NpmResolutionRc = crate::sync::MaybeArc; /// Handles updating and storing npm resolution in memory. /// diff --git a/resolvers/deno/npm/mod.rs b/resolvers/deno/npm/mod.rs index 4b102d6491..26b156d29d 100644 --- a/resolvers/deno/npm/mod.rs +++ b/resolvers/deno/npm/mod.rs @@ -36,9 +36,9 @@ pub use self::local::get_package_folder_id_folder_name; pub use self::local::normalize_pkg_name_for_node_modules_deno_folder; use self::managed::create_managed_in_npm_pkg_checker; use self::managed::ManagedInNpmPkgCheckerCreateOptions; +pub use self::managed::ManagedNpmResolver; +pub use self::managed::ManagedNpmResolverRc; use crate::sync::new_rc; -use crate::sync::MaybeSend; -use crate::sync::MaybeSync; mod byonm; mod local; @@ -108,37 +108,50 @@ pub enum ResolveReqWithSubPathErrorKind { #[derive(Debug, Error, JsError)] pub enum ResolvePkgFolderFromDenoReqError { #[class(inherit)] - #[error("{0}")] - Managed(Box), + #[error(transparent)] + Managed(managed::ManagedResolvePkgFolderFromDenoReqError), #[class(inherit)] #[error(transparent)] - Byonm(#[from] ByonmResolvePkgFolderFromDenoReqError), + Byonm(byonm::ByonmResolvePkgFolderFromDenoReqError), } -#[allow(clippy::disallowed_types)] -pub type CliNpmReqResolverRc = crate::sync::MaybeArc; +#[derive(Debug, Clone)] +pub enum ByonmOrManagedNpmResolver< + TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, +> { + /// The resolver when "bring your own node_modules" is enabled where Deno + /// does not setup the node_modules directories automatically, but instead + /// uses what already exists on the file system. + Byonm(ByonmNpmResolverRc), + Managed(ManagedNpmResolverRc), +} -// todo(dsherret): a temporary trait until we extract -// out the CLI npm resolver into here -pub trait CliNpmReqResolver: Debug + MaybeSend + MaybeSync { - fn resolve_pkg_folder_from_deno_module_req( +impl + ByonmOrManagedNpmResolver +{ + pub fn resolve_pkg_folder_from_deno_module_req( &self, req: &PackageReq, referrer: &Url, - ) -> Result; + ) -> Result { + match self { + ByonmOrManagedNpmResolver::Byonm(byonm_resolver) => byonm_resolver + .resolve_pkg_folder_from_deno_module_req(req, referrer) + .map_err(ResolvePkgFolderFromDenoReqError::Byonm), + ByonmOrManagedNpmResolver::Managed(managed_resolver) => managed_resolver + .resolve_pkg_folder_from_deno_module_req(req, referrer) + .map_err(ResolvePkgFolderFromDenoReqError::Managed), + } + } } pub struct NpmReqResolverOptions< TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { - /// The resolver when "bring your own node_modules" is enabled where Deno - /// does not setup the node_modules directories automatically, but instead - /// uses what already exists on the file system. - pub byonm_resolver: Option>, pub in_npm_pkg_checker: InNpmPackageCheckerRc, pub node_resolver: NodeResolverRc, - pub npm_req_resolver: CliNpmReqResolverRc, + pub npm_resolver: ByonmOrManagedNpmResolver, pub sys: TSys, } @@ -151,11 +164,10 @@ pub struct NpmReqResolver< TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { - byonm_resolver: Option>, sys: TSys, in_npm_pkg_checker: InNpmPackageCheckerRc, node_resolver: NodeResolverRc, - npm_resolver: CliNpmReqResolverRc, + npm_resolver: ByonmOrManagedNpmResolver, } impl< @@ -167,11 +179,10 @@ impl< options: NpmReqResolverOptions, ) -> Self { Self { - byonm_resolver: options.byonm_resolver, sys: options.sys, in_npm_pkg_checker: options.in_npm_pkg_checker, node_resolver: options.node_resolver, - npm_resolver: options.npm_req_resolver, + npm_resolver: options.npm_resolver, } } @@ -213,7 +224,7 @@ impl< match resolution_result { Ok(url) => Ok(url), Err(err) => { - if self.byonm_resolver.is_some() { + if matches!(self.npm_resolver, ByonmOrManagedNpmResolver::Byonm(_)) { let package_json_path = package_folder.join("package.json"); if !self.sys.fs_exists_no_err(&package_json_path) { return Err( @@ -281,7 +292,10 @@ impl< .into_box(), ); } - if let Some(byonm_npm_resolver) = &self.byonm_resolver { + if let ByonmOrManagedNpmResolver::Byonm( + byonm_npm_resolver, + ) = &self.npm_resolver + { if byonm_npm_resolver .find_ancestor_package_json_with_dep( package_name, diff --git a/resolvers/deno/sync.rs b/resolvers/deno/sync.rs index 1734e84231..af3e290bb2 100644 --- a/resolvers/deno/sync.rs +++ b/resolvers/deno/sync.rs @@ -43,7 +43,13 @@ mod inner { } impl MaybeDashMap { - pub fn get<'a>(&'a self, key: &K) -> Option> { + pub fn get<'a, Q: Eq + Hash + ?Sized>( + &'a self, + key: &Q, + ) -> Option> + where + K: std::borrow::Borrow, + { Ref::filter_map(self.0.borrow(), |map| map.get(key)).ok() } From f6dcc135379d2bc78c8489d483ed7da65174f953 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Fri, 10 Jan 2025 20:39:43 -0500 Subject: [PATCH 03/38] fix(regression): show bare-node-builtin hint when using an import map (#27632) --- cli/graph_util.rs | 12 ++++-------- tests/specs/run/node_prefix_missing/__test__.jsonc | 5 +++++ tests/specs/run/node_prefix_missing/config.json | 1 + tests/specs/run/node_prefix_missing/deno.json | 3 +++ tests/specs/run/node_prefix_missing/main.ts.out | 2 +- .../specs/run/node_prefix_missing/main_no_config.out | 3 +++ 6 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 tests/specs/run/node_prefix_missing/deno.json create mode 100644 tests/specs/run/node_prefix_missing/main_no_config.out diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 84beee027e..8da44c76ab 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -36,7 +36,6 @@ use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::jsr::JsrDepPackageReq; use deno_semver::package::PackageNv; use deno_semver::SmallStackString; -use import_map::ImportMapError; use node_resolver::InNpmPackageChecker; use crate::args::config_to_deno_graph_workspace_member; @@ -1024,14 +1023,11 @@ fn get_resolution_error_bare_specifier( { Some(specifier.as_str()) } else if let ResolutionError::ResolverError { error, .. } = error { - if let ResolveError::Other(error) = (*error).as_ref() { - if let Some(import_map::ImportMapErrorKind::UnmappedBareSpecifier( + if let ResolveError::ImportMap(error) = (*error).as_ref() { + if let import_map::ImportMapErrorKind::UnmappedBareSpecifier( specifier, _, - )) = error - .as_any() - .downcast_ref::() - .map(|e| &**e) + ) = error.as_kind() { Some(specifier.as_str()) } else { @@ -1324,7 +1320,7 @@ mod test { let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap(); let err = import_map.resolve(input, &specifier).err().unwrap(); let err = ResolutionError::ResolverError { - error: Arc::new(ResolveError::Other(JsErrorBox::from_err(err))), + error: Arc::new(ResolveError::ImportMap(err)), specifier: input.to_string(), range: Range { specifier, diff --git a/tests/specs/run/node_prefix_missing/__test__.jsonc b/tests/specs/run/node_prefix_missing/__test__.jsonc index 305020ed97..fa4504fdc2 100644 --- a/tests/specs/run/node_prefix_missing/__test__.jsonc +++ b/tests/specs/run/node_prefix_missing/__test__.jsonc @@ -5,6 +5,11 @@ "output": "main.ts.out", "exitCode": 1 }, + "basic_no_config": { + "args": "run --quiet --no-config main.ts", + "output": "main_no_config.out", + "exitCode": 1 + }, "unstable_bare_node_builtins_enabled": { "args": "run --unstable-bare-node-builtins main.ts", "output": "feature_enabled.out" diff --git a/tests/specs/run/node_prefix_missing/config.json b/tests/specs/run/node_prefix_missing/config.json index 72f40aaf36..52f5f4d4f4 100644 --- a/tests/specs/run/node_prefix_missing/config.json +++ b/tests/specs/run/node_prefix_missing/config.json @@ -1,3 +1,4 @@ { + "imports": {}, "unstable": ["bare-node-builtins"] } diff --git a/tests/specs/run/node_prefix_missing/deno.json b/tests/specs/run/node_prefix_missing/deno.json new file mode 100644 index 0000000000..f6ca8454c5 --- /dev/null +++ b/tests/specs/run/node_prefix_missing/deno.json @@ -0,0 +1,3 @@ +{ + "imports": {} +} diff --git a/tests/specs/run/node_prefix_missing/main.ts.out b/tests/specs/run/node_prefix_missing/main.ts.out index 48b4e37e27..c7067c6026 100644 --- a/tests/specs/run/node_prefix_missing/main.ts.out +++ b/tests/specs/run/node_prefix_missing/main.ts.out @@ -1,3 +1,3 @@ -error: Relative import path "fs" not prefixed with / or ./ or ../ +error: Relative import path "fs" not prefixed with / or ./ or ../ and not in import map from "[WILDLINE]/main.ts" hint: If you want to use a built-in Node module, add a "node:" prefix (ex. "node:fs"). at file:///[WILDCARD]/main.ts:1:16 diff --git a/tests/specs/run/node_prefix_missing/main_no_config.out b/tests/specs/run/node_prefix_missing/main_no_config.out new file mode 100644 index 0000000000..48b4e37e27 --- /dev/null +++ b/tests/specs/run/node_prefix_missing/main_no_config.out @@ -0,0 +1,3 @@ +error: Relative import path "fs" not prefixed with / or ./ or ../ + hint: If you want to use a built-in Node module, add a "node:" prefix (ex. "node:fs"). + at file:///[WILDCARD]/main.ts:1:16 From 70c822bfe2180a2c98f52f02ded6aa1f19bc5b89 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Fri, 10 Jan 2025 19:26:01 -0800 Subject: [PATCH 04/38] fix(lsp/check): don't resolve unknown media types to a `.js` extension (#27631) Fixes https://github.com/denoland/deno/issues/25762. Note that some of the things in that issue are not resolved (vite/client types not working properly which has other root causes), but the wildcard module augmentation specifically is fixed by this. We were telling TSC that files with unknown media types had an extension of `.js`, so the ambient module declarations weren't applying. Instead, just don't resolve them, so the ambient declaration applies. --- cli/lsp/tsc.rs | 14 ++++++++++---- cli/tsc/99_main_compiler.js | 8 ++++---- cli/tsc/mod.rs | 27 ++++++++++++++++---------- tests/integration/lsp_tests.rs | 35 ++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index cd1a724f5e..8d9a5a46a1 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -4509,11 +4509,12 @@ fn op_release( #[op2] #[serde] +#[allow(clippy::type_complexity)] fn op_resolve( state: &mut OpState, #[string] base: String, #[serde] specifiers: Vec<(bool, String)>, -) -> Result>, deno_core::url::ParseError> { +) -> Result)>>, deno_core::url::ParseError> { op_resolve_inner(state, ResolveArgs { base, specifiers }) } @@ -4595,10 +4596,11 @@ async fn op_poll_requests( } #[inline] +#[allow(clippy::type_complexity)] fn op_resolve_inner( state: &mut OpState, args: ResolveArgs, -) -> Result>, deno_core::url::ParseError> { +) -> Result)>>, deno_core::url::ParseError> { let state = state.borrow_mut::(); let mark = state.performance.mark_with_args("tsc.op.op_resolve", &args); let referrer = state.specifier_map.normalize(&args.base)?; @@ -4611,7 +4613,11 @@ fn op_resolve_inner( o.map(|(s, mt)| { ( state.specifier_map.denormalize(&s), - mt.as_ts_extension().to_string(), + if matches!(mt, MediaType::Unknown) { + None + } else { + Some(mt.as_ts_extension().to_string()) + }, ) }) }) @@ -6461,7 +6467,7 @@ mod tests { resolved, vec![Some(( temp_dir.url().join("b.ts").unwrap().to_string(), - MediaType::TypeScript.as_ts_extension().to_string() + Some(MediaType::TypeScript.as_ts_extension().to_string()) ))] ); } diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js index 25813c3f9d..b3279f54ac 100644 --- a/cli/tsc/99_main_compiler.js +++ b/cli/tsc/99_main_compiler.js @@ -723,7 +723,7 @@ delete Object.prototype.__proto__; } : arg; if (fileReference.fileName.startsWith("npm:")) { - /** @type {[string, ts.Extension] | undefined} */ + /** @type {[string, ts.Extension | null] | undefined} */ const resolved = ops.op_resolve( containingFilePath, [ @@ -735,7 +735,7 @@ delete Object.prototype.__proto__; ], ], )?.[0]; - if (resolved) { + if (resolved && resolved[1]) { return { resolvedTypeReferenceDirective: { primary: true, @@ -785,7 +785,7 @@ delete Object.prototype.__proto__; debug(` base: ${base}`); debug(` specifiers: ${specifiers.map((s) => s[1]).join(", ")}`); } - /** @type {Array<[string, ts.Extension] | undefined>} */ + /** @type {Array<[string, ts.Extension | null] | undefined>} */ const resolved = ops.op_resolve( base, specifiers, @@ -793,7 +793,7 @@ delete Object.prototype.__proto__; if (resolved) { /** @type {Array} */ const result = resolved.map((item) => { - if (item) { + if (item && item[1]) { const [resolvedFileName, extension] = item; return { resolvedModule: { diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 1473b8a8d9..f645a5f6b8 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -746,7 +746,7 @@ fn op_resolve( state: &mut OpState, #[string] base: String, #[serde] specifiers: Vec<(bool, String)>, -) -> Result, ResolveError> { +) -> Result)>, ResolveError> { op_resolve_inner(state, ResolveArgs { base, specifiers }) } @@ -754,9 +754,9 @@ fn op_resolve( fn op_resolve_inner( state: &mut OpState, args: ResolveArgs, -) -> Result, ResolveError> { +) -> Result)>, ResolveError> { let state = state.borrow_mut::(); - let mut resolved: Vec<(String, &'static str)> = + let mut resolved: Vec<(String, Option<&'static str>)> = Vec::with_capacity(args.specifiers.len()); let referrer = if let Some(remapped_specifier) = state.maybe_remapped_specifier(&args.base) @@ -770,14 +770,14 @@ fn op_resolve_inner( if specifier.starts_with("node:") { resolved.push(( MISSING_DEPENDENCY_SPECIFIER.to_string(), - MediaType::Dts.as_ts_extension(), + Some(MediaType::Dts.as_ts_extension()), )); continue; } if specifier.starts_with("asset:///") { let ext = MediaType::from_str(&specifier).as_ts_extension(); - resolved.push((specifier, ext)); + resolved.push((specifier, Some(ext))); continue; } @@ -857,14 +857,15 @@ fn op_resolve_inner( ( specifier_str, match media_type { - MediaType::Css => ".js", // surface these as .js for typescript - media_type => media_type.as_ts_extension(), + MediaType::Css => Some(".js"), // surface these as .js for typescript + MediaType::Unknown => None, + media_type => Some(media_type.as_ts_extension()), }, ) } None => ( MISSING_DEPENDENCY_SPECIFIER.to_string(), - MediaType::Dts.as_ts_extension(), + Some(MediaType::Dts.as_ts_extension()), ), }; log::debug!("Resolved {} from {} to {:?}", specifier, referrer, result); @@ -1441,7 +1442,10 @@ mod tests { }, ) .expect("should have invoked op"); - assert_eq!(actual, vec![("https://deno.land/x/b.ts".into(), ".ts")]); + assert_eq!( + actual, + vec![("https://deno.land/x/b.ts".into(), Some(".ts"))] + ); } #[tokio::test] @@ -1460,7 +1464,10 @@ mod tests { }, ) .expect("should have not errored"); - assert_eq!(actual, vec![(MISSING_DEPENDENCY_SPECIFIER.into(), ".d.ts")]); + assert_eq!( + actual, + vec![(MISSING_DEPENDENCY_SPECIFIER.into(), Some(".d.ts"))] + ); } #[tokio::test] diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 247851da9c..a25710b2b1 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -17221,3 +17221,38 @@ fn lsp_wasm_module() { ); client.shutdown(); } + +#[test] +fn wildcard_augment() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + let temp_dir = context.temp_dir().path(); + let source = source_file( + temp_dir.join("index.ts"), + r#" + import styles from "./hello_world.scss"; + + function bar(v: string): string { + return v; + } + + bar(styles); + "#, + ); + temp_dir.join("index.d.ts").write( + r#" + declare module '*.scss' { + const content: string; + export default content; + } + "#, + ); + temp_dir + .join("hello_world.scss") + .write("body { color: red; }"); + + client.initialize_default(); + + let diagnostics = client.did_open_file(&source); + assert_eq!(diagnostics.all().len(), 0); +} From 2091691164eadecd22af28e00abf15d5cd0ae377 Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Mon, 13 Jan 2025 18:11:26 +0900 Subject: [PATCH 05/38] fix(ext/node): apply `@npmcli/agent` workaround to `npm-check-updates` (#27639) See the comment https://github.com/denoland/deno/pull/25470#issuecomment-2435077722 for the reason why we do this workaround to make `make-fetch-happen` work in Deno This PR applies the same workaround to `npm-check-updates` package. `npm-check-updates` internally uses [`npm-registry-fetch`](https://www.npmjs.com/package/npm-registry-fetch) which uses [`make-fetch-happen`](https://www.npmjs.com/package/make-fetch-happen) (the problematic package) for making http request to npm registry. The detection of `make-fetch-happen` doesn't work for `npm-check-updates` because we use call stack at `net.Socket` constructor to check if it's called from `make-fetch-happen`, but `npm-check-updates` bundles its dependency and the check doesn't work. This PR adds the check of `npm-check-updates` string in call stack in net.Socket constructor to trigger the workaroud. closes #27629 --- ext/node/polyfills/net.ts | 11 +- .../npm-check-updates-17.1.13.tgz | Bin 0 -> 1495496 bytes .../npm/npm-check-updates/registry.json | 201 ++++++++++++++++++ .../npm/npm_check_updates/__test__.jsonc | 7 + tests/specs/npm/npm_check_updates/output.out | 2 + .../specs/npm/npm_check_updates/package.json | 5 + 6 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 tests/registry/npm/npm-check-updates/npm-check-updates-17.1.13.tgz create mode 100644 tests/registry/npm/npm-check-updates/registry.json create mode 100644 tests/specs/npm/npm_check_updates/__test__.jsonc create mode 100644 tests/specs/npm/npm_check_updates/output.out create mode 100644 tests/specs/npm/npm_check_updates/package.json diff --git a/ext/node/polyfills/net.ts b/ext/node/polyfills/net.ts index 3f7603079e..bebdd8dade 100644 --- a/ext/node/polyfills/net.ts +++ b/ext/node/polyfills/net.ts @@ -1224,15 +1224,20 @@ export class Socket extends Duplex { super(options); - // Note: If the socket is created from @npmcli/agent, the 'socket' event - // on ClientRequest object happens after 'connect' event on Socket object. + // Note: If the socket is created from one of: + // - @npmcli/agent + // - npm-check-updates (bundles @npmcli/agent as a dependency) + // the 'socket' event on ClientRequest object happens after 'connect' event on Socket object. // That swaps the sequence of op_node_http_request_with_conn() call and // initial socket read. That causes op_node_http_request_with_conn() not // working. // To avoid the above situation, we detect the socket created from // @npmcli/agent and pause the socket (and also skips the startTls call // if it's TLSSocket) - this._isNpmAgent = new Error().stack?.includes("@npmcli/agent") || false; + // TODO(kt3k): Remove this workaround + const errorStack = new Error().stack; + this._isNpmAgent = errorStack?.includes("@npmcli/agent") || + errorStack?.includes("npm-check-updates") || false; if (this._isNpmAgent) { this.pause(); } diff --git a/tests/registry/npm/npm-check-updates/npm-check-updates-17.1.13.tgz b/tests/registry/npm/npm-check-updates/npm-check-updates-17.1.13.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4a95f26159d8f6bab1f2940eb2e662216bb19517 GIT binary patch literal 1495496 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

uAF8*}6a&YD0nuKc#u4%Yt z;OgsKt|D9|xYj%i*mVHcq2H)CM%NKsC%$d;s=)OM*Be|lxEgT1!z~84INUh632;ln zEe*E}+_G>hz^x275pELPsw9;n$vR1nNOB6h0qkb5o5OAeyEE)Au)D#YgFO%X9PCT5 zFT!4gy#)Iz?CY?XVc&#(2ljo~4`4rm{Q~w&*zaI}fc**fSJ-Q?H(~#PLktca91?Iy z!66Ta5*#XU5aCdTLk$jfI5gqVhJy@;E*$!B7{Fl&hbbK9a9F`%4Tl{Z_Ha<(aDu}H z4p&lGl7fzM7v&MkLzIswuTZ|DY+{qcW(J#8Z1%A^$L0o`3O3K!N@J^ltp>IZ$Tg5_ zBiBW)iQERcA#!KrPRL!6^K}}&rR!FMn+&%m+&XX@z-Y>H~$!mnglfkY8uoWs0C1qpq4?cfGUD2fm-vVqdEX}2&#YPKwX2n z1@!=`0_q9WGpJWkZ=kB68lak>T7D-zeo!Bv@t_HyB|-CfNb_Q?g4XiQG1?ro1!ybK z)}ZY`J0hndcR;>`ynvjAd>Q!!@+sscl)7A6vy7-6D^i7_UQ znAl@NLxD#jNzw%}0U|qM0#7&n~+|f^c2!Bk=~s2&ZH-i-hlLLq%V_xi}ahMFOr^0 z`e)MLlfFv&6VmrZq;E0PPM}>tyZL0jgJyvq1Dyk%2R#9L5_I1Rs#ic4L6< zWH=?m4H?DBC__dqGK%4Bfo7AY9+1%>bBD|WvL(o7A-jNV064CHQ*n?Sw< z`4r?jkUK+8gq#fdJmd_>NszBVz6JRt< zBHaa_T=x}NF|hJriC}fX8h|wfYXsH=tSMMCu;yT`z}kSd1#1V^9xMf{6If@kE@0ij zQo+)}GQcvydcY$F4;~&#zd3Jo9vN>sJxcHp;ZcW210F4S4B#<@#~2=Scx>RYhsO~f z3Ovs6xWMBI4;>x`JWP04@OWS>g|Rfo@)#>(Ou|?VV=~n0P&Gh$fMi0g3AHrT7Eqf& ztp_!o^+r(Rp{791fcgaL3#g}{UV@qi^&QkZP#2)CLH!2x12iOP#G%oF#slOz$O6bq zkn13u#IT5&CKHoP;}E-%X^l)ri&01?yCRcnTasg#8?Mo zV~kBOHpQ6dV+8$px){4*Ov9Ltu{*{d7>{9`$GCv;B*wkyIT$Zuyo&J}#_JewV!VZM z&k--iCm5e$e2(!Y##b0$V|;`0z5kdOVF}|Fa&f;)FQz~)ft-L`61fy|8RW9ad5alx zB63ya>d48+wUFx|*F&z4+yJ==a#Q5y$SsgtBDY3vi=2Yo4LK9JJ8}=?W3-}E@kT|J zicKo&REkllOr-{uCR7^HYKB&)w7Mf^jyyzGZ4$FW3Vl*KlG2@&mZY>GC4-bjQm&J7 zl2me}B9e+kDpgXclL}ADLsDswN|Thwq^uB;BVv_QZlrP~l?f4BL~Ii=K`K{LnGvx| zq%sk=MB<2eCXz_RIT2?>l896#6@`dnBGrg!5b;5zJdv72Y7wbJ#3d0|M4S+*OQaH! zdZgMW(wtNWM7on|l}IO29g*soR7<2LpUYkXnY+wxkv(wHm2DNUcn& z-fs4rXFfunL!L)IiF_LQ4DvbT^T-#F7m=?bUqil*yo`Jk`4;j$Y@;dSc@+R^ROvEq|#{`eAt8!ND+Kp6Cq&(vJ!woyLm`b5Y2-^C-lBP^#jWioX-jHU2G)JV_B+U+K=1H?kT1nEJkmivz*Q9BXrb$`?X-TBDC$1lb z25EOmdq~=JO`=wbS|RF@s0LB}VfO4sCCg(f3Y{;ceE_-t6lFOQ0a^#XFmnFHJ$(1A5Cb@Rucp}#uxe4TcBKI4yIAW!U z>lGtUtQxVJ#Oe@hL98vYF2pinI3o8U%Whfrz_MqSy|Jvyay-k$S+2-(1(p+8ZozVU zmRqu%!g6PpyRm$n%QskFV)-GU{D$RKmOrvWnH37G&|rlDD{NR{&k7c#+hj7u@tjO1WWwQej8lIF znVxZa!|5GoF`OlEmcm&UX9b* zMIwesj0!Q@#8?nx1xcMe66BE~k2-mjXpAS19gQW(V@Mto@~~)3ps^%*tjJ?a9x9DB zY3xE{Ga75tSc%38G`6I%HH~Fy>_KBg8dqstqj7`AbsF~~C4KWuIhb(+&$;iCx%_mi z_RTZEU^e;sV8d+558@kN(fFNmb;`9Ux20T{ay;ck%H=87ru>F-2IY>F?^0f-e3J4l z%AILqKoc{XsL{lj@@JZe(L|9Z)>Oz+;X;!enyk{~oF;EHRi&v5d33RL!p0ICYit~` zal*z08&_jg(&=eUPdlm{=}DreJw16}sNX!p3ue7|IhfshWW!v>RmXZoJj&*l9%s_CM$dD4 z&eID|FKK#C(Q|^HoAg|y=QX_)=y^xa7kX~dONm}Yda2U$iC!!8vZvP`y$19mS7QLnDO`x|PRg3icptk{4EA%#_w=TUksamJkHC6NUx})lvYCEbG zskWxNLbX2ClT?$aR;8*!)hX2y)aXT{~!scumHMvVs5&(tVU zy+jR;>V0}2(R-5KQ`DSLvqlY#ntN(q={-m9XKJpfnW5&AS{Z5;sFkO8mEIM4H|brc z4^N-{%`>=QKKonX)4ju-fBZZQ{mrwqpnK8ARdr)wO&=L*&8ekP>q;LSeGKViM;|@< z7|_R_#ab*jX0bMlX)JbO@e+&o$Sy{939_q^okVt1vQt@gkEFY z3N|UQuJDlHQG>@69y@qU;IV|q3?3(VEHEZuEP=5c#%36+U;y|)2fwU&PxER&ckVlIifh0K|lCTu$F%y=>@klB*VR%GV+H~r=rTd=V4 zj4fC!|1`FI^NcN6-24`JcUPWL4oi6~709eX=2nL=iJGH;NXMHT{C zB+0x>7HQ)8a*@egBa1v)WXM7xi!)hN$YM+u5?RK`a!!_6vaFGXNtPqBya2x;s})(b z$?`^)I$2p{y(TM#tVOb}l9fu<1F{~I^^vUWWIZEmnXEfxlOdZ1+0@BKA)6c7#>k;Y z4jr;>k?oXhPh?vmTZwE(xV+%w@g1U-C{@c&<%sw-H-%jR=nQLZl zn7L)9_kqI93(<5|dyre3RW0OdtXO2l3M=kdam0#!Rw}U)$4V7eys_emm13-vVWl)H zOR;jT{lT~i4vSk&Ei5(^unHXbYoQWwW=9t)H;)01wCYG5vXOhT79s4Wn zud%^FZ%TV9+FjA^iS}gLo73)v_7=3)qrENdI>^(0llCsO-=e(}?RV)QM*BSNskA?$gCgz6Y5z_K3LTv2a6pGcIxN!R zhz=8UIH4n+4!U$$qr({;#_4cQhcP;^=rBu%89G?f(S?pmbaxTa%{PIq){ z(n+6A26XIsaQx=kLa;i=>ItiNtnpY&V=afZ8rE7^8=!kH`i!*;)@~kG*JD3DCVlhl zCRktl%hzN=#|Jve(Mg<68+1ITlQNwi=|rQ`0iAMm+NHAuov!IDMrSges&sOu^E{oU z=qyd=MLNsS>5NXtbgI!=o6hERX3*K1&bD-3rL!ZQ$LTyv=Y2Y>(fNSR3UvOUi#?rh z>7qdwGF?vTT%pSZU08HApvy8{w&~(RS4Fzi=;BTn3%Zo)(xj^jU6tu-NmmWJTC@C( z6-2s=(;Y{5DY{G0ok({Q-4*DrMR#qw8`9kh?rXSj;eLd>0{0W#FL1xYU4{D%?i$>6 zxSMddz>0&#ft3I&1(xTi;hSeS!A9N{v~FU9jR(pplqHm9l-nrxP#&P{*#=Qwqr5?R zi}D`j1Ijm)Rg^W9b#zZ&#<9s`GmFh4HcQy7U{l1Vgv~lO8-9b{_%vl~HnG{lW(S*H zZ1%7@z~&g6Q*6$#xyGjFogAAdY^t7d1zRa>Ww4b6s{mFJtP)rJ$G@YaA22HnV zx=+(1njX^hl%^*%y@Ax6NqZ)pne<@Q6025NRif21ZR}`cPa6j+XQ|wzU4_a#m1|Uv zF;1ZE8ZPsaXNSh7XywO&Iw(_(!r>!n+S+w1z z?GA0vXnP4~1WOB3cPm}g<0gLxk2MVOah zUWR#vWp*svXPGX`%vfg6G8W4`ST@13IhHN3Y>8z>norZbLW>8F#-6bRTX}31u~osA zh%E_QHEh+f)xuUATi(5DY{PHLVyB9o8g{(1so3dar;nWhEkCFvLo7k}E4n|?{hjVF zbg$8aKo2Q;NYX=r9%}R;(?gRUTJ$iahb28s=wU?<3awsftww8WmMO4|$TD@7K0tFs z(skhaz;%F=fHP?)3)~&JBXDcrw!oc%y8%B3egXUv_!aPN;5pzEz&C*}0N3I|y44=44nPs|zI4kmMj)p+*goV@R$bm8YE~^r*#cm(FW9&|_JHzfAy9?~D zd|Syk&sKt61-lpQdWIS7dZCT6=LHSNULJcz?3J)r#-4<|8usegYhbVGJE(|5az-~3 zy1CJfMz=iOCh4|`;|h*N97{N^;kb$87Tul5Jx2E&%ulpl#(RaO$;`Tv1yV`Gi=&s(+-kw=C2 ze!sqXb`|XPu-C`l5PKu+c`=}{x53^Hdk5?tv3J7W<>yJSZ=UG|`xER>vA@8+=L`h< zXYAiRCvG%m(s-A~TQokW@i>h)X?#q%HBBUGqCkZ%O)hD&OH( zHr%pdoedjoFk{0q8>ZMW&xR{DYO|5VMlCi&#f^ z!a6GJmRYyLx+&J>S+~Wy3yZfdMNc# z8lW^nX@b%er8!Cql)Qii-+WVs8&1YmE{t+GD&k1QQ4L2;9F5V9b`o->!nlOvGLEY_ zuH(3Y<2H^vIPT(j;72a{=G!2~QykCGJ?`$FtwU*v(i){5N_&(}D4kKdpmak?L&-$x zj?x3GJXSfZCb62rY6h!WtQN3Z#A*qvo_hhT%2;hWo^6RQ?hA6VnCdcj%(YXa7iSj%87kF_G!N>~%ICSk3LwK~=sSd+2V z#9A9`J*@Sy*2UToYa^^pJc(S}W9^7F1#2g)>a0I!{SCG=Y+hsYEt`+oe9aa~a!IiT z&lVh8^w`3?I{Mu=4orNz&!mWx5>6_=1>W6?C$388%PZ*7(2XhLuF})Gzm1wsa5}^3 z38yMfHJlnawQ$DajK^7qEi|^cv1J8~63(V~zQN5z7qIyGBLsduBLM@IOhgt%)Bx)(t(x_!n%b}J>t%zC$wHj&-)LN*u zQR|@ALv4)O%wtFGh}ssl6RV4?US;(`X4U;tIHDgTPGWo#d2a_+X z$urqv@`*JItl4ADDrAjjd*EHDId^TP@gX z%T^~CPGGo%p#sA@3?DG!U^Iep5=J)|nJ~`4cm(4jjK?sZ!uSZ27K}|8FJNrJ_yCh3 zOqwu}VA6(37A9wytYLD6X&k0Am>R5}1AfX{3TvHNzXLH5VpWLMA=UvmTFeMyQ;5wV zHiy^}Vhe~JA(n&K1>!u!lMpXJT!i=%;zyYAI8<>I!;yD`_PehPpX)zm>UUomzR>(5 z$)gO8@;EBssDz^`j#@Zs{(5ymp1I-;YAJEjHX+qP0)&g1u zXyu@_fmRn0_`HS4$#t}b%fR)+8JnDJQ|L+1+e2>w zeeWjzcV8{ObQ#i>rb`7^JgzdhD&VS!t17N)xN72RhAZ!)5Uvzlop5!=)dg1?t_)n= zab@A^fomSu30(X8v~>a3MO>F~UBng5mxUS>6f$Ju&TexoHy5sl58@6>9*F9Vh za6Q8H7}pbAPjNlR^#a#RT(5Aw!SxQ;2T$^?bzGZXuQmzX2)Ic?KMB1w^aSW_q1S*O z54|E{%*fzyBD%-5srpY!twmGuRfNiF1 zGhv$(+gNPVV_TVRTWl+^?S*agY};kq0o(4_)?nKa+bV2(WVPw}~05?P2jBxYQB)d7_=7^h| zHiz3hZi~1r<5tA2gxi{bVeGqa1lYEHk#^{_!-^ed?4Yt^oE>A3vLGFYGzaMfq&6^2 zKza!25v0eE-a>j0=>??MkX9jWK>7sfGo&rZBp{Q4Ob#+7$h08Shs*+o7K{WKrC}_? zxDV4Fv%1XcGi%PQJ+ltXQrOX?wG2}#OzASE!;~IVModwdVlw5yBwDrnga7Q9r}w z1lI&yt8lHr^$3?aT()pb!7+nE7KJhjMHEUXc=5Qu`$mAR`Aekvy8oTwi!@<`!VrZ6 z3QH9BDBMx7P*6}fqo83jk4XWOWlR<@S;6E8lVeP-FuBF#4wHLKUNCvaqz=a#Y8G5o zxUE4IKx=}wgzE*a54f6e)!~+aTODoIT#usAEv~pz5H-K-ECKfO-e@2wDcTIA|Pb70^V`vY;J6yMktd zwg>GDx&V3!^eX6O&^w^_;HZMafszG907V9+O6zTy*J0j+c?;&gDDf5l`_3-{`uhHZ z&w((X!h8+$JuEEP%&;qAdx`B6w)facVkeHBGsyRav95MP-MI7q;H`HWYU2&!3%EWaX*D+iR zxaM%3!*w3l72FEA<#C(BZ3ee#+!kU_c9O^05)2QcA7qL`Fy^DGujW!w`G`eUE(CDKvLSu=> z9E~X&D>U|Kj?mnoxkpn&^M>XfO$+bdCExG9P2e>CH5k6`|Lop0^f12a`ojMz2mw z`Q2AXnf`{x%%fRCvx26GW);mEnsqc~G(EQ&Xb#aFdo`I`Gp(MgH$a;qOK9??vhFMdj~>^!K9r_d@=A(f@lf_0(@;BA*`OTj;mIZ+~)|AKmS5KIZ$Y$nHmX?_<9I@xmN_biMca-P^DJ zsQ=R)Z|C@!E>be)KTkJ&bFR z^vXn{Ud84wGDQBTfCq7(a-+q=YI6_KK|S9FMPqZ zU%oKW&&Ufi`py6O;(`A7=g-&Z_9s93(;xkrkBqov`737q`8c?Y?jfTuiucdIx*Yxf zdeK4r*K7U$`>R*6*l&So=!N-D4-@bG!u*$q;mlu{KRisL^$YXO!wBjx%y$oys{h3N z5&r&q(?Qu+F@2ACMbhV=MZQNpOji7b@jIA1{KEJhEEIoX{0_P&6MT%{!E*K&=G&+H z>VN9-AA|ajLF30j{!>rJ5}{+jpyTAu!zmwyb_KL(q>w#C1WyT49@KlS;K!STmH`BPs#(I4W%N9I#|@v? z-H+kqM`iJo0Fhwm^ZQ50oXAiiUxw=NFW&b2)qZs0`Ko% zf%nj7;5`%xynlQI-ajIN_s?M9{WBDJ|BM9Q!(V~-$VVXb_7(`ee+EMD(LgBl5eR*K z1U|k(fse1xz{giO@bMK5e1wC6k8mjP5&jH(gu{W)x39ow^ds;Ud<%qw?}2deD-aI7 z1){INNFe(49*BnD0>QWUuRt*P_ThrBK;-=`8i>3HKV1+BMBd-u1CjSoFc5kFc!3WW zxaB_I1Ch|zXCU(7ranGDTo4IF+>S&(BJY97=jT@-@)>>$L_VWmfymd}dms`Hh60iB z`zI^b@rNDb2`W5;JM87`W zluMDX@C&%PkvEq>E|o%`E{Fu8;b_POpMhX7`u6pLQ5Ob7FBo>AJJ!MI$Hxo4FrUE} ze3k!td%;(3I2s7PyW<;te~-Qgg72ZA2VHz9^yWhM+4qmomkZt6-akX1F8m0&Fyi7P zAMR6;Pq+N5=Ft1wn+t=VFBoy*XUK(L9t^wC9s5woZ9Vki_Bj-Ockz)>)P-)lA7Abp zeT3gaf#65v&BeHs4t~5^`3y!vf#9b*+`-S!h|Art^jFyJZTS5y5(tJ}t__A??-CA$ zKLWw<*Lx@s3`e8kKrr&=_AT=6zV(aSf{~EhN+k43y8|DLM1sK={BYs>3**)hiF~{; zA8yG=_&pGeeulpS!RVJ;<~3TuXe1I2e7w2r@ELVE_cIy_xw9hl6?W%FF!X}2^!qCv z3clbA^YOxbzPs?tt>GgaabYwR_zHz1(ZE+I^7Z9Hcb0{sVK*I(d!7Y1E?@coqzx#>{&Gw}8K8GLhL=<7cM|LtG@ z_U~_Qq`y$aJumwC7I5c8G!Xp^M85(-cktaIbEov%XCUaZs5{3)uVHkDCJ+p}!x9a+ zgA{uE3WVOmfzT@*4TOSkflx3QaG5a_3pc*0yA}z4L<5naD^G%7 zAAv|P>`I%ED{WlC@a~p-cQag8ii9F>E(p5d^)nKPgrY7k>WZdl$OUeOD+xZ{T&d&= zxR2lqL<5nJcUNY)a_1xD{`~m#1=mN!O}USKz6V{w6$(V6Za1PIUxDb`3w*u>qHkXz z7q~xNiSZVF4@6z^M}u#XKr|Q(x*!yY219Pj6))~D;KvKP zaw7Ecf?qGZJ8OfXuNTIhweD1XL01liB5n;|k@pw;dO=s}d_`ZFs9R?^=s`C(?9QHG z*qxU_cRg_7OESG`h`P1C2j5|=KUo( z-rdzD_#O?r^5!)cL$6sIin?zdioRI!E%Fu!e!NE`f#AnWetdkn>CexXT#2~S?&~E9 zzCK*ae0_vo>BvjQxO5A@`WX(syD$`dNg8+dhd*BU5BJ${(tcy6__s2u0r96+ZG7dZoWUUhwk; zzh3Z_8-8KJFHATR2))?Ng;5u}ZAF8@j~D!W!LL9l`tH^fbtgnH68#qXkHG)*uYdc$ z|Ih#NfBXG^|3ChR|NgJQ|N5U^^1uD-{|Wr-U+&kHyI=ZW-rP-X*xT8BxSKuuz}W}h zJ_z<9X&*c%TlPV=4?X+Pw+}=6FtQJ0`!Id&kL<(FJ}CC#WFOAId9{3bwOs7O)jr(p zgKi%T`*61pmVJ2G$N1~R-9F~+qvs;dKGysvBd;fqb^F+`k4^j7vX5>1*!7Nc*hj@a zp6uhrK3?skW*?cR|X>6aS_GxCH zmiB3FpSJdCXP*@Nbhc04*%A9>*{6qnj@xI>KJ)fju+Lt!68l`V&t>~8+Go$tp1b*S zU;bRR&o%p8x6cjx+_cXv``otAUHja#&wcwm^jbf!?DN__@BFXX$h$}L^VL4z?6YQ{ zb^C1C=ezfcm!y43+n20IflI}{i1tOYFE#s8w=WI9eUJE;rq{w{WM3wJa%W%m_T^|_ z6#H_sFRFdf?2B$+Ec+U>uU=Rk`vac0Sp$gj=dRaHc<&L9O6pIBQWaZ0+3LksuePe$s$u)rncOw!Rq}4DmaRT) zjkC3ct)*-&ZEG1@%h_7V)+)9p+L~l*HCyveb=g|a)<(8AwzY|^&1`LMYb#q@+uGLF zcDA;+HJ|M?-PSCxgL=~cUvSU6xQT~t#BGDK4c;~cue?#T4KGrGZM1BoZ5v(xJ3R8? zQNozn#@sfRwz0B}jcx4w(ihvf+Q!W`G~3W^!?2C}uO~f%m`U5r*k;x?bGDhc&7y6V zY_sx<)E^!-OrIajoo()I^JtqV+q`()GcEfbv+oJ}F4*^^eNWkUpWW_18R70T!hPnG z|E_xoD{fnyZSl4x*jCcEQnuyuf+gCPWLs6+s{2K|p658*(rwGIt-Eb`*Fhqm9ucgE z{qQ`P*^jLK$lHEoKKtQ|f=Ac?XpVe(FaPib!(-+DSM0~heq8Lw)qdRUhxU5TiE&Ph z_nUf=!-)xgPQi&4omk0#Uay^a(ut>>c*cq6oOr>Bmz;Rn ziC3Js=)~(zTz29uC*F4A9mmxgxR(Q*xaGtj4i|Sg&f$26^Bd)g4p(+Kk0Tte?QmU( z>p9%m;XFf5ki*=_@-Za=e zQE?JgCsA_}btlnq5-lg;d6RY$Gbb^35=$qsauRDNvGv+WT%Cl+B96d00`CZdBP1Om z

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�L= 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


+iR zUEUHMNKSg>XjO%}>dDH4gAnhLDN{XosDH4vtd6tmH_XP4y@q1?*}6Q3f~nQ4a<^>L z+#=#aE2WF&R_Badf z1&N8+Q#Y!UnwEKkX{wM4_k-HH!rMIs(YNi!j+3Ot~htLmi?rz zrHK(SX*7Zz$;gZyf^MSF@l@f_v2rfd33^-VSolw8TbCH}PvWTLv`2O}hdL`rbmf>s z>1k{`tr<8=2SFB5F+`KV$zofo_|DE*nvN}TaEShIYPr{B^qCK|UoyWE$`Yx(Px~rq z2 zWnz*xWms7`L7>_bJ%F`I{Gmb;qUHXcZZ1ul!*o{l@XgYlJClf!4?zX zLjta}wsgEc$LL`a22aYJ%fZfq2#(8s$+kS z-6#C25c{SZrP4+Z+NoG=_D(IW{OX#T(VdccZmnEYyf%kdql*A;Vw-B#NJO<|48>7R z1)U8s?x9G!ArowxGBNZp=dT^tOf!Z~8&#(+_lG1CkG*-bR{O0~Cc=Ha+~HS8^f*Ye zwn1uXJ2Q+Fh8V^yNg4cN&kD3;s(_kqj}YVOAj4NW+ghr@k5{!int~@MwmP^rphY zF+MI-1zkKgoj!L2eABglo8v*`HWY(4=D}>`S$L?#?OYmr{N!=m}wekO`sb=e-5@=AA`c)A8_Fdzgzw z(hFoEol$Lzgi4uhgn}rr6H2-*#WJ9_Er?81(3Wh9(z(^rRu9gdrP89QW({`!yl}M7 zO^8NOFcTHx2Hq1I6Q_74Q9+lQvx%KrbK}NBPQfF6FS*62vvaQ0TpWv|BV7ACsmxW* zL#=Wo-x(Srv7N)|XYhsO)_Sa$8usREPOd@@x9bgjw>DKW^$)}%Lg925AF@^Q9x5a~ zjL^rF-;YZ0GSLYu zZK$Z{tx8QaJ~qt;PTt-VlZPaGHwP#r`3Ll=16dvLm>m&jq0rJuFgRYD6aqMr#wK1c zjScP|;NPes{cf!Cw>9z2o>)6_yD5W^xpqvnmfU6<K2 znu8wi_UJdD(t1N)f98fGr7ttGh}&@31JCYZ{6eC{;EGTBMH%wq!p_(~HcgpA<-PvG z$1HW@MoZ<{R7#+xO#eb5H5I|TFjGcS_PRrHAv;3QmgW;S8}!u7l()8!L$8&qJb9CZ z82ka^g9x8~HjDitya+j6S`*WX?NYbwHjO04rVv>&@~W9OXBtvCh){OKN&s>)so)EA zTjgXMoM_J~G6R^bY-`D7nN@dQAOA}Ss5+1A6;B>1@Y;NjLBr1<_Ef=>MGy;Bd>}mr ziJ77tg*b|Em z-M-?QYN;U6pbY`ccskT`I>OJ#LzM&W=}=lda8k>)LlwAw|LIT;_@4CGts4rru%@O$ z*+$+Ia>_(A_|zEL9p!&SPZsF4F7E%XP?MdLk;kqE^}5C)fby`O>x!ao9#CX5buM}` zYI}R*SWD`hYyTU&g$n67$yZ5E=<+z0*>Z0zWp~uk%#P^zI)Y7XD1QbmAxTTYheByf zjt30e8mLsBf!-uA17P;A;G_GQJIyrbsPiPsX7kZ_*6!mnkA})DTV}Q~3 z?+j-EsCZPkNag>78{BB8%)}}DDo5|3i;E)hw4aAd=gM36kK$6UD;<~G61q2*!lfe( zm2%DVsFbThL78i*(>`Gwf3KhNGgEW ze@Vn>NoXY+VjTWK#317XY2xWT6(I(5)`%Sl1y>6L#`ndmJxvP@iZWdl2_YDNdnOx@ z;R3QufLVA)J{NHIujB&GelHi$LNX+y z@K99g<3U}$kVwxQy9$ZQoBS;QVav&OOjvUx6RbFqm9I35!KnX;%P78o<<*e68453k z%)P(~wIl)8`HSqWP|s~t;ibR_#}R?|<}nwxW*0B1z7`dvF01yn>*EJ(2xI*ZxDcHC z*$eQw;KDik7jhzJzn2rqpfg#&Hn$Fo&^ZC)SmDrjLJ#D6$F!F_k{~!YR=!d(lcSKC zB9F7ffXt13EdM^N7ji;{jL;uK_PRoLC(8q6k-hd}WVe6B0R3@f|8Ic3%r2e%UUum( z$KGO2?Dt@=y<57s?WY6cW7n+GZ4F{epnm0S+g54h9p!p1{SvG8Ynzj>3nvPAH0;pR z1x3>4z=g*`GdpILtH5{CkV%CeZof&PX1-Xuy}pj3H75c{a~Y=5OB9W+8|JVo*}sR~dI^wUAFU zrIvX-slo5vJ&sStp>ebofOtM@K=iN~`6;e#7qh*qJ$j1k8l-z;5ySAoI2bxuv zR>Er**@&&-LMZs?Ap!PG4n?N)EgGD;zQ$8Sh5BzC@uHjQhOP(^(a9u=HS;iWo*MdB zbV1_~x%Lq~_ccTUOE!sdL`oI2DPkbXM?2QYXZUppdF#~EGr~|4QK~avS#nrKweLjj zHaqNaZMN3nVSQ$IgQ-b(tQ*_ZW&$ZC3T9xQanvr78X9<6>#fYQ zw)P4q5hi7VNXa|MfOFKKLt#VaCzb-6rb4|lEvRiOQuhuAi{>EXm`dfYLzjSd9|)V+ zb$X<|?}!&6mL`t%u+if7*&#upima>qcv4i6>6+AklTBUqgaYjn-DpyvDmYMT75w1U zz(~|6kDN$*dy_I?No3M&CDgS`3_eG2mgV~Nq`M7H(tGI88B_WARSQ=Z*enQv{d@#Jqft|$=VZOhbhxpkNXPHF;L zHT3@H@e#%r`h+>8@(MSlQYhC8f@5IoMVw(BCi3VQQ52*I~H%B@Xt9}?JSfYOx{ z&2!L^{&r1a8Di@GSc-F#{$mZahq4>Qo_wjBCO*sAH=OP;6p_EcflZi3T!WE-lN{jy zS|UBaqt5zGC+*8Hw9Rb3G5yXbe=AvujSih2Y9mbDd0(X}6Ug{vvlFCAVQkZV*dI3N z;cfFcg-mv@^a!6{aY)WH<(!3S@>Cp7j=5q|6he)V`?hsJq3~@`i9+gvOn7d&*gbq52d4 zr@eEcW$(in(ls6GA-kk-Omxv#wXta{vy_Mg-Y+=u*dh~`2!YZ4LaaLd91dL(0p{A^UHWq9AuiH31Jhu_&N)cgC$rVP47FM_`gCeh#eE z@3#1j-ZG{wqc9WlkQp8ZUTse5ILdE~#sEuKXhSIH9x3ehXdY@UK&to1z*Nt~h>~ZA zC=pEQP{c^)d(D)SvrRcUc372O!wu!ZD}_@sc%=&i*!BjcyE6q+;H3a48rZ@_*ow7g?@<05U z*!dc|n68htaiqo?b@J^*W0-9-XvD`_wnZ7r{5WecrI;j*`GB9N!aSo<0n=7OAe6H) zU79@t*E7kgY^e;r90SGV{CztTl^Z+O`hhg??omLaBeHHwyCHY9obPSjg2!QFSVtxp zV)4r!(gOB1iK$YPx(RBL9FvWqieTJfV?Vgo2w=yg28X%57KQ_DiGyts$c|*8ULHO-CK9yRj#N0s8{iWp7*fwxi<1Y)E~~uH*tCFPX6#1 ztE;P98yiN^_tn+v`u5s}@o(#!TdURT*4FBV@o%fujkWcv@o%et1puaT;zs|ry80(9 za&>jpkpKN}^1rVOcU~0xVX*LKy|mExN8ZAlg&Z0zlosM}8g;#R;myZ|a=8+OJ@4~4 z>`g~rT#1v&pRC-(VX)E-$73%@V!|Y7`AIgl!yxejI8F=QFo+W)_JhI5v#E*k&geXj zufx&OV(RW`oDcoPizjZ^Gu|0X%f`E3jK#&b zxti%}@HrTi3_y{jWOzXj8`9@;Jo3BVl2%rZyvfMzdP|kd%T8rbG8T>0eEisnyY9s6 zLEiwb4)_0M8YbRR82gDI1~|mm%iuB@d5M8=G~T7F7%N8gt*CMBc5ma68xQSpif~!Q zAup5rp+EBUfj(kqpNx0!-WiLRmzS4|%QVnsLc^@Q<9;ubOs}s*$#?2I@{(y37*-gL zJU3X%)cy}+4c7e~C*nO!!YDC%Uf-RL5~Dv2y0`{}`Cc3bymfI3Bwz3Kok*goS2B{w z^+$d%fCg@CyfgalDE7V^?~JeCc_n_|SV|rzUf4HOZ^qwX!L(~?$;mJZ?~TB_H%=cX zo)bl3v~=Y>OuTO5^$a%}OcBp6FRxTjmzP&Y5*pW@;X*+yK9-C@h*kgoH8=YA%gd{) zWgU1L&Kd6vZK1ywBI27Fh|JrJSQ0mb*zb9~UWUxuY_U2!>GH7Ok3ESxgjLgi-;0cQ zbV}%3EI*e$q^zCBON@$q_l*Cs2uHctL^3*+|>JhSu zbsOF&_6!|VvV(V-E}jpD%ggBUGRT4g5hV`^KIG5z3wclnndv(@#bgRkW2t1MO}E4rHa8ChJh6@VIVX&g{ZT)aG3hx2-ESb6sBtO-) zmuBHn))Wb+I29a?A{4>+0w&_Fp_wQ?C6PI%lgea;DF7QH4g!bIBbQP+jbl@G1&JOU z)A5vh+pV>yJ%pc|tRi(umoDEod`rIKG-X2JyN0qX<4~3z8KqkpIFw%3O!Kt}h#>Rj z!Ym&eDqT7OT##}~#Mf=*ZEuD-E&))?`{;+#&>v>j9E)u`yo zf9%jR7iFlELD|PvPX|24Id^HN`dpwJgP&Dl7f$HipiMe)+%8NK;A~POa-F}Bo9R?- z6(b5BMVcazJv}+>DNkuz^vNM7njEUa*{or$v)_~jJiZAZpU9a%V6suOgXvRG+XPC? zPGyg*Gk6?6Ym=Q3SXwzz9$seVUO)TVU^igJf&s<1_S8E zP%t!tO^oSGoP*yx5STNjcO(Nn@~(Vxejf;j48jg2x5=((Xp!aE7i-3_FN33wZuYh| zABvuUm~LYZV7DoA+ks63MB}uYWM5hE3MI2(Z{iQr^ZjGxW{$1uVM&W&(MY*OX(uG!{$6yz3geK=>5mq939_p-3|Vd z_n+<6t?jkk`%iUi`+wel{*&K-G&Gq1{?i@0quUBqsN8u$FN`W~5c?}}@(AVfEvWRY zrtx$FF9z{SHynl0vs+I=qmcMs{EWKKd7Uy3JI&9QY40~q+GmHg&+U4>J~ieC`CHH;&j8F2miggyqvDCR;`bJ|B9bpv2Nn~_^P0*wasVtwf1MA~zB zlK}y19QORa??rEfSQ&Y-m%K4Pu9l3|PbKXFw|CfkkCL7!G`y4c(RY^EhS68#kKwOdEGrO-hztWce;x;E5)>K!E zV5t=sf>bLnfUH(p3}CH70i3ncB5-TP3hIbRsn>TlpkQiz2wEuPozcF&@w!R*)_aVX zh;Elf70_9w+V;c98${tW=plB_=>j)7*B(?$&uh>4pX;HkxBFNwmy4!UGRoz0(OC5G zE3FUQIQGWZBd>#FF0tBE4AjFhK%v=kCriuvt2R~n2;EPhW4J%V>Esh&7%#>PlF0YO zdX}Y1Rd0`F)E<8pwa1Q^HH|EFsM>xK*DNbVCvfhy>l-VAL@>T8X)4lD2p3qcUNu$k z`&;!2hZ9K;o12PO9pP7wy<|yDfEW3(`e`})-pp(6d3`_dj-qhlMad(Bj$un+k_)|a zkzQeuoURv4$6n-KkGwbZM8qZEQpNr8VW$y2UvYygW_tvt8Z1U6Q%9(ouS6`Q#!$|xNPMBjC8jHi8RiEr=8k7J&QIut z9pooEr-Oi=E~0R343lIMzo}FPelnb1m%HJ(a_m2>R1gF!-4NKhq;fq9uPf{QRd2Po z;q9z>YwMfaJ6qlEb#=SH<-OkQZm+HGY`9yS)&9m#g<65o1hU2~yiycEB2+ZEJ`EWF zZ!!p7z>B9}V$MBd8hgkCdk={h^t>Kae~i2C$TKGH$V(E>7`l` z&h=xWD5Mte;WRuMT<36c=sl!B%j|=jbcc8|RzA8b{maYVr>|SzzscY0-z$FEd+@r@ zzMO>g^s`jmTGk)*(8hwh%IqHl6oo^O4`%@$EXzLP38o?7LgF6Z>h znn9w^wq#VdmfsfO+sD*{^v{MDkNhB6>G?72v=M|W*M4&E$DZ+XMX$OfhW+Ii=-T+n zSbeD1OS7uHF03Ic6cnkcc)`4xeEPkZI)ie)F^2Hk`wR0VWu3|{mCI%RERY?Md->TT z^X)}F<_-$*26?LvP}SrK9B<$HDxgf*^Jd|Q)&*=+Q6D?d2UP-^HSe56Uhi%C3sRWO zH=reN3n%f*J0O9%X`l`Bl9&S4_}Qqg0>va6y1AL6zk9@TP zVt|MwMjE>h1&qMY##(N3xY;|@gqRz7m(0=d3A@aKeOSYxM`$F;)E?G)B^mJb@`zlrmvSQHZ4? zB9v>r{BpwgBdS+83!QAfi0(;=hJi}`ksXWB^umZ8q3zAe(?zELs=?b!v^p7M@gxen zUK|^J;MW&HY5#^lfe^%%!c=*v7bVG~UX~<}Bs{SQ@TN!xi2a}!d2tvGr*UQI#w-1i zJ0LLtPOp3*fL#t&A z@b?|!^Nad1e$9TNj^E__6{KVmd3_%YpP=6|+5*L3E3~w@vbb#gYAh}qZwwq%XN9Uz zvI0emD=W;paDT$zkjj8JL!mw234IF8;R@uIOGxJeit&1kBIV9b(ZkclJ+5KBef zQ0cdCs=+@BhFeaf=vObe1OE_)7@`GGGnjWhjJh5Qn1D)sV+kfDHfAvh>G^39`R{Mv zj9f{aFT(Hd@HEXT47@uJJLQc_&xBntG&{Z2q-M-${&c{1W>%Ryx_2MrdDE#1fJ)r; zf;&}XN%Ol|thY~W=d;~DXrC+^KGswYMtx(+3+~EV9Wptj=_%qSgsLLHgu)IO+_@fB zvpw+lOegwDST%k%s>U0>iv3_I%bsW2mVo0a8S7HVl!jCixj{T~6Ys#g^F~V}_*a7$ z{++qOd5+4+Ic=!OwXmhQAl%q;V|dy^Cn@<68D$y*SU6Qs-5P5J>qPEzyZl+a!qPSm z-8-=4^W1UC_!{GnW_)^jQ8MDd@AmY-b>NWt?C0q12t0WEMyL1b!)sRCH(@DG98WP zl>^+FIOGq)deKqJbg;I$Rn&CtZQf?KQZekI*S!UR8s^h9@{F2y*Pg`2#GiP;M3ROG zOr_mexXWFKcciP^Sji`ibsevqB6xX~vg z7hVa*)cW2J*4I>X&;j~EFT9V9>Z*YTJ4SVN^Ys>(nFDD1eiSFNPUMX|7ZrwXBHq(u z0~E1zUzF$cy0NofP4`;dTXkz(IgO?Sin8vD7se;t;++x3Wp2K-T#hFrKUrEVOC5>0 z<>3E_-Y&_;A6Gvu1C^?-iW)!tWaKKXiAtY0U$ZVQkIFM!ZG48s{%WinZ&LU^7rz$m zX5kgL*l3>ao>`ww`?T3U>_{~J_RWAI$IO;I^SFLoJUubrH#>_ZW6^G&*awc?gx}`T z(R=5jeFDE5&C>(Z`b-6QiuRkQ4*XF&X&*X^pUQDK_LgFQ5TM)u{}q$?_6_evyNSn) z&=21|hW_L^xASb&UOaWomfbwP`25~E=``Div(9kkpG!NJm*u6^pFdVtc0OHR_I_Tz zyexmayzG5lD}BGbEH78ei5Dk)#?rkm^VOZBzql;8tktR1sAXmj>qV_q!v|nES8ja} zF@D%|5!!t|I%zjf%vNsEEc??lLV+Ssjx2f*3q@2~)Xx#VuT@u-I33^nNq1=Ey3oBp z;bboQr(QHJyOYV{8(rMy6^Y3KmykIhDao7qGAEOf_xY4K@=;-jYgtzeq&|nC5D@cs z4ZyLo0>UdjD*yWTim&6qNozT~4{Oo zCEu|3Zy=w3>pl+d{ovck52g=49ISvY2vmF4Rh2q6-!+k0@?qV`a}%$VV#Z=-#6o=8 ziSzsxbCy{qPPF?ft&_y1h%V-QS<yWB#%qg!ji`noh$%U}gW^kMgUw70@ zA^80Hr?eSbgIOn|w1$jS1RSm*5RuFl_J?C3Av zT&2U*bfKh*{CCX&TGLgg=^$548$4^ZzZ!W}J!o zi{L;&@wtT7h=Q)rSb?)8KGde`EJLMqt6xCvmHYY+cp)zcl|x~27EeKtXUI}RBOZp+ zQ4eMPKt6CIeyxHIV0|%Vh*hZ=H81hHf>-hT=qL@w>0>vTx}(vfZjUz#qXXt?G)zRN zT=^HzT!;V!y|Q41(#uOp{l>5Q2yfC=vtf+7BR7r>8=MI=jw_mWlTgB1m)Pe$v}sLO zh_-f-4}HU!x2h~Kgw{8SXF{I!|-C$3_O1T7KF%*SrtvEWYl@g>=a*Wr>V$_ zI5Kk#H3wd@ln%oK#<8Gwp|@+CszrYKg14zxL$M9~{CMZbJ{W@V;!{h1&cgL2l~B1X zrZI07i#+V&>{S%3L77Z5ljJ3>u;-0TGJRYc!yhFgS0#fGs9Y|KIAQVUG-<}_#7{*7 zO$V4({L337uVPV1^$`a9B&;Bp(t{Q$i!%MAZufcpgQTrpl37a{ZQSJ<8lb{%3;QhW zP!pv!2oAl6oW4chpCyEG!RDx8rS;F8QD-dSBhKVg9`HK4Ok=Ny^FiZuo)1pEq;}y` zmb}m!!@kx$O+jerA5f34xNcy<-~eO~s-&!$1?27fa7=X;nc$=Vt)BwskUrucpU`|7 z*w^f_C>dF{tB_*7&8druC<0A!Hg)@+qetorydJa&rHsYv!J_esp#O38Q#lFGCKE5R zQ9~^X(vfX=Ke&(oE<3^&)bsZwWrqG2?TW^};N`2BEH&TyZ& z5r&Y`qklpLb2L)X7NM&6fDcF5XvQlRw?>{&TKtJF0IA?7%gMUIooYwjm&J!y^Ev_< zo~oy2S@?jB3)i|Sr3Nmg2jD-cbA>@UxLT5zSc<(-zhrzCc=_3no$(}jRKSI(Sr~yw z1^V=3V;CmJ#7%}J5U@vn*9Y0di@I=D{n+TcF&O+NLl-WIN9lz612$juwIce`NRpaz zo|ix-9Fb*->y?ZpRVQV_1J55zi$K&=1$;bvqkT|JzUC!y?iucgmgO0e5jL*9t_xbu zd(Rk8W1(0wTuHo2#`QFTMv-UuF?SY(#=ZLp@*Zu8R-b$lT%+ehtRDcl9Bj5YA=iy{ z#jN?Ob_hW(^hW)+dMT4IRD&ZPq)H`~f^tTWw0xqN!|z!k9XCbc87pE_{2!DkS$Y*- zZT=RgV{i)9tT*aw(_t&EyuudFzq}8y5wB2teHP{O9<^twg1?H>C#lSL;pY{-RRgfn ztvj0bym(2tENR9Ata0P16q|1#vaq@ej*{UAapDGDFE-p!F^oC5$$aw*vE{ z_;x){>m~#oL?d(bSwS>*!D6sa{^F!io(73OGGf>7;qnUlx%WpSP+uU60tTDl90NT> z9yroNX$(jC5h^WCMy?+$mX&87dk)Oj@*_ONCCh)ol5{gzwZBwOG_TkQd4ZeWbT zu;MyQh8TU(aJwY^hf{>WC=4ehd6>yG8ROJ(H9x>A#(fCR_h2=_y}Q98L(GsgC6HzY{o-wnVKh)LB zo63-9hhV&p+~DigiSScY9K6d~)n zadqtZu~1q-#giV%Bq$2;yu*(=iL z)Zghh`i0WMi2s|m5x}_#(>aRfC~O4aFKNpNAs918lC)v!kFgKallE5l8~X4E@Lfb5 zDlHVe;>&@d5ovhgQ>IFiJj&3Q>cUM$!xWFcxDoW8tVO%bJRnopOc8Wad+d{4&bkO_ zn-bbEeB{I?^0d-l;%F|E79{7oP+A}^ZlSawctEi^EX@OUXzF+X30@8YDaD2&;U?Ua z`f>56TtO@WE~+z|E5BQrze!q!b!l1$I;=P>TtI}tEM+W|7L+zioG9pkbti=8Nr-!k zbO3KZ_>9~Rf2XY!7bEoJjrxeMqCdg53jlTa=k6C-qOPlN}3#4Nf`7DtGb z(K#{UWy_{4RWhAzyGAkCnh<7@a=c=bdSMgHE5$7+PN+=@{hY|r8tx2DV(*R*9Y(54zAXxJj@k=+w1*X&b@2dd}oq!ec=doUM>G=d)}VN$-}H;k59 zP|(BF)CC1MmQ4L-YZ1$@enVv*Y6^yJoqqqWR(j)#GV^FQ^I8>6g7SgdL{A;p*5fx*?o63u z5|b0#NJXbwjk=ah6*9@&jckowneDVqAv~Lk@~h;*F=d29YD#%t*D-Bn$DyFKFiDPZ zY^So(IwQoRb9IxPE9$&Y!ybzuqB1|A{ZLb_II9aGoB#$=w(n{kt;(^8 zpnI{Ws;uX#P=xLSS*5XF(-WF^L_lD>BF`P&C9T~QN5PxZAiC15V>olf{SIYq#EqzO zY+CpY;cy#!GS9gUO&T>iWikU}i_&N|wS3rkA|UT)1Gt<9C&S%W!P#4i>!I}7)JRrR zXG>M8Sef#+R!+$r@sbdT@PYnJF+dd38&jLUR~?;|9xdbuC9P@VnNQ`0ws&fJ5N=G* znqjGQzN$e%pG9@f_X(-o9n%?dGIl!qknx=GPu;N%Q#Ns!ziVKgZU=L<+j4gMl881S zo2b4h#1U8rMOGJ^<5X-hapwTZ+BrpgZ&I@829LWhJ~+gLI(^DIUj*b7+O;u=cKbKl zBbTGeH~56Xgw9hr@9n2te|$;UJzNh)D5td1zo~qnNXFlbROFQ1v~jJMH)Q#~%AMXY z8xckpZ(<5v&V`GtFhyBEAV$7v+P@)}-Px6QOPc`2_->DgWyiq%_6g;{hSa`Dxa`AS zksaDO!DUb^^^3$36LFrbhROu3PON^80P(D*Otwn3ZY?cnzo<5`2~Nj8mkLaOvWSjq z2Wwx54HGLxB1HOTOq;w;oXV|5DP0wZ+BBOdDsMrDj=r2+V9A`o`KH6!=4zGRZqnT7L~< z4Ldev0YJ`&F9%|w>nvrp1?g&1GHA%Cjj09r4i=w}#pfD-zL0l`BM-1V;_4nywdG|X zuoJU65Y(Y2g4tvAvVjEg@UPl(H#BI3+zGvP zbWO{mey)D11&TBzRqfInTSq`KBCE|&{W}2b6WWSn-V0gVrHk=M6jREP1`@U=r;QoO zL@JFFEUJqs+I{@HKLgcrs6pHs9)xV4I=YgS)S_F!0g}*U#se-{yn)&zubCWL<2L^PX6z)OIQ!S!wBz2t&KZiH9`kHHmOE*BxXrO+o?M2yp=u zt=y;N@>>3UsPR$~)U z^X!(kP^Nh5(65FNa2^`F8Vm`9W)_69wEzqpdL;B`zYmu7lZDJIqb8s-EAH9?$%uTw zX>_)2kFMvo$#$HfRLLOr-`$fC9_TX=ZyFp8wL2*(9wEqvj|F3 zljS?22a!LH#XgSWR9wM#225lG7AbGEv05fJio}mra_6N5Tg*6TvEmiv5Z*U8%N6ELiHvzBKu)2oph>!Uu|)4S^jM(1uXWG)Pw?;Z<2u{U_mX0 zHB<0gs4Z@oPmZJzcxMc=vwzIZ9;fm_QlILEcE7^Zr9ZO4{Jm;0YckysX}|(5Pfx+z~uV6E1E`4-nFPkY&df5ceeJf zP6*c$QYfpI&QO!EFNDntI`cz%$k}q#HBO?I!WX3#0Ks#|)@trcVFh`xK~3u!x1Fdq zkqKM<+rFl=qWWUd1y(hviDj7$27-K2pmVflr_PZ*BDU&6VRKv2tdXUiFW~A>if)L* z;@F!0hi;66^fQYCYa}u8n=Pbd0(BLMY6Srz9CA@vduMcof?O2k# zdykc0TUuqfWOsxXh-DhQen<(uzhNud)X~&@NPzHa+_ojl&HC#-^`ZlCh18CKKD($Q z7h1cf>HJ1?R=uZUK0UX7#=5*D z%=hTDK1dbM^9MYS)pY{#N_} zmo#^F)y;v}+c^`c>P&2Uocy4!*$s=H&4+|Qzsb9ZOGXy!+usYel}ns!L{H)-geF&6 z{Inj_PO@lpPcv8i9oBxZl@&mnt5hvD7}f-~x3NP~`GBB`rTgoan6Sgz#<4}?w%MMg zJ+w&#Q^WwaG-hVGBXq7b+7WB6pr@g&-f|=txlTDd2e!b%=8Z)aJ2hQ^9N3cCY@6~O zk9cQNXm(8TR^MiI9a4d_O*<=S2)%QF{9ki}I7B#)eX87P>oVBXR_Nbp5qWHwjfsQk zaF$S$sm&~^BiTBl8$*q;dvGLpNv&qbln9s&yx<`Kdq9N0n>gogqQBO_sz2nIa4CDw z&hJ^Omexw^FU#`z!u+2>^K4`NqV|{M|6E<$+FZ@$|6E;N`=9)u|JnIJ6&lRX|B2S? zkvH%j<|XUI#PBOn_Xp`WGp6Y(WmgdUCosy=SMc;f^IM3;39)hug3eCdB=Mp^1aL77 z!&v-ydC3k-{A0)Z^btRPT3Y`1x4(Y+dFj_T^8ep{Tya;P%#{yNp$Gp|{{5%&n|Htd z$N&1@pFh1?{uxrA$nsCGe%R#a<)4>-<&jsnmlxTyagm0@CSR+ijqlJA{k2-!_zsP5 zjy-eb=w#*eL$|*YBwwP(cfb7Oe}7tDUW8sgv2)+I#Y~tDh}v@E4V;I`5<{e9DDeHN zg+X~^EDjcziy|8#)Y)f2ZMGgL2tPoqZ@EW>5#UonuqGU-UUP~ApBykK4*SA420U{X z>GxtmJet$TiAOPMuAGO7*TsyX#^vP|HMzXJDnYm_`11F!sh+=IUS3^gW70Tx5b|vZ z={ni<3zp@_9ErUIu1`I5l?uR3DG3eCXG(!>%OjWV!LPVG;deC+M*c0-z~nf~SLhFQ zMX?2!uS&+12ptDynCa9{40oD@V>j`;A{Y*OW%Z0+2ypRLpd3uoAheFBQn`=H>^^O1J*Wc%`e81WS#%Z<2*4B-b=Er%jY2V~?P^TuffER)XwC`#q z+deRr2y@H^*!au_Q*A0G1S&3{Z24N$X1kaUs^OKg4TW!hrJ-uJEOX3O;;2apOFm`b z0h*AxH~yb>+duFAx6cM&oG&f+FS-BM*0(qE_y5}J|K$Jv&%XaPH26XOZ@24qhhF;Q zWM%A5UUt*F@ng_ccf-33aDYfN?&-o(-sw?B)Nf>>~#2)+UCnH-G!O$$OpNc~x$QaTviDQ;tfX>E2wDx2Blo_vNd?phH}Zwui25v6G8GnDt_d8p)maA$s|j zsULa0#lpe4ZVv4ElcHCy!|^Me7N86m1Lil7d|joERr+`Y7_O(RUB#9Ou8sxBg_}k=vUWx78fnJP*Z%0GO;V7=gcjv|pxT&{Q+3KqjX1Yxk^_q_2W z1fHO*BY{{;85WVwv6v+&;sj;#(x$1(I}UXEw;9;QH;c|7{PYu(O%ZG7mt3+vc?5uF znu9^)4cvq;2x_~${B~9t-)Z1?!zid=#g(xa$L_!@N@zPbA#M>Z$*d|zOBgqI2_@MV%jkJ;p#$U=-fjFctFt3081?x+y$ zW}dX?qmjstNh1<>xx^C@G12q5bryTTzyJk}6L&!IX^7f$SRn4AoSm{tK{*p83J#M% zCPvI3?fP_-5F$hLsUqN|H+5wt)t>_XQVL&;u1je@fSMGLHjT2)B4X4uJ^O-Otd|Ls zMMU(1M#U>gRY2sVI|mbp++#SSMYw?wSH-ad9h@8WMvx&g>>F3wDz0F26ED|q><3+9 zzWJH}fdVveBMMC>dPb%mqak55B0r%oaG7AO}awR>2v~R%*uE6Up%N`~qY?mR_73o`n8;V256{ZQuXeb73 zG>T;hc>Kc&MK*%H5~Fj7s-d6Y=hPg#kH*L!`-$wuCyF7F3DvC}rR*BA1drY57WB?B z=!QL&SL?8S>b!x;{|rpj&qj~=xju&H0m>^F$XJVFcJD1hsIiG3NQ^;DVH`;>)wq7t z(yR6iOfP9*=1(GXz{ewA@wAFbKHji;wvpAh{PQ0=VEE&!SIcv6iyy>8#BE#ggB6(8 zA0=$FQ5PeR&C9W!VI#kN(`4MtC`EngKjazszC0`K2V5s&ygyy51tF0jU|tN__}=MT zR;bYWD-=}!+3G1RlJv7wQ@>L&r492JE2aL+s-&I)5*=R=CMg8|C56EVo-~60Iq=c@ zoDHBnAeYhrS$+-#^|3M_OciBdn2wrDr2A)Mrs66Sg?f&5Y~B$rP?7m_wPV?Ngq{>1cJ!U5W-|!R$wYvu=xHA)s|RfPHm#afW6bRvjq>ix0VM!)}H!IV90kbPKuX?Jhlzd2kAjC?N zWywh(1&b??Q%IGh4fR89fu>lLc%w3>RXPEW^ zUB#?D%kL3x-3{mfdr=5tZ^7>7HgnE)W>FB&G-LN0eNQuZIbVd4BqF6tPmhN!^VpuG zrI;WGY?N{JeanKhaIG8#IZHUQTPxDk!`wi6!$`=mHuupZMvBSAbPB@Q(`TNNICW?paEm0v%s!+K;|B>M2c4iuF(DG)TqQ z6{BhS%0PL9tYgaH1}cKd6<@3iWI{tx7}bi=#ztyCIF_b6q9~)FX2W0jexyepC0z|v z&nm89NGbC0AEd9tKXma(4kA=KFg5LkM9e-3BRLEF0WU%jE!2BR_&=aB)S_@I?WYzt zRX`4=PntThkV5++Px$a|TbeOEI{awy1G;1)bZepQj`q31hS20gP#12{WYm5@w)x7s z=vWx)YPRba9L5UFgbuSlhE0wRMNxaW1RZ^_q;1+a^{gq;YsWNSJIa*kSQt7rqFrT- zWRo${d66;FmSvh-=m0&c$w+ez8XTfiu*)P_&VvIc2mNTOkZWTL!=7Y1zO9?)ZJpy1 zNxw%^c89avX)34Fjxg=APwk?=LrVltv)O>1orW41^CkTgBWc(-miWVwe|Q`_P}+^1 z_X~HTEqn*{op4fK18EOY^2fN@C3pJ{N1;K#jibVeqNC37xpas`{{W|T4J))|_#^v0 zTECGMIL8o!{S_g|*hl49iw$ZgcD{{pAVEif25nbY+T~wpVMdO~v!x9YJD}FFa$?#O z%XX?1)C_%uJH1lFJTU<&j+?xf>?F`Y_v^ZOq{5|K<53t}%5y=*$l$YqUoq%_w=d)H zb)<81VjpXc02Jyighir+d7y_t+Yrt@JUJ6!`_!6sTN* zl8rzM-&bQ7QR$i4m-c%YbSk0vgA^F4c`oa;$4$9eD${`?x}p-k(vwJA&7hA6Cr8p&}Yw& zlL{EWk0*)We|%;G6aw5JiJw`2=mx!!7d^LnwmPJojw>TK7!=pPA9}%x_uwZ~9m;+*L{SqGkzUXMl)q8en}BZZ1&y8!CR#UO z((~%i>ADvtE0ZXk%&XH4gT6nAlQ5b)%Uc>P@~@|$J0**xxUzeCdW6E}i&~xfV=tU0 zFK9?W@#B}&9(&QidtQSsto{ecQ#?oj9yKHX$$Lqogx3F(COvQDKE9-ZNK*a$_3uBk z|2bF^b<=Ly&#O%Se>ZU$taQUM=8E{iSR?Zcf#SO-O z;E#WBrlRiLQf~mDdR&=Cqj~lI*Cd#XD}k5XhtX}h>#o4X`nxa97xwm?d-a7~&bfMD z*wYVh=i>h8hM_-R+-}ZBVJ4E55!6yY=TXv??$Gsv7aW6Bvmc|(WDIHH`-sq9aJTP0 zo`xL{%~a;KqfyFUaJRx9ezbJ$!|!SSviZVUeRgGd{fwVo8-6^yG8@D^ulMJic6XW# zSCa77o4bQ7N+F4xR}Zo<#mNfu-ScYt@e0g!P7U%)UFrFehY5f3hzS6hiJZCS^CyE@ z8o{)Eg&K|?b5$UHD%A7mb4A6S&0DCKtaxsmthll71}pb|FBw)wVR$>8yr99H0j86l zn|Lchm|zaFbfGs6Z_+OACii|1kOy9U=CXYwf8{!S@Z#S+P}d!MBe2Yz z%iMx9xI6L(!S9I(FspS@q=4tQ&hOQW2Y=2kY3+Y6h>NoRy%--N_s5``+XJ9U@WZpZ z(w#ek7kAx>w=xLb`Pc1q;=W{}nZKXcXui+sof{ca6hOZ%wC7q{lphzt0yThoVdM|& z`yM^yLt?&i_r6C(UHlwOMrGIGI=a;(+%g1d6##I&9I*}>;}=kw8ld0KCuw7~L2 z)Dg{~8*LOYcVR;ovR^R_G^py{gMlmrv!F^m#WF~YOWYnSh;;2R;qR9Ln^740N|u%( z6{UPwUpBtt6Q=Y_8hYJZFnI&pTd&6{bOH3`o7kwX>DF+Ufo5nYhZy#JN=BTqw=)a` zAr+^qr>4jiq(#qCkDD7Q_~YMDHwA@~L6G_`U{{!8df6z>Je`_DiMn6rH(o-#GClRi zm?k~x4xvO@dlFFlF;BQs0V|S~Wk?`QP84xC2IFXW#w06vH}Z_z0Nk;zr!knQg^@A# zV@OpDw!75Hs5=~oy^?Vq0XJeyB0r44aBa1`RbJyd@QA*Guh8&f4rz5UQ?CGnl7okC z+`bPuyX@oAV*7LFqIJ+b++PHnJc6s*4dz$Mm=klU^3S`~%ggfCdM-uZ}j)( z0DEO!aPaDa0LSnzg;wM^MJPQb*ayy9U5_6%Uez&PKJ%Un0pF@4PUT#zoLb0nzG_*YCaosJWoZb^sNK(1AI+;i(yMa=aCyPZ z)NaDCgP(Hrd~shdALYwOT(0%c)8R^DHlidoR&mvSw(e+l-H}$8PlDfPLRVp|?1gxy zyazu{N^l&&>EafhOU6VjVnHn=mV&FN!Yn~JbOcoQ3P>#_$O`S1jPA9p%mnj#SrS38 zUpe)=xA2kbe9!dDi&TBnwW{4i^1!MY!XZn~kj`RuhEu;+G6wL^ADN}X{=!-ECWL`; z?gzc_J}wz%<-HMy{p21lDR8|Rh22{uOHy~NGO*3A+b9)*~$o}91oLgp14W{~(R@BL^RmyCGY9RlS(awD+o=1bO3 zc1p(BeI!ue)U+wM#@G+0iKn0vOvVOl2n-f|xhq~lTsF*69F~j(FuMzoPC|n$&tT>; zcuGx2UR0K|v>pdblvL z1EKIEWh;4jGzE|2u#cl%KO$dP0_Q9?(-ZZ@UB)JAk_}Pp^1FA&<-)xmtgl@z=%*m^ zz&;L)I*F}RpVBTI#;>Y~8ox1?6lVA1zf+lZU}PzGxCEyDB_jzl2a6b0a;JJ{)ZD}? z2jTtFa=IKCuCU){J9JSZ$JIKQDj;idk=*n&sw%=8Q+_7Z;ES;`70`v3T@SW2yU34JxAk`X5b zO=$5{1tvwmQY$!YJBOzQOPB>~+gg5`uM5tsMLl${VL!4Z-!osnm&9gg3SjmE4gO(N zS66dgiPBf^jOuD;V$x<-8!3wzfS1`xs_A{#uYwl|Is~_p0-@}aB}n~XeP3RZM=is1 z`{0W2_Li2pU2H(W_vRsA*U0gL5DF%}K)cJ#89<}V8Fza#PPp5HM)}k2YWKT3*>2BR z>VvE_?e_uk!hS#Yl9EBD*d=2U#y&|LAU4AOeAX}%B~<>Nx@SdQKvUrbCBGF4yQ)La zCF5BS#M)I=COSx6$uQ^7CFAqwLNYd^8&~*@L00pA|MALz z2c;Mo06(GNjBw2dZUQk^t{5+`%GBBKIDT%gB$mWelLwFRT^u@BlaJsp=Hb#O2S3g_ zJy1C71R)1*e3d{}<iP2Wustb521rljaG&Rz*MQb^-JsV8K@I`BBx?9XCWa-~*$yH%h=3eY0_7PH{ z7*92yi%8t(rQFItuzP>v-oeU}VdUMjADR9=@{-v^i-4hYJ96ijQ=|YpMt?U&r}{oc z=E)optex5a%(y!4@Sy44&nos+fe7gGoQ`JR!V)67+8{%|Si!5)ueloN%LPSj7SJyo z;F?kW62@}Zd31G?k}*zla-1N6c}$f^ndZDQgiDaF;zL=$n->wR3@@Y>hZrMfuFqq6 z)|RKp1=L(Ckg8I1BO0-mm1v$rGSo>`pr1i4Xc0Na_Zbv}_aP%&YX@)k2`xAr>R77j zYEVwCy6|kyIGwZ4XW@(<`Ru znLlH-GnD6Zm#NzP7eN5^TJ>jwCW$#p#K1yn}Z6?WX za?jm!HiKJIsZ=VJq*8r|qht`}LOxq#@VG;`_`w-4jj~CROl7lZAizxkBCb*77rf$Y zIFooFp2INP3#ch=vOSM8@{TSm%+nI}dtlT-^~_h@(Bi6DMV+nnNKMkThGkKihw4}M zy$yr?27(lrpU=0%>iycP{GY$smEG)WPP5skEDCqAN_uS9Fs7M_szPd`rcG5pRLh5t zTz>ySUUV*QI6H>H7SV4Z)mog%=djyj*yJ{H4sGtG+m`)m9DZF&JV*9$A#G2Km2LuKtH5%CA)=dT-xZMrn4AF{dgGnDez_t z$zzH*0iz`O6baE8`{O{pQ{rp~5(1zy%8HWkgb>E}qRg^HQgalh@WKf;GGMy|E-DrR zKLegJ@($=!!GK25gCL?|IIIwPSr7GKqO?ysxM&~;9G8s(Gu!lOoc2ZudyTaf;UZs87(kz9+h%NC%9fN6txwW63a!}E(nl5EyXWMWP!8xDv z?ANMn+vbv_&-_YasJqTg<$HoLbkS#oTSbx=Nu$-KBCq)yIhcQGEgc=b{|6KkvMFEwa$^iY3&{3sq~o9y}I zZG0b_JvmNg+M=YBIXw2?hd?LRB5nO{w?A7B-gwluTGs>$i+ZYBsu? zXet}ZK+F1Z6)-!!iKgdfMEG;lStoSOkHLtypA9fY8U8Gya!-D7$~P-b={5aHB|fHE z;f)mI7&fqyJSCc@)@DlQWfq*0psV=&p$v)GFt6U$qp-wv;0f1hdQeq_iehMB8C5|o z&QUs;k1@cWk8cHI8sxY0I)HWSCCN8i5O>+%0j;L2kc*Z2spWwoy-34CWe8NX9e$$- zkO}PzdK@>Xm_M!8f3B8Cg{77r0bAvPS=#eoTzu~>h)*<%%Vq<&*hT6ZWj3E$vys#rjYy(5xs3Oy&{VEwftt*%;>dL1@G_oWT-GNIYXD z$C^q?kTq@-=bgGYBw~+whY;HkLAHlkz8Chdna#;fG}SyKThq+yr$Fd4fTbSz!M~1* zejY=V4(J1GwrJOoNGboPY&_*RoT26OHAH7G^xje~_`JAndFHFC@@`|*tN7fj$~4h<{~Zx-hbj$ zfDbinjJ>HCPD)T(DD4`#knsV}=|oj*pf8+xadVMuTwGjKk@I%tR@Gg&k|2e2A5Gzz!t^>z0hHYT+KJb#@h%8^U)&l`G|+#4bjFDt9+vph47| zz#$~X;IhCBXeEcAlk5s7N!77RnvJVr@e-)3?+=}`vmSgrJL`2~N`lNCCJ&EZ?_Ip! z`|kbsAP5_cmIb^z06=e~y2T90rPLNdWA(|x%i8sfPaVKn6uuu3~EnMM2T zER{8svt^bR8SEOk3y;kC6m+|gZ3fex!Ide7a53ngMRa;HEKaQnIX5nW$kVjP%FJ=a zb(ljm+^I>6m1N-nS)OEjq1-3c-b~)}P9H$J({p4`&P|}XB}UQ;(RcV@qn?#J`f(YP zrw}&OlU!a#^La;ES&XX(#+GWf1Vl)}JR~8R;)rVqW}6n`S(r}mKpXlDSFrIrXgiBM zDhhBP2or>5Xu+11AqdkDLYloKoC>MdEx@)PW=0ts6FOUt`6GUUmC%N-}R<#|&hEsFgbVQCgUqx zDhB)tcpTIBYE@*iz3R)MynnD za}p-i7Hwtpt2`{Ut^kRO3&krDB{G&cq>5mE?N;8L>+0RaBOEBVTht||)yZD>E%G|wyN&WGJuJ!mp2G-&iAyF& z6;sP_KM3?f`gp}DI*udN)G=7$Gc4MQV)1awUEpbn;vIo0=eLCW$*Rd!JF2Rq`KQA> zT86)gNh?K~a`?rp;$@*#!hJ&CP+Wel?Xl$h;^%tBv;3((s65eItMDq*h2_AP}dO z5uBsOk&Of38$Yyw{e8|lsM^CVy}K>3zj0evj}3t2KTzUDh5_|Y$$`AsE>pxeHRSvZ z!ZQ5#vZ6+z76TtgE=GJ2V=n0T-^-sG8O@-T@%)9^6c5}?P@3Py3!POmdyLi4Zl&jk z)%lO{u)*O`OuPi@i@11E&;MRFHrV`+FUZC=MYV)a)Jd||F#1x zDwH!eyc(qKJEPPU>7KSLXIuXu{EX}#ZU=ELo0<>1${UW)?mYOWUaM+my733$Yc`4B z9dX}%!_%=(zEqKU^sU1&L4ar|f2=UE7qJ;{U>ErA9*!@3?zX9uK6Wi%Fc2XYizSK_ z1Fmft&8Eom(ve7}pxHW0KV7V8n*}LVX;$i8`?yr&N(~kGt(f$RGHWa_w#Vu*wDQ_% zH8u5G^&r~v4cwGHg)ddS?a>Y^qm-C)BNl}^`!*kUZ^hOeAPRd{=%Vk}U4ja zKR*f2`;*HBGr8ajyWwrf%?+$czYP<+X_QVzl){d3od)_bXBb~iSb=))nmZ~+i$@I0 znaw4~Wi!QZAD9ZcNKe<8cTlk)oX0FO+7mH{Aa=_~(8O-|2(nag{XM2!5y7UpGj9vX z@M*l^w0tBX{sGKrM%ZapcpUHRI@{gXrByrRsrseL5ClBy}EW3>C= zG?4b0UNFW$(W4su!K-^n0z zd7<(WRKpO=D%U!@Io0dCSc2*7KI)Bst7kOZo>AWG$*V9sAe|}e85*dx2dPnhBR3vE{yRW)((4q;M zkR@5^J-xAa`1kjF@AqI;C(-D1^}J2N{P5S>xqPa1pU~0t7JRd;271?c+hY;pRq7xS4E=m%LsvRLD%%i38lo|U93QHQ6;x1|=3E>J&ib#COdQhCD zfH+gLDU%H?&q-l-R|x}ZY~0bnUc}-XQD?QVDV{%%^};}p#xjp1763j=lc@-mk$g53 z>-ZU>T0;EXjJpwIzW7F|f%V9La+D3?;glZy!GNiV(LU`un!?z75e`3&1_F$+!YK<} zS3&zUJ~xT$*R8-H)taX-&QU#h2e?$URo)gaSqsG%_QIg(v!R)^i~>Jng7~|rkw+rz zLnOXrs!UN-_*!kOV>39LV*uDRrV{-m!X2CVJ(uyLM%gVo`Iecuj*>B2Y1yRI@J3V#A+;c^(*@OC9H+=vlQ)d&~v}OBr`3w{3A956h;$$+1T5oFN| zU8Kc>EO~j(BaGff#Pi}hyam4s1L!WIZ)qm(!YQmA$fW?hfXy1Wk+=)vQkyGc=;tWS zCRf)OwfHI%;WdN|rCBEd0q4^aBaGjv31X;weMh8VKHfVy{soRnsg%e-XZ1#v%8df{ za#q4z?5Z(&vCD6_oWQ*3;oT@i52W1)jJVNb+yuZDWmbZPQ!m8S9d{OzC;M;rj^3Zt zpo!M&aQ=XA?Qu3%=gOt_M5TYEF{(4CecmKa6X6KFx>4N2AeHdO5Y%B&Dk)Ag6JK4I zW+2E+Am4Umoh>_@u`N{Q_lK6IcaSh6$56E~c$q_=ssNF}?;2d5O;7^Jpx>oPAmx-; zbFk~m0Mc*6^13|=@0*&-+3W^ltz~36MGI~t(;~A*In6D~Czw>io>;r5cjY*}3NRub z>?9^^gbGR?-p8ZK2*$p)x;kRcT!W~9JT9+s|5TX9X_MjqOsuun0~Xxa;y$*Z%$7qm zL&RXW(!qZXBU!We?Usc{#eQ(^vhpshHpu3%Y@TW|pQ{t4d-u^2rXPZY8Duh5N7fTl zh=~EGCbmzKQE>6us6#|F=X|wBZxHSAppzReFfh+nLD^gw4r3lH$gR`@z-gunb|VNN?N! zc>Vpw>z$LGiyw~O?um~d&(gE9X?L`ZIFXINRT79sJIVTC(g;KYjeQ#}vBAjW?R*zi zX{`I*qr*4*-+w9sq?uc$<1R!;XZ?0hc24$w`?vw>QsWN$*S!1Po!uXF_u^4Q21v_v zc?`*?M!eJG_lK~5UA*2uhF*31S~gJ~#~977X|c@f{o^iLHg_gP-a(3VkPSK;_=Wy% zw4|>{W1~T6!jh8UaRr@~)y~?Jl+IzQqB7g{vr`S4lC=z?QQ3z~=CwExG=o(II>$>^ z-c;+l^Gv+m**`?juTJO9{y*OCZHSZWNXHd{cP5g4MWpZk=(=&2XRrmausC5K!?xf} ziQ2=l?Cdjh{QZo!tWfl`9PlIf{V;{3FTDtDCc%SQd7fNFX_UwPf>oisztI4s#W>27 zDWXtB5o~fqVw1mpr%>JlkZvkP*V>lY`qoht8G|>~GL8n#cDs$cj_GwJa&+7kkmF%>b#+s8Iwwc3k2b`c2q;(L z3JMdE#G|+*JSj(85*5>;j79+lg1UzDE%k7Cbo35*0U3Y`xf=TMF$Hz_1q5~;Ep12; z3l)jlw$iBk$@)W>4iX4lwxtjH&&1BVeW5}V#KrD)m|l^y{L#&Z<|xDC+UZFFYsUpd zOyj)O^0TxPt3sY71Zo!HIDw5fogj2f?FiAH8h+R;8jnWMA`|F087vIggt|@k5n?qp zT1$1{8IpS4W8|o#pKRTfLBq^Li!FpSz+=!0!L#68sQ;N+FQiBl_DPA^T0G zA|%o2dcS%;cKy@%8)q>~*-H4GD6ZmaR_V!LSPO98%xzY)85qE`Iig%9;nvb%uB@q( zqf3gNBrFO6>^mJ!No)IH+;+=+0w*3jCQs*?_-W^Of9Jb{y{?u^I-CS(_Hsz~xFy!V z*sLksA8-|(TZ<(8R^7Uf3RK}{y8M58-MSk`QLtNk3tC543X)$2SH2m5dKc7NGD z*t4WA8vtU~botDR?qNphNx0<6SL7p35taM$Hvui<{!L(4v`z@_aOn+U4ysQ+5m!{v z+PEp@q8B7MD+9-3K!~s?FmGOTAN425Q1J+^;9(gl%~1tMn82os)yy%d^h7PUcyAs6 z4-23I{t=|3>GDvoLOE~E3IRg7vjjd{_&9HkS@C_Y1{Fg)zU~V)Ag=+bI!dgooU@!1sb*qFkg3`b+H4#2sVdvD~HRhyxmmNm^*8{*qGwUC%2NV4=;i5t-G z7L%lG)ih9BUpg5#eGFu!ivU2LIt^BK>(^VQ)otDpHAwU{OS1DiAEslkSpHgU+Gw;qJf5vlK~SPP@K z@p=n&ntIPP1#-XCFi2rndmWbbwCYXOyH;0z2i#nGRJQP1Ro|PgQSwRLH=JwsPWP9? zUF$xCS!_03sx&ns(B#5%in_5P{q@7k|uF_v!E?i^0e+e6MpXKI+Ubr zSCTC#GSZTqQ4dKLF3lCSkW92DcYM)(T$Dv!LsMGAOLYy0g|`jzM_n6TSkFIoO?kPW zcj{WIvO2!0YiCMjOIvG-VrdCELu=U*b^evi6r;}Rpt`*0fK!WmDR5xEJQo^NSQeNH zwlf!?s%u(4SH5;K7>36R9h9B@*|ECmeXx6FlxH68_SAqjP@Wx;wSoRKDc-*sfk z@;vDWrHdZHkA6t1TZU%KKgzu6 z&N=gD)|uBf>3ZY~`|G_oJMRxpF7^(0k6!N|eh;BnC*|;~#->{XUPvz99=+ZJEBfr! zt5?+;M+dL>j!m5}zx=XN=Xh`D^~KS-&cTM%bfKgmR-y3XTb@4g?Q`y3D# zgOhqRD^yT5ML@fW20X4eAnGJFw^TWC@kVJ`=E0X{>C}y5neM>rmN`A5J_cHWjViF- zD`mzKgSX9Y=W8t(Sp!CbK%*a6o&V0ZQ3v~n??KY&Kp^8JEFr))(ISb{$$g{6<<8Ih zhp&%*?$)=ti_;hD*rwim3A+tAxP^8~o+e8f4s<&2j}JD)by<#!jZWt(F0UuOc0U_+ z%5eOl=s+gMFj;}Pww+#*^*XCB27@oZ48MNW55pI$U-w^ytLyzQzFzCzWSrqSr`f4}qHF*sh}p9jZp<)1&ie<%OiKUBphU}ysQH)8ujA}f6>UGbPPMzt-{9Yt=7k4qw&f_}EYOM=QjPZV?ql`1F3HVZdbz`h0rwDSB z5Iw!DQ1d)f!GNGuF_3gvlGgNYQ`29kBf5|f7G7$^*=M}_v(GSB1U`=7^Y(8bdLCWH zMM+j9I{k5-k&RxCXn~-sZ+c&~n{{u$4k&5*PzPpZH_Jt5D!Q1x4X3?Gh1(}ry09RZ-Eye=j~D!*($eW1#-rw^0F5EC^mGL@gINyVmid*+l<1#D zh6HdKQd948sI1#|~Pzj8kfgY~{D*#`3GEti_S$W;aWcxWHhVU=Xk;Z?=C@R5a`kxc9FxB4vuq&2P zA1#x!8>uO*N>LmsWmWC`+B`dJZ?~H5XWOl2b9>|LtbO`x`}}!pn|^>WJUbgatgX&Y z!!;IlJ4s$geuy`R4b5K|&Q*bmNP5Rg3 zE-tSzs!dX4ux+GQDv}AAJ<6cKch_}{hT#)QL|gVIG?Mga(yo?Ca5RGBJ2^^lN8HnvWf)* z0dbn{<8s0I4tn{+&USx&mGxqU%;R;U8X}lw6`dqZuN)nZw7Jcln#vY8x2xkR)vgH~ zAuCl<4Y6~B39#;?wiOyqjYTI^ZdI0`r-KKf(nW9R&a|1NIdp=MvErmW7fsbsTUFTJ z_D^98+~8K$6jU9wtc|ah`gyl0;k2sbm&(2hrL4W}kD`{-$sbIyM-U7VTb^hpm5!8pMeA;wK|n|n{Sz7bM$y)(=QV4vlWBlH_32<+mZtmu{iv4@6% z_{Ptn@(YQ&IBePdLRxZl6g9QkZII8^xw<*q*IUh1qwy~4QvfQ~BlSuko-|pVcXUzT zlCKS|>aZpS1du9s!QvA1VrsMh{ByojYnWuLTL&AaaZW zTy+7F>XI_V`KU}P6nH08zdS%oueRBUnFrBsxAoeuF}deh*E*_LBt*!Qc(6g}gY`-v zuFUVNc;M}AHWvXT)1v-mtXk>^emw4Nz`1+bb67J)bVrhF0(x4Z+}+-# z0m&>7(AF0aTS%3Pb>7F1w!A}uR;l^@{_8pOu7-^O*utuy5LEkGf(LL(e*U?=L^+CP zjV^)WC>wZCba%bk+_+E9jFI`QPqfTYGA{HwldDhP)9c;C>Rr5K#PCdp1b;#SUv}Q^ zog5t<936h&coejyhi$(kcwZ1Wf!S%wHpB29dS%ODoTB2-IqMExtBNWM;QF$c6@SlY z)v1lW!W)k#{sZ)K$LwY;v_)_#5N0*E+wQ;fg4X>H+|O#RXMfO@%6n7s+)-+u8UFX4 z@|U=$I5(8q>HObY%Afw0;@(eiF8>sF6zg_kt1thmHx&CO;HYH(1NW1q@%dBSPV9S0 z_dk3$v2P{wu=z9HOx!yO;r%DNm$)~Q8U!DAD{&6yb;9I-)}3U@LI0U%?~QH*-UPFXt@_G?*4Lkd4)~^%pO{c=hF1U&~nI zCaGA2$B}Myg*mS>$IKfoM=^(mq zw0OOTxd}d_t$;5dXVWzlOd}KhBgr z-!dK4!E3}Az{g;}pB}n3q_%V~@UmcH}!zB=~MNj)W zESfg#mV=lwPCc)Kib8@M$s94oQQjVhc@gcWr86?f<x}UeiOac=LjsXk~Ls+jh;#x;Q$&wYZBs|q+a^7(=-tu9&JmT)BIUM&<%?PcG{s7dbo99#M{1D3~-Prn99@Ot9tAy%e)mtrnMA|{H5Vabn~ zo!!d1Axdu7{g6k4y!L9Gp6Cm)q_(R*(&`EvYCr*acq_Qr%9= zYn))Q<-f{qD&%xcJ29&d3*HT0O!4X}Sp_l$PZ)y>uUU$_Y?2IgEkZFKTEn5QtQo`sP-D1+*UpDwmJ#V^foKe~ ztlbOqM(Ywr82xh+CcOVZNEaZ8GLS%qXJo?w$7uJ3yn?g;q-OSg`-|afXN#$bYFkQq z=Y3l))eTv^StB=!e~;YINH~%q&oaZ=n~#(j|DJ`vP~6)hV(y}^hzVTGN?U2Ke;>`U zdaD)+n+-M;@m#FYZl^ciZE<=oHYhrq#cZ{*#%4K~wmOa?pHDAS{a)N;POFdKX8zJl zBmHTs8-XT`3<9&%r0V`Flfk;Ikle^1@AO}X#h-TWA92K}bi;JtF!y|!>9)0ldje-w zxP`KBOC2U^sQ;L?Dmel_b~=K>M|=n2L6WezjtcaQg~aaBa0u{LZ zJI_=AbZ$BTl|X90)4Omc&5`$HI+h{s8+-R-bl=4o7CH=E^$r4|BcgE<_M@F7X?9NG zTG&24?_33RMSS{sqs51N9RW=Xc~po7qBm9VKT!(l#*1bPy?aBLN^&|S1PXTMS5^6@ zs8a=j>*Oy4L_BwRC|`G^@-a_N9e} z6c49*#?}K0 zS$TGTS#uuN&^Qkkt~SvCHPUreY-?OLFgS!q$`tdB+Ygj8J z@ICnSe39t0o-QjQ*isLb*Gg)A%VgGBIgO)a;7l@WRM8gbNDV&u#(9s=vx^yZ>LG+Y z7@xM=ZH5F2xAXbeSOrRx=Yh=xz^fs8>wMEmn!dozHq&UroS)m+sL%WM>bSLKvfg+a0#JU$*5&TqD{;&1z$6`ZB2i$PYdfaa@Fc|*37 zR8N~|447oSFrkun)o11M`ke}PrHiZ+|G@k)G;ousX6FLvb_$2z3w- zW?1`D9g5@&vyH6SVmaZrw*>{=2TKQEApK^BwriO29;}72{~{WzF8FqWXgR$FZ0LGB zku-_&QCvVU8r-=+TK4IRWOQhP_nf3Y%F6P}O~lt3e^1UXoDADs@#x2_R9mzN+f_>&zq3uOf*5ku=S? z$XLocYyEfk=#X@bZb0>>AwwVoZR_`)S=ByD>m8*1^gy$+)O5(Gg_x*7nS_aT&+^xV8K>SUho>aIf^zlM%@GQ$zt&mUDF)h9EAl*Yaugh zhNNxQ0yxaCCU}15mtwAY;MZT696l`P&T1W9H-J*~~K+@mbp zD5y3k2|Vq2=*g87_4Jg{GkN0?!9}g;=kd5)p_-jE9L4F?N4G0cEYbGFwW0^#=%XXQ^qh{4T3GzN;5PjKpTU^S& za9mFx=-2ELa12v1NpDgxe@C&xF(@YEC~saK6T!qVjFV_Us+y+{)XQuG|HKOIQB+=M zgBklW$&=Y7$51X=64@5}2jc8AMV7PADo!s^IvGVdunZkZgNpCXFut19SAadCwh$Nf zhPch*fmmfm*N?#*2mIGVTrPq?BjPAYWaPqzUg`}`26WLnpy#S`LX$s%X@!5M2HvPtj^Dq=rK%4-}N^lC6?QR|yvUp#n z(SglecEd93RKZzLB%K#@y{@{RqkN^B=B=X20#%GZ|D5x+p6CWLhc8b~HF-L|M6d(! z9B)g1Tjw&eh$)PgeUm*?;RP90XhoT4=~XhtH9ru|G!vI$I=yVQ9fr}|RlmaMsRO$G ziD*IRYgKfuxlMn5)S9eWeLjylyDG!UpDo=+`t*Fh&!pY3owKwj=6;CbsY|1H9=XWmonu!D4{`z6l%JL0(=ayYqTe>qt}R(r@8at&P7O=1P|psDs8)|;G9*5xW+~)} zs$1q!I6{fubeHB}GESoV9aN!L^6cOO4U63@Eu*wNA@@RF!R;;_z*&O&GbS=jB)e5C zFT)z3>d51RCd+(aFc^d%GuWGL@D^Wqym~8CaJCu=rrA*Wx4^M<+Lrp%hBvf9FB?oZ zs(?7A&6X$30Ud=mMC092_oU&e(CLW(DvOl}ANg1CwkuZfctJ1j*`$Qi(ZG{%^q`vaVJilwU|3qj{A2@#4+znEvh3XcsP}%8aIlMlVd6py?(xbt85k~cNRSwa6!=pSH5_yZUj z{-uK*roFSTCpsU7J{xYHrK+$x0qW9E3t1q5=PO zo~e&RIpz(~7)_Eg25*B7d|ZL(8>$u>>3laC4x@ZSG@hB}kU!9TQHMx)Pzdki(PSj| z>1-%M@nRh;k>j+q*3#PAmo4}55#D#hVRWJ+P_19Az5MdxL zXJ2G!1nV1QfU=?Cn*O0I$0$+kvMha_-K9wu4&LS2RUQ>~@ene}>MyezUY4&$$C%Iw zAN?hT)DFYZBdKhCqYaFGpa*jHp`S+sP-usV-LfC{uOo*@^kVCL97cH#+~@iDE=%IR z-9Kcty2|6y{(2Kd<1o>0{Av<0!q=)%z=QAiPQ0)t}i$J_w z|2hy~fT6}0tLyNe7x15#PV*h`{c~Zk<}XZrY0m)3#;44(Lmqb_;qr!95BMr5Hmvb# z;h=llsEk30PY10HKenp3@cvjAZz#tqh}w3t|I^;Z{^1))^zn;YdSU-28x9W$;{}xm zQ4&r!R5qGjcT?NpToVg(W>j6 z@lP!Vtjn$g>g50E=`WZD&<1!GTeYCB@|%?6q~rt?TXT4NYc4wcqim;mA)_C+nQHh*=+$x(| z?hm=191JP61FODCrK0FBxen6<5HCl*gFV{M5iJ?+=26&}4P3F>w` zk4D*Tv;+mJ*x~dvodq^3mSRfe29NmUx1gZz?Ek2f<}gkN@5z|L+WcL66Zeg1;L$7luB_)V>*_6-CT*}4uNx?Q4WnLCL#j>_3DV?P%uSZoOMHa#Udt8-=yeyaN& ze~`D*i9LRw)J?S>Kd>JG85GJ7rqs?>YyZt7s5vKAVDi16!BwHAo!UnBvbxCoZcViy zEL=UjTS3Uoi`CTDPz1I@CP0-$P^TsfD$1y!PVW`e=Fn%Mjt8<W6o`1HZ<$~G|Z9F;m9@fukVZHnPY1HSv^ zby%WyMBX7Omt%iY7MSlG?3JND=wQd{3Dg%aUmsyT`+|8})mA~&2uMhWt2tTZF-5&I zC#ZpHzF%D!w6594TX>|&3J&~K(~y_ql!>Bk`I zXL(pgs;Mzv>_aB*X3Lwk9{8}*so%t4?%?G%t&ny>J}T@sDyQa+$QR%Ii5_ltQ&};# z#?U(e;F(DJ(!g@jy9u)#t)ahSPeRSLE zn%{@u7ZnvO2ErJFH~Js|e}YL76%@pR9xEWdJE$mgj8N+UeI{aH#@-|mF$8Fe1dLy& zgXb*330%dZ_Ql^LhO4c~iP!{wt(&enW=kHrNU5u}62gisyJS54CpG)!5;#iy)WZ@y zf`a%rk8yD-rr9JHQF*vOA?8_8DeNTd-!e$8GEpdur-41n8Lc z4;v!4)&dR=#3&x&k;`ZGVjam^HKtYw=Y0OTWsyko7)g%tWnu+v9^>MArJsdKRP^KY zstTD=R6Tct30EV;6G0>JRk&gm(6&s`!N-Y2FqDM2Ini{GWYpGQ{zmSBLbX@?x>+w> z=r~8tsCA2ybf8t=g7wvxwQaa1L8HdfVCMfU31MC`IT@^V*k+ZyqpXss8~+Q*WE!@6 z(=s|xo<@ttPwjO?jNf_aJW9TP;#{VqN~5MjF?dXFwpz=hQ!f}5Oj?sw&7@y9M@Mjm!; zZlJF&$Uo+o$!wAAw1I71LY|l|I?`OptGjJlHwCw4#bBvMFJW>oxd4=1lqcKZ+Uf;a zBUsu8vUAeeolpS>@iB}x2fwv@aXM(4udTp;O=8z%E*W@WEqX<$ksI%i4=}u%zqD#E z+*-~Z=n_F)vimb36F`R;DpSI1%t@GJ$ri>0#y!gtpKdI%%6XshH3mX1evZrQW~0++ zEl|+<21Ux)t2iaE+fZPI{-YX8EzZg6Bl9XCltiR?lczJ z;qo1*780*lKVvmd2_BvS-}Q=Fu47s5Kxz7vi#EbFPr+s{&GPsP(k*rA?b#hLwclJs z;f0UJwHNfd!Amm-8$Hi!ulEp9JF7OnIv|15b!E^slWM>1`0Um{#fIO;l*|;ttJJl> zpDP>S0>98}kvG7nj>_zF``PWbr;iqhYA4u|=`Blfop8`&pjC@c>rQO4#e=(QO=hY;UAxLv&wu zS#QQTz8)iMTd1z1?Kw?VAjxLu*R!+j4g>`9q?jXrnD@sA9J6^OYL}Tj-ne}7yAsPL zf@o|vK!`gO-1N1a?Ncc5A!2z4f<`Pg|Y9>drH+lT1JmpLhT& zjU3FT(V}1Uz`8AjfNI=tMxNwVtkGVi0~bzmH3Y4HP^v-Ybv$%0c`Ae_%R7`SR#>9*@g zl!Y%y@KjQaA>bKku`fAjd}n~a;~XNi76R#h7sG>Pi4PF+S?QAGyMA5)Re6z(A{7`V zOb61}$+t@^6k#==CwUT(ho%JvuAa4W&bE`e=!Z#vlHiMHnNRTn-Q&JR(2RQL`E#%2 zG!?`*?jA%B8fY3!Y*F#n;zlukzu`&~{bE}C()PrM1vAezPb=gj=IFy)b6%cN@433% z+mmY|4?$e*{;WL_Cu0R`HtMwe3|M6?(J)<`;7=YaJXD7gZ5fW&^scPa=P22AYLdh7 zu!(?LbCut!FHC$-AqjbZD^!qXcg@zPJVA`Yd*NqK%km$NB8bU+he|^B8-ywwhzzI&g!3x%T3B;J}%0H_Y{duOSARw7M(1YAA_VyoI29qd0B)AaNIofOXuO`=qdH zzb4GF&2SA9oy%VBgNvs42MS)rA0caCEPj9SzK!q)VOfDXt3JQZ_kLDPhgh(8+E4Ju zm5TumQO@kuZwi5H0Oq;5j!3JtYQz%T7rw1|V50$5t*AHrH@?}D1~ASMgPFkK(EdOZ z7=wrN=8M)ab6@_X;+5~|L4AEWIEPSk8bqX%#eagiFOYK5HY(Ft(`;5Jj-{Orm}SZ% zl?+Oc$5}W)0aXJ0i~N$td4{2cF$79B#!&oq+Y2Z1))v-Z;%)W!crs;lVN3Y8`-e-} zAZ-WvSRTpa)rbnejk_JA62{RMx7Hs&*}FS{s6O;8JnmD>HNV+}${4gjBkAjWj-jFN ziMu|8h#^y&rN@?KJcR71*gP*wIS8nnWGN;_Dg5 z0AI%Zkx3nY;*^E*V7=GJIAd)*#wXQ1mm3x1^Fpg;BeRPK6J=eu? zDOvV7Ikt=po3$24I{lG3KX#ry5pVZT#6jGTz?Sv@{a?{VXI#-mZ(Q6!wPV+hQ_Hm~ zk2*hA{Ko9a8RYHdwsO6)bmK}uQq!>NR;TTh!ZKoUF z(L@)pil^Atx8lcX+jb*!$JDH(HEDSwZc4)#3_FrfmwW{3!qp>NTKcC?)u3({g0JnM&tX#u`p< zEaZ~%QO8#Do7a)G&W}~M@%ypP4fo&+Aq<(w+yIGEsRo*G`5P2`0}5pcf0(R3>;;=u zhh!;Oo&K<@heM2C8xAA$agxf<^as?x4RaA?2}>a=)ecYW0J7rq&tW=bX?vW6CBE|E z8|+=2zF3FcqK&h&{Ol}kK#Y6%*GfYrv4y-{$hmTr0S5i+I2q(oim^@AM+&^vKp>Vi zR5q?L3Bm%ic8dr*Mw2WpzVEK%GAhO)xcYOmFI+A&E3Pepga2aI4*juhU{JaBVT)oA zA~-@F22;TO6w;PeTWpI4j1y?KB?rrMY-GI;t@bd>_rm_QRPKDI+ zxncvgaY|a75VI0D6O-GD$gQ7X6@ySd`y2Tkpr{%aW?qzF#Ns({JI+nZ@D)smWEM;o zKPhE06xomD#M6cX#Twus&l?0-JcqgjSfjk;+@&|L?z6HxPU5n8(~?QkFw3PP1aT5U z*|PE87W~(9(P$$_;q0V0ra7XeMMjf&CGad7`GivV9c9d?|SrDzTT@hk9u@{*)L-*`T4Wf+1dHi zkH0ogf89EN-fC_&+s|69?WdhsHG%U~fjfV$=z2=K$@%lnmE;7hE_?gJFS*IKW3F+Rk6j}86T`CnW#+~XE*JVG%)Wz)95Du)pDX!Tkt}q_LrUXGsJJupYC%B<(_G zrM#r<#Asp++o&ieLrAw-W;#%sMF*4qbzR0sZx>12kD4p%Eus>v*7Hru-!ZRY~$g6V|_LgD=XisvY;nF&SaZO zfiCNDf^kAJ^NJv|U1PWpOdD8c%)G8$IaW@}R-3@gJDK3j!Lq)A1+7M<4&wCv2|KZ| zN;dJRt}Air2+n6XLT-WKz=KX&YEc;%B20?R@5Tb@Iy--`QH|VlMV!-12+%csE9b;2iP!=Q!@IEs@Nf+VN?cs2xJx zO<045Gv(3vo0;8brzYawo;O`1>RS^HI76@RK5ZY4@+ge5Y)#N>O_DSwrSh zQ9^djl(aOHdzzko);Rmj-xiB1XEeN$d$3|xBFp7R^$qaliRN@mo|HN*Uoo7+Iu6o$ zGg*^2dze{CBY8JukPriCM#=BwOmBOVgUTY@56x28)aTsIM$3HuoBsT_Mujd?Sph%; zG05JhQPJ0j*hD6Il3rsHFLj@D24d8c6bz5fLUDSPMB<-Nv5>xc0@8ECZeTWX>lW>s z>K3~}lbDzLZF3D(clKs0gK2ZCCTeFN8}vO{nlAzKdlVF%j<^ex8ypXSDKmUsmpOHF za%EbHihc;0b2bH_ANETX-wAa;MPH@SFdru=eQq?E$`lG>cuWn18mP=-Dq``CNH#_M z{JEu3$VFdPlyr-&2*O>_&RXNGgD~NO-akuO zb$8&FTB5NC2eh-OoN@Y6MnH!xw=Z+@bdhz3!y@zokyJ%zL~1lT(qB~c*+Q5xVR9QL zDkEqE4iK(b2UbnN#1B@{^uVs_+XRQlRnMrw=h?&0~ zYgCjFldi-)FiHnD47?GdAZ0c9HrqupA{shf`zRYslBg}!o-oaNKf#`|u}(M+f09bB zpbLvkj*Hwo$>9XDdmU2VU)3WDwzbG)^bcrl-mLp+6UfcrbuYhf@Lg;Q1C~ed3is#3qTdW}n!M+u=8BWt&>) zyucDLn*r*kTTbIe=u5>v8-nSjikDdj_F&_&T%b#h)+PQY4@Qo_M*j~$nPK=y=6Lo8 zFb5a!o4#3l41KM=V!>#hb$)j~0m0)NJbd4rvsl%NHR;a8b9Z>#rbl(OqYhdvlCkbr z`B3TKY=;G^OQlOyvoS2-q(GZRY?Z`mtcoD9H!p(Ustl0>!+eQv!7F0n3K;jV^ks3Q zrQZGA*GKi+?3U8tj%Ew>5AhJL*qBx~P6fFQfTtHa-IFrw0nVQ(x`)XS0Z^+=?bRo= z-o$(PT{sOyFY1RA41yU83M*EK=r+oy$951n=ierJj>E$axz4)K*) zv75*SfB@B3rO@9@P0%n-`25J9W_p-TKg_Q%)yO%Cgf`q{nkrXo;nDPjIqYNFn4gh0P$~m5k3a8i^>qwQK@z zEfgrw100%fB{s5tdJ6|$^`IZ6xB7Xg_rZD|LWLJXk;g+mw>L1i1~yLajUAFv-=icD zJ6_M55WORM?WR^ne;*g8VI94Ea4))dEcWQ58%e%tdl$kGem}3o;StePDWg1Xt0G zUGye#GU!fvN4*cti(=A)9ISEcf!}gF9ntJxNBtYT!^=uiH&A5aE>ecv7Uf!X03?3! zM1ird!UDXJaF;|Qd~k1zZzHLo<#6!Kqxv_BNeQqM@*i_Nl1bE11W>b z$#AGtA`^580GH*+05#7f{S%|PyuLsbtjZ&pQ>pgQmW)CxW-qL;^A+yM7pFqw>P}jr53nC$r zl_<$Wq!>hFj+kC0PM@Z`nU)O_hncM(hSkM(S+r#{yDa|n3h_KjYImTztyiL=;Q@T5 z$;hL`vH@|oI9|`AIvf^g$f~!oiUvMTB1eajKVa#72hQ4&#%7zud7iQCy);3TWXj{liauaC-4D3LNo+! zuG@UOf6~&WyV-b}$5+>-0KMS)>e`Ey_0_enynX9N@1h)IHPbT|NTc3VT;*X}LUit7 z9$|h;(2_#Z3w!~df?YSBu6tz|r}VXv93TgJz(y5gKm+Or zofm;Ng(x!wH~}vpz&fDl^i!GABM{?B4?@NTkkzovLV36w{v{5zx)1R=UBXZfBf#KyC-%IUyH+|!~MfI$NPuh@4ekSJZX#lLveT{ z_I}zsJQ3X=b`B1(yPfwZKO7xvJa>=Y{c^nj{SPPNhoghnd&gbz-JUqu-}&xfkGebj zMeH8z?7t1f>z%hd-vgG%;^^duy<@Bb$474i0pvY;16B49C3=U4djtu{Z_m@wG5&tv-7`47 z-rG6YKm5K6Sn$d?)g2Iyjxxb|-0Y5{emso(n5kVqCThJ#lQbT;xYD)DCq;>-qK_Yi zQwk9#>dKCztG)X%ltP+L%$T*Il{L1yAAKe3&{Gzm6{NI&2zEt?RUso2tQN zuk2Z~rD{+FCmBYYm2YZ#v|$A|@6{JcuY3IIn5jCn(I_&vHTaJGTv2u|a?hFvi74rV zMI}fq4ntO~L@<1xQh2s#Ad0x0ggT)C>bP)DI?qUEnBBB5-D&Z1q&SUP4@P5fxQ)ny zBh1yb;8g_*P~(7ogn3?LKMZ@uAiCE>WQN>OY}xyQ<`6%^2?UN+Tu)fB$3YuoOTCXs zonn9IXhm-g0P7nqKT~Hq>t`Wg4^w-A&qr+!4>8S$Ssl$FQFUTAd)qN$QOLtyG*IocTt0opL$Y*AGf~3Psbn?cR7E2LW-~zdhmc%D+{MK; zZ1%*)AcajO14JV#d;ScS00Obg2HQ}?LZd6r2)@bCJ${NwQaS%(Q)eI-#Q3Ezk{b`{sf zr>l;kkRzOoQeG<0Yk;r24S5f|Jq%UO-&UnkdRBHia0)|{NnMJEWHjo76IXvy!drmN z1q!rOjgsupfwH}qwLrci$d+h&Qsn(WuOF9NXMv)d?#K=2Wmj&cMwkhCae*gSnDZJY9rXR~qby4b9$ z!8kkLSxKW~rlgzmhS?$HNwgtP6`~2tB)2wxt)`P^3M~(^H9kXryqxV;pIqwk>`#g^ z8<}HBI$$Kn2!e8tRj4kpc`rb+<~+IpQ9mP);VH7a#Xwokm$Gm6VJ*3{kL#;;O&588 z5$)OLvc!=1Iz`I!)u36UmzCE68GdfaShv zFn2(7PE%@Uo(JyZN8xc+Si<}Z_HN7mi|pI!w~)qQ4>O{VoY`R#Udj9yzzV%AONtHg z0Ko}xTckG=_C@C0eUs8t9e!1IWwskDxa4Bp$_Qm=*mqk4REA*kgL??$fC0@Ylz`uA9@TAt{t^q-58D965gOcFL-Jg4LvJOu`3G9Mo!=ll1Z0O0J zlN3wI(PXn)-vgQtKvl*2AvKV&Z6K~Oz|?ba68E@6O^t|dwKn}y+8F|^h{rMoQC+Sk z4^!YRgN=freCi#hw?k{7PM1!HdYsn%S~8>xWS~~03OL}}kcRmcytY4x3&`&xs?3{T zy{3zF6Q3~2EW_g7rn5Ld{~RRt$_lztYEcXg^$G6dM^PnbrO+%tR>UdDIo_xcqSD%7 zRa_aavEy5<-`LdIBW;V*%8sfHPNgxXcaNbR#_V)*lT(edQ_l+~2>nz2Ug@+jjKbQ= zmCq6`sY-AyGxcP|--Y$aFrZq`VpNW!b7HCt&bjAWLp(iaLo{a^_iBh%A7KIWJoij9 ze>Nlp-;8kTW^>63#F|S_UBORCM#hZOk0FxPlFgh#q7lI!~1V=c*L!A^cfk_(k3TzpBj5XdX{7z5$Y zeUi^n_d3nUW{n3_bot8SVC9kf#Iv)2o>?8Z$=^mjDR@3^up76OejwJ#msZ*%wHqxK zV2kQnyAg20sdrD}8@L7jz6SW*(+K0jMLRB^J++^CgrwM(>edarR;zjmO0)8fJT0G| zZ(7>H!dOkMtTePojlzYs#L9Fx^R#1zzEZKr>aUU^pxwkGm2WS?CO*#xxq-_*%q}E% zC-w^roGrfx+@aggx2)~i%yXwB-lJRo>DgIvcGf-TnxwWihy4IyP9sz;$dneKoMJ#4 z1BmdJG(;Xuaz0{yU;^YcIl;6&bx@tEsSl)_U48mwMW;N2hCMx3>K9PuJ~j+&zU@Tb^n~|574w zbic1|fQ}TJL?leAvJ(f9W-IOIHPb>Pum_!HE6w)vR;R_s#k-^^Li4(ORDadZFvzOn zLG5DWIi_GmE98VJ!;BN1Uz;l*S5{i5zpk7sl%P?|u2*+FGZ>S%|ut+HLU&Jh}qMfmH!j2{7bX50gTCa z05&{mAu?M_BBSWq@?fQ@Y26g5ghFrEBFih!MVwc}+ujN)-kMr1*Nj$NRh+YoKbh*k zVSE}o$|#_|{Y446v$LN&t;GnsT=v_Ltt?z`pY{qiCG!?C+ld%SjA++E0MxUmb`X^4 zQ#2RaCz>!o@R{j-a&!BWo$OA6`k%2fG{| z^CW*gO0|$5CI20^@qkAjaj#DLqUl_Vo>+0_8Nb}NFX$F%Vb{I@NKf=72w`mFX?H`g zZ><`A1L^s)@m`oG)4DFDeKdUu_(7c<_Bb)@1v{%=I{76>N1vUm;zRn$2O)W3V>hZ+ z-L>n+x^|f>&pF@c%<5S3W;ge4=XNqr`>4o&3YQymW(KhI2?Dpt+mxiX&wxx1=Usvc+QbCGJj9Af$ z%6@~s+#zUh#L~0RFl6c3XH@eV^3-iX11lKxHusKdzwhoHzdJs9vwyH>)!MLX{c!Yl zZ^0WBSj(F!$7OLFke8P<&98BggNDitz%~EN`v|wSfwjal@Uwgd#>Of}s)P$_ms<%$ z>ZUbSM{ydDVo2Pqjr4K)iHX+9bCD^&n~Dw^*)4;ts;5H5^!w-@#{x%hICWYoVjKpV zmAc?V6Bg* zp7!uIFcTX_1A$#(+&79pBg4?=eHltS?~?_G6S$jYs<;9Nk?H$9X%_u#tj;%19;UqC zY^38+BM=X&#fE5r+N;>;bkwJIIv#x}+F5?pX~<2CC&ndcrOGb9tlX&zaC|SK z{rn^S{sLn)>sdlF93aj>3wx(bCXh<25Sk_-xxi)c&apyy;pmE1v}IifFnz2-R$}QY zF0Us&)WgR`81{<}aPP`h9`>W*Bv~02owz6_QPFuRTkc-N1jyvs5QAYD#)*L7`f&=@ zqggH@@H``T-*g3hH)ZGxv0r){rdctiU>gCLv7_@E+KU`9?J|S(8k!3aoYHANF)suPE z6JA|50Ec7@+!dCRcJQa}y;?lvw1&L`POq*r*b#FMrjcTQ{k%o3OfaCB#E1 z=sJ=s2N|v@bf^!=etZ<7`$se)VNob)p}7=QaGJA};NT3%qr-v~?kF38H*L=e5DOoa z5Co;}N!-7Ik5()}cPcIS_L;R0=>=;rghgg!NNdr>a1sv!aRvYREm#`v_hKn0Axp*2 zaXQHEia_jielo7m{V)|tCIbo#V(AVv4y z?H#{Wk%%=AjLHImr{U_IOeGXbLo=XDRa=M?2u=j?sR2iTKLI~wcyF1Eq03jR5Y#wJ z2Zh-|l{ON^aFV50`YjkYWI1B7la}$yPjNnhic@sCR#ZvHBQXy9H{n%8{)syDzZ^l)7CQ-qSuTOI`ynOXoW@Z?0Y{7e zbp+>*ysfd6p8)(-e5*H--FNQ^hu)+B{4&UrBlNL|Zm2MeG;oXs4e8Fp5u3vZ2c~9# zg5#hMdPZ80Fu#rPH63~bqkUXF1-W;#`f4xBqasUg%`wEUFXF2pkMQ28H6G^E6YEF` z_7kc|MaN~@wqfy<%GiQow;u%9gu4=W>pKfeCTu7%L^R6@Z-7f>K``!Ic zp18THixRcF8Qef24;lP06A{viR?*pKaE)+EU{$f0xeSIuUaZIweIs72uC7+IWf$aJ z3rSAhJBXDGo3@0eH82QMQAQYT)SCwo(=K2YiZTg*StB?++B-b)455ysyWjcp;JLwS zb!d|wklihrwcNaTYEE0#gr#b>zY%Mzs})eH6kaw~y@~9tk281vf&E-0XRS(Zh)3UN zh;D%)p&QGDub)|~saKS9w2p@=w`DH9NB4HV-`PJ5m{%9vH6dgii0HOF06-&WDTjla zg&bmDf$Aa-**4A-ZHnd)u0-gCZekXa!XyymtcdAi0k=b#p9?pNvixpsr>ZVDUIp#ZEWr1}h0Bh$3oZYzeMjAl(e1$ZK+~{e*x&daatT$Hv{JA&1tt2bm zn}9)g&k)M{}&jgXZz^l=i{Tp zgI~l)>!VcuR2q&j^`Y~T%dZ^f%`*eO^Nm4U{e=~MG3h*%?sPCxVkI*RkqRS<2G9*U z-}b>7H?SH*UZ$dqlLUE^!V}0?NFt9=*8*SQ1WXAiQ z{M6a|9p?_CAzbItos%*^hKH{gT0{(^!qGF|vP1y_cJdxzki%r^E)lHl%)iqw=N;Lp zJ^QZy-W2dm7K;GY?!uZPTsz>1FR91n@@uZ5`Rp?zY(7IPLZGXo;U$ihpsVZ(`G-bj z<+`RsV3kufQ`#plM{p_8dS7GC`d^(+pvEDgGh%GRj8YqMr`)~`?R3Z1`3 z=d4oyI$f~jy<4NZUfFyyOTWh~w2Lqh7rj7S^yM;}t7kO0%wZlgc&|87`ft&MXH6$Z z8h%j$M)UZ}4mz#7Q1Mbc%3RjioH*_JwTlvm4w}=w{0R2qR!iW)*StX5D{;ZSXVzMR z3`oA;i4+Tub(8LAZ; z9*E~K%=Q9mW*9TK@Vvp8_z;N794%45M~>}Kk7fT>4K1#kRkYSxkJKbhYgiVQd8mG6 z-`g{UHT{T_G#?H3kAcAwg-0Pl`;gy~F?HsWxtBSOL z?3Q^Hj+{J3Q8;R}+EnDVa!aDCus^lT+~^a#`O9wQ@Qy+2i2yg)-%_dbGlY9nrR;}K zAe+YO0_qArobx87t>DprRlAlJ*cAI$eRsfZD*90=2||EsN>IQ?2|V{gf&PwZd1Ou% z_-B)S9x7u+{tZN!l)>hYFYS8BBq5d+FcI2k?HolL|o*btb$~`WuWb**PiQS~=Y9~4c zqkfs}lnk4YRD{jTIc~6N0YtdWF(?tYKcgtw&*r z>!1>chxeeWi2ZaJr*S#m^rdL6!&xN|t;HB%&&RidF%9zDc^xok9GfKHK$4b$zXMuL zSs@oI^;63O!+{+b+ctpJ+77=_1jvN;1wD=%RLq~&>pxe^qry^4kASW6z%1?gFD}0K z7Q`nSfe##Rv5f$>T5c?XHJB7q!luSvfsqwklCp2GX?>&)VMqKzw-PQ;(u>nDpFU2uPs^x)QI_bez52gW{ZA{J zmF3myVsj_S?J z!5g7pu@hFjCIEmyf4>5`Z6Jc#v^WGN^9b#hS*@7C2;(6t#5SD45=uzC$jVADn@UQM z(JlJC$tPSxBKDYf7{a^Og81gpgKSMRtDgcXbrCxEd%?e!Nvg8k#JHth!}iq!IQ)h) zEc`iO$5}ER#z|7xe$)DM`-843?>4r7HGW&6+Y+y=vURY!_(@iwN?>us>%ea+?K~4P z%xQ0usDyzS;$;QRYQ<{%USqD47bq{5zr#9{qsyb)IGYsR|Igl=uD6loh@!8Oc6o|q znL8;`%cwLImmZ(vc6q#XpBYglr^u9)Wh#@MnUt)SG(YbH+(*1maz6mEAQn=R%T?Vy zr)#E7WvmDU0)apvfSb$Hbg`yk6!6wH%(R%)h^542)^L;$v+h@P8t?`CtbDn|Uf|S` zPY}sV%|)D3=sF1T7v%+PjHfrj*{T4gh19OmOEEs+4V}n>C4BOxZ`^DkOD88ME^ywi z?4qg*n-e5yx|CO6{D~L^=)#^U`Y8B|!43rm*DV=Q)PTJz*V%bg>;^swRjic15V>du zT4AC3=F#cu9Q_->^D7_*w35T*MS3nCs8bmur(8Ne%e#PGb$)0}r>BrOot`#gav;Lr zMZWoIG(H)P4?q3^7-6YYF&cLVAU&pGw_rFP7DAg0DXumd%9j2xdEea);0f}j@CVVD zPLl>XKqx~>9WWUuyXjbi2uno)17&VTc|U|23p&3F493kuf31`sE+e zH0`lqb$^PX${;q&=?%s8UM|4eKBSOk#M^WEN>c94=Zo|-Tv&aOYYZe$PEDY>B|=gP z(YJVEBd?Vk>T($jX#_OXlUQC_^LZWN15o{aVb;)t{Vf_BX34h%Ghu1$H4ql(U9ef!6yL{Sra)J%9L+6^F&Lkc2 zN?L<(|Ip*|@l}-F(8Uto&!CxQglv;;xFVP*Es{jhJQq*7;v|sao0S+W;W^9e5@Qgk zi@kKGC5mSRrkvjo>?ETkSMA86mgb*?_ZKpPJe@A(7qf~NnMMwO6GDz<3~i6W-ygoN zSH54^RejaDqBmCId8z>Sbgfi=5>8g!18S9CX~9b@@2<42r}bNt&=QIlWrl(LAHnTX zN!SQhi4&o=WU@^uL@Kl88%e_v8mAgqPJN0AQ${t#h4(C_a{p9&a7pw4*y zfyopFZpJ9}w|;ES3h6z@sA$&GPP%lNzZnf{7@kDLj{yB4Dt@Tv-1fC;=uGvqx;%;W0(H;^mmQhCoahcOJd@N|qP_OC1MWL-cslm+7Z;c(pE@iP1aNxt+cFb#5$o|*%?#h! z!+Hy!*>%=&AG4It=Lh&(e26WPLl}74hE8kpG%GBQq%+EuY4Y`KP1!66u1d4A{%IfQ zYFw!y{k!F>)4a$a)Js?RQ@m={w@Zd1ei5D1kzLybY88f|56~s+rc%H#05l8wjR6G* zHd;TkTNUC0v-@*x5p@tM=eElz;)gWNO9pdM|+e%s`_#5gQO<)_ej^ z%!*Gyiv#Pom~x2(6X({vJ%EOF89NAl7UMr);fkpOdCQ%=ih_tvT)>@&U1Xah|vn+!BS@EYHl*qbg74LQ(r|sZUZL$ z`1i<%2*}sqkln1}>$`Xa(V2a$H~w{HG}E3@oa;rR zN|Epo8HfWa&8+k0oJsPR>cq3=gie)(sjpuf%3NF6J^Hjs8z6j0m9(y>N4fp^rn)3D z8a?uk;vZ3wq;PEC>WV=J*UN2zgoxQs@A?j zN7GwuO!S)}&ye;^pQC6Q6d9-i(lf(1>SyYkzQ(*v5raLY>uJ9vNn~NEh5~piQY5eKk72Q z!biSE8eBw+C0gXbQ`uFb9Ir#bk5vX%73c&Q+mU`!^}5iD4L<`jSZK0l3MBr4^)wCB z9u|*h5s~V^uA5)PXGK{Za?W785{yEoiBP_RVW?-v5x#7WE_3u`d>RF-1eUXOoOK-m z;^%WRRaAt@Or{iUStgrrt4=jX5Lq3SrPzbW=^k?rqt_A9d~gw7!Mh6G&~-#t(5Ch%& zc0@4dcjFK5{u9KcL~vxlv%I59jIc2(hdr@#eez9SmLWS8}OqSQaq7^Tc<%9})K zL3jzTx{=+(ASLrgPt##uNG?t@6Q5rcdLT$lz~2U<%)aT)*kmf3`$J39Ylw@Hp{v>$ zUYSFmG6R9Zbk$szu8;!=-`+*Ah@eo*g6_TW6aB}qxTs%-U&@Ng+3Z$>Rz>r2@)lf2 zqD5kjGMZcDPcW$jJ(2dQ+Lhzvyow(2U?RnzBtBnqCKP^hVqh$yu$j{5LI1fP4E`4#gq6_3dvMB=iD+Hjf9>nA5s{zo*G zgs7R2u^Ze5)8`_5)%5u;Cf%5FtV%$)91Rq>GNuEEA47QFGg>4MOoB;3fe$oo|Z7h_fh3oV=-zA@8C{E*gS9gMUMQ_96LLtO*&O|*6 zpZc(k8$i?rPLx@s(PlL$t%|el5`Xtg?aiY_jE^L0@Zb2&C>W04eRwr_H5_~xV_M0n zldg*8sz8$q0>(TWi8mJ5vUO~NkbFgymCLiR672sN$SAk7uwG>GWw}zZD_n+4Rr=G5 zTT$?J1ftIUi(BmE{!?Yobz+4;?iofI%3qb&_`x`jg8%uF*TbV;M|-aG-%NLSzk!_0 zggrRTd>7>DDw{=r43`k7;p4m4`?IhH6IlNx2Q;i-fus{Tgh)d8c-UTnMn0}UQyUf> zXw&*~S`99%!RKo5xos#gKDTWq0x7}gJ!4y$8ILIaPxzpDIbmqRjr9Pk>GSibm_7$% zWK25g9(_LE3+|DrFw*h!mK4y0 zmMt^1BCl|7+h2>y^yqUN&PoUgG+I$JO#}ryv}c-irom+a-+~bJO9^?7T>`EzD|7{n zuTL3wMf-IzaD7>5x^X4JPx07grD7AL&b);DZ^ojygj@{`!Dk6tH@D&2H*9pAv;v-v9j(i09`5nizUd$J}#^Ym(qF1E$ z;a3eo9e|Ny7LX!?vZ7jtJQ_)_bN(qJg;xp6Zo2$Zo=Bn1HMd-x3yZ!p=cznEDbB@~ zV+%0@s??EP9>Zi-gUnH0f9<6iqE%s&-@-$QTR?-<=5QQ1a3LJXgUGK!*>-)Prp0uu zKo9BUaGS@K;4{gOv3-Z~nK3WwC{My=evuYVXDM*Vd*g*YdTa1UtOo9MES(ITM+GF_ z(`AeeL+Zj%z^T=9H_8WP)IvFY*Zch5Hh&YZ=cmu<`8@cP#)tO7EwYZE&UVw&U+y>2 z7aU1iUrA&Dmt$FGatU(x1dhMfjh-e`HzkpfE`v39%j<^G{)%C=k9{!SuLo9Z2?U_4 z1eH)5Cd`8oG41FG;b9DkE?gwJJwJpdV8jnjck_uzVOltY^f_SMA%b@apf?k9bZ!$> z*b=Kj9$rP(NS{$#f@hMa4Ir%Bd((v@sL-VNAbPf)w4D?j<2nif)w##612c_A)4yL-7JF@NNrp6)uXqe0w z@Ujlr5qI$_u23WwrM{Ps>)gJBs0It89pzI8{OjxmvEf$7OX2Y`M`Ikk3|eaz!mCBae(MFTdvzovs4Ax!xZr+8Cf|hWWpfP{{ zJv1fv1u^GDiAN>b6sv%PJT6hg!AmGh4J(izId=)jv-7lgk9wic+V946S}#?&KTT?7 z--P=h;9oC;QXMG@XD9j0?k@l=#WKo7D^<^;5r23Wj!D5)^O-$jRG|3dFc-Hk<9&uRe_54PFCk zTk3Djk%;D1aRylRmMWy&q|_S~)WPx4ABICT0TiVApkh;O_wEO_?StpuxzH8+3B!(N zti;ery|GWowFyj~aT^UD@RD-jzdMjX@V|Z1Jg75rgfDic)1&gy&(rDg@eh^h^!UZy z&*h_^_m5vz%KPQ|50%Qni$<(&IpYLlYQVe+ydKeRa{RJ!E+_#Dc@`9;+iMDCJjej< z4ZkWH`*fQBaJ2W`aie01Y0P^L>Ol8-y)0t%{S4E*)gc>mk6OoTz3FKj(^jl%n6jrV zwT~{8gaV^v`%r;!&*5T`UPp5y9j#VC#E|#@a!KQD7~L9&MFBFWaEdLS+8AeDJ7$l{ z5M*;CT0OQu*`{f>ac?+Gv~kcrW_ZSYYxL{p3@H#ag4j&wI5;pH?jD2UQTu<+uVYkn zV?F+O5nOI!Ohb9WPJ~5L+Eu;(ulGN_A-PU8?8a6crpZ;539SZ(dxmW^$X91) z=s6s$2SV7S4LmTj6X2OHt|5f4zmWiZ9=w91-J;7 z{4jweAUt~FU&k)yU^dTJVK%4xLcB=LqXNC2g~~I`;wDg5B=Y_d z`b5Kw*({z%Nr6F(&QkE$U&!Tg3I<-0yr=<~H-k*yB$DvC=3>c`o%Wo!2e;ww?aglM zzB+v#)=#I;cW=M!w(swQTJ1-fS3MPp(((uHHo|~zh^*LfNKa@tg?1n0vSc1Dq9UT; z2!>d>Dk}1#X@g`!K^#^E=(Fzbl>SQy;*`$aF|tA?@~CXZF=HmD>w1QxNJcteh8b8D zNhSzR`4>4Z4(h9}uiVc92nHU`=jt{Z;t`-<{xJJYx7KhK45vaw2>K$Ej01M%+!Vf8 zrrsRIMuo0j@bsotJ1D?G&cZJ_sO_Cp0+HZ&M|YEDN~;LWa~g> zbG8rT7U`~dw?u$Ij`;q29QXcyu-G`Y%cEo=cL;elu{`qM`;IyDXknv;C>mRuM~maf zNs4j)AFH&8=KR%&yi13(&+H=121U6kSn2dRx^ILW!DL%Hr=p15Q+4{hM0Y}NUCeT1 zG(3`fpkha&XY8=6`iAy}M02z+B&9~hmkn}Q!vb1uCM|KYhnW>P5@$o!5<&pg#Qig6 z9MEQ`G!s})MwN%sYANg~Id`vA(aGPb-pmYb#8SDmn6E{xLzNxOT6Ev}T`6{%9x<_-f z_1G*>JyUE@=VWmgeun2bw8Th|foHQOIU1NsC&P&%$Li5B358Kb#dZ zz!d6!@a~s|`9tTc2_=_Gw$o~@Ow&VKqejESrYI=z78~M*o=@gs8foOaQXQ`xe>yAA zC@x5?Wmp*yfN)kcE!DkcuuV9i&-gnbXW*to|A$~W&7$zLBjd~jkAMy2{C7-E=tPxpn9x#_JgnPzJP}QtG{_3kv=3y82mKvxx3G`|pJh|%8>uE>% z%hm}QQ_8aNY7c8){E7ChY2kXcfKhnra#-)}MTwP8PDBk^RQVUS z?*`$EPcyJ9zhPVj8WC1V=)P=(H8N4z;=NCl^ zE8A$mtxDmilqY_CAt$%wXAC+qZxRn|>l1)h98)xAClDvGw>0D4WNiSP7=}`Eo>=0$ zJv+eTBfzl$QcdxfgsQM@OuN4MwHFX;N6h_u0BVm}GGwg@idGJg) z<=1b;?Um}c<|oJbiWJ%6)%40-R;qeM{EveU@;EEgD*5Ae|4buCUVBCu*qW>GDMjgz+hA`5eQ?}xUx*=km# z*{-&S-%^qVD^ESN=xfw7*! zdz7H`lEAAN0=5`2HLlD_Odk9+LxR9K0?GE76@hKE!ub_FiN9Yz#W_WAckElhRF|V) zBVXTfn$z=lJ~iePn7|qaaK8eAS(xBjfQKweiehs9tWmF zsu#HE@CZA38IS?3ZbYe#EqDIXkq9%k5d?uhdNSctmVgG$=B>f6J3@$xmf{l!=`t=+ z802?fSpwLQgkHY1y=HUDl#XoanUd*YLbG<>UaiJs_*yp$u-2rK;Izzw0OJ_e)08TC zZyl?YJcr_{+u7_?J7Qt&0#TL>zFR+qvoVU9m8US!4T#pS3t7KEmAC1!nAmAHPYDoY%oyK$PW2C2{7iL8m1{RO4Ep zKr-rCp-#M#-IBr`Y$Gwj&~)w^6;Q>@%EPx+9Pl77!=_VIkGyD9)-`UGj+0mv_OvWz z4h&a<*sQb7$B8peL1BQ{O4VS7lR)cjCgo0w8k5Y8Rc{BA)NA<=BUQ^M-Lp!S&AG9z zJu6#wCfJ4IAi7*N5V=xq>$LHt7J>l66_?Gs+Q%>!8mzJE)-o~S3`p$n6h9NxKz0Sq zO7!|?_<90#9=Hrx$RG?Cv9@%TtD0ZP^EDP5$4p7=#)RTcC$>;)J@xPdvLH29vd+ZB zP|(i499M&u*l$Ec9?6RYt!s|ND+_K!WsYqjTqZN~FkgOMOrbu~fRG%KpB1T0g2Oph z4uk{_0}e_MAFjlup)AVN#gzy)Wy)yW?HHRA+qC?v$M)FK-D`&&S$s~uEhy4mK;Cso zcY|SzuESjUGdNGtd?^L*40&4Tqh`Ag=lX0uop9X-y6naNBwdB~`eJ=?0@kOrHuZ-f zAaCeZg8pzrBpGYbRVye-cxCGc$w|H5qifU+SBzhZX=w@JA zplr;_=;b^uriJv+2hzeK{%chJLbdL72YAu{mb|HaVIHYrXFkb?>UL%Ka`+*R59WKkd0eJw>^ooQsj6rEk4RU#HhmHVpHqtg#`S^PhyP;-W}D zM<5OeU?}keCSrN;DS~b}j+z*cxj=OtqyhtNkz$U;)E4SFL@hoSIEs%&clds#21fIc zsIe@c@$9Yj@bT?DYDCG^J2H-Oy=jc!{OM%;f8M?W%j)vMzdi#SfJzzu1>@=$)9G#b z=;s%=_s1_Q)9HQVe9w4#Bik(tbICuE){x&kNW*znK$+^u&f%64Q^v{FA3;PS9wA&B zC07*@CeAw`{b4%zFd8hQ%${cPc{L!*6+^C8RuSPclBPBPVm;)P7av)CE-bLD3P9sQ zBWPDF#}|m_D7pHRu;o3Eim~`A>q884%Am`xvGaDrm4BLq@gka&=_X+Yu9D(Jyr|v{ zUfcrY+FgekE9KLRTR9pUn>jQX6}bG6kjdq!Y3NUb*B{47L`OgG*1#Bl_n=ZM*I!l| zd|LctXBT#PL6+7Sdk->&%&ht_yjO^#j^QF+Tj9B7kGFgTdhINR$K`MEavV8S6>p^B zLi$+Rc`N@S(97ezFu-7V;}swAJOj9RsbhS|0#HEc4jB{zkCfn$|7!@ zF4EJ+B7~SRjYWJanrY0^49MZT*PX4M+Ust!tD(&DXc9;GmvoWCXf$vXNn8{Ib1LEWeT{*8PU zgx@1?9d#shYEh22(wo)gDIQ;(N|eJZfh-}g`{~6k{(1jNnAeGXj1v3v^m+Y<>GKy2 z3ipErD+;Z`#sU7+?J*M&D!xZ0xM@S0RdmI5dx(770}YDp1D}1oxcwa6+`~>H;8s1b znI%J6#65VhQ7FYYEC?vji9;bG%BpHczM`R#1h;rQoG;>}sLkUXmU#^yVF`aZHFz{b z4f1z3daQOgsv}uJJi>8mV7kAGc%oz1fMkCK{qEVV#T{GOIF&QZL9h|*Lc(;~Xzan_E_j>C36*eTVt3~NR;OjFwu_YAD7bHSY)B)D7hT3pN4saW`iVT;XEhl zJUXFcX0BHu?@-zrst${3!8)^7DqabTZ0CR(UPdn47sj7uvQGr5G)~~1f*id~u#KOO z!rEU4wf{Qa#e>P+blQMNo(4tI2w;Q_^l@I^Nao*vA21Tekya|snv|f~WN5HoIi>|# z7wIT;XlKSJO+qUF1`34uQ*km|tmaW(w&w<3N~|lo3}>Ii^QbQL+K(-|^~ka};pO6? zqRH~IcAaLQ@v*k3A&WCyy2N1MQX)`L-C81K2vkM)_x16?>dcxtqeE^etIT8-89uaY z8pNiFmw_N$8m2y{hP>Q*U=48PMvYBw7>|cqi~Bu`mBFbR$14#_B_2LlbIWbTwDbon zVTh3WV-K|)jYjZ?C;=y}U?v782%msYf~)cRFZriw;uWhOkeyX%9#tTx06~>HWvP~1BUoClP8ad41OfD>MG44~Sz1-`ROaT+OMcEP_(m{41!v(L4>2p0e@ z?dVQ6x#Q2*7XV$YH}^99;!lqgGkq3ig@2UsJli1w$f90?!|O2Fqud2N}cUv5f@Bv#o%WUulltA*#VIL%RAgqO9r zsI8Xvc;J2Ix)i6aIJfNnC$y>08+CPs`|AoQ5g&1Ix(cOK@t@pGX)URB0B@^6}2SmzIuDr z4dyEmv}GOzr>k>sBP>G=ZqJD@L*7cl+mw!9jYuEPw1N`awlJd5Bj zeC<{ZN=1ALqppHM!Wpvot0+57b1am{i^YxL@{9DGw%1*;@e1^%=ef%$!CAeDw#)EK zo}xnpqu^zf=izx|&g&&`mRVlQqVqT}GPYifnFB=CL`*f^TdMjLjX|%Htxi*?`P>;{;tR(RaC~Y*^Eg_>$rJY#RUXzm=+~CvH5UO%A(U%yqFVDu*W5d(&gbz z?L(5kamoTR@uf#!LT7)b97!qOOqvOccZ!^JZdJ)=>C#$`MBlaiB0|NNkG#a5ftyQ| z%xk#rP+Z>)j>P1VdL9JKRI(((KDCiYVK%!+m%t!c@01*U!SkoLb1JcjFF_t)tcB81 zI82bdxPXxZl!DLL7=Uq_FkEDD^7%Romo|Fi^Q0!k4hQvlT3e=zMePg?;gZ>nCF4K= zDQFA+KvK07vn6g(EUV?YJ-bDCZh%Rw+$wXqWJ_?B#BesXASK@jwPloDT0N|YH=9W) z(ECIj$a3VR6`ZYh>4=31f*V^fFuBc3uOiQ45?66_9ht)HN%V!CY3QK4?%L+o3JT!6 zfDt=)U3fTW$IoAJ>BG!Tj4la#HGCz-%16o7|Bh}xr0<1$AyxzL(0C@RwkqO7%Jaid70Mk)n0cx+jyk5&Hwy&H(*yn zlk_FfUhDCt0~%Br3L|{4@I{%2vC)@BRyFuiF;qkk-~Vv6l2R&3qYao1*OKuYVyp=m zYwZY(F(Y+DvFEX>S2{syGvG02#tQeUq~EC7wXjEv+qTv=beGzRF*sdzwJ`50ZKGFiR7x7&u+rD>z3xcu}g&sPz7t3VbCOlkTY zE(jOV{q%V~cyUX;3-SK`lTDo8j+DBs+Uw3%Uy#x`xhhLDB0l4u(QuT()i}XN%Z+ifPY) zKNg0N5vm$_p2!lEfe|poa}9GAgp!wsRuJkPwk~Or9G!zfA7#==&>=1!&&Bt#dYP{= zuYf?Slyc?k0FZHrg9A~HfdNh^5qlaEXD6sU4yVTGejR3s=fZH*L<#Q$kH(F1yTC3( zHI_uPmCA;}!gcBLaYN_x`0GZ#d^#1#k!~2uqwUdVi&(D?E=DZvi{;rOuA6gW^Lt}g zlf)_qO=6e62~roYv+H@e!l~DXk#+ml`b#g5n6msfoQm!m7^k8G0eStApdrIHQY=<| zZ*3@{6LO3i+|%vNLPIK(D`tkzc|xC+%~uUFkBS-`&DaP(=22#I;(2s7q+L*n-Uj)( z9O^+-pmRrN?eYHO=%|IUc?G@Y6d>rmX+z)%%Zw*Jy^KyFNgzd$bJa_2^54Qo~hTs&G{k zwa=>Sdp5R}xaP*Ofnydr zYS`n$Vr5kqcF~Iz4`OLvhri@JP7@$zND-84TXqHeSQE?**w!K%GZ$!dxrFP9Z zRh~6a^uslS7jLXzo&BhOHv&=F15?&{lo#_j!`RW_f;x-9c@l8rGzmT?@fXwLi6eP5 ze*aYcGi_`pHehMtO5gTg9nWh+S;l25?@NwXDHs>wvZfr<=*qsnj-6*H5JRE#!- zL5d-28x|?bAVuYJ+Y_UnGCnbS0J9S-fhhmyFJ%;yj-7t&~#ujB_Iw6AoeJvWxIDgc^1(7A^QJUHnC~t&5%SSi30f z!p>hMiJ}I@>c8Y1s~&rpQpuk!?P1pClRb=+t7)jzsyFLRJ6{{ilwQ3b>Rd94F$aof zF(zMk4PwkHWD;ZH%eGTd?;3P9Wuc<1P*|2UEs-RW7xO5~c>BuCgsogMGciHoh9+CO zs4_Gu{Y%ae<}o!fv0)jR7@3Vm@aIUnf#;?snJm5g0}gU!S}8$36Xv1Y?DlQ9TE+sTw9vCAZ2oxkMuG&^tTp0xFhscA*?8I#0J z`xy%=WjA)p-3{ygDiltevP4gKW=RO0PEiR8S z3mR!Uqw~1cjL|Kc&6G$_$|`s*P)b+2gfy=)!9)WaRA0yxWn`n(Q(V+Bt!*~SS4@a9 z^Jh2b*KtxJXOoupjLBKKlj6!^Ii^%BfsM3o@P1XJTNneG!zXi~M@WgKBt1>%jCyTr zA)kC@$g9GV$WT);U7=801-qo@s%r&Txzud8SwqSK$sCF{F|yKyks)6wKQ8BCK~a~^7U8+DLIGJ9tWe~T#rt)dDOG*b#QENcu@{%m+ zwzheP5KQBn_G7Qxown|-A^((1fvlqBTEd%B^Le-Nj#D5H_<5ZxA%c>asZzyv(J7k; z`xLbv&+6QcWRJfsUS=sQX~F$WH9S?EF@=cSTG&E|-AL5N3V2zlx2O_-X8%l=kXNB% zM^!Ljq*l?SqMS__)OG100Qv9}wm637T5&PpTe_%q7fz0(XDPf)#G5`~(juNC4Jjwz z{OT!hKv4GZ>(a`ACr)9`Q0YsixpRa!(ErrEod1(uk!ZIE%SW&QK_x<2Z?|);g;L%Ym=yTQ(7(Q=JQU;38C&s=yv#RV0Z6H;2W=0uPe=7__#3COoQu zSc5IsjV$@0s8HqZJLSbbPgc3LC zTTxr+B+<@U2rc;JJQo#>-Xlv1#%5z(%v5=*>oFV4N z@W2d=B0YoqXboms$pmVyAvm-q5o-+g+z`1aS3}aXDv0cg7KH3xQ4?v01Y-a@WNeZ> z9;UJx^JM*utw7ocDz*nvJ5Y?KdE9JpUy?pQ<19^pkNruwP%L|zH(K4^YiID~|-8BAG-Ge{B@{EafnVspd1AVW0_Lt`3o4AUnDG5~MJRIe-t zS5-}EOv+XqM9K_j38Psc6w7=WijdGdM0lP_5%?<1Jo+z4O5_o4N5Q^1%#YWH z1&@T?OOt~+deSTaUU%7v=+_MVeEq=tO_$*K$ki0T3`)C_Wvb_nY@l-NYN*#j+bhRR zi;4QkQ;=Fqc>s4QBA7wC4!dW`_d_%gz(&rnvh!UytNCX=NWy=&aTyhI)d|AcG!c+R;7qx_2 zH7ZIUCFWTzpa<-4$=c*iT1>kl z2f25k;usx-Ie1x6D@pYGzaaj+F(R#bxV;y{f-|ce1@tZM@9(wJfobz^)62LRMawLj z;aeBF-LcB*C>CI+fhSi50>-Q<%B4oBB4a_QldB~96Q=LrYvJI4mnviH{Hj58LkD2E z+Wh$Lb(uK%$9J!W>E$v_qNFg$lu0%J(rv;~_}@wx4_-sVyI?0{XYrMJCC!d2)!1-(9*RKo`KGL=yBgez&cUgAv~ z#qj>z%8p=z@N21WNb#rnH=GpfmD$<@YH}F%J<{n4u zTRdjf>d+i8l34mS*2-F&0h=TK66dIn7FPsivv&o(@f646UtnTrG*|KZ5;?jQOGIF{ z8pwoW=4B*G&_>>bqvE)-l~wC=1&8ITK&(G=JQfJYmL~)6n-i3o){W0VCR1N4XDNCN zdzL8=yvszvp?(>Dc^?*Wes%-APF8RT%m&8uGMUry+D9}`q`)f^S3YvncrsYv2B_}c zi!A|%A=|M%Sjbw^fERsCbBXKL$4IK)WqkioTWcf&+SNsiUYWoMho!_C#c6@*I>C~|_fz3ffv zo8@JXu@l|Q_uuO_VPD9K9JDUNfT&_N(PvF?;8EkRJ|V=SXvB0qUNJ;*-7EwsCJ68D zL`Qp0x&I8a1q*>JwX651kw122B2*&%};o0E#^V4Q@py; zAvd_KtE^U$&7Ni>FVfi6GUsJaRlJUAR{JT9V3X#Yw?l#sZAF}xJR zNA$k9WrMi?RH-k+`8b)EHOW+iQc$V{FBv0wNew_JkP)RS#=$kb&NQi2#mDvPo72nl2qfPML43 z2gtdxSBS-zA_(cKV13&pA@N|5MFM^{P>1xMdd$n8>297L=$9a%P2DtSki*$GM|TkL zub0pWk|@BIeC7=xEa?6X-<%LpR`qPu>-BV5ROP2=QheVt+X#(KG}(k^ZS1PK#l}HM7+pgC@*NUSvl)Q5zZnX_X8< z0=^{UWEHV>ZxMko)r7H<9lwjws)n^v;p1@-zj;i|Y)e=jIrt**9uJyj)FCSxzGK9V z;J%jxZ=b{* z-E$UUpseZisC@MEbb5^U+{e>t{=3PjF|bw%KJxu9;+bvKSk zC_R4JIA^8}^A+i9DTs~B1(9*4XVjn(R`(fZ-Q8i92bkW;ARinb!rz(Z^V4H6~R1BN<|PBML4?%;-aprF4t4u+QqMHrmNyebaZTg z-ra3#c*E3uj&9zC*EYJ^5?vTin`9!kF4FKR>k*e{5wboM7 z2IM1yAoLU7JI82L$Y!E@3_Z%zy-`te7;FH#$AFp`5RQ5_b18b}+H8!J865BsrLusc zqg_>p8Cnk0l&cHj%^{E4G-qxd=+N%AUqFa;^QJvdJuy5sjE0$<%^rZumlBT z5Tv2g8&I^wV4M*yK&g^u=b|<+4zY}Kjhly{rxe;}aW>Y7^J8hv(pDT>A|CW#0s4aU3- zGth;~{Upu<@RS84PaW1(rT8q!(`pdT=Rqtq5n)lq_krNc8y$JVTP;KgVl7S$JM3jh zFD1Mu6`_sLqKlFp$jTdH{-w*ZafV4CZ@~?>@u1T<=S{Ndfo5QausLh(V&10RbnVWz zY2`z!T=B6yf)q>hVJ>VcuyLC;HdRr>5j2(*J9343?u3rki-)OWd6X>V<}8&AMDYCZ zeQy!|JX!!^si5jaT-iZW^JsCr>3AkJ?EkS!$%F#60Y4fRm%uFyJ^l1KJ@bQfeRTk- zdM(+Nrq4^$=WZ=Zt{Bh&Z(8Xt@7g94Q@1g)jWP-A1=nUXXWPE32d{;72MLRx7 zHdo=I8qCv=NtDm@afcLFsPF;9ez43_0MmYIjPO=59l>i+M2(a4MHKu63g*FSbOzdR zSZFegIBoidUaUU52(v*^ZjzWLCjXWR5H!I;Kx$R#K**Mou(jajO#wsgUSvg~$^yqE zjXjz+3*z8kgT-DDzkF$O3DEV3q5_+-aTLLcW-JWSh z`lNeoWereV7$v~Fh|W%p>M5^zW@Mf5tT>599>g%&e!`G-Ti!(e_>^z*3r13u1{&pcTO1KKO(Jo^15D|3}bBl!0)o0HMHijb3@ z1)spj?_2P*7G4H0O*y&z{YCuB@aWTNvb@B9ve_py7=YLLtpK1Jl+fHgDrOD-;$8bo z`1kZOI?bZ%037nh;UbuYuoOSNC}V0(I1{LlUk(P5G^H2t7;bxo^IsM{y)ldyi!j3$ zoVWfL0tVN~vTR5x4Ln^C1GRhDTZ1ICFTl_Gftkqij!?^b%9FA)JYf+!inFJ>PF^zx z-5|j4ncI7lhDT&`wy1*x9|MbKuv5>n4t15t<%CvZ$FnPt@R+h3YN>zqy zRtj{inx@U6tTD+Q)-x|4x=UT%?o;QiC4SdUy8CX7J4ZJFw|sXC&`nNTW{?`*yRH6g z-|?2&pNI6z_6#O$`b=NK5wB(K3Sed>R?JBHmU_bW@cO6W;I+L+h~ul~5)M=6)v7`1 zKhZXf#Z@^2N(C!Y-0SCY=0+-k_Sf4j&DO0*Muj&R(vRCYsRQycWGq0 zy^)mQaUX9l8}TUYMkCrqGjFV71Hv;OSi|d~fbMJD9g_zNww@oipc{<OezHUzABm_fpyxq_(YEH82?;c$C8$n`j_`0&0 zk6v`deQZc>$oA8VHOSLw)7`8s>O-8aR$ady0h6P!2piOH!@;UAecf<4W;GleA%^v# z(Q4UPTQ&Dg^Kbuw&uK(iYs5K-0I!lfo`c_scrmAw6sfJ5t2}vNTgVqSVrt&wiIAc zvSQnYZ#eWmaFWJQnIGT1{*XfJ_q?R}c+%z`R8Y9?R}LNdX`9WDJa*^kMz|JZB0o-_ zoCq1u7Re3p%G7in-geYi*}@P5;`|lK;nAE#mj#LdY=3l5=4JKRf)kShrW$M{b`@R| zO}+gM(20KmW5SJL6Q7jvI?cydCdA6ECpl;>dl#Aq6`sIbaQdwq22gQ6xIB%|SLrG* z%S~ML`vvtN%`bx%fpd4Kle%tF-%Z+flLl_m$W0ovq#q&W5Y3Lh1pkU3T_?N8vj+_-1g7;p0$E`G*CH_1iW#D#a#c9S}G?~^|3 zed6{$aeJSPoupRN9cioOOY3;j4&AhN&y&{oq#fD=YIRy{M6Hge!_Kx_X~HXYUCgz* z4$-x`+eRhNFuLwUwYEHsZ+W2Xc~H>vprGgJcj%cS4@I{|9#}?QPnrjo(Y7aT;7M~S zsJ-QqM!V-p8+JWueS0F>!yPse?ct%Pk~HfT1|6foj#J>!XkqBKFf>{i?l^#Vn@*)}iv!;6y1cUMo4aPq#bvX_`)@Z} zJzu?TU*e80ap+4Nx!ty#Mz`&@r%2Z<()TpoY5Ee|zQm3%am$x@=t~@X68l|W;=~=w zcFP#bwy)m6gSu9;<4fG~C3>dA$H?0)-xRmnEni~Wm*}nT!I_U=wp&{chi!w`v4^117rvX=_9b?F ziQYE1eTj#@#EB=-BO$cgtu0@oBh$6ptr5p=yX_la+c%W#~xqEu)pKe#b4cZ5G*f zx&GEp+bH5g!PcPZOLU20%aAnMTLTa3whr6A#Evhq=S%GS5`BWlsAU>uq_8^vxmzU(>!Z^hUl!9}0GSquue9Jaku8&!nE-aO5d6F^Y`b z<=Y!=8AZmvqt3YFOWgJ)x@@LrvYFn**TcjWhI$iod=nqJO%8pDzFC?0a6R$hy5DgT z+3y>$^gW{O;g(V4aLYXcwT%;ar`>g088?lS*kpU+6q$_8B4f|unoK6n7+RB-Q4zie zopxTnKWAl2t7}cu?gk4=jr{=pv`qUrXg4p z-rDlY4g+7JXIXXHJHA9$((Q~5{YJ;55o~un3cz+};@hDozAe_fnp<68qKCB`>#*JP z9nX4wFT?hg9QYX8z_(oteB8<>Li7%Om3=yY5-2zh%e({Vg9XTdwx5zhmr}{T+|6*gtIg z5dEV-)dp)N1ls>9pFOB8IBH)7o}nF;yU)*0|#q8BdH&yydpiHgtNO zcDL^qF%DMUkt^SI&3%5*-F9}nL3hV2GIUTk*fGw5gPp$H%FyU&)E~IFE<5IiIq-=k zEmJIM?YKocW|6J7TV$(i6zTQcBE4<1h|% zr>*U6tI*J0Gp+5BRcO?7uXhIK%7X8Xuh5oN$aA$an0Od3q&j5VI;P4qKhJ zTeY=iRo(Jdb-7jRuw`g>;JfcBWD1jqZQocY&1Tn^I`oQ|?(zo_vt^2yJ020aZOPH5 zR#FzSu74j(5T9dYi@k46M(_qhP&^_3;CLIg@PTM1FciJPfP{-F&r*9T= zxeFwY%|bgJPoaSY)6j$Xj&YoAO*$iAOJl1g-y)xM+yf^h8aJequIH|!HR*Oe=<0Uc zX4Q!Y6Wxgk|5nFyw%Y2Nr<|>>hfYnsTx+uByJ?+l^#{IGkNOQ#d%o0x2TfZO6T+T* zj%`hP+a`oQITcbpXzGous-w2A(3VxG?<+L43i&ueZ+z%Y^?^3&nhpAvv$y z-WHg}Qbj&+D}^$(#9TI;+5}w~oO)kFDlbfMvU^ik;+phKEyLm1Ei!ByMO=G@$z(V% zi@4I?WMsB7^0YECTNw>K8jo#L6BE>EMZ9_R1Fv*=Y)MCVb)N-A_|2k#$lmJxYR|1|!xjAmeE7^0madCjZ_ z=V?Kq9>gPg)f~iosDG;Xf;K2{qcAT9c^oDBu1G>^r$OTgImR6 z28e9=u=t+GidYYgUQV1T>0*jV1+jT@$~FY(4nVU*Hd8+8ZhIc+v?LxHjbM^y!P^Yn zxkOn#_y8U}=4q6J`=?pDN{V3mTmdkBuAiRg;PaF`^TM-oL_rWI%T+;7Q$0a|@;I4; zp>uYz$}!>(puH9X-fPH-8q3vU(db!DmrvsS4X#i`9!B96BL<7#XJtQT10PZ=w9G6s zT4p-T0KbGF^QTcGx=eqG8S)xO-~G_6?Ho_1E4Vf|m`+#i=D2frG@X7K?7%-`OzI5r zr@I3`a0rB-4t?!(YxGN>1MxF}AJ8S^&msP_xAA8+s zn7T!+ZVj+GxT%GoVH1BQlsFmE4+7q6Hf!|Tr5{RdwdjWuTU+#l!1dZq`f1ZohkknW zGoT-8rHyd+Is|F2Lz!Kw-=+Fpk-0_fY*CdSmFZDpkNWRXA3Xx2e@H*nRiEnZP@@9l zy`4V&?9dO@*unAl2GqrXiV)s_B%4KU+|y19oxv1O0Z|h{H~MN3Q`Oejo>et2v~f(Q)};cRF2- zwmU;8Fq%vbYxFxgz7usTqB1C~@#k<;Em^uV-VqC7NF?8+pAHc+&C(9h3XQr)3jj_~ z_(L-|q8S|1Tu%i2TZCSkk1ma-J0^s7YV=EGb_jWWBC9?T3#h0Oc}*N8-WUr+(a_q> z=7>g!Kf}RR<$y{~b{>T?-OQ1>fYgkL2K&9P+qLQfdmpv8?&uRnI2!kNDpVO@C?D)1 z7(-+Rqfx&}KP~zh)6WDeA{mdyoj$^g#5tO@y99oFh(Dbk{`9fu$qs$(P>r1(DvFD8 zG}#%`4>mp-QjH-cjzp^?%EZMrnoRm8L5?Qdl!2UZG#U0EL0Y2;uIkZbIM`hJQF9<# zq!A5=$KP&tX2nTV;UnqyIOLLkx>sPH)&je8v5qcP==kZp`cW5U~n$QifM(P%=XJ|PfC$fQT3 z3Dua;n$hj|&GvgNbwo^RG#XDtH#KhuJM?pC^fR{l+4lCcE&8FK!(WHcAcLkwiv;CbO4_t&yT0)atmeC-c>&@btK)P!@PpbhhrQ#apGl8*H16Fo zsGP|akZ+p=DO=k1&xJYHYGrs?$;ig?&J&o(NYJI#(FT^Ky79Axp^q%L{e*b9))s83fV1V_-P*B-iL<;)6;KNKD+M+w}^0lkuStt0vvUH6?ariDBoF zqKA;rd@_R3hmidZ(U7IcekYxE(xNyPk#NOuH)(F`+UCf`xlmU*L?B1QUf=j?i!U+c zA)f7Y_Sme7Ee-n}Bh~oocSRYqo1syrQ!zd#m4k{H)=0^`9h~o>*z&tX^CaGkdJ{t) zChF^pMcSvL+q77=1w+}Ub_T?$21Lw<#KjJYhz^M!ha{toND>{5#NI(7&uApp{)i}l zOf8H%#u}NJs{*Au5<|yBVhdxE9mhg~8jrW=2Vox*mmg0$mPkFsL;7e)Lf^1UBOY!E zB=^_^4|_zj!ycV-`fV{il-j4V{cZZekq@`2S(4j_+cW_?EjlF;=KJ)sLujNU#2620 zqj8spG$i0R%iBtZCJGz&1u3)`fe9KKZd2kmjbNJ~r|BIFxp&+ZpM>P@h<@lyHNe)! zhh6&F`c@~4QJ*Mer}>1V_Gl>N`eBns*CdH)h)RahuqEcSO_R{3y=6!zgkfhWJ_&1L z0d=Wrm#S>FYHTGBdsMS8xh%-``c8=>li41_=0$0Tw6?@P(k7B8-OHF3 z+IXieNaLGzEr>^sc{G^t&FoOB0sW!~RXG%k^ssYWsW9b}U}e7}4Qyhf--b4xJX7Be zw-6ujY^pS5qM*p0Tztw!u$mqmq&C2+nv-11TiWvFG zGar+G&d1+uKE^l^N=EGM{2p^*i(bEhT=zE+v?K<9TS4+4PMq^jwnG$lsmlL_3)OQX z`F#bxe@@l6nX2DUB>d-$ebX8H-Gs(}&f7Pdx8F^y{O62)+ZnS3&&gwLrbeUw);Bf6 z8jaiIHFjUyvP5TVO^HKQ!jbQ27Tbq*Z{4;9S!<_DKU)rDhrQqXqS2Kvn?xKavU!?Zb|tcbB(Y!WL?>{g{iQQJeZ9 z^QV!xBN%md_~nDtp^Mu+$|K{okucU8iCaB!SvVSfv)dqXBRHBIKcNzl)2K;xTLRxL zvBJeC-35)rUC^j4CWo%#I^zC?ZhuByQK&EGN=ztSevJ;r)C~k<5I3Df10%Xl9V_z? zvPcxSB>kar;j&FPmD}R#hK&5iWHdG&j>X-{P+XyiOHO&0-x)rPqPq z68p9X)vucm=P>rqY5BIN(O)$!_KEAClk;tloL@OP_Oa@p)ADW4mA`IU#{ZlTes~;D zT3XKYNdWx$jA{RDs8v0C)ux)Rme0dgAJKrLbn>kKjm2S*wbTpU@YEPQz<(Zxk#4r#PKP-{YJRy#z+$d)YIQr;tj3{ zb6l0N^Hxa#(>BJ~)G)kUzL2g`aGQMzHG2{L%vVnVCC0I@i9#U22@Cqvp+V^DYw?Jf zGDNsYgRXwkShk*C?*`8tgxrg9VQg)IJ3&gj`nB{u1f5kBRu_NCaapkl+52YQLS3a| zFmur>zF2-mLB=7zZI&+B6Kx%$P&X;ucmQRvRP?OSN5>*o(VYp8W(a-6$tq&83@s@B z8f7W1K`$V(A-nH(^Q3v`=^oN26^M}jU%KIZ8P1|=kfccsLX|~XHIToH=&Yy}X)TM- zFN)wY%sy8G{2LM>6Vq5gCx&bh=;mZHvHDBW8ioX?jz#dMryymPUY^DYQ1w%A(m5fI zDHcjPCq2T*P_;Ub!&w#=@hn{6_;NNtyVcg<&^-op4fdC@nQM}<(Mq`%PP*Ia;e@pg{1l~c`9RGQc%r0Ap{D`dVA>p zged4;bO|J0zyg3FW3bog3v5Eaq#4AjjKVy!8>>t78jU`$J|_S_zI{7>HypelgP?f? zvaZ;a7Yr*l$1{0(uAVyIT zzTZXX<1fo{>E}}Lk~LJ%(^WQ$DxN-025&|u28gU3r-k4p8;(e;2Bq^=Nw@vx;~x*l z4>VkwPN&oP%hKldWQ)rz%A@Qm8itqAVi@M&O-Kp%Mfy6ujxtDwkB`fx{7}`>B#&k* zh-Qkpz&W++8dz#^{yNNy;YFBXTT&F?bMvu*HTh2|^H#t%=jG%A$KuHxk3`Kq@#nvq zClZnT@}(^VOLi#^0?GLi7Ce@Lx7UI}-TWA|g9D>xPzyT8DCL!E5F;1PF-nXkhhHZ4 zzW-jYwGBMnIIjQ)Tg0=d+^iBHmEa}z_tMO!ygeP4bp6D+qm>h5O{b?dSyGObvI*gG zg9)Mq#F#b^K=shml-u$5-)k0Q;{`Iy&(=-O-Q8wlel%8tTF}~rSVkEyGjV4)^ zo{)7C=}hjia(09oihDkknlmgxI|Eak4YDk}smD3~QY)3s-VjU58zKmL)M}9ir%~`p zursNSJ39VUGGtVy+N1WDVLl6S0J}_|HZ3+S7qeu&UKg#BDvl}OyhD>c3v7rLa~Uqn zUtlJ_)Qc>>ELT)C?D|=}0L`e#74)ETF^GJrCWmS8MY9WP*Kxmzd7E^5rIM?+WNTNe z9_x#A7A_)e1u;a;NbvyR7h4El`eG=%{!-AOE^BrqwQ~|AMZ#YPl3oE1gQUy)LGog@ zrRV-E;KDL)?iP92=x0Y%ks*85Bpe)=3mIEPhM`eNiSCSEggM6_kq&G){>oyEyp}`R zjvVgUWGoq6jcJqkVvw*w;)4H`-2+cGD2XK^Ydof_;9%pv>D@GUH)G75H3x6b9LlYs zSpi{;l1K_``A*<$+w|?3>(1q#!*=;LO%^wkILiy$Bdgqa#ZFB-U9cY<(O61HaAaFG zo8agW|JXS^KElM~a^<_dgX15{2fOP3_l{~|?XQE{f8jw7{%L&oeSLTT;9vgjzfX=| zR(`lUV)@4}AFT32V0N2`Zj&-|#*TWruo8gZBL54f}mBST_ z;O~00%;SnS?s=qbj~w}(F6etU;%SQ9DLW5HO?J|E>N>ATD|f#|t4|t_TYIx1)!mwU zf3GxR^YlZ*mfabppFcjT@c1c(M^7m{++4U~PK`BCdtLwCF)P=k?9Sp?%KFS4*#@R& zSh}mVv*X3;!@O~);@#WF#v22dY90aKre_g%k8kE7jE%ny#x@RY1JkK&lpHpLKKwSI zkDf5u5ATE{!$-rn7cdMO_`8=ghTlZa7}frSA|u?1=RzxrcgcuN~sL z$Q>4rdQJo1F4m3(YjX`&eoX`vYc#e*_{dN&Rx3Me0ewu69c$F%b+oW!cRPIKntWP> z91EOnx07ELqQn}*q0{^Wp@A&$w$|a`>%zNOtsg##A=n{Gtj0PIHTL!4Z!Dy4KaF!* zaiq4^gp;y{(^^XykBcK@H8)uUvyQuBRdA_a1%I(hu4U_w3RPp_cD$DVJrn`TYG|@< zo!h~nD*rc&kPm6uzm@cUr{3Vp=$3<;3~y<+?*tn(k^d_Kr!>DZeu|8k(lr97G@lSZ z#hgRiMHdllYwUH{)!XEvOHAd~@#AoB#l(F?@J|`c){Iwcg_e~eV$C?A10F8aAMkZk z3{i?VOTehGufF)AD&Xm(qm7Dat{a1nTJc+(B8;m^t0J7|#_*AfZ3{14zf&|xD_*1> zAad}SAdp>eEJ(EyW%wH_giZVFgUa|~64{Yv#M+YH%Y-Mo;m{ulW>dtMffez^UZsL> zO7Cn#zjrnf!nI>MYZJRV1+y6qge)i+$v}u;Gz*GB+iu!uClG$$#(gtP4s9^w9r3v% zwlR6u{9S@*3-&>4^sB;V*M42V?AGWXAa3^K17>>}=Of}~ZyDjU$DSzKqmIF1cMMKz zht{t7cx~HYx!ZE@eqxMm!JRjS+I|e@7IC>_tN2v(=PaRnHbJwV*O6saYW)H ze{2Zegtmj-ptZ^M$fidk(oKhQq>(X48gXL#(E!gfahh!KqhU5{t^9Qh%vk)&4+^}& zOVpDR;0S|7e4Yg5BKktlOmp$f1mBoKYDK;(fe)x2U@>~@l>`0U-b12zUW3h1UY$Pf z?t;<`U5AyZdZQ8K7im`1W^p!K#YON53+@Ib@Nrf86off=txA^?4$&xZ1T5hJNuU7y zugKo%19}I4EV|G#oXaBcClm-+HX>>ipPfx$9Mm;3BlN@tk9@#k5)=q_1K^PGCjkL# znjm{G8HIQrDe!4NT}A8)bO--Gb??5`HnKd5zKT{>egjM#t|1A@Wag9FvN6UOV;sU{ za)_{nEwCj=lDTE^?|y*&i2F&-SC_uYGP%sGv%m8X$WmXbtE;Q)*44#|a4erbKr!c? zLtm&8Cz`>(D^Th|1Ay?$ACur#Wv_vE+!p-9!?F5wQI@9)lq^qmhwy=3-&nj`W%uK+ zMpr7!%?)L^k)Kw~k;=}nyNY~P(BqgK=V7G)XL5d7KpCD8Ba9kzw=6rYILZ0tDt>`; zej6)v&}&CRPC zy!5_0)*?V?3QhNAhDUu)oZkFU^Sl(xI-tCBM*H;QhnnYAqFSG0lB%l3iqx7i=B+&OZ2Nh?ShGATB&c`##2(hS#&9_g#rs3e>?bEMV1s^KsLB73IM=>c4S5ZdIJkE%_GC zl%|k!>y7jAMa9{CAwNJKIDWsqRdKerRXZ{4qOxL$F#c4Q-I2;9m zmLicC+x8bhMDpUL{rZH-~nd=OvljY4ACHOwu0&M%6vY^kI?)S8ixHdnN2?dh4Em*I8UQc zjz=rjW_|od_3^Q+J~nKp8-oUQ-A_6b4{lmhSog;EjRilhe|ngFuIOU@aRM9IT)7Ra z+=DVU0Q*d4Q@h(aP>kY;ztt?vmn8r^$d4PJR*H%`kC}2i9Hz-MO!GTN9pjeJqy~B& zAiu&-3fwTBO+rkqYUdYvuu^xL~oxfb4x*sN;l0bA?ERGz7{;1xYS6q(r-*gmAv&a_M+s<#~X9uz`6% zA88=QJ*NigVPy)9VU&+%=d1l>vet=ipRXYbp7#?F=km4ladN)4b+I0<4_<^jo8jix z_N$$j{r>sJtBaT6>+Sxl&GnrZ!OQK9ix)dTy3!m#5mY)nKTa3{Z{`TP zTpBml_u86s5;|ZL0zp_NxrQ2d8Rlu42IDZ#LuVAGVa2(L@)4KphnP3VNiM9`P=rDW z8)cGJCx#5hW7Q6%UxCy{&I_ZHY!txq)(wHhBZZ`v@7@vgVDX~|cts;IhM{Zx=DaR^ zQ5Lw3mv7DY51PA}4gBtGzF64A=GMkzZJ25%?iI_+*yeKpYR%bv@oL5S)!BRj)`QKh zO`|ERAqB75_A_UB>!tIn**G-4=4@_nJHI;HIzJhgE)*v0Ei7)71ne3G6_gL(=8RHx z32%>+qv82HL5{-P0tK=d0a^2Khg|y@JimaHLSJ7#{6{@+J*-8m;ceJo9zkyFgbhp^ zFIQIH+GO)DZmKYaj8jw+K~G$Sd$4?c#Fb24z{bQazBS8{?N}8v{Qz5qu8m?WWti=w zjmk*+`n!>M@|k{S)051ZRRTG?X5u^?qNV3xHaQQ|)oGAsVFL}+s?&aI3A1q&=g$XG29u5V0Yv#tl!eZ(Yi7}9+3oMYL(|SLXi%>#D)PFtge*|pREc!prRQ z@7h{{Z9E5$)pJaDua|9+j56|9A^9#Z7j~l+=eOUS%@yZA&T?@_!%rLV$=(=ORvsDC zJi%f2&)zvN*T1nTQ_-JbGm3S5uaw5T#bOf6WqfF^_R5d*zHc$UQYcK$`9rMlp^&GK z+I!2Ecb#mnD-FLz)w(PLuCDO*$8LA{k*l~2sHhaC|0DR#OSSy2a1VW%)xR6&%eb{l zb&RqfE^!)0`1Q$*ckmCYXQEw&dknUARLlfwC)Dtn=kM<;^=|#ul3hr28}RXC;dQ$! z;Pt1%>u&w%?ASkQH4Y##CzO~hm3F${IA}WWoX=0c%H|$kzkOTg8xRz6pd1WOzcNBr zk-DB$Q!{@ifo_6o1XjZ>+-Z`^${3E>?qk4Gyb(W3` z9{|S>G&;ESCK&f;W4Nsb^dA=Yk_+c1Ne3BwkCPbu!4)Thhz4{gtgT7KDh-Ud1}7MR znst7M1m%Qy8yHyy)Buxou#dgiIVA1tLY$?Qc>&UNvKpED{iK5R>4jxU~8LA zAP=>jsMJ6T3CB?SlMw1Wn5cXbd|$CD+dc^#=49_0{d*P`fu+v4s}lA# zS8bt3;5|hP$KrKREV5uNXsISIT!2vmh|PIz&>x57!J6mNU@S%C?}}7jx)$&{1|ogD zn}hFDF{nfn|4JE&o0L#a+Y&a2N6VKoNZCxq@==fz%MU;iNN(V^u6{DTbHJhNL>Zd2 zxT?j?6?7G66vTruhjE32VfefskO+(x3klILzc>afl4JVaSyx}wD?Q8-2C#_?fJUE8 zb%yx|xdR-h(Ilfw{aB6(j5SXuaG7RG(OHBr&`^cmXfVoOIH0#b<2)Z1BR z+-jn>FU6%1zwfA^3}&P`xfw;{&{@U;zZ(jP4#Omlid8>iG2ntLR^h*LyvndhiBS6a z^I{Hug5{kJO)1`E^NO?||3Gg}9lb4C+uYjMEQd zxK|;Huam2A05O4Kl#jyHSsDfDV97~RXDLe{3J9t~t#B1u!xp*B4O}%Bhd{moI2-ls z=ZTXCSD`b5nkf>0tX7_}+;of77dDe=ks^bZ!rLj>fv12=SU}VcOAD(i68JXko7X{c zZ^cVr&1helu^sMD!1y}kKd?yTr2u%b0!95TJ$`$Fj=Ou$nlgWf523oHweYH!j;*T> z#!65##5U{pR_q6G^v?OXwDf7Ql!4;U{Jn4>=*`O+i?Q)d5#gQ1YoKyB57K;j&YQ-N zm&!1v?SP1B%!YDI22Hffw8XeZ?@0-_eQ_uGOI&C$a=0UCrR)v;1t?3IseJFq=Ei1Wrwn~RHTcCtF>gKnTXV5+=|ek33FaHS z0&hjw8rTo;hV$PamF%F*O36Jn(==4hEo_fu8NA5!tyPQ_d{yC-cC4Skxd!4Ycn5Ca zWZ^VOK^dd1B*>i4RO{a)H?4ezabJP>?eyXZO-=Y`7DqWC7lp>p(=_}H%qxhU0OGt+ zbx#H%9!MgWGi-1Qrs92L-?Rfv)39V?Hbsh}GXDK)G+(QZVJX>zeFNubzBR=#oh|?I z8w~Atx|?%l@*m^7Y3y45=chV1F!}h4Q09--qHw3|EAUx~ z={_8BtLWb-o2nNysIqrfy|MWtwMys7v`~|Nnl34A3DXj+NJEfT!^t$i;}MZxThd$^ zb`f0K-2kG5 z&0DM9zum`KhwmX_>WbHm&Gq~x?T9;B5K{5KI? zJiTnREEg_F62#t&kRI6;9^rmw0LQAG>Qm#X)LBBU6Td8J{*iW_XW04U&9j(lv~1G* zx4c(FOeJhYqAw#1BxlwRzhUpU=dxL?dy2n8=EPwNz!>M9ZfnA8N z4T&dflHNLGAW6f)tS@1_fMf(|4r?xn4QC@*P=f0uqN}*i1AH-rySVR?c;G~N=8U6B zlowRuuirb+^3gpyxY99|s9{B#C@ep0xMbytB+kP)Kc@5q@=*CS7z|Le;XDHH+Lg5P`TGDbnw^RhJdpri( zjPy@je})*XTmKyzCY0a7+T$rAtOd!>+Eb&b5mwX;uuR z%2uq9QUirX1L!a*wr6c#Xl%sjFDPKF8_ClxBot2)Aphko3~!2ORCKe>J5cFB9}j~Z zQynsq#o|1JB;{G=N@Fi-ecL2OvxN&w+x9Df&%IWQ~; zEI$IVw|$bljV4SsXn7Rqy$m}ksexlq>9iJtTgETJU||46P&?18P8B=Q$z=AalmUxm z<|Z%Ug3_B}rWKQ*gY0fP%p~;SKp`##cAn+0v&l~06~o`hGVXG+K$m@h_j>Ooan;>l2Z{jT&hUb3tIhcQLEn`Ah-D3 zYVbS9$wWdm(TZtE3Z_tVp4_rbLym8JtT_B26B9{0Z6TT#4tYiQAsJYdN>fJVs)%$I zQc*k~>-+&$8hos=&3L(_*b3`*kkN>q-dYPnRvAPS?(GjUtHPUQ1p`!9KL}-(R3rzb zvC@}Mzia621Nt-qufAXmcHtF?w49i#fG0hvK$e1u8q^X4!aoIIHt_GWqLi21;RsfRj?y!)mh z?_bj5Y6cR4&Q#K)%_f$O@lx1%w#t@PIE`gB=KP_}9rl-st|>=i&do~2hRTp}-+ZIy ziV4*bvF>LQYx9DHWar#QiCPw$xR{p*Y;@SDA~m@GROPBXHpka z&3tbqv#Cwsg;%BcE|fVkHrIueO+|m0xVc)X2b2%mnOkEP#8DpIhiw%bs-i@BgQFNg z$k~?l@sK4%T;rMH0V=G|lUeS};%plBAt}v(lHvqIAgFra^Y3miB)k5?;&8uwxzQ@v;+iXlG251nna78&({S#*D5s^>!jkBkdOZ7 zKkw`zeO%X2s<=K9hUUv|SaJ_XWn#Ng1_-#01~eO2p@Vkt2qNy`T+w+5;m8|M%?9X~ zUkv8Ip;^hz5A0fRO?Vjip8!ZnmE{mA5%C8=vc;tW&0m0@J=gYS;Vo=!~wmh^Zs83+qr0&J=!dX4=gi$nJ38^9Ls?5 z#lXyi^D|@CG4Npfmw-6qAceFVe3pZ?$@ApaoO>#)=DzH7O#$-Xnao%0bYbSK+72wc zewoe8-Z2bvwAnOdD}uwesZs-(yfY^aFTxbgD$Va8uuT!fhRF4=a(aeOWg3_n=xZ{C z6)OT*o8onjST#BOA#5!{mdz$1990+v*C7j>*&B!5&RZ2nI+V97nD;v&cg$umE8|p1-@}1Hutn4T^oQIi(nTR*o}ye{aK7dO^#GTZpOIa(;!8z&V7~ZRh## zBuz-hK@mAGRhg~%V1XkzE;wZ(hna{5A)VG5DbjI*3vm8rqcn=IR3h8ra-?BJ+780b zvC?hnhqlF)g2Z>2hS#t%d2_UbVdT|NI;7 zZdreR0m-yhzHU@DAD*s7=A9mB3VV-H6hhuLJoxcALQ&xgAu&C2-8<&R6}!=(zf@rg{g3*%=YiZd>X z$psmir=2HM#@1N@H*cJ!EQ*KYa7kyGCQ;VTnqs+UWSV#Wh6c34JKMlg__(^d%0O03 zQ>zS$pl`6_4#H^~_Q6kETp{R9o0p_)Cz4~8e%yjZCfi?rasFkJVX4Vkb*saGI0WeF z*OKxN80C@VPT-gULip|TV!K+wn7kOWf+6|4ptI}DLuh}up)BwTQhzAew8)&Op3SXG z%hM+*&}s@U(GCkV&s8{hq7aQyUY1#yc5>Loxc?uOGR`jrKuFNi%D47+fSaFtq2`1CG6s4~}{q=;teVHZs+{Y#Q z_V2Boxlg~*r}2EH-|5Q`z8G_X@b=;}5VFTc%w`Syx>UfFl~fk~I=VFlNyRy@42nwELBcMtSv#Hkj;h6;k9}dCVXs?ic>LW^JA`CWFSlt%d#xuAGL1ZT6667al;BSD-5|x#7u5lnk`#VpaD)M3 z7WN^$bTN$3{XBf~yg!lxVA-GvA_yaL0aJN#k`8EYKA3UJ>DOUN;+9DffvZdAp<3Al z{r`jhf0R`}Id2Mv>A9nuiY&r`%o(CyF_|FjDuNMbVXo4GQ>U0c!=%TO1BvF+DT}1l zGdj0+mW@^RP>5fW*Mt>7T`3L8m`sx_+%=^No<>x_Ft9QmlJmgWEMyt=eZ^EiAjTQ4 zghVb1W=YgtWrmx;q2p3cgeDN@^VhG=!vj*J6rK0FPBaMP9PgWe55OI!0j8UgpbwJS z`8f2_pdZQ$DA&GzU4|pmkZ=0_>Di}`fBkjy*I&<{e){zfJY~IVyjc15kClgqwP9qK z5sOW(=3$mAHe)CSk~O?jYgP#p#WpJQIF{HeJB5F4kLSmRqer7I$16a0Zonm>_^IQU zU$bd&6I-Hqe-w=eXC*~1qH)+e+CNSXgM4IFnWbZ+AWX2;YhWGZ{7SZTyMa71TM$Wn z5e>UJ@9A0ru0-#i^IZcblA`QjI%%h;L8@ja z%AUv5iBSj>zvaPr91iN^R@mG5D?FO2-Pze7N?D#jcECTEEfQO%hE^wG9<0vN@rtRDv=98V zs(Xr;wXLr^zdA3~pUoF#N*Kvly(wfAJV=-&$ry#h+4(r?^YXojD2vz(%W8($4JXm_ zX&PMv%UGUeOiwU_8EPVD)1ZG94Dq%UJS9>{yo>=Y7~k^zJj`#xFn*3uJ)eZYNb#PD zvuu>i#sh@#t`Q$hC*6J;O{JIQ-_q9jlgC;XK_SKL9|D6=$L5fz@tD*D9AI8B-9hsQr#{qrh#j#{N_VCON)CVsaq;kzN z*kFP&>@C?UWtqAN#$zzsKp|~5lfbCf=uX!oy3=*OoD<{@X#EZ*Cvh$U*y_03i&;KP z!}(DexAg!)zj2I@Btif2hhd*q2_pb_Lw z0Vc``a*WM<`EvpM=TE=RQ48pv*4dF{nzv`UZGzX{^*GA)JvcI#TpmqACrb=R-0dT`GcY;0&ol6x4 z0B%WKUdm>JWU1I9HpTpOoWMzN2^x_PN_)AFLy%503_1;M6Qz;SaL(zl`-|tbF4wrYu^bHDhsy;u@w;W@1WIHcGiUPt3dd zj_Avhoe{~XV~1Px_)u>e24fb8<*n(UM&@BKP^lh+{s{KsIMjQSYIRjEbcU!ztkIo{ zaTuhsy(lJn!F$^0Sk~$w9EW*m53At+N9BT7Pm(gtV&1dB;vX6vniIg;t0D#qjALoV z`OR6l&3$vaKu!gf&IvI82#%S_x&o;oGa0F%gd9x97RJ|6nvknd+FsbO2(2xv&FePo zgKS=LKBC}`!P82dhYR)qT2OpeD$ZWFeXvUAv*_Y(*^&)cJ{eqILdr3B`ZB~pl)Q14 z$o{gV?)zJv#c6o4Y^mKrb{F@Zi!kqx8u3N4TsXJzl_kpuMKQKy%Ax8+k?(-HM+J>- zd2XYsIA4{tCYxU=9zs)Nq{h_Pn1J7u(yuB7BF!5^J6$d<&48|ee8_-QY$`Ygpd?RS3C`vg6}ZkW33bfUIir z9{4R)Zj-^RGGd()_OLRyT(H!FU~5x&k22Dz-;^oY3b_T}y(xgp>%Xw7NG21IpS9E_ z+Xu6JJe@d^^L*%(3PTVrOeIP`7dm8Z_gGuDmWa1F!F3Rg@v<(pl|D00e=U7woH0>7 z=)FT0!;8I_mz@9ezy7x~{}pe%Szh{TEgGwpCD_N0W^gHowSg~vWkyF>dcd6AOCT9A z7cPv^Fxx4YIc>i{Bn1r2g~{W7Ee|Z95-K57p&=V;g2@$czFDxnSM2;Pe7*A$iC@L9 zGS~!z3YHd-jvUfEj&4y<+Ab4AGBN04@rpNi&wI(dN>+|h+L}zx=eoe$<7hy%LS6uvwx6X`b=p`5mxCRItfNy7Kx+5N7n5Oi1 z6F?rN;SE9nJq7S*lH+IidKSPRK*3p`=Md^Z?0PN{?5Az$nF)yp3IF3HPLl-6b@Ma~ zCODE|(7&Ufnfm>t^5h7>lci45C=b=IEF1$8!LSF52wd>=695<|ad@^NpJ0;0{4h=O z1Z1W*)Jx7UG2mu;XHw*b`D4@ku?6#;M`QEd3uqXeEf=$KXBN(&qiGsmN69Sf-c8Pv zF%CDG!h0|xXCqk*qv3A>319flAUvM|7GZ2;l&2ZO+o5SB84*_&=CT?2U6Qi#tf1UB zpseAlz=SRqYU!1YV5W{*G!B^*`Ei(-ACRt(Bc%5*{-Oc9f!4T?`3&x0YQ=nekv$Ej z(=e9JT0e$~{Sk(pOz-%Y@tCE3L?x}GaWKrNwo!zKMXW_X#mNyp(>}vHTBe6f#dK|< zR~I-Ym~1r-Ut~`$6zd;P;i7gbVPo9*CCgkR835>3WAMVR3s>LZa+6K-(=d@w;W(Vo zicat3f0#EKJuLPJYC=))_QH6AOwMc;#r@Dlr)VyJcA29M!VGM^)o>g@!=q#pR--fo zKLGqrGNg>_CzU6+gJG3sUm02STUjSUT&e>0>wrLrF7Din=sbzh7;Syi91TA-x@TbE zIXh~%k8z3O_Wq>uWWUjB9G}%1`+oPV>UYIa3USyO>>hGOPp;Iyl9_X>UkM$-fWV?qpQ+|SumNs# ze0(U|Ov7xN#4HhfnbD4iX9-x;nvtj-WVmLIiGE~ljKB%<(2WPJkjOMkW@#UJEIlC{ z;Z%N}!2jJa7!Wt4G8^h?6Q_{BqfI346KpCsIv`!wpG`r3$&Ltiy=@L=({Xs~qN4y8 z^C-w%x^?ZqlR`;plbinUX054pP8f1ciT zagrfXzIx??ugZSUw1gXxrZ?VKP$#haw~9qE^1fgWeW~1bm@hQ|SVSL|t<)g7tK3F7L;c__6!AyHnsDSi@7LZ*g(8V<evlb|^qqs@qrg2y-YPrMfvj#(tL{A3j6 zA)a(KKUinIWq^7=y!J7ooJpr{Z?O7Nmu%rRhs2|s2vmZwP+ER`6gnoTouUSg%QucD5iX!$ z90eIk_VComyd(iZ`bp&p!8W|6e^n*jWnoU8fqFtuS(v+s&N#_yto6mDUXQ~(r!D6^ zO|FpQQSk@j0{;|DS`I&M@EMdBKrXytNsXfm)l-eNyIKiM(rHp=?mc8USwBH$ zb#_L^K3=`3wnZ87I5gNueV5hsvy1F(gPDYI4RMgEi5UDiLKPluGH1j!yeJ+JrCx24 zhStZgWHkiE4aSW>GMe2y*{2yfG@diIn#dvm3X%t^ApkoNy$`CvD9@*+)#0VWmly?6 ztVjjkDS-z+0V-iKNKnDsw=fSB58j{o9}bVKFNB(025TcA_`#2_Tg>l>6;L%< zY8d9e{sm3HclUd~61%svEWxPt*~d?Y%e502-T6&_?p zutg0?9N|wnDO9s)&`u8{mh|{?Fof|WiU-LJGUtrU2Q%&&z4bm2iu`dzQa(N_p$#f#c|1<&Nhlc@CKm3SSoWV}R zzvJmdjuki$Gc7c29_ts-06l>N9@}oyc0{2DK-wK6J%DyFh4SC zfSa4=2sdIQRB&E-46)`Si?p>3=3>0|JWDG+ULlQ{P75`E`ypj+2AN=$31$pafp|)>gOZ^@kCzxgvW`ksk;I1oe zB6zf?OX8!nD&-ex22Aq0B5^xgar#@Ff@8dg7I z8w5Zs^E=a&Fpz!1cg?7&V8H~To5SIl&D@!_X&0bN;iW7uEn49?U=d$M?XX~@;_i{1 zCVf0PCfL@4K^JVJ?qgNP`3$S`Q(p8vRyT?q*RC z%L;*P%9S<4NpczCX%}?ZWMp_Em5OExEl$9TglzeUH#H;Wk@{tJ(#Q^iG)3EZA5>+? z4(6--=`tz!!)u%uYR3jztBx8{D$IGuSXGix$Qyi&M{o~9%sGeE14|*-nFZ%!iIbnJo3YnGz zdFXy}6Q=4{Z#q@KRC&H5ET{K;tUIeJ`Dm=lca7=Kq2RrwH*AJu_`@9w=T8@ zfm=0Vs^bgz!MhVblKo8Soib0A*$w$QXQ}*vw}g7GXx5L~y@TpmyH@M^$7pw?{B|2J zjUSuaFRf4HB0|e2#Owe+CutRL=|O2JNkb#$#X&&6_Ch8M`5Mf(6SUHC^**m0ynU1R zQGAwt@H>1)o8hgJk24mCQ$rEY!y)ShV45LYioU56#B92`6$Ng(c2pwCxJp&N65WP; zY3S9%PON?oC;!VfY6U-ePEo*NbK zvYWA~9Aol~ju6^#9OQ>%ehU`v#%7DP3-iXJ=sQAkCJqaH}3?0{k%R8|$-BjEBp z7EEC?N#AM1wB7$P_9Lb+$zCkq}*#~Xl(jjKD8>)YE+IwQjBK^!512bDj{e4Jzo2o#Onxd6JDh*KN3!y6c{bO5OGUguiaD(sA8RrQwRPhc8-{rt2TzD|J_-o~Zb)IEFu1 zssWX2s=+4wyr{HXH>e2L^((@yUr;%00?V}l^b^-T#f}96=~HL;z2%CjCm#`Jw+G$2 zb*QlA?aHx=17AM6O{mZn&@22Axd$-TsoSCFxxY%rj zNcAs00HBMbZ6g>k=H}p-rU08e0W8*CF%{IZY`#^wA>7wpF{<{U@@bV27dairg#DVV1k-J@J<5qBq6W0x_5nDpA@?Sqa@s z({O#!6H;K+5jn2~{mu{OQtW*Kox-{08PK>PL*1vKG74qJXk(wJ#Mn2%NJ{l`6oJ zt>UI~j$^to*jwFg3=EE75={&08bs3s{(>mGLG*PAubOHYD+UFbe`yQE$=InP9pP5I zhhs&Q2i$wzb^B_69aVXM1!e{nF1;!>1d!mWXarEDuBULv!$t?VxfTiQlv=90;+256 zF4AB7SQGUvQOCOX=x|_8keB(lepOB=?d2_EQOI8G>1rSTWH)kyuRk{H*m$d|2<@6? z9g)<$_bfi|zc*O4Iqf~bjxp`P%&Lg&L=ftbAhA<;`~FezK_Rm^j8#)I-Bf5x;B>o{4llMU&f1^wcnHA4A7Ux>)U)<1 z|3Z^`P*vUDKDyInoO9!azma{1xo z3C)RQS;s_`%nto(E{qMWh&9?1kyM8S*@mb0ekxgtI`?Ga5gfkTNd1={Ew{QWjtp*t zP$2BBTMfpE#tXL~wmsQ`?}`!1^h5Y6G=~;7-Q=~Pfa<(BF0nKJuM(bqHxXI zRRlRkg1q{1f_#MpdG}KUS$F-;t!fqo7@NFan24gkvBDbc#tYeUsoz9K4*J{F!pdk6jU*mxvg9^=?MCxsmoHJ8Hh)G%Cz z$OODjfRjMY6aMHd(5618^`zgL3#%Ts*HM+%{(Ccm!gGK9+cRRrN7QA{%hk8XCb?5i zv(x#zv%`ZJ;MRO2j6GWoqHYcXo9kYiDlvjS!?B!J0@!8fb9089=)Tfl{69@fAPI$b zhqe@r8m{nZt0jY-nx+;h9H+`gv!Fl#2AEs%_-tMZ&8TK1dG0R4JPjCG8}ZR;HC$A7 zobG2^zOyA3vb)ZKd37K6nA?US%y9OIauDM{GXR>q#PsJ2LT_g#^rNZx=6C*90n z^By%0G`DbSb}K@RPh653kzTs5P%yay{P=6$>*@ltXy;ms^RY*83s>x;5_*H%_MfmL z1=!C36Jb-|3tvPI?QA7EKDZ28{%*pZIht6-}kpy%Oqo51=|>qZ^Wn9u+*@1I>sU@gHoH z&EsfTr772VZG$I4&SDD|--*#&Q#N;OGzXpz)EMixbIox}F#Z-Vmj*pqwRDHvjkxrP zXX*Bu3`L7AI7%8*=CTcMS8k=Wvk|+*S*=Pb-mh*{4ZE-W(^5dUjd#EeSxV8G>{hj) z$sT_3G^az4Na`u!F!$tFgRB)Sy!QjWqMj|@4~@+i>20Lt=&2{a$`KN)Zx)z54lo#1 ziz_^yU*T;sT-hu9R9BTN{C3d_S97y1zPX}R`N9(Jl9DFO=8PpBfSTyL{`CK6tJxyo ze|)9-?DI1h)yzYc-FNHvk1Z;VWk2Hh~{a$Agd$uDT_fak)*9MJHUr-ha#uTNze1a%t?$iB-G0T8jT%Eq3u=1a$? zGUoz!k*XIo<{xueq{lX*Q_)D97AdeI>?2e%GKzl8uw~h{`Xg7;npf$=@5FQ6#H%XG z@)e)!?J20!sy3hE?%LW{6y2`ed7viaDsS#7C{PO6QA(@dYO;Y#>ml`o~<9^T)Ob4?kczQ38}#?-#H%I^`i-3AtM{&rP2GKT~>=ZJq+LMY- zkZnP}BDup1uxL}sn)_MKx8;%gjJt2mC9G+4Bh8RuSfmFB7G>8qJH)ny_Ncpxf<~}l z>bqLYTO-Zx#wRls2MqYRl>O?`mF~KL;`R}ht25K^$!m(6OR$A)HD2=i^xanOz48sm z4%*IY$~e7a_;K2|Bo1GweVTN~cE*YfjPSB%8tS#V1VHgqR0+iHYt|usxBebmxb@WG_n=gFJq5PS*LNaNoiW0644Vo2;#DyuWHJBJEkoY z6@=4Et1zynb1gmyk_K3Qu+?|5CI}!* zCLW+a0DN5g4ju$JDYFm4R1&)g*J{cNo|}|4tdl^g=JMp4#&JXc*5;;k>&K^*Y(&BR zf|ljXZqdxnh{4@I0*5id_cX!ea?i`^6y|wc{fT*QNS^D8Z;WE$bT{>eOS5nC3jg{a znr;GX=*4yEDipCdL2Fx0zjK2G7#=9fYT{3~zA^FJKR)pjocR9sHzt0YCVrhrb^H4! zeuE~yWw5HpCqDj}iEm4p&=uSNm5IOohbDfLR!v@4Jp0niXx{ZZ_heRQQ-o&ThF^eu zPwlmu={Z!B{)~1SnDp4AGR@Moxm~7U3P@FyW z=PHl~R;zbAKf}ud&C4Hy{wL=-{)gr{BBX8Cr7KfRJ;SZ}vQEBhwTrKVk|8B#(sQQu z1-tc{_x+1|gCvEQRUKh+;~7FX>F2of{{_sai9(q+KtlOU^~p zB`yT@Hm&`5Z(R6wm0Z`~->JV#?lUBdlf1q_aEXcPzu@;|Vf%%R4N04HoaPH(X|LDb zw*R9fE)F7&)B&Pg1g98#>r||az(GPZB^J=O1Y7y)30hUU?4)S{3(^i7j7}!SDzDEk z0%axQ)%C)c%7*`H&S$9I@+PfGg9qBaSPcMiMXiN^Ot|f96&5Zwyc?q6bq>@!0VCc$ z?OS*H-G--^px`Zb*W6-vk=1T-4HVjy`D2rsQySQI)hLIy{`L!itiEH2-;tN@Dn()H zeW4Dv$%|9y;6;_TDcQkJ)hI_Dyu=RHi~ziRmq;bh+N3mkoYKhxD0)*Rs|VWB8`8D? zOo#H1y*0w%v#NABi7G`zqLncq#gC2hb^5G;xMm>wY&w0h}R|%JA~ucRjTz( zAnH{U)gzw`G72y@E1=FqQ7aqe_}MK3&4i4*sIq6`d(fkTNUs>O+<@$!A-f{GnWFJI zq?JNeGa%zGYHShxCS>epSbM~ih{A$)B8m@^_6wUFZ+w0(uk7>2WFT1B6Y|Ap~&;)+AA)L}aZvo6#9 zQzJ|@zyu>}qK~IeKAw8f$5S_bJaq#oAFY=qKAuZ|v6II@KAQMHNWQQD`PV|Si4x?W zmLPx2Kt3`QH}N>C1CZbNXOUl%C}fO_!9R#_f4daDuh|Jt=1mj7w?bQ`$5kDO*|l6| z#KKf_BsNXFQLWhAeMxg*H=AqjR_L8)-KWqRbvj908vAE^a~DUgW&73`OSVX8Y>(=N z05j7(g9Gn^(8nx`X0OFZ3tFy!KA~{FX?dds1I^Vg37d-{m^af<*hMEUt7C^3*HvWI z$&X9=&(x6sS3EwLpA`203F8ek@IeM6vm5I*HrO4Sfl{L?8U4Y6I#l}(!a)GarN=f= zvQ6e}#PUJ}oqUV3PA?2v1|& zSYWw@CzQqN8=|Dpdes;l&Ta!N+TSWEpBhyX`Yyk}eBEvAcr^qMglQ6^CYnM$-i?ykdp#8MDZ%wrLK>OZ-_0~UUTh(37 zF8${vDd~~0-;X^MqfZX4*Whf2<#x$)-3DsDAff{%{6)uAw1g3jUM&zjf9t8}0C2lr zlXFfUh4MGVg(m0nmRU%?Cnf!kV?QLRk?eE7`?!W7-FKwTbjd%U)$6cuUJL1Q+v9UR zDinhF*R47$L@t6?f?|DjBaNy&O+wpKokDr4661P$P8I)@GFLX~@T-R9Yb+>UX zUez97>H?w`VSU%}eMr_LCSKU%s*?P%Mc`OBLTsP6dNcw-gX*CaDOE6+oeniL!y1#BtQsi zQN+of~;xxX>M3mUSTaboa5YBrKv8Dq{#)6>2&VwW*FE!s&VOCxH=C z&`;q6Y)9=oXd0aoovs6u5gQ)c7lEEDbx}K1Yu!KRC=@!*#KAwxJ>Dc#!@TS(uj!U2 z!%W2o8PY~eksgtW*AH+@0EMsCXweqagCG=W7EjMcUQ@mXK?ff@ZXM%7MHT&i2Pi+| zh7@@ihvG4*xC-3+e-2!6Nm0G6Ik?InDITGr&ul(YpzYSjO&VDr7TmFLK>0_! zS7lu;ONx>z4QDn~nEEkAdH8tX9^SU4aadePgNeT&Z1se;d{{(ko5QG(a~0LuC!cUb zo6|71h+q1*c03#{koU5ne{A%lUF}UXHv=8HLB+CTh29n0dJjnL8-b@jnm2WT7uv%B zJ^BoFo1&-MgbfLPz;T3Hp|yipJ9Z3PE)>|nKkCQEPvQD_095FN7!>>0W*ds`lhjq& z=a$*0@rkTky1_0VW2QYH5r%mqWIQQOISX<+lCCWe4pJb#U>ik4MhbRR*rXa=L!O7~ zsK9^Rfc^cF86K$I9Zkj16$XGj8XTqri+{Q~}yyT#oc={MN z2jp?UOVf2vc0BWl5r+JDT4X^ueKn^Pc*DyWciD?0JW7pDt9_D(4PN#nXiOfyQtmL%6yp za))D~T_+c4?NKjk&)o6krpZxUzCJ}9GO7En;BdT=_sH%JeURRKqEC6>`_>^vToHcD zCy5BPYhg_4#gESE-w+7uW@rTo@qKx!^U-OOrq*x)DlxT*M&PkIb}<&MFZzh*AsMbv zw}6e5wtxGx&S5`|==6tPtvS5|fQZzPSEB#pr ze-0Z!24%IBt$(hTzeTk$){`8xslfnk9w(=G~c3PlATfRIXtXkB@%^S42s6YN^S6IA$vLf~`yapO^}ARea_ zRB_5im@WzNXoC@#;tPLHOFsLTBE#1+k5myM#U-{LZF^Ed<}^Tb4ANGc#Wl$jFFgjW zAcBuJ*jhifJ_t7!iI75_OMFr1hERXHG*_U3*5Vu0 zJL;GkmOoX(sW0}feXV7H*VZ2t70aF!vZ39y{7_^Q)sDJK97Tdpi*<%$`Gj@E0Able z@%~iy!3UpxcXJPgU5GPqL*zauS|vZxiaNX%_kJ$4Nb9P6R?T9Oa|~ z_^hsITzd^E^wMOvl_qhF)6V8~QkxaM1vE=q8_{UCb~#_|3%)e|8oL>EQycG7?5jEZv#M*b8G+10ZJkZi_=c{nwS8j_(W$zxzRF%` zS<7BV-rwy8c$(48CC^sCmaZ0`AnKtG+eD@>F?}neD0&!*%2@Gt7*drmDPaCa$iwsf z`+9CO-8p%bC=jHJ`xTn2q?H7v@ekSif7o2hc&QeZF!Bwkm#*^0jlVDew@!uvavP`2oBF1h5vy(TUW$d~{jCmT)al@Z5==>U3& zkW|90mO-O0?%gh_Wn159TpbTL zyrLE=fqv%ca9>Fk7*Hiz+v>b?{XL}^fytwUGp8dZ&G=&(sEw*ZC{qlO=Pcg)X2*t@ zB@6+J5-Px2LU)UMAU!5x09qT`YTXT#r(A3P&D3t_TUe(;r4kgzW`p1?E?dO!k>F1# z+d|hc!@ur$ z4|HNDkC<{(xdZE{VqkCsG#JmNZGq#fX#THLycwlV7)F=h8rupC*HyVAI}N4{)|SC?6@ zEjZv6wT#rZh~p)01)5SVb8LJ2up8)8}aaN((C4COy)Ki-)6 ziAsb0H;4f||AqPP0LB)kk&-7yB+k!`R;87~KR4P`(X}df9LIB_tlcM(W=CgTk=c`s z1Tj4oZUwv5>pdL}!-o~&+uEMm_YD$MFv*OP^rwfRaYDwgKii{IhkNu2bZCCHqf)zo z`h;VV!J)=bp6yZCSG718&L{M8&mOBhda^x7R+Lo+TE@h6J`H8qz2+}GCrWKv8y8MH=Ak`KAjn-;_4i$#)$#mt1VM`25C%R4oDW~s9Mf6 z*xtZ4j*vcXcXd)IlFF_~iNhUo+*E0xD6JnSc#f#dxG8(El=h|r6Tg% zT8`w46nNtJ$iAAfS?fDyOtEG}Dy^vh`Xn`QIn~^sm?=zLQ=Bf8XPZaZ=Ig!E_2pk6 zP9}RMPJEqE(|3KH&YVz;7QNHMB8u<-J1BmHsp$ql(!V6n2_e-;GDi>%<^Y1-X9qn% z?bpalD7br`iKV{o>Gd~g(%6B-=!mwUtVy0nBe^!6qr5bT0S}Igk+*%IBdRwK)Vb7v z>@r)%S2`&QdiLglak&G=Z`P@k4V06DR}E6fPo=RNoyNg>!$>>C>XqBLY^cLyNFQ4@ zeG-m3etn?NaZ>#0E1`Tf6!UcDRWhM22n$uHUW?L_v7w3P_mvRp@S-eLXK%-~XS)W0 z&`%}tHE_N4HujZ4&NZ_&s31$j6cg>6Q!(DBFWSSuolHPD4czHfa$ zQP&x@$ShUYX@dbGN_GabO6LVbdQo>9m({dpG}OnA;LepVv_cH10jMjjQIOApSM)U= z;yN(4U#0y=I{Vx}BFf*L?#ts7oWGwVcy*pq;IBjWR)FoGdMSz!DM#Z}n>bEX*3WuY z)dtitl6L31W?;Eh!17OHvA!nKas;%jV0}BeEPH=t0wiC0J1CDew~*_j%STw9g;4Eu z95oeZ8W|M{(Alm+J{h;@bbnV?_oef^SKznGo?_&^yxdoOa>u(OIQshLm-;1LFA?n< z&X_h>IWLT&qkRb&Z-j6>U#&no^Zr2(W3*ow|Ci$U)A{imOiW16)o|Y$xR`qAkPS~I zRK}ew3Y_7-0gg28}D=Ls@S$w4lO)fu-ib=UUw4NjyA zU}6xrGplJQpQ}>-P-Z_@`{mFQ?ITgiBQVlHz2=c$7wLP04dej-T}>%tcmo+9{^ATO zcn;q+cGZc8CRZaFD@Qpr^=)5Du~Nx$WU5cROTxG?vB`$kQyy~ROn#k{ufeJm?DBG`>9Go+eIv_3*!w97ay_<9+evDBm9B8_t5@=<7+HrK zOf%a;b1lq8!D&OA@|0kmu3OLqtc)2<)eW@%v&IPM&}ISTkL$v9Q6aDAJ|B#z+u{h| zv!;%NVO*97>RK>jkGHZva$R{R-Ys=`%L^8JK9TWOGkrhZweTsQ4u%^{JXuJLt9xZt zwafaI&=$Ehn-v495>B?$QAclCJ-PR3LIT)OmE%BcR7Zw);kvF=`Ad)36&d^}?T^Xy zU#aMOPO0e!UpPT$LmK@~`3e$sqhVir281ODa*)@dHT896&gsZwDlH?CbO$s03UH~{mE)nT5}w6iegDQx-;9xxZFaY*q@mqI zqX=4-+21TV8D%l@_c^A9rdo`u0aDYt4jQ``3tT<)BQ#7!quL2}!vN^MJj zg~&DdmRI!^hU;{{@P-jCSL2TCHG}!c(Fh2kuua7Yus|sD<^Xr{kJP~xzDNxO=&A<) zJw{haAG_-sxvm?W2dJ;^brG$dx)M^~>nz+9ODgkBp)vM_hg?tI;_<;g%ExGbZ60?O z>}_jGwzO{IE5f9xfU%J;=DuoNuT_N#+?8MXQbIAVnx|h0wzj+rnNZYLIjn$D_(JF1 zz32T5B#Q%?FhU&AMw5Af#8b-fORcJ*j)jPzXHk z$y&BN?WlrB>8m^z$|qdvd@%&S1MEo3#q8dg7mS0q+9W8#W`IBtS@CU8m^<5OQ$wbo zPNna{=uz*!`YA+A)>YscL9U;4fBH%9?D}0-UKCsL#VsRuoefD!9q)ugC zY-G#hx@i=Ux-S!ijwY7;W9(bz0qyrH`%{-Do2n5WE=mgILI#ryZA$XxJnjFyZB zFeSedoGP?W`S0B}p1sdKA`SI|I8)mIRY0o0XBw6+E=oTVl5wMs97Ih%Lz){=Kx`qh zJuW@UNT8GoGDjqPbl?!)PWMz2E5BhH4b&EIia1J-WjUbW^B6*09Ww1{)od#;=g(^E zgw@4#&WV=@*G(wXXLSMm@I2ikGYerHEg&4%;NmIdkWzn9a5?Qq-7iLh%E(LGO5WY_ zjRg7~X>z_JRp;d{iFI0=Vms4`Jj_ZNoiLP|81&Fnw=~=vC*m9A84LDQRG(ns6K@OJ zH{4$k&*W0>LFn<>z8ruwcg7_6Z|y4a>`#i=*i|CIpSE@CPtLX?tUT=c`p%{b3Ss2M zbd`Owt1kFMG`VXvb)tM!EkhjLglZyg1SvHd5-x`j)miCt3x5}FZQ=Yv3wBE>=2AAD5*(Xt9YpDJ@Cop>5n2G+AILfn-JxfzJw(n< zS)Ke5{%AjIQIZ1+?V`)R5;!j{u6??{FC4WOT)|Su8&J?V)Rr<C?~Rjx+*E@bHjVxR(aA+jjL|W!>V1jNt~KDfpw+LBBf2zyp(~2kE-iN zRTjEsp#4Toa~*K(Q$!F&O;Pr|XF}!vWwR9$T*u7Mk4v*pY> zZ5I^k%Wbg$WSqS>?ytrY3Ekdvg5LRpo}E-(H$kLr``WF8sXN5nUh~p-UA#oYzog5P z?~Ir_W5OtM&%)=GN^_a|`gTH`58hS#+t6|~@iuphm@+O%wT~W<45ZGg8Mp4Wh2(F% zyCSQb`i4qQ(WjVkSDr0Wnj(>XK*!H0wQ&2TKCa%7Ytp}l`y@0_TG22Fy6{EbOwnwp z@Z49lMDgn2D(!|XoDYE+m^t|ArH~m*aN}s9;=SLH+2*>mPV0Lrw9=RjG+CXnf)|j7 zMM*rU&_EA6`!d9rO~9@S`K1fpUu)BDOPbUDw5n&6x?S^BC@>z7@@cxzp@rI+k7;C1 zH|qv}>?t+zmG@t@FItIB|9*2uYT55-Og!FLmnDVqKLOd_Gx4h9fG-bpLJCShz@DKi zbxqcZWSDaIxc3c@#wqQI6U?mx)*hWCMaY|s~3v_m$9_Peo)Ag3(c*Nwu>lA>c~l3 zt@UkAwls&EQ?=;2Bqr2vt7gX2f*1j!-4_ZOImL@GftvB$$@~Pc?a&?|e`98%S9@1U z6a`fG>C7eMwbcM=fvis|MSVvsM!fxVsFQ^HMifZfILPPLjlRILR5xh)3!-4EV>)il zHQ85WAE=C(TCkJ>lRle$ukctp?&dKa&>Yw43yJ)5@lVADPi0l3j(L_-Owr5J$c&I-jx+N4{J)gB)H&QHC2DjF ziKWbHGIbcM6}~~I8ibI7n$R9#?0rPkRh8FFn1}MN&4F~4-$=#I4YXx~@?HeRUiB^~ zO=qvF#)@s&yHSg+Z+%woE!hBARIbm0ABzjjeB=n|f zt;u~?ipWy^LSsW!Mc++}X{*e($gU5LjaLmLSrvvf7&%3a;nV85Zs@FH6vxtMbqV?! zdgL|LEL&c-S7%WbuK_GKe|3szmLk@u%E@AyC52AiE*k$1C&t#+WFtsN?Oh!@=%x2< zzG!`?L00Dzh58eeuLN3{8m@ok-RzS4p$&0W)^)ks-Y5c?HThUT~TEF zf88h@kFyESye?E!wI>UubB;5^ z^9a_`X^>}oBy+=*gW!+-$dvj!DE71!i&fDv;Ec2-fgWoeu~$Hd%fXp~4RL;6jnPTg zN$UE-9|;oc7Si`QzdGO6 z82N^pjdvAeE`PSsPWUikN8M>~B2yHfB8zr)&K;7EPbo6e*bTdeX3e?lI7#b=BSW+(?|rnek4zAyY8BDo%3GwdRJZuK_Vl^O6%jApy|JzrP;UPc^iKaY*C$(WOQrQ?yAH1v zN;V~r0l*o;I$clIsO#$mshG@c?BCOA5aflg4$E#*e@PP5Hp$)Am8SZt)K*USE4?&s zSGeZu1nej|wsyEO$vpS6sSk5+@Wl}rDAc4Yts5$@Ut>aEJG56c+uC|fQ=_ggM)|h0 z)zXn1`kwkV@1|wlb1m1##Z{qeb)|*X>r{t6H8N6yggPW6QPf2z2|r3FC&dU-^Tt^x zHN+O(X8<(o?+9~q2PDx|yz^5L(^L$*d;=qdU*$FXLK77gFSb0oKbdZjxDQp-Gnr)(VW13aM-j2M4mT8t7@5#&Vu(7(Y`)NsSNaU2BybZ2m|Cp}1YstWA zLTc-vaE%DsT6%T0;Brr^VGYAJ@kJg7h9EAf)^~{#e3jzBxZ7R%IrN6R=9v-Ux^0Qj zSIjTq)aSaVE)I;Vrbk!;jxn)%1l50dzKRtXp;^f z@#d*gd|)Om6tieV+R?-#+UU+x&;QHbyKOa&EZxEnR6Pbz6sNJTq*Pi6V}vorxb8R` zFvgfOPydgM85t2N8>+fj_5RlPkG(E>QL>au??KIOmE*SWblE+Vu10MT-GWS6UXWsYJ#V4FHf znQ&Mfsm%g6StQ%2cI|~yyfR28mWQdnZ`@UnI zp&Y6F)3OjtT7gacv11YrIBo~3bvhC5N-VG2bY5g?ZaEF7MvXwm@-w!-GCXvZh$=av z&<-7vsd`lvhf`D^Qamc?%Cgu3l&;{)A7H;*>&mRnbnS2a7}G!3^0}vCuIz#b%B(f| z?18XWm*E^(m0!P=z#;R6V39OH)|(uTtmIA4+u-Ep3zc!d{HRP>B0@U;WXWDJ8IbD- zNHJ^0ujDu-q`u5`nvIc@kUp?+OZ>p8#6YV<=>CAz=Uds>8{9aD1~M--v@WqqP)Fr~ zmbX>g%%{s}_~0(Bko#GDPF5UfpLL#^OU_dM&_mewB8qfirz&EIRg?qLtHFulZql1A zGKhiQSa|dXH!^z=mLe=VM6^J-6L(3w4=om67UHbBOd6OLoDx~Y2@W@W?Jc&Wt@*E| zZ{cpfQXwTH64@E$jU5imj{TLr#vW%>+iJ72wsrTLo8oR%{N0C24i9lh~L!M{J3gu3hk@CB;7hy>O{$_OQ7zZZ#E`81g$(U`$ZvO3* z&7yG)Tu<_K5A=228NTkj0Gs>LBL5xWB#Ou6L?pm$NQU7{g3b zKG{39l7A~+_L|Cu4;>wKGZ|SO)=}JV(vECRFU6~>o@;nJDmNlD8XfC8%-4vc>X3g!rLxpOz&8ZRIZjME`f@rX-35p zcBgL#+V`upt8^dLido5_M&5g*_3se5_E-54cThn6yZ$Emj&Ad#@PF6H!Qpp_TZ4`( zqt@CU!E<9dDCP}SLBDnYA#2Z9X0=h7V6$croNiWt`XIjBZQy+QAH1&5q^_o$llEj~ zl>e+z4^h1tnrQy(4)Ix?g|GJiq-E_uc1uaMnClX?@Cjqh3LF@(hj^1SWn+b2?HTIs zaP@m{{zoF<{L8zkuMilnNfCShir{SZY@aenAifBpcDMh0fCY^l-+r2J(!as8p7H)9 zr_k`88aV`|0v9rI+??w+cLb+wKlP)&g!NG}^wxzV*RLR(ffGU04_J!O_Y|{!RL5Xq z)=-&k8v<`J|4BNLVs z-OBIVLM1aZW&xEvt&}L@agYdHa>4?rvE{rQ=7@j(s(oTId6`r~i2vV=wjnXdhfujQ zzAOewK15G#6%o+@2XE||oi1@}ax5!&@CmH#8?KRcaE32S;;6d>ycOV$Nh!@<-ti`R z23EYRyUf9rp}1u$gDB{bk7$QKeH9RYGBdBrCZRNYjLHe}9UYDwx6H$1$lyyx9V{8; z#M)_Gh4O)Crpe0LJyTRKpyx_q4hl_OtvKFm%80-#qU==%dao?8W^yo*pX;=z zZt#D1a>TA?IpQ_(u1ef=Me||dn&sb^>_+bJz|7Lb48y+K)@3G$OokzN*ZX`7Lf3mb zSTr3zpSW@Ne}kO(1LngT#U|?SM>6i-jO#6#bG>+HJXG5>Jg}Y+ep(lGvPM5JiDKyCsRBJYvyEA-YtV(1agXVRiLrF1IB@^l^r^WyI?0=VEQ{9f~*bpPo!)F64b5Ywm}Z!r*JZ_$$;eH-oceP4A|+l;*m&rA_v9?2fL7^&CfEnny4+6}8DJ^$$aA-aCc8Md?e+g=YvD+g>f zV|iCOS#bX&sTz!x(zr9}Hs~i&>8pGNAh7Q{f?X~Uou36y_t-Z0&WS5=896NWk_CS}U8#&fEdXC4eqfN}8B7riz8ZJOWPOg6z= zi6=x(-hKZJJ)SE0hhpEt3X2+F$na=;+mr!xU=P>`C{anSP-90H@ zu-%=g1D9SzfT|J({DSZ#6NTpUPd{LatV*CXtZh4;PWvp@tiLN4}g;yBB=hfR1zVjF^2pG+rU>`JGqo zkr>&@ z{e(ltpX>0rxar&7ozSjW^hW(g#EB|#f2cgj*tTA}T9aoL26)lnfjRV3L9;v^%9a#v z(brCk`6?;PBfCj32bT`g_}QCV^fmGl^EEea$mju$d6LBKVIx?!s6aV;-}a@z6?`$} z@pjGx8K#qHcfop8=x0q_y0rY(z}S$1K?pXNw3oZd87X6JrQ2TarKfwg8mDkOR=rqQj;jVqt zsr=&2j39iS7uPQn2F<+L3!XI{o5|SU_puCf5LX8+MdwGn@5qkBC*|yvXecO=i z%WDTv$x-@=M_Kys(=7eSQJy7L43N0=d$Kej%n}a1Z=4z3EIav73~uNBz<@)-n~v-w zaZBIu$>s2tr4Dj9#U#U!^bKd_*fpQT+P~Bhw81P-AC;A|`DAGxihPwsF24u+isvu@ zI#+rW-^zv96uyf(PT4_Z^m;yMECX?}ZaA|7^y9o|oLEV8P+2wERif_bvrAWlti4X7 zsW<5=>$^)&(GU@I+uw1#MGSA!H)sBG0aMwHd+#)sV3T~ccx(D_z~t~dE{$(bUa_$& z*qVu~`g1$)if@W1$on?*l)vPj`?ia|fdXx*ola#^;psMhOmu>t&dT)1 zxHQhoT!4QB5gAMPZ5> zIW5ZX-gfOHU)Y7{n2vT#h}!gH@@aZ@ugId=u8=m`AGs8hW6!@+kg1mpy5QEOeLY6JyeAX(2HSUyX`7I!+Z-m+M9yn{iUrjPPUYpCD3(A)9DSc~z8AmW z44+m3nz!L`Zx&FVZ^_lUkQ1M*irvMv7`soqlzxnrdz)*YT@rELSzPSWfsS+_*^)*} z2Yq}^(4@s~xoGv#K`o$CtPIyQ2KuZ0==Jim9J-3hdPFRS=@K-5Q@ryAf4(hV%L&n$ z&7I?ZdjVQdyU=J4wHXU$L257hm@HYQKL3)nB3*+PygM2bT~mRVKeCK@5+LtGhA?y1 zhRi-O5ed=qo*Nyf@O@8aJc+sHt`1-z>h5kB_UkM;J^QWVSX7Wfq{Am&^BQaA&>3#u zBG(&@>nW=xPE*dsl=PV8QUt4;ZbPfWar-LLhEhH|r1mN&A~Vw;Qo*fu0*q$ZR# z@>pJWq;?zm?M|c1#ye7jk^0=)w>y7z+^h?(T;Nc~KWPoPLv9KVphP_3Uh->la-NI` zxO4j2k9l5hkLQ|A@p7w7`O3S4TDHXUqyKD&G+}StrVb6^f;_y>Y% zQwDuBVujZsYZ&$&q$U~gS+8=W0M4Xt0{u@HhH>#stIM^C=-_P`gt5Rlv9+VZ>lrDl zs)PJcOxmzBJd1X{=QNe2eUl(jvKXHi^dZTx7*%d)D|7+Xdu$s{M<7JiVY;E|Hf!dj z`ojq!ba%}ea5z@D8El4#OICk4|%hI{l~A?cBl zD(bM*QehaM6e>irRoiCTP~3F4`D1MkO0s~I$ZV!%hqYwF4cnYXQ$~_7pB6uLyYqL% zFJ8%$A1kG>h>tIQa>p;K_{7|bhlbBY`oEn#8%*Y|hOJ+_klpU4k^8B8*w=$32Kd<| zPtKZt0tkgNJh2>YSKv*njzZxsqtYBFX%CGDO7ehD6hA-Ans=!g6Ig><>A`#FuXpFh z1z3xz;f5+p!%QKFNA$keaneK&5FJ|A^DJA>^_*3_l{oiSI)85W;cke`Q0?))GNax_ zn$#Xeb4bywT8P~j{@@OCwyT@=uWRS_Dq0l77nGU*$r=O^b;UYNp{*G=Z3%7yqTw}< zE4g1S44bpiR6~T!-x1tg&Y3ta%wS+ z$SzQ%+lGILY*Xc!>?L=^xw`eMJN%Y?3(Sd~FW!>evG6U6?$Eb{a3Sp{C%cANla4i+ zkTjemcW^qJTlv);UhW8Qp_z5E_r+V1I~KlW(H;7h5M~B1-hPxcjJua<)8r1#<^9DS zUhW8PCt87r2PvWJ%zkZhNBr8CU)@nooas5`pe;evVt?yJ!LE)W;;sOb;AOxtqsD}m zHJXC3_tB&gDv028GPZv6{Uv8hCx<6D{pYn9uI0NVAs)_0mu>S>Ltfiu@85}3%57nb zI1@UgCu13PZ8PmjH8*mVHR-CD6%wJ?0t-MF2;OXSPDQP!lKIqrLLbVv6mt*tHm3_9w$gg&e7GvAx!NfZATeT zU)8x;0qh{@L@G!5-GOi-&~AvVml-7;BN*A8`)^-Wr?(0L8beVVOx-7XVmMPp>Vo&v z$Qpc;Gi6t(3C)5EdN$gH9A+Y=zD{!>4Mjs6$xRdxb@ibRVz_4*+x_Y1c;Og+^F{2? z1fVX|YX&I0{|{diH}vwWUf*ZtH&IwZufsv{ktgfAKQc?Q?RM5ck#6r%nj*!moCxn2 zT*T3r)u%{#iz4Nqp9+qv%SPfrsb`+4`&FaF=C}a~+M)FNv6(dsx;qkvWRg6iJanC( z(8P0@H?X-`p6pTnQinQNv?>6&zuH*{c^k2yBPTPhL(?)F=TRghfImx!iMXX4{8#`7 zBJ$Hd*0gO5?}3Hl?&chpZP*3^Ox~!(i;IX z=7r)cVvJo&pj&++%8@eAC-OXG* zY!#D?l)`aARX&>E!Mxq#3Ol#B-7l;;(1XZ=ng;QK#-Qw9=O#5>p#FGoi3#YGPSJ5n z#OZ<&igCHheMngCPuk0z^G3fhJbN(3uL<>=6*44$>d0})U<~2bMx(?gT*|j)K#plZ z-v0doNomT+3;x>!vdnzet`G9hmN*4_|#xT$fp@YtYy+!E};-o_t2eHL?{iQE?d5+~HsL z0yg!zQ_k#HeUUsz<#mYqT)z_mgL5(+Iw3 zVs6_i<*)jxp3#n9atm*AN%mP){*ks0t{Q83oZ(}E>Rpo^xq1pq&~_!spJkDn!ORyN z_6q=;zU3N{5wBujJg6NU-NBL8;SdYXW_~IE!Wq!Z+N+MC)^5xxR98S1Y!oaTS%)mp z&EgX`X!k|U`H5=P?b0FiwLl)+kTuJKoM0RR^w{RsLXLCWexb? z6n^k8IliyY9t+CRrE^`+=%hCyaI}+I!mwy3 z)Jao(iu*)I3@Nn^E`?Ur6hasZZ*@G?ZCF12I$@&c7^XDc2gNa4Ci{)u;o#y_X$@9< zjvCk%b4CpkMRhLj&=e=Rn&sPEajN%T{tlHno){ zss{436XB;Th4J&o|0p|9ZLWpYkgXIw$uj@Go@DnQ@&;%3Op#1adHmH3YpF{nIK(!c zv)$2^*?d9y>`dJE%B5cz*}2k1o<8toR5WM!WPXO%a9pJ`e5jAc8UFU!441xHbHAL? za(`nA_gFK=7H6jP3G)L@|Ci0?WcdE^nW}o))jVJ~$P#`&skD(xY2>)b9+_WjODEFZ zka=TQ<~s6%MfHou6k2qxV^bVf6mCRem(#c{PPP#TOm@IiXIt({6sP)X&#o3W+r7tG zbQxO&CFLi^dndVg?_;1dCA__HQkXw%WVGKHs$xzN3QJLolhk7voKPSeh6A)VnNx8l zE#-hqK{~VeGC4Si0EqjPcGu3XN!oiS_3X;#0mpdkmRH)mcBJKcf~tH4a`!gz)$G#F zKO|mn_mj^2J#s%ElGmkB;^&Vf)-aZ5pK~D)yUzdmo>L;YP>6NKBOq5xGKYM0h(?kZY0N?+rx&a(TUnUg zIo;Y8TQg0WL);n!I>g)M4g`Gf_6e)kJrFd$>cGtM<_^yQswl@9HqfFgIn4t=igoZ+ zhbE)G6CD=HIP>9p%B-9%z{O$;f?2BO0N9$-2zq95Wo5wY$|(=JiRG)0a2J4ApQ7zo z#?X0|g(j{Kq9%c1lYMctxty#5y}RxsuC4QwZ+H{fA>Ua`oYPw-j#DFrn^`9fvGJo% z2&;{wUfm^>&Of6gf!p5XGo;VTBPs#>1#}V_<)5DB#_8ES;vd7X0?xEPRJrw45ZiT) z{B0mGL2ctFYO&3^u-azAYg(@!Cveo$6fwPlG{(= zm7pK{ z_=-=v+d}LsHqKOI!1&Ps$i7bd&s!ylpMLmYv)aym6ds#}8M3(eZ14zvH0- zbGG)2j$cE^FJq{#{a(j2uR+HwRbO}f_26g(jDGM`eqy*xFzS®A3sjg1YI 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

f`PqWK|Fh<8QMQv8Z_Cufq$8de1vML;sl zEJ;`LnJVd6iz9160jUH1z6Hk7L1AjZn+oTj1e>vh<4BU-;CBMzah;uj&Li6V-LNu?)()^zc9 z6gCYsPN$BzO>~i2qL$Y0NjI(H7npQ18d%x@5`R4%4~^|8-tt76BzGo7YTA7!LRZ*C z6`=!bP$jlrjO$o`RYlY-_Gz4f0F=p(Alq}m9wJfbpf)Qu;K<sDmjt|A0R{BlUk#CV7ZvZ8m1Dn~4<=+Xqdu(Xae zF)gTqE++fPCgc&KD@c+-wbw+C?d8Uwmt6za7TrB`!w_zr2%%U;$F>2I6&+qsP;qVw zty@YH4zmpR(1O0)$hm5&-8o`wx0L>qkmMaVUWQPOFCBJ~mo~aVNP4=GtRB`%ZZX3d zJ@{*|apX)YCaQHFa>2FgwHpL14s^9jn1cwfp(25LyFo}s0IgKTg+FzLD7ikGs%!N1 z9%FMt#X>aLrA+EmpMomJGpZ(Sz@)|O2vM%KRf*9FO_tl#6o`gUG~}L-!}bIt4*P3Jy5nJk#OMH0$m0MgRSlJQ8j+azKWz(MOOgVkuE`7)g!M~m9(hpeG%{v z`b;52h6{RNgg{0UbsGc$+&BVz3cR38^guKi@|ova+_s(RT2-PS-nK49Op)UD^4e(o z+A1}m6*EuJQk=uLbDPrDwOhe9TFs;BvxJ^QXf#^G`(RVpT1qanXSZW72*i$~Xf{!tP#BSg2hlqy+B?^NLq-a-<@-$6 zTUGVvD=TGeaAAvvf)Fcrl*9P47;rHW;>Apc?MolOrPnMeWTPuqM5(1<;~2maU9n;X zlP0!_YguWqi;>1Tb-I5qtU)u#U!N{|_|V%BtzgN|BwALcfPGno-JE z=FtZtBFB$eb37Qng?A+fUhdktbH7_KFqQwhW5|>v9dkKKP zsDTduw5SkEEO-Lx2q>+J8*Gn7q}rrq=teCb3qxVl(2i!KhUV$9T;eaS2AeO)=-{(w zzquA-a|?hU%a-6kN%AB*r46F|BRR-M&Y+|KBB=p26FKY&QiWscIbgNjF$Mgp3F(T0 zk_w1NcxTK0jnoXG7R=OU2x&;&nVi;?fyNFiq)Y1TLM;ftK<~bb7GfG-1BnW8C6i3p z2@)tq9j@Sf(sY&jJc+L?;D_fLgVAY^S3xd>oqbg>j4?P{Y8(%L3iM{XeNySMKyE2;mhpx^TANgQ+8v(S8X#*G zzgTOv3v(T`uVr3H04SR~#jvP~;Py>Il2#w*ZUuL*ZuwKg*kkYVJxWYxwwN0~Yrp7- zqm4bAX`!Q)jn1J&1J`sFLM%o24pnoT&^ zkA}ivoG5YFz5?c?iY!*o#&QRHLEtTy0{~n1JgIYyF}1H`$xC=rK;JR31Kf*YloGme z49S<^BYqTIrNcOZ=aaGFYGip3syunT3q^NCU4VW=42sz7q)rbFA|Vd%sKaC2fL+B{ zU$gx->phG*C7Jk>?Tf)Q>SNilmf-g$_;vfeDLzTVW|v;{rDt1iR7?rgE?GM4TRt+y z;q~F^f_I0appvJD9K0Bazc1!FT5tUMRs!O5WHT*0(hoy$kgGdh_h1%yD|>yUb@ zJ?FeI@^uZ-UU;6>C1@n938M)~P2}EbnHabrmZ#EsAHN@`$QX8$5`&aX5_X!MZ&NY) znyd`XMv{xp+(8TSMY{{xTuOxVbE?;X57bR;-VS&y<;fs!Q-X(z2dsY*Sw4eY*((iwd76!o`4OoZaK3=tEc@wI`PwG&&D5fwQG3^ zL%7MC(59E~)oO1$V6lbK(qb7IEkF7{e87Ou?WbJ_6qeYJV_UozmkqAzmS+tECMgPu zR?A&Pk1tqnHSvp8F_3VUFmUG@wCaK`#c>|JZ-xRnwZc7Xt`!WgYTYV+(d?amV+Yr) z@2sE}|A{LDmi^6(4GJGla1hTauNLdhIFl^)EX{PF7J8s3g7pSy#Ue!S(9Ot(UySCW zCNw9=PL05SZunOtg==h~gF{XT=buxn$~pmqnE}X=5XsoI_;*j2loU|_NZGC8Mk83Y z$LZ`|t`FFU_E;@2TGb|mHWCoK4Td0!siM%`T+OL1VXr%4vy#(;yRo)vq8z8*D1(EEa%NOFE?%>@J7n@x?3x9LAD*Rk#DgfIytoT-yG zCf02bQKzC~DzQ88Vf-#q@x@@Cto_;A=5&@bXGPEBIDQwAzZH|a*;t9iQu{nk<7z*MpYqT%B2cU3wdsa z)EGg_a6+O^hxcO5zyz5woRw(4|sc*MlzY3gRvpag8(hbNIUW%Jx^1{o!9N2jh%GnnoNfzOInwh zV40~7#}E6DLy0{v-@&<2ZQGlQ5{{UxW4@3Bn5HMlTu!y>sbHr^pCf^lbOdH6IZW({ zO`_VmuxVNTKJi}m!CS7Scry+UDB-*Vl6zYNyxyDC6I?xzOBWMyL`4^6Y_n0C#`=z= ziz<%Lc>-@rM!IIzd#jqzXI+90>+ccCK}$GaO5nZN2fO|qc8M}RE3I|mU;$A^ZEva@ z=On_9lWBFekGN+=P3Q9oBmQz%N;jHY92(=~0Gt*r*XtevCp*#2%i#ZQhn+!uJRpNO5ABn|9gn(_23=zLxY z9|5uBJYHPR`f@7A8n+kNH*0xUw!8D{p{yQU#!9En9&M2NAgS!pjzsyLy?=q zWSKQfKO>vl7d6g9x#`K%FVgHzJFjLF#6GDaT_>D80OZA1-Mvn`Um79DfWnb;NR6D< zhcv_oA425M`Q7y9IHOrM%x|vMG~ifK&>4oF-cqU@pwpe(yQp#Qv?m8Enb!22AN}Yh zd8O4`a)$2(fyJpc?ADW2e03 zVUiGD785%q8Rt}aNA_pLa;C+0JeaPZa{k7w=1tj+cl@H-JJBja)F`1KA*MLuI2&Ct zZC|~1V-+z>=^6P6ydqAROiSw24l-=yqX|=PW1PE>^Cq#;D&j1DzuisMIa{%7=3_DJ z+{w=ni=kcDh{dqM-LV+i3R^~b76`eBOZhV`Qv_dJRbg0M#D3UZtHw%IbN}#*efrso zy;Prmo=Fgf0;X0FCYI@#Mi3^J>7dbvcN+O(8pN<8&-96Xm&P| z^^%U}jMcR2B!@rj-4-wirh~g05VM5wNr{9PN6k1~NzTLpCM|IOfDH%lB!YNGrO~s1 zM6Kb)@DWrZYqDXnRzkD6)wjDVo_we%-I+8#`$y+))t-uYXD#?=QLLqNYOkGgfU214 z$M$h?tW;B-f{Bq%@V6U&38&U{mA)!-{C9iB6rBW%~KY89Xe1OigH(Ya~DjjnAIZsdCpIu|!(?+vcr8{EA&xO=x?RI~4z z@T+!v)o_nc-$e)j>+UJzw#}u)jBCT0T6l6MlbCfXcCB*NYK3CBc*_LLSzC z&FQ$kZdUaOKGT;!wN`ypWqLU)ey0n%i2&$!q$I+b1pjJ3eBNERmtW7R`enS0yIPI0 z)?Jg{>Np%r?PJqmZoh`tR7}dbT zdUluq_EJ?5FuPs}mtLwMQsOm)x**2@yVRvlI82yM3bF`QI`Ekkhi)G6lY*9m1$n_S zY_;&qy!a55{T3R7MqgQ7zl;59wak0_^J(}3?8cM?ys=IX=2_E#p6A%duU*KW7CF`+ zLkF%t5kaN%;uO3_&TDki>;}*J0Cs!XQOc@Hj}KU#z3V(izL=Dki3Ms67N%(azT-vri${W#U?6U9h$q@8@bEv0{K|U0t&y zKbzN6l1ZeBDM7-12A*-UWF{~58V=XE?O&`qHSkeX;w~Y(GUD*wpxM6qnk&~9pMGDW zs?|mT0a!y7b6AbnWv@wqou3hs5trRuW%)VYR-22CIt5Eql?R1$*YOL)HkS2`ci{`q znfT0t5{)YAoZ-Gyk_EL7X`-OUyZB<#5%dXeuaO*DO-B;aGVv~?Lo`*V^)p!^7S7hT z6cT6>g11f&9<7Xl-o>xno;g;h**Y~sY$uFFzSgIM(BQnDirp%JMIqS(B}~acNj63F zd-_Cecco-Yum_T$zy{QCa&|)yv)Z6L{~v#xk`k;#7v^B1DJjuhOAxA#HqHdqBtwc< zd2(8lLyM~t_Fj;@HGEbT3Nn%WENpkMm@um?ED4%b0-SgrAZ-Lv6j+t>U>J&q>rxU~ znbWj9ldeElE!$Rq4@0RqE)&4%L*B$Rx!G zEglXj_O6`OmKO9!Aq@gotZ(g-I`luTY(;P8`(agel1a3lcFBVVYOV`l#49p_LH>-7 z$N*4vK~4y2LTj@6An&7%(FPPo#FrL!fEvDA(zE+^}fD!Vqd$v~Ujm{~}UDzG2a#1=X`{XaoRc(rHp) z0jL2_2TwdYe*s;xbFLBGYXmLt=n&&NDWH@Pg@i}188wib5n+wr=4ak?sz_C)%>NZ3xccL&-#SIcr2p+_{ z!ZeL)HZ?PuzrK!{KP}q7@;WcpHxPE??1%NO1*M!@2Nw!E$K05dOIc z|8vobaI|;DG9R#`&m=ja^k`_=>P2%JX~{Sakrrqe`~g0)1gtLs+Xa`|iWB=-R)DYf zp%31BZ)Jps@A6NVh5xv^3Eu{ghW$2&f(dH+*a2e5c7Pr=J=q7$`g(FKn>Bv1ND%SOlDu5YlN;P@(LiwbOAIA+l*#w*Hwk zlN0ViQHPR*9hacU#*XNCmmqgyM?;rLB}DZkR$QA}w>4JL&|Q3|dbXbPY% zT~9aF*Z1`FER3X+LQ;q*YGi%7UhmGt6kTYjr&T?}T3;%rB(-o#NH<2h^i+~D{yGho zv|iHcnjH1w`_f_)s>AoK)N#QKtdur63^-fOC+b;Uq@ENgtY=+E)@!&P{YI`MtIS># z`mzpRtS8K?gB>|1XWoy12$I)?PS!ozl7mdA;QMPV@Vyhlqwb4eNdS^n24gRhNtAH2QSu_r~veJniv@ zz7sR?_357h_qgAm3h^65yh{K_T0nlCaF(7MJxRS6g(k8xVZ^oC62d+1RXqvfUL`>Xg9MXul`&x1n*N z<-g#T*3yEObxGJ9`NPr=(2t2l(;g{<5amdZ)GejOgaj<2vmX9}G3=sdB2y}Gr6R2Q zel}+rlQ3s%T0FuxC7X$AYkBoKCAsuapv)IsJ#FA4J?cetz|!DeuRg z56NFY{bt7fx;L|9Qv$gL{<9GaWDcV;w?!FNi6A4IaYhqWkV$FFTmVpMphV+M7_kuA z{WC9%c|@yQ0Y&54(w0sL5MEB^ho{M&Ntz<5^A>WCIbe|l2m&E1Wm$?lp=A>Y5EwSv zm5dq}XSfNSoIr|a!f92(^>*RAgc8^4(*hVX^(^#8^aJO2WaxpNp%+%s0#BE8kU!$P{d-c0Ha~i!Uff@ zeZIonrNL`~-56&c&ufihzg*<|((%GcCrhQydG%`qsYj6O-&f>L^a1?e8`B9XZUoej zRA^aM;zIw8E?{thb(NIlZt_W&1XqsrHMzM?O8Kka zV{^e6tOD^YsY?JSS0o|U$JC6hFvh0U+c!gmDgI$vPR98s%k7CTZ&Q^_XIHWhkz<6g zD2JcS;cK(~O=!`)Xp^m75ML_sO5zdGGC@{kDJ~?N_=!`q53g-?CYF@q^&c%+y?W)x ze`u}$)AEnsTlGn6{YNX8wXRrG|Jllq-&^%rYyGm-0M0dkUgJBFh8hzIzyCq&GHew$ zL?Ej*rBRo$3{GH_#&d{RfEOb|OiaeR#EjgDCkZ7N;{ZpvPy`}F^*vpJ9+tE)pt+%* zpA;UiF&dqN0)*x)CwdSGNzh^)-Z?@idsDg9F>Qv`*1l16y+l!!q3E51bwXNTsS1wM@@zpi9cwOs_A0zpa2F?2vP3={45Mc zkiBKtLY!{(lpy!n_jADir4-A= zTem~vG-t~{NG|J0W)fm`Ye$WxE)yiF!Bebf7nFl)hLfH=rC@r$sNI#+dcNcf5vxGKiM z7?sYrq(nNE4Uw+ydQq;AL86VQY4y4o?^>5um6QSqtdGZ&QoSy!DGg*pJ#d?ND!mRi zY(($X{ampK`3|PXr#l!%9_9^Uj7&*W9Anz`(P@q?oC#1d>!7agE~N)xln{j^aYO*L z0)z=+!;GdoSXbn>Qoa+i9R}o01RxjzTIeB+`akfL+{OiqFR>e`0@IX5tCqH|`f&N0 z<@L*#w60mwx^hYVsx|K~|D=BD%0J8lS%fF62~vVelO9!(JFUYqmQpy68SC?+yi(}( z*z+Oz>t|64=S6GU&6tdVUYwh-vpLhNKRurZve>1Ae>Z!`TUXp}+qdU8*;ej+r%&=)X1a?OtThVgW6xL2`6ohqP>Rs-C|UDo*35Qc}|U$VOec z?9=Mp@}(JEO~ATU&55Oy_`6`NP|E+7KBFgbx#dY~O>4bKNk0a8UEDd^Q@t)smQ z#rcaui0`BKZ}`cd-ugJU*8U9-lXd{LXKz9yC6GA$>_YjV~ZG zjK|{imp~#;z_}v=gpbh5JI@=yg75{xmPVT3V7B+qX1q&p}#PX{w|=u^T{t+rO+7X zDYD(ea+m#?XI%4t*W2s)4yt_mW?X%mP6#+#*t+9U>Og%;2Hd6fswfL7v0fEH?T1Uj zL@LPPs&*XjR@6R{Dh0P}SLH;3odSh7u!I&ex{|_&#z>YF)&jvk=%YLXxHL2*uh|GV zz>SmG=;Ic~j~QQYn-!^NDb{VX*qJN-ZAR~y)9CxEVZQIH1>SG8SX>L^qhvMS{1$ls^pP?j6KuDxP(3yoet*hC{mm%oLT{x5`->ntpc)K+T z{1-_-^xg_ED{_tx*8*ZN)`SjG4U;6@wpqalX~N)4s-?b{!A3-#rmLcms$=VqiTH{; zRn+x9TBJ4bpAFII2eA;+q)u7tkmBIauq`ws${QqAk@4L=K}f%-uLtR=q;;ZPr$sp- z%JIIiBx7vBb)~YVLv|8qYG7O8orbzV6S3PzJTepc+LEG>T1RogBXW%@$Qs-tNeU&} zts>T&W~W=uF7*km(T_OSiphoL+pYxf*N2iW(*9d<_W^hsLiDg}_2u*M8Xx(TH*hJd zv^f-xrvLitD`#bL`kWquA-U#uHDy+rEFOpJII&Gn?myB(NK*h^y5<+#lajwycWSyhhZ*yC#!N#Z)Wu*{?A5;T7sTpOBI ziIn8BLuGhX)ZE|TW%!&oiDPF!dc6ioT^Fjp?~Zm$U_xn%?6>L>rWOPDna_`6;BQgVlQi-VM&@t7jou2d`;@?U7zaN8 zsU+(Q@u9Hbj5xe?cGAJ&iK6yf;P4?QVg1r<&KI%2I>WC5Ozon)zZRgTCl3fv@BzY~ zOc+3)v+3=dKUxg9B_lDpOsWn@3W)N zEeEhlFB;mTTIPdiSb;V4`;7zU6~5JKHzABoml0tP!&aBF&E zjU7l!3V$U>&&W}m&&hS(ouZC!mHC{6+&;HX%hY4XR%E^Qd8AF2=#FG3X<86qpG|d{ z9aj`nP=gi^07bySYQ$t}_2F4!r>^q+DUf)L8^)p4;yT;^06`bDWc5ntGxC) zXm*haXrj{_U|A!c89H`QKxfyy;(s^}2rqUiX=@30gm&#g)CBWj2PPTh-7q9i$l+{% z7;`r*N$w=&jb~s^3^Oxku?SO1s2P7EA4UzJ>-ifHoIV$%4tlS z;5ro35cJidg!LyRFrZkj+)hdF%EWL|o}hK#qjB37d<*ob#LT}%f6D{B1=}aYg%MU zzh@_>GaX)J$r>@Tbl#wd8u=}B&EKKRmdt!nF9Z(!mUdAPI(Cl|vlJtUBg zh>hMtoi^m}v)X7M@cvNj6ykjr57reFr)BHej5W31?HmNq-fc;;#wwf;8@lWVxif1UZuuReA@n z#?sfpeVM?iLlFmKxA3wq&W*yb7T}fc>U;OxOJ`-9g}9y(s8HvxkB7fkS(c?`PWs(u zV|~L-(t%axisrd4snh3a|KL}SDh}2N?};5wDu(s2?zwVssMac#_rl~v9Fz*JpQ}ct0+I-T>PhwJAtP$l=BW@tVc9Ybv;Qn zbR&S#nSz+{4hm$#QY2jylO2&?Y^C0pL|EL?;%_O)O|#ez&B-OvLcBR>)C$u`glT;6 zKEmW|O4PfQgx9?tP?S`!Bh~A`hl5Kc;3Lj(F+9+bD8#!^LIP2a&*f7lKnC@?W{>TA za91!S1$bzL$ZidKQC4`u2UspHV8Z)9RAHq4iWr8LKf)QHIAyD7c)|U8k?#ADJwe~O3@FF4n*Y^6( z5Vc<%%d^cBmwfj(TKG_%Q{q&s1y$KiDo>_t>$nTYI_f@?mN6x@qzCNPx8Jrlg#FKm zkVq_D^-<7oG|mQ(tX6S+a_Op%0#<%zmEucbO&e5!%&Mj90GYo+{e~d3m3A9s3Gq!p z_Ex|HXqXb0uKEaDW?0ANeWA|5c?h=B?*g=mKm2F|t|$_5x4>>#vU(*K%yv9SvY=<+ zPsDt7Y+$Jd`^m|Ar6A}qLi3~18furQ` z51cklT=20BT#W~{P-sqFMwZ36sA-UPj_u-DQW5l!9f1{PTvpGyB5p!4>rNu#idjh# zUwUxfUQ+7DQGMEpq(fdoQi@CXN|`h{0wN?5t|K5M)~i5ADlm^G-1EDZl7=fPvI#9& zz0yujq(H^4YQNS_8?34???^r_kV=eTlAxoJkF@HN@tnH+URAOIb+l8Yfsut{6}BUf zwTLGLO|!E1ab-y|pv&z>pSH~kx@OML1I|69Eq4;!`9ls;gFB91qU|{>S+P$@o24^o zJ`I{Z`*228Jo<1na2CtvNYF7snrh0rbUDXpFwCEiISb|0Ty$U>ZZQ7{7H0H@&{nQFE!a<@G`Rz-I&24SVCVYVlARIxiql-nRkN&GG72%tWY8=3?7qB>zc z9NOr^&Q(64hvu<4XuY{j<~$~jS5DtHenYhe-bX^@VFz+0=3Wvmd$WORF@P`mzYfB8a2I;Pa|0+a6Gq1O)3ny!o)QS zvbsb9nJ0ln0@pj55x;hbiHNPrZnV^u4ispcmG5tx1qm%}v!Dh=Lp0hp%bKy%nd+FU z&y!w22<-;P zM2JTU_v9CpAj9yUc)Y|q;&-nLdfiGwmfO;Tbj2^ftmc^X=1I7%vTEqyl$Rt~UuwGQ zVbxZB;}LMTx}a#agrp0;*vz#5`84eQd-b7w2{|QQuHZwOIosat>Dh| zY8uwyO&u<0Nt*DU|!<0T(LnX*<~5in45*|3T;A?_UR`dlA!TwU^yC_C6@z&MI?R9v4J4p z3s4OIDgCG2#GQFrt8LXW8#X8{#?L;*+U7s<5(&SxKzd_%s&CTk~0BN2&p7&A`3WXo;sZFi)U%YbWz0zRNIWE^p;O%Wc?i{MeVQ(&@T`N*oJbB65qs{cV$E@5 zkgG>e0o^ImtsQU+XLpy-%Hu;^ly}OHEehaz5bWLH(*e&5+XKOf-X-D-=upeM7BVv( zbZ5}Z9`FNxYdHQ!v#keop9HxXfvDo9LdYO)T{hPx3Q+LDx`CAb4gNXIprPDI7`RAX zkSH}XS`p(#f(GZ}0&IamQkdnfZ4aR@X?=jW?hLh|jdq~sOSG2A*Y+lyz(p+>$3g|I zPmUuv^2oOf~n6gKL6J6jRTUUJ?!8e9rBvi3)Tb`=iZnRxg+{Up9`*U_p z5T2~Hk1)v!I{Mw0)?PtyxF1Soy0(nnR~_vujLRLc=N_8^WctiW5_zne5!MW-+%*qd zx0v~as44?W0?Cf#$<{GJXE&(&E?&>g9IT>&)vA(`G%=!zK+E{V!kWIcNZBFA8ji^e zNmUdQec)Sbaxv}QS#iC$%YfEFX`j|gcNfCNeF zp#_h3kOT)=Vwoh8I%VuA?Py|^KS&+2E}TJt%|k1nrdm+5=>&f?+{p5*#o4;V+i%;8 z=FZ#j;Lph{v;Ru1PK>ACsPZ(_3aMMu$ZIKqhmE)+8 zqg`xFX+cl~0b61Etj^j2A;;=q!xAQC!84)YI8V1Irb!`uRe}5gq`(HnRnYL=&XAcv zI|(6igJ^d^YyR{=&CoPCe-HU%pbx?&>#CT*?IDfSx|V?+iCSaB-2N+)kyS??ru$XE zg99f>&?GITtt;2lghhm`+H;esl|mkuv4Fgjqk&WrfG;)d$qw&N3x}1I#3+~u9kz7sd8LVaauLAob0HEYCR(- zg{E3#m6?r~Gb2_z-32o0;&f+?Tmm0Y!ky3oCgz=)NAzKYS)UkQd ztF0Z4@$LZr-X&}Rm`ggTif8+0r*zYB@ldRIc8dB^B?C3(`bgN6MHhI|hqV#fhOrV7 zK2(Kt(c-t7LY8eM#U&x|ZtDoRi?jk1C*gz_P111<8FoD-fQzO&u;bN`#{n7xSt!ry zQ&?NUiGOf~W`hM>8!WKX(v23MCg_6+w^S)_e2a9$R1F$^8|b1~+v$~VsOI$C+eZJl zw(jZUT7$9ur3k#m;v?PQ@vPC=Iew^%BG0fvN;9G-xPmhpGA7XOkZmnffom~s`ia}g zg<4R$!6jGHjox897PND2Ik!K7atN_khmhGa!rQuiqE zFI#^1rMt60aO3CGapPCd58Bp7yOT0IMIGO+NN$*|mSHSngvo0oCu5x9+-VRl%r)v6 z&avpi_V(AJ2He!C9yF2hsznHK^|pe~(}^Ew8*nHq2~h`1!9_plaYe|x#@doC??{#w zcTg4vT1RH{i3k^2Zy=6huJ39$i41PWcj|quLB1^7}LKZiv{>JHQ3RAEuBKl9h_fa=zee ztcMbb0>&M6PFwFITyin5b9n}-Abz(6lfX8Zz=Sa zs)C#dW3vJSP^MR|CY(^U@-&q477zbRzC5?k*Q`L3SYy_X7=KHZYr zCL)^CVp9%B3@tn{5Pr{-0vF<}l02@qqy!ePx>Yr?tB%#|iBAQYL0b;~&KcDIB>*7! zYK4>(gTJef=%S_vygm+2@xfY>&0-;KjnLW7ZC5T_g<5cp37qi2;#HQt;u&$E!3Dl} zB2Dx0u^X%GZa8_H7UJDPr)Za$`J9}-jfq5p;RCX|f|!5N5upnNkv$A2Ik`A87ecNP zJ%*2P>Jm-eYhmf4?1d_7q-&^;j{9M2kL#Q@0sM|#p3@Ro`Rnnw5_!k+4T@mhxN_x)U!brrXGiv~kID36PqLD#-E1BT`JN~<`U!7A8FnwAmi6)&2k(}O6sGn38F`d$?~?27}t zG--n(i*lqxvZ{-OQ=**V0;AS+fNjw`GeMViJ@4j~SdLM!OXWPFO>)bH9;-y4B=?8LY|zeAYD?nOslOEi!$VZB>dsr;dlmB#g~_2J=iBpmF8-!QMyI>6R}h5 z1v*&!m%pt0TnPVlN%;S?wS}YMMQ{Db@BYWzb??lMeD$C0^{!9f$BYs3l)3NQ+Vr-z z-o|LSt*v)~*wzNO(YLkrc67k!tONYHpo_Fx1CfhV_>e!)=fC?B{zVLQ;^KA9mq#3f14j;(`ZC@FRdN%a1jHLEGF$9;VslTrOC{k2Bv1Ug8=jqzhW*BqgLB zUiWUX&y^;HjZHog-JSW zixW>iTC%#mss<`fBjE!HlFnxmyw7x_FP)~SD)g{vfbA{m5mo4Mdy5HXfXFp_+-|W? z3)r7qpK#!|zr(jr*u6L;3-a&t}H*1uQS)Yqh%uZ?8RhP8q`z1TEcwQ_#Tx4UM;_aUgxncelJo9={r)oYLP z{0%hRA*nSPYC~5of1O-Y%M)R`+g~`#h$48>y)GB?rSrv8qR6*Al{$b5oEg2?AI8lIEQ6FQ#+Mg@LZBZ^5}^814eXo-X@ zP)($FA)pNmuBrG zdHt`vKz&2%-gEB)Al8(_RPltaAJ`W6>_P1NB{)Eb9}O+eU5^-)W!(Ql+;gW^e}pq} zH@Lb>z#WGz?V*vV2>8ER6EHU4!RJgNa9V`Md3@#IF+8W+b%9NsPO9X{EvK|m?K4h6 z2U&cDp5WOD34NnFo4inPdIVoG}g>b^UPy_2v|@u?>W>2_$nh?#Q4fMk!EVTZcv2+RV{08^tawCM}T-DHebXv0NOW;5AL&9kDw zZ0BoHSk4SfDj=yTUty}3GHWR*E$B_GW0lCI<@xiKNxFyy%_aLG0vg`uJi0(}y5_VRR`h+W1d5aYil~yP^g)_wpZOn%(U_fL1TFwyDA_p4a6LI2<6b#`}ZEN16 zI%@wWV7z)~*=E%2c6i#R@`+D9J1{D!qg7gPhQW#=d=i&S6wpk8E~!y0ZBKN{k_u-K z8nm{QUa}<>;KD2^riW)q1%3e5(y?2b6NGrY^=&e0-*MgrR-VdB?Vw*&!!}#pSu|%+ zGj*~<-GIT?Ifw?&tFl1QCfmw1p04hI(z(x5U`wcW>~-5-(h$L~RrT)|5<%_RFP-(h zr!ycREFnQ+NxSC?2lWt+lQmb@KcQ9IS~rg3kA1b-4l{$ddzJN+C;Pa zsbD}TTtKKj{>J;%#v}J${n!-jAGOh|3aJg|+&@{gtvNOIh>b7MuNsPCe6PHAz zFH_1#w=DPwC*Q#UBwqB9VlihEJt}SaPMcA=;Oun}6c~Sf`lPluH&>IA*yhY=E<961 zDONWhtb73i6YH%%i;8B0H?VVrMi~_W&`|8}PGHkr6KaZtYzjlvjusla1GnWst+g(& z8;WC*Py4i+i+tL)hKI1T-p?bntP?vAA7J+-7#~y7iD|1JeY-siN->Td@h?+~saBxW z_vyvjT#6b~$s@FC-Z5Q&WdsVY=rv#D)74F(l8NUa8Z&UNY)|#P#@YG04FUUaZ*Jvf{<>dGEm!W|I{IaP%O5gHve zu?`UmZ4c_TdzT01+Ht!63W##};DdVKiKJjkvvV%U&fE5-*5|-w_Cxhbknb-2Y6o1+ zZb7-}?PR0TbmBJUMdc|krd0-o0yXcB7gbftbEY5k};M1tF#Iq5(V26cg5=zeT)Q zZs`oeRl^0(3;F;^T}Fk&levGNbKRch@wn0gK6*hipz!^@Yb?Kc?+}ds1f=MZ z=dZfmu7B!n`k0iSUYF%yFiY!}BH*d&m%@b@+dROP8k-VSL3jBlnz6uQ?eE6V`$vtI z8y-@2loUVjA3fXOdkRTDxl@=CG=ui?8&qq^U82D&#I^fXTGCQKksfYqtyAq166RV0PDS_* zVx7zc1+~MWI{GvN9c;vagZQv%=^YFqgAFi*jH#`EZ3+@(HSdKT=_1pY_;7vW-Y~Pz z?%v9;k~tGWb-pT>W=8y1v1-ic>KC9ve>E^MB4CbPeI^#``+$IfJ*We@dE%4H);h0_ zeg{@vrhN?W0`ZrrTVZG-ED*g{!8g4-dU41Kuw-bWk)ks`Bu>D5!;~91%|@{!cC&UA zma&X;ONtMZ`I*CYPC@PTB+kqIbdsc2)-@FL|L6?E9oqnu!_nE3MSfvxkE2;KwV^A| zvNX$|;83sgkzixNvd7wA6vg~3k3?k4`S_z?0pK-$n?{TBEXz5TF59(rh;t8 zcSkP{-yQ7#pZzCC@7})JdwcZk^}+Lh?ms2-vdxCQw()S0$2ygo`xRgNVJ7&UIKKco zXBLZ31rSxwM+mxxx4B_-w}wE0@M(p^VO*krS{xw1G$>0@qgHrer~rYd0Jz%!o#EjR zKU~Kcb`%q>+@VZ=GS)9Lpmap~`Qu-~r;f@zI;_5hEwoLxH^s=qY&Orq+LOmNzk{Re zQh)pz?G-h{xF<4DRMK>cK~rpuw|JyS;LN^KCcx^+`sMa| zxI>*ZE-$nEyp!dfAtuVUr(dY;?xW6j_s>osW1>wd+ylD^>8Uzf;>2XA6bM@rC%(n6 z%{Q+Pk3PM5djx3^2m*9tLSewgH#SAo8K-Ya$W{s*(?T7 zbgaJwPIT?IY78N;*#ELY|7FPD;ImtEGvtMM)ZG?g^A_nj1U1#+3DL^a92lp36`fLS zPQ>AJh;l8c03v}PcPhp3)E-b+4HIq8N$&!gOybVzRVPbrC|nG%5nNybRl5}&7??*e|M%{wP z`X;hwN4wpw-srZ=J6mMr@zO?FwM5HfY@SUk#8CgsAb$a-5E4{Py9|pIZX{m0ZGtqaFK(YxA1_8Vq1r$G@ehh^%|^R!(y=#}mygBhgpX*{wG@*|T^e)RIp|=7~R5qa?O0WdmP8M8kTK7>JC*z|)6l6$-S~>N>!;3OG5Qo+cG+YyuWWA+Fz1 zULF`XMc}RA)a7!TGRah3Z2WqG^>UH*PJL*SP2F-yPac2hdVSetxcS>@ zJ$XFKF5-O%DEA^M$~cYlCb21vc4gkxbMTUvd~lPONO>dPo4_^5;}7uOg6RrhsaEv> z#LV?Mj7GPcw3!Rtt`9c(lAANlW42rF-e&1AZZ;@$RHNf6I;WgynmE22VVB)My{z3yeIW-meVOgFA$|V%REZDxAvMqsB60RE{o6~p< z?sq`8ayL|mQwyD5*#uh@6%eSf^32FJbLcEzq>$OEz?4Z-lVS^l>O#-_9C5a&*a>37 zH~`Ir;%L+cQRg_zFQa@!LQ4_|;JjImY0!(C2#vBG87iC_UP2nOVv&!dVXWIDw#BH7 zk{4smTtMsb-G-t@q65>$X{nxzwXLLe$kW26(PMP&)@li^}oVzfTPF(-15`fSEjjb?_v|+X2 z8t4t^i$KmY9|fiBBR(7PnCMg#BNeadl#|yXYGlJ#i$&8oTNKuQ#~7hF*9{kL z>YxDx4OI2 z@u|-CW##pA_0Au4~;2_sHIBfu6`Ut&;RjU~Gl{I1nHfgP# zL=ASEMIV#dVrHQ^kBOiQ@g7y~190irL2B!6#b2shA*lh}-G`eGJ+Xu@V+a(7?YBZP zc$aOc-z(VMQ7XeJWjE#(A;!d+oW>Zw3#~3N;V-B5Ygf8jq{a--Zn|6RYaYSdImEw1 za|cZ~>rv5rvbwVl@_=^0Ci^rDV2~CXOtjWN^>4vijzB$0hdC;6T3+KPI_shkC9=q| zTa8$o8zG@%cj6g71dLw06@v#Ik_%3_@7=?;A6Scn5%?E)Lv49g(Tu{g6RY$_HgU2$ z`r=hwVdr5pc)3=PUIndqcdc8!N-HcE>VSzW-H#I8c{?BgVNEMpyn$jR-{lm+mM0Z?bH|aSA-5a!cQ>KEK4X;=6|!{Z~>$vS+}Sx z4T<|yQWo)a+=gNh$7N$rmPLBloU0dYNWd4_URZmlrMQ@_5r#pd60}4D+SQfXdD2Kt z$3p7ZMQ-8)$lSkO^?VE@a1nzOq!f(_c_uC}Dw$TEPObU?uq!H)e6d}e7K>cY&gLnO z!9X<9vcJ=Kn#32Hc;P?>ki?tt1dUuZJhWv_#YL%pTNI@UcYTR+$B$Q#BAJ;p z4Ie46bzK+U?d+B$*ChFQP#x83`Tc=b7OoH4{I*O(G&|ytl{VtW@i361vT|oMtiCq7 zQ-Lzk#!tM8;_235R9uu@sX#$cY^9eZoorW>*ZqperS=53M8@y3-5TUY9gQV>(IIZ6 zDw|R45yxq{(3zrN3W+IVLiPbgP@z+n~x;w_@-;>0IxR7M#(ra@-1laP&DA| zV4howo2DZ~s9?Mbubw$c>*M4@oktmMZ$4UG38ouTgc~~xw)>#CcOEimIqi_@&^21V zX-pWJe}p%%DA)j$1jYDfV$^BgF|ofz8*+XPV^w6c7%p_-N{ zU0DB>q6Cdxgw8$=Je@)w)!8gd)oGqx7I1Gw>E84*x`G61Fv)+uJN)-oPu~6X;_cxx zfX++ke27jHS!|nG)6*a#9Zwg?bN8p3=n#FsqMU;I!9X^EAuH7>h0 z`7xHdvH<^CuDqZhqYS z&SeL8?Jaqp;+FXWw|=F@flPt+|MB(U-CB|z9Lrmw8{%UNuDk3>T6%SEZgGuH^V%D9 znpbWJE}fn)ZC5}HOu@{NNgoC(B2CvcvmBWlm5p0GXjV=Wx925x1_33_MU)EwH9++v zcKkHfuWLvp9MI6zC_Qc|EchC*`-PDEuYlVxfZESQ_r@rvje0~gfvD&tg<$YNShK5?q@|l_N0>Qr~a`%tDYt{hr*d94VmpX}kLAVfE9WtDnBJBU?Wj z;|)Uv)*HsSwCDn}l{OYB6*=B6_J=NZoLf9+C>A82PnL$I4D2Mi*-J3bUyp7=w|t(M|BMg{f&B{zTH$0)Yj(aW*ZqHHA~V3 zr_Cnn{qXRGh}NEFZ{R}qy?{|~4qpG`-^o8vd;XL2>-hvjHZpAeU=@l`V&ZUOVGk6- zvIdXf*4n660Cxv%+uf`d&!NUegDN_UmfeoGyoNiqI_i4dK%@J-;~N&d_eX=|JDJn|F-|{hkaoZ z%l-C4L$GayKN1bpua3z4iaYQP|7%CmCfuso?RKMlQdBLX4R|1OrQLy$1a^)}w{=J1 zDSyEb8k2|n*K7ZR0ralbjKG`t1q1N*2m7c0PqWDqSWB}q8OBQ>4a_CQ&mRD%=Kn|ZtwaGYPzSr|J=^$ z$ZEQ#6a3t+>ELU+HgNE{y&LeU8GxYab9*Nstm&Fz@^kxUP_F4*L-yzPt}jGQ_k2HW z?`w8T_sQ!_->O^p#DRp+a-~;!&v6n zan}S>=Jyn}q$2aAvi)HC(U3!9xHHmiI9*jd5VNrwr^`IKjD86?fwbB3El>+~+3F&X zIlZbdq}oeSS7^p2Ly^aHqG~JPtXb6gKE~fd&K$vX7A`36hIULkt5;No0snn_n#c>A8FnX0JJa0!D-AR z2r-fNRc|mjZKm^CvHPxd9Cd!*>-=-G^OuwBhu^jzeRne$oc1OO^X&6!G(=OzzIuOr zu>W-L$sRl7+5hp~(d)nMzgmA@$9tWBMxEa`JAdiCJGtK4Y~M6@?+gar z!Cr53UQ<>nwi+3;gj-EVQ``nwmeG0(#X_j-I~`9Y0(vnjKiV4I{`E+N2;M>IQKP{0Vj{ z#V<*D)@&GqI?u{+=_EswSvKp#{iAnJUcdg^^Zl2`d zobLa9yMK7}Rc6WZ+tAc>K8T&~Rg-bPmNH_=u4^+);qABterOIzoAq#!Yu$r}MO>oo zif&qU>ppz*`qkn7S6Vo`Hm2zU_$FBE^#t;EnB%=V_2BzU1R-9*&k-b z_HDqQ0xjcj7ti4*z$f&FMI!jS_6}D{Es$c72btbCIyLW2z79>Gx=e2ic-1#~D&G)07V#T&9aM&XeLC58(mXAda(qh}9tK7dXD?N~oU0$bCt9 zrRIx#o)t*qfu|6Ma?n+GRFiEychsgOlgu}!VD)d2Qb+CbR~_P|uWXK0^zhQLjlQcy zcY6SEJddNY`JE2R5-Q|iLOSUw?@wF|qd6=boYle55eUK=S5I; z9`*k6aBK6=-)vVai#%B6@Zn#25H~a{qG<<*=-}YwU2S)hW^@ow_CJD|NfY89+P&0) z*W-`iRfX5J**oqW4+baKH_g_Ajoog0Fc=Jez4z%)gF$i9o3zz?_;Bz3dw=coJiAEZ zQGs@PB3}3+~*cYiu%-$DYvj! zZ_grCMw1CR_Q$h1+JHaeCcwIz!0;YTvC_VlN!;hA1=1~NSu_kSL zfuujB^p!WO)Wi)?=nYPL4%ekr3EaZRDp7xR(-uEg$;O7cMY{RM4j*rEoSdi)^}c!U zI&ip6omKdxb<=upu3MlN{#Re*Dhy8z7P;_b0i@;xy*0F_)5b+% zm2-dJ{1tcKL{hrx_2`2Q+}qvwp|wjN^?($&_a;C`-`fI5V!Pf?pA6P+wlK=>P3yLs z&q3^Z>cb+=uM|e0jZ5vfTZGT#5F5RLx`lHt6u|bY9!ep`!l>amMr+Bj1P%g&5=XO} zofhr2(PrM__KF?<&JBNtYb8XHunveIUD;mcT^94yDeM|%e=QX{`41Yrne^t zqR9@*g*2f=+fXb{|L#6k!nDYsW#Qju8aP*&#^a4IoMB80h$KfFh1WD>eZ;-#7EYS> z+N;@v`Vwju`ILj@T8S72xh>RHwm@sFBuB&X2Wps2r|7Leonkxmz)eyWscDo?$e9Oy zSt#U8iU6p}v#f}zJ~+%^Pj(XUlZc`CV+3(Ud8D++rg3+gO`3zdI6I6Hgmad32rL9=`b&hJ)c^78_9wM zjtisr!8T%3nv1iX!Cf3;`C6(|*E6r;1Azy8xR=Bv!(O-B^;r?`4u&q3({oz_EC&yz zvY!|Z4R3dBIh&KdYH~HYlOFZxh`%W)L`^zQE~I}AeawA#8DX{coVsFhEfGN6Y|MqZ zgKaxy5c>ot+*ZT#e`%R z#(ro@EG2w*odzx6`ZBcfJPp&~vYq$5EEzYxi$kgtb1rU(!c`{+eDj(|XKb+FM98_~ zIe_%U%^QVfT#H$VE~asPkzIz;xH^aAKg`ZS>6?sIWR?~2nmJk^Os--J`^Fc`d~+gp zV(jRHMd}?qucfVpMk45-ZV|X{`n)gnD;Mr&$r0TcGAK(gVh{n@=MDYc%{%6!If3Kk zxk~)zqo89Ag|Mk7rdfCvMVu!w^1m9(tv8_}NNt3mjpJ8NBiU3p>%#Y@^=5buDR@1o=VM({1F}_w(GNqG?_;Q%Q_oHZ{Q;7uSA8uiQ5qB$i>v9W& zAI0g5g6cIBg+A1XBE8e$S$Tr=nZ=wnB60lySC8M5qc6&2>g2pQ*njh4?+GYe8V?>k zX!wv65O-DxzdKUY{ppjsbK%fXl^3xBc4EF7R(V>Cl6_*g=vtMCC4Aqf^Vz$5*WC2x zeQjgVj@V{)s2ff~L754%R1F5jryW%!vt%0KQ+)=R2C_K^h$(D*a*@(tFNHWSymv(@ zo+}K98kO;Q!D9F}yAeSo3>^ZMvR@1{3g#~QeF7qT$U$&C7!*4vy$ShjfH0KUOB;cb ztwA8-f)<>j%rqUvA3<&kA1=?5Y0PAW&VPVIbmNcl5GO8<5c}HL;RAzG&TD{u^3&YK zA1%m7fWMD7PqcX_4J-zkMn(A?K35~n>(OckYl)NMqb)Ep5L%HUdzz{!&!a2E>iJ{= zcdt+sBv-Spg$w5|G89Kg`6LMFQ9cRtHySrP2any56vPCJ+k**plLG(63KjgHPf&E< zjBpBiWM7ly4+Xg!qRL|t<&&i-nN}^Z&x>qgu#TI@$Ea?=_SnNg^v%m9WBh4?33n*Q zqOH%#BRM3O=$i{VkP^TfVVX_c&b9wW6&Lm~jBWZhpSmr6NawTRH0e<-tyWwwekfz* zERUb3r;C!lfa@MaG=LJk_z>ug z+<1(w((o)Eo?AyHdQ~wm&9%;jt`>QMHdRc9K)BvEUJOdB;0ot64uJ-O5pe{lh@sjt zLb{E2g!w7c`K-gn;*_7VQsZL>A{0$2&!>}|6TEDwZL>i(U|lDkh3q?=WmgA2fcS@x zHaFeAb$}$jDeita;T#ZW+`o@o)Wwb8Ta;&ii?1le{HZR$e-?_yfIg~C}DH^Rxv%?bP8oCd-hy3UF zY6~)Yn%{rAcg=s^yvK~4wkt$0hlCA+vk+LQLs&!3gqy=WWKS@7lQIxa7aX1-6MLgUsMnZ;zeg?9VVU1RawU7tH?zX*FO-@U=Q>fUBxPzxqgP#yM&Q;h zv$ylP78l-N$Y+hfZ`2pgiAfv-?E*)r<+s^mev2;o_vy>pMG37=m5L6n0=3t7(2R&63UCQF}{3N!6re9@n3$!|z2k{lvlvpHS?l!l)oxNUXz@H(eW;Ff60d0hcn~_{q%V;&Df;@ipL7+AiP?gXCPZ1j zp@;}?jH#C}pKAQt-0lC+JpQ$Jva#Db?wz!D^^bed5A<>h!B(aThIT-2s|ExWct?X3 z^d>dN(M2-M(rz+DAK??{-N2|~aGcT^47%nNGeBG%pXiT<5kBTT?f~b;KFSFj&POs| z6lcu_R^hblr!iJ+xH<>O1Ju-Ga<;NU=HhckGEr*R8qU=IoH1D#VZs?#W!GwdDA3#tX}wL`HHo*r?6HY5;EHA>a*ah^3oTS&UAX7AU*pxbM$-a-<;v+iIX z=SenN-tW8H_L|}u<;5_|<8aqyp3Iu`yf|KqwcSI2!zf81h%1KSgCMgIml8EdbC8@l z1ND09RR+qx^h%vVOgv7%WNuh@oaOt`@T_Tl(M(x9dL`#%CoNxi1l+nN?n1m;YC|>1 z)I=2EHZ-IL_Qq1)g#XIe-eTlt%f)z1xPDPk4l96CFdzbhRc;Gspa_HD7=@Z9=Vbca zrYO5bTY)gWt>SX14@qOaF25f|U^>odmJ2J&_vRC93mKL!IFb#S*;nNh%Yo7P_0 zgv`B?x0Vy)sMF{%=1UEWJ5JxbGa%D7Kih5=&6M8^f?)}47j#)!a z>6mtGr^j0-vY3Jv+0yM3$yx+f4gJy8#-8ur51F;k&nHv||ESu%)V~O!T%AFbM+vU< zfxbO>(HZASoQ~jQ7`j)CeWNKA%+R+ZTyQIuEzw{!FW36~rpf51EPoYW@<|naJ%8aX zvI+ZUz*QEs-F{wAM@#!@yO7^Ef5{jmrfJ)#4miXuOup;Q!<-j|yH{SVU>DBJYC5nS z>`g@hRHwht#9DwFt<+8Dk^i-8J(`U}vsa_c-jIPB{ZT1D&_|?oWGv+kf}V^H)z_ z|8j^1Q(8F!uFb9PWs*MJR(=1w?n`eggBCuyVrX650r@cPKu zWO5Ym0pBr6%Hxfb)-E`7pKSDdiLFIv*!%VP*B?$cemMTMj~>T6@DS=U5Z}MAns+E+=%-JdITX48Z6u8z$b6hn93eaRjzQm0keg4sd31R=kB8O9 z={(X`&@^hxCOUs9n82G!)Cu)1OmR|=KTO_R%lHW z#a7FTcYbJqa(fF@uKC3I?DqQxjeX=0->Xfh*Uh#lZBd8%G!Y1i$Z-_KaN;yqPq~cn zSl{6NBq=wF;;aw82~j>_Pa4}^PZ_r04sQVfhP^i z-IL!5Z=Gnop|)@?jR%dYkXqn1@oWhEX7u#5?O3B5cx43;^9;=mFw^51RAJQJ0||!q zwZqH6$&Ty|z+2&(chR16mkve)e0AJC`Sc&hy^~MJh~Q2>aU_b9ehU$uSH~%L5RiT% z>*gd?Mih;ORa%Q_sokmb=n{dtZI8CEjN=%V!)@5eAOPZ$yh5X@AQ4qa#nnkG6GeRHy(lk&|J{M1d@PWbvHn?XkI z1cDQq0y0^K`BL|xshRO;dR(z)xdLI;u9cE*6?I)yaE&<|AJ2T&;Z!SYZMB`0bJN%+ z!sxVjmc>|YIJbw%M|#2Yc!Dm$PH&+LL~ob?aZDm|HD`ev`zqTfo#eip5dj7~x|+wP z5gAtG(WS@Azdd-~A>Pc$gnj@sDVHHFjQcIo!HxO(qz~3C4YbNC@X@v&+Q0tLYpce; zJ=(xVecyA<14HTIvs`upCC=TG14J^9<-&-<_TUhX%<2E=(@v;L!K zBG>-47hOh^wHJI8O$s%Ot}x9CM*^1&ISJ#c5(EBJEZLT$y`R_L5`9UCT>b<01p0=B z!yilb1F?fl$30;|

3ogS$HT@m=h4+4|qSJ$M1$KPxtXY5k^9eS?`Pp_d)f|G?j- zAh&1_3-xbPff)rV#UJ{XQ+>$q;ORoBV@&*jbr5`Z#oror=pF!fsJ`>FiqZXE^XO9G z2`pur%}MHq1!RgodR13WHddh$J-Z!uvOtM8Z1dsgWfFT}T+w%d2`s|h zmlx9@WQ!rIvk+YtKo^0nQO896h`W=n`eB@9|F-?pX_VK1wDU|idJuZ=-?qn27!YVx zcUD@z?i`kLP-9TmYuzXcBFvsyRlbrR!5-b54KybauBp=UxOC=q+za*TlYfEq7mwt? z)?z07yJiwdS^Df57PEMDmwwTc4YGi~8MS^7!PcjK2aT}!HRUV@C+kVtyuKlr#Ob&) zQ+>a};!;e7Qx-^nITyOEKOrV)v%8dYoy`=BxcoUO_sSA@~+W$?4dMKuJ^DNHp3vQpurkg2&R-LqnO;(Q141&-5e1# z>yzz@YQm#dw)Hayw*%>+i+Gq}BIPAB2p#G?%4LYrGD)@9@{KtL<4A+tzi@1(^E@^v zcoCm)m*zzEH0U%Ddw^pMZQdx;e@(OOd@)z(Jv>JJb~JGnVC+D_qVwQ!{vq3HPkH&7 zer;Id16?rzIryrWRkcU#ZZYW-f*VX2<}(+GS`K${T6Ga#l%ZGN_mJ6I#M*4MW*yc# zUTQa@972e{H%XutWGSc4<15Mbybs%=YJr535($Aj#F$3TE< z>r#ugrRfj`))a`Y=ww&8&Gx%k%2@sE?Z@<@R}W34tTu=w7(HiYNoek1k(jrl!+Uh(%}) zZ9R-I1{U*|Iq79TZS|ho_aI19d1jO*1UNT6?JB`rQ`e6hjwj>n^myl5uB1G6`Pzo& zYjGM1GmRrn3fab{S9Bu}etM$5+x+e?`ZCh3c4--K+qNnj5DSYPZA&>hme^b$C~(%l zoSC<+RiY#%{_&50sMBb84tcc;oM%)fr^yt8J90)gntcLFFn0w)?52+fNiDXUcE2GB ziM|E!v(c(V)?ltqEYyb!ip~qr!N=UQ7IHPfLE5n|0gFRT;i@VKhbC!(_lCEaXkxlt zUAUu=raYrB^g)nyTWz%s_~M}vHWsXprOdCFv3Bw>>`+4POY=OwNFX64CMzy8^q~Mm z5#dluhugx~EBrP%V;HNUUk8KU^;Y}g4Mv&n?luR5-luyljT-DOv_A6`v2$~d|6d#; z+!F}huVG(ZB-s=LF4tb4BF1OUTs4G)-jjasbQ+xz3}6;N{RQ3-(oRVf&H-lv)CR8< z!_XK$P@?+!rt)?=%}F)NN-{?&$(`vx#f}XIy^SU+{NZd{y`-%g_qO~~<@WODntfPg zrNiI+2f;7fPLK~CM7h9w@E`g@Na2y2BT(OrJcc8re3bNjWAHxbBK(I7{d)Z^SCwYv zRs^Q^uFXbK1drxcOH)+djyTZFOKP^-%J1M|%U1;5!KO*EcUolAMHz>$X3hL~SlWOl zYbxc`T8_?ptQFpnVcZjZa018atJN6mqbWJZKGy~xu2f`_ zl&UDs$kKJ3fa(PT`vJ!_&7u(*Lr2ph!@Q%#aNa4(t7#1F1WT{mwjmkrWo&ZbqBjZ0 zGlWu!kdIAM(vd_|+$zT5#egqbAe53{T8a8Z=m446g$xV{eB39+n^gq^i1q$3P@3?#}ho1G>p0)NqkWhvc_M&76KBuO!BQ&Ol0Z2C5O(3Ru{MJE}F zXIwiH!1fPt+C(!pkALm|>13mS{Og}iHk!Nr!2qV&+HEy=`+sV7AGBJ#_j-viY|&kV zA3Ohjymg}c??bK%uwLu!b{{~)mg_a`;~acL{Y$I6-9C}IW*xj?M_%sVY@dWW$Y$Ef z1#Y-d7HFoiCO;4_7mm$Ih*ScD83-rd=rw#1G`UIDlVRX40FI|jxN6K}Vv0h{bPQG1 zDDVnqIcP!=_gyB)m6;Jt7+Fh;LP}&E9YY>}<%ihVFx4qKMSe);9WRd?&yPfQ)jWme}1u5Uk8$ z0N9{YHoi#QRNIzEs_%L>N=Sb%fD|Jv7nXH&{UvVtvRo6dR$5hc_j5PWg!c(g#8!6S z+@L7ZG_2e=&nws;#cPa5`=~n3X&y)C5}X3y>w>NeUwJ&s%D7R7UgRU`4XG{9kyk^LL@Nrt?`YZ;ko~b%YjMic2D=~0Uow6Cs3nb^JbHQQ9Li|yZ4mYHCd`Vpi3P)%%DD4Z68-5A*6D}K_{pf zsWOE%E>6TpfZVTe&DtIN0=By1$x9PF5g^vip^PStfI09oSL?A8C2K5vE5K_&6#1Hr z)@mme)E@to5ZyxVaj2nY$OFBH4)~3(lju&F&0=*9ZNUFv0kKG}6pzE>b(K2c)FDo6 zBj}K+BnmPy%+hf(>Dth2lb?`PdJaN;3~xmiOm1*l6IDYKXNx@1_XvhT@nkweH7oRw z<8oXjj0YNf!JA6vER4w$PQHj6bfQp+`_(gQy>w)5(J~uR&C+RrOb0N<; zjdesfcS?G^<+IXAD?BSkV&0ti>+Pqc2dg}c25roHR7x7TG3oozZJFxh2WJ|SSh@*NU`1yh*F?tMaH&%O)_>#!gHiO_hBdfhx(dXn z^N8t>zPi4ta1n=Wj;LFLof}izejHh^=C0d?n1|Qq0KFKfxc~wDaMRaM<$IX}%e4FS z$+sbP5@=kV#s_gULQ{zyV!Z>oYBUT$H&prXDjhbVdRuY$A208W$T_ zzdCAEh&Y{|zzyZEiQXIk&^3B7go({RQM0+1^LN~M+=0=fqY5fT?xQ)9OtNyM4XXcp=_7zW8rDAWPp4M^;hRbv_=LZ8l_i+p+5U| zxm}CyVdw03tZ15P3@Te1!q23^W(4hYZ-_;wcP9yzUPxtHZX0~Oje!&6PuWI)GnE)S z%R2n2#^DTU?%#(Pw|Ix; zH~kDWIRGxpFRGLx-&xaPC}5~FAdKYTE;slqg?7aJQL2pc(+D#kQM64=qcKV#s37p! zz@NjOQMeTmRty!vJRBQc0qccX7?YH?nDoDzJU)E(`t6IS@P69IlX#ts*s~}vlQF~} zhnI@ON?yhg_-A;|Vgy^zEVJ8wMAc;$w|hNzLR zTk2F^H$kMntHD>na|xgkuiv#t^BlniCZ&QpO0ciwoe$G%edXQy8p5rwyc-^%9Q#V# z=rAGHSKgftQe=H4Z?%1Wyi}DEIoD!HerxClZz=zhyCY`qZHTvSZ~o3ijnnfKQl#PY zVqesJ0cMRRZS!Xh?tse5`7BxdjU;;Mjux7;gR6^gYap01MvYX5n0APe=V=_1o%G0% zPJfH9q|=X#P`%?U!OTDa0mWa2Ki^YMHn_Tw%T2$ip45eK#{{ObD3oP-wLh5TRYi$q z@gq4GaxcTjQ`-NVCe^P=@ncjZLnf-2*f*tcI@LDkII#VQ9w;!VL)wX%;J?+_6>eB> zIZ3+@qP|h@-oI}EOSEV9LhYy@F{mthY&Q)Ass=m;-#)@rT5bT#&=k0`C*w49rR)S=}O0S*O|RMBa65!(YW zBCh-Q^)0Gw4j-pO{hNlgrjFPTYDA~)w$azL(nQaMXW^NiTZn>xyb>DcJiZDgVY{gd zOT@&5NZT?>9a-%tbrP?D9eV;B8%>{4R9zFkG8uPf*$Cb3`1|)rjl%PzT(W`uLJ^VZC1<= zIH-=-CKUZrQ?uBW*1JAW%cj$|t+qA=Sqql@X#$3B)J_ttwevKv=qZL*FHGHHeSU_j zCB3^vH&uPgvYAOpa(bYH)FpJ0u2or1`|2C@Kz+NZ9;mI&&CNFZ|McOqb?I-XQ)ue- zMiJL{yx-uu%NpW_kb}tpTAIk!kU0^Beuw z)~5MOmwtn7Pg;*z`9Pw6NH;vw)}d;Yu_*$@x-BF0=E_TmylF#mH@7#xHIjU;nPnr& zeqaI)t-a9j^0v)i56xeH{yK{n8Iumpfd!`hjhWatW;)+&K5Q%f=Oe$*vuyt3)w67F zZ=DXTh)K;c#t->XAeMm36b~a5>BTA__4{CrNdMBDD z7jeTanCIEYD>wRoT?Kfs@$B6iX14qj!V<^1+ew*6X)%s-@_UCT*C}7jCwVlo{oKgC z|48fq39U0YkU)~9Z)xc}f^9oQUli0=Pe&Ao9>uN;433_Z2(y@`4J_@87&0)G83Zr^ z+l6_a&Eve}G^%LrX%av*z+4PcJCSzO+ag^UUfin1o90B-d7B`D5xv64{B{1%IM14e z_i&|>S}Bl1dF%*p4V99D>s+e(YV)yGFMsi#(c;(!d<4mrsEN!`hQDkBc)1Dvk-D@>#?nio(n?n#OJdYI-X< z#R8c}nXDo`4X1(l0N65+$mICEtu8!A^WILct+sV%Sa*1Q&Z9xy3pduj+9g}{zPiv; z5{^H2KMn5QLo?!r?$THxNXYOk$Z#thup3$vBTg<;QpSPms?U*89|qQY0hGq@`26It zV?SDQ*koE6u4Y%AtG+si5Ih)d>q5-l364;S=POob_ULiwLQ-oAozYeebN8yW5eofq zH{N8^WO(J=J(B)8X+=J?9otm#>)K6fQk+G3JZifik&ZJ7LcGFcHd~ZHW4%mL$R2c* zy+|%%zY=ESc@pK5>U{_TM6v6Xwvf6fD#H(!KwV%txG%q z*h$dhjs&O`Q?`oaK7k=YG093vlY>z6F|(v7kQsg)NCczj8x=*Imz;_0SyV9f(#+!z zt;cdwR9)i`&O=7QVIU9LW4~rn9O9vZJb?Z%!hlL$_oOL_qW#a_aOlCSyX$}GtIh7# zV?dukO%=aZ){SBUEb8Up(0l6!2P$ zm{^8XX-(k_q2eN+R!Yg#1B*>E%d99X_0nul(zR*_?vHKb5WRto_z>K&?nRVe@hbG) zA_WYB*;CYwqhF|0GwPaT%LV4xP>m(HfuU>9;KR~0a2zT23dn27rl4aq+yfE@8MA3T ziH28TYn*nFxr_3VTBO4mqFTTLwcHSAOA3F%3Bu4xI%zxOp^b8!18tIKYMv!vw+w7D zm@SOXVhql~T>t4bp>Y4%{ObNZLIZe9^>khAw-k*#IjESWi96`%(;)j+3)a=DSy6`T ziWEyeo@MJcQTbSmdGdIT+IHA=s;3#}XI-;035M3G4EFn-T(e!(HUZ=jj(;U9wfzmV zX$}pv_Cv&!m|Dwwoo`wzR->hEF;U!W)}H6lWER!EykP6gynsuoJM_GkaA~Fhy^c&u z*&z|)FW(*>S=t-rUVNwqMbKP2<`y{fhzg+4@d9ZhgLpiShb5FGV>P(zu@bub!CiHU zKIS~TCV06Wk_Z(qIWtOu zS|xaGepH{kG%kvMrKckSul$6A zlYtTZ>Ey>W9=sHqZi)(Z8e<49Ee>sKak2fciPQkGJCcg{^eKQ)p6%~FU9)bp@#ghm zsAC=U@ZDKd?0=k3lVMUK&(1FLtyXA1$#9Cdj>#^xTCCrTz+$W7Qj~p2TCa9=2Q+E3 zEnphaE#$C`awfbqwB;^iU}O@N`Q52`R_f<8&yx!fRo=COES;6y$F`0INUMPma>NA& zpyZCnQvhQmCfntC)b5^36*{=Qc9wiGY9_gIf>oFdlc@DI(eSf4EHTE}o)GAcnrlEQ zp`Pl6WqL1O`#yzP5J*&H&FHWb) zFwkkY?kF_zM5}3>gmI1s0|wP_YrUGrNo&ceGeFZ6Yc?1HXGRVl(%xSJ`5LqfXo z)!vqAt*Y2bKH~n%T8B}+clHrbAnHjp9WJKi<@J-1J-$fBamk6yoyV{lgvig@=`|0u z4(69_z%p5iFG&Kvl;t}g)|KzLjO7yXj-_^@GAYJMj4tEZqLliU%Cv4N5Yn_V)0y!| zNBc6UvqB)D<^~}*%Y|kkKz%Savwa(COrvY<@9$97L~5$0C3nGHJIy=-+o2v87S@4=WDr&Bm}pt*Q{0oJ8f(PC^S(Y_SEH>+pIuAEFJMBtxOMeyF4 zU|)fatI~fJNkOnp6SWjOJ3Dm)g`Th_^ZH&wREK`dqK|v<+m{F+9u>=Pg~Sjwr|1d8 zokJA?*pc6YdA=k;GTehUbymgyp{h7Nz@aaZ{|IrN7ReEV57doDci@;nlulG?Ew&GA zDC72UPR+Y{#|m3@Ty~PY?ikr?D}1Nk8E-pZ2wP8yI$UE^6xlF|%sUZU37w^lI%|B{ zgKt5QQ4pf$dKycMs(Cfb_(<>k0Obij)V2;&$?GOWXuid9MILO#CR-R%}9N`SlxQOXeB zR~~X{GfhshnKb#jt&6Xm}gU24pTFR+=A+qT+vqpQBiBj2Gk#(g%418F!}w= zH4$qj>9YXk&*o&-jO=E~Iul5u^sI(|phR-cn0ie*+Pe27x|_0N`=&49)%SYpFWs%K zQcsMrnhS5Hm##HutD$Dl52TPIi#DFANf;7ppn*CLk_fCTIICG{l~i!{muJZtmur?~ z65VU78Ph=6&2-1fw2X6|!P>Dpu3X1E5H_}Wu!S)K@qbM9>xn#Gp--V$_cht1>$gYG z+wZ;-56uIqu342$rOh@c;3IMy8|#~f=UqP{1_ z4gzV`ib|H5P4*4d3B}ab)5~qGJI*UKieb4<2yU2kP&d5P-9X{wt#YELX!t zj(*PwKFOHsfy*(Q0-D}_(2rU&i;FUv&2>r7nl*>67c#T?Q(7r1;!xaCB|4x3U$$Y4 zT5T`2G7DQ}`J-GhTv~e%!6KV>t_=?@r8p_tY^7~k6S=2d)74Az*c(GKMRd0?MU_1! zOJHw)Oz%MA#)@p@jmRr23z@P6Tn#O6_635jgZ--&FfXIB5-asJ6 z_W(fet4H$_>S@(t-YK&V-dm)z+ZZ(Vy%aIMzva0a>=$Gdgo4_z=oQU)-Idr}!aA_5 z+*$!68$Qgk^Mvh&t;Qf44zqkDtalE6dP2@W&tE=!4emc9Ji8o3>$0pB{F*56^oKOq58$tAuF$kH3f+ji6pf4$P=WHF4_pjDsBO7?B%u_ zQQ3r*Qu$@;w~d!e0T=~nyIK{zC19-|w8JGgmZd}mHYD=n@rt{{TDuyqOzW|i(h|eoX_*PH0~AnevtiJ(N-}>+@F%{kK{LlyPJc%Z3OkTAd*$b8<{s&JqViES37LoPB-Gr&!^rT{oC~tj@eK`9hZal?mp;to{v!t zzK4y8BwdQDp-m?lchK9+JyFr?FAz7?D8=L3^^QST-Dk2&J)3jhY(vLwe>Ls8iL|U+ zfM>uMO=}2kXG{OOQ{7Wbu`i1FP)uZv{%*P7jv~(=UXSjr`YX*Ma4t({1GX*6PzleS z?DV(LRDf-VZkon9q^-oC*V3b?ud>tMtkBKw{E}fDY$rG~&kO|6P!dfc*ha&D0Pn!4 z5Ki#)x9$ZBwYR+XI(J|Z=hz830I%We16`KO+FhMg(IG3muxl0 zA~}&}dob=Q;d!X;C2e-1ildT?qfg(fnW2_B*RmHkNK`1i>FJ0&*JT;n)YjyIt z;@ujwtr3&t{1VpC+ls|1R5b?b6i29St3ZqdrW%#nupTYCMaLRQ2Dr$FXp;=GaPWO| zEwm8(K=y#E%jhcTX(X2|Vu988WXalIjIfiSudu4RZ@Qv}2gG~Ar6g-1U?9t@P8nes zQE>JkW>xHzHqmJ=z>-uwA9wI5U>BZ`JFj3B_@RX&oK$vshVC6`{>d@q*^N)f>n$&50Dw}E5r8%^Ax?6tg=x!kTx+&iqvd zv3R~PSX1Q+1`oN;=XC|53fP;}T)3bxgvD@WBrPM>xZ2VlsNHMTRA6%o=)T65B5YIf z3#9)hV+zDhkHZabLIwD`;ewW#RNVgESZ-sn0%y{ER#;mEWO`BvWTO)I{M2R}DSmo4yyA<^tenk})R<-Vi3~bNn$HmeZ>?YwaPHg}indf|S## z4hVfZ&VI`pgA3s+AGkHbKtIKE9r(%`&Ao(ns8~&T=L&mL|ir-mojW1>qj0%$XcotB;n#xo!(hR&2|&81-TA$Y0J@rSXnU48re#&P@`7Esjj6~ ztq-)ip0@SI$7yTwv?7?cr;&s|@3!xfQ09S3<4IN~@Bre^C)xZehpczaVM}dqZf&dQ zMHCIyKfCI1cs5fNc|L#;yf8<>L8oNc^0nK+1}jxMm^0IlWA0_Cugu}*&MLP zFUhn(-1c%X@eXNp=4TC|U#gM0~gLycUD2|g87P7WgVzm*N z`iN=@bgbL_wy^_n&tzurYAGq06w|XR6FXo$4<5jE;oVUo!yVjDvX%&^AAJs zKv9CTj5r4JVBZM=O*j4+51|DiOG{?8WQtc_k-O_y?Rblx1t|KUcGQ;XhKjdOoHLt8 zc{D3bU{82!N8EQveXMNS#YQs!7+X^xf z-30Hdyrl7{_LgFr<{eIs8<@*+a-yf>T+)KGH8=Itx@fqJiJL(_YCeC^pFcRCGyOS( z05qH8q{UjH!sFVL)D`Q_M<;UUBSPYGy+f+(27IWVN`d=K7Ya9|tNVAH^bwkaB`uw} zQhm}_Q%EvokCgoRK|@s%6x$5XRUiithB-4tXOtwnn^<6{lhK(a`>K$6;;I18ucKZ~ z!Qy~)IaYMvYKs*8$ClrQw&5*!v7D@9``fK=!DUTtJ?d^lG*`_X?2tCaebH*)ze-L7 z*w#L`#9UhD^`q1Q?qt|s3#ISVq(JE!Fg1EhoYN8Skkq#(#s6JI)1`a0WM?FgBEk$6y@Dp5}tH%rorcC#ua$ z5y*f^cs?P2OBjDR`{G{QBrd8O64;2!I`nyJ1mLehZ@{q_2xt9zY}=gJ6*$2Dgoegc zC2%{6RmeilwHdY5DNjcSWI06?7viYs?=m_XR#Ntj;qMFKvKum7(P(!4Tp%v3B^?^=o)!61}>xTWHzSj%=U%tiQ z#C=Yjw2W~vb?O>^0qdf>`AWQt?(X)?i*9*a?uF`{MaAb__Ha%FP+1UVc!%5Pn{c76~@wU|p z5Mz`<$_{UzNo(Tpe5~|DjQ&}>G=nXe6IYmR=3*COtT716aLMYJ?W)~32Yn|^YombIlBxuHZ{ujBsnl zRNRiQ&6z&_@5P#0(9?f?DRXKeW(`U~pR=L=%q;#ZFsRkZ{P*He*FC7}eyq!*nh~l@ zYPe_(F4bJ_e>I!>csZXM8w$x|RBI6BDo)i9S9PpvEf4Au1E0@lnkD_AjOM;WEc{WN zW(C!J8LR1R%~#?z&AI&#W;V_3z7@A=>54GlCn(zgeMy- z0)A6>6XZ7sgATBq&E0;-GN7&9+p(Z}gxj;Ay5+xEfi~3>=7+?a#xj0VH?8LsdQ!QIZ_ zuG-*!#E2m-=;2Z>=;0rtpIeLjS;F$vb2hX!eg0RIbGQ$E{x{6(@Sm`Sef<9|6muH* z)_Arw$QXJ=xBV}{`cxtDw;0ni0Frg@;i;g=o- z`6apl>-MK)hugspYo`|)$?b5fw!{Bw+}zaAA09VX^Ng(G<_zg_3&rE3+bABr7yA#= zJeqC!LpegdmOqvwtYF|T;|QIt`AQt2In@8b9HAlTZp9H=$}P;9jR^(+FE{v~&JDhd zM@e*aHDAgO+Df%ezkne${nT)TJyJsUn#aFB9t?`xY9w#Z1uo)`@uNgRI{9#oR#F8<+?nnZnk^cL_`X7GGfm@HbJCTL1_#g3#wO zHZV$nrh!_=zgc$zoK1X%5SZl0nD0T3rn=sijDFGU!6RUUxk6aL%RHLTL9F;; zk(JgNgu8*9Y1rNU`|yupJ_mOj`qM=;)sWaxTejS4-gcp0w^*DOW!~IsE2qV_aP#d$ zk(e(W3$A&!wh!mJRNW^wfwD}`^?4e$ikR>7`09jKy@*#b(*RF>{J&wOPw5-~!Jnz` zKL7j0cCPjgukq@e8yKYL{!_VWcOw72IO+Az$lZ+*mL*qRWf&hjMkB;! z;uL+hRm}t6U7q!k!?N1GFusw90l#8+z9^v?1dBXQJTM83|JR!bV^;CRz%LdN;B~c6 z6_jY)^}T>3Qx=2gpygDW=K|Oy#j9}*;7jB{f$;ZAh!?HyOLM-Wk_KZLgN~#OT;O>- zdjf@J`0g|03hni*neBD)B@4F{C{!rG&oO20Ete_O%MyBDMVf%y@P|qgjtuhnqofGS zpPk!_5zL-^B@qJR(Eq{W14NOx5*-k^A7gA|-^AVpMJb zEFyR@=;WH)fGx1ACN&W6Gv@6v0&66T09?eQjPbrzv#G!Hm>Q~pX4ZG2g+kxXmVrv_ zePe?WJ67UfE|$i6{^AdTKT#2~4@A=gYp|Lq@wggf+U$bGGVB_5gw^kPd}aQ&bUo!+ z#HQ{NiMc7tTuQ?IGR;M7I@m)o$0I7x5F6TB*4-r_@sSNVso5&;<$+8YnS7wu+PkVG z;)@NnxLiD2PfV7C2eFp_qyE6zhqVvQrQwd+nr)Zl{=Uuw_B=@*aZ zF&s~@Y2buxJ@{H#l6Oua-fzV=I1};LBtt!VjF+h<h}% zYtshb^PN+TH5=XDG&$|DFA!K2I4z{hiPuEib5+_%vmvjI)+1EfII?B0k&#(Kt1pyz zzcL3|6?EG&zoK~EQ6#7$QEtMU=vYZ2lrYQ)ph{h59PE(`mopf)a}$@5U>gbhCZ&$! zQM0kA-l}k*@nxtt3H=zhLWg_W(G%1N(KhbR^Q_#RV{`1pLD|$m!e$p(g|6o^)L|v{pr|_QoGv~2&Xb`rBAW8< zp*y^~{yx=KmZrwW1h2AnG=rCZ8$Srpwq9^xY+Bmda_MA}-Q4o|Rj)%(DWH(*QN3I6 z?{lAnVLH1-!X{u5FgK(wKk*k$9c&37AU~QDtq@;til&mW8iw!N_EVrrBC$glAi{{%J zcVqgIMg(8r^{o3n*xnA$*23rD^Llxdxh^>razys5Z`d}Wem&oHivLABv+oL>@man) z|CV;Q(#Ke4ZwXsZlOh%rg-2?D}U8TEh-q~gWsR#9%v}0 z+>b4#;KL{G8ohtsI?Ncb?^i-3m1L}UHT7Rd4D-xn(xep+F^=EbkFyPzMv;JEGR=r- zPGR~Hh#2HVi7|G?ksAMm?1lLo5f-uBnKenkyy_%5aCIT+{D!+Cvz4tQWnbz96Pz#o zuT_Wwy{K8#XUavYr>LK!fIN*p=O;--KkMhd6UmB zVzJ%a>B&k{t7n8qWA~m?=&PE)3-w9T42+X8+z&P9*K4?^MV=7p0s%IVq+wk+@pE zBM|8yi=tE(F=u+1u({X#b0?t^F8*jz{8%}xvwIG_mx?&17geZfpl~Zsr2>uU7?VU` zA)gbT+w77w8$+_iUQ`Gevlwyak1*A9#z43^CtfpoCiOQCj*g4%ZayRI4eK1y5pSE~ z(JQcOtgF&y>m3%1g!x#s;bgFEYzXIj#$hB_lcMIE9N>Uky|a;*hV}h{%K-@Dy3nvdsR zr@exb4|#5Z0IOYXnZ#vhMO?ExD9t|0l4k^+{h`Au7AWrl`GkZFQoaRWsWVZ<5H9N8*oQd!!}~Q2`)9MBkZsm6a?di>zPN3t}YPTKU6;QK29Ur1PMZR0x9e>;0}1 zuL}R3@PDRarX~S-G_O-P;<<~o1yt0xn3$`2OBa_`8@ZJM7Zb(ugC^CLx|0z&J)E3x z``i2D^z*FwSgW)UZo+65+Wq~ozg}uIc@hVPk=H~D#JV{?YDMVPV~FAQUjQj)Ul#g{$*SSVM(hTH=)H({lY;-2(X{uMj95j(!jYnWk^h9#FE zHL}YxiIiE3@Ou4IzHd;DH!8_GpVv05<(D4Ko!vgqGF%+97vqK;V-eTXywWF+Ql)8# zamfGKuJbm1)4$BpF0QOds9B^#rhSiXi=f^I8)uIVEyS7Gm7&JXboC261hYaA+T@1Z zjc@}?nB|o@G-Nm&-&EJu)T=WUaA^MlR%uR4rE6j&NZ5aNYf8W9jx4sw_JD%^(AyoI zM*Gn@E}k-lS0a9Yk^zfc+S%Fn=f$ug&&n}Cl(x=&MJ>%g<}zqBL@wm-a$=9Bj-O?A~PAeyzKenf(rdi1(Gf=a^zpl0YwXk`%S4@Zpv zIJ12B-B!_vz+2kz}Vx1#mlF+Reud-8ThM5OMBwpjf0O$1Y=2IPeL3(SK z`JA-W_?@O1yxu&I@K->jrNfHrj@xT8gMh_VeNGd2T*dKa>q;Z8w!UvFSV(Xs9fy@L z5`5BQh=+rs#lQu{zDNfJ`xp}1i}Z_*6;iVKa=~ksyOm08GD{~sleE6Vr6qP=Aith@ zqT)daPul!|d#ZYomkUe#=jl9(*;ct7n_eE@Pxnu~w3fgI*GkP3mxpnm4XGTU?YLA% zQ!lM=ZCU}stx!OfVQJxoY#3J8xZqIC77?E}%cOq6RS#G-V7%*|js;yECD?SiKH-v$ z397_sxWo@NfefE>E|Aa)9Vk`pfRZ9Q4r1w9?2e%h1wRY0XP8zfQn~2A=LpuwWf?<{b%;yI6Pb#3|k7{W;n60~8tdPV(9CWL$#;vrAe$qSN&!XS}HQ z;QCLs%gm!uH;TZSi*cn|=Lxi4P5SrZ^0EvK@>!hZ6N_!mLqFpjh|AfqJSZR8N9CMz z{-cNJJ&RlRXd#KaY6pe2V%`6kVfjxd4W)oD;v#7rf1E#4QB{4e&%p*zPy(2WOL9u?^^ji{oq50Dy&g{(mIm40E~^$Ty@AXy%w+S3R6?|TBq5THssRdXl~t>+bI z-?>=={(DS5JlFL#8uxOLcRu;;Q))Id3sg@-BS+e=>stP5=uLRw-(>CFI;ZC7(v_XO zxW6sdI-5Qt{H0wTlc^E!fA8|}qM0&!%nIsgTB6coiYSiob_t=jv-b659q-{VDgm=z zD++e8)e@Jtc0Af`c;1nhoFUX@F3`qEQxU}VT%Tq3fmltvr1WyF2B8=8R8ZEE{4Np$y z;7T~h1IwBOJ?9MY|tvH)OBrVQtCzV z0+pjR^`94oDT!v2iJo;Awe1En5qi^cs75u&swzd3tzBiShG#&+F$s6BKr`FQszrc* z^Qyhc!p` z(hHmQCL}lxrQN+U`v6BK>+8Ra%uT|TYj%AGZ)zf0 z?iwWx3nY_}j-G{#H+qy13xaR9tZJ1-A0L14O`JOfQel_*DDpF)9G7#fdFx^3$9!60 z?b3ZWGZA%dX2O^>=OBTU_9>X`XE$^Z(1ZX~ifR+fXxbFL-d8FRLr6KqhJSNs^`Cn|ML z#Az-V&Vhsd13SMrdETv?ckn?G(hg*rw<+FL*WoKedvL<;XST?$WUZy@AMqYORvBWP zV4sPScz^k|)gvud#vA#3OJYf-tOnmU9WS8*=Ksdu9?Q&*zMCiQ4#YQZc(9BAqOF-y zrh0DC2KBHFu@qGErqQG^p%Hs$#waK2V*pMhMZgsR$}%gc6Iz)**rsC-`RI zBNI+d5lFh)d7FdXX4wncN{kaPHrTI|R?*&Zms+o3>M~igfj$tkfa&H*)e6Qm#;BCU zPq^*eXlapNuQnUfOpU%S{vZ@xs|oOA~>q4FZ8 z+uX+%76uC+)@&ZM%YooD*ph-4#n8q33V~kA&{1ezn$s*+bed=&Js}u%8vOprLw)8@ zDveF34q(ro^1~)VFP-OrS16fw$IZLpAkP$-34yoo&L-TrHqC)|QKFE!!#`0JrS&_M z9q|P0N#E@}Iz#VOH(hd4KNEih?r831$&2ZUhOyIF4eG4Pu8BD((S)%hFP3#4HFxQ> z=OJ93^tD--gAXqg}I1F*fX7BB0d^iLCLAGz^xbX#vfWc z(RZNXb2;~G+_qylX*Oj;W}%9fR(Bp?nTejGt=>(+@*G+x-q0e$3R|2loi$iDxasMa zz_C9vB+Uf-vCjlE1b?HI3UQhQXzgp34zQ&T=xY-@@)*e4&rTr>lt%ceH#Lv*JV;{bXzp{MAD)Iyjta|$u40Wj5ie2KRH!-lUL zVSNWj;?V=S`$r=FAmqE>IKSKRSe^3g#6*-iutB_A7F^G(^j;oxb)Fl?>*-6$_mfvg zZzAYD37K4xFk?r;<1m6X^oI}-jn9-A8j2_%@u?+RYrAd!H;@TBxCs&3J4*P{^y6Y+UKVlx~jfoZ+fm(cYz+cdkfi5}Or*I41oampUGocCwjxC(`fG zBga+-ZJW-ecUI9sJqES*<47X57yqw7+$kF$|M$P-_(j~8^p9{q+wgqr_I~e1lh7dk zS&@2Xg{!E@Y^+EW%8c9zQkN1k64q{nYKA&LN}3ko|IX{{A*`oh9&4ai*9LYBjtM2M z7rUSFdEof+s=r`5$8G{Um-K?XM7gg`5@et1b4We1i}4tc*BDw9-MdxNU*S;uffXBe zIbdkj8i?2yQUZ2yo%Ex`xk1Jf16Wq7qP`fGXCf_9=whqHdCn2YBq1A6BIerI!`^zN zCms)u4K)-0iR}{f+Zff21gm0g7f9($M|J^`JWhlWi1O)FXeJtgdbR?20|`_1hk(D` z4(+AXr2#j0A5P@i?U8EHSLi&y%@^_w0;qOgcos|Zn=1hvr^zATmFJDcD>f>mAN*oK ze`Euu9Y_FuNLnXsD8b23Y^5vTz^HtMpv^k-Qi^q=O+@%UKDSVm-b@!{Js8bD_BeF_ z$EvDr@SJ<$Iq*?M?bCK#tvlwYJ_LrwXy)NU=Gk({I7H=DY0YTK5?9A%iht0OC*)M+ zN;bBYJo)1_O{Hfe(S421KyqRoQ2IrZi@^;3r>H}ny?WeWmr_m-7s#1M&HsST--q(z zLK#nhg<-^!>MHIjdi{P!zBBE~@)Q1xbQ^}kz<-L&0-scN%f9t$5q7G033kp+VrtYj z15-J?n1Y4?%{E^#W7<)XxW4rtVODyJY(qMXNLjkvm`g<^6(wL0u?$+)G)dmLV>QJ~ ze`R8>(+IG%BrS`P5P-uW@*ijH-&|0`=+|Gi1p4Q@(5b!d!w7M4Cf(I~nM*qk#^g(0%Oaw`_`vwMVu{RLz^}IP`LJ`j7(f9> z&?HK|?=;`P5{v_RM${5K2hx-H;!s!ie_N4VdGoz8mdtuzV;w??!l<8Xn*;2eYU^ld z$#j4N_E7FWdq~PU=7#H5wwsIEovP|S8rB9O;WHz!x)vSHWeNCjvU8Znqd}*iraM%O zb+6ff6aHF(K-o&8(C_HNc84ePLFZIKz+e>-XTdQJNp)`GT+`YdLoY3}xQ^&t$@v92 zzY7^g_@#V4zoxcG0Oxa(o$J;Ga}JBzENA=U1=wz7QWsTNW;g{$eFVdi01xxJ)Wtuu z*b=3rvir$gloePi8}i|=&W*uV%GNgyYULgc8o?vB`WyqNU5Y>ziY=>=e$NH(s87Sh zD|?`~T{Im9lHtjt3~SZFdT+t(xy`K8+)e$NTB#smMH!VL|sbIDLP zDtPkpcj5n4%!Xq` z$~qa#<@7(D=m65Yw``vcobzt4ebStgTW&# zdqvr$^!@(alF$zMle3&?s4y9i^|2C%;!BdzE9`yvt>ZPUhsXAuSct z8rk6*s8OR#>Xi7XcW5EZC2`iqkKgOK;LwU?F0JmlNq_TZs#3&Ss-YMFx5}bVT zxKH&zk~nv{wD!ChWwTV}fHJweY}uHuYm~LX`B;^kmsV$gRU4e$!fKfIoILRFT@*~8`@ zFSjQ;MS4v`oAXqDTwMGyE<_&z{LgwJT&{p0zc0GtFJ>eapZ-EYg0#e<2;iFMFayT} zJyo?W7n};KPaovK$kd}J3~jF!3J>Z=HfBqQ8PefqbbEQdoSa?V9q(@5$LBj65A}3= zIX=$cq!os~Wk)YtD8YUtl;^)cdEx+LfO8xUVC%BHj96~v4HD8BEZgBOD`pQ^&8(<~ z&j~9e>g4iJ6meY-KsVA5ERKVXUgq>LXxDC@Xhdh*fzsc~U8+j_p_LcmnOVDixjh7!Aq*IO>YhIQR zUZ&+wvf^&b`Fb)#_Nzf|Lx4T1#dBc$M#S|ZGPY0mN}iF)g@^JU&E+Xn z9;y+mmjJhpNZa*AZeCj%UKN0~NXnMs3aq_Tgw^aZgGF(-0y`X;O+(}{S(k6RgE84S z{LXWeS-N@sTfjt-uexXOYniLm09Z4O)#7&~NJZtF-==KCM#ybZ;}(>44bIct26tc?U@?07DrYtZVLLZF zXm58zYiZ_cUq?K&T)u6FG5TNn0T6t5%y|Q+*RpbUqO(iA0i+^Ws(C|dK5V1*b3y^v zqhmymZ_xf~qxyS8xV#n`(FDmV1b<-dj}W^#`vMY1vFz=Jf`fh=OpN`31Ij=uJr= z4#(5*h{rj#^EwYzf8FL==8AC4TW^$g{TRIe)U$rFy9Jf!|LrWr#c8l*VblXDhYL-i z#FVVAlzwmjEx<%K@L9dw^&A%wZG~D~{C;e#`g>dG{G&cNyBj>I(5AmjSi>=wG#B@| zJTRqRC)L1qw$w9k03LN?v+DnCs~B;J8NnyB(?0yuS)l@4$q8pLpy^W=`}$&9R6{LR zJ0^n5Z50y`VWn@t>573QbyT32+9ucEB^^)=!gCOr!5;S3Ro1A!U6+DDif7SX>bQo~ zC+Qe@AO&)ao3(REUZ!lbp>MORa&^@=CV%ew)cO&s}kQ2-I;s_rRE+Hb2bEGRaqUCYA znyGZgB_ieGYDMS9)sGuYf_98wGK5pb7jPv+kbcUjmba7NxSa!Nn|g9q21J5*va6YN zP?!c7Z=`vaV`Dp%NGLP*7H3%epWd=-u2gsTyr`Yn;v7 z8dR>>LDcia^{-SP$`jP>cV|d;4zgk)~O@-j&85&Bf z^SPEq*>bT5iFvn9(iMm~*rWeNhDQ(}682pZ+Y_p3PjhqbiFk8xaPKEHFH}<9l`;Pn4AUT!&i7Fa=%3@;9l2Y?w zjLerW@=XgM__{pMI2eVWY^mFZ?{pabyE7s}@s&A0n_H=ZTFXL-z7PCL_oA)s61UI# z)~9%>qQwf+JArZExi z`1A~c!PnydsQ(4<*iKY*J5N?4A<(M+lx_^YY`7`rqf^ZOrx~5B|3c>A&BnkfU$@ep z?7l~Grk#yW1-MF>6tAEC@#0lir9hfT4Hk|eQ7lMr{Chm(Yq$e~!bSA|(Wtr9f0luqJhM+h4{4B0~Q+;YxwFyKJ&qS`BSZixVA zg_9IfFHC+6IS_>w@F^MQm<*bHmLd_j2?5k%c14dk$FW>xo6hCEeS*oQWDH}^adn< zch-X4G5qywGU3vx+>HPA0H#9<7lJ*eOKq8Xu%7kyv1b(Fl?YRROcA?2*H(6uV}c2P z{mM26Gy+QWKDaD7z8@3}y#tVQMlgNEDRn+tL6L=M5JHpCErG(|7sNssW%RTM7lYPq zN7!L=hB+yQaRo+fQixU4u@MuDX34Vyg;F42-Ch<8&CQiI#B^eFUv%4_}|q;EM1nD8t-{4nSB!*Vpn6purGOrqVGg^3O}3CcA~ zJbQpM@`@wYT0&sMa|L=r0{nX&Thr69G2x3f5wGujMkPf2Mh}zG-KpWQ744a)g zr;zxotfmKL6Oo6;WEL?Mbh#+~K z2@cJTX2R;v-v5QHAYrH`0h0k_0Ue!ESGi|sDAsnV6z=td$RKA9auDv+%}c zPe5r2mbEPm(qraZ!P^#11SalLijlgbM9<&+#zHaY`|}O6wXYCQBzI(`d!aAKMUUBz zU9BA+DQ(5RWEAHqsUJdmt$sVp04r|ahGkZP9(eh7C-X32zFoq2fSK|rIg6En#aq50 zJSI?Dds)P|87aCYFV|5MBxVZ7Sd(%6x$ul`zR~_I=Iv{DGiPJlDd7h)=m{g{I$=;h zM*na?rN(A3opFMlbne7j_Tmrrej&P%(a!Wf6Ym6RYjkjGjOCdnTSP)=AlA>5q0`fT zL_->m`|1%Csa+_OVj3+)VZUtkni1J91EwvN2T7`HBWE8N$qaD6vu74D7+tA#VpduayPoBJxBfms@|K|PM>Q$vjO?;TP%?tj z_g0fs#jcxZN|Pl#h(q+f4^^l5ux-PDmfJ3qi_DJSH{|iBG!&P*{BJznVeJ%0NPP*z z@h{@t1YEh90*bgYL8U^P=~5SFzvG`u>iT;-U9>3Xe+W;;_(LX~U=L6JrjDiacMRb9 zlSM-pthMuPXjB-aXJg*HiU6E~f?UoyA(0OBEnHp4LC1oPs&XfqkqzesnRM}*08?1^ zgGE%puk$&Rog@44UE<~_ZP+;<9<2wwZ;Ib{n5_F-Fq8UI!Io<8Eq(ijTkvQVtI&cL z5R=PSXzkL4M5{h8$7Yn_FJ`gAr1tP`Mjl#h0r4)G3k}9_*{oS)s&J6_1G?s52?}5Z zNID}@VtM-2@Ky|>7=8a~AwA|MWFUMA;eh;j(W6~83Gy+#4GoR5V5CfBX|&~gKfux7 z28+!>TrouNVWmz93?aHA3At$?RJ(#NU{fD^`_#>UBgZ1 z_^sHu4THs$?!-imUB%W&JhkmO;F69o)#zG^Tz|!2&grJGm>cGC{I-Ob5Q& zIwsS^-;+dVR(2PZnMzI0<$&H&Xn#K3uZx6$$0a_mO?`&JKiML zn8hI@x7undIFs{7bm^+TRGGI1G6FT(b{Y5w#E97dO^s2V32QhLSG(q9YkHk35qkTn_&x88=lxX|jvOch#YlYrzTpY+SX0BpG@Xhlun5$W~ zn66heDsLT%fi@-w_{tvj?r-4IWO_3Lb~I8iG?YuBTIX#uT?@906H@aoxk#*`|IDysE_UpvKa>^Q;5Pg?R|W zbXO{@U2llvH-bYAC7qzUIba7%+bys^Iyz+Jw}1V|>X$fILw6o#)0#K8`#yE2;%Zm# z$;+ z#rAJxlJ!eE8Q{bKhp?Y`^|z&F$!b?MUcDbgsRRMk7~}9qd8=T2yue*L3&)$GB$r zToE>1^Vn8G1$z~`-6%OqNxUa570d(8%6E(LN62&sKs9qokU6$`qa_?`_zE1+_TVtS zsi)9B{}|0<^*uu8g4{R~FOZKvoF<39C$63I_0JWP`|^BHkdG8G_NV92)>1WuIVqW( zhAbP}vpIWUnS2hplR~xZYeS1I%j8`l^(wE^P}uJ$BHsm`1(;;JyOaksh|lz1BdfV& zK{%8_My$n82oudMmKDDVRnm%P;Y#`g?KfAgY?op z738+v8SOdlX?2K#^O?fGW@}z_+*$uJ!3$Tff||V^iJRx6hU|t|aK{-EBEi6pJfte8sXE> z%^+>1z9obsm1|^-#_<_Q*_rC$iQX4GizVz1!0z!q3oRRW3LP70OV|OO(Mo?|w0m0w&v@)LDEv=Dw@mm_ zQ;ebV-=Kg+nD?Iw+s+Xrp=z9$I0ddbGj1qjXkiV-`0CJKwGdWV3wi-`Y=r+fiDGd);>8n|#7V2wqH`fX@)V2yKmQeB*__uRYTd$%WCgICr&^-t&g zLGiG*7q3zn_$iqn(2Y@5BPZp_xI&kHV!hytv7BtT%(ne;yD;a13}fq!OQRxN+~=>8 zHp4#0Si`5WlvtqbC%aU%bl45AH=SUuiQd_J(WSZK#~GR%)RgA)c5$xfqFbJ5%t<@J zZ$~b7{wZbk=hu6`d3o_rl|utaVcpC@VdkY_m40}slSWH4RLfGn4pV;yxjd4E^7TSjiv>rYG6Gc}1HBrEsyfjA1T(CMZu=y3>xTDBBc zurBsXCnxo%Q=qw!(m5;ktnuaZXl{PwRet|^JKi_I5VPi+KyS>aQ>y@C`q}E68FT@< z16e1XuXjR>_(3mZDf+2eaEE{_#S zoISg)(cyk%)HUq5F|59+m!I#~2Ho$un-ay~gNk~Qr;Gya*z`KUy!r++McXS;0G8Xk zk{sOWO~AgLli78K)NQBR!LS>y8qoL_`Xtm=DYZpa;;sA38iCv!Gnhe`5^u9l%s({xx{t)Ymjts^zt233=^Tk!PzPsu z=idna_yN{ZkW&G>2cIi+PDrAUjQ7=bYYc_=y6EwIvf#ms?H{Aosz<%v>L}p<)%Y&2 zZW+y0+MIc{S@vnXKDl5(5vw_**<~D8aBMZE&-TK&8 z+vN$E_SEwM)}}lFB1!(>Uuyly*=Qg`_88eyR%Fi%^)zf8aPM_o^?% zD-+Mfi|yG|fWI%*LUWHV`7Occ4V=$Bz1vM>UG6vZT~+Gck1dtUt;qJf=55b^x9j{Wsn|2pyXJ`KU6G!+cx(na? z>l$R6r-oVTs`4}>l!Su(O6a>K>5e|R+HLd9W)Agb?$IDFUEqiBjH{N zE%5u!t-ww07>=%qeXQ3Iw?h}4IOSY8V3o+YeR>I5J7Fn5a?I`ke^2ay9qgME$;agU z^4(A+$)czEQkHjLi0{n*zCRb;Jlk6Qe1UhHSmVy@dLr54`0)68M1gm`3JG6kK zKDlkSnB&_~5=6?;;SgV5Cm5>D1iZxa2qW5@Y?XKC@TB0Eg5XFp0?qimh&iyt!D#$0 z7Zxm;z^Cv(*}WP9MMnz!uJPP|e$-Ip5^)U|_Vq4eBBVN*pTc zGfFZp+_7)HF`i+$jOAeL^MQ^A&Tc)o&lp@LmvTjTk7OfD&s^o?K}_S~!!&Q&yvil{ zG36Hyde=M;K3I8|5c8xZpuUUVeOeg(Lilp%rwuT?+Z82|kJzQQSu(6k>uMMV59PH( zSD1397!Vy>9Sb^CG2#F2VnZt$mlZmpx*YK%V&?yx-f3UYvCgn$-$fiNr)7l!L@kX! z)XTxUzH+;V2^#8|quo77a(J)Htv`u&fH)L8j5A2eNB))1>_fN>$UGR<@L-#dB;67- z&wHy-S(1E8&Mx&T4w$Feb1l$kHY&;KsYAt7 z%$c8i#|1PlG0HwE1pfxV73s=1{CZv9-7_cb;1jPE8osyPh_j5~z6D4ZABD2bQn_Mp zysXSaxLz6)KFkDk@`>dI)0Y!5`LSWZegfU{m;OB1vw5N|vo8fycL7#o)2qI!BPGxi z_I8>xG;+t{oz{AKojTng=5i-5Y%%~t#>Vg73Qj#y#*kbzZ{XHa!cpsan{{?rjdEv+ zl8XB!lFFJ>sddMF$9Cm!JAht`+NsY8(&}l*O~9nwz%!-&*Jep*wE5B28zjoQ0o~@6 zK~X5gVc6%|$>Uq5w4AHYh{Bb(<#ejs;s`tM4Yheinw+ok1n*0%j|mj`Mx|M?Xx}OA z%mw!rCXA&@?0O**wetO56aw{kFQzx|aNTq0bS`Co2E#4iH?o;$6Xs!wHtN zSw&^??VGEeuNTW9pNCHwD3Q9TMl(CV+@=8hT$ik4yxkQB(5@fTr~{W2_yq6vJDPZK z=|nwkDyDi?BueGnxsOuDrj&Q!lRuGVo23XBq;AZfKq{{zEf^=^56*=aD=*A5$SPfPf$^t`Zy)e zw4M$-bIwG`u{3l^i}*X1?H}NPC5?MrF~8AnIElzrLXw%I1VSLx$Nz*W?-$ZdcD=nx zQ!;k`K3vbt5UliCKMIm` z6#PwTWRa5wxvVY?J5HeI=Vz2Yjvm|HI1iw=-seqC7{{h&eN7pqfwZ}Y=a|-uKqT9`KwS(EWaGr$oC&glDWRXBu(V61vR$AtzcIlv? z_DPr~V4$t$58mF39pE-*z$khq=WcQu+Ncc#R1ywV4wCy&)!m_?#>2%B3k4tPzE2-| zl|NcCT@5S>A7Wj9(j+8DeNZ$^8-d@oN--VKqrEy4L|^pl;^Omqf3g0(+g=}^U(YOL zzcVYXmG(pgCahSdpk|zYO2AQlAlhw+^%s4<;O2N6-M@!ia!N?58-~^H_(@VJQoEbP z?|I*R%+32U@J*L)MC2F@S_%axqxrtLTb^Iv9Bc(IC>$#ygVN2PG&&^4!-i?J3EN3C zPrDZ8;q!dI1t*`zQx^5imu#K?I!RsS$L)D{I~%;8rT_CU;CAtFdcOW^VqSIxyV>qr zR*lTRM6=8S;WPGJw5aZ+gbK&RkE zyRkwtaza5_p6Y?eg2&4DbYvJ)PH_w<07PHZmK$r^C>*$G!uD-Xo-$W~U&;U$hC6Dj zl*ub;U7Si~&L&m_MzMe0lLS-|VTs(nvq(ONwQw)Zmvcnb32iX%Rpb;-u>vg~p*$uu zJOC@URm6v!31yf5(_kKAjGcO=zq3_Gi&X44B?+t;Nj^us)KpwR6G8%>eSopIvRN=1%4b4f2iZ+aoI)?pNtsH7doWFDPn(MOTNHM6S& zld+7oR$)lTOeF(7#!s)kQgc8W(PG4DmItwmlYfTZQgGUGVw;d|vBW)t>*98C5>5dt zHWiFX6(PBf>^6EUYpdWtv_)XROJdXBe$t0Cgu>s0fWp(p!{&TCv$#u&FnVK@dJ0mO z=si#>kbRQyoaV{jH?7I~?JFc}ssHnQ9T z`2qXEG9g9MU1m^~17B&_QFcyVX8VcqB+pc9?-8)OhO6P`4HaiE+ zgi1s6a6P)qD0}K8xhe=_@=B2<3!>-RBP+PBkcvy=Vfs+k|DQv05@%`DTRT&nT7Ay`!octl?iEKesg%VD9leX@lqm$^G*9|D z#8BE-cE+V+BLQ_9+fEACwEycqQ#OGM(?b8mfT{r!i+Uzi2HkpGPK9)AfbW6V8}vB5 zYB0fALrsE=i+16w#cZa-AMve9Qe#(lzq6*yiJw~MQ{Aqxb7%ay=c?wDp#%1MsL4i* znLXBZ8^g`@8?zvsbM=jcZx{>|SIQkwT(TTqJPw^oreu2r=!xe^M)H=#XdzjaNNjoo z5D?LDRDQTWOt)$foZg`PSrnPsMdM61N~|_#>T-JJrnriWZqX>|7j#7cIuU`NCAwX(8$b@EcqQ@-J%bqm)6e^< z9=XXfu7!dZP6I@ePx(Jz_ZIEe(uaXfBVwQPTh2PPt7}T`OZA*Z^RZat{P>EZB8>s6i(F{8G?CX-~TTbBP8du>Y`L`M~u>asDc!U>8 zui?~jjX6)64w8^rNb*diG|LAy|E$-dq7&KYOXvF3FXa70r6f~oY`6?oO$^QSOe_hj zeDYJ)oWceg9gifr77<83Cwf^9;$6h2JPuu83|)H?>rPC^ z(%KAI$~H;=GPTFI<|P9-r~83zVx(XL7a6s1at+|{!!&YU)w8a8 zD4^zSUuiH42mseKLjWKr23f?p9*BJ!MIe~%AOZs~P-a?r5R$a&GNlZ)-a|h)g~mrh z!bdmwm#v^Sxfixz)Sm%-SUb0!6<$3b^+sbItW*iq(e%G& zGO3Qmo+$KS?w0Eu_;*jQ6D-y`c2a9e+GPk#AlH5W9{^lHqrW7>=~C5jzQ6!-qkM)v zvuspz8|;(Z<`c)333q8YqRq8aR1(Bv?ei3T`pGWFlQzN$vKpd-M*qTI9$F8(h@b zpx7d5hSV~kh<`<6WQ}pfM%5fs(_}(hTy3()-34*4p_%3Vd}a)huD+XYf?2YBxxq)V zOF(?8+P@9&HL%p#eiKnAd#6OnyybY@CZ|-E!gjcxZABw-oX+BU2X0QkV`EEmwC`XR z%&HypjdRNO4KYPAb4JtN6K5*i`{(%xGG|zVF+=yWfHZm`7xlibFxv*FZIxfHW$YS_ z;-Fs#4O%nXYXEme=?490*iFa6wQ*XrO4qfqcGac+78k~Yrc*xb@W)-)LyPkXTjkLQ#ZET#=CFEG)PLvhn342?-3|z~uwb^FowL_8 zT@tR2rZ&1ZuQywk4ZrotQe!Z7U3}G#c?!|w#bXF7M})Vqx^T!U7;_N86WLDK$Zy<8 zd`Gp7cg>b!o-+I}I7&D5t1)|`koYJy7OQ!Y+Ca_hdIjvkk zgdBe{)G2~jW+;7HM>R;4gqRh{sQb9beq+iwzQaj4W~?>{OJYCXqCDSD=GpeR8cgch z^k2r+8F1@o(19~_SeDk?#T?xPjwAfNJO>P_12ORhMZC# z*bT}quuZr@xL+z$e}?h~N=zZhj_1;l)d<2c%0PD@UsPp!NbfL26?+7Qd$JI8QI?`E zH;P@y%;mmM0@TvC^?7Nn?M5b<-^*M^o2bxQ_{7HK7bX1YCu$OAfzRGmA2@W$t53CfO;>Cqj@tQ?fP}QSsBgJ z8DBl~qN*~RZzHaRj&0C=&q5yTgs5qu@0Id5sWiZQN zr}qnGyPBc4IaEO7#wH6ENoWp(n(bC(UqBcxGBR+Kd&bVz&7 zoLYsJ%SYfQ4e(GjB5_n25WZ?Kx3g6{GZ7+vc?C|A^uhq#`-lw~mr^e2AI#ngH{`Dn z=L7sBx`!m^H#yWAS;DM_br*)U3MLxn(fSITF~!Slu%EBV^B!hGt>VB-Yj^ccoBEpL z4B($y&*ptq&eXba0dht#u+;F0V11M(=NrgNFxTZQt19f#4EZX2$_8@q^moP83TpOAoPF1=BO(in9j?xEv4Q&Vu|p8FJ* zr;EZ0a0NwCufD#n^nCTv?!tlX7qE66PVxx+G&5JsS|cD!ldUFH8ftHxcc}+HGkqqx zX-YeK<`}o2N@mSxToa60MrX9RD4Di|O9h+r7zV}ju9W==`N)k?XvALePAdzkYJ-Ry zJlX3HHP?2W7IQ!vG<$NCm2rfiigRmO@mR>c5Vz>b(NK$@1q|Z*$cgChSv~1?{?d^? zxT3-eJ9HSWmSkffDJUBEBH%%sJPAu?D9O4CdyTy20m`3Og^<2iZA)0St)Vx&-YS|v zC?>ulh4K{Xe_w=0sWkykYq=2#rsli>afKJ>f4Tl?c=;h?PV`g5xKOMVYemM3!Tgi@qR$*Q-9ci|z4QwSH`{C*6J}PjIXY zNX|V`U4(%?Slr2R-AeMAZ1qxkG23E@1?qmE3-Quy&=%5l|RNI!)oVTe*dE$$gY z>Dcl6_v22RW)v|w0Ed7<$D$YCuDc#$JE+v8lxZ$% zLl;u`Ii5&)AyfnZ*gyE2(G2)+z$zj&157=zO-~dXR|E21rgvTjZdbfDJiycp^I6GC ztA1@Z2n$Gj9h0lh4G)3}qLF zc--t0KHv97>3O9C+Y<0Yyd6lbX)5grfAU|g!NgFm%<9F|6-Xw48D_{n9R3P*aV`m# zsB9*!jY~BzvfLsB8eN4LkB7tOv{=kg`7p$0SVnv0&xE_Bx?<`~MKM2mmXAid29`Ys z@6Uu-ZUQ>6wo)1^s160wnieG-Nm<`=jyMAXv%=FZ%GF^i&_RFrDUz6 ze8fhf(+dgz%%1VajnS9fcHn8yV4n;{TnAS>4}{VAc9xIyCr|!B0fhOAyo%|^2GWR4Ex1~rt@`t@e_5S{FwD>?IIR(k=rOW|Mi-_?LV>OQ&GomLr>T+U1u; zPCzFqc!qx$!Pt3I)US#~J~A1q4M3E9dK0P+1MkW_O@yTL@lC<-?K%h23xeL)*B5%Z zQe&td2>936Sc2Ko5O&825#|k}!Q;Q;Ii}l!F0@k?Kq#FjX^jAo_*YcPOl8EN`lMxg z#hMzFNIYBeaDncUd;AAR_=`Dl1z{F4!ADa01A5w}U!r)fuMX@Nl-U}p);Nxs$%v_75v^5<_LUjv+;oQOv_y^cRM%QvB^CFHTtvuc ziUNril}6lqRb{g|!1>e#B%MWU=aK$I7&oIr6I8$~nLEJN0_>iK3JhR29H+wg%vk#s zK)OKj3$5pV3U7Z1!vyeQ3rdW8$(R!dwDqO#kw9dP{O5E_1{2!U2lxii0?4I#5!9Gr zGTzH<1VC0-nvxc|>8+5X;w-$h0sPL^1tHbq95enChD6j8nZ6C@F9o8?er%aZ6o?`l zbYhml|%nN{G zS(Jze?k2GtnJJKZn@?%J$(;>2DKF8f8?u+z)N^ycCkl;=Q z)AN*Vq6(AaoJuuiG)u=0@htAC&W8^%vEMd(aTN%pdNV*M}deGZ< zNRSu0a*wAboeX|y#1Ixe+JkCc+`E-|d|n^H(gI}3#){QCDKW#h9cewA%fV9S_}P4b z)iqr-K+!&%51g`n19>3U5z>pb^@66!@}pjpX49djf0~@{s?OD?j%})ShWQp=H^X!Z z!;NdWFU#t)rDeKAUm1HdU%4v-E)$>&PU{C00#$WDAjX;TMByG9?T{Rs;1raytHAov zX3}Wkmz>na3?eC~OR?Cqx$|6r{Y?mn4c#7PT81ScJ>EFWF@LC6$m|?f&UFPesleV+ ze}D$UvvZy660!2CMar0T4SvP2Cn;d_5!r_uw8XouAe{(sMdV;j?$Gr_&y-H8jM6jl z#egfxmvCKhwh$t@wWieP_Nq7d06@&`6-Pd!eZH-iYL<*NS^fZ{F##)J$MR(SwNKhD z20NVuxY~e!fze-Sl!VYDRT$Z|w&gv<%>M}#rv z5*}YH(vieD<7+@IOh!qa^i`Gp7pRNC?{~$qcAv>YFP+jIy1^95^krA9)&2XFJ;hxb zF42m?9?JmQ9lQ10Z)!iO^&l^tT_Ugo2><_kFstwsNC5mhF!{K{ zY|`yBg_X8jIQT>ALTJe7riX;wm?|;R zATT3~>2w)^JlAFI)dSu39m#LCSsWi}4%`MjWNhR{6{hyAR?M3K``$|~CDeALJ*Hl` zj94;yoU6yId#u&$UUM2Jh*JoRrrX=<7@^9i#4{}BK(xw5Zp2Hjk^NC~B9AtIqj?Wi zIaC?4Rxs2}t8{X0&`x*N{B<%HaRk{6rmNeTZ_Sc<$Gezl=v5dlaa116<~7`?G)W#~ z4Yl*iRei&~^NIG(sceE3u})MnRRd zu&A08S5SU2Z&XxYWnis3RObs_RnKCbq?=|WG@s_~Nz&8|w=rQj-)TCiH0wqNNE4fr zBWP%nra?OBK9Q7U-t9Ff!E}rO;S)@~hIiakYR3OSxLC2eY;0;6kU-NgR0`(@yc=tr zg*6;SGts*JFq*WR$k>3yN>?;2xN0QH7C&NltL(weP;l!Qtd=eW_im$%%zFaq_pA+O zH)@y>ZWQ*zTYR>%sK^_C!ZWY)Q8x(ewKvPk;PRnki1MlOCV&s&st*iM zd>A1S_I^hO=a;wajEAJdaezskcvRgJI68}Z{HKl_?3qt7NzCSY!zk0Upc_!QWwy!E z1O*r{iqxQhk#LY8Qe#N;kVn*kfuW5S14=S4BPr(TjUi-r!!@(F2ipQ(Me3Lxz%?}-Wy{(A88g#LdG z;2D_3is7#;hRK_*82)O+c!Gy>{WjdZ@niOTuB&O5*IVRhyahtY))XvKd9kJ8g5Mef zI87MoX5tOhD61freS|lo7t4SFd1T*{HV;CtL&3Q!Ajt%(AwfO7Tni-UR;n2ODu!T= zAUcl0D=D2s&g!~T7VzHQj&>zBOACw4BqW6;W4uWS+tM=gIqpZKZ7+jwC=g>R^ATGk z{#`G-fn;MlI7sI6>9Xq(T$rA}4@C}4w45e&H^{e3Ev?P7%YAUYX{4Kmw_P^|i@{M% zy2!e8s!8(ryYD+|8aQCpoc+7e2$cX;Nu-&oE~%NFPJ?=(VTVeLFs*QaSb+X5>~KpS zWN`kwT$W!@G(NV@Pw0KOGtr-#ZA#5>ph*Sg@bl?ZKpa4uWcZ{yE70f~%W5?M41{H8 zI)%K`qv8tf&cL*0#iFtY#!B0vQ59^dev=L5fbX8}l%u=Kv7Ze+Y0!=bA{6%Fne>+N zreh#-SBD8ONPlW-6S`E=y3%9BO7K;z=2fV2^;gIjd^mdH+H=!)0SPTI!>vqWGa#8k zwj(N<_or(Wa=rEbTG#5QcR#;GzZTE6XId^O5xMm2d42Hu=BElw?$PTPsFbUxyXqVDKz&c89zDX>->6xZFKUh4 z5v<$GWSTCf>>=B==YZIN3%&HhJ7D8=dg>XkBC-;!)ioqWm?6;WT2{mzo-b<7yBl<}ey-~fBfY7|3|IoM7w3`b z#ffciR!+;gj!lbw8k?4ldbD<4EdDDx=^YJ!eOnfvmJyFU$&sNkgSb)VRGCcSlu32C zRWZ^B??FToz}D>0~b5yR&3b7cVhO`<|kxk#5I5bbUEX!$N6LfGlpJ0Ojp* z1;*anvGJc zBg)_-StxACZ-#xk?Q7qo`fOf!>ok|i?9Tpkp%-53_&^j0M-cQMejeiy_KU!?pctj2 z@=9?!C|hV2EDk*pMXI2w%5SDIm*Gsp@1P(2NEBl8&8unR6%>!e_ej#`xG>4g(-j(2smE8|o6$ zJn++9VXdWap%15QFpde7>s= zb0DAf(r*DaHrC^6l?5!>584uU1T;7#X!(w^b``(SE^mRxI*Umc9rqU7%*1K8*Jc`r zB0!8>k%09XkD3|8ZPP(n+(|8^afL;BI_TZ?A;)O=Ww!N=0koC@N zbPMxgcI436#K-mwn*MiPROy3;QZ^f_2iwyBWw;o7p5QUR7lUd8dghZXz36tmg{L_s zUyes$h95^FJvsihYgY~nnh%Vq&mJMTPloV6KM>k)(G`lWCl?cyEykWi(nct6yDO0_ zVG+Umopw!=HxMPS&nb~ie}^KXp1z_`?f?T>Q^eGHfmuHFP_ z1pWB)UZhzuruh6Z*Coxmwmqv5t>yJH%WBotm#l8Fv3pk;+0-xPW&<=mfZrl{tF!CB z2%p;c9>3TKrJ3CzaC*c2-g3$U<9oDS+D~D-9^)4@ByD{`3k`-*(r#x7r?r6XY-iYY z%eY}}_*uifFJ#@1!Q^b%cfrwL$8UcOlb@9O%0HCSe(7KRM7x=3fW{h(Lr>hsRI%8w zjbH(@0;Rt4Aqb-TdKDu%;f1@wnAYFPH{8lfjf$9C)cSk6<*r88RCim8+Q{JPU)<^$ zfR{@blwEV_inUmK@p>H+^KjF()(F;Xdb_Ycco*Xf)=Z{Hz*hg{-SR)`_QgdD_*egu zZ9VdURj&ha{ovrs2qKbQWJKSg0x&)vcO=SRtbA|17GB|> zpyXJ~@i*Cej{pRkzx5pdMtTdmJ^J#OV{6B3KBsw2`YB?JDc9X4G*Z*P`>(n`kN8iQ7lJ(s50$xlRIFS1t2; zqU$UrJl8GK(@l%>EJXy@QY#cswn>&zQwzr%87una$ZN>(Yu;A4l|GYgD^}amiye6= z+SD~hr;l4l_B5_EC(e~MVBjm?I(P`eluU)BU}CQX>$jd< zJ5kv#gniH4{xAr^h%$K)u=PYtgc*PyGUZDm`jOe0pWjR}n^1c-jP z18ywLr%_#mecKQh+vJnr)UfJAYBNIJquZX*F0`@9jiyG%nB2sgi^)thuTh!FCwifF zc@4R^f!c*okn399Y3xj{(m(Nq3!e!$21of7mpZjvC4Ckn9zxP!%6lnKCsyMfNH=D2 zGS?l+|4mfJadFmDVM#G}jSg!p;GiJq%vG7pA#gkaz0dVZp{qR1+Lcz2JX2k1@WL%M z0U{JCxh%4g2OLytva=P#DqWN&uAN3$F?OgLmjH;AO$U0+QSbjh%As~1 z0(Ue_JM7@1%+5ip2JAy^kXgxF3#=kFC7ryrdRS6%v3Z$$*+e_(2<8`3A&2p%ZMSd) zUzI4yg@hblcTM8#8wXLLb>9;z_*elXb$fyOUe+ba-<~9f(IQ-3@MMk0`3AXc#?{O( zv(F1#MXu3plF9G6+7F%H0X zA4}Kt?QK-hRP3=T^VWks68iJZb!<0)GESRd{;|Hw#5sr*4oJpW<?+F|H!75rEosKm>UAm>r-xh>&lksN&72I1ITlx?XS zFwf&^CPH+@2Ij1FoNDj+FO}WwT;4tExtx6 zXlhWVl(bit3!;TQsE^-s*gen>x1;~t;XVE^5)>gqzk>|jNQfLMx)pullko=yuwzof zJxsjh#~@)2+(;ZuBT(_iHQ-qi6K^z7B9j6S-lZ3956a}mC@PbGMAM$zl8sKuSdH*u zQ$e#@ zfHkwMmQIKe&NZwgFLqI&f1(G#W9L#?3knZuAI)xdxB}@I3GOjxNG<@una+ zWKaR|$}(y_faw5;G3=?jI7Yilx7X|YRRJCgV1L^bnqcaBw{ zGm#fLZvc|y0f!Vi+FU@&?Sfg(2>qF2q3?A|fN-mmJO%XzPC!pUanLsrlwYw=B#8Hk z)jG6Kq7bnS07(G>YaHDa>t<|)B^0^+z7ZHA-nI4CJ4uq6kM^WFUD2RND`BXv{xsKV z4Os0seuEwGz~Fr_ZifK;m?fXKraI@VfF}vl9E!wWFOm@nOB`s=tuP{==9h%^{`Iwa zy;8$v4b&BMLFYxSzP`p@t#DjA84+G394cGmo~_)xqJ`XZo6Q|U)j4?ad>@2|jzs)` zeeKVXFDfaLm52wrUNh`N2geJ@pn&;>m<>q=&?l5VACAZ%z(= zcz1a6OUJz8JFCphgSmq{i;SaH!Sa%ziK03UhAsM>3@NwJl?VVsU;Baq;am7ZB(Tx5 zB1m3?fvh;Ies-LArW6x;*I*kUA{ut!T8v3E4}zKCK-zwr05)^r0PrUUPdCE9%@uA7 z-@k7@L=Fmhppcand9w`|h53FEL8U;)P`{M-PKd)nH6ieZ0m}%ANx`|HCoyoy4C06> zkdRQd&P9OJvAq;FCS|nccvB72UF4VYhFafKid+xLx}y*r1dU5C^z zA2_O}C)HFTVU|bnSRMpsZ3l0Ysyd-e8_uZeO5;KqR+k})Ai>a$7rYB*qk2q=Ay>8U z7#S3+%JfD^Q;Pxi1$4reNLUgWCyeW1fz}Yo&%F6V+@af1%NsAh=w;D5@t#gAs5?9e zYx>V5t+`bjEjAEGZ?laz-o$RwRlb)j6U% z?AjnPt?xRsfg8_eX=DE|Jrosx#c*5AvH|YaKP?0BCO%FPVIO_k;0@Yk0I;(d;{>Z> z4mr#K>lM60*<8nI%|``TaBOMa~#`PIp2*gitB)E181RoVQ>W~w% z4ndExc(s^OucfM@%w(5E$^^6_W;vOo{dA8acOFDgp3LTEkp$b~Wv8?zMqxXOI9OWa zc09cy4KxA9bL}NRM?1&}xgk z&ZgF~l~s!3=^;HCIk>+}aK2+<+e8*y(`gHwOcSOpW3>77J0@~%dTcS!7Jfb~hP}|)8l{L_Y`o_R}NIjk3^B*G7Wsh2d(Aro0DT zKUPH!svo@a`F*i6=234=yUstUXrEqTiETy#dh<=;VzKFwL=E>`SIk+X9+2p|&17mf z%&X;qJv&{8Zb_`(hXQOKi?t{3U~#FpaRPR~&F1~M^1|CFF`Y%=oLNPa z0=IGyzmtDh=c#5VO0~_@iJT}8F+R8?!G~II4e_ms(}f5mV!-;L2R$M}I|m1XVwTZ4 zSK20Lp{y0aae!YJWQxeZ7cR*)C26g)Jk^wN82q-zS&8vykVpcvAj@6zKCr)?M%}jF zJ1sWIpMxS#b-c@csS;=V1n$hIuoPEw1F=HA$MRkl(%>t^v6;PBCLDaf=ma_1y}^PBhcY7;9{aE1gTV z7bpU{jYL45dN%L$sFFcFo4*B2yHBFe<7yDe<7}H)lgimwsu4-s6$FQsZ9oclN$1&L zL&q9aTX_PU6GjaZk1H7UMK$uRD^BT^ykUx3oYvOURDhbxE7tHD@QZ^&III;J>vh?*m1?!1`Zr=zrWWn0YXup#kelGO5-s4xNq1Ts{+}&i*+bVq zFEAl+WW5J&XER+@$+`BDs+>%;x5l8)QuM+nZ!-g%I#_;T$3_FrAMtDqVEQ-KWnU{{T8t~yo35a@cJQ1p>LU_v zIIqgyQ$=ivWIEnMTD9+X9(M?n!uSrvlP_`3pSV*SzX>ceYt_*)(;=7T-gm9Q(v*5w zs}btGd+Tj(k$mL7Jk#``uoCQ-^-lDfy+Lhh`KmD0(r5TqZ8Y6$nPB*vo#D+-sGBy% zO-!QklA-{GtkyG-RzRO>zsM?r6r}zF3JOQHuvEk~pjNgnP`yL7fm78vA{1!FCy43v zpl#(mQ?;Rjp6S2E)PF5KTlUH4b;L8^u5`!cLI|#DM(zg8&`A+4w3Z0jkDGf7kV_y@ zXAN4Yq^fG_6MvQ$)S0xH=?ZvkusN}Y%Ci<8d)jZ_RS{!ELyiC&NTBbN(nMbSgO!p* zH_${$X(IT-s5HX_d`g*wHa6NUqa>hwu_Nb*nvc(D86iBHtv^`CJ@0$RqCG}Px$JYxh}f%eoe zd*abC(O_h;!x6jkwCs@RA%pogi~bD$+I6k?$sOD*d0W6vkJzWm+Y1f;k#;cAK-{T( zP^6Gxo^9cg>kx5iP)Pl0p5&vGVvet&E?uR^Q}RpbeE9I__^0Q`KXx8s2AndFPkKP`4xF|pHf1MubEzKJB{P<#7{92TS^;uJNC5qzWtSQ@vd;L{*;!pLEZqOgDE}r*kUUn|VU?g>Nsz0$Ap&bKU8y&Z^@vKIF^Y@EJFIs^5_e z)Vu^DG8@cG?QZO1w8V$-hkXkC3>7UZck_eobzbUb<@5J*CevFxh(z1DhR}Yj`yuq% ztN1MsG@LJZ=XgZ;71I7jJGQz31umGIXO0*2Aeqmn%kI4I%25Hn9dO3IlJKCf<^fxY zkDH{(+ygf+v{`0=>tIht0@9o;VTVuDw}WrgsL&N!`)N~WH9i^echB=>jQ{}1*TNr& z+i|^8SJ`w*+uVT})K>*5S7E&>U0zyE095?|gyjb+A?d#^=4z@h^|TMJme;F(vKmsQ zAPmwd5#^J6&=)l&*Q@?;l~VDc=F()0eV?q-elko?%@B@qP&L3&OUmQIXOW^w-_sDDWdgahAs=A~L@xzB}BKZJT;XZrpZ6%{}#qoC=1iFvrjUJ+V`1Ct+ z#m$gTH3>T%D(IIvQ2Q@@l=xMXbX|20iUoHI) zGk|GX2F;we6n$!oHjW5g^I3IL%!Rap?<)4%eJ=^&da7q>o;_VvU5W#i7uFqs_wM}v zW$#_M+cvUv(Z5o1yuybl&~p0By;q8&c5J8P(|%;x%1O_NiUkry2{8zu0noBy>-_e+ z_M@ICfTZK}nYnj*t#(A9Q19BcpWm)9ND?*^;d)%H;|f&sRB8@Lv=Y6LapDhZNeaI% zlIajfrbmjk;Stlj35R4T_QoRkFox-DcK<%F3bp_SC@9J1Ixs~*dyqZ(!LfKJz7-y?^kb_5O-x{OyLQxC-i20#!WSqC*0M4FQi%5j1o4U?!jzvUEcDA`TL2F(H5B`RuEiw(!LZCA;O(vR z_RxEKlO`CULMdY74_JZ8vvz)XVXMvbNz4~$bFj1~-wBENHSv!Gw&6LD~8ts~ccWz~IWH&P-5Odi$6N)FY{ zJvuhpl9%?S=-dXNNBMA!Ezm`L3`&<1?1$4aD7^4Cwnyl^4GSUF6ik7UC68GWclBIU z(SjJJkVFZ!3E*=G)88~bZFfO67HaBcM^ig8Jwdid z?2DJ@zg+}49eqik6(!yKHWy&{9(&?9a!0|uANHM#A1mJY-sIlwp0UBq?j6r^b}^!4 zZ9i2I2G`sUS>renvwLsf%K8NgJhOXXzIq>LYvZwXZ1Bt>=%#A^7vK;66oaQIObKLX zKrY1~eE;<5?Ck05mv5gxefhVuAH|7+_WrlO=wiXDz?%>Lv~7=8{2RX|@Pu}%q>k+C zX-p=DWHw1SKtv_m=;=In-c^Ni!TCCx!uhS0#G@|hWQa@odl&mS0;5tvy zU#O%Fld|Rud4!vydRL2hQ5AKKj?k(wqI*KgFSqB2iNiQ8Yp(&9E579cz{~HB#QC>s zm}!xJHxbh{dVVVfd;-wsSD<{m(4IN){bL^WiCW>o`B9wZ>($Z40E8;IgvyW4@94iT zGxbLTQX}+N8T|0O@;dJNE>OH)q^VW>0}%Pag9iuZ$N#k)FbTB2n`d$U&S~a9YHX)z zx3S2ZDs##{UIe<5q*rO<6blaUs*1~Nw`CsSV^zBKO;+5<%AJ(ZWRz8!yFGXuDh2GY zQ|hNcsk)38GSJNi{;A-f9R7I^|18^|uglW!@jB4TO;IHqHwkw#H0K}eNq=wQOC9rNaBwS!VSEhXT0ruh||*g8#&jsY%)O4fKYUyVqxrzW*dzpcfXnKA=n_a*V4lbrw6XMA3e~olaSBn&&l2`IWDOT}Sx-cZAHmHQ~ zy04)FXzAnKa5UaOjV92}ulGNFHJjDJhTqGI6_$WV9A^;Qe=FuvDjQCMDmv8alk&0< zzXT)6a7fk2rL(US5HUdiis_YKUHAcxvP2ON%)U0U&4l0GQGpLoIKyla@ zuqMTU?L45LZQk;kS$^U{UxX%r9!xQ}i}&VQZBID);$4->=iLSp44#o0}5!DsXPN z-=R*l{5@(w@joIC;=GG_;0qljT+CDDudUBQc&!(uZrt8%w&wsn&s+Wk4a#3I#C*f6K$|wt(TP6*ME-3fcCckimt)XH+k}tnqKQM_FuKHWv^d;eD?h5k#TkS z7LP_K10cJ=fy8PpMCz+Wl+?F30Ct&w{5lwcsw>4`JTWb)OAiPLtS_$Z?|VNSrUSdLqu(d0I}y8o9-b3m|sP%re~l(B>LP!Fks-$BGTX z%F}Rp9ui9`6LB6NoL?YBc$&+J_MC*r#A04tgeyTUl0L1SZ8=ur`;p=}CiV#y2QahD zvmA%(x$Ec!D2x_a9oCZm8I_0YqlyL@9Uij2~KKYbGGj)LlJ z5d8}jy6ZeNcaCmZYf^b*TE_$L;favTCHNA&mzkw+?x5>itiF|MF0E-|Fbtm%=~<=A zI}o;90SByZ)d8WcbpsYzG$%xDqO=g-i4D8ZUKWc7b-KULS}*(kVl?U}O48G{F^^sFTXJ z4SiBATi90n$!w21J2e6_5Z{W_H$o+80xli3q>TYV7MR~ss!NYdF{I_9N6zXFm=AxJ7qdb)dJE2o-kM>?b7SX=`wXqFiI}gRF^@1!d2ZxX` zSwC%?zRzv##t__bcpveZ<}DODI|_46Nr=Gt?&I`;KywQ6k2n&80o;bJ&O$3J_CZi_ z0n4XcW5~KV(mxfj0cw!tZOb8>$sNUayGkUiUshM zwJhT*1|YXI7nh;2UxEjqG_&;!jJ%^{N}O{I@B}zR^P;&{N+UHl7&<*}Plr8graAPh zmbDn7E>L}grkTF}j?@)8S1nVkMWx-ksgbEc zU}<`1v-9Ekud~?{7VTm*n~{R|{^7v!rm(&k4o~->@F@E9>!|bd`ws^ryOr6D%3X|f z{T?N-2Cx3?q5|rDznP7+srt6Zy#`ICMgAp;!=pE6ZM!S(x3?CZdiz`b_Rxwynca(~ zA!0VWH#+vWL+D#;3hYn7Hmi_P-^gZoKG*}7%2W7fAO0D`KYtxum`~FB>4yfG1F)WA z`doq@gqje!WWhRjwu9D0-yoj2tYj&b3-CP6H3Xz))>$O-)XzjvY&}q5jV7oOuMi(e zBt@h2_Q|xUz=R6kIdP^KGIa2lIqKi>SWTzm>4&Cf4{S2mTubpQG&&XYv@zk+@VqME zpr(K_NqiX@F|=A7NA$8d)9s#!!SHl%czX2fr|Ag8Iq;v;;px%+Pt(z8aO{2hq-gjf zEQkecMvfb18v|V@Jd4Vh&BldmDQ5Q|${8l*9*za8GD!}Tq7h@1GJxt5>n@W>3>A4y z6<1kX^N{9jRF)WALBiJJI?WP5;3QLkBKHL7Mm}k@MtCvhGx`D1WT!!C_^ztrvtfwZf7f1nMN z2B1(1tfT9knwP~>#GlwHft49_i{nawfGMT(2slln3I6z%cp&=h@sj!xa{D7B~(j$VUlTI(Opm{-O zx{}7-bV$Kbl|)&0CF7i6Kk4unOOScEQ3Mu!`oTATS$MqYAOtB1D^m7rpK6V~VIg-m zbm>_0tt<-EXJX0H90)_+pc>)|g2Y@M6@2cguCaE#UTvETy{Ar+=wVjKyvJ+d#4UX4 z{Nyr6_^|c88N6NJ3H=nOdUB4e_mQ{GrZ$!&!&RMMc(qu2%AO}})&oV1UEb`w;8Ys@ zKl~nbOyx6%8S0%eip662^+-F_vlI@Tg<7|vtA6V?Eb9@v%MPaHbxvGfG736uyI&l4 zwq_ZUJyTUl8bBUlQwME>%4?4EAF;pO*493BjHA=?>60iU)!#r3Jg#Bz1dRF=t@20* zcj-xEz-~~iLHa1=wZRqwZ7W{+gLP|Zk1I^6pG7EkO2$IyThZW-=xIT~q)m5v#2yGeJq)m~#mJNH@5 zvt4&Sp}J`>8U%WEXWc(Q1wQNS;Zhi?(xN1uR|ji5k)43hUjUPa?*_g*0#(^bqO3*U z`UE4_3Azrm%L)uaEC4Bx^VB(enr2-WZ;?Rf=JxIzboH=)v!})|*IOyqXbz(w1<7f_ z_lSINPdY&T9B1z^z zd3rJ0-VY)02zN;tsG@iO-1Q}aw@yF5M0O>LqV^j5*LU~D%{TTg2X6CzaX13ogC4oE zVQFI~fmrhO*JesI(-(GMY3(56at|0u7!MG{ygX^Xla=WcZPq zxz?Pi%3)!fAMDo13N$izT$r;0Sgnt`k%4`%I~R^Mw)^nmKG`CJwXSW;3yf|qsO8ud%=*eki>$~cDM38fb9zG~=7JnBs0>xoWZ9~0b96v<(aUW7{=+Ws z0Vi1PB;Fw#z%1^!T?02T)Ey!OWjDl4*V#7(?08~tz);je+ijL39;|8D+bq9X8@a>D ze}jB>*X>u`j)vF^jqM?VYjQtE{R8bhvRicNi>{?VzVq&>Hl6O7VTatLeTBkQ=TF_V zdqvqqc_BYw7>i?o2kSe8xmYBE@v4U1GXmrh@27aN81)PyK)*bA+6kQgZjzw+qBTrL{s= z8#-U$O@m>7Fs+}!@nGcLn62+{wG+BqpO9lGh;2hF|B*ZDHd)B0L!*EU~; z!jUB4cS2ro7@xC>vt?1O%x8NPCXySLU~XFsr&9v{7uvgu2@*O@RdyVik#QBszq2To z9ba3z{W6*tFwmuF{zVu3!%-kuA`NN<01)hNSur2#XqQeW9)%y&-s`%T`fGbV-E*(o zK?THv;1}HExNZVo1cY|LjtM@L1K}T3a!`}^5IUYhS?z{x9H_|JMk=&O*)LwaU^m90 z9}Q;Pujdl&$udz!>@RFQchqF4=XZLxwYrU#46TSKJtl1q!-nk-K#ddalf%&+7v^iq z>hT8Mv;*2mN)D6eA}`Rd6rAHH9Ff-WL#+7~=JipbX-VNuHS(J1x)^t?vWjPe?67ey z4o(|vS zgTYdvl6sDUpJ13=Q~V5QIgevV9E#hCA3uj7(qrHLw5LYa<@=)1!dsM-W(G6*g2!cW zc&B2Jny{%Mc}$*)!I~eokGPwK5vU4nu;Jye_dizh?*8S3+8j;%9>1-t1!N|hc#mNg zj&LrlH+Q49;~95;7z#^thSy7kn2g{qn>hYbj4ES6#~8X~0vU7rn_*pa?D$%vX^jXH zlxr<2Cx{VA9ZoxVf1}?ts+c>-uc-Lur~5lb?apB;#$<}w1L!>x+>@~IPbUn0WK2?n*v;* zVCd^CJ3x13$ddb7QaZ2?jqMG~2?bP4!w{VO@!CMmah^aQ*{>eZY*iKfsU7yIs`%AV zyy++s;uUo2CWWXKjwXWbm#j;f?5Xc{JI@m z1TC^lSRoV?;%i}B#2JvpaCs#zZug4 zE?sy`Xz>b-2^gy*aX&P9_L4g@cq1XlA5A3sjk6}_&Do>ZXS^|WMVd>gi>_%WM1C%K zBi9^1C-H8ty{0#SBZwdqc)Hr;B~Fx{M)x@~3zS!8b#^y^1t%T&w8 z!xR`2f`EdeiPH>2+yVE-4r1W2Oho6h$xtOt0FxWjuc}lLI65{-N0ZCAPJxgYx;&CJRpT#Q!wd-GN3xE6xCm)2}IUV1_Vtg6|iJ$I)0G|KS6O+G&NS( zI8L|B8G|g7z#XLxx&js)=#ypATo+BDl2y=6fI^+h$oDUQ=$-DDP!ekRPUKE@e!eP+m zt=)HDx6C~u*GMI#R%(-&F4Xomw@yma#EWZjU(tK($g87{!BX>enn5G&j=m{4p$aIq z9h%3}p2!A{_YF`TWjD|VLPf9XkL(p%X7T%?s`UrfAgwR99l`>@CKO{tcoxi0w@E7} zV}azF5OX(Cv5*-_xU_1uq8;dDbEEc)vj+?-TYCzUNX5E4<;Al%juNG@Bh}(8vuI)5 z_@RLF^mph|24EjdM3tMYVj0aXAPoiCAC5moAI2D`%@Ses;a1a+==MWs*(WxAh1@%8 zxzyGq=OeZEX_yp9r6mcmmY+7%~%Y)GFZcQ7K|p;V}bWJL-d~jiY_}guEtsN=KYfq#~(! z92EwV@h3&dhbO^!FjYXDo@!@AMNyNYIo{PJ&4dq7;KlagDU4mIV=UWVskVFRap+@+ z;c>!Q+PVef5Zme4f{LQIVJ%U}K{u>_KD88sq=B4xN|lKkYzI^w`TT~L^SC3B#tD-0 zRX8FL8s>hjfqJjFE3FGVM7gXAyhh`zIOX$4U{>|Ig?49EGKdCP3Sz(&3q(00UPa2IOS1LnBrHqvW1W(8*nN<1%SzsG?I!3!ivIZF#kjCkTSgIwsv(#YF5 zNl`TEt&eFpLO#HfM4S2y+k{XV#EIywnl?@)6_0LEnbkJ1m-HNa+g;%h?g6l`m9#E( zwNM7w2jEm6^3ZP`o^aE%S)}`xZ|n$m23off`eu|}w4;L$|9A(#R3H00`j^pY)W83% z{BJf=2%phK4A38pTL&*tL`at+?ya<5&kr;Q&Ec?$+XUMXngVX(+buUI;ePD#hS}4s zL+9@48FH;*H1xJVZ9|hBSuLO1@FPdv{$F>yK&PtHO0KmOs=(rhgR*l^@1Lg7u@0o3 zXdQX>g9T_B$uO0N$AAU@md0QkxKQugAkv zTi_dfh;9e%xU`b;0{g*fgE4wzc@Oso#~WP*{U+2&_Nv+&Aa3935n&6Vi46YhyUSA| zUyBo^^B_X6tadw%Tynyi&bI+oXG`~(wAGF~D-A;mLtj}KEz_)#6>WjN4J_XX8GyaguR~)5 z^~8#zR#vlpu1Z$9zV8}2ih0)uK9d{5*6Rv!w=m-Sg4=tu9{C|An?g#uy!;_4DWovd zP?LC@xD)k!3;|Z*@lWY%x_&Sw#|E^dwtxO+()I5 zJ80#)Qvb7VE8DcO>ac6<7J=8jF5~WvsYu4xU$ZMRm+zgpAdlM}xZnOd@L4xRkMzxX8Jf_%lc;2@Acfxw5r{H_uPkA9juCL8B>e-b*c5{Q+q`Jr znjD`RNV-9+U@>N_=|)y%B|#U#K{QThIgbGQ6vyqn04_-WAB4z9Q;>lK*XdFA|GKC9 zf1~D}Z6KA*Yu5t>Jcq%-5TY6AK!7zwUv_&ijPpIn%K}YN8ZTXgYUX_Jf-|>}J`Fb= zEfGNQLPaotgNs4*x$yqyr{m!W@Tm!l`uzUa7oEWVx-4A%E$r&M(8215>E8&_5Bc2R zzD-w9>l3+**IA>~9-3wK-XrU}gtWuxs=g}BWvkFLS49F}uZkoxqyo4vcyS~?irKw{ zDx2Lq!iRS}zCR^nNPE&8I;noWNb{6bCgxfDH~Ooa2b9$c^3EsLQyyJyJtFDAdhoaB zuf7K-XX{ZdOS>(rKV8WUDBV5gCh(SNXmSL|W;d_N)jUDvR)4JgwRgNxaNggODD=mVNG=;|H?6-pj23!coM}eUf6& znf{wV;^8t~rN7IB+zo&%s_2zfL0OSjMebbLwSz$aq-dUgXkI@RCzz{hygxkub^ot> zr?c63Hanlqh8N?}{poT0lQW5NjTpa-P=ibS&)(9pWU~Q#8Oc1MM;z}Qs*bF|evR9G z`;r2xtj~F2C?s2cXxu$%_SB-G>HcD%7T9k(XPn;EYGr5o7e zz3 z`%;_h3wH|};JyWVlt};+zyH9^^z0K_%fApl=sN73?VE-Bf?epQ7I!GN2h9*F;|p?} zKV@+PVK68_usxzG7U1iNd`yA7J=V|9sc)x#@kr+H{ZGuPu?uxPkKVq0@$BWZ7mv;! z|M>Ro>6^1>FaP%Tr{|B(et7lz#oM>8@16Rt1%TFk!c<^;2&x=6*Af20;z#rVTZ9K8j?NP-+)|bt z^5%9mFS6kPEiz!M9ghd2V1)tUMLpUo%TkvPU`o*}>l#IG6L&uP^AakbKc#@;v-5KX1}mg z``V*v(v>s}b#qg^A)bi+;>c48ed93V4gZWj9!?(KjfTo;ZWN95kSRfOpx5N1`N#TY zcgCt-7IP@%lKMU`HK z6bw#^+to&y8LDwgz%81{rI~;4_I0OfoZ$=FxKQwSBV|$i%CS+ISyjPpi zajB)xQRola4Vn@5pmI+f{2n!BpvQ71%gUp+gCoIb zWDs+w)BR}IIo<3`usb+XXbm8~sa?e`y|tG?X`qf!8y-9>S{FI2L+x0VZLVs|iim(6 z^-)!~~dB&&IZDAoc0yZc(`{yJe|hH`io^|1t|c>az~j3KU_qv{*+*jJX0wmLyUk{I z)2NYkqkA7fWJ5i8WCsV)Iz(;DH`j6zRAoC(A({428!gg>LLdK3MorB=*#@N+spr zEtZ&zx9yxx0`E8y=!1YF=UiUL?^B3+tA)$~Gm8xUAOX`prbz;qfVmV&TB|a!p^yfc zbEyP#EpusmWDj}TY!AZA))Dkowe&~u+_X%gx~%FN+ut@_oR0cxwPF~{o*px)fO^FV z{zvgKOQ>(P;%j(0vX!r^Rb(a-qE1lphF=H7DtylHvJR1U2^19b?P$t|#;km3<^o1$ zm5v!*0Yu%bmrDwln$5;^Fve0dD)~w|?!LRaypq|uE`v)6Im6F_YKf}nT>b-oi&YHB$67?)=jX|674r+I3+u#NKU2Ucd)2AZk08X!Rbl#H>*-bQ*JVK0>3*j<3}xHa~LM zhYNSwv2Cog>Teov%h)BIw8o)etnP0^kxY9!EZ<<(|N| zb^9ws-F?S6LJ}ER+8MQw%_8zDfTBb1)(a;E*Jngc24{#zInoRf_+z#^eHZY64`+0{ z3+LqGBc^~;Y8i;(Yv-C(1akux3l`t&PZHkUW3efbUchrFk@NKxV6VR&iI3_bEkGLp zDNJ8lxY1tX`!=BmMjcP2a@iq1w9j|xOZYDZs6}7~X|B3MQun&n(xEgvR*V?evJ{6$ zVwqm8D~VCRCPif6l%QDn5~-n&yNy*nJYoTnxh|6vfpQ@qDm1icCflgTK_9o@{t05K4lThTAld0oMmCj2R3Y%e%}fdv-0sXPA*fn5JoaU8>L&YeZusQE|dTXj;47 zmm2v^n>fiLgY@Lem+B^75OYGk0L_z<^Fel;ItEGeh4b|ffKx|+xRq3v^QJH~+xD+x zEti-B5)vU+wz`r?1T&5VOb{40E6Rd^c$Ek5(k!#5l#`FgxlnHH)?!q}Jd-PipJC^G zNNKJU3&D4cVRs9iU5TW)$*F@aAonW1`I~il+1m-DC~MfMMA(6$c>}79p{tQ^-GGW` z;)xsDZL~h@-PEm5rc)a5!NGTGbGdPHwaKEaE5Lz(o*v>9-;M%tp%yTN&keM>iQt`O z<3BN;M^XU>V^N89z97$luAr>6{`uu&i0IXLV}l@E3yO2+ha1Zb>+^>fD*6U>hgwc0 zeIdLbjXJ+?7yssBbllzhCpc2@T|18te!n=Hrs}&eEEi?&`T6DJp4c!_Nk&nmvRpry zh`)?5IkkH77fO6xn>~tGz_6}eBE3ywCmzJc4#AL|P8|NRPTU1Kue!U=;{arT?_sK2 z7X#ba;X<`CG833+nt&?^XjUORT8VD|*=-c$Xn~7lZBI=~j1)4}zFH1B@D+C8!J*fB zQV>!uAh9AXJ%wul4gj2y8iGZ^iT1%hnT(c@Ep2>C)*Np3|?rBsYFVjrcw{;^|csbI=E3S$-L#49;D3@8f zN^=ma5uBLrPtpT}&Jn}n#$$^yuf;NUFv1c27m&OW%3ULGTlk1+4!FZLV@8wHjsb36 zdiTDSxJ5a{X$70QQqAS)S$uSc845NtY?1{NMWzfI7cze19s$y5y0h#yY z(bvD(U!SKJx`N+2Dp1{ZPSJ0CGREWn?0~J0Al~*%z`?Z=!hA&WZ)j z5To%r#6cxhxF3CYA|8eisN$|U|eeZ+vbdLQnGJf&2Ck^XEr;EL;xqG)$a@% zdzDKSWwTwEJG!+fvMeqkD3VozNJmuK7Cd-GE;sZjPJWB)h0Gge#oD@S%u4vW^*c8; z1LRq$QZ(l2rtE%F>1}!u@PuzWuW;#T4l0?f7jig66$R!z>;>5d7*gUw z&n<@?Rct$1?TY`^NJsVExs-d@-T)fYRO$$H@Z-gLLYY?MVg z>;q5j9hBHQF)lXMm-(}^ox6!RzvxIj-OkY|PR03PaDguN{o5P2>Df*3Lze{2e5~S>*y+Cu4G44~Q#9m+;z?`LLJ8>4SKBxo^K~uW|e|MMdfikpLHWVtc1eh3< zsl&{B%O#|ygxs&d;*lx^3^a>%g`y)=MD`#EC4x_i1-x?;SdGUjfdpE2fL}|HWMjk< zN?APBzyP7sRLqKcJ5vop6_E0(7DIcUV4_I-0(6!<@!ENM=*;5e;DN^f>l6KvUbo&& z^k?q#JFnhNm+LOHgw_z6)P?kq&}usct?#})IYE^U`Bf{>obgyBg+y2#3KFw`dD2?^ z^6Ka3Phh1~I=6I*pQH&F7xnE5;G1gNmaP7zN;aqfd{o0fmEHNmE8XIAh{r3IB0Rp$ zlIjRZ;9A4$FdZ!UURTI`Er9sU@1yjS+7PO+Ki&80RJ+bbXTSMzYY z)*fya%eNT)-5+JK;6Nm)qC5aQ3?7M=-GLIW-n3POoqD5A*@2yq@Rn61iEXM~pJ3th ztC|$!otkl@&w(sDhyvp|ibO|+mTjgPiD)Oa_v z(>89WL)hH_yQONO+b~AfOQl0V>z!61kRzWF`&j}RyMl)$aaf$SFBpEb57ET_an~tK ze)PEXuFtxK%#IqAthBKr@$11srzo1&S`^i?r3yppHwoM4Z5zje?pxV$EI^x{=UlMS zv%rd)GkLFYFTcQOHrsh%V!0Chb}x=^4kSDR1 zKY{5%4BIGH+XoW3z=L@x*Gnmgnd5^r8dL0y;xPj++NEJ_mp({7M`NtS7Yi zaoCnTZ$I`3p7xb+rWVpD>MkoQCv^gzz&pHYHV$N$4sY8t(+|}%cY3$$87;&gn=^Zk z!h9a}HT1^yj#BxZL39hCU4O;P}fe_l|RIuX=c{X*IT= zYb?LrTvOG%%ys-n=X$ZLV@|(P)~v*7afneS*<% zDk^fcA>e4sC@xarb;M?xm#>yfa*TekAwiFd&N9RF;!;E=@-Xe?Mp{1GIn zaW3G_2s-;qTw>zXCLZTD^7%Z-;j=_WZz4+m?=n;SL|2ko`&H?pmcSS;5ecb89x;Pw z`}9&f%YhxWU;ch7SpX0&P3$_;fz~Fuk4rK3#OYr?>OY_wYUZzx#do z%^4FRIFpTvsRu2y5;)ZXjhBrbO>b3!xN&1LnAcKrq+M$UfRa>l6@zK1ih?ygTZ+1v zXixR^!V0--7tM=i!i|gBz4``StLoW3L{GR{A>1xP{8hIizKYX4T+Px8T$Kkgnx^0jpqr*G6B1SCh zvJ1**6|Cwb1jQC;7>YYaiI8haRV{wsBF^s z9jdiy^a1j6W;$O*paNT4nAU--#44*fDG+DJIW#=hW}o>j(ic)klvzQCwA-8K17VSZ zI1j(A@8+$XoV3hoKG@<510@7=2dPK63LixX)UEwhZBUl> zu;JZ6PTejF#k&dUEe5r^2owkkZyN~ghPCDAQKw77vce_lTnspjT&a|rVXC@J?)I6R z&2k-zjjb_fIT6dsRtQxS(?ZY5{Kr53p`0Gk(-%dMNQnQrM$x^t6=djD(c=-x5M!2x zN=Y=;XyVIN^a!<9{SGVk;PuFf2w+=#0~-1=+hW8#>TPJq=1sIo2<-QrUBu|O#anB3 zF9NLF3jTn5j(p2t%&S*-+iaYuPN2(u3HOlT;i#Eu7l4eHFq0lE+B92D8G`J-Aef6 z`_$uh$qy(CwZtg;_%XxxC$@76l{2tl!}w}h)jd|5Q| z2v~RqSf6S`F5=A$vJ5c+05&I&GcmhoD;q!%FfxEEpd+qMYGqNU&Ei^?7DZLbx-6)9 zs60?1@*U1+&&&&f`E;P;Y>G>p{w8CsL7)`w=5rDs93=znc28YOF;xVanBP*!AMovI z6N&HFK+vait?nAEjkDp@06Ephr*`5J z1)%6rYJ?L6%RC?uxd4iQ0eCBPuwIN}&8;I4*|&f_q`CpwtB#wrUfzPH!TAIbC1r|4 z1)K#WI14P79a{uL%LtPwDRSxA0hcLLSyp^@h_UW%ptVDJg4-jHS2{034Sz!jV_WYS z=S0Qe!0qjbcx%i9Y1g&TzOe|Bk>>I`PISLBxoq0qQ}=A~&Y(CYg-W@=yS!Eiy6w>s zGU5`Ew9vfk>yoUPS{KSWG|nB@Vxouno{#K?LBh$67qF=z$$}YiK`LOtr4w0PH?0~7 zP?k9>gfOA@7!R|l;uOI&5vn1u38rJU$$3hr^J#FN%+@?0XKh!c_WgV|@IISCgN*Wg zo#SbZ+uHNyx+-okF6b$u#tv?p86j*}onZ(d z_={ldZ|@_aGU3!N`O)@6zIbS#~SR z>p_XN12Gy_O}6lO>SWA5(!VwkqmGtUF8luWhb}06A9Q>Y!iuLN9jV^K#gBr;LooC^ zx4dL_eonQ1bXVXc#y}7N?a5ehu&H3iDPRA3I_TC&4 z>*4O*Nw(`svZ)P~!A6{jxNeA2hf_E@S3=YjFJ3SicLLIopHl4`SC&dTDW^jW$Ro(2 zR-+oCN|jWztcu@3g_gfht0G6}eD}lGa+yK)Q}VO<3Bhff+hHXqVgLf%06YZV$JtsQ znR&VE$JeVo4@Z^4Dd?BV#%{N)6Y zR8>OZn2-_^%*;_IEc!FhvCq*%5EKL8F2Xx(qy)j`I$t3832`$TO@eCx=BAbjSX<*P zyCnu0T~5kMHVvj^doS}8SUc2TKw4uL*&WrS;ID~Fikp}+e%%z+JH-OxT(ywSEo5*P zjSPirgCG}nwa|H6Lb{jUg}U3BU2$?aTO`6jvAWF@*>In2poOPa>go_7wG&9UdbZ4B z1h-H*65N{rgAr2>M)a_sX>tIU9+Xa6VcL#*CQtP7Sc?j2BUdc@-$+{e1o1OfSHs^f z3CN#w?lJH_Nb?g!(*zei{*AuY3<^#^G<- zy=9dq2?&Q)C7(=1(1*^dZ~`p+Zk-vS#(eR$A16ili0%qAA|vyx--TUo%hI_;N^o`g zt}A|`6rjTZ?4e@GY2y2%?Rg&|ZHjO^VE}3aQKCJjMJgF5Nm$c%*Qp%~suH_61Up09 zupD*q2w~r!?#`d?Q1(ca(c8LO_*y}K)MXhhi|T2-xE?|l@U$N=Q=yQQjC6Xu0a+6Z z_F|Il1!e$4+ZC|pR<2RO(2Sl%)v%c-c1oyTluZqKqKgB+p`UKuO`3F#6e|Y9)1w(A z5&JX{`p0u>>#SC1EQiq|Qcj5MH2YBcg<_E~{0jw5xOnlQtgU^;CYJIA2^B6}9%Ox@GZ- zgeUiX#^JmuWj+y$tf=J$Cy+2{$dGXuo*oS*VlX290r2t$13z)vTBkGxf165cn%#U_ z+Sn0`F@f$;w=suL+6XiQz*VqloLtCos(*#80i6~5@MNF53_It(r^hi7HgQggG@Q^N zWNk6s1+aRdNVRaB8g^oMx;IcA7>uHQr)}^r>}6DeJEOZ81sq7Fg7@bIZ=1nr^w}EB z1&(+qKa6_yn8pcs7mj)>4Q4Of%{ACyy@5OlC5@3Sm$2P)l}%Koe!>`jG$Fal#DdI9 zR??D6g28BB74KvqVKK#I_<6PLR8+{AE{Zsl^+Fj;3y3rG-Q6$+R5%?axx1;Ly3lUh z78*&>D#ev`rpMGoyPZ90`s-{qoz14_@ZXDlm8pCbOkn_eOVG16RSZ!7wB5&o)f66K(k9{1#OdvR|l7vYM`o+ z@5e?f-1ho@KFCM`MHXYE8;Kcvjj%;TDj%x3nk!9h4H3Pj&k^a?p2P;EFyO3%ik4Av)NxjbJk zI}#V5R!WuaPrYN;@$gvaui&Vq5Mc#j=LZL2sCTC~>2|0vp_ukfiMISu`(TzWH9y#! zfJ>0cYTGQXzX!r-#m-v@0*9SrRWXk+=8Jx(8|pDR__Tdw+fm%3K!?F+r%P+12D8l4 zlF$q`rJ&f}E1Eypvv|yH5g<4P9Qp(0w=n)X654Lh;W1X4Lpt>DWk|a`!BdUdTNOhT zg_EcDOv2_%%4P&Zr~`EqH|auULa&F3T!zfuN(x)0c}gzE&KJ=O_1x5cH_O#m`mHz- zcF7K|8hpvwhyv)X6(l^X+M^}d)LVC zQxe8ch}Y7&RlWBkP#q3=(ddmh6+<=u!(t*<6Y*{$-kFeLpds%b`g$vPB9u=!^dyn> zLYxS$`${&iZgRCDp2&JprDao8L#SSnalC->JLuKy-j!@-_kah&XQyIs6}^2c>la0` z&ZIcP$I(rdl0Va@PxN3>NIDdy3BC#h>=}511EgPDOCqy#?i|rTLV!hw%-gS<0c8{ra*CA$u?t40!I1%9{ zigT+j80LE{uZIZgjH+RyoIg185{G4o#;Qo1DP9$*dtMcZwSPu>jf=$Ewi@W}>eQRWt>dM561swhltHh_ei8hf^@}Pw$XAGZ9>X zJJeoQyPztijpdBybhiz4Hq%2(%L|E!LAWf6oc$Cx*KZc2gTFc{*K#HT~h@^Q)4x2&jH-I5SizFq8{5t`OxBg zG3CgBhlN2O(LCti6LrAiBuT3yJxlP*eP?}bJ+aCFTB}z`Ju;>A>`zouS{mw+1Lq07 zJF;ep`a7{%ZtkyD#_hG;t5z|1=$6BN`Q`8-m%Ez~*&*dGLfBCTOi(_oYrQ0cWjz>? z0s~l@VqK~AFq{2{s#v{3$pvnLWlevh^>t7E!dpQ74VS7}RsW4X9;eh*U6Ot}QyWE* zem!v>t17Lh!Nu`wiBzdctBf9+E(3l4csH_&-l_Sexg`(<9eSh@$reXb(rPcjF2^&u z&KHP)^jg^hKxwT0cMAUu39xB|5AILXW9!qiLg8NxtDr8hYy_6&tLwXA3LSryn4*f-O68_@zcXYn#5IH zzeD|N4vIMli~Nh2r{I}qK6z^<<$uF(`Vz_`{)bXJEZ13fD}YIXoyF8*IHFWCvH{H_ zSOlw7f>M>LfBp2)lPAw!zkU4Z`SYhw)Z{&Q3o{7+Jn-9!t=5Q+4M(c7=Wos)odv2o zeBf1;F43HkgOP4nRCt{fpfRb*7z=pUX)TcTNgK&gIJiWpT2zb;_2C|SI=L){M*Rt z-_w_8rhA7EobGX!Fx2cWfUi+2BMuIz?f0?*N3gGP&!n|FPPA={ing9T)Em+fQ)*|r z0<6x!LO*}Tn^muFd&2lk=__M6BC{}5?N;~vr$=W$>T~5(r;9!Q@!50O3Tm}Jsd@Qi zSE9c-`}d!ozIgOTb@K4=EgY1$d|H@*F`LiEhaq(wAyy}kyKT`CS);x!lcv<>8gw&*q zB4N!vD1U3i<#HLtUxVTNMNFwPydq{v_&%lgz@56)fQn&Q+o}W`7>A`H<=(}OfKoit z)eHwOfB5?oZD8`Muc7*h$UXTgXVJ>*HaX01F+M7|%_yxZKXa^Rq_qbh=nvU$Ys0{& z7~eb=k8<(+_0Ke7xJ~P(sOZu_Q7WN*pfV5^l|X5c9L~`qHx_?Qb5LQU+cYTe78$^5 zII@`h&|qY#C4xn|S$poPH5^daDZE~nvKoFAtN6o_c=$j5&B6Ja{&;Ci9{FyS# zvC}B{PR|MV3w=aEu=%YP*D@|KO=Ff73pCS->vf(~VD1CQ1oSQ~)^(iY1DX*dkYp~A%d7}hNvikGRQ(z5}gooW}?)>z>TEb)t#2X zfhWhR)XYu@(S*Kdyj__$kr0o_WC2d&6Ragty%~;>(NgMfs*sFy*euqW^0c5?GHrAi zFy0sO9Oe?L=Nnd4jo!sPed}6W$2Hwh^EKRhSQqXMf1E{Uy zER)DUFr$mXoB$sI7EOpcHE4bi6fm7Wqxm5pA4!;g00o@M4{38t8wRHUy1OnJDGFIO zk;F}G5GQXW)Tiw92wnp|{7YF$l*~7x@I>bP#~tV2VMY4RxvPuW z^`Nif4{zwYIQ%y;7KaZW{v~ww-MfrGngk#gV1I)bnmSufi5hQ(Y_ZM|SMx~3K)N-e zI^-@4r%ShpjIVlfe(QUpmd&I3@eQOzA&z1=uvBmAEs0OO5H?+xx^&u}EiD%%X zv&hzotU1!M#@z<{9Cq9LxB?G;bU#O$n&z0K7X|W;4`UDp;nUeQJHG^ zl5xNze$aY%mx~S^N_7!xvRK=a(5+T8+O$TLr zOUf$~=I}VYRQgiC_3%J=8{?2ca}%}J&!*6JYfw7S+M@tgK&ihh!&i)bgja*|rCV1> zA}p%4j900Kwb`!CI?!m~#$vKfbB*ZvD)hkf?1MVhowRjFsP;fl=0%aoIJX&^n`?=( zwNYd#(Eb2W|HhUn%xk-rdGGSc1QKB{0|f0sDb29xs@TuUTBk*kLF^_HKIEy2yn(YS zj0>3RU|K)^<%#E54A*GUFg_!zK9Lks1Sxy3e6_4i`8Q1rdnlDz!prhiBH#0SaF0pk z`ygxrS_G}KY^VJS5L>Lz;b+hHR%um14m8KA0e|;YVV75RtkcA*VVx#D-nrE$ ztKP4#T3=W0{8jxEShZ(xp1lKZ$Et&$^i<=1qiRa?!m1_Bi=G-xS@pHoi48pnG(QKe zN$rdS9`p{w`a)F`gQ)Yuu7{uWROEi6_hzf6)yA4u!I~DWnid;tS_EsFr&V*^s?B=Z zH(jl7ojLPoY}0&&X3L+eO*0jmCx4bU%~973h303Q+408(K0zJ44WYv38uyje3hF|n9Hd#T*X98+~;W|k;m zO3g6}kG&JnF?4I>Kbh?l8fk$|vI`REM;)H~`~4K{->LC>8hwcNzT)DpO?JCYIi+D80O^e>UF&r#fY6m)Qn!q=5+x8NYF=WuLXPpx@$zmxQ^=eoQ9)a zPXalC^jDZW84#AziUY|gJ_-JOBg^(T+VN9&^E7Z4xzEP?1qcgH7&bUmEsuOluOdRB zvd004qjnC?j*tDE&LvN;pD0O11CcH`_&F*$5L*}b9|A`ALot=dTTvahn`pvs-}RU$ zl8qnl<1|AEM!`_DMm@m+Ygs09J5B0>%v0z)R&k5qpkdpYNV|(+cQ)(j`Kip)W}?H4 zm+J;XXu$EMwm3=UxxkKV(9+Uq7a=rlUGBh57)x0z2_?_iiAN96@QeJUNA{?E*U6-} zeP`3Uli5i)uIuzFAD&-;A8=U}@6$Rh@;EyZ4+2TNOb=`Bp<#PE_>iwp#Q%2JpnVQD z(?K@Q*6LE?3~jvVv>`x1A(g$cYmu?CwN`4^UP4DNF=idaEllcAi_5{_5^B2~M1xDz zFkaHN;Fr|(T>{+yWxE}eqL`~?^)YNVnb@rFvnA9|m0lY48)(WMv4wr)imEnATtL&z zPGIp;TAEO$Wp4NB=UR$O_Tr;EV05X>5j*bcq3U*k>?EqiC@EEz_aWI=(K-W*mntX~$JTRnDDqn$>((8^jK0lfx0!i01ec-LPdn&35JY|8{4wLqII_eE zi5q<>+sYlo7jc$=h_X;;(G2R@gx$UsbT-@eEKCA)%FS+-u@4S_avrnP`zg8zpz9t{ zem`V-8Kd+n9zS|HIOED%G0QGr2k>kZzg&tVH>{pLkc~j%NhqiOgMCqpeY2m#X-0Y3 zh!&|WA#Wagr$-BxZEs>YSf1sY#zM@7_e%9HWSDk&=S7^qR@YsdJ-`k#1^;xyzIUA` zhkPJZT7z|&cpJk?g1OXT>7aZvGIJY@&E8lBfJ0wED(9nt(uu(dR#uD&Vy%Jt1hd4` z&;raDz39Gz&d|?-#ZcS<%wS8gxJe?|#q8QbskN?SVjTdz4ZI{!U*=fu7B`7bfDL|{ z;0UoU#ayB<&_CDd`#6(?!ibUiTD8>T<*8R4@)lZcwg68y0-7G?UN35uYgA}U}J1$2%7a)RZv8`~1BmX*QcU{JK@HQSC__4aF7_9(!B zC}eR1u2Z$03`wJX1!;t;y)A9L3Vh0r1c}UvzVH&F`{7MoB?k!R1HV?j*$5iaSYlDf zp6a7Vt|e}J(hxG>?MCQ=?R%%(J>V_1Xa`VCyB0f~Yc|7puIV5Ix-$Khg2o`~EA50G z+dPU(h+Dh=vAnzd%;Zr0)t95KWSUJUnBOl6vDc@qfrE$T;6Hfw;Ex`P8KNou!&;Vo zNAX#0DT*eMHs!Ot)piA7H=dAYAAt?b%^1ZU9;1M<2oyePS}`#EcRiP$F{qt z_JdSuUeToB_Txnej{PWASzW)(Q++AMy2Hz{$U6+{nvJA1zNN4wpSIg ziF3RFv%{FP73#VmD9XWy1l1iIB`8+8$OEpw_zLaWeV(a2kxn=_DNY0W(f)a5(-;N= zH0ZU)TnNv&o@+FKTk~z~C1&1D42a_{{%1|Ojy}T>Eak&iIGHbbd=Rk}iC2IEj`~p? zB_v@1y$A6+ub#{aK9 zU*rhjFIFWNGKbhBnPbk`reLoI4cHqva!Fc+)^7*HqGu?N>I^uE2NTP)*Z zz7*2vO;N##t!_DJND&FJ%u&j6n%d#5Y(_Z2CO9X*)j=sLenfpv25Jk51Arj9P4O60 zqV}DNX<-4jP{wn-@rjTFL`Pc&)r}MAF^QJ;UUo%Kf3eso){g!#8X-d&N84a*Z|AJ$ zL$D&wM@`}3l!cgKKR90OmQI{(S*g?IN~7x9%vF0U?G1-mc+UvH2y3jKF*Ee(Q^-}3 zYqrrrHWhsO@@)Hksp6U8^r9pbaVLOQbZE8)f1CWrSD*C22U>4 zZHl)k@7|uvK)QY|qb*1=kGFHrvx)o+6({w?+VaGanftTSlSW$~YG5Q7@b|=uFo^Dk zOhGz2Rp*q~b;%EE;ki!w;;|W(r<^|>p#=jbH#B1^4wESC5;jTNy zp1GJY&=qL-RSM8gItEqY1YE~?l9_-&iWXFHdJxzEPDLtURJmp#fs2A#v?GF;DsqbX z(-D8hQkJ4y(HPU2j|F<_fVE9J>B+}njEga{g1z1@Q9pQTeEXY1B(jm!D$S+Vi^bMB zp}gVrDHHlcBx|zEhlV6pY0U-OqkBY-_;7I|56?+&RqQf!Q`U`wO}Jz@KfB9b1V?t; z-W(X`JIsTd!*QVr(HGCx#W==ycxHB#R}S{0twa;s88;Ym%iJ%qMz)CBp5kYgkG9f* zy5HD$n7-bCHsL|1;E_1LwXeV$6t9<>*}a6CX-Z`hx`B}uPHQHRDy!eR#?bsZK=m~V zhO2NlEKM)$igg1o{gsVtK$on7*C{7rq-i?ok~#FnOV@3eHP8R#uE*Vly3$ou$b+Xl zX^x-92V9#n7%#-sz6aO^<)3Xejwfa!@LESYRg0@?4chT~2UE^x_18=C6UcL<(Lupi zDZYu*Mu#S7oI;HfIqb1Tnaa$f0{D?tCp+33xoC8%9TK65kp0Qxy*68goR+OGx3dj# z9;T`z-a}2o4{@3eWfcKo?Z`{kvq%9l0|21cRguFD&rk>ot3l8FU58W;-~RVG`>%G+ z^a*p8areU&I#skI{(pP0zEW_!Br*(xp0j{pNWv6ceZbplPMW2QdD;YB+drL%PS17( z=&ar$woD~gahhXDAi}=T)6yN&JkjJ9z%n!4$DmpJO0()Q) zNXWVXj;VU5`1kIKwo7@FOVdzmArqJjf4oM#cEy0ux_5;;+7&3Y$PtUbZ(S3w%|BM} z6eN>3N_%L25pRgF$QF#2>l6*+O$r++^m81`1A73GZa>3Kyxeh771-vm9nxw$2wRw( z?Kx%`&sJ3QRMhA-d@UUWrW;O2t$o7T%2L~Ku67@(a&KAMACWzhRg1S~>K8F6xO^A# zDH(jlm?AjFZstYh=k8WSm_Y9CK=|8~QoPGtiO&kz)MRxuFP^?UoA`+lA>;$~a42nF zaXvzwras#G{tO*9=*gzj)_=_bwQ^NY$L*P1u*L!MbF(ivnw%^zf04*cHlXtg_=LlH zvW61o!$s!RXT%-quxZZmNR3b-ieg(y@GceisBFz6QY-DZvgEu zXO-Z6!4ck~0w)i=5HYM5T+6r;47;(O{`B;5(3ww`w6T_7C}O(BSzgwXBVEm{9lirdk2z9PH=DFjl>9~ zS~WyUA#Ikyee=tYkIqQVh?iR>SH*i7*lHOe$pcP&)SifLDtOmL5M>pfG|B)0GZ#2n zkr2N?_ep-!kZqH8Vog4Qi3uQrYt&rApmkNp`468?oph)V>OtWQom^!TZ8@fY#!9P;|CibmSsg-tM~jh8C$42ySMPOWlnUbk2vlnb#}aRUIz$%I%G zNXji?O)YxeQb*9%(QxcT*>UvO)@_-= zoF{xZ+HzJaWX@v~Y$-Te=k;~EY=*69w1s`u?eBNkfWvFowJ|<+NtOYTatm2fhchnP zlH?8%u(X2UQjjMxEws+3#QOdr-h6`tw(ERBH)Sxlz^7 z`kFzt{dJ&uqG%4!3w%0-e#MB-ealf5m|&jn0ZO;9Vk{Se=Cu;j7p;^s6OYd=!cpZIig!hFE3>nFNoVBdsyI{d&?v!OVp=gJKSBj&cy+YM z>26;_fyx0^3!3~4T3Zb1t=URXxteXmA9-fFRzJrJXOq=W7&K(8kd`lTY?-O;N7HXD zWU$+Adm*CFzy=AK42_Ap&vdBv-bY`a4=4)p>^*36Y;E1UVT|Ik%x(dTcGzX=q8|9F z_|b8vhTOxK2<5)+)PI|f84$QN1xHpSnPZqiti;f;75_mBKjBMUqrNHVM%w_W?%?oiN42ZF% z{vch3g*0uw(OAWA%76!E??a@H0&`5ZSgY&z_QLfXZONcT&W8I8) z<5p3-zg#t27;f6UDmMSg2`T83-okE-L5Z$ISGiGmQ^&th;3<#47boKU;@Fh}9)JHV z{~^PmN*68tE4ad6nUBLJNk<;(tjm&?=Njk6?iqUtw}H9rGR&^JI@QIzj+R9Q**%7f zIb=Oq%!iN`*@FA(@s)bh#CZ}|2`0KdsGHl2aIfZ&jsgLtmNCKkgBb(3cm}IukY7K# zGsrrzM{H5Gc|qGG!&U{?licuk_5UeW#~^G0#>Yx5<_MFZr-^OP2(mns)kICoC=wRC zjDB~ry0koBp)$bBQP9DVR4UG8u?F|inhny*r5-?kr zMSd%?qDm;KBst!ad+4&Lu2M)D)#dR2{ctg#*dyoD+eX{mjK>7UOidxVQXS9pi|vF< zceaMZk#oq;FGgXfi!H$gyA9de_~?08Z{fDEUC_hsQ?~dLGq%`i!djSFHw8dhQ@p+2 zl0oBcn}Q>()nY#Cz_#%&kq#fHK3#w4BJ#o@P zyW`JuQwVjJ6Z!r`O2A`QQn_ubgyNDN)o66ootN1uyKRh$?<8AG^Q5v891crXQVN8pMb`+>kRwj-a0U* z9Wc+I(g=Tvvv-jHqMl&3?H|&t@%EE)j`9`A;NWWw}?PZte_IJgGO7&CUpmbmHpwCG}a9fVJ%NV=bq95 zVCATvWWVkA;x@4$pBv4ndUn?VbQ9)c{_C!*ebbu({#RVgXPgN{!2mP`#daC!W+q}P zAvWjdyGbS%)&fP;-P*h@CGz`fac%Rq8#9oc*Rpw3KfXyWhDDYeNe5{i#^wIKRSlJ|IB8k_1%t2L>MjF$ybaL+Cw7$*{R&rGU z15PzT>QGn)*fW+(Bjo18wb?K|@b{jY61cVl;Kc5vbjf;w$>=N^o(Xe|?q<3C0QrjQ zNC|S{M9Xx?vz*S@*h*Cih#LrMbCc%ZJXAO$PzVeD3;`>b0|09tT!s?{;2p1B<}f|^ zL;<$wFEPc@ba084c2`rzRjty?p+*u;AoUZv{0sI`erPbWfF9z@Gk@M*vac_Yi?|4v=nmAbTEm(s3lyBc=SnW&xo!`+5j z#fkWM7m@(f>fly%`l_>)T7NROe5AVWs53Za<7W>eknJ$k;UbZ5;pN-I2+ueW5Kam; z!cKm6%O+=`)2>O%xXu@6#ghv1XXp%zP4RPC%IYz=<+niP&9^5fW)`DhVksw0hZ#nj z{ul35Hey5^#T_KUI|PAL8IefDIh_m@3XBHQV94`1=BBQAdtSgr!Wr(^lrl8yAGWX4 z#Tc)oGm8_!6>ouakCmURFE2RB9`Bu%T49Qr74RbK zDz(lRcrsthEBT?Eh{63sDj&!lYM)A;|Kl#EgYM`PLnQmz4p0?1$$lcA_n3Au9&P@B z7^rRdgL>m#-hGu1rXlX2-iG4{GaSMC{+lWI*D?j$-KLZ`7<8TWFKKg)@(MunPX~6A zzt6Zz--hqf@E!Lr=5;6y$)CdOc*H|VKtEXtZ4~hUm&G|8XWF%>S__&dSAb=Fc5HQv-cp>#r9Z~X5u3|i6 zMJ};E#$8k?jSlKkF4ASXFoR%ZNtzy+w6z#_Aek;`Fp1@Wh%wIV3dK}af16fP9bNPh zQ^*xXW97-xSeL5qo1%ILb8MVx+1eziZeQzW_OIWPl~i1}f~~t14(jf<1C9M;RC9KN zkHn(LGP%H&2SYh{slxshGGF|^?7a(j+eVTo{8!p}5ws~#vJ)q!M$tO5lhIv2@>$Mg z=94rQL^df{AixDcJ;vhw?e|nwKdKuIl9HWlW;e+>76EiuzpAUN>sibJSwP(Erat$M zW8O^FGAK54fyj+1Uxj4@YlMn5vI(8O8~2v?4mXeU!ApG1d;7C2F{Kp=@9}(3t0Hf5 zH!P;6J*N!jfk|7Di)TrBnbMxp?(!x&DMeleRVqds_Qyt~L-%+bo>{ZM++@dW6ONi8 zK%JDt9<$nGFR1hU4bCL)M*Hqg$Kep;(Pu4A=00 zyeYOGi~C}0^WoP$F~&^vH1$6okn@d4#I-aS8?7YPV@W$~U#TT)knhqShLA%dc0BSy@2oJ?ErupkFiM0WH*y zp24`9pAsF9oZ&04k1l!`*O4azbi$Zdl(r^X)eh6tSl~ZlEI?lIatX?ohdk>6Qd&4 zt~Uz!y6}%^pdg*@onk_=zz91og>_JsMZiFYRFjYJ7C3a)_?X|ueSJfTUSe&ZGekgV z={Cex1KB`1K({ZmO)EL`U?tW!$vgjbi7L7LF)gc*dlQdo2P<8SsaGxD0$?DL$$VqO zm(kO3;ZLj+*F)Ovpg@Pj{sTmfr(h}@WnCbg8EG^~C8CDj?X^R|t-k^cY_9+atr#4L z2&V7Bj)=@8sVsuJ1DJxmth)_cAa4rTBzw9m-`rmxiN=92aIyJGdG(FtOr;ytyJny=^(M2w3}C}4p}=1XrI{XBqZANHb`nD_}%2Y_|DdX<_(d7YfrW9=inM7`NGq;pvyul;Zmo!Qd8Mw*0;(7GeF?V?lQ+Gr=Jz{v!`H%M9TQ#6H^6k*u@A030Y98 zgxgw(eV!hgZS$g$bRMw0u&GM4LIF`-4I}X~Ln|S$95qux|F0%hBtiU>Ui~kkSN1yk zhapX<{`D~V@ika1tP|R>tH>H{iT0~;S)y%9a zw~U+hL79oe56k&kEE1bub$`nVv8juo(Vm#2#;)(E21hbWr)iBowJJ}N5<$i-Gf61% zhn!9qTbJJxKrey;?=+b=S0sy2jG}v!p=ZE{@2Q?MA+%QBH;*VaB&@N$ycf$(49_JWCFlU! zPpC)>@-a?rA@@_u5|A;z-ukMEu#L9c;axF!zAf|BJm zFSI^uA;mz*-Bz~K$shOU!u`=C&mSYP}G(g7*_=)c{bERFLdYP^54pLc*QY}P1FSXrKTou zpF$YqQrcK&9N|D=N!XpbF;ocZz+7~jHdHV+FrCAcbi>n71V9W70ZzB0wDjcyqqK}| z4A51v1lJ6EwIb{w7t5bQq4k0|tqzmrS_ElR2bCfw+{JsD%)6_)7>wmasbl0-Z6kYy z;XpGR8`!5{2zoEfXQ;838Ch(9e9*%d{O&I8=5jm-9A6SHV99`Vhtx*?>MJ4Rv^r1; z=3j)x>eB(LgQPf=S?O=s^d?a9(f#KRKL8`aP4_Ogp5Yq6r2??XEuCl7)3ge*S^9bHPIO8LHpjIKvB zOIbx~OE>&KyGz1{!Z=sRg8yVp{&z4YhgjJOAi_=}NKZ~N^Q#uq1|6DxhjSzi4*IqS z+^r9{k3QHIVU7eWEMyA{a*HF5@Y_MvCiHW+VJ9li`^cZsCu7&ZPEseVQulu^aYVkC9WnC{2k zA}`CdmcNsH8xtA9-Iu6c!!;Cr;o;!+a>9{y9DQz+&?1Bc;|MjqIa%DsdsL_`b+@9n zJJi>hk{oy21kNCYUq*EJkWgN{S_~`mQL7NG5jb=S&9F^7*_YSRBiN}h$(~@=nLeQh zseaxl@>$vZV(o(SH6>&#rDV;!Uo59-9d$6y zLY|M6?%(n7^N@mKJEKfQuCAbBgsmrrcZKLt*;QinrSkagD!UOIkPWs=H%{x6k`FGKkAr`{reQC3*fsfU|YJHP737*Ql4qsJJ z7}biwu4>*;60O&2R#4zVjLage_6m)7nUs`x`aeYre|)}vC3pSb&G`Sx*Z-UG_3Mj^ zem66e--NkXm$A6BWx^Va#BFD9ncVA+?ElBhzt)g}-Bu2^jx1~iOY#xC(mH(7;x+=a zHQ1z}vBrAL(Z?M0nB8P)yd!nlS4m4kM??6$-}0=Gmr_LeT!Or+8p3YG;w z+wt@;EGVpwFbT=yCGcvA4(l1z;4Dl$SDvvQW25OXmk`5y?qt2F3mwkcjX@F%3{j2X zSZf$la)DHU2hnJYz}n1du{<*CN5q*vVu>wQMy3oigqm$K0p;3UAt`J#vX+eu1UfW1 zn61Zg3^jEiXO|CJ5xdTWh8*KAWhcuVi0>hOASBqf2%$nD*w~pEwjM%%LNpp4 zx8~@`fwga(EP>gbLJ(YWbfo<^F*+cR)DW+oWCCV_Li9U<>+clC8lw`9tJO(4oB)75 z%FNfZK}K#Jvibu=TV1RXhyk{OUT7YoPJ6(n6(-?U;a7AdYCcRSI7=x1;H(jR9D>F; zFL7((`~E)qvWLMC zMig;3ZY9htQv;^zz&KBHn;M{%I=guUSZ^_~#`*-hnN;96BhdX%O`R#;^7`a?M!}9d z{g0x}cP5ph{;przIbd+AoAo?B!cgh)pJb5RxZawuOWvss!?etGj^C(TFl zDt=!``AwYPx#j=(Bh4Wc9Kb%`RW*Le=XPFKr`27w>zt+Wn z%8FB6c0y$*ep!v?Pjit@AsEJKCO6XROkAXx$_q~rm?gLtPqN|^!#Gzux_(Oek1$iv zeJxP%$s&$jk+9Eab__aK!$kE{KjZwX2gil)bB$OmVTA*Q67U!}6(*^&kH5Uyvk&^@ zGZ`aL;01FAXPzqskbBPZaVXvOV!q4itiBeip2*UwZj0%z zn$yc4=}z9NAzbTKt!T&^sURRD8(Et&Jsi_Mttg$|$QdMJn(2(fhpMep$WiGi{(-J| zY7ksB@fWd)dF1io`yCEsy{=PD6?3M9ysk_8$M=BS%SLp`iQU59F0o~(^&P>t4QtEL zV&Ux`p)=f;()xPGpZD56U)k?H(YXo~>i5rzs_s{3nC%Y=^Edq!HTrj`auur6);n1b zRdFaH>tU#nE^*u%jP;jSdo8m3ejmc`>wln2_yfDuY18u@&Nh2uw$&4}hdnWS)B~;& zJV9!cqT%x}u6kf5n>{hv>WRt2o|q7ri3=ux%dWyqR*-dr_=irbXdeA1M(8}zZ!_DF zRlP)i2mei0lv%V56jNmTbJpn`w`QZZRYAGgn5R`$L&W27#+IqI4kIIn6Sg326$}M! zG#U1(_om3GA8lBUu@Ezs}`^7Fdv2J8VA6sUx#5A*w4!)6- z=U214bdQ+{5s>YrnAYC_vJ63iW$oRAQ1vlQ&LN&5-8@yJeyUD$I|=qTvU`h4i5;Ks z^uFKRH1}JR`x3ih+S4GzZ3UbA9_Zr(?_FGF=}<;nEL~7LxPf1JMV&#oF*a7#Y`41_ z#X$T)uB|#X1l~5(#db^y64FYg+vKZwmQ*i`a!Jk_eYtj6^9Lp;RSSLr{WM8ERc}~7 zC<#H2~uf4GO?TOL(_1fGk@r#*9YK4Vr@ES+;_Ya=J=$;NXi-C|E)F!@!Uun#fijBqU<| z>Z>Jm%OP-WC1;ssutY7FaCF*O#~>GgT%sh7g#yX2o};rp+9Y*Q zrIpu(NbB7I9S!Uo*H{7#8o*$###G8$+}_wZ`nK}XdxxmPTDu2}w(cKAUVi5ty)!vH2l84;gM(W8IMK=shLj0tIVi9UX*_K37f~rAVFBvH zM(%KE=toCM66AyL1#Th!0^d_J!vKYgcv_hyNboW#&*?U{Y6b`-#)NT4>%BA0R{PI-*F*SGvMD)TDy=o?Y^R>>Q|eRRZZ4%HR}Y(W(pcsXP>2Y2eP9{ z0h&bO8nO(N6{KUVmtf6YS*o0A7KA))!8{Ob3gLlP2#e9jND~LvD;@Xk((no@nfuRH*JFs1_Ll+D zM0P9oT-G1;vs=eg;~U4VU8k}srHueOS(?wUI!w2`hl*e{bgv83s9JC?q_bLMHH{zK zgj?J0wW;VmsysCRWG_^S`lcChcGw@el)$m7?7pwOLCmDA! zdR~-lvIf(c%sj7e{FvCgYV)H%_@xk*7Fw2#3~5C+HraaHAXG zsKA*jo#cKbZ}rwQ?ACIeL}Y1QXHs0sv{Wf4(;Dd{>>H7YVJ4GYiyzf&$dLogP!ckJ zljz@~Zc-DS8@^0uGYP44fO=wnR3xHPFD99xq#!AU9P^35g%y|>On|`(a_|0 zoDNesa+BH{qmJO9xH9m$>5++gR=}06j$M25x?}I8smWA>G@gh98upweBasNYK6F)d zJe)ZP7+z>$)}+Hg{MGu=;_L$Xo=k$_1= z0!i*+Qs9)?g5%Zs+kv&pSV&G>s*i zW7S}x8T*X)bjqAxwf?|#1h!F+6Q^!lnpMcBD*hs-Q%K0ERZSv&@SrWlDlrE;szx)> zs?w|JWulViu~~kNASRT%l^O;X(Lf8T9XQ_1XM19v0JnS|!P_>Vx_B26VcgR@Gcq{cpbA4Eo#B z7|mTV#_N%tJNrI3aH_pTRcau$lvylYnLun8dk2K+=KPrEqScUkw(XwS?71gvH;6&Y z@p~3?RZ%OdTW~{r#@h+C6JqlWt2w@ZzY~PRxQ>}~X$>R;)@8dbA}RfyTqYay0QLbb zH8p$FQWKN^ssXnKpi6 zg7q)C-s}cDV^CsQXY{l=oiS5;r_KZ}^v2JY&}IMj%il2SXsm1$SlVW_rOUS0w#$Oc z_sJJ(t>(>weY&Mt1g`S*qtzlEzb==R@aVDgI?dAh8i!B84&eONW|zPu4U=p*&&Wxo znx6v0Tzyh=bh?2T=-02_9n4R`FTP^0Ucwx|k;9@KvA2IsDkvyN=&y8VL5HzBrxcDD z<@hWeo>|?~S#lx8sRT(8^;eEm0A!LM{jA(~jLg96*#{lChStu%-{X6A62DAlo*|kF zF-%1`2)%oY*>%+B8s>H+(k)n+zA*btSBUDQoXEPTXQ9>30Kvo)S*sd6&c!aM=e2>k z!%cMkm_9`**J!vwj2dk=Xc6V*)FO1-TeD+5vjQsbZDV?gSL$V>37^rd;fgifvq5x2 zFppb&TN_yKzHkt_q%FfS`i!HqwsKE%gUgu8sjB6yhcM7-`%Ef7S9wjBY!!>$Xr>5| zx+2r(#6}qpLP|@f&?@bT;mKlo?p3?LI6dH-i*KTBEAP-4r5o&tbo|V7(Nw9F;KVZh z+7;l6wb>OnBElMCS8U;%CYC8F|4w*QG^{}^I_S@x}Jj@PmZN}8;pKMcucPrNYD;f$ZWt_6XHq5LN^{H&@utNF>B6VJe!rqvp3S&i~b(^LnAb<6|s}0Zk z!Q+|q0Zb}eI9e-1G7K#Wv2cKi7c~fds)V7H2l=*(!#Z zyFslTf2JED{?dGMAenz0-mi#$9-4-n90+(U&(!&JhJgV<*gQ=p>2L#y4Zl$l*OW`r zO2R8wRF2*SDW;3h?Uqnhw}k5f$@8Hd{;{ySR2ocxsx_7?cDQnTz6E7=XzgMT53*%h zDcw`0gN7-HQwg^q3Pn*w5i$_(ri)-gy=oqU@HQ;ghJ(Wd0iz-9kj0nNEBvz5rm3;b z;$~N@RSkBi)qh6WC!487JyTl*Nch_7EkqJrqD*+1se3w7D8@l=aSvJ&KyMKiQnq!# zTG4q1-RsAxtK+nK{_6GfS8sz+`da#m;k5$q0^NYu!!vN5T@krc*(gLawm8OTq`TVw zFbXd0GB>oLgP*gYXP(#*!|jmbV#UncAqQekdg~Az@pdCz>q@L889KJxDnbttCMKn@ zWT|^=`9oD1?`OSv{7-;$oP}%x4pQ?v*j_7bq9ef0)_dhRD;u5uVBQNX$6J@O5F@o5d;ER z+>%=63G@n*%qL}*$}(=ldb)b==q`fQEkp~`wx0HP-0EKF&^)$*nlgdywMj~wr|GQK z<*aR1FdOK?J}uxsa%hHoZd?Bv~9N z?li4q@mgbE4=+)1%eh!LBF`?j^;IpjmCJGa;6CRZY%v| zg%v5L@~hbg*ilhb@(otbtX3QGxq%qtn?gnxZ{037Y95(g5(8Ka*2_mO@b|8SSX9)G1>F?mO=y?kQW%6@Vx4Y{mvBW_N2)3M7z%m+^(sIOZ!U`ARKnX6bY#P~Jk z>Iz8Wg3$>zP}&Cuh58P!v!GfRGAocGF;t?hCKWm|D>bxG^TZ*rKk;w|F^JYmTTfsz zXoS-cD8-~u;>Tg41MHGu;JFeP(kAQ$qqsY!-d1?3Cmke)Dh9DD;+V~ABj4sG|8gs16dn>u-2cG2TT~N*wkg~|-+A4d2Ao7#unk5G>7U1ew^lx*y zK*Qj3DQ7`oFrS91CQ~EGi^aYQl+dZ@hO7e;NYP@X&*>vlP1ObMpI14Rv4Om(?e$`q zgfC2LjG$;Ns#?5$_1r)v3v#k5zwU{u065^cCDOV_>h~bXB&!N?XhSKn%rV(H@@8o* zE|UuGVcHBF;K@y zD4r9c5#d#o3BbFtjQNtes!$!FDDJVhquAQyN z9g`@Pv(+Ndejij>ihICdkCz~BAm{&)#`}Ot-3-O=C<_X~)!&zYZMm1>GP);9sg4wN zYPX*(ZOrznyWpDlE5!xPFb$5qSA~R|>)odUC_4-9o+Tr@#XZ7h3GOnji^d_mjKyf! zV$8@-htAz_&=^0?OmIWo@|g8A#f6})qG8REFJpN;2QOt(mCFlRiZcj4obP($1j_v? znW6>ozv;v*!ltF>cdMJRF0jOS_S0Ft{zR5FGMO@KR(OfmztVg8OPyxixK$fX9AL(k z4d|sd*Lj8;yv6sjIA*3>Da2%wkn39j_4kIKM0 zI;3~U3XJw6ehNNja3zGls-Y1FGUZ(jln~%uS{w0x)_Hfr#kIWC%Qs2(5Ll;ponH$NymRQ7m zPT5V!)`jxGeD#%}r*Ld~%3%YJ=#H}k#bjs>S+yJd6f%DR8cY=k$8EfaCV()R{#@@4 zwwWA|ySw60?}h-U*VA|Tq{)vNyugd zYU*v4z;y~v3+<2Fq8fB9`KIfMGlBJ1TU zvE9c_MbO5Wjb_cxw(-iVZ+zY)q3QNGZ=Vmmo+~-Qf6db>tEh0I{Gon1iTKlxi0OAk4KCBEbaWNYF8!R21~qz>EoK7UJ0Dt-xYcwnCceoaAoUM*&MyzYQU>%cePAV zX^c@5D0Woa6`RDng)~qAflMebjHOc&mhVw#RDCrYALG^^R*l9M>ED8gqVi0V7R<2R zmI`hU9S%-5_^`<19CmgLtAK)}cm(gGuK3H2%Vcz$pzhHQ#A>d#pjp(%3N4_1rY-N+ zt=3$fdkriMmXhlk0Nrcu>fKfSbdLBDCJgt?fg3Rm{SDq&Tud$f??(Il)ZG7`bWif+ z-oGo=t5(lngP`r+g`#m<7Hn$qDXGNd$W!DVsD zk-?sQEAmlx{eo!W{@@s!fMhR9*5W@x@nP36E;)?CB^SVevt=8Q^)(ED%On zzLdDt?zL?xxJLh&W)gB*RZE1+&!=e}EtMpz_$w_7=FcbzbYSyq|7^8>Kmfx2<$(?X z)CV|sx8U1N%#4-}c?g9avN1J+J~p#bI>1In{YHCOqy47LT$_WqV=^gJau&?N&~eK& z3wWy^m>y^sh}$?D@Jl zlF*n#Fb%xM`0Y953wM_Jtc97#oc+;RsFqHC zG#k|d_kSiUwbo$&WT*aQr#_188Ul;xHeKq7{6C&k;yhAN9Ld=b+MkyDS<3gU$8|Vc z{!h;1-)0N^E=`u~NDHHzS9K7L5bRH3ftu6*{~N=KD&r42-vc9U2uqaVm$vhmuB$%F zstb)NQC&B-umZBf4mU6N_imr&79N&9X~wU!Ta>DU%6zBBfr&9R64CVn@so{!A72T5$+ z&CARy3$F+BGV>DioxQ6dDD<^g8oq4MmygQiM^hInZzfd*(AN>HbPy`=SV=PF?+xc6 zn0R6?KFX;`&e1A49R;nZch$9=#VmbB*DpwuXYJKaBveOtl}16zjO-U_`hi`vDTDRogbVD34kD zLsH4GmySxQXP$<(BpN-L-}0(9zqOOS>yH%9fT)e1w8s$Quzs+HTaMp>%7hFl7^+vr z^JysXEhA%`iJzC2c@1%BPg#~So%eG(o!6L_RJr0Q zk>EmMQRRd7T$vp3AQM!bO-MqFLHV)kK+eFUjGRxz3EyaHXE3lFI0b|Jjq4PX zFv9ne+#oB;Em+w+!kEGYug5C$I?JKe?Dt!}IgQt3r8`Q>IWe7QbvlD=vgwrkEX#Rr zatYdYCrO$&vKBX4+5j)Rj>~}OSm?Sk0k*5afBbfz;}@i_8i(=>-q_O z!T{6Uu!)!RNTMlE)|sXxr&~;jfu?V&2&0eA0>s117Tp458r*Shp+dH48VGlv|K-gK zFyYjn92+eNcQ@$w1JPj&q#Y4$_81odB1!qnn-^~jppRYC&HWakW@%I5LIR)+F=vbEvI4J$|TQB%sEHtc4T=masUn0K^@K!V$)rjnn)T~qab zVzXwOA$W(RD^7z0na`nnMhCnBJ(MJd$Mq0IZYQ5lPh|;?s_w@@$a_%b07%%>d$!ax zPuiiBd69;MFfLWmhPF<$Z)4WFIs=392?aMy0|N8S@K!L(c3UzA9tl@RN?sNZ*M?Iz zNh+4zk^)SMzfOj(28xCp6$o8{X8uZ5G}xV;usAQ|KHS>7B?GqMab`M)NGWGoGL%st z9G?4=9ymOAm(8?;+(Es9w=-5`A!Uc&DQp)LI8&W^l?nE=DkbTXaYi$}*Q*EyD0T&y zJfFn<`}g}_e3&gxy2}V_1M-qA*sfRk&5eKiX>nWsAmUhsIMkH~9_&TPft)z)7N1}I zX3lcXlLyud?gU8@5p+LxPIsj~xl$U9~4B9g+(Uwxc1=$V-jmq0YS`At&ZZE?XR7K%K zq?w9dXhCWH1{@y(q1?umDlx8l>&fHPSv#boll3ijuB}Rhzdwe6yWr}o`h&uq0%Cu< zk_iksEUN3OmQ#wX<$I*)Bpz@bDdj|7%_`*YWP)kfcx?B)$TyH9a${-&+oJOyTkQdy zwHO`mB>7=@A}$LE3+F~BY^2v#*+HZ@d3w5cLIFyzlIbjyjZD`x?w8P;*ATdQ$EQdf zCAE)H2>Y9UB+~*2QzLG@mj0+k0;-K6>RnNb{!f!N_wA^t2j&{!eKV)az+EFF?90f^a6 z&go-JjSlSpXg-utRKeG2NKpWJ);EvIB|eU0OuX(N7Eor3m$6CGgXUmRfzzj+ID}{_ zhsVd=?e?fOdKi?34||-3daRPbJIS{1ocVpy{d7s*SH~e>@tK1O&2i9^MWVbScv_a zqSTXDq6*zf0wf2N^=;Ro92FmPnNUa>)F6wh(49heM->)YWh8YC{BV7Xd5tA?ELA*v zlUiglsp@8aw+5k&ti1zM0WcMBnw5sD$XU%1F^(HZFgyie^ujw-yLn! z*2XAl@PS^fM>*F!AzFmbgI4iEgVTu#x1Bti>zGiqF7%%({6}12TEO;24k^|dJ@prq z)T6gu&?Sp`*M+?EBDOBzdW*Mu;qJO$x=fBS!=kB3d#0`=$VjBM zEJ?qlbwROsgX;%&?>|8}Gf+?Cacm$^B~Z6rr~u{K-oeuase-L2qNJ_1*M}5HBBqK( zdF&4)P@oO2)A;J?NLJ5BE}lZ6Pc$p5X2i}0c5Q#vl=!7q%*zrpU1f68W^4j{`0rwB z0vQ0{u6bv36K%HeMhzcYP&}x)i5Ll*%6KA@{F*EX$fRL-mY}CeSy6&_O3qscROdFV zEUJDWx^0qIfJ-Um2w=J7k3J)r$Y)}nXR@M5{U?s*=tMPu5L0B8d!Rx-^?)M}PZ$c0 zG%5`rGVKXt|CLN8rl7h7OQ)Bm=Te+>u0ABa)5Ue?L}h4FICFvm^%EQm; z+=u5=cs?!aGZHSA_ z!7sCT`E=v!ntYCq$3?5YWuc8;Z1NYD_N8G4w^Xp8df7D_ENXF73k6uj4_e8x2=7+? zvyFnBB^Aj8e-|<`A(Eyak9ifti(TBB*HzJ&!@5kOD841gq)HC!$W{+=m))bSo>Wop!GTtF7VHa~fL;kG{Q$gIeM+M?Tn)8e~N z++1*2jQ)PY=KQNtORJy0Mco=^h)RkFwM{}C1 zjhIwmz8Bf@uS0@DuzE+i)39P<0=-8!`43z|;}4G6je*CynDa!HlS(zonRv-{lKK#Li|DtZMf4fr$&x#Mnvdj_ z<<2{nIqw|hn)&)bx4H#8>d+Xs)8+0P{3|@eSI+6B<7;+@!dsKplUB1VtubMLC(uFBLL7u2b76_?Y9O`q-?uhK*QW;ida^uq8!@da7>)| z-4(y$(X#}*!H#U@%BxMq77`NNXtvpw!yV-o#5g1y_`#N&N;D;5#o&#yeOSG-RFuu> zo>_bbNzG}$oVFku_Q-!9Q@j-Ol`#kOMK9U8ymn0eq2uu|lS%m!hX66b;Js#5k;aT< zCTrOQfs51Vip6R5%ju5(+O{uNbjZwFXn%xy13q6n0#gw;wkLceI4c^r>sgttI#FEH z84)|xoz8u|Q8w=1;OuSO?{;u^RB2`nZ$w^HMOiz0Lk&^6_CwDRensXNGbE4Y6r@8d zw_3NmV&mXw&qpccD+Rg+*2(lhM>*Je;g7nU=Rjd zU&t~YU%w`6+Q{S*i}c|EdN7#}uLt7cCaz3YOa_Ey*)?7_7h-`Qti{?QOi`$*!2X~Q zW~(x?p{#suCnMttgeF&6F^RD!QHRQaESP@5afARx0{M4n`yJ(Wn^m=(0q{fX6?g#V zByZEHW~|2P)z7k=YTeo-DNmD$+$*w74zpsz?5j>}1GF^%-8aoUbw$REzRqul^ zqZzQdR}4`QmO|SmBsEX#z|kA4ZO?}{_Bg$=yLu+eX$557n=s*F0<D(D z;ISu@;hAMjNb3R39DSCh7xL&cEc{3{Bl9{f$vm3Oxk1Z?dCX5VCvoxj{)rf+CD!{I zlZ0zFDy>9@j_Qh5r*)-rc+aP(za!oa^m6GK{v9W2Rw1Bod_bTTq`cnHSpr*5MOv$A z^aW}T)x90Ycq@h2LmlZbhUUUj90-mGCCDvU$aU{ zHT79zNOO82Efa2nR^jEy!l4K$Nu5BP6XYR$wIO)~PzouCY0sWj1x6bQ#|=F+nW-$k zfFc<+!Ra`KV7jH;Kxb`OJ~F=qS73--f{1pORA-!CTR=O=zrtw=F^*anU6Y{XBR4T=@r-j zcT8p5lEZX9L+@I~fyVYj0~2ufwX*i69`N_~k(=l74F)Q=2Ma*pSjcl$zvuVX@Dx;* zP9!-}lRXfdhMgH^Njilu^Wgh~^k34xK20E z`uf-{+d%$tSxo;buOjL}4}lr@uz5LZLl#B@fg^Pwcu<;;3xhF4+4R+P?2B!fc{@~# z(RkhSD^m=Gv&;`3G)s6Z8!F=9gm|!neT}R1Uo834BH&s^wLKIJHK38G4YuJY8;$h) z;#FbJ&{B@U4y&M$WLlggekBS=M_24|txKk;$u%c+H17KG^U5i#(3;|^C9_&N!(O-q zUUPorZb5%PxED9_Y`1R+#G2frgK;8)4NJmQE5CEd;Xa`&apE8maxN)wZ~T{J2P{pU z0%|WM8WN5iwwRd!{*in$c8rWqPdsi&%PmhrF{shrx+U%h_*>TRcS)T+S&!4udsMX$Y_E)GCU1pIve)!XMkz1e^J4-S-k zQDj+qN4Ui;vlMHhSZM0F1k?tlwgtmT!SB4cW5`rZGD}kel8<1+^aeKt6(iO-c)jBf zZw~n+aQeYfFGnh*t^I%(FYoQbf?|eh$2jNigt1Tb+s&LSUTEGwn8n6wKI# zjz#1Oa3T|=_ne;+Mm$7$7ij$O_@DARI`cv`7GK5Gwc#ou{(^gmpTBY2Vws_)ZD= zXcg!y*JGS_+YhWjOE}n1(;R1(gNzuL=%{wIM@FQij179H_VN!{TsNvac`mPydxQ{< zDCxI2qnwTiwwN#EU*b(TlWSJ%z2o6f1guI$% z=`gLcYgIV|B5)zgYf&b{Yt;o9={Q3l{b5#|o)WCeZmvpW!$ARHNjG zKGjwND;R@B)P+-GObLk(>-N0J@tFw-eO2@L$<_26BWRJG>)J1a!_&>)P`K&%S^ zne_BCAFojvMfz(G1gId0jPv3$>Ml-Nba&9BH*+wxR=)y6*JT_%p1O1TJS zj-1T-h6OM~1JRk+v;W9v(_xnO#}(Ist<gEZV`Ob?=-&VDZCIK9FlKq>pRrm=;v3h~-f__69# zL{)+aUtH$09Dum}OqOY_=bkdagNzcU*|yZ}fn01<7BlkDsLLeH05>rfsO@%IiFsbh znsr-;|2_HQ1NCR|#Rmjj$=L$msk#_?Y;nR+fCf^_>C8mb{SfYX2(b|(rjU41{cqnxC4N9L0!sriJY@?a>;n3?2Zo021Za55b^EPIP4mWds}KX3t6yhxufS~X7AU8l zY0cF6ti;()5qjqo`yd=`y>G9>%rcy6HO{@SL$0T@Td0s#(Z<^9TCf12Pw}vr&XQqm z7)15lQksr@Q^FXKNWBw(~AnOUd{2&tMs5DMlsji@?0no|w(+&=)&b_8|a+w#_sSTLG0* zW$!{iLf`dWv+*TV*s`_uA!PC6?7Vf?Sp%W8x^u^wr{kQvjPhSk+RDJdOEe62F15_0@QHBAd z>O!S9=#ncqg%vTXdW48Uo*)B-RcR&{I~Z_V!8{rb$-`uSYox12Bboo;rZpw3%nFg6VE(( zUS>pQAlbe4d#0$?5C*QyVyXpO1JHd!KJvgSCt!SLZXj6dwRIms_I(Zk9IT#mTqYBW zBWB-KGAV~=OwT#b(;+4!(PgwrM`^+rC|78b=*(>dZe>hzF0V}hxi|8^=6F~ukqZ>~ zPl-l%C4I8eFnv+N5a&cBe|hslmy73R#_w|{)8t%kjAcDM+c-;RGno%m$qj5}@Wlr; zbp)~J&QTX`2H^$Ooot*V+YZOCJT}k_5JII}O3ek<@)|_e?sq05^c>Z+O<^NchjPM2 zI3y1AlJokmY>i-F<8(3)7vQ0=oDET&zTa+0SkRlBB6`UZa@!Rn=}!ROc4S#%tUn5i z3s0>faf6Xqe};%t6yqHn?(r=iHf6a1jdmK{#%7ySjc<^52~|-2vtlhBmMjDUN;#3^ zppp$%8iKD>Q)nO6gsH@79I&bF2pi3!D73@5r?GB(a=UkdW~Q>L;9%N;>C;c!eyOU4 z%u`ebe{Ub= zqYc+_)ja3CI{YdDtcF9a;?$|IFTk7t@p^CR{AajX{W{W zygEzAb;QDUx>KeJgeZpC^2kPN4~@#-%1ZNGmYT-HpzW6Pw*&UY4%rk8#`m}DW6`$N6M+vl-e}9la{KA-eyzt_ zIWbMGSz{sG3nEN;C9|;tyUmvYgg6zU8sN0Qg9TQ!lmj#0va2h8Y*Jb7Wq?KOz?L>< zD>Pw7Zcpr_EqX0=I9tJcO9XqKmvZcz_wmkB36{=o;qhx!dYlJ)w&;o4?MCy=@VkHu z;xwz;a>EF%plqrioVJZ~)0@|ZS!Sp3IOl!z3;M5PpDZppkeju(8wOphjFUKf$rk&l9Xb*H&aTTXh+7`g~o3;RqiGeDNapWbdv<5AWC;=S+uKWD-=#QRf%X z)_a@>)P&f>kj`sXO0WUZ*`X*K3-tjYuI`2Qsk%!)u5KiLvk4# z9t`}0FGVW;5;|bFMf%`@=@pchsu^C`hBe1F`AxX+@4{vXAfckM9I6t>aBtb{iU-In zYeOQp#16gLb_DV44@q`~_HPDi8CVRn>1wDvhs4n_!@?V5*Vf?3T8t9VehV zvZ))UsXkQ(VoTf?TbrAk##Q#peDVVBmPtM;rf5`V4Vkx{-KeCQ?pVos0fmzG?vIcD z9fj^_7*1FD?ofx5W8MafKscwJ{ONno7F3HePv5Jp z53)=>G*^1A;1f=R0rYl@F=yKb)d1Q~efo~FAXU^o^R)mAChGM4A(c5cr!;%VrP_Eh z{#t@=sf;uTHZUU1Mhew9GF^JEYk+23)u6z&jP->3KLwXa%E=tvr+Z?{tq-41NlXu* z;#o0^_|2AH!b}H5Sv=tyiM&YQ?p}Kdjob6@`S7q&>h9qt9RilgY|H`HB zPl>_mbhkswM8&cyC6KA;sJM_$D(R#tp@C{38f!;T+~Z-=rE;An5#cjma*6_${~Da0?E0Y&iM9qgxwwi z8s~oIb`jFDgegPwUG#*ST0fCwa4OC6t)8meO;c!!+Na-Qia9diE^H^JyL>?!=gE=; zs;vt{7_3zX?O7ZRc{jADL7+Je+Ft4f@Z!xcduY?*80}=`oNP?2+3_fMDE}z0j9HI1 z{Yun5?Hb}iV0wFWTvA3W=sb-nzaSb2Sjyq8FG^z>i@MGzSjpuXW{|AWknb!hO_DB( z%`_|vFqX(N4YhI%ZYM>j+wZ%Bcjk%<7Ap*T1UD@o~0z>8Rb>{ z^x3mFd#_*pxc?J=B1=|lUUVVL)1*$P+)9E1l+{r18*yJe-sD%*tSHXsGXk3%(6Qcj$3Q`nZBbpQgK)b1`C-14G@ zYvM)Me^?zO;jlwM&MeE!Z@n1i1*B_Jho#pAH^KJ@)yBXpwh-PM?dIrp`W!93JWGTR z!kJlP;Lvr1XMm_^hzR$FhOaIu(6r4Knjca`Hs`FFmBmn2RSZ^|Z`0vIM!M*f0x!WCofU zhw6@|fuwqBjUq=9b`vklZvEbJR}zoh#eGBYbVAs2if*2al9+IK%-GKm7PM8_&ue`l z$Je{NqO;lQiLFiMd=9$Wrx5=`8|T^=ySplSfh}!1GO|0S--mcF@_i-F>Ut)U30TW( zAq|kzN+RJv8|pKu9qB7;;S4DfkU^mS(^2Qsdc{JRV=xqQmu4ipwOgwS<(BNYi@@7%a<&^QtbU z*1m!FL`%E|jwu0|ohSJyDMwyCAox>|9H1R9fKNx@aY=<33}eVnfm6U@+}NcHtfZDs z!{6OCaTE~A;p9q-e8Aq8vYHinCHcF$O!8_B!t_l}{yAtp(F;2-6Pjh*@0vj4>`n^E z35u?J=6HoziiP&kR^2iS3CFo5FOfb`dZrU2r2Rcts#(fuabc!So$L$?(D*pTRHuLt z+R4D5YZXt;5`)-$ymyM)(C_56^qz;+Uosz&Wb-3$fF%C%q7OVrN;$u?eB#On~^y zn-^ZK3l=k}QCD#X7j34o7sj{}Vq{#np(tT)9-yb@`C{iN;*Z{mmFpv*z{;Aae$Sd`jJ296d=33zgmWG6NUpc=x!ybv4WBrEdC z3EpptN-7ZOBy)&+;@A}ak6BVCQ}KZa-pwn#;w-?u!ud?3dm#?hv>($~6bx1314=y> zN=}sI%IY8;0~{TcGZA@_Z-89wT06`XCA`HZ37(F1<@ScYC9_n_=BHUYG>g($Z6gD} zNHSlNy3A@DWvpbAuL*pTZF3`a$5#VnsuxM7Z9%?oT7r&LD&qZH`v{hYVDo2|qEX&eL4vTzL#VzQ#fR4GC(L{+dy+~?laKZ}KaS5tg z-#V)rM11OChu3C(tGcvHxwYvprfZOl2~fn2=>Id?*o}4vM@ORv-QA<3co%<(`w<`6 z?#&eFGW@wQujoy6Gfne(E#YID!@oCY;HJ5IbB6!ijFRhW_hxi+Ddl;!dvkenEfe^1 zjsJ9azv!p2ypqGnq^HqKq1Bqu)un^U^-c4~tVrqzD;#becl}MFzC1*epU$-EbmO{s zQC!M$FR8Q*c6FJeyA9N_7U6IU>|oD31OJuxrcuN%pdT%VD(;KxZC(Z^%dG~lyf;BW zmkuD9eYe&qx%OTJ!HgU*xTJ11c;&rm6!8lLTRL-EQrP5Hq?e6%%~IZrV0%-iJ%!G0 zMS9tI*DU3|2)0*wM(F{pqUuQ>;I2t6#0EUt#@<)z{}vg@Eykvu<#x{!Yt==l7>rwOKYV zlPsEowG0&MiBXRTRd?NmYl1lIDH_#Xck!AqraeP@y6Y}s6H3)H6s6m;kRq^>KO-O& zGDn;tD<20KghqRLPk>aLtxH-FFyQQU$DxU>_#1A%>0@7x*oVQy0HAmPx=00S7tm4+ zL`NF~KvH7U_qR$phDxkrI)&h11*G)_ltdK{e0f!jAjK#0Qb5;2Bhiv6>NR;JfW+8A@xvywtFe<&gY(;YSk+ z#fO0F5dCVDkhv;AKU%(zOo36O#MykBwB6%2b4AfmHCA>06nUe0nbs5YkpMU$Gi^8Z4Jy5hc!r&Y4WFFW&${*GMVE~ z6z`p(l~U$w?kA{cKk;5bR9uj+fh;D;#L;J8=0~4VKnl1VXpE_P#@Cm+ zc=Q=j&7;qZxe|4Z!2S*I6EH>8E7T-_m|tFjF|k~0Ze`Fa9Xy+@xx zFJS0LpS?Qz%nsQZmAc`|(pcI%LpzX=prOK?av9yJMWVWoy_zLMNk#n|i201GWS`WP z$(;%WNLOb zZh|NkBD@;c0(fbJtjxmDRBhN8LXD$Z0f{2~@t41dZ@OXwL3b6=quRr>q}(e;@@XBV zw9`!O8*B_6$@2@4s?~*f^zbxQ@$Z40LD_}wrdIJeWF-TC26Jjs`(Fmis9~rb*w_?y z($J^LJo$*Uhm|z$Ok_y`de}YJ4E=;}f>x~ZaN|d{j0?WjO6bv8YBqwFrJj}Y0!(tZ z?JJ^=uP3aevKA+!bUZ#miDFeJ7*C7U1u`pk1nt4dI*?i1RM`wol2T=|?x2nJ3?%W0-(SAA<a0YjI-9^NCWt;R}-fQU#CUJjRh=(8+xGQ>0RVX9D_nD|GxOxFw4J|0`gy$V_D0)&+WJi!Puo2eof6qvoLB4* zhj~u+0vvQut^r`b4x)x$H3q}}ZRn#%lQ!)T$HygZ`gqX)Ua875m}CczQ;p*Pq4hufaK2f-I>2osC-C>b|6M?I*P=|y>sb5>W__npVUocV z3@$fK-WOm8jzN)PJsaUDQrLV?bkt$f>DlcNh!bTNj75mjnne0Gk@Wzqd0i5NMo#YO zdXMX+8|1+)+(IeFBJz%8gxcWt@w?ZKU$L#4v!nPi@6}MBnrrV7e{X~%&Pg2Ai=I6R z>j7xYooQ?^C>PH8;_l#nUp(hK7qlp;z5Cm%v&)~WQ-_DUV#5R=?F7^>N!ZocmudzK zlcK-al*YJ0>|FN1DkGhywX!p}R3n#{&zd)Ja)z@T|A85cfkT5Z;!3bw>wbPJ}Cit4l8EE3W8@JKE+* zp_7*BMdz(^Rpl=Kf>I}wK#AmcOAHy%uR+fb@g-ZiR_M;$=tsdQbJYCah4wY zY^Kgd!&Huy!vWQ4K9?bG(wSNf-m-#6NB4mP?8NtXJ3bq1t0Er>Q?udnLyf5?Z!vPo zo;<&rMV)_k_&(8rX|_gC;tE_vyPH1PU zE#5I7H4Sr5K!0xEr~sdswIUs}TfULXfv8p;ay^xh3lpzgro@yiBT?Q0{Xk*w7VFb2 zIy}tMXly@(e^@9ch4uG2*1G|7oZZGr4g7{(-lPCMMJSp}Xyirh6rxcHb~6P3r2z$m z0VZ}+V@IsfFG9py_6sYm?iZWEX15xB_c2UMzDhZfS2MUYxq=}Vd5B&tp!AiTt=ivf zNekIti>MQ3kR}fkymd?>)&8yKr$oe~hrMPoi+~Sp6-Ke+qoeyrN4sD2dx)AX(}P+A zZSd5XkeBI|94TWZXENx+S~H-8C>KfQY$P<4u~wpJMAO_qU<5=lLT_&H!3IxZ_+SeM zM+ujnXRk4Q`7a00W1|8}&=(S~LZYhYr$z!F+j{%8_;vrqi?uIF4f;-(FPFYUbfL?n z%%je}mS-!6@)PGG7j;kE7(=9?C>@{i zuDdtrWTd2dc}Qg3>H~**ux(`oC}fqTdA%X?3$0sIdb5z8j%naL?OTiTO?$>$(SZ@P zz{9pJ0cW6p{2LzwJlQe8lN|#**)hNqhsnqA_%R;?Jn?UQ4DiIi z@xH*5?aPxV940*3dQYBknDE5EahULAVZs;t4W8U@cI@zE#|}@nJ$SP10elVN4a>k)x-MAbqc@1Z4f0)NZ=yS!ssfB>UB{Qf1VeYIo77^ zC_u_U^*=oNOza&TC?_x_Ph*C6k^kx9G2?N z($|(AL@f;w?f3PWs|suYo!-FIF_2p-lUHed&Fof~+?tLVP(b_uo_ZJ@9|YAUhS!jI zT2{j{g?LM&Vu%(B=5$c9G4x>sv*__WgM^zTu+Y*(If})B_O*g3gKRFPgd=6|tSrD0 z_EL7TOuV0iGpMXVb4KaFlS(RRJfEi{d%R5ZQE^EcIwq|9>MQjnR{py1CURfJ)||YQ z`AC*vP=0gcRgB-g%P-$oU7xo%hp}c!`(htdW4Wxw^Q##cFO-N?&qt8Mg%a0kBpK>s z&>2gfT%?l(688j#V?F|}Qa(i|nDA@Yyf{V;PSlU&Xd-WFkPAa@(W8EZHrM^ez?wI% zzSxIUJ*Vesy^B6LgMJ@5cgRo!nQtJ2SwHD-J^uQeCyzHD_aA-x_}gzEsk#PhF#n!L znG|kE$*|tYlNw!jv?J>zt2;Hv;cXP#wk7;$LZ&CFqhY z^Nn8)`lDi4_1_jnR`q|Cr|f9f-2l~%|2PQ^;xD$) zZ5+n@Xv>+9XT==pF=Vt?I|MM>b_Qu$nv=QoCAos95DxFMD9^Q(&hIi*P=-qCBH#SJ z{U@FaVCV<>3ll*LBzQ`0#>{#HUPabY*WAb=X4GO$5=aAMuU)&M^W{*Pc7n?c%!{w2 z(X-X4DO6Qq>*|);D}6Z>ex=R>kdJx^;7Rmnr zOf|Apus`t#BrU8qwUjgNXvbS*V(XBQnj)jzxGPyP-e)VC; zwaNNb5|c@rxt0)fz}}JXL)Y(%FNdr~1Rr37ifM99k$GliagmPXNW~i{E^{O5(__b8 zIag}E@*GXDG@(jkH}B^c#ks7+iKgmWohYW87L=gGcdxRtbnMqWR?$7K{628Bwu5{+SzCs%?PE&H{cMjaeirze`~QeQphgCJ22hvJH3 zSSEHRj-{Y=8HR~a&mbF({^S2kuQs}(Izwu4DS=>Q#bly_L{)NEkv7i{BpJ0$voCDd zDd1phfc0Kl%&Y8Lfa`FI`^l=mSFZ$#F0IIos3}{Ck_FY&Gd6K2U5QG6qj}Pt^jMoy zRA4VxA@LJ04tmNTLEVh>9ju3myXpc5D86|1{D)tDGDlCz;uGp?PJnah$o!(C630QA zE}s*9%aQp-jL`X!rPUZscONSQ6(*)UnyslI^3su$va7EW{pJ!{1?jv#oT_A;lqvb% z(s~n#BC@G2wv`wb#d#{LJ_m0u@Yls$cL#ct3~@@*I)H^Q*tL5d&m&jt+t}!E6#wnz zi~oddlVB7l#oND$|8pST%<~%aM#In$)Ydl)a+* zHLcGgwENf<9pIP|9M9#j1z$FhncmpYK0ySps8SVs6q=)q=C8+*YUcsA!z3jf-+9wOa*He+4k=ld%z z;8|y#^2oIGB4#CsuU8F!FlG=gY{PN20?^YJg0RUUgbH{No!lr8giQ==sCXlg@G7BL zq9-01C9fME8NCIvq?Rv0C=+2|EjB3>Xv-#JStbM2$EG%IxsaJMMmkHXACf8^Iwrtp zN%ioX#{(71>-!zdCZRrTJ)W`;kBq9&0D3@$zxAvnL1{(y(r{)TV2Ct1h2Q~rl z?2X*bWY;zW%15P`~1yI!uHX8dfM@!PSf1)u0CI8Sppb8rP`Ni z{^((cvlPD~2ULlzO>sI;vys@^{N}sI+Ad(6mQ`)aC@Ty)s5Ne2v_K|FZ-M&tlSf-F z)G)NI$J74Xa!ykbbBn#AdZTLWhyuc8;X|a2K|5CQ4dd7MGvy{_DubI5VEopm`0A_H zLJxJJZ@zm>g_@Q#t(9=7yW)`;C@gB)Q*HUn)!Ezk2qwKh?7V&R^l$qIou26I?Z4T3 z@qBL|en0*B=f6Gw$Llxn`=|Z4FP{GJjz0Xf|MsuH{P6DS-rN1xudvz=zwEzw_MiK2 zpLdR95K2W5^&B`3{Hxo%xj|aExBu?d)0fW)TfmdEI!k8(v%9U9fdw$J^Y;1EmwWqf z|MBi`&)*#EzkbyisH)rlXY}OgD2_JoA8u_tIX*fX-R~Y9#WzPsqYn>zi=(5s+b3H# z+7d3*t|HeB8iT_EI&C)*BNnS@MF(oV`}xi5pWZxu+32})LsCW$wo-3iuBNa3e^$d%%KYY^SHKV6{PUvT+T4Uc49pgYNbcxe4H@|T2lB{AgGAt!*<@p zv?bw$ao&R=v%UZrG8Z=aga03H8V84mTlVK;`}14#^U*{5^O61eo&EX5{QTO&{o2C) z+Cuo+LiqY?`|}&~^BdcTZ)_hPTL_OWgvYiIk8K~mwQ#?+aKE*1zqN3`wGh6w5Wcgc z_|A^viS5G^+lMC>!V?Q&YwIEVZA))G{Eq!*N|(1@EnU1mr@}0HoCrT2%)V>9}2sX^u?YE;Rn2&&1XC)zBo~V6JF2i z>O{%L#khn(>Sqvr;36%H9Bp>AogA~O6XFYj8Vr(+9PH$UdVco&=eK{|+1gZ(2Y-G2 z>$|`1KYRB4)sBvQ1mW|Qom>3A3Y@{FUp5vu#xi31lWsgtA;FUq(#YH}@DzHd8Ag@3 zZqbcPIhqe;M5)8zwW$ixU6QHHHnbg_meCfF(gcHDd%h%(l?vIl08#IZ?))7Fe^7xR z-u1+}>x`{~X~%W(3&a&NQ7RqxVGKQk9wsW7&qb2WQ5{}@-UFYsGLC{Ju$i*)oQVI9 zu4Q#oy-RP($hLbmOU7-U6%NpNV5ncbEQC{2>xcNv5OB zqTt7=VM4yRvOW5!Zst0~gXZEP0~{Ng`UEmnEtrwdZgLph@ zm?k_OjVd0ziNc9s45v?KZlpx&Mjt&8lz7EV$-?Gv*Vx!J<*|l4p0SSk1aI~z?Ox~T zXui3*^~2#K(Az{q@fY!(*cC%ij(oTM%{IIpx?aOZ>2e~(7at6;#rD?p3+($sXrPZGn(V*^l|;r5I8*5mdxGU~1t4+kJhxlnF<0_tN! zdCnS2`-v3X_xyfI5S4xj9a!|3950Z<8#xnfkQV+{LZNF zW(PK$5Gh0mU1OI;4w1Pr5wTFD2h({p1I3`U$`rg0S{UQ@WyS_B2E3dvB-0{Oar56` z1reeZ1kwyPCA5KnEL0E;goThKAUiNxJA`Iy2O#}f27up;vXn^RqcVqkhvC;pIu02vMt(=dKRhsMW0 z4jRpjjB<~9#0ak(?yCZ!avyGEe&8L*=h(TSwwGPcL8qJtk6GtXt4lb~#0BqY=5m{^ zR&qn(ret~m959_I_MG9x+@Tk0U;qfIjJeZL5Eh*VKE+#VV#W0eC0FQkSX ztp%1nmOj+DiKj5|21*21+10c8Dv_Vt$hG^ku&dNGr3 zZ{lZUBhY*7+c)|_j?yJ(Lu3>BN;2`i2nO$xlVyv5(&u*%k1h5%>`G`$ zb3^j`SMK2_9=8pzSEzdjxQT<|Mxv#bv>q69N~&=h9&iwL;S|{V>9u%fOICqRD7&q4 zMP5t9>VOhPe$6||=nd>^3Ld((Y$K7_J<3r5BJYdD9)K)g`k939M!+G#eujP*HOS0d z3^HA9DI05XBG+1g($<1)E7jxT`Y~(Z#*?5!q#!1A3bOhTla|F|f+bU6E8%F01RIKABv|{YA z-Wl;Xz?uKqEOwjyzkq|3_LgZSs#~F6sAV^pWFQH9t3#1OqdkHUw-i7+ycNjOG&}84 zFO3DWI7)i!i@X|BJ!xrR(d0Bu*`q>>33o5`6tZ+gn!6hcr44{bC$lxhlzYVTgCQtv zfBqUL(W8AO)fMT@(@`bBGkk~tG$p=1^1fK3h-R6hEW8G>o5<^>`J_fsUysWMpElv& z6{xBJk)AjUzAF~2)I$-?Sm|-0KBpjo#q`$cjMPnG3BFmrYnHX%O4F&+?0IU=Uf7y1 zS`zj!=y=v5Pp7$v>3E?B+gJ~U@r$B&tque~RC1HEAu-c?nv@)WR@#2hwb+*o(fgvF z6bd~0d1>kYkT@Jg9q)rX9Qwia+414l4NLBJi}A+(=C1zcuKwn({^qXcfs41&uW8bBcm2T=av+#+@B&TxYeQzDnS3xGUn zyx_d7<7G{HM5p{>vlYl&A$3z(Vi!Sc!A`eCbb4@fx_^AMa|lTTCxdp_w-#|}?_4xe z^r8S9k6f1FsMB}jn9#M;$i6h2Is=Ey8AKy++F|M6rRz2x4L$Z*VNU$`oX_P#K23~* zQW*>UkIGrVAkhPT8ah8GJeXWSu3$b_AVJ2z;w!?qh6-=L#ExlvqU5u+)I^#r6L*go zzq3Ty@6k$`1{J{Q?rMtMD^vjkj!9urxPKGOIn&|5b9t_96u|;iuMoH>u5B%V(>L|n zio((LO>2P)(*0PG&Z?b0i+7g$l0;7;@2#2>7@5B|RYWdkAZAGSskU#b^&c}!Ip~48 z8J{7C_Z9I(qG-AqVEcf?qZ9U}T`)jA_7WD15N*{)@yPA>!P$|z#)Hh9?$-$6?qcX1 zuC6#cKFo9on0I!3n2O7}+a2q25TYUylU|Kt=5tvLWWExGx1I&MYD30X=L1>#6OlUr zP&g=Z4UO=8a8ZTe(8LnpI*y*>7->N23HOBg8WI{wGKnBiL`cKUvaC=9s5&jDPPWve zR_RJa9rB2veq6?`KbgL=u^!orfaZvm$&LhTT2;v(qQXgYxY0gibB*^`1?6fH7};BW ze2er`k2wohRJq01&rjSBPHihy2MOw?crDTT+M^PK9g#5V0+mc-U(pvaSogchD57SJ zS1c_#XiWk7U<11t6B^7%^u{V-YPm4PoLN4jy7U&fa-@_Zn8_Y9XXEYfxt$vlM*g)Q zhz`LYmfBp7hFvr&g}L2CVSpO9G*W0BQg>x4m0+mDGMB`nJGavrK~QyOYvFdg$L!Te zjaSk1w1cLd6^IYvc5Zy{o|0qmEJZE?PrB%`=iYfdaXbLV?c!4jWd!7kt?!&J>w>}# zv#WrP*$=KoKUYbbbbJ@mvs^Kh6}4HGaZAe2CzHObG{HF?=1R+Ceua@PFoE7d&;zC1 zgdR;APy{s&N~hf7wZj#N@>;pWH#df+m|(yFrAs8E=#oh7XhALCt!QTsc*k@xNS?%m zId7@0O{tV2e%xk&+WeRa+D<=>c1tq`#xmHrUoSbG480S)6{$NfhVl25uG~JdMhFid z@fU)``AlcSw7@ByL}Z0HX~;jdG46_+WWm;sJoio>KOVKQ4cJqwAf(}JIPw9)T$nhN z|C_{Ry09`$SDvof2X8I6iw1*mgef_}yJ zOT#XrZ8n3PoLD7`?M3kCRCmh&&Zb_O2lZjK#03*)pbc}Twb^Z>&y06rNM|$+GoQ0< zxm$-xlXUiqPg3^eHL_DLb$}>hpruOTc9{7w^HolXOMk+yP0CwQyaBT8$VsY@vAVkU z5{QEi7h#y*zbpcj$KFd7{@UmPIl}-SFgMP-!jrtBZ>Xl6 zKn8&k@W}fjrs$AP+pzhJN#K@08v9$R@YWjjQ1)cnhDwbeGc*k?7a8^AOOqyLHw$kp zX6<2O%cO=(#ZY1T0ZZrdf%Rfxu9!h8Wv~%`@?^{n`JJKaD+H;_xoOPTq)Phap#Lf7 zK0682x$4=Ef{b=Jm5S6?1}??&099yIVXsKBhp~J+7cNIZ?l~7k4^Q#&kWaCL?i(++ zshu|VCl6sfy1RmFw@kEJM*KXO=F00bpcl#sjpqJjV1rWKWco&5JPP@gK*T^1MoOY6 zy;RfWWoBBbAe#!9YcJsrEuX?DQQ;!u)v7C%>XWx`)m6}EjZx-8-jd~IaIjvl+S>NS z+AQufOrkmk+k`hcGo<gn0eh9GL2z~`1&{LpPP%O<%?-NckLZy9Pqw{FJzN^m0_}p zA0J;_1^SO98Geew@#H0Rp-I2MDlX~AN@ePyS(6&1o5I^*9i^3b4?aJd0+oKG8dO@% zh1Fa_J_@ZW7GRFFn?kma&Msy<{aQp}_HsxDBi1#E}|lh}*yy@-;1S-dcw(C(Q6RRmz5 zqiEaD)xk3O^3}rFJG0@MO*>qn6WWr(sKQSz38?o#H>7fQd`JfYLWqAD`}>FIc0Ke2 zfHB`zZrJa)Z&PAKFER-FvAD~X12B*V0RE)fB)^1zFFVDX%Ys+A`l%7d=weP4q0T| zy9h{u7mFr;0GMf?aB*2d1LI2c$7=?m!PM`P4x73ptCDUnVO;<s*?Ira1T8mJEasS97hRVg? znf7fO81CxluY5L-OG`h0<=sABWm=#;t438|=%Jh3IM|;qRm8>NQ3B3nJu6lQOIUW) znBlN!k}vJsy>WwUD&nP@*4@7E1$=u_Q-einB9eez2zp{Fy|7!rZO37M1nMa_)uWyr zAJTgxjo5>IE2=xb^mOi{sIQ^vL2%0z^jAn7%R8gw1~OG(2&F5+4g>mevCz^P&Hara z%Z%C^D7KQhTqjeR`c{TGeFY+s?e|gJP)fcav^A%(jG(!3{18Un%myWG(t(fOF!x-)z zq^UHQ+!cq{RYi7xNoW|-ruxkbx*vOtTx40qV~-7uBPJLK1i5IoUu-Tt%vejIWH+^~ z1r{Id+ZY<@cMQ~_u|@XW#D#aD`i1K?w+&iNHp@@oYXb9-j5%oZ0-J{|X;ViWjGw?Q zbLbitb!4W&TDP=mKzxg?o48tK8GPWa3vE-ArdBIzwF3HYNcTgQo4PK|GzQr+pGAI3 zN^G1o0*^cmeLW0FA7wx=w%$B^!OhJLYnV7&f;YR4#pwsg! zUWHtJayzmJfclSjxfyhfc3VCK7(%>IZ7)-VyZ2qDK1tW1&0V!KVxEFkN61dl=gDST zM9g=Ey=x@QsBw901?r1gpf7qTBKkrsVnpM`iy}dj`a$+rqmMlZ&{e76m9M$0MV=yO zghO`cO(f??3<>6Aw5P1G4n~|1H!6exGg;VDCRt8b5TAc`TQ2T`e2H-FZRqxNSTJJFs5ywAK>f#I~NJ(x{X84Us90~#!grcJUK?2}7F=WwuOd#uE0Yzusv{Hifj zOyxdq-0}TIQyt;9VuUs`mV?*SA^4DO$+N7)H-0ZM(!-xb6XV7(dLaUh=fcf!j*mkA zxE6bbniP5m7N6c+*o*0M@QV)|KqLn?apESUm_?Z^sr{VSE(+S5f^W)}HZT%!nUHc4yY=dZNhV{75cHjVX|2MCNa%po8SYr0NbjRTwuP*p(5 zdXm6ZA~hSMuYm$RDd>oM+@-Qk?WJPykP~gDIU&kYVD=U|XN{RO^kO#Pi8#MI;N?~E zWBjkh`m%EeXBFrLXB58{4LIA1u-oaqJ{m9i>o8H|J`$S!64I+*5CMmeoH_P6j0Cqv z{%YKO;B_{0&yyfsPEiG*Q%)h245g2TZ~RKriXL-V8^IA5vY&D-Gh3@%&5v3LBIC0& z`!UaA(DYXP+ko(I1H!)z2>&)9{M&#qV?Y@Hdn^duIQF7sir|n|dI8JBmo_QHJLVGa zm`i@gXe}yBri*AkyTo|9VPgCY%S0O5;kD5+(TeTaj1x~(>qPAE<0!cf;UZP67tzO? zYATaa5O{sm{bCfAj2?~!`=H{-*W`-52CkGId5)|kBwh^HnIGQ}cZ!D35h>8QU%oo9 z1RR!dB~BpkF?Q!h*DM5qAIBpv786vaCDO3ynnem7>gKt5l>&z5e!21d$e^Vh4X-1& zOGVJ9hbJhP728(4Rt)WcihKc|G;DKfL>m8*R;0`=3wa7q_;03{xMKSA=QTNv|F${( zbK0DuRZQXyh8Pzl@UFwe2VM;ZUaD1U$b-n|BUbX-(t35Z&z-|hN1wQwbdzaGp|iyc z=ig)TDhJ})#V{%~(h8>a3%gz!eaVp^bD zlZ1xt21FjZ6PBZt^Gt*qSc8qLFm!&z6AxsJDjBX`)P(qNt6eclej z`Eu+mAwzI;kq z{^={fW}H+J`zRuqo2IFmntH%0EMi5rg^MBrLxy)Qs*IMAx}hp7tH>I$tu0coRtGseTH+oOSJ(j^)^Nb9OIJ7@P9vi|Kh6x~ErBV?VRkAS>Tu4f9 z?2gGADREy))l7-TbY(rsCO4(&8^wJetNFk-bH~x(qbo*HwC~6)e zt+1lWm;oU*I)sTZ3uBYh0tNx8Izp&YeF_M4;`H?NtnAVFw3I!>|u~f7KiPM$5VEbOn<3|igZM&A}T$pLP#a7 z31PX0z90m!@^V9*VOCUZvYCehEykC(DMZhdfP&0sI)0+jbeyr8j?HG%^s3cOR)q~8 z7BV&IU)a?8`I-;eW=<2>(~nd@&&BNfjMM|q&r@B~F7}U)KOUc?GN^;2-*yfU_Ad92 zc0cYN9R0dU7P)PU7j(idJJBe_sE|*6593;+(0xK&qSXXk7miyz`YStxJfnDJ(NTv! z`LJ_*`tI!g`~Bm~lY{@aFHIr#fA^%}PvGYOe6ZS{7#zmC_9AkPaujA@{JR&0g#*$5 zNJFt%^1%SVP6lq2(C;5v7{Q`0Kfe3t{_d&NWwt#}stK^@`;=fywPYDJLCOh#O_;tQ zJNn1>?@#trYaNe2ykz1ZUhKM(^;fY03e^62By<i4e`oLV-Twc4JleZ__wnp# z?*t%7rOlj~b-Vcs9JqlC&W^^;|NHphbicTFe3H)EJ=GKQi%5_v`iDf`b|EZ0X7qH) zwSNzKB2IxY?x=F2c~ON}r_{^Jg>2{@Z%7l+_E_Y9U{lcaRZXJI9M;KWItDxq#Si9| z39(Y4n~I)M8Ncqc+7@r7SS3W4pZu~ggK)J>Auy+(f6`h#d#*AIcjL4Qc!$K$r zqd}WGP`CucX?vXdJ{7n}w8uw={Qy}u2>p-?RzH4^6F8vbYo68o-AW~-%=i(cqO|ix zuwdXl@TT}l?M}7t(uO2k`XtP-3m6?)QqH*_Q!ITN;8JKAz{D#t@^uPK1n&=3D11f^ zdv7R(j2xNq_#?La7*U)2-(YMCDu;Ec;B_we^$7L5bg5xPf-qp1wG?1>XasDm@pw6# z|Lq$a>y5#GSwAuiI&X<~cIYKQHudk6aND_zqOLHQZ#?OS%Nts%qMmEhd3`}#lMX5C zH3#o9*dk*IOWG(n{XA@<^%!Pq2T<>n(=O>#4*61enHK{GKVUP0gD#gYQ#&oW;NS-p zUIHd)NPTi>NS|_`ktpnq07^K5Z|s78N#H008A;Vwg^_v0hYmKCKZ~?DybI!9yYSHr zZpy?_Xb3n$#|n*Nb9+OoC<~>(wy|DC!`T@wUWJh?xP9fh@qLrONgKD9I&1T!Ri^8h z-^1oxg4HazO<(jL{Qv<(di^jI{Xrvc`2HxHgHgBlo_H*RbpxFdNy3oy!v{J0OdAA~ zi9Y+be|-=nJ3*Hs%0ZBB7fi=X;#0*T{MkcrY^KD&RO z@D9=Vb5RS6C5@{ye8OV%T%Pg8Tob#>pO`*M<>#;RIFFSpGp^`Lv`A7(&Ko-LVH9AZ1KuX^cap72;uP1;NkTh6i)|2VvSA)F`%0^-)#5WODVLc<- za4wQbF20(?8IL-V<^`bM8V>uD+$3|{N=Hlim&pi$`oq4-8=KlMd+9r-2x6Ib_%0O$ zINL95kFgj|v9w@_UY%LKScxe)1iOhbs}-BPQBjHVrp$X$i3mqAU477Hn;P_b8QAHK zrsmU=Rsq!C2W=6YAi7og3xZ0yUW0r=I)AS=e)WpTAB@q8)P*8DA^eQpen0G-1+m-n z)SjR3>ZQ|Uz95ZF(CNpFBP%Z@4t2Vy!tD~?aD2527o=~3z-yMpTxm2Lpyejbg8JfI z%MHv<^Y&L96c@7?zYl(PzY73ECr0 zyXe90!0({dIH++fn5;vL_nQ>)1~yMOIf0g&_-{uK5Jx-PG+eBDZj)#4;X58xXP#YS zTJf($ymV8Tb6C5vX#**@`={DQc0a(Hp0<(Daufgk@7zce9c0(hGkD@KWrP9pXz4DD z*pnQ|MkOEEI%in~W^*Dg8Bk!Yp2~csNN#Q-M~7qLYpSzEF+=X9ku&u|?%0t0%Z-zd z!qJA+%UV2Ga=lltGBLD;^~Q^>M=xjFrGxBEl_T6sA8(@s`S}@^O?tUbHKMedTIDjDU$V zu=o(RfgtcMv^|C{U?sXVQ?Vk&>oEb9zd-Y~1&eAYrr5M|Y)RUYL)M?LD~CVWt{lF^t{lG9t{l#|EB_60 zVx4DW*2H{2sEw1@5DRuBNneF*jNE;oeQMhv2ExuO^X?s;QX)EXll%uCKu_B@Y>up* z*}6lMqZdM5^o7iw+MjtV^LOJQ06TGgJD7U`Rf@{W<|l&O$5G~nIc@fIpwsqKpsrv% zZSh>_Ps4hN#s146K62tS?!xRxK(OSq?t_Z&(nkDfC_fLp=fL{80j?qb;a?E(55EiI zA3hK94}V<5Km0z3fA|c z;vaqNr<;vfFFh=2Hf5dZLLh@TY$eIL~4B7#2)>Pyn1{N0#AJfU@#FQ1t4@Mv_wILXHV1KpZ!qk`?D9--=95Ifq(X+Y4FcpM1_C$Vmkb@rz-K!el#uq z*^8+0&t6QAfA&O0{@GtnlYcgkQhCPr(b?QeWl6$!_M>X=&%THH{_Gk0`?J5I0{`s$ zXz^rIT&z`H-Kl>vT z`+v3rAPbRRL_Kx(f~x(qXY2OQUP`(DCp<|1hOL`JwRrYi{r=e>q2T}19>>EM-P6Mt zJdTIYK8}Y!_Hq297YCpD^mr+r%&gNA5VXMO* z37&^93C~$Ie&QBU@$;{7gK#u{*$0h`&+}7$bsv5xsy`>VXQkLrfwzkGhkrq|Km0Ce zfA}o4Km2jg{_y*t{VecaB75NovU|*#-ltclbkr^zcPN zI*!fB08K{=@Hs{D;p&{=**_ z`47Jn^3Nt>IT6_gb8I46fYRbSH5dABbX`lq_)QIW%JN%4W`zkHJbs0`>9`JIIZ<;% zqlyvL=)oS3;&1KIaKka%HyTj1@7;T8V^7t~udbA@gRR zC!rkbYl+p|$^C9o+WON+v6o5TN`!v1IS(6dY~Qf%x>-1j@4r7y(E zrb8&DaIh;$$k0g4`r9`xyMSGkTcNaN#4v`xJY&pM+D<1ijc_aHkNtQ-`pwR)o4f!G z(6WLMt7{?zGmwDXD}(KuLez8UfP!d-ELM54e42+`9SE|u7>1jHm3o0aHnT)-bY0KA zSxlUf*y!RrY78LrDT;q9xIGuuWP5>VhV5=-xoKSbn_CQyiw*u{8A|cJOsG7{LX!vYO6Y~ znp4T7EAgbe?fHvuW8X%nyQ2% zBT(%UgLi=pgb`xF-3SUj8+*ehsJ%wm*RV%b28!@QOaEhX`ZOncK_^R^;l+>#Rbp7! z=yS0vhRnc4&sF8&t&FPern-R{hJ^O!1zpsv$#Mj#{*)(gGkcr2r3^jKxXt;zUi>=e z9nby1PHh)OhN67&_4GhC=A1{*l~aqJo?_re5q!FB+tZ%DYWMQf*ZxZaom%cqgZWfI zvZvuGpI!g{XV-u3d+RArsobmoKZGpnua)ol zMllklfBVbiKXC^o8eh19Y7XIhx9@kE8qe=2IIkxmr8Aw2-7LnB$GKi2Ghs^J3xrKx z<64ba#F^O3xt}3&Ld3r3MsaSwL44~aF$p98+Q$TzgJCkk+{YknP&zp4~jVjAjN=RK~6FZ)FQeD=wZ;mwKb{lx5xRTS+ zsT*B;i83mENZQ2*BAgd5D1H9Uh#{S6Yl_{@%&76~iN6SL$SeCZB8N&%=f#fx1Q*G~ zh(ap(LcAGf@W5-u0D3iWj= zG*Eyu4KM-`fF+9h6KJQW04LVzjUN*~==4WjFD9d4;0Ers$1IKgK;ruB8D76KyQx~v zN!!jR!Put!&4-8A4C_+}hgczB2%C*{z}Kj(Fbw(=I}aOjU-d~i)7;skv8q@j*)yz2 zQ6&^F?D<;nt{)Hk?nLJA-8|ucp5j};MbiKp@;UP&MRc1YHn73;lmQzozHgf8L5Ar1 z0ev>;Y1gM7HcgJ3-OJ3{eslW{nR##byf}%%Nj!6+?=Ed%V6Pe5Juh?o4-}il>^+Uv zDnVCQ`c%G$!IU3Ui3A*|FzkD70PUlZ2ah;uI&2b5ng@k!c2Cu!nJlsXv}!cA??y`+ z4nfp&H41DqL(ZQF=~b2^<8`%@IMeykC0D9#XQSA*Q=S~u)&zCRKv{c8-A>auG$S1| zTE;*--KJE9iZ;#19Iyy10SRH$C5StAu`$mR=4;{%vU4`AY#6#2QR8<%& zT5mzIq0%9LlQYI4{l-x=hmbBUk^LYZMJPXtP>AdW;pqA%BN^?uL$~86lZpy9j`|r8 zA;NmtH?85e`<|6f%t`TW4s&0A44_+-`^?>|5EyBqW$7-#GpWjp@HUZ$$%kjYa9Ms& zHRl1N^2R7_NfVhJaxk+VI=|6w9^9C^QaA*$m~zRKti#hU1pM+n9xVpsX`!zCAzMxZk7 z`C@dSG95PVcjn+j%ug!MQ5DXmiJVhN%%ODeMSj;K4}Nk(I-@uV2U(ctucmMYSF#w^ z%hu_~r0w;?2lBfYr3R$5uq1FRtt#kI5+-h6!#-JXra?EI;~P>1vu~M{uwJ$mNlBIz zN8tkrya%!$MPX!dfbJh3e>^^^931_&b9k_KdAz@~clmDre?A`VUB3HxcC>e5xOQIX z%reHN@YF)#;ge4;kgLQCo^g1M-6)4vVhGa7K41MlpH}4Qe2>h6?6P9nG?SF1J+Nn_ z5h(crEjJiEp$OTFCh{djc@>8MU&2M8-*pUg*?QKJq{2(5vD_*)SyY2-5lZDdgb$K7km(`H43}KJWa?w@dEn zXLv62lWcpe^nw((6UPL&A>BaSb)3_2X=e=K^De(!GhE0}8U9;Hab4XjgA?9@n3swGBga^|L~;{Q`f&4h=kW%U3V1{QyVz5+%uDoJj<^a}2cf=-UPI?x%4Xs6^W@8}z8 zgGCz8dJA{C@U={M;Hy(Y!a)a*lVI(v0lEo3T>qgy_JP%#ZACs@-lssZL z^6u)VSdSbAU~~j1jCYMBz!HzlOoOJb#1Li-Fyg=d^{;;^N>SC68zxcdxc$C@>GRxZ z=I9~mMWgy{@mEz(4hN?c0YfV9PvL`gYs!Pw6h(sruvsMPn8TFZaIV`fAPzebO57yi zu=8RkJ?DJ0t7G0He#)`vt#r(@r#xjrzRNMsWBs^X{8Vi>cigTdM=;L%a}#16@Be>i z2gmz+cEK^1Stg_;ZN=1tpYv?QDE*{QH}zJGHe`FfT*J8+e`^veavvlq$k2^dFPD5p z<23R_;YQVc8Tw?VNV!Jjg3!cbDgB8c=d$#>Qe;4ArVI1>B>YVZ{w4)7DaeHDn~M?@ z$a0Y|fVgFfK(|mAB8UwtUlt=zs4pdnCpFidBJ0cubE-Ltmzji_|9yOLx}Pu2G%)&4 zc41**Y&01GtR>aYP#hCln#!L}8#)`MHX3iplv>j&&OnC^ddTml>zfm|pKId)fU)OQ za|WTf1HQLzZ`K=ZniB7^6?o%e7$tE6a2XQUneVe!cv(v-@BBrbK4mUtifUGyKLq$^vYQLR?163nwTv@eJpWEgo#;(JlqzYfC4nvEy<;Ia+!C zn`Ch(5UehOo^;sKPv{0b|@zn@OHoH9D7gGz5r&1Se!XLCD7_n#=Bu>(4O>tgd>IfUQ0s zp1HVCxbQB_!z1Q?q|gK_Y;dH_z@wWMkee`8*^ue|?vH(Fe+?zTW6E87tc=81sI3$I zFXEeU)b9dM>jtTbFty0^+(Bh;H0*oh>C^ZWh2zO4Sv*hxJcO^L>m{z=kI4gEwzIG7 z)E{`^NLx}uKS~@!x}Z-WQwFLJu?1Wn!59MwREgyWWDwi4t;F|YDu9H+g{=A^L_p$@ zP=yRY_|ldoi(v%e4G?{%kF<-bcc4heZgA~wl12K3xImFmtv@FQoMIGDcnpCTA>W zjp@?dejF;mV~;gIMU5lxI!t^#8pzFVl11qg@!%V;OYwiVAI2UKJo=M#@Hel6NV-c; zt{(<~VBL?1VOYWsH9o_jjD({k1u$g|`9vg0r)(q6hz6D5Cky0kH|}ug1-5Cgmcgts zzH#q7ehF=o#bdAI`S&OnWv2DQpY1XQ0Et))X}!j& z9R!_l;0M=fPtqJ&k9>wct1H8BhDq`v-oX=Sh8c@t@Xa)30V@ZApZIQnb`Y-+pEfA~ zwKhWHyM8(Xe*MjhV!DXgN3nPfN@4D47xqlcItq6>9dDR;T{z~z_RKeQ5E7SlfTYI@ z5}#QZz;j@>Nt^|DLHH0nZ3ZLSxN!88e@kn;cm2LN?(qsyOGyuljnjV*5eCHM3ufEH zPy{oggW4-c@^pT~dCuQT;rYvl?u-X05Jpdw>XST&IochZ$Om7aeWhpv|SP%~tSeD=Pv^ODpHGto{7@XxlQh z#7-IDCCXHYiO=WS&(^}PksBl)TlhwmPF;L#&ejRNM_3;W^!(e5U2sCmI$>Loex0+M zgRU1aRM=>!eX$~GPf`I!W>;j{M&^UQGkCiib_KtyJA$9ir9WE>MIWd&4Q;`R(NKrnO9Ua3KgnV z$33rj3|h}zp!aVS>{Z8TZ8VDvFtWNs%JK#m( z5R`t9VJD>cS=dPe{>%p*c9I6c#G<988k?3DoM%3?7Iq`g)#;M>)|{gsc7lRyWk=-C z^Y^9^De3DReVuqgqQAYAJvUdFV+8()&3oY~_%XfmoNH6xi3(XW6+dBJ=9j2K@1|9q zb4{uQLLq~u;wP*LyHJ<1t}aEZF~=AvefVz|EhOHDQF^&BPMD5UP-~8{_G7T7^5YwR zR%+}JD+P0OxaY?m_4L))SyoHtnIp)P+1lCS*(do$CMig>uQEk@YWT#6rBVBgtfLzw z@gJglj&DZ2UfM%KWKWA_>iGN}GUv4e<5Lr+x6L`~z0)GglDY!r}Pp#Di(>IsDs z7{f8g34m7x%S4DGfFPJ~(Z9eZgtn?MScof7hPj2c#qyL0+jI~SNwfwLwzo;ON&Irz z;39F$O+kA7FpMnxGjfA&IIwK;npi%FgKQaI=QzT-f8o%v&TlUO-_Q9E{@K5{Fal9S z9{Fb;c7sLJAA;C^ycT!>mVa>LJMxAL z52cT$0C5=IN;R_--3{FM&N6iaMnL>KR(W)`jU@pv->OLI3CCm6y0oc?aBw={Q%n?p=TrZ|APoMH6LP$Nd2;sd2xP0L z#|KBhN(be5|8i$6>W0tj-`EX6dt4UpcRq zS1!KQ&#UF-i}PxEm9qs_gXp?y-^>#I6m2dP-D?#$h2H(Pe43@lk57|K2r_BYrfm|6X2mlMQJcExb_3E zVsiVFnCAh2MjbbR8Gx9x>$%;w=k+>nkM9c9xV`KTz@yTlRbPQT6#i##ZB@s#wk?lp z4M*+1-?7PVijRzE;uq38{~8QNuD!@|own1FkjC#>F8PV!l8kRwYk`{Dwid{iuyb~8 zieTVvN6p+>kIhU_LaR*}j>65;TA)GoS_?3mp*Nm#+o`XtW_rukYD*zT1t{3n6nGB+ zn?Pj04jBco!Rg91kOXZXu4$=>3?+m{Q|a3sY=Sm$I7&S7aCr;Xx7PSIOzhIP9nhr@ z-D`NnblfQNy*SnGb_hlmre+3EI&lbhE1>#({8*71ydjO(U1oVbCT~bx{GtPrH>4}M z97;N0w7BlWoeE0ao*O3~SgZ#g^@|2kZcM`&qn-J^AB6!}9#@p5);2MCj7z{>weOJu zn9PIztm}hy6pR7^j8U8HU*8Zo3F(3d?wFnx{4N>w)mKT|>$s!XQ|bzXCGMlhm;1S1 z=6@3F4XJ-#Y1rC6x`UeKJ7ed;xpg{DAYt~yjoEZnLqSTSyCe>HN{Ze(jT*d#%==pGdTPnfZ;Qm#0+@L2_6br72VOb}W6we*hi3>Lm zyrA0tHA1@V2HmnZhQJhP(mCvViPx79GJnUI zjE1n8_18B7;_R<-je@*U%YwX~19E`t7`!6Jud3s<9=H#TL4!5k-ma}QXWSSb^61>Z zV7)Ze3OAxcsdS{?qK9}?KHt|t;4zOcq9%7 z=}Brw;X~|2F^M70Q5OuD9>B1p>$!a}SHSp6je5E5C(QYYyB112+n8l%8|uz3KW%3l z(|30HX*=6sJG*R~Pc>|2eVy(lRD!L{+rc?E5N7EI@90*f?m>Zj?_aw~7$M)*S`ZG* zLjLCWthC*$SCk8Q^@>=cX~i85kC07-9zOV;D2&5i!c0NEgzS%p{V;+HTYf>Nw_0Tw zg-HlAs<;42cTgA0LS6>F0o3*IyL{HU{lrv;amO8cvrnX!nMi%rFp;lF{KDV;e&1c< zqkxCe0MErR@-S%opfSssjqI4~I!|G2zxR%83Fa@q)(2$bYH!|PRl8iX3#afNJHb%Xwd?_cGKgV;h+V-9!4+ z2?J&+8Y`1O{(!RLYOUT_URhmR-*DTVuGhQ1@o(??gCHD!iQ;5*|1h5XF3tmQx(g}b zyaz&Mg0@r|Mb7;_`yEAegw{d@^7-wCU2i9`1YPdI{e6##l*s)(+>#qjQYziw+jNZc zC}Nkm)}cGC!y4<6G*)Npapz@v)Cjj9Bz5T33M8HuA&-OYBvwG#S-sUxV#SWH5&8~A zi{st%Se~nIUomKD(uCrESG(oM3^a&-z(_^D~V_$eH57?<0+Gcn-@ch`1B|+-gNAc^4@QN zLBN*p{gz$D`zRb71c^14mO-Zho7+@A!ECJYn<|1YP4eaUtTD*5>Fekm6+vTB%1JUz zpj=bxl(5&m-_*Kd^lJW-iTRncSBn2TeMv}94C&!?Zvn#4GYF>>UQ$gG;rk3$?!zzI zZPc6&V4jcwtSsHGKQ@DuJ^W&)ts(233^sgn)>dtD#{_DI7wI}JZJ0~p^@-){O=PMj z3DaAcYty#k~u(|DgTk#RSBokPyFzt37iM;lVypG z)#P%Vee=!i+ZeF*Zfk4Ze#=<6UT-s{A&RsLu~YX6_j^{%>5*?!KBnASu<4vMi8IRA z5+37C*CWt>3fm@RT5f z2ZZGn*cIBq*;TWliU8Znwd{a`c&RWm0Zdtgir$^RI~Yo_Lj0aJ@NJnv`G5PzA3@P@ z8e+GOoH#7^9)e!MUz>R2ju*#Ngz*qY-Pmv`(J5pvNV@!2bTJ>aGsF((HmL#_H9%}_ zk&aEuW#w{uG)eRr6=f7M@`jNYdqE zuldRPMFEXpF4I$>XacPvk9)fJ4i8v2WnH$nhc;`1(?NQOvk}}~*KW!Lg5sKiT8p9X zGU@>s(BhA9JdZ<0wXD1HFcTIJPA%3hmtlt1u(ZXOey3Je0(6)nCdea0PvxyU+kSO7 z$ixVQnbQ@KA<#2UtAO8Ys^dIrYwl724ouex5D%L~(4!1c1L@V@_=C66CO$5T&T2W$ z_bZ*kBX*v${89lCiwYPhHrh9+_$@QsPCJ&R+U&3cgQ=YEO$-T9NOMY{azbW(o45`s zi=S`cXBB>WUq)^}GX;>5yODPqTCPSlBSAIGuHe6MUm|w9h(+t{i_XWxp(wl3mux4} z+RM>ql*{D!J3Fe}*_ zgV1qRT*AnTB~6OVwbiC_ebege=F01)y36Le%ci<@bKSbBZY^iR&CCglX1E0tHF%Vd z@xMrG0ngn+1`pr)3Cqi5xc?GHVYD4pjT`pfy|(zRZI|eNsaN@DOXULWX{-l70_4pb z61?7fm*qG14o`0UUUC{*ffH%S;Wy=Xaq*kD6qsJcyj_s@jIJ6V(52uhPiV2&?d`n9 z9-9{{Kl=li=o?M}NU208TMqJH{c6~sq#QVsg#IZDfZfW@zF?=?Fh=l;&SfL-*p4Os zp&cuQZO)i<+8{Ah%DSFm6QZXo^A|l+bZhW!5Ej5#m8^Sny;#BM?!)DSKowENOsZ(C@LgsKy z2m;)EO!>BmlUB9=N}TOpMvQXz85mF|ZWaMfkQsBc6c{#)9=9reG*DXO2bNn&9JaR_ zuK~ausAj30t>r9-3Nsiak90Wxh+Eo}s=vONEmzoMPT2 z6=q#@T`?ep{&+A|mM8BTW)5rp9@Exf_^6Twt7DSoc9@`6jL)RBl3tQOYdicL@R@4( z?mr#RUjyHcJTks9Tw?uWXP4BLE48{UT5@hmGARJIizNgAD-wv~oF@OMWRK2=Q9tpA z{fY7XjQQ$ac&Io8453{5Bg6BL6~R5OzBG}(>5P2lHsLo`NW6?b4& z9W?ch9N(!rWBC9_nm9EwiKLiBT_M%sC1iFZ3CV9GNNy-VnAnL zOW|36J$?o}$CQcCuLmw4L&*Bhm_oMx8em(~gv1u#iP9FWUaC3u*J+bd&FR2~lzk9U zz`Vwlz2CIME_Sm_i<^c*%FEOWAN%lxq%u2Ldqib*rKt;<2Ww~ENXoxt%0?VRD1?)mq} z-rzK}2F{nvDILPaHqcN9vmp0xlu{3LxnVW;4EVCU%ny6ZKmpOZ}LRXgJ_NU@cORsBGi}mN3yI zn3F1eJf8rUCGQh_&)eP!Z11G{8dytQ{QH_+vaCtGU9;a}U-gUaZCX;_tf~O+);P%C z|F$$q9MY{bE|qtMU%~cIe5;$NmV?ebet8l*1SVvC;RJ1alM<4NaskH_h_&+`FON1jXsIx;S<)$1oxU=x+s_P@4eOnnLs?) z2e2ZAKuN>C3ua!UHnrY@?1*k6qE0iCJ;B2@iEY?YKJTnn?>4(m2t6Dp{s7EY1@)1v zoH_8npzJn6A@J7Lgo_jRK5R;l9=I=FcWWj1qg=ZvdG_mW-9Yd!N?Q|p>wf7vk#p-* zok?ulxQ}f(C&E1_80C=6fA>}fRl2g}sDM%DbMv+Q4k~a8@ zw$Ox<<6L&&i`?Q-WpgHRF~1?mM^uS)I)M?cQ`#eL5t&_K%AYy;6ef(rn`RJp4X>sT zVb>`0Rq1VdLsYu_5^^1Yue=wEq6#!6@{!eM&a@_Ob_Ip?$c(^^0W z5Wmw}Aa4IUjQr$gpe=Tn)&PY9)7RsbnKiNL?4nJSY7PSGakjE=-^f@dM%WdnNNn=s z${_6WBBQQrtlG+@qaS->@U*U}T6fg(Xti;=Ep$k_H)DhSQ0K#_e;Qh2XM!vQOf+Tw zCy0;OMMS%gOkJFOiLeXSL7XzQ#>TWc1HWXRMorJ)^l*qb^QuN3uSua(P!UF^72&Vk ziUR-x)I)gWR*PY&Pz~4I%zFh0ooo%INaPn%|Gf9Ewa}EkRX&74Qb|!)^aOb^{2p`L z-xQzu|Hc#4*b)m)@W3{f6H+VP4Wy#+#HyFa6B}>r(%rzeYUMkr@%Wro!27a%_qjg! zTsM}cLw}YYoqmr@z(u0AG)BrYU=iu~uyT>qF?*u2T^b|T%$op1{kaYS@F2hpi4zaa z-0wVZNFXXKjT0z)75(#saO5Seh49{sdj0SLp2A%p;+@mT%V@B)yR=&>IdD&RTpF(* zJTJU1f$;qXUi%=pNBhVeMFgoC^bqnJ?!2lnY1a5v%~tp{t=$C8v>VOzlBc`QU|8oc zBv{j$yte9P3+%dk_Unml!yipUtL3~_X|rC_INrLUrN!FP*8ESK|J5|lytc}_T3RA~ z2yKX4TP7X1-x>8WKL*;MBHK;&ej{BUoJ#wXrqs}lCS^6Up*0wZxok3%2aH@?^6-F40Ue~_W35Qp*VBkw-J|STLXA))mCg-s7;$C)HHcuw51szQ^KJwa}WlJ>1sCf zEMv~F2=0@PTv7PP$b56ET+MhMmWGWoA73+G%3rd?4@_He_KmGw$FocYC=s8I5MVUw zwsC5L2T@-xV=8pudu>Cxp76plqd|f7ZM@k^Kte~Bx^jXlDcDHQg|#a zQ9rtfJh&4~1Hgz4aEl{&N`q|Z^o$cZk%$1YRB9vy;9^2qqSRJy$=m70d9**Nny z8cT07aX`n~@ylbj$C3q3Wso*gtUS;(Z2Y+{j@UwzKop0JIXhtVlUUnyl!-EkGszp~ zNlZBHCnfeqR$3yG&4LDkp-w4GadpO4r>DNCI%lrMQj02c7F&QnkITkr0DiA05`=p9 zon!yxE;`JFjCrQ(GqT^}z{xHF^ClE<*Zupohl1#Vt+|HxMAk5l9n#^m+1I&*xP zR-c*`r%mYZqE^&idrMej7u6LU8m%v^sS4XfYMbL3+Ni_KGKxCLEMwq(M607cLQ&n6 z=Ff_%kYSQM0jo3t(ITm6^*u}~p z!tRu6lzj2Z^p^}(i~&z$^l+O??dgIy!+om4Q*RtrT2msJWFx|q>(%PUcL@u#kCA-5 zt`-@F6Y&^Ab9@;=z+Vv+W*GVRu<_wg>51i4A+<_vQ;#2l*5VGS2@y?9S_?xAR@7P` zzk5+==%&6&=z+9svh(S{AwFb(YD0MBPmw?HNDtgRGWS!~0=pjuMw4?*cRJ0+TuzKl z+?ZQ3XU01SSnkbyM-x@&%U##DB*uiXQf1wPF}00JTcv_8iT8NaZD|TdY3A283Dry@ zBhskr5*W%3)|gv`)u@-b6(IAl;6J~q)0heP;E0&Dah@ce0KIDXo@{M#c~HE`8Pzv$ z>dW@_c71uq9glAyQH8}9zxQr?%VdUf0@dc5M{U&xi}rj@nQJRZTmeD%=R9}Y-J4Nx z2PrVo1co=$qdguT)w!R}5`O51*H&cPIdG^7Z-*^3^s7nE5Y_DR{p+LAz?$l2Rj%dX z9oST0uv7_Wh2vQDg4$dd5L4Cx)uwu1(`Oy{UV~2*^D4_i^i=pvDGO?+Mig!8rk+`? ze;ptkw%Bsoz~$0Ewn<}E(ru)^G|XT~SY33)eri5jt{mNX>{>4QwB#3GKLBv)K%7Onv8` z>z~X|qKe>8^IC=#wO>D!#_DWJCA7}y#0IzHN|!V9s=FF5-RX8|LSXB`sj3xj75MS- ztJ5qVZZpWP%|qI{TRRiWFmFbWFYCtZ@<2&)AVxEKE0O9Hs%8vw*Ve_q8h7Uhi39%} zAN{I^%yWU@+3LxuWrY=)JyfFUb!^>jkw$HWKyL5+#B$LVlF6mRsN<0jC+{Gff*}qh zi~Xf47{EFSWx$7Ck9OyT!^<#IpstekR79cga1C}iol4m4W=(H?Vtpvwtkt&7u`8v{ z>pDWGGipojUE3m%AVs0#wPsiOSacrrEiQs?V*xKJu?}tj z+6%hA8)PD5D6Z!)Yqs#L0|muqdLd^+`zWp|n(1Yp=k+@JaNj8_e!36#PpR7p_v?f2 zs#)+?8iug~YCz5Z+`?RBo&e?d2GtE&W+zy*}+E2}!~ zxudKkY!cfL(TsOtlTzs}+ish3pj~c852E>W(`Iq{&Tv=~g71UpbBxArth&YC)~W9^ zynC|tPVL|W_zD#@7 zf-2DIEO88QR^Lps3L|||-;9&`7|lGVFq(NvpG{L5XXo_UIH!MwvrlR~$E;qF|26Ml z5GI)|{NKDiJPMO}wlN5kStj_u=J*$3VofzR$+O1L&I~(cul{$ASa1KUI|$DZZy?|0 z`$TY(!PG^8p*DSEQuRAGOehBk%``GwUv@U0f1*YYX6zD0<@3+9pF7iN-kGu@us|P! z;S3}uj1y90rgRWZZ%lQmHEjv~wx6|`&XxW0byYPxNoG~Z+CdZwaPb7Oqd9U0GiTK5 zujjj2<8RJ(Cy=pxtc7|l%St>=%`9o#IIS{wPh?G&58H9o1y8qQn4zd1; zhcC^Xhzy1!ni22AiB+Pg2yVTETg&R?82sC65U1C=Q?8ByrWo)dQb_ZU4bj!8N*2!WWIf~v7gcEeF%B%M_!b?(e^9#csvAY4b2@(wZ4z@Ew_8`9jnY2PDKew|)O1PB+CCH3!{L@xdpD)w9++Lu?h$TWM*tRXz zF0#l0HW=Clwn@L>2G<_0#0iIn{m2zI1e)b!db389m!6;2f6JRDJFs%}S0;d!XMY(+ z_7wIar~lo)=SH)PK=}o`n6=6ounfc7req52u+#1SQGp#we^_9L(qAaB zL+LvOb|^h5utQ$7hBThT)X)#}1$K}Rk_o|gx&==(S0Mjv&ka*(l#@{#^HSuG5{uX= zvyJlF4fQ!|v3J4^E^^i)+w9J=m?gtv_R!Nme<_k1WaO~SGqa5K zi(#x|?(jL&aNIv(+He?_XURn}_=|gyv%;OAs}3&{*e|Lg*5DH=&FhQdc1$J3U#5rB zpoq0a0u~x!o2l{NkRZp7U{9c2py@zaOd@f5(ds=Y*AN;`m0P|`w?nCz z+Jbq$ArCYvt+WWk#8Y)i;5?`=roimZuf(W*vqc{4Y>Z+xs`U8-+WnilfFeO&f6HhM zp;*Kl{!Q0Qq`YD5Bx_3%QX@rdw>Sa66-(KYxU;fmnl8&RTYWDW&8$Pg5`!XO(3 zMz$5B^in#u*~?xihbSKb`kPGn_FLs~cT3}7@Ziz-!n>8?8kvZdn?^S>iRN#0ZWnSz z$o(373d+9yq-a#~o}#luI7-x=cSw*LTD|NxpFv7y!#0=8K~9jQbid2NyxToIrzh$kV(v8b6Z)^~0cc}YS8*~kGC^elt4 zp5iwOe%f9#8uCKbm#}W;1imyf-*bbjpx>v%y3@T+M;tm)y+Y$H$!-%FpH_pakIs6Q zAP%6CXGVsDRBTZcydlROO_qO+_1q8|LnpgwX573Krmk>(xnUwyPfpE`b2;P3DZ0zJ za++N87z?HB8^R>vX&43&xr^SL;wa*`rsVynvaEeJQmsBJ;!Nr{CXmW zF#9XAL7w5V$mocXQ&LZBGp~W*nH20VsLuQq73|Kf&Ur0)skxOo$0Y;5S?q%*j^Fx< zo#TLJ@IHe}#*>Yv9CF8BV&IP9sQzib8Xr5#5H7fyYU_E)8=!PKH}M0uU0%-18Ue*? ztLw(h5AbPKnU9a7I@k5Atx^D+e>c!X zZ`bF@Z0Nla;hK3}cdpNaa{U7SbD`D=sGiGgcB88YJiHpn1319cn2D|GlPZPBPaRRu zZ!ct+(X|+Yo*~w3Z;`v2jpne}a(mnI%Xc+BAw||iO0-~J9)782iv$|AvY)Y^WX7}) zVB_SS-Ej;Vqr{Q<~vm)RZbAyp54B@a}i*+d3bmS}<^(TA6Jz;2v!N5Wqz_SWHMeOm4i0dMJU{To{Rn0`SvMRAhO$Fh*%4Y)|#XO^<~z zXJ|=LTyq;vf7bEl2w>6mX2#|$;Eu#fW1ezris!J5=iq{T{&10r9H(y-MLjfL^SE{j z{F%41hJf0n%(Kzf1Fs6Pv8h>PExWVN^?$zZPzKgRAOavp#rA^$lzMHA6vCtEN>)aiD+{7tNn%HNe1;?aehOc$CH+6cSWDDeRuX7l6 zb}3!k*om(;(XCO(sZGVTqZs*4xeh9n0vH#_DodmLj&5R%Z6~>HCvw|~ z?p&eniNW-BETUkJRq`Ossiu|{l86cGZ>-Kmfn!ZAGrB%p^VRi@&}X|nnMH{E3rL>> zG;gV|8YB{77u*8^U1IwtKd@IfRUrKmQ0`4STY;{gN|TVO_8DC+6;9)e{SxSx-Yl6n zVf^mvsKkvqq+VuGX^Z%FDNnmvGxD?tGzgZZbG2@VMxSE*oSHO8_FDid>_XZkh_|4* z@nj=ofH#T)_z@1nh>wG*<8x`3EAiBA;S5bx%lz-I>;^3#=TSPjOuju{BlX2lPQXY; z^ihTlaXT3+bMP#2QxJXoMt*9`y+dSn)EF}2-z05z$_AK{@=@*1l_%g%vpa{u<8P;jDzNFuu<6)M(iIEnW?|EjC(xM%Hu7jn*K+Ny z+-)}pHh#|*nrFmRR4jHlv)q=m;HhM_(^3Xgl4h zl>FWtUG3x1zLwuB@8AQal={%4vf^B*Dtw@(c}dSOatK|9DHJhem)&krGck))ta-q=B(A6wT82{;jA~D^$llZ&8byuPOaK-YE}4q!>K`M^);u~fPUe>8%}L` z!>O&*oZ8BoQ(J8~wbeDJwg!W4IJNbfQ`>-l8cq%R+t_gGwVG3hxzyL3dL5?KaO#Z> zr@mZs>MQWinp0nGIQ7*Hr@mHm>T7FGeZA(?*J1t*r%_#V8nv3!s5P8MZOv)GiW+N9 zV;TP0a2hKOr?Il(G*;J~##+N^tZg`r^@h_}-*6fmYtC}D<}6n?oaNevvs?!_z&{OV zxv}9a15lPXoaL1@XL+^eEUz}4<<&K3d2Pd4USD&TH)_uE#)h*}Z8$5{4QHiZb5`mN zXJxtOtN=7u)|{2qhO@G|;jFCHoRzgTXJviOS=j(EZ#b*fnzLG6b5?5&XSD|Z-EdYL zHD`4h{%JU?%WKZ+O2b)&J;632PYgPDX!&$3sIBWGaXRXn2)*2hm z+H%8LTd6r~D{Ic$YRy?&-Eh`mFW1+cwT(4ry}IG7*J{ps9sX%J>-9Bfy$&0_;jFJT zob{D8XMJVESzm29>uYPy`g+Y-2P{}$b2h4L&PJ`~Y}7WKjrxYO(O7dfmTS(&@|v@; z(r`9b*PM;DnzOOC=4`AtoQ;i|v$3&uA?0fC5BolsY}8lnC4s8v;xFb4M8}%!xs=I$o5xevnMyWY)@+mCso_!~@OiFv+^GjC1oAj3r}N(oVx0xqPo54 z)pfNF9T9!s&1Ty-N+R^r>b9O9P@#k%i?~{1^Ev zINKe7a{%7~Dy(6sV_U^19n%&{tRZNAC%Ellng|&1aZS?7nqvN z7MRIe@niK)eO9Qj5IUtAwO*xu15$cdOtb*{itX*1^1vY522@F8+~ByL<&dX2fSBTN ze)2nar0vF_ZB0nz2HkMr5I=|$&+Vc`b>c=CmeWm0J#FaZqtxRV+!*DCqS+f)C>%NDiN(2@)_KgN|4}p#-3=j;z=6f$*LP1p{LHh z;6$1HJk1l!X`U;llE~iN;p}(-3Kl+&|7;e<1;c0GA*c`)Ix;QnAV0m{HKlR z?yQd>3TvkXo;687%oU~%WehYr9Q;)rYL7;X!P-13 zS0O_2_)#>J9RF1qGEl^N!ZvB>r@}_~vY`zySW@x%6VU@$Xg=|~Fb*L4WMd2Jo?W~< zbXPw3g|P((EG9A2i7V!FxQ?vzlW$SBfTvmdh%LyF$B&}^EnZcA8u7sfgj$?LXc zoAl}Z%O>Q~Sn}uT0W78Hl~d_C%@whwh?$ET4O#b7`o8YaZToe1uQ<}F8sKp&`(Tyt zihrKGJ1WORuLBughzF4@V_{)X5a5+!1^(GoLSYWWn3_^@6F>e$Dd>_{-AYaRQcFS6 z0E0zFJ-6e<1jvs+81}t^7bG4;ohP?(8?w_F8bUN3LhlO)W6Ydikb!$0_{pg2r8#4| z;i%pB*ne1vG*Q^=hi*dutrtP>H*S2h8+PT-{V=%3f9dsOFyiRQ3&Y@uAA1%yxp(`v zw2WhXLvRnzYcKF3Hvy+x9#k|YF8OqP^ebt*ojWh+I>f77SI965u9qvfvDDT3Fd}V` zc|=}3>L;;7hNFaZ!mda9{+%c4y=jNt2?>MUzTdgqT8x70%h>a}mk9_v?B*f~ga7g- zpCT`g4W-)>V8|pKLE1<^Apbc1a7emgX9PP|k!6h7Lz2e6<==*3*w;S|lSoFl5B?ZN zaY>`jQ>k!F2@wgQ5ACHaChP~Q^(7zkoR0+W{m)>d_=?n5Qmdi7dKS1~L*$)#s@GQM zt6yK%>qG8ARug1a_&4MuvIWGzdO>_PrEsB81bB5u5u_y|35p&bmVo8-W3Lki-PoQD ztP~GaunKsCrP3a1-r>qV#i}O3$U)#IKFv4B$D{JO+fi_b-sYGdiCJZH5J0W1Ok%yX z$Q&AqLrFK1PZYTX4deFU2i@?2{Dg7*Al*~X54ETt3{PY*T{ z2R%gJ(h@m~J@VkSX?3(kzjysUkZ}DmKXTc^&io)*r>kq!wRD9=gIgm_{{o^DmPS6o zsI(wANo@61Z$#5AGIGz8ivpz$=%d|x{~Bmm#T^chT)3kEnnzv|cif>zfvHsD@r>V) z*1}3_Aq%bjF=bV}Ac?}^gjf&=A56Gx8m;o^WSIboEP^9g;i+(9;u{^98hCz}WUn&< z>356>3HQZL0-`$gK%2xCEZ-zY)i?4n|B4{+7zpBU;4v{);Kearzaov2oT*gD`PG$` z#wvNO)>eWEnU|B0Z6JKJR8&{`Sa=5YnRT+Y*Fron1hdQ4qE<6c?0&3-yDUV%CHuFEC^!DqcO3;TQLO(1O? z4blkGaY$b0(2R&!;k;U@)K^w?f8L$r-DO1UJ8zQJmfgzcx7xlz2tQ4$Mb|>NFWv9k zqQvr|7x~2AVxBBgk~%EG3eSD=3;dTM%te+!3(t`gHEw`BGxqnbq5SqjvA%qqXDhR) z39zMyMg^?qE9?u?E}xXZ>Q!Bo7|3FO39!&M87N3FU^O&kth=NTZ(St=N$cC=wlHqOrfQCo|Oj zKJ-0w@(&P*`;T*9y9)=O7rrsipf+Jp34jQksMg9FS!3z7J z#|rg&?x>$^O0Q!_t&tWKRFaAErt(Xw_{agDF(;x38Mgy{f-?-BKeSD6wB|`aui`eLD%N&*z_8t#N(jq9hk0E{0Hyg%3OpxM;PyukBXr=Wnf+Wu1SvFG_Z+W!rD9R;y&cwW{A1&p-csVZXJ? z_^k^c-)^>A75c+|Yn`{t*Zyr7C#R$P@xLx?dFVTD0z+EoZu$4i3;cJh)xCIaFZpV% zOSjYU;+W2_GNnGoZ&O;F)7i9I3d}%IhA=CYFP8G|oOl@dLDJK%b0j`jZgh=8p7;v$ z7>9{q7#z|bC6dQAqB5k!L8DzYVI-rJY@o{?{FV6Eai9F9RE+#e@MKP*p zY7T*Fmm++3+LZAj*n>mDQ37JSEwZ@i0P}R`kl~F3=}Ylnm+-W7JBb(3pS-OfUk<|< z&!&TWtUN1-%q&UsXcE6vGFY+-@}JHUxgNL#C|Oy|w1WS!$(Od&hH6F4(3QyziiQl^ zw_YbP4>?qU32l~^X#DZO_kxZ`hNB3i)-ef#{v_K03_ZN5+?0T84p+ey3Ur29M@ ziv+;IU@#cW^$zqj(D{nqK~e!pdHFu*AreEh2CVuSTjg_mJ48QAG)}I_FNA+fURSOx zD`3Kh-`Xbf{4MRkj<`6wK{;eEj-yy?ET?wH|2ikTUWl6)IR;^src$V6{uJ^iM5F9$ zyt)s2Q)`GBoL!wOe}gMqy%?xP@hgeQvuxl3Tv|r4JdzYOo47MC_NEtM#Fv)sktp;6 zxw^!mx3j<>_-TFVLMsEFR|lo|%V6WE_GLz5&z{*oYp3cM?YI}xq6zqb9~j%fU&<3b z-vYkwW97C1?8~>D2Nu$vgx0CA2xKN5;Y$u%F z&1m6nptmzRKtC{Uih-kS6wSjSd3sty-dtaOT9-7|XH*EL!oL|3wX7gZKA7D2>0m-K zycK+8;3bsQE^EDIn-TdbxP0M})M+cVgw{(o`DIMKtFliImVcUk2Hl-@xfa#Qf%6a; zhD9*2*Zw`Q^8jdmU;erOcXD{(vQyU|-La1{@ntq~Z~S38A+Iu+#Iri-kq1FWD68L8O#rWalA5&eE*4} zKfo)aBk^8`wEnoTM$2K%Z&5TFsEp&qLqJHXGL9v470~La1!S_?YcN8)LCkf3AOh3M z&_8+dXN3QBIsAtxqFZX^GVKTMswD6S)Opc>{HAUip#$cwmr&<+O(S&hT}Gb;5G@L&LQrK@lnJxjv=@(8xNa0k zn8i{l%Gpm;5%lwCpbpR@)JyN0&;rafO4nDU_N+#Fq}HreA!mv7x*Jo}$^n!xZiCcn z^~(3aWz$!nt<_c8?o} zg!~!qP_8&A96;^)3aDKU2^Fqh>C*w6Q&eP$RtR5>{r@tuoK0LW0LWgE3_$V>q3E$s zD~OZG;ccN6>(S$XE3;fm?hC6E3fJ{95G?_(LVq{#1{0bcTLUz;pi;12sPkh=$ctA82>VKZGnFH?Z6+)ynhVGLs50WJf&y74kU^Z-I0tB{M zrl1FneeM2`E*@3L_=0mOfJm?kI4k60K3HDVxY>GT5mz~owztXi3VPWbf~Nj0C}LHO zc{t=~Qn+^_?2pbJP3t6?&%lTd&IuLOrsjEK2ef3VH6ya%SdEhQ+;-5*R;^Rk9*iM9 zbCnzA@~zSSc{w~xKvUq^C~J?xUQZi;v#dP|p?dpnDLmpf+LP^nDr?U?6}0hRRJR;e zkR2>*zjS-gLuO0RiFJvj!bLs!M>z`3L$FNb%}bV=UDR|!`te6T!jIhf1o#p4F=69n z9Ni?4COsx$G^7}1!rHb(Z$gv657Xw*Pr%ul{Cggyv*QU4 zEVqgR7A5D>6Ei8;OWAyS1}e)gV0m&}nB+l2D|IX!RsdcnqGsTS6dk1cYnhu{4(BSrY=Xj2g0>k;yr4RDSBaC zt;;2V)xBEBB~?uF@I+=`#pHW58Dw|NF-;F|!Xs{He?yZ&?9b9Dc3^nnB?u!w!F~W$ ze{D?D{u;O@;eL4R@JX@Bi%9{puGSm)9hlJq)CdnoWps9hvJFB4 zgTl~kr4yPmRJ>u1g_gxOn^aiu%#EjTmi;yE$_Pb9Z1_YiZI4`&g+zq?6VaJ67P1p; zFQ@2Ff#IE`UTm3M_7bNhRTj=P8fqwp9P5xmCmJgBBlBuZqoEp!hv9=jCyOn8geT%! zfj%uPlZ=nu>ue!;jT8Y>L zd;?hB>WB6fmHwCgwG2IMY5788`W{>s-qzh24k1Kx1C}iEhv>nLe#2xCO{Wnk8r21I zcs!@mUvpcmMSl%RS#&~I3-p>T?03DJeBIJtS6Qd!2(fmDO&6!B?BRQrshzx<5cp=$8y511b;p@K)AkR7x*kjL-m6K0Q z>{*ERqzSIh>Ij6j=reAwk0i)l@!fWKw_J%ScN|Ca8K7FC)BW}M@WauG>CKN4)R2Dz z)i3rIC-cjYGPgamK_XwZp05|YeeWfh`F`DeeZ9fcnX92XQg~wm+%YfVD^g5>2e?2O zI9^6^Ob2O$rOzRllpC_ZXk+|kO2IA=jntJ-ki|E&k93O4|mzCzfA4)Qj2oTTA zh4&=M@xRp4pKNDlV+q_H?_HdHczv*UdU0}kynpa3QxS<>uw`hiv42jkv=KFH3O5m9 zqp7uOXrI}#bk;~(THA8tqV27?KiMW9Ti<^&MqGT{vN)?6U*#2c%*QW@L1pFlJA
(w2m>YJS}cadANvGPG*6hIyId>P}CPK@TRX*!OojE$9pFy zb;|}_jY8D})GeYVjwJ^AmVuiLIgF!s46#Q7U6|~cK*G$ zQ9N~Q4*q!(cc;y^$W6MD-<5KxyG;tgSL z>XjzXHdglA5P;x2&D{5RDHjXE#0N~2@%;v9Cai#3LZ3b7jWYP;+1#(J%I z>F_hggv~Imm`N+{ET_1AP*AiyIgzeDh8f6eW$nOi!b9!sZXd?jNKPQNdP?Duid z`m285{k~<&E86`O^1R~E%8|$_%7B+uju{tiR=coLv_~zQ61lg+UBAqMl}4~>?sZgw zd!BmpcKMIGQ+wK8zpXWFhnYZNul7L9nDNCAMGqz<$YY1+DR`u#{Gn6cKf3P9H+UR; zDXRDt2JbqSqgV$2t#p*;bQnucR*EH-$|=mGviyo*4(|@sCMj(M$q3H171I64*uh-} zjRwbr-m;^;{A}lASJ)4#L@QPw6Le$&;18vPY$THwF0&+dwrv1RkE!TfCEZ=o<_K5i z9HGuOYIVeHF{*x}!3^@e2rcuNrWi4WDYWIO_T{j3fgj?7t%@+XpgVQ)3}jg0^{A@@ zNYm69)Ek+&X~D{vZXq6{ z#siw(MDdlt-h&ZaA{3TmRg-Z{yc&yA30;$DHJl|v%i?GAN^{6(S%@r{`x=PbyB!4c z#J{FCw(bp4)Y>kf&sxVO@vMS%toXvdQoqLrrs42wY+o7-&8 z#2;q~j2SS-fD$y6U1_dA(iJ93Il zn>>IX`Akto#lM}S%qO-Nc)?@ORZkMrXoK8VqEpn!RP|!jHAMhR9zR9)Ao0=C?NN4_ zN_3T4ts#f3vUkdi*E|{AKshcSx_b=!v~tQk*wWDd_YU}G8ZX5pB+Nf1w zydL=vjlpjZ?F|}tfQS(0HR7RUdXKHNGVd^WK{3n7?&xY7jLa~iOQM>U#Da}qnYqN& zMS)Vs4^bwGLMTQB^9RA4S=LnTROQ`^TCBHG{5PwzDWPM`tECx&g^;pkM@FgLnp-Rz zW!vVLWafngJ$JVIYm?}j#!Up10o%OZ;D2=cYcHQBzqFwJOSf{jpVV%(hMXkl^li8l zWZWb7e!W39l=muCFRZR#;!kjZYJEqNXdVyfdv7-L!|{jXciUiYaDPV)jm@$3@!Zjl z_bxshzq|PR{^@TQM~BC!WSi)(^auZQc(BJk4D=V8^MU^A_0Aiy#`zb!zwI3F?4Ir& ztM5+#d9d;_(6q;^ab8eh|4jXP9#dZe~5%2$ve8hC+twcaDOcYb)KKi%k&+RhMa3Tclw zd!%;ar^XO3dZcz3kG;_U595y7+YXHNE9R4wk2Vb$7ZvaWzM1zxk62=npmH>7cY3`} ztF!*1)+04}z7S_82r!-i60xxhqpbK*7m)Mr>jmB8Xr4mgPx%1rRlgtj;g#95>Zfyk zH<$PIdEdlOa}aM@`W~Jfy}f=;c7ovK=&cyV?AR^s_~y8%-_MqQ$NNV`%{@!=z5QR0 z3p)%g9gg{4A{kv;dQ9IOoLqO!!K*giTxrx!;ex;UZTE=a z_KOn?UW;kq-4Sn$+pdg+?mK1~X?1$ftBhF=R;3~AQ1p7D?}w1rBFb22P1&sPqG$$X zZq$#rd%c$a-Rv!W0dG6)8t1W1WQ=4U%62N_+aWO>&jT-p!v@%zk2CgC7CJ@~a_J3; zOjv-k$xB`pTq12aM@6{xENY6>Q;e!tc44?lGp&lk?C?Wdo= zuea_6(|;leJGuu%x(wBN>i+nBD<_e0CE_t1@7>NE%**?!-RLX?qI;NJ_#B_LmI!p} zK#<>8AEJl9&p&kUZK7N#*%v? zTN>dOD@Q2gu1(BWoLxk*43QTEcvqzf)<^I#3o2Hk!i&gDP76wk5CuXf(}alFOvP`e z{j83jb^474KGt7*`F%&+Trg@#L8E~J?e|Jk!&(kmR+d$!=Ohghi6X37xnSWklp@pI zCeq)vW(4B!CfUuB+pQbKUuL@2u{HF^e#&UB`81J%;?1W+EMDSBZ9%_HyeQWvjDgpirau6Wkcg@6eZt)zhD0_OYxC zPbp+4iJ8pP3bQY8RUAB@JPZa2_R6Ysu|B2#G9b)aVq0CO5ZnU&7i}FD2oNJA?BWD#2gX#yCE=lb!C`kNrx{M() zyH4g3ubalO_*)Siv5Z(T%tf9{VG}Zd#Kc&pc>Smx;ixIb72AK7KJ0P^Y-n7vQb7S& z27DZXJDR|`3u2*oakO=>VYn4E`l`mOQ0|T8e7J}UBZP*6$W}k2{8RoWm5i;JFDCg1 z)VO{Z@v6wvWLSf%1qdgIw?UvC7#T&<(r|U8l+7_W@XUBXEtuR%)z1A&CTn;&|GNx` zM6t>bh&fa|uorSss>SS2fZU4Lo-G<27Ys;t0x>Z3GcU;bYxJC6J6oizlXpZJebS0hFL_<+A4sF=dvkyU7Uuv%Uk*#@l1Esx1$+-^LFYs7o~X|zG|agAaA{I- zp>fLDW?uVj^RS@WxL3B4k3MBZ-VhHB6F8v6c^PDu@@kOp1Yoj#ET?8W0|IhML&++e zD#;+9EC%+h8MEBO2I7^_Qc}^dp=(*GK7UG1AR9L+#17oN5Vkb}!b^Hqk9`b<1TYGp zy-M!B+^4Fw^rl)Ic^!=`Bt>9z)lwcNJqt^tc$pLA?)PK&Ch@QV{qwS92=}EKSim>HVc7 z=bA{w=&7X<5CT_lmSUIGeKG`a_sixZo_!gU;MN?W-*gY!b0iRF&sV)wi!!Km)<&I) ze`@E`nOwrI=M@Z49BWd>@67GW8!|WWNm~^D8s-FcyMNLW&yslaBO+_1{$iW}81-u- ze-yB*0797nx#+=Bel?*butr(->BO06=*vDg$4;0Pn&Qx z{5r1fQHV72E*6(JcA5UNq1k0Qpc8fwp%Y?qrVc@RFD(@vxvk!h;i-(FfNR?ooe`w5 zICAS0rd>eo_+})$4Jk)>qAt+I&Pk^ae;;v9Jl~BJXf<;+e~p{m$e2Rhn@p6e!6w1`LSYPkN-b7b5;+abM)kw5@kUe7 z>3`^{)x!GJtDIEn*@fdZhiUDa!S!l;g?|RUh@{y}2`cNZ2%5~T*%7 z&Mz*T?Va!`%8Ws~%`jg!5OaRU)Zy+vrJeMcKKO5!>n69LJQnt^ayh&>NOt-4T&RYo z>am?K67&wur)Lpx9LL`6-*&XZ*S*&)g^a?p-*{10lyHGujmx&jocEk{RDP+_1R@dc z2vwdOvt(5%32!v?9>WkYRP2;Nmn~K-a-lCBsnswsD2DPu)S@nVr<0GMHEEjbN}}fQ z_AW%VUFD}5d!9n13C3G&@ZXW8nL0PD+J2Xie9Sn9p#&{>-yIwSD=T!Tp>( z8(2yv*b3CUkkdLf88vGJ1JI$%2;Cm1RK;y|gZHSS8td-O;VBJE1S6CKWKdD#?|ewP zLej?_yFY!_+rs=~i`FLE4?J)b50xQ&f>p^EGlr`4AK0Sn6 zQ&T5e9&MTw0o2u5mIE3ULelaySnhYfzrjSfMaH}Tau5GSe$BBv98|d7?It|U&n*mr zsy4g-`}uP;moFHvdn{kwVkzB~hA@hcq|%1K1dD=8u2|DnBB_bDW{j?e=jB-P0XQ$S zQXbw+$_ll<9idG^!qsZlxEG>TQ1_k`Pq}2=Y^;&alqLd{oV9kmSuYP)iL05}!M<_C z2GBrp9_&iUolnlwJYKXEa8;$pm?~5z4w#d0pzlEb+5B{)vomtB(W8};oNa8b3Jn%EV1=x0v&iU;HT#rLbjqv zRD{X9gC!S}=f(THnS<*+f8$C{wdVSLm#q@Z>+$dmuz!E>%vO*rJz>7{tid`d^9(%e zJ%BW{Kg)~}*01claAJ`FRC9)ZIG+>!)RI8J{s8PxTVdgcW|+-N4BZxch`q|on-`PT z7gOFj{pqZc^BKPvYT-k(iu72#kChtd;cl|UF64D5&E5HiB?_y^2R>TkoEHXmp${Qu z@#IC_DZewwbUI6~ndaRFBXI&eASN$38r1>E#KSs;*y;910IPVuoH#euWjy0E|8ahk z_y?cPQS1;qQ#U2x_()h62%gAGrSm&C@xZ%OT z31Sga{!2S}sy|~18pyc9bHvqphgZ|@kbb7!>9?)+(M*3OSv?(A10+t1T+lb;-1tQv z0FuF%uvP1VhQECQem}W`AwiLfBFDb;K(hT(vLv)NjQ8t;B^EQVyi(AmE#dq_X1q!Q z=r`Zn5+v0wWnS%K;*=rhXd-ja4#V?)=HxlG>#MFkI+S|cnce1B>Ssj!c8v8T=UO#; zRTEi4EbAgklHNyR2Ds@D-5(`WZaZJ^VmG)9CtfZ|oU>aW$DKFdHxq6@uAv|LWQ`p@ z>6tHEJZ94$*FGlmA0czvO@%L8KS95DK-%bdjBK-s_wEX&DBHHhQEX<-;h479Kylr?qnmQmFiefUZniLHYd>EqB7MsE1&OvD%Of2zW zSwV6TcBLbV#k2%1>B$q>KmE+Fa6cp>I|*7^WDibVBbA5toNGtlqETfD0D9C>U=R>f zm}p`tzzf%R$n)iYFwfBJgQkh3Wr0x0#t_V*0JrK)S;Lt+Avo{`weU8rUSP>aO?r_v z{+jO>Bv%F?s{z!vGbt@ixkgb2q#M?(k{7GetgSG@t!@OLs=w0Ftf#2luzsg7e?zd( zj*2}qMup-ygY>ROg8N_$RgB?N&4}(QtI}d6t@We;Dg_&Rvq9+rCLW!Z zS(Q+Vf_%uh!>}wLK~JkTuNs!SevMjWC%$+!U8~-05fcZf&h0CH4UURkkUt`*X2_~E#k&ZR+YsNP4FSy> z6jpwF54uh3D&am{E{jhXr;Y;U&RKwMmr}UohoAiSUWqP?zP6MOG4$I%2O2X}PTgC`6P2 z8F41wDB+qBbcy<>`|JJDLahY7$-rWr8}mf*r^UccG4SD?f1lV_drZ!NDVai~rp;)_ zLuFU=M#qE9tH@I9!ugSM&TV~r%Bn`frnN#_jVsK@D#YmlL}4OF_a#h$52!DR(fE@xH<0vU${ctQEKKR_(KsBWp6DOE7vNMh+KK%Ycxx)ZeP`wx zDh~}?Vh^biZbD>v67_jc8Z3;cv4+o<2~-^ssu==FGl*7dC4U^M$KQ&OD#v(CK7cL${z-XvU?p@wL!G{mM5U)gQZG zRMf)x4mF$dB)aay9-I^Uh*vHS7PR;i4*20sdX(dV@d_9Vdcb^tV+l~=-*~R)9V9yH z9=Vqtq}E29AWX@^7Sn-&0M~bi?mGW<;kM!y0%PmHgdqywAyqim^7b$*`+9Y2yEq(h z>4f07&wx*wjxzjtRakAuU^qzK-O+0@pMw?966W#ijne!6)r!21%kUT=$4P`&?SexF z5{oew86vqJ3=(xvPH5SRGt*Y+!VxcEcP}8&#&l_jwu6b4-Zsc@sM?1L9BY za&_ycZQQo*!Bbt(CtrN&{HN&blIXw1#r+8<44&&wZ(D*Y&ygkCRon@tw$N0v#lmV3+&p9C}g$+ z#-N_Om>`)N@ijji#01J$E7~Jobq*#(chyTB1GDU9d;(Pw^Zx1VwfcD|-c_}n%Ac6y z)MNbIn~FdpNWkfjh%W=k2GUwv-7IRHb?x!U|SqqP}% z!Gqjib)TxAdy?YEQ+xlR&FR}!GUUOHw z5%ciGdaEmHKmV2NZ$J&58%KhWW!`u%-EJmLyf0-hzjH-(worJ^R;#I!$OK^t(L?RD zP+SE)Kx|gV>bW)JXoNGL!DDXk`q3HG3NEU3av6>kR_6j5j4)#K&>1 zdiPRRV=0C?y8>&@0Fd$wHDOkvmqA>9eui{A`KvG**xPdi9A5~{nkn#Y^)KGOQWJvDr?OOq=iZ|4-KJfz1q`j~Bkzz~MAmoe) z1u~--lgtffwgoT%=<)V6pvn45SAXZ_iwO;9+F`S=ptVM0@1o^%$0d^!<$q3c2vDig zL6hu<_b~SyckZCD8Z2mpJ*KhBxH@V}g8N3rWb>J(iPP@;C{T+}`m?5pJYvU*I#%4| zUfc+OGDx&=*8}T0lJw${y%-yYWpvFGY682eXcxIL1FeRo+sd_=Yx?ih!T=K&dT!ml zc6G>AS(K2gs$j|08pI)z<`aw)_RjVUvHidb391l$sT!ulU;iW)+7_p-GK8RA8ccVL z4^~~gf#v1uswYpqzvq;Apx(HA%VF)bcdu2YvAx$j77u-`FKa7^A~8UEruD31$XPru zPL@~((WBx|nl@@B&WrkwefQqJLj6toaZ@Rb2)4<3J4r{2o;||KZA@G1#*@{W<_jkX zL4TEK^U;$6-7(&!D4(^p`8H5AibXK0r|8z0bhBKWZMn*0eHr!_0YqoZB%*y+7xgVQ z>hxeWHfK844UuQ0(O|NK+bN=c{nZWk^aa9HhsxIjB@s5kd;Lk@jh^hW8dS7k3vI_l z)3O>R#D31%i_!S%QJ>pW%iP~_2R>O^(;Ut`;D5u-0PJ4zQDca@Y)unb)qoH&%S$zwe;Q%MpAYo(s z1Xip4eKg*oFjrrP*T$#0YCl8kt^TxVB(4kKM9HQ_4XAf^{$n{bgPYLD7Z+OAWTipMZGg? zJ_>-M4vK4k#WX(*{b9}hRpGqi!WBqZF_!Ww6j$88RXV6kpJZ!g0Ja3w&{LfuN6#H)YA$>vQ&Cs6y?FKQ zI`ovEKNn$Nn8gcU1vRzt%j3rEa2%o$L`eIFjPzFA#o;2pa8sH2DgaqT*|%0mKUEi$ zWY9w+r1v{iNt`iib5{8%Thk88*8~Eba=!&(8iItmc4Jm2J?MN=;?&MfiC^21Cu4Qj zs>!xwG33?2J^TbE)7WQxpEG}#D{UPXm>AzMdgeiPCV|Qx`T=+yK}z7jG_sMYt|b19 zytp+n=Sf~pY%GjvyzAYT_;zOcsX83rhF2uww7SU(H%b+&bRx; zn1Kh&ht<0U+KF*4)3bQ>Pg`5WLqnmE_l@nHw8(v+_P$&0CC|(l}C|jZsE}fT z1&v&v#Ozjfi1d#Wz6tjZ5XP#;m-)`1HP+RV;=#|x9!tMX0#0BvEQJ))&n&BW4$hfx zYqM*!76u+mz$oMJe?o#|j$xhk6p|y|`I(4)?Z&5i5)-HhQN*p3{uWw5J@l$*kohxQ z&5giLXHJK(boc2c!UGpn@BFz@YiBiWRIa1rGE_mDk(z?>>nJ4WI4so5ty>r5np&8e zTT8p=+mO}PpeifA6QSeG0Eae0^^r<=TLxOnLCuunn*doCx}(j_eb~s~7uFFi=QT?X zjxS;`b)?+n8T{L%+_bnh9Ip)vr%#@Y`Q%?8dhecJjO#ghZg>{%U3M5(0~|+XaQV{t zeME z66?nW_u$%T@2)O0DMw+zKY^{X^06^*Nu#ZAc>nl%@m7PND_lqK2O%7%3V#pezG4gN ziGs-zRXLx9a8s{nZNJ% z&aptSNe1wji>sInIP#Vq+2Y{l=H#|>gXVjpn7@o)LASq68g^}_FU*x3!B;Rg(3d=( zVI&@qJQBt}A4y->Amz^Na~g~3FM7b7Cwvm1naBu<*eCHxDB#z+O#DV6D$5L-FZ&)< zkR`j5dQLmKaBTfpL0t7{Ib~-@h3MRLwACREUO#=lmYDv-qXO8qi)~0NBmWmawFGhh z^8Dw7!)7lUU>+UpX)~Um&7r#F7Qwd{w2|BwV&o>}2pI@HBbEpy~-MW_;<=qXn zmXZ4fkXR&5ys52_f?(oq%hM;+)G^OztkkZU9>q{)-!#n2lqbsU22GeR7t8>-zwSVQ zJsAy;A*2pUwkpWT`}~4!-R)Itg9$i|0FYW+zfxb0xX#5DAVVAbI zB$N|KnbnEtQks4(JD4A^)pA40UTr+z=#^60<~7795I#(&fVy2+9zE+v;feO;MOQKf zTz-NMn#l~W^jghjid=sSFsNJ+xy}=4;^={CBvF1tcABFZ{E4@Rrs-VI{6`2AxivRK zo)DCu4VXfEVav^kSKNU`NMQ4Qimb2Gr%jWQM;+QGFDhYjF z_9hgVZ^$`AXSmK^sS;0SCQf(H>YMHR#?aW=^c~sT=Ni-=CECqV{oOOnw&xypzb(uu zH>jZED#gtga06ZWgC7Nf)OcqLqxu!GiIx&STfnN~5MGCTn0;&=W*9U9zz7+o~|Z z)saC~5g}y~(LO+*cZ8=}NT)~1hl^JRw!-3>lqDegFEeF<-kh>{9N6orq9TBhoItRb zck^LMErpxnxX{9Avcq(H-j-l74u#~M1x%<>nx0tHSWx5OqL+273umq7dx@lWB&OB? zpNf~cE)7ariBgu-+Eqgmj6%k$21i)hwv$v9i5v(Q=-}jB9pi)e6dIlQrzrL}zeXF8 zf-21gr!KP+jm^il?MERy2}$=r=q8j_{soCqmJqShTr%KA-E!LN>C*?KY|4@JW>FJM zYiJnOpBJ_tmjlg;mg4GAV+UDpGYWz#WOD3&H?(;qz^dr#xK+uzXBN)!Q0?2i-i%rT zdQ)?qXuHfO zO3!_RXhQMua*lE=9iqXzYq{3st!kYk&B#4Q0#Js#i}Sh0P5j#!K64aqJZ>JmF`^)W ztUcl(%O_b}GKaI^0Qtu3IwwSByi*-W9>0%zS}xe>@tfra<#JteQnsL|51#$XcNYcs!ciR#NGJx$xLy zXzpGn4k>ngp`DoLHwT%Z0@=78D!NwtJbg?)8 z#nY$j?gg|+sqkX`k||E)CtmIV)H7qZfC(78!(rf7>~{EXqq`x%Q*h`&UeFyjup$L8 z8FxPh<;Sp^5A=(g&(-I)PCvZcHF~g!Xg)(=<9H3B@|yyTWK2!g^P&_9qa&d`hCRd@ ze=U|UlDT~-I&T$B7@ZBMnj>W)aD=n7b`3-3GE>smf%{?FJHe2Vs9VwteEtgK&Bp+a zvi;niHlG5GG|egs({R6vCV%On3vjf^f*I2KS4=CC+A7%tW`Y(YsQjv&MUiuho7|Xo z8q3mr5u=K!6G;c)lJ2xoUHJp@ct5$*>_%e09dT&?Rshd)v3L6Vk)cMtuOWAUqkEf! zK)NMsaVIdnA6pKJ@=>8VRl~a*xD!0^?B8@!y3G~r50StJ#zN8p&{1%ZmBB=IH&k*g z44w9l(*_PoiNRnhUKWsF`SQFiqWf`$Q2jHQoVdqf;M#Fsp*|dMcMPyY_YB&HjHdCV z%y06TEK}{-si&-*+Ai=X>4F#lFDG=8vlfpdZ_+TX3C{6C9gu!-ObB9rfbQf(D=c+V zMjA>7DWMO{`Ir4#|I-etjfL1f9Us}Nlyra|s=DzMBTZrjI%usOCQ;!LFSJS7K&g*Y z^T6_$*e+foUO$-fyHhB1NX}yBpqZm3xG(q!=o=+AngutOjij@&u=LVZlgk=2Lnf>x-?Z)B-Les zD0OOGKj#LlOvbCo!D zhqRWBp`oT_fnPzh)maS46PP4P;>f-*JoH0yHQ{)o@L)ptI{YdKf&sP;JCtii>@Phd za@orrgWoA^aio4#9oRT2iMa^Y^ln4zT|*YA#r}S4vtix=lf`wR#a7A zwFTeYI$0&p8?;?KDPypKbu`ICQ{40g-8F`9h=P23p^jN)o&jY;r9_uy_U#M^-A zw?sm)jTbadD=<~3YFJFjjRX;34DjzI=~t0HB!XV)(%J{n8JJOMfD8TYAw)U7G&JQQ zB$~{$l23Sb1TUE#H_hf?Nas~+`GfqJVoe=&kG~sA39MhNB0F|fr7sW1@25#FL?Ans z>v(4vc%LN$LR2kt zZ)v_~#{T{oxnMsPE1Z=NT$9OS-&$Qtnax?{O2Ylz9{>GidlQ|Z6P}Fw>8M+myV<=m z*9*DQa2UGzaPN9Nk{nwr9?~7JUyx*}kpKwSl&^0LW|-v$wt?n;4swv6d;&J+uSyi# zit?KC*eVawsKlgfQxC+B!IrbsP?ppM+h1?*7hEDKyT~M6?sSS0^~Ge`Dmte6Tl-;m zzjh*`&X{YKiVq-)i6Xmyv^e6o^PFu2d|2Y@k-l zoB9Uvjv|pm+{8@wnrV}bLV}x5t9^iuKFV&eisQ3v=>ql{P4d8FAubhHkC6x3u@thr zhH$a509}MdSu6dcT?e7;HnayuQmw6G0vr*9e19`nS8pX0#~esh2|qrQwZ4&Eso3nY zpNu!Zy9v}m$YW&m=#^*B{XuAL_0xm~L=P>J41xA$igvWjAZfJLS5$3zlsWn`DS(qk zxc&ekvS$m~_BQjF$!vYVN@dxC&Ihi&DE+$2J2gEc_ABXT$HQGh*K9yjTT)RA{loBpo4R05_bJ&I)Vp>QsxxSG2OVSHxw50K%;YTObm zz88`&$e|sxI5@X+?&e3}z!dsFSZPIz-~MI?fg=Fs1X82^7iDV$Q?5WWg)OBcuKG-o zcW?6RqeWkQLu|$5xErOZxDbYQ+e}P6W-OII7r`27*PG|5ZS@ri!4f5Ks00qb8xi`# z3O`c3!EOrq0M!IY3(kLeXF}|$T7h%1pxaqEzoYOj*E%~Zx76MTWk9&tHo>J}^I2v` z-0ll4M-d$Sq+cgZqn81OLj2!a;|TYSE=46Xd|mg0TmrZGs~wRn2kBwQY@_8g;+YPe zrznea$Jn626w%HpI;;p8w{oP<;9TKOZiLipu(-x;!6nw6z9{t`{HqA`i5~rWUAk>Q z3AE59#YnWe85(MqD9&Y);&{KiA4Ob0 zlJ0~?m2K7~}te<5$9H;bm=DHmM@2Rw2NxbgFhvGdx8sS>#>%aXxw zHHH|$6Fa6eBHPb9hET87tHq?X=ciSS_d1G??#(+3Mu-to>N7F63mmDc3184Rc7~r+ zI>2RS71lI-nlF@~I7Ky0H8tC72D zPW@SFzffeh0}t_hs|5*%d*xHQ$oF_ra4`7Yj4C8$ga33{FnNZK#e7Pp4;a;3!!4gf z8t{?~8lmYb==ix3F?DbAxE5&NY2Lg1PJqg)g2>!mGUC+lI_ZcER`{Oi%c;Qb78)H1Fk)HlO}DQ2+j|RP@f*U zGu;D8ArlJI9k5~_w%&U%{+%$~ zd1;wdF3}L$sNPm}bY|a6CV>$V5SIdYReoz@Ol`RM@?}T3J@d;Jk-2(?3tVrq=z}8G z77+-fG~P7h7?fvFAmkh{WdOo3&|gek3V3vQ9xUJo{7~FwzrZ?i5~BqF?SR1`RLsO- z-oU-o1Efn5L*RV!Y^u}wix|>UDZ@UBDd({Tz}6Tmy}<+Ssb*A6$|%*`c#EzF<+e`s zHPYaTeT;i13T2*$CTB_k+T>V2N;ki!VcF)32ZNp`1A{zEQeAcNI{5K;>Uq}XB$p@i z@Ki*o0u;d7#7iZ;-!U+qa_y=uaWA@QB#hg*5K7h59JekxJQqicxFbQ=K?~hhHi=y{ zlviwLOQgM6zHi)G6ShF1-jQXQZ>hM*TZ1Wds92v z^!61SZ0#Aw5k#O~3G?~=b5q;&uyT{HmmMta$lKravldgU{|au4{}|0Q+& z4 zoitl(f^>5AGx{-SeZU*NOrEprhS#-qI}evdujuh=DWpD$Su#u}TL$B(Q7}1=QTIPA z9kR+j%IAVrnVaMeOhZ(ojGxF9LKeA96AR|Tjs`b+JBZnD{Jgukl*GikRV8!4x=5^= zWWXMIqjdXLiYRTUuZuQZs3a-I2S<>&Bl%XfV%}Q7bQi$^G@tBI4QAl``X?QX#AN8Z z5Y2xMkw^F|<246W^5eoPU1ih^Kh@+Dl^RBA%n3%Z05=DDMao)ho3IKy4-AQW3q5nJ zbcVJXiixq6_AUI%xo5k#`X(+eH>Zv#PaRy93y)~K=MpHS{}=UJh$u9F6(iJhLo^gm9)CsITg-68-&)m4B)5s6c(wwhMHJv)# z)kxJ6BFRpv&k?7tA?WE0-n5z6pIPp@}MxH18e#whyo8--e44w6cA`&5s z5KPAfnK(w^mT@HI5{k_PZt%<}abJHU20}_h@w+JXq=S^0>9DaS)!)k%6k|+jIkzFL z>)L)QV^d0_S)v+l^HeH}zKeAHqZBv1`~Qtk`%ig6i_rlvjS#S`k3u4-Bkh}_&Rjc9 z%yO4s_Aa$Z?IAaZ8@k+-C22z}j;&ScBpGXV?sea0-p~xGs4deo>!7Hs-3e+215q9( z^{MsLINE5`wWKb-vw?<9he|%RL^-*rj&LrNL2(4v0&c* zY=NQ+E6l*^aCP4-04czk!Yd`rL}1?GY++eawh`?6caJrjbLH) zI`r+g;_Zn6p4{z(ZqAKv?K?%IaP6zVZ@6Nz{ zuX`M}vp_Q>2l%%FN^v#WOpU`XP%2nbY<>T-4=ZX>!%6ZLW0-&bV2 zqAjuNa9JL&i~M1~iG<~x8QUAVr*GsQNOMV{c-6-CQfGnohU=6F4u#Mk%x(BNO*G-T z#Dyr3V6|gDx}bp^B!}1VmQ)*(}*IEr(=g6=5R2J9?Eg(%pL2Zg=6ePO3Bc@xTl1%F7)S&9)O7+8kWIbh6?gONhTj%NM zh5&txDe5Ly{85$A&aD;)m1v*fiHgJTmvtMx-0teyyfo&qe$bJ`W5#_8O6?aLIe+on zp>IlbeCr(dcGnyDz&Cu5(@|I9G9Un;z6$es(-r#fBN;He&my46(MYN)wLU#P68gDT z3HNr8YH{xqYPR3(LJjsqIBP%Oau|l;I-Ux&eG@eatj3o) zHd_k90HjRls1|rElo>tV1|ZLWn6MpVft~wH@CtF1K3FiSD!&ikC7A5f$}r;1?B8cw;lB375*??tur3i*tS|(2$rN zyax9z!qLkkr0s#o=J!18oO&}KDvjrFjLRzvn$(9SgAdiLTEqsR!T+YU%@*q8Fu$CY z0SoDhl?Q8n!^Y!kL;HXtYc?@&A6n)#R>!hIEa<5_c@}wEe$5Y>g8NOm)%XJdUhhZH zu{aWBp>z1zKK#2eFw2mJ$(cX1Y(E=@G+Q_}J?B?e!_VW?Hcan|)J--q=%a3V_RFM` zQVDI^`L}^_2Z9>yO2jA4An00EP=*J6&EU3uff99;oAOMDOh&eCvx^CuQcW9Qh)R!i zNcnFlT>0G(6T%a4xHUO3VwMI`7nQCf)BX+sS~S1o&pZP{Q?nap7-pj7JguD9$ANj# zP^$)4(Oo~s~<3unq`8zAGl$m+0Go` zfzj5;Px!gK%`awQ(uYvk%zG+6U=x`)0@${A+!IEl9fyw<1v;GPts)xz<1FL(G3pFO2 zTwgHjF@0H4>@}&pr`*@)k^BRFs44@Vci+KK%iV1T2~G@ zyCiG)cwK|vfF{W21MOcFL=BVh*CdICR)kye7$Gf5*NgbYpEql_5I}5Vcvm(xi^R?`z>Yn4NY5;t=NfJd zBrF%lIJm2DZ7@4lr=U@!`-jkf8Cku;1SKn|Sx&Z~@(h`{oyo3PMKpNqF6Vp
pO< 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¥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 =TI~@Dg;tOSHN3QQ$C=Fj)>FeP7SY+R-mDP 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

A|D7MF8?5dfhfMNL}clVkE0Ejz|pVEimowYWm8 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 N>kHN3>4@iM%hEQ=tz$ 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∓>y${MKbU+W8vwkxhg{|)`}(%JF={ldN~*OuWyG} zB7+C0YN!svHaT=T!l9c0`RA6D4&GE1RSFS z+sR8#$4MwDzsGPQ4sa=wg4Z>Vaw?jIdw;QtcnV)X$=<;*d!GFu$xfe|p6)c1jvw=y z{}d#roNp4~FP0k6O{OsmuPNu2F8IxPA0QJj@d$RHFiGB7gm2HNFqRI<%&zrb2KS!) znOuKy&KA1#eL07rN+2>CQd9gHy$GoGM@~VuLAUs^DQ_er**Gm-%$j%G8~mL5wEJWc z*NSm%Xzo(MkjaG#JJuc2r+N&gSoJrn4VuO_>s5a*Q8@j-u3vZkb>~!$#N}VOE?1N! zA%oo3|KyOx>}f~=Af#XEePUfKO69*$bnL_C7utjV{!VAz{dKG-d0rV^PwvsD<8+*k P|MqwV2kaA=0H{#_5MrVk literal 0 HcmV?d00001 diff --git a/tests/registry/npm/npm-check-updates/registry.json b/tests/registry/npm/npm-check-updates/registry.json new file mode 100644 index 0000000000..71d96fd83d --- /dev/null +++ b/tests/registry/npm/npm-check-updates/registry.json @@ -0,0 +1,201 @@ +{ + "name": "npm-check-updates", + "dist-tags": { + "latest": "17.1.13" + }, + "versions": { + "17.1.13": { + "name": "npm-check-updates", + "version": "17.1.13", + "author": { + "name": "Tomas Junnonen", + "email": "tomas1@gmail.com" + }, + "license": "Apache-2.0", + "description": "Find newer versions of dependencies than what your package.json allows", + "engines": { + "node": "^18.18.0 || >=20.0.0", + "npm": ">=8.12.1" + }, + "main": "build/index.js", + "types": "build/index.d.ts", + "scripts": { + "build": "rimraf build && npm run build:options && vite build", + "build:options": "vite-node src/scripts/build-options.ts", + "build:analyze": "rimraf build && npm run build:options && ANALYZER=true vite build", + "lint": "cross-env FORCE_COLOR=1 npm-run-all --parallel --aggregate-output lint:*", + "lint:lockfile": "lockfile-lint", + "lint:markdown": "markdownlint \"**/*.md\" --ignore \"**/node_modules/**/*.md\" --ignore build --config .markdownlint.js", + "lint:src": "eslint --cache --cache-location node_modules/.cache/.eslintcache --ignore-path .gitignore --report-unused-disable-directives .", + "prepare": "src/scripts/install-hooks", + "prepublishOnly": "npm run build", + "prettier": "prettier . --check", + "test": "npm run test:unit && npm run test:e2e", + "test:bun": "test/bun-install.sh && mocha test/bun", + "test:unit": "mocha test test/package-managers/*", + "test:e2e": "./test/e2e.sh", + "ncu": "node build/cli.js" + }, + "bin": { + "npm-check-updates": "build/cli.js", + "ncu": "build/cli.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/raineorshine/npm-check-updates.git" + }, + "bugs": { + "url": "https://github.com/raineorshine/npm-check-updates/issues" + }, + "overrides": { + "ip": "2.0.1", + "jsonparse": "https://github.com/ARitz-Cracker/jsonparse/tree/patch-1", + "@yarnpkg/parsers": "2.6.0" + }, + "devDependencies": { + "@trivago/prettier-plugin-sort-imports": "^4.3.0", + "@types/chai": "^4.3.19", + "@types/chai-as-promised": "^8.0.0", + "@types/chai-string": "^1.4.5", + "@types/cli-table": "^0.3.4", + "@types/hosted-git-info": "^3.0.5", + "@types/ini": "^4.1.1", + "@types/js-yaml": "^4.0.9", + "@types/json-parse-helpfulerror": "^1.0.3", + "@types/jsonlines": "^0.1.5", + "@types/lodash": "^4.17.10", + "@types/mocha": "^10.0.9", + "@types/node": "^22.7.5", + "@types/npm-registry-fetch": "^8.0.7", + "@types/parse-github-url": "^1.0.3", + "@types/picomatch": "^3.0.1", + "@types/progress": "^2.0.7", + "@types/prompts": "^2.4.9", + "@types/remote-git-tags": "^4.0.2", + "@types/semver": "^7.5.8", + "@types/semver-utils": "^1.1.3", + "@types/sinon": "^17.0.3", + "@types/update-notifier": "^6.0.8", + "@typescript-eslint/eslint-plugin": "^8.9.0", + "@typescript-eslint/parser": "^8.9.0", + "camelcase": "^6.3.0", + "chai": "^4.3.10", + "chai-as-promised": "^7.1.2", + "chai-string": "^1.5.0", + "chalk": "^5.3.0", + "cli-table3": "^0.6.5", + "commander": "^12.1.0", + "cross-env": "^7.0.3", + "dequal": "^2.0.3", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-config-raine": "^0.5.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsdoc": "^50.4.1", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.6.0", + "fast-glob": "^3.3.2", + "fast-memoize": "^2.5.2", + "find-up": "5.0.0", + "fp-and-or": "^1.0.2", + "hosted-git-info": "^8.0.0", + "ini": "^5.0.0", + "js-yaml": "^4.1.0", + "json-parse-helpfulerror": "^1.0.3", + "jsonlines": "^0.1.1", + "lockfile-lint": "^4.14.0", + "lodash": "^4.17.21", + "markdownlint-cli": "^0.42.0", + "mocha": "^10.7.3", + "npm-registry-fetch": "^18.0.2", + "npm-run-all": "^4.1.5", + "p-map": "^4.0.0", + "parse-github-url": "^1.0.3", + "picomatch": "^4.0.2", + "prettier": "^3.3.3", + "progress": "^2.0.3", + "prompts-ncu": "^3.0.2", + "rc-config-loader": "^4.1.3", + "remote-git-tags": "^3.0.0", + "rfdc": "^1.4.1", + "rimraf": "^6.0.1", + "rollup-plugin-node-externals": "^7.1.3", + "semver": "^7.6.3", + "semver-utils": "^1.1.4", + "should": "^13.2.3", + "sinon": "^19.0.2", + "source-map-support": "^0.5.21", + "spawn-please": "^3.0.0", + "strip-ansi": "^7.1.0", + "strip-json-comments": "^5.0.1", + "ts-node": "^10.9.2", + "typescript": "^5.6.3", + "typescript-json-schema": "^0.65.1", + "untildify": "^4.0.0", + "update-notifier": "^7.3.1", + "verdaccio": "^6.0.1", + "vite": "^5.4.9", + "vite-bundle-analyzer": "^0.12.1", + "vite-node": "^2.1.3", + "vite-plugin-dts": "^4.2.4", + "yarn": "^1.22.22" + }, + "lockfile-lint": { + "allowed-schemes": [ + "https:", + "git+ssh:" + ], + "allowed-hosts": [ + "npm", + "github.com" + ], + "empty-hostname": false, + "type": "npm ", + "path": "package-lock.json" + }, + "mocha": { + "check-leaks": true, + "extension": [ + "test.ts" + ], + "require": [ + "source-map-support/register", + "ts-node/register" + ], + "timeout": 60000, + "trace-deprecation": true, + "trace-warnings": true, + "use_strict": true + }, + "_id": "npm-check-updates@17.1.13", + "gitHead": "f514093647f1833c83653765493c694372d14fea", + "_nodeVersion": "22.0.0", + "_npmVersion": "10.9.1", + "dist": { + "integrity": "sha512-m9Woo2J5XVab0VcQpYvrQ0hx3ySI1mGbiHR595mc6Lr1/FIaTWvv+oU+T1WKSfXRiluKC/V5P6Bdk5agaYpqqg==", + "shasum": "93e1c5fa5b8e11bca0bd143650b14ffcf9fc6b5a", + "tarball": "http://localhost:4260/npm-check-updates/npm-check-updates-17.1.13.tgz", + "fileCount": 19, + "unpackedSize": 5336239 + }, + "directories": {}, + "_hasShrinkwrap": false + } + }, + "bugs": { + "url": "https://github.com/raineorshine/npm-check-updates/issues" + }, + "author": { + "name": "Tomas Junnonen", + "email": "tomas1@gmail.com" + }, + "license": "Apache-2.0", + "homepage": "https://github.com/raineorshine/npm-check-updates", + "repository": { + "type": "git", + "url": "git+https://github.com/raineorshine/npm-check-updates.git" + }, + "description": "Find newer versions of dependencies than what your package.json allows", + "readmeFilename": "README.md" +} diff --git a/tests/specs/npm/npm_check_updates/__test__.jsonc b/tests/specs/npm/npm_check_updates/__test__.jsonc new file mode 100644 index 0000000000..27b84c5f05 --- /dev/null +++ b/tests/specs/npm/npm_check_updates/__test__.jsonc @@ -0,0 +1,7 @@ +{ + "tempDir": true, + "steps": [{ + "args": "run -A npm:npm-check-updates", + "output": "output.out" + }] +} diff --git a/tests/specs/npm/npm_check_updates/output.out b/tests/specs/npm/npm_check_updates/output.out new file mode 100644 index 0000000000..b8c1ae4957 --- /dev/null +++ b/tests/specs/npm/npm_check_updates/output.out @@ -0,0 +1,2 @@ +[WILDCARD] +All dependencies match the latest package versions[WILDCARD] \ No newline at end of file diff --git a/tests/specs/npm/npm_check_updates/package.json b/tests/specs/npm/npm_check_updates/package.json new file mode 100644 index 0000000000..82afc391cd --- /dev/null +++ b/tests/specs/npm/npm_check_updates/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "chalk": "^5.0.1" + } +} From f912aac2cb94d1770219bc2c25471e0a23bb2d64 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Mon, 13 Jan 2025 15:31:08 +0000 Subject: [PATCH 06/38] fix(lsp): handle pathless untitled URIs (#27637) --- cli/lsp/language_server.rs | 8 +++---- cli/lsp/urls.rs | 23 +++++++++---------- tests/integration/lsp_tests.rs | 40 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 35f5374efe..03f63e5f25 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1419,18 +1419,16 @@ impl Inner { // the file path is only used to determine what formatter should // be used to format the file, so give the filepath an extension // that matches what the user selected as the language - let file_path = document + let ext = document .maybe_language_id() - .and_then(|id| id.as_extension()) - .map(|ext| file_path.with_extension(ext)) - .unwrap_or(file_path); + .and_then(|id| id.as_extension().map(|s| s.to_string())); // it's not a js/ts file, so attempt to format its contents format_file( &file_path, document.content(), &fmt_options, &unstable_options, - None, + ext, ) } }; diff --git a/cli/lsp/urls.rs b/cli/lsp/urls.rs index 91c04f11c0..2aadaf5352 100644 --- a/cli/lsp/urls.rs +++ b/cli/lsp/urls.rs @@ -282,24 +282,26 @@ impl LspUrlMap { } } -/// Convert a e.g. `deno-notebook-cell:` specifier to a `file:` specifier. +/// Convert a e.g. `vscode-notebook-cell:` specifier to a `file:` specifier. /// ```rust /// assert_eq!( /// file_like_to_file_specifier( -/// &Url::parse("deno-notebook-cell:/path/to/file.ipynb#abc").unwrap(), +/// &Url::parse("vscode-notebook-cell:/path/to/file.ipynb#abc").unwrap(), /// ), -/// Some(Url::parse("file:///path/to/file.ipynb.ts?scheme=deno-notebook-cell#abc").unwrap()), +/// Some(Url::parse("file:///path/to/file.ipynb?scheme=untitled#abc").unwrap()), /// ); fn file_like_to_file_specifier(specifier: &Url) -> Option { - if matches!(specifier.scheme(), "untitled" | "deno-notebook-cell") { + if matches!( + specifier.scheme(), + "untitled" | "vscode-notebook-cell" | "deno-notebook-cell" + ) { if let Ok(mut s) = ModuleSpecifier::parse(&format!( - "file://{}", + "file:///{}", &specifier.as_str()[deno_core::url::quirks::internal_components(specifier) - .host_end as usize..], + .host_end as usize..].trim_start_matches('/'), )) { s.query_pairs_mut() .append_pair("scheme", specifier.scheme()); - s.set_path(&format!("{}.ts", s.path())); return Some(s); } } @@ -432,11 +434,11 @@ mod tests { fn test_file_like_to_file_specifier() { assert_eq!( file_like_to_file_specifier( - &Url::parse("deno-notebook-cell:/path/to/file.ipynb#abc").unwrap(), + &Url::parse("vscode-notebook-cell:/path/to/file.ipynb#abc").unwrap(), ), Some( Url::parse( - "file:///path/to/file.ipynb.ts?scheme=deno-notebook-cell#abc" + "file:///path/to/file.ipynb?scheme=vscode-notebook-cell#abc" ) .unwrap() ), @@ -446,8 +448,7 @@ mod tests { &Url::parse("untitled:/path/to/file.ipynb#123").unwrap(), ), Some( - Url::parse("file:///path/to/file.ipynb.ts?scheme=untitled#123") - .unwrap() + Url::parse("file:///path/to/file.ipynb?scheme=untitled#123").unwrap() ), ); } diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index a25710b2b1..bbeb6e7c13 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -11690,6 +11690,46 @@ fn lsp_format_exclude_default_config() { client.shutdown(); } +#[test] +fn lsp_format_untitled() { + let context = TestContextBuilder::new().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + client.initialize_default(); + client.did_open(json!({ + "textDocument": { + "uri": "untitled:Untitled-1", + "languageId": "typescript", + "version": 1, + "text": " console.log();\n", + }, + })); + let res = client.write_request( + "textDocument/formatting", + json!({ + "textDocument": { + "uri": "untitled:Untitled-1", + }, + "options": { + "tabSize": 2, + "insertSpaces": true, + }, + }), + ); + assert_eq!( + res, + json!([ + { + "range": { + "start": { "line": 0, "character": 0 }, + "end": { "line": 0, "character": 2 }, + }, + "newText": "", + }, + ]) + ); + client.shutdown(); +} + #[test] fn lsp_format_json() { let context = TestContextBuilder::new().use_temp_cwd().build(); From 714b40262e0f9bc7e1a98e76f6e211012b161706 Mon Sep 17 00:00:00 2001 From: Benjamin Swerdlow Date: Mon, 13 Jan 2025 08:34:37 -0800 Subject: [PATCH 07/38] refactor(node_resolver): make conditions_from_resolution_mode configurable (#27596) --- cli/factory.rs | 1 + cli/lsp/resolver.rs | 1 + cli/standalone/mod.rs | 1 + resolvers/node/lib.rs | 2 + resolvers/node/resolution.rs | 75 +++++++++++++++++++++++++++++++----- 5 files changed, 70 insertions(+), 10 deletions(-) diff --git a/cli/factory.rs b/cli/factory.rs index 5cc99830bc..25a39cae8b 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -670,6 +670,7 @@ impl CliFactory { .into_npm_pkg_folder_resolver(), self.pkg_json_resolver().clone(), self.sys(), + node_resolver::ConditionsFromResolutionMode::default(), ))) } .boxed_local(), diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 57ef2e6a3c..d7f7e684a9 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -783,6 +783,7 @@ impl<'a> ResolverFactory<'a> { npm_resolver.clone().into_npm_pkg_folder_resolver(), self.pkg_json_resolver.clone(), self.sys.clone(), + node_resolver::ConditionsFromResolutionMode::default(), ))) }) .as_ref() diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index 961e8d6b51..ff38912a89 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -833,6 +833,7 @@ pub async fn run( npm_resolver.clone().into_npm_pkg_folder_resolver(), pkg_json_resolver.clone(), sys.clone(), + node_resolver::ConditionsFromResolutionMode::default(), )); let cjs_tracker = Arc::new(CjsTracker::new( in_npm_pkg_checker.clone(), diff --git a/resolvers/node/lib.rs b/resolvers/node/lib.rs index 7d8c98eafc..faee4f1645 100644 --- a/resolvers/node/lib.rs +++ b/resolvers/node/lib.rs @@ -9,6 +9,7 @@ mod npm; mod package_json; mod path; mod resolution; + mod sync; pub use deno_package_json::PackageJson; @@ -22,6 +23,7 @@ pub use package_json::PackageJsonThreadLocalCache; pub use path::PathClean; pub use resolution::parse_npm_pkg_name; pub use resolution::resolve_specifier_into_node_modules; +pub use resolution::ConditionsFromResolutionMode; pub use resolution::IsBuiltInNodeModuleChecker; pub use resolution::NodeResolution; pub use resolution::NodeResolutionKind; diff --git a/resolvers/node/resolution.rs b/resolvers/node/resolution.rs index d0b52213f3..a60a6bec9e 100644 --- a/resolvers/node/resolution.rs +++ b/resolvers/node/resolution.rs @@ -1,6 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::borrow::Cow; +use std::fmt::Debug; use std::path::Path; use std::path::PathBuf; @@ -54,12 +55,32 @@ pub static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"]; pub static REQUIRE_CONDITIONS: &[&str] = &["require", "node"]; static TYPES_ONLY_CONDITIONS: &[&str] = &["types"]; -fn conditions_from_resolution_mode( - resolution_mode: ResolutionMode, -) -> &'static [&'static str] { - match resolution_mode { - ResolutionMode::Import => DEFAULT_CONDITIONS, - ResolutionMode::Require => REQUIRE_CONDITIONS, +type ConditionsFromResolutionModeFn = Box< + dyn Fn(ResolutionMode) -> &'static [&'static str] + Send + Sync + 'static, +>; + +#[derive(Default)] +pub struct ConditionsFromResolutionMode(Option); + +impl Debug for ConditionsFromResolutionMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ConditionsFromResolutionMode").finish() + } +} + +impl ConditionsFromResolutionMode { + pub fn new(func: ConditionsFromResolutionModeFn) -> Self { + Self(Some(func)) + } + + fn resolve( + &self, + resolution_mode: ResolutionMode, + ) -> &'static [&'static str] { + match &self.0 { + Some(func) => func(ResolutionMode::Import), + None => resolution_mode.default_conditions(), + } } } @@ -69,6 +90,15 @@ pub enum ResolutionMode { Require, } +impl ResolutionMode { + pub fn default_conditions(&self) -> &'static [&'static str] { + match self { + ResolutionMode::Import => DEFAULT_CONDITIONS, + ResolutionMode::Require => REQUIRE_CONDITIONS, + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum NodeResolutionKind { Execution, @@ -120,6 +150,7 @@ pub struct NodeResolver< npm_pkg_folder_resolver: NpmPackageFolderResolverRc, pkg_json_resolver: PackageJsonResolverRc, sys: TSys, + conditions_from_resolution_mode: ConditionsFromResolutionMode, } impl< @@ -133,6 +164,7 @@ impl< npm_pkg_folder_resolver: NpmPackageFolderResolverRc, pkg_json_resolver: PackageJsonResolverRc, sys: TSys, + conditions_from_resolution_mode: ConditionsFromResolutionMode, ) -> Self { Self { in_npm_pkg_checker, @@ -140,6 +172,7 @@ impl< npm_pkg_folder_resolver, pkg_json_resolver, sys, + conditions_from_resolution_mode, } } @@ -197,11 +230,14 @@ impl< } } + let conditions = self + .conditions_from_resolution_mode + .resolve(resolution_mode); let url = self.module_resolve( specifier, referrer, resolution_mode, - conditions_from_resolution_mode(resolution_mode), + conditions, resolution_kind, )?; @@ -211,6 +247,7 @@ impl< &file_path, Some(referrer), resolution_mode, + conditions, )? } else { url @@ -343,7 +380,9 @@ impl< &package_subpath, maybe_referrer, resolution_mode, - conditions_from_resolution_mode(resolution_mode), + self + .conditions_from_resolution_mode + .resolve(resolution_mode), resolution_kind, )?; // TODO(bartlomieju): skipped checking errors for commonJS resolution and @@ -411,6 +450,7 @@ impl< path: &Path, maybe_referrer: Option<&Url>, resolution_mode: ResolutionMode, + conditions: &[&str], ) -> Result { fn probe_extensions( sys: &TSys, @@ -474,7 +514,7 @@ impl< /* sub path */ ".", maybe_referrer, resolution_mode, - conditions_from_resolution_mode(resolution_mode), + conditions, NodeResolutionKind::Types, ); if let Ok(resolution) = resolution_result { @@ -855,6 +895,7 @@ impl< &path, maybe_referrer, resolution_mode, + conditions, )?)); } else { return Ok(Some(url)); @@ -1212,6 +1253,7 @@ impl< package_subpath, maybe_referrer, resolution_mode, + conditions, resolution_kind, ) .map_err(|err| { @@ -1249,6 +1291,7 @@ impl< package_json, referrer, resolution_mode, + conditions, resolution_kind, ) .map_err(|err| { @@ -1268,6 +1311,7 @@ impl< package_json, referrer, resolution_mode, + conditions, resolution_kind, ) .map_err(|err| { @@ -1281,6 +1325,7 @@ impl< package_subpath, referrer, resolution_mode, + conditions, resolution_kind, ) .map_err(|err| { @@ -1294,12 +1339,18 @@ impl< package_subpath: &str, referrer: Option<&Url>, resolution_mode: ResolutionMode, + conditions: &[&str], resolution_kind: NodeResolutionKind, ) -> Result { assert_ne!(package_subpath, "."); let file_path = directory.join(package_subpath); if resolution_kind.is_types() { - Ok(self.path_to_declaration_url(&file_path, referrer, resolution_mode)?) + Ok(self.path_to_declaration_url( + &file_path, + referrer, + resolution_mode, + conditions, + )?) } else { Ok(url_from_file_path(&file_path).unwrap()) } @@ -1311,6 +1362,7 @@ impl< package_subpath: &str, maybe_referrer: Option<&Url>, resolution_mode: ResolutionMode, + conditions: &[&str], resolution_kind: NodeResolutionKind, ) -> Result { if package_subpath == "." { @@ -1327,6 +1379,7 @@ impl< package_subpath, maybe_referrer, resolution_mode, + conditions, resolution_kind, ) .map_err(|err| err.into()) @@ -1338,6 +1391,7 @@ impl< package_json: &PackageJson, maybe_referrer: Option<&Url>, resolution_mode: ResolutionMode, + conditions: &[&str], resolution_kind: NodeResolutionKind, ) -> Result { let pkg_json_kind = match resolution_mode { @@ -1356,6 +1410,7 @@ impl< &main, maybe_referrer, resolution_mode, + conditions, ); // don't surface errors, fallback to checking the index now if let Ok(url) = decl_url_result { From 2a2b39eb2ecdc85c87fba594a51d7b3ed6d837fe Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 13 Jan 2025 12:02:37 -0500 Subject: [PATCH 08/38] fix(compile): store embedded fs case sensitivity (#27653) --- cli/standalone/binary.rs | 23 +++- cli/standalone/serialization.rs | 1 + cli/standalone/virtual_fs.rs | 128 ++++++++++++++---- .../case_insensitive_building/__test__.jsonc | 24 ++++ .../case_insensitive_building/compile.out | 10 ++ .../case_insensitive_building/file.txt | 1 + .../compile/case_insensitive_building/main.js | 1 + .../case_insensitive_building/main.out | 1 + 8 files changed, 161 insertions(+), 28 deletions(-) create mode 100644 tests/specs/compile/case_insensitive_building/__test__.jsonc create mode 100644 tests/specs/compile/case_insensitive_building/compile.out create mode 100644 tests/specs/compile/case_insensitive_building/file.txt create mode 100644 tests/specs/compile/case_insensitive_building/main.js create mode 100644 tests/specs/compile/case_insensitive_building/main.out diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index f07c645d89..296d6825a7 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -73,6 +73,7 @@ use super::serialization::SourceMapStore; use super::virtual_fs::output_vfs; use super::virtual_fs::BuiltVfs; use super::virtual_fs::FileBackedVfs; +use super::virtual_fs::FileSystemCaseSensitivity; use super::virtual_fs::VfsBuilder; use super::virtual_fs::VfsFileSubDataKind; use super::virtual_fs::VfsRoot; @@ -202,6 +203,7 @@ pub struct Metadata { pub node_modules: Option, pub unstable_config: UnstableConfig, pub otel_config: OtelConfig, + pub vfs_case_sensitivity: FileSystemCaseSensitivity, } #[allow(clippy::too_many_arguments)] @@ -379,7 +381,11 @@ pub fn extract_standalone( root_path: root_path.clone(), start_file_offset: 0, }; - Arc::new(FileBackedVfs::new(Cow::Borrowed(vfs_files_data), fs_root)) + Arc::new(FileBackedVfs::new( + Cow::Borrowed(vfs_files_data), + fs_root, + metadata.vfs_case_sensitivity, + )) }; Ok(Some(StandaloneData { metadata, @@ -851,6 +857,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { npm_lazy_caching: self.cli_options.unstable_npm_lazy_caching(), }, otel_config: self.cli_options.otel_config(), + vfs_case_sensitivity: vfs.case_sensitivity, }; write_binary_bytes( @@ -984,11 +991,15 @@ impl<'a> DenoCompileBinaryWriter<'a> { // it's better to not expose the user's cache directory, so take it out // of there + let case_sensitivity = vfs.case_sensitivity(); let parent = global_cache_root_path.parent().unwrap(); let parent_dir = vfs.get_dir_mut(parent).unwrap(); let index = parent_dir .entries - .binary_search(DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME) + .binary_search( + DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME, + case_sensitivity, + ) .unwrap(); let npm_global_cache_dir_entry = parent_dir.entries.remove(index); @@ -998,7 +1009,9 @@ impl<'a> DenoCompileBinaryWriter<'a> { Cow::Borrowed(DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME); for ancestor in parent.ancestors() { let dir = vfs.get_dir_mut(ancestor).unwrap(); - if let Ok(index) = dir.entries.binary_search(&last_name) { + if let Ok(index) = + dir.entries.binary_search(&last_name, case_sensitivity) + { dir.entries.remove(index); } last_name = Cow::Owned(dir.name.clone()); @@ -1009,7 +1022,9 @@ impl<'a> DenoCompileBinaryWriter<'a> { // now build the vfs and add the global cache dir entry there let mut built_vfs = vfs.build(); - built_vfs.entries.insert(npm_global_cache_dir_entry); + built_vfs + .entries + .insert(npm_global_cache_dir_entry, case_sensitivity); built_vfs } InnerCliNpmResolverRef::Byonm(_) => vfs.build(), diff --git a/cli/standalone/serialization.rs b/cli/standalone/serialization.rs index 238ef44fd0..ae2e411b5f 100644 --- a/cli/standalone/serialization.rs +++ b/cli/standalone/serialization.rs @@ -27,6 +27,7 @@ use indexmap::IndexMap; use super::binary::Metadata; use super::virtual_fs::BuiltVfs; +use super::virtual_fs::FileSystemCaseSensitivity; use super::virtual_fs::VfsBuilder; use super::virtual_fs::VirtualDirectoryEntries; use crate::standalone::virtual_fs::VirtualDirectory; diff --git a/cli/standalone/virtual_fs.rs b/cli/standalone/virtual_fs.rs index e167b153a7..0b1f33259d 100644 --- a/cli/standalone/virtual_fs.rs +++ b/cli/standalone/virtual_fs.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::cell::RefCell; +use std::cmp::Ordering; use std::collections::HashMap; use std::collections::HashSet; use std::fs::File; @@ -74,6 +75,7 @@ impl WindowsSystemRootablePath { #[derive(Debug)] pub struct BuiltVfs { pub root_path: WindowsSystemRootablePath, + pub case_sensitivity: FileSystemCaseSensitivity, pub entries: VirtualDirectoryEntries, pub files: Vec>, } @@ -95,6 +97,7 @@ pub struct VfsBuilder { file_offsets: HashMap, /// The minimum root directory that should be included in the VFS. min_root_dir: Option, + case_sensitivity: FileSystemCaseSensitivity, } impl VfsBuilder { @@ -108,9 +111,23 @@ impl VfsBuilder { current_offset: 0, file_offsets: Default::default(), min_root_dir: Default::default(), + // This is not exactly correct because file systems on these OSes + // may be case-sensitive or not based on the directory, but this + // is a good enough approximation and limitation. In the future, + // we may want to store this information per directory instead + // depending on the feedback we get. + case_sensitivity: if cfg!(windows) || cfg!(target_os = "macos") { + FileSystemCaseSensitivity::Insensitive + } else { + FileSystemCaseSensitivity::Sensitive + }, } } + pub fn case_sensitivity(&self) -> FileSystemCaseSensitivity { + self.case_sensitivity + } + /// Add a directory that might be the minimum root directory /// of the VFS. /// @@ -215,7 +232,10 @@ impl VfsBuilder { continue; } let name = component.as_os_str().to_string_lossy(); - let index = match current_dir.entries.binary_search(&name) { + let index = match current_dir + .entries + .binary_search(&name, self.case_sensitivity) + { Ok(index) => index, Err(insert_index) => { current_dir.entries.0.insert( @@ -252,7 +272,9 @@ impl VfsBuilder { continue; } let name = component.as_os_str().to_string_lossy(); - let entry = current_dir.entries.get_mut_by_name(&name)?; + let entry = current_dir + .entries + .get_mut_by_name(&name, self.case_sensitivity)?; match entry { VfsEntry::Dir(dir) => { current_dir = dir; @@ -304,6 +326,7 @@ impl VfsBuilder { ) -> Result<(), AnyError> { log::debug!("Adding file '{}'", path.display()); let checksum = util::checksum::gen(&[&data]); + let case_sensitivity = self.case_sensitivity; let offset = if let Some(offset) = self.file_offsets.get(&checksum) { // duplicate file, reuse an old offset *offset @@ -318,7 +341,7 @@ impl VfsBuilder { offset, len: data.len() as u64, }; - match dir.entries.binary_search(&name) { + match dir.entries.binary_search(&name, case_sensitivity) { Ok(index) => { let entry = &mut dir.entries.0[index]; match entry { @@ -379,10 +402,11 @@ impl VfsBuilder { std::fs::read_link(path) .with_context(|| format!("Reading symlink '{}'", path.display()))?, ); + let case_sensitivity = self.case_sensitivity; let target = normalize_path(path.parent().unwrap().join(&target)); let dir = self.add_dir_raw(path.parent().unwrap()); let name = path.file_name().unwrap().to_string_lossy(); - match dir.entries.binary_search(&name) { + match dir.entries.binary_search(&name, case_sensitivity) { Ok(_) => {} // previously inserted Err(insert_index) => { dir.entries.0.insert( @@ -478,6 +502,7 @@ impl VfsBuilder { } BuiltVfs { root_path: current_path, + case_sensitivity: self.case_sensitivity, entries: current_dir.entries, files: self.files, } @@ -906,6 +931,14 @@ impl VfsEntry { } } +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum FileSystemCaseSensitivity { + #[serde(rename = "s")] + Sensitive, + #[serde(rename = "i")] + Insensitive, +} + #[derive(Debug, Default, Serialize, Deserialize)] pub struct VirtualDirectoryEntries(Vec); @@ -928,23 +961,54 @@ impl VirtualDirectoryEntries { self.0.len() } - pub fn get_by_name(&self, name: &str) -> Option<&VfsEntry> { - self.binary_search(name).ok().map(|index| &self.0[index]) + pub fn get_by_name( + &self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Option<&VfsEntry> { + self + .binary_search(name, case_sensitivity) + .ok() + .map(|index| &self.0[index]) } - pub fn get_mut_by_name(&mut self, name: &str) -> Option<&mut VfsEntry> { + pub fn get_mut_by_name( + &mut self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Option<&mut VfsEntry> { self - .binary_search(name) + .binary_search(name, case_sensitivity) .ok() .map(|index| &mut self.0[index]) } - pub fn binary_search(&self, name: &str) -> Result { - self.0.binary_search_by(|e| e.name().cmp(name)) + pub fn binary_search( + &self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Result { + match case_sensitivity { + FileSystemCaseSensitivity::Sensitive => { + self.0.binary_search_by(|e| e.name().cmp(name)) + } + FileSystemCaseSensitivity::Insensitive => self.0.binary_search_by(|e| { + e.name() + .chars() + .zip(name.chars()) + .map(|(a, b)| a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase())) + .find(|&ord| ord != Ordering::Equal) + .unwrap_or_else(|| e.name().len().cmp(&name.len())) + }), + } } - pub fn insert(&mut self, entry: VfsEntry) { - match self.binary_search(entry.name()) { + pub fn insert( + &mut self, + entry: VfsEntry, + case_sensitivity: FileSystemCaseSensitivity, + ) { + match self.binary_search(entry.name(), case_sensitivity) { Ok(index) => { self.0[index] = entry; } @@ -1039,19 +1103,21 @@ impl VfsRoot { fn find_entry<'a>( &'a self, path: &Path, + case_sensitivity: FileSystemCaseSensitivity, ) -> std::io::Result<(PathBuf, VfsEntryRef<'a>)> { - self.find_entry_inner(path, &mut HashSet::new()) + self.find_entry_inner(path, &mut HashSet::new(), case_sensitivity) } fn find_entry_inner<'a>( &'a self, path: &Path, seen: &mut HashSet, + case_sensitivity: FileSystemCaseSensitivity, ) -> std::io::Result<(PathBuf, VfsEntryRef<'a>)> { let mut path = Cow::Borrowed(path); loop { let (resolved_path, entry) = - self.find_entry_no_follow_inner(&path, seen)?; + self.find_entry_no_follow_inner(&path, seen, case_sensitivity)?; match entry { VfsEntryRef::Symlink(symlink) => { if !seen.insert(path.to_path_buf()) { @@ -1072,14 +1138,16 @@ impl VfsRoot { fn find_entry_no_follow( &self, path: &Path, + case_sensitivity: FileSystemCaseSensitivity, ) -> std::io::Result<(PathBuf, VfsEntryRef)> { - self.find_entry_no_follow_inner(path, &mut HashSet::new()) + self.find_entry_no_follow_inner(path, &mut HashSet::new(), case_sensitivity) } fn find_entry_no_follow_inner<'a>( &'a self, path: &Path, seen: &mut HashSet, + case_sensitivity: FileSystemCaseSensitivity, ) -> std::io::Result<(PathBuf, VfsEntryRef<'a>)> { let relative_path = match path.strip_prefix(&self.root_path) { Ok(p) => p, @@ -1101,7 +1169,8 @@ impl VfsRoot { } VfsEntryRef::Symlink(symlink) => { let dest = symlink.resolve_dest_from_root(&self.root_path); - let (resolved_path, entry) = self.find_entry_inner(&dest, seen)?; + let (resolved_path, entry) = + self.find_entry_inner(&dest, seen, case_sensitivity)?; final_path = resolved_path; // overwrite with the new resolved path match entry { VfsEntryRef::Dir(dir) => { @@ -1126,7 +1195,7 @@ impl VfsRoot { let component = component.to_string_lossy(); current_entry = current_dir .entries - .get_by_name(&component) + .get_by_name(&component, case_sensitivity) .ok_or_else(|| { std::io::Error::new(std::io::ErrorKind::NotFound, "path not found") })? @@ -1392,13 +1461,19 @@ impl FileBackedVfsMetadata { pub struct FileBackedVfs { vfs_data: Cow<'static, [u8]>, fs_root: VfsRoot, + case_sensitivity: FileSystemCaseSensitivity, } impl FileBackedVfs { - pub fn new(data: Cow<'static, [u8]>, fs_root: VfsRoot) -> Self { + pub fn new( + data: Cow<'static, [u8]>, + fs_root: VfsRoot, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Self { Self { vfs_data: data, fs_root, + case_sensitivity, } } @@ -1451,7 +1526,9 @@ impl FileBackedVfs { } pub fn read_link(&self, path: &Path) -> std::io::Result { - let (_, entry) = self.fs_root.find_entry_no_follow(path)?; + let (_, entry) = self + .fs_root + .find_entry_no_follow(path, self.case_sensitivity)?; match entry { VfsEntryRef::Symlink(symlink) => { Ok(symlink.resolve_dest_from_root(&self.fs_root.root_path)) @@ -1464,17 +1541,19 @@ impl FileBackedVfs { } pub fn lstat(&self, path: &Path) -> std::io::Result { - let (_, entry) = self.fs_root.find_entry_no_follow(path)?; + let (_, entry) = self + .fs_root + .find_entry_no_follow(path, self.case_sensitivity)?; Ok(entry.as_metadata()) } pub fn stat(&self, path: &Path) -> std::io::Result { - let (_, entry) = self.fs_root.find_entry(path)?; + let (_, entry) = self.fs_root.find_entry(path, self.case_sensitivity)?; Ok(entry.as_metadata()) } pub fn canonicalize(&self, path: &Path) -> std::io::Result { - let (path, _) = self.fs_root.find_entry(path)?; + let (path, _) = self.fs_root.find_entry(path, self.case_sensitivity)?; Ok(path) } @@ -1536,7 +1615,7 @@ impl FileBackedVfs { } pub fn dir_entry(&self, path: &Path) -> std::io::Result<&VirtualDirectory> { - let (_, entry) = self.fs_root.find_entry(path)?; + let (_, entry) = self.fs_root.find_entry(path, self.case_sensitivity)?; match entry { VfsEntryRef::Dir(dir) => Ok(dir), VfsEntryRef::Symlink(_) => unreachable!(), @@ -1548,7 +1627,7 @@ impl FileBackedVfs { } pub fn file_entry(&self, path: &Path) -> std::io::Result<&VirtualFile> { - let (_, entry) = self.fs_root.find_entry(path)?; + let (_, entry) = self.fs_root.find_entry(path, self.case_sensitivity)?; match entry { VfsEntryRef::Dir(_) => Err(std::io::Error::new( std::io::ErrorKind::Other, @@ -1754,6 +1833,7 @@ mod test { root_path: dest_path.to_path_buf(), start_file_offset: 0, }, + FileSystemCaseSensitivity::Sensitive, ), ) } diff --git a/tests/specs/compile/case_insensitive_building/__test__.jsonc b/tests/specs/compile/case_insensitive_building/__test__.jsonc new file mode 100644 index 0000000000..38636dc273 --- /dev/null +++ b/tests/specs/compile/case_insensitive_building/__test__.jsonc @@ -0,0 +1,24 @@ +{ + "tempDir": true, + "steps": [{ + "if": "mac", + "args": "compile --output main --include file.txt --include FILE.txt main.js", + "output": "compile.out" + }, { + "if": "mac", + "commandName": "./main", + "args": [], + "output": "main.out", + "exitCode": 0 + }, { + "if": "windows", + "args": "compile --output main.exe --include file.txt --include FILE.txt main.js", + "output": "compile.out" + }, { + "if": "windows", + "commandName": "./main.exe", + "args": [], + "output": "main.out", + "exitCode": 0 + }] +} diff --git a/tests/specs/compile/case_insensitive_building/compile.out b/tests/specs/compile/case_insensitive_building/compile.out new file mode 100644 index 0000000000..895c2f1d46 --- /dev/null +++ b/tests/specs/compile/case_insensitive_building/compile.out @@ -0,0 +1,10 @@ +Compile file:///[WILDLINE]/main.js to main[WILDLINE] + +Embedded Files + +main[WILDLINE] +├── file.txt ([WILDLINE]) +└── main.js ([WILDLINE]) + +Size: [WILDLINE] + diff --git a/tests/specs/compile/case_insensitive_building/file.txt b/tests/specs/compile/case_insensitive_building/file.txt new file mode 100644 index 0000000000..40816a2b5a --- /dev/null +++ b/tests/specs/compile/case_insensitive_building/file.txt @@ -0,0 +1 @@ +Hi \ No newline at end of file diff --git a/tests/specs/compile/case_insensitive_building/main.js b/tests/specs/compile/case_insensitive_building/main.js new file mode 100644 index 0000000000..0fafe8a4dd --- /dev/null +++ b/tests/specs/compile/case_insensitive_building/main.js @@ -0,0 +1 @@ +console.log(Deno.readTextFileSync(import.meta.dirname + "/file.txt")); diff --git a/tests/specs/compile/case_insensitive_building/main.out b/tests/specs/compile/case_insensitive_building/main.out new file mode 100644 index 0000000000..b14df6442e --- /dev/null +++ b/tests/specs/compile/case_insensitive_building/main.out @@ -0,0 +1 @@ +Hi From 5a39f2f09675f4f2ea0198bd8b8e59c9ade703dc Mon Sep 17 00:00:00 2001 From: TateKennington Date: Tue, 14 Jan 2025 10:46:56 +1300 Subject: [PATCH 09/38] fix(node): Prevent node:child_process from always inheriting the parent environment (#27343) (#27340) Fixes #27343 Currently the node:child_process polyfill is always passing the full parent environment to all spawned subprocesses. In the case where `options.env` is provided those keys are overridden but the rest of the parent environment is still passed through. On Node the behaviour is for child processes to only inherit the parent environment when `options.env` isn't specified. When `options.env` is specified the child process inherits only those keys. This PR updates the internal node child_process polyfill so that the `clearEnv` argument is set to true when spawning the subprocess to prevent the parent environment always being inherited by default. It also fixes an issue where `normalizeSpawnArguments` wasn't returning the `env` option if `options.env` was unset. --- ext/node/polyfills/internal/child_process.ts | 2 + tests/unit_node/child_process_test.ts | 67 ++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index 17809cc559..569ee7d328 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -277,6 +277,7 @@ export class ChildProcess extends EventEmitter { try { this.#process = new Deno.Command(cmd, { args: cmdArgs, + clearEnv: true, cwd, env: stringEnv, stdin: toDenoStdio(stdin), @@ -839,6 +840,7 @@ export function normalizeSpawnArguments( args, cwd, detached: !!options.detached, + env, envPairs, file, windowsHide: !!options.windowsHide, diff --git a/tests/unit_node/child_process_test.ts b/tests/unit_node/child_process_test.ts index bd875ad419..1732b9d2bf 100644 --- a/tests/unit_node/child_process_test.ts +++ b/tests/unit_node/child_process_test.ts @@ -656,6 +656,73 @@ Deno.test({ }, }); +Deno.test({ + name: + "[node/child_process spawn] child inherits Deno.env when options.env is not provided", + async fn() { + const deferred = withTimeout(); + Deno.env.set("BAR", "BAR"); + const env = spawn( + `"${Deno.execPath()}" eval -p "Deno.env.toObject().BAR"`, + { + shell: true, + }, + ); + try { + let envOutput = ""; + + assert(env.stdout); + env.on("error", (err: Error) => deferred.reject(err)); + env.stdout.on("data", (data) => { + envOutput += data; + }); + env.on("close", () => { + deferred.resolve(envOutput.trim()); + }); + await deferred.promise; + } finally { + env.kill(); + Deno.env.delete("BAR"); + } + const value = await deferred.promise; + assertEquals(value, "BAR"); + }, +}); + +Deno.test({ + name: + "[node/child_process spawn] child doesn't inherit Deno.env when options.env is provided", + async fn() { + const deferred = withTimeout(); + Deno.env.set("BAZ", "BAZ"); + const env = spawn( + `"${Deno.execPath()}" eval -p "Deno.env.toObject().BAZ"`, + { + env: {}, + shell: true, + }, + ); + try { + let envOutput = ""; + + assert(env.stdout); + env.on("error", (err: Error) => deferred.reject(err)); + env.stdout.on("data", (data) => { + envOutput += data; + }); + env.on("close", () => { + deferred.resolve(envOutput.trim()); + }); + await deferred.promise; + } finally { + env.kill(); + Deno.env.delete("BAZ"); + } + const value = await deferred.promise; + assertEquals(value, "undefined"); + }, +}); + // Regression test for https://github.com/denoland/deno/issues/20373 Deno.test(async function undefinedValueInEnvVar() { const deferred = withTimeout(); From 9dbb99a83cb599028aef662b23e13faf2df15297 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 13 Jan 2025 17:35:18 -0500 Subject: [PATCH 10/38] refactor: create `NpmInstaller` (#27626) This separates npm resolution code from npm installation (more work towards moving resolution code out of the CLI and cleaning up this code). --- Cargo.lock | 4 +- Cargo.toml | 2 +- cli/factory.rs | 223 ++++- cli/graph_util.rs | 44 +- cli/lsp/documents.rs | 10 +- cli/lsp/resolver.rs | 177 +++- cli/main.rs | 12 +- .../common/bin_entries.rs | 3 +- .../common/lifecycle_scripts.rs | 0 .../installers => installer}/common/mod.rs | 4 +- .../installers => installer}/global.rs | 14 +- .../installers => installer}/local.rs | 14 +- cli/npm/installer/mod.rs | 283 +++++++ .../installer.rs => installer/resolution.rs} | 17 +- cli/npm/managed.rs | 496 +++++++++++ cli/npm/managed/installers/mod.rs | 55 -- cli/npm/managed/mod.rs | 768 ------------------ cli/npm/mod.rs | 22 +- cli/resolver.rs | 107 ++- cli/standalone/mod.rs | 46 +- cli/tools/check.rs | 9 +- cli/tools/info.rs | 7 +- cli/tools/installer.rs | 4 +- cli/tools/jupyter/mod.rs | 4 +- cli/tools/registry/pm.rs | 6 +- cli/tools/registry/pm/cache_deps.rs | 15 +- cli/tools/registry/pm/deps.rs | 10 +- cli/tools/registry/pm/outdated.rs | 1 + cli/tools/repl/mod.rs | 4 +- cli/tools/repl/session.rs | 16 +- cli/tools/run/mod.rs | 12 +- cli/tools/task.rs | 21 +- cli/tsc/mod.rs | 5 +- cli/worker.rs | 13 +- resolvers/deno/npm/managed/global.rs | 6 +- resolvers/deno/npm/managed/local.rs | 6 +- resolvers/deno/npm/managed/mod.rs | 57 +- resolvers/deno/npm/managed/resolution.rs | 9 +- runtime/ops/process.rs | 2 + 39 files changed, 1367 insertions(+), 1141 deletions(-) rename cli/npm/{managed/installers => installer}/common/bin_entries.rs (99%) rename cli/npm/{managed/installers => installer}/common/lifecycle_scripts.rs (100%) rename cli/npm/{managed/installers => installer}/common/mod.rs (79%) rename cli/npm/{managed/installers => installer}/global.rs (97%) rename cli/npm/{managed/installers => installer}/local.rs (99%) create mode 100644 cli/npm/installer/mod.rs rename cli/npm/{managed/installer.rs => installer/resolution.rs} (92%) create mode 100644 cli/npm/managed.rs delete mode 100644 cli/npm/managed/installers/mod.rs delete mode 100644 cli/npm/managed/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 1f13898fe0..b2a78300c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2074,9 +2074,9 @@ dependencies = [ [[package]] name = "deno_npm" -version = "0.27.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f818ad5dc4c206b50b5cfa6f10b4b94b127e15c8342c152768eba40c225ca23" +checksum = "4adceb4c34f10e837d0e3ae76e88dddefb13e83c05c1ef1699fa5519241c9d27" dependencies = [ "async-trait", "capacity_builder 0.5.0", diff --git a/Cargo.toml b/Cargo.toml index 48abe48305..2b52664a7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ deno_bench_util = { version = "0.179.0", path = "./bench_util" } deno_config = { version = "=0.43.0", features = ["workspace", "sync"] } deno_lockfile = "=0.24.0" deno_media_type = { version = "0.2.3", features = ["module_specifier"] } -deno_npm = "=0.27.0" +deno_npm = "=0.27.2" deno_path_util = "=0.3.0" deno_permissions = { version = "0.44.0", path = "./runtime/permissions" } deno_runtime = { version = "0.193.0", path = "./runtime" } diff --git a/cli/factory.rs b/cli/factory.rs index 25a39cae8b..e3873b5164 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -11,8 +11,10 @@ use deno_core::error::AnyError; use deno_core::futures::FutureExt; use deno_core::FeatureChecker; use deno_error::JsErrorBox; +use deno_npm_cache::NpmCacheSetting; use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; +use deno_resolver::npm::managed::NpmResolutionCell; use deno_resolver::npm::CreateInNpmPkgCheckerOptions; use deno_resolver::npm::NpmReqResolverOptions; use deno_resolver::sloppy_imports::SloppyImportsCachedFs; @@ -67,19 +69,27 @@ use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; use crate::npm::create_cli_npm_resolver; +use crate::npm::installer::NpmInstaller; +use crate::npm::installer::NpmResolutionInstaller; use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliManagedNpmResolverCreateOptions; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmCacheHttpClient; +use crate::npm::CliNpmRegistryInfoProvider; use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolverCreateOptions; use crate::npm::CliNpmResolverManagedSnapshotOption; +use crate::npm::CliNpmTarballCache; use crate::npm::NpmRegistryReadPermissionChecker; use crate::npm::NpmRegistryReadPermissionCheckerMode; +use crate::npm::NpmResolutionInitializer; use crate::resolver::CjsTracker; use crate::resolver::CliDenoResolver; +use crate::resolver::CliNpmGraphResolver; use crate::resolver::CliNpmReqResolver; use crate::resolver::CliResolver; -use crate::resolver::CliResolverOptions; use crate::resolver::CliSloppyImportsResolver; +use crate::resolver::FoundPackageJsonDepFlag; use crate::resolver::NpmModuleLoader; use crate::standalone::binary::DenoCompileBinaryWriter; use crate::sys::CliSys; @@ -188,6 +198,7 @@ struct CliFactoryServices { emitter: Deferred>, feature_checker: Deferred>, file_fetcher: Deferred>, + found_pkg_json_dep_flag: Arc, fs: Deferred>, global_http_cache: Deferred>, http_cache: Deferred>, @@ -202,9 +213,18 @@ struct CliFactoryServices { module_load_preparer: Deferred>, node_code_translator: Deferred>, node_resolver: Deferred>, + npm_cache: Deferred>, npm_cache_dir: Deferred>, + npm_cache_http_client: Deferred>, + npm_graph_resolver: Deferred>, + npm_installer: Deferred>, + npm_registry_info_provider: Deferred>, npm_req_resolver: Deferred>, + npm_resolution: Arc, + npm_resolution_initializer: Deferred>, + npm_resolution_installer: Deferred>, npm_resolver: Deferred>, + npm_tarball_cache: Deferred>, parsed_source_cache: Deferred>, permission_desc_parser: Deferred>>, @@ -398,6 +418,18 @@ impl CliFactory { }) } + pub fn npm_cache(&self) -> Result<&Arc, AnyError> { + self.services.npm_cache.get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(CliNpmCache::new( + self.npm_cache_dir()?.clone(), + self.sys(), + NpmCacheSetting::from_cache_setting(&cli_options.cache_setting()), + cli_options.npmrc().clone(), + ))) + }) + } + pub fn npm_cache_dir(&self) -> Result<&Arc, AnyError> { self.services.npm_cache_dir.get_or_try_init(|| { let global_path = self.deno_dir()?.npm_folder_path(); @@ -410,6 +442,123 @@ impl CliFactory { }) } + pub fn npm_cache_http_client(&self) -> &Arc { + self.services.npm_cache_http_client.get_or_init(|| { + Arc::new(CliNpmCacheHttpClient::new( + self.http_client_provider().clone(), + self.text_only_progress_bar().clone(), + )) + }) + } + + pub fn npm_graph_resolver( + &self, + ) -> Result<&Arc, AnyError> { + self.services.npm_graph_resolver.get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(CliNpmGraphResolver::new( + self.npm_installer_if_managed()?.cloned(), + self.services.found_pkg_json_dep_flag.clone(), + cli_options.unstable_bare_node_builtins(), + cli_options.default_npm_caching_strategy(), + ))) + }) + } + + pub fn npm_installer_if_managed( + &self, + ) -> Result>, AnyError> { + let options = self.cli_options()?; + if options.use_byonm() || options.no_npm() { + Ok(None) + } else { + Ok(Some(self.npm_installer()?)) + } + } + + pub fn npm_installer(&self) -> Result<&Arc, AnyError> { + self.services.npm_installer.get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(NpmInstaller::new( + self.npm_cache()?.clone(), + Arc::new(NpmInstallDepsProvider::from_workspace( + cli_options.workspace(), + )), + self.npm_resolution().clone(), + self.npm_resolution_initializer()?.clone(), + self.npm_resolution_installer()?.clone(), + self.text_only_progress_bar(), + self.sys(), + self.npm_tarball_cache()?.clone(), + cli_options.maybe_lockfile().cloned(), + cli_options.node_modules_dir_path().cloned(), + cli_options.lifecycle_scripts_config(), + cli_options.npm_system_info(), + ))) + }) + } + + pub fn npm_registry_info_provider( + &self, + ) -> Result<&Arc, AnyError> { + self + .services + .npm_registry_info_provider + .get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(CliNpmRegistryInfoProvider::new( + self.npm_cache()?.clone(), + self.npm_cache_http_client().clone(), + cli_options.npmrc().clone(), + ))) + }) + } + + pub fn npm_resolution(&self) -> &Arc { + &self.services.npm_resolution + } + + pub fn npm_resolution_initializer( + &self, + ) -> Result<&Arc, AnyError> { + self + .services + .npm_resolution_initializer + .get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(NpmResolutionInitializer::new( + self.npm_registry_info_provider()?.clone(), + self.npm_resolution().clone(), + match cli_options.resolve_npm_resolution_snapshot()? { + Some(snapshot) => { + CliNpmResolverManagedSnapshotOption::Specified(Some(snapshot)) + } + None => match cli_options.maybe_lockfile() { + Some(lockfile) => { + CliNpmResolverManagedSnapshotOption::ResolveFromLockfile( + lockfile.clone(), + ) + } + None => CliNpmResolverManagedSnapshotOption::Specified(None), + }, + }, + ))) + }) + } + + pub fn npm_resolution_installer( + &self, + ) -> Result<&Arc, AnyError> { + self.services.npm_resolution_installer.get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(NpmResolutionInstaller::new( + self.npm_registry_info_provider()?.clone(), + self.npm_resolution().clone(), + cli_options.maybe_lockfile().cloned(), + ))) + }) + } + pub async fn npm_resolver( &self, ) -> Result<&Arc, AnyError> { @@ -419,7 +568,7 @@ impl CliFactory { .get_or_try_init_async( async { let cli_options = self.cli_options()?; - create_cli_npm_resolver(if cli_options.use_byonm() { + Ok(create_cli_npm_resolver(if cli_options.use_byonm() { CliNpmResolverCreateOptions::Byonm( CliByonmNpmResolverCreateOptions { sys: self.sys(), @@ -438,52 +587,43 @@ impl CliFactory { }, ) } else { + self + .npm_resolution_initializer()? + .ensure_initialized() + .await?; CliNpmResolverCreateOptions::Managed( CliManagedNpmResolverCreateOptions { - http_client_provider: self.http_client_provider().clone(), - npm_install_deps_provider: Arc::new( - NpmInstallDepsProvider::from_workspace( - cli_options.workspace(), - ), - ), sys: self.sys(), - snapshot: match cli_options.resolve_npm_resolution_snapshot()? { - Some(snapshot) => { - CliNpmResolverManagedSnapshotOption::Specified(Some( - snapshot, - )) - } - None => match cli_options.maybe_lockfile() { - Some(lockfile) => { - CliNpmResolverManagedSnapshotOption::ResolveFromLockfile( - lockfile.clone(), - ) - } - None => { - CliNpmResolverManagedSnapshotOption::Specified(None) - } - }, - }, - maybe_lockfile: cli_options.maybe_lockfile().cloned(), + npm_resolution: self.npm_resolution().clone(), npm_cache_dir: self.npm_cache_dir()?.clone(), - cache_setting: cli_options.cache_setting(), - text_only_progress_bar: self.text_only_progress_bar().clone(), maybe_node_modules_path: cli_options .node_modules_dir_path() .cloned(), npm_system_info: cli_options.npm_system_info(), npmrc: cli_options.npmrc().clone(), - lifecycle_scripts: cli_options.lifecycle_scripts_config(), }, ) - }) - .await + })) } .boxed_local(), ) .await } + pub fn npm_tarball_cache( + &self, + ) -> Result<&Arc, AnyError> { + self.services.npm_tarball_cache.get_or_try_init(|| { + let cli_options = self.cli_options()?; + Ok(Arc::new(CliNpmTarballCache::new( + self.npm_cache()?.clone(), + self.npm_cache_http_client().clone(), + self.sys(), + cli_options.npmrc().clone(), + ))) + }) + } + pub fn sloppy_imports_resolver( &self, ) -> Result>, AnyError> { @@ -571,17 +711,10 @@ impl CliFactory { .resolver .get_or_try_init_async( async { - let cli_options = self.cli_options()?; - Ok(Arc::new(CliResolver::new(CliResolverOptions { - npm_resolver: if cli_options.no_npm() { - None - } else { - Some(self.npm_resolver().await?.clone()) - }, - bare_node_builtins_enabled: cli_options - .unstable_bare_node_builtins(), - deno_resolver: self.deno_resolver().await?.clone(), - }))) + Ok(Arc::new(CliResolver::new( + self.deno_resolver().await?.clone(), + self.services.found_pkg_json_dep_flag.clone(), + ))) } .boxed_local(), ) @@ -752,6 +885,7 @@ impl CliFactory { cli_options.clone(), self.module_graph_builder().await?.clone(), self.node_resolver().await?.clone(), + self.npm_installer_if_managed()?.cloned(), self.npm_resolver().await?.clone(), self.sys(), ))) @@ -777,6 +911,8 @@ impl CliFactory { cli_options.maybe_lockfile().cloned(), self.maybe_file_watcher_reporter().clone(), self.module_info_cache()?.clone(), + self.npm_graph_resolver()?.clone(), + self.npm_installer_if_managed()?.cloned(), self.npm_resolver().await?.clone(), self.parsed_source_cache().clone(), self.resolver().await?.clone(), @@ -797,7 +933,7 @@ impl CliFactory { let cli_options = self.cli_options()?; Ok(Arc::new(ModuleGraphCreator::new( cli_options.clone(), - self.npm_resolver().await?.clone(), + self.npm_installer_if_managed()?.cloned(), self.module_graph_builder().await?.clone(), self.type_checker().await?.clone(), ))) @@ -997,6 +1133,7 @@ impl CliFactory { self.sys(), )), node_resolver.clone(), + self.npm_installer_if_managed()?.cloned(), npm_resolver.clone(), pkg_json_resolver, self.root_cert_store_provider().clone(), diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 8da44c76ab..17d4fef553 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use deno_config::deno_json; use deno_config::deno_json::JsxImportSourceConfig; +use deno_config::deno_json::NodeModulesDirMode; use deno_config::workspace::JsrPackageConfig; use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; @@ -51,8 +52,11 @@ use crate::cache::ModuleInfoCache; use crate::cache::ParsedSourceCache; use crate::colors; use crate::file_fetcher::CliFileFetcher; +use crate::npm::installer::NpmInstaller; +use crate::npm::installer::PackageCaching; use crate::npm::CliNpmResolver; use crate::resolver::CjsTracker; +use crate::resolver::CliNpmGraphResolver; use crate::resolver::CliResolver; use crate::resolver::CliSloppyImportsResolver; use crate::sys::CliSys; @@ -263,7 +267,7 @@ pub struct CreateGraphOptions<'a> { pub struct ModuleGraphCreator { options: Arc, - npm_resolver: Arc, + npm_installer: Option>, module_graph_builder: Arc, type_checker: Arc, } @@ -271,13 +275,13 @@ pub struct ModuleGraphCreator { impl ModuleGraphCreator { pub fn new( options: Arc, - npm_resolver: Arc, + npm_installer: Option>, module_graph_builder: Arc, type_checker: Arc, ) -> Self { Self { options, - npm_resolver, + npm_installer, module_graph_builder, type_checker, } @@ -400,9 +404,9 @@ impl ModuleGraphCreator { .build_graph_with_npm_resolution(&mut graph, options) .await?; - if let Some(npm_resolver) = self.npm_resolver.as_managed() { + if let Some(npm_installer) = &self.npm_installer { if graph.has_node_specifier && self.options.type_check_mode().is_true() { - npm_resolver.inject_synthetic_types_node_package().await?; + npm_installer.inject_synthetic_types_node_package().await?; } } @@ -497,6 +501,8 @@ pub struct ModuleGraphBuilder { lockfile: Option>, maybe_file_watcher_reporter: Option, module_info_cache: Arc, + npm_graph_resolver: Arc, + npm_installer: Option>, npm_resolver: Arc, parsed_source_cache: Arc, resolver: Arc, @@ -516,6 +522,8 @@ impl ModuleGraphBuilder { lockfile: Option>, maybe_file_watcher_reporter: Option, module_info_cache: Arc, + npm_graph_resolver: Arc, + npm_installer: Option>, npm_resolver: Arc, parsed_source_cache: Arc, resolver: Arc, @@ -532,6 +540,8 @@ impl ModuleGraphBuilder { lockfile, maybe_file_watcher_reporter, module_info_cache, + npm_graph_resolver, + npm_installer, npm_resolver, parsed_source_cache, resolver, @@ -630,10 +640,7 @@ impl ModuleGraphBuilder { Some(loader) => MutLoaderRef::Borrowed(loader), None => MutLoaderRef::Owned(self.create_graph_loader()), }; - let cli_resolver = &self.resolver; let graph_resolver = self.create_graph_resolver()?; - let graph_npm_resolver = - cli_resolver.create_graph_npm_resolver(options.npm_caching); let maybe_file_watcher_reporter = self .maybe_file_watcher_reporter .as_ref() @@ -654,7 +661,7 @@ impl ModuleGraphBuilder { executor: Default::default(), file_system: &self.sys, jsr_url_provider: &CliJsrUrlProvider, - npm_resolver: Some(&graph_npm_resolver), + npm_resolver: Some(self.npm_graph_resolver.as_ref()), module_analyzer: &analyzer, reporter: maybe_file_watcher_reporter, resolver: Some(&graph_resolver), @@ -678,16 +685,15 @@ impl ModuleGraphBuilder { if self .cli_options .node_modules_dir()? - .map(|m| m.uses_node_modules_dir()) + .map(|m| m == NodeModulesDirMode::Auto) .unwrap_or(false) { - if let Some(npm_resolver) = self.npm_resolver.as_managed() { - let already_done = - npm_resolver.ensure_top_level_package_json_install().await?; + if let Some(npm_installer) = &self.npm_installer { + let already_done = npm_installer + .ensure_top_level_package_json_install() + .await?; if !already_done && matches!(npm_caching, NpmCachingStrategy::Eager) { - npm_resolver - .cache_packages(crate::npm::PackageCaching::All) - .await?; + npm_installer.cache_packages(PackageCaching::All).await?; } } } @@ -775,11 +781,7 @@ impl ModuleGraphBuilder { None }; let parser = self.parsed_source_cache.as_capturing_parser(); - let cli_resolver = &self.resolver; let graph_resolver = self.create_graph_resolver()?; - let graph_npm_resolver = cli_resolver.create_graph_npm_resolver( - self.cli_options.default_npm_caching_strategy(), - ); graph.build_fast_check_type_graph( deno_graph::BuildFastCheckTypeGraphOptions { @@ -788,7 +790,7 @@ impl ModuleGraphBuilder { fast_check_dts: false, jsr_url_provider: &CliJsrUrlProvider, resolver: Some(&graph_resolver), - npm_resolver: Some(&graph_npm_resolver), + npm_resolver: Some(self.npm_graph_resolver.as_ref()), workspace_fast_check: options.workspace_fast_check, }, ); diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index f31353d436..70f55ffd62 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -480,7 +480,7 @@ impl Document { let is_cjs_resolver = resolver.as_is_cjs_resolver(self.file_referrer.as_ref()); let npm_resolver = - resolver.create_graph_npm_resolver(self.file_referrer.as_ref()); + resolver.as_graph_npm_resolver(self.file_referrer.as_ref()); let config_data = resolver.as_config_data(self.file_referrer.as_ref()); let jsx_import_source_config = config_data.and_then(|d| d.maybe_jsx_import_source_config()); @@ -503,7 +503,7 @@ impl Document { s, &CliJsrUrlProvider, Some(&resolver), - Some(&npm_resolver), + Some(npm_resolver.as_ref()), ), ) }) @@ -513,7 +513,7 @@ impl Document { Arc::new(d.with_new_resolver( &CliJsrUrlProvider, Some(&resolver), - Some(&npm_resolver), + Some(npm_resolver.as_ref()), )) }); is_script = self.is_script; @@ -1702,7 +1702,7 @@ fn analyze_module( ) -> (ModuleResult, ResolutionMode) { match parsed_source_result { Ok(parsed_source) => { - let npm_resolver = resolver.create_graph_npm_resolver(file_referrer); + let npm_resolver = resolver.as_graph_npm_resolver(file_referrer); let cli_resolver = resolver.as_cli_resolver(file_referrer); let is_cjs_resolver = resolver.as_is_cjs_resolver(file_referrer); let config_data = resolver.as_config_data(file_referrer); @@ -1731,7 +1731,7 @@ fn analyze_module( file_system: &deno_graph::source::NullFileSystem, jsr_url_provider: &CliJsrUrlProvider, maybe_resolver: Some(&resolver), - maybe_npm_resolver: Some(&npm_resolver), + maybe_npm_resolver: Some(npm_resolver.as_ref()), }, )), module_resolution_mode, diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index d7f7e684a9..af4ab6571f 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -9,7 +9,6 @@ use std::sync::Arc; use dashmap::DashMap; use deno_ast::MediaType; -use deno_cache_dir::file_fetcher::CacheSetting; use deno_cache_dir::npm::NpmCacheDir; use deno_cache_dir::HttpCache; use deno_config::deno_json::JsxImportSourceConfig; @@ -21,9 +20,11 @@ use deno_graph::GraphImport; use deno_graph::ModuleSpecifier; use deno_graph::Range; use deno_npm::NpmSystemInfo; +use deno_npm_cache::TarballCache; use deno_path_util::url_to_file_path; use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; +use deno_resolver::npm::managed::NpmResolutionCell; use deno_resolver::npm::CreateInNpmPkgCheckerOptions; use deno_resolver::npm::NpmReqResolverOptions; use deno_resolver::DenoResolverOptions; @@ -42,6 +43,8 @@ use super::cache::LspCache; use super::jsr::JsrCacheResolver; use crate::args::create_default_npmrc; use crate::args::CliLockfile; +use crate::args::LifecycleScriptsConfig; +use crate::args::NpmCachingStrategy; use crate::args::NpmInstallDepsProvider; use crate::factory::Deferred; use crate::graph_util::to_node_resolution_kind; @@ -53,19 +56,25 @@ use crate::lsp::config::ConfigData; use crate::lsp::logging::lsp_warn; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; -use crate::npm::create_cli_npm_resolver_for_lsp; +use crate::npm::create_cli_npm_resolver; +use crate::npm::installer::NpmInstaller; +use crate::npm::installer::NpmResolutionInstaller; use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliManagedNpmResolverCreateOptions; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmCacheHttpClient; +use crate::npm::CliNpmRegistryInfoProvider; use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolverCreateOptions; use crate::npm::CliNpmResolverManagedSnapshotOption; use crate::npm::ManagedCliNpmResolver; +use crate::npm::NpmResolutionInitializer; use crate::resolver::CliDenoResolver; +use crate::resolver::CliNpmGraphResolver; use crate::resolver::CliNpmReqResolver; use crate::resolver::CliResolver; -use crate::resolver::CliResolverOptions; +use crate::resolver::FoundPackageJsonDepFlag; use crate::resolver::IsCjsResolver; -use crate::resolver::WorkerCliNpmGraphResolver; use crate::sys::CliSys; use crate::tsc::into_specifier_and_media_type; use crate::util::progress_bar::ProgressBar; @@ -77,6 +86,8 @@ struct LspScopeResolver { in_npm_pkg_checker: Arc, is_cjs_resolver: Arc, jsr_resolver: Option>, + npm_graph_resolver: Arc, + npm_installer: Option>, npm_resolver: Option>, node_resolver: Option>, npm_pkg_req_resolver: Option>, @@ -96,6 +107,8 @@ impl Default for LspScopeResolver { in_npm_pkg_checker: factory.in_npm_pkg_checker().clone(), is_cjs_resolver: factory.is_cjs_resolver().clone(), jsr_resolver: None, + npm_graph_resolver: factory.npm_graph_resolver().clone(), + npm_installer: None, npm_resolver: None, node_resolver: None, npm_pkg_req_resolver: None, @@ -121,6 +134,7 @@ impl LspScopeResolver { } let in_npm_pkg_checker = factory.in_npm_pkg_checker().clone(); let npm_resolver = factory.npm_resolver().cloned(); + let npm_installer = factory.npm_installer().cloned(); let node_resolver = factory.node_resolver().cloned(); let npm_pkg_req_resolver = factory.npm_pkg_req_resolver().cloned(); let cli_resolver = factory.cli_resolver().clone(); @@ -133,8 +147,7 @@ impl LspScopeResolver { cache.for_specifier(config_data.map(|d| d.scope.as_ref())), config_data.and_then(|d| d.lockfile.clone()), ))); - let npm_graph_resolver = cli_resolver - .create_graph_npm_resolver(crate::graph_util::NpmCachingStrategy::Eager); + let npm_graph_resolver = factory.npm_graph_resolver(); let maybe_jsx_import_source_config = config_data.and_then(|d| d.maybe_jsx_import_source_config()); let graph_imports = config_data @@ -156,7 +169,7 @@ impl LspScopeResolver { imports, &CliJsrUrlProvider, Some(&resolver), - Some(&npm_graph_resolver), + Some(npm_graph_resolver.as_ref()), ); (referrer, graph_import) }) @@ -207,8 +220,10 @@ impl LspScopeResolver { in_npm_pkg_checker, is_cjs_resolver: factory.is_cjs_resolver().clone(), jsr_resolver, + npm_graph_resolver: factory.npm_graph_resolver().clone(), npm_pkg_req_resolver, npm_resolver, + npm_installer, node_resolver, pkg_json_resolver, redirect_resolver, @@ -231,6 +246,9 @@ impl LspScopeResolver { in_npm_pkg_checker: factory.in_npm_pkg_checker().clone(), is_cjs_resolver: factory.is_cjs_resolver().clone(), jsr_resolver: self.jsr_resolver.clone(), + npm_graph_resolver: factory.npm_graph_resolver().clone(), + // npm installer isn't necessary for a snapshot + npm_installer: None, npm_pkg_req_resolver: factory.npm_pkg_req_resolver().cloned(), npm_resolver: factory.npm_resolver().cloned(), node_resolver: factory.node_resolver().cloned(), @@ -318,14 +336,12 @@ impl LspResolver { if let Some(dep_info) = dep_info { *resolver.dep_info.lock() = dep_info.clone(); } - if let Some(npm_resolver) = resolver.npm_resolver.as_ref() { - if let Some(npm_resolver) = npm_resolver.as_managed() { - let reqs = dep_info - .map(|i| i.npm_reqs.iter().cloned().collect::>()) - .unwrap_or_default(); - if let Err(err) = npm_resolver.set_package_reqs(&reqs).await { - lsp_warn!("Could not set npm package requirements: {:#}", err); - } + if let Some(npm_installer) = resolver.npm_installer.as_ref() { + let reqs = dep_info + .map(|i| i.npm_reqs.iter().cloned().collect::>()) + .unwrap_or_default(); + if let Err(err) = npm_installer.set_package_reqs(&reqs).await { + lsp_warn!("Could not set npm package requirements: {:#}", err); } } } @@ -339,14 +355,12 @@ impl LspResolver { resolver.resolver.as_ref() } - pub fn create_graph_npm_resolver( + pub fn as_graph_npm_resolver( &self, file_referrer: Option<&ModuleSpecifier>, - ) -> WorkerCliNpmGraphResolver { + ) -> &Arc { let resolver = self.get_scope_resolver(file_referrer); - resolver - .resolver - .create_graph_npm_resolver(crate::graph_util::NpmCachingStrategy::Eager) + &resolver.npm_graph_resolver } pub fn as_is_cjs_resolver( @@ -590,9 +604,12 @@ pub struct ScopeDepInfo { #[derive(Default)] struct ResolverFactoryServices { cli_resolver: Deferred>, + found_pkg_json_dep_flag: Arc, in_npm_pkg_checker: Deferred>, is_cjs_resolver: Deferred>, node_resolver: Deferred>>, + npm_graph_resolver: Deferred>, + npm_installer: Option>, npm_pkg_req_resolver: Deferred>>, npm_resolver: Option>, } @@ -616,6 +633,10 @@ impl<'a> ResolverFactory<'a> { } } + // todo(dsherret): probably this method could be removed in the future + // and instead just `npm_resolution_initializer.ensure_initialized()` could + // be called. The reason this exists is because creating the npm resolvers + // used to be async. async fn init_npm_resolver( &mut self, http_client_provider: &Arc, @@ -645,11 +666,31 @@ impl<'a> ResolverFactory<'a> { cache.deno_dir().npm_folder_path(), npmrc.get_all_known_registries_urls(), )); - CliNpmResolverCreateOptions::Managed(CliManagedNpmResolverCreateOptions { - http_client_provider: http_client_provider.clone(), - // only used for top level install, so we can ignore this - npm_install_deps_provider: Arc::new(NpmInstallDepsProvider::empty()), - snapshot: match self.config_data.and_then(|d| d.lockfile.as_ref()) { + let npm_cache = Arc::new(CliNpmCache::new( + npm_cache_dir.clone(), + sys.clone(), + // Use an "only" cache setting in order to make the + // user do an explicit "cache" command and prevent + // the cache from being filled with lots of packages while + // the user is typing. + deno_npm_cache::NpmCacheSetting::Only, + npmrc.clone(), + )); + let pb = ProgressBar::new(ProgressBarStyle::TextOnly); + let npm_client = Arc::new(CliNpmCacheHttpClient::new( + http_client_provider.clone(), + pb.clone(), + )); + let registry_info_provider = Arc::new(CliNpmRegistryInfoProvider::new( + npm_cache.clone(), + npm_client.clone(), + npmrc.clone(), + )); + let npm_resolution = Arc::new(NpmResolutionCell::default()); + let npm_resolution_initializer = Arc::new(NpmResolutionInitializer::new( + registry_info_provider.clone(), + npm_resolution.clone(), + match self.config_data.and_then(|d| d.lockfile.as_ref()) { Some(lockfile) => { CliNpmResolverManagedSnapshotOption::ResolveFromLockfile( lockfile.clone(), @@ -657,26 +698,62 @@ impl<'a> ResolverFactory<'a> { } None => CliNpmResolverManagedSnapshotOption::Specified(None), }, + )); + // Don't provide the lockfile. We don't want these resolvers + // updating it. Only the cache request should update the lockfile. + let maybe_lockfile: Option> = None; + let maybe_node_modules_path = + self.config_data.and_then(|d| d.node_modules_dir.clone()); + let tarball_cache = Arc::new(TarballCache::new( + npm_cache.clone(), + npm_client.clone(), + sys.clone(), + npmrc.clone(), + )); + let npm_resolution_installer = Arc::new(NpmResolutionInstaller::new( + registry_info_provider, + npm_resolution.clone(), + maybe_lockfile.clone(), + )); + let npm_installer = Arc::new(NpmInstaller::new( + npm_cache.clone(), + Arc::new(NpmInstallDepsProvider::empty()), + npm_resolution.clone(), + npm_resolution_initializer.clone(), + npm_resolution_installer, + &pb, + sys.clone(), + tarball_cache.clone(), + maybe_lockfile, + maybe_node_modules_path.clone(), + LifecycleScriptsConfig::default(), + NpmSystemInfo::default(), + )); + self.set_npm_installer(npm_installer); + // spawn due to the lsp's `Send` requirement + deno_core::unsync::spawn(async move { + if let Err(err) = npm_resolution_initializer.ensure_initialized().await + { + log::warn!("failed to initialize npm resolution: {}", err); + } + }) + .await + .unwrap(); + + CliNpmResolverCreateOptions::Managed(CliManagedNpmResolverCreateOptions { sys: CliSys::default(), npm_cache_dir, - // Use an "only" cache setting in order to make the - // user do an explicit "cache" command and prevent - // the cache from being filled with lots of packages while - // the user is typing. - cache_setting: CacheSetting::Only, - text_only_progress_bar: ProgressBar::new(ProgressBarStyle::TextOnly), - // Don't provide the lockfile. We don't want these resolvers - // updating it. Only the cache request should update the lockfile. - maybe_lockfile: None, - maybe_node_modules_path: self - .config_data - .and_then(|d| d.node_modules_dir.clone()), + maybe_node_modules_path, npmrc, + npm_resolution, npm_system_info: NpmSystemInfo::default(), - lifecycle_scripts: Default::default(), }) }; - self.set_npm_resolver(create_cli_npm_resolver_for_lsp(options).await); + self.set_npm_resolver(create_cli_npm_resolver(options)); + } + + pub fn set_npm_installer(&mut self, npm_installer: Arc) { + self.services.npm_installer = Some(npm_installer); } pub fn set_npm_resolver(&mut self, npm_resolver: Arc) { @@ -720,13 +797,27 @@ impl<'a> ResolverFactory<'a> { is_byonm: self.config_data.map(|d| d.byonm).unwrap_or(false), maybe_vendor_dir: self.config_data.and_then(|d| d.vendor_dir.as_ref()), })); - Arc::new(CliResolver::new(CliResolverOptions { + Arc::new(CliResolver::new( deno_resolver, - npm_resolver: self.npm_resolver().cloned(), - bare_node_builtins_enabled: self + self.services.found_pkg_json_dep_flag.clone(), + )) + }) + } + + pub fn npm_installer(&self) -> Option<&Arc> { + self.services.npm_installer.as_ref() + } + + pub fn npm_graph_resolver(&self) -> &Arc { + self.services.npm_graph_resolver.get_or_init(|| { + Arc::new(CliNpmGraphResolver::new( + None, + self.services.found_pkg_json_dep_flag.clone(), + self .config_data .is_some_and(|d| d.unstable.contains("bare-node-builtins")), - })) + NpmCachingStrategy::Eager, + )) }) } diff --git a/cli/main.rs b/cli/main.rs index 6bbefcf956..f97ea81e5d 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -40,7 +40,6 @@ use deno_core::error::AnyError; use deno_core::error::CoreError; use deno_core::futures::FutureExt; use deno_core::unsync::JoinHandle; -use deno_npm::resolution::SnapshotFromLockfileError; use deno_resolver::npm::ByonmResolvePkgFolderFromDenoReqError; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_runtime::fmt_errors::format_js_error; @@ -52,6 +51,7 @@ use factory::CliFactory; use standalone::MODULE_NOT_FOUND; use standalone::UNSUPPORTED_SCHEME; +use self::npm::ResolveSnapshotError; use crate::args::flags_from_vec; use crate::args::DenoSubcommand; use crate::args::Flags; @@ -376,13 +376,15 @@ fn exit_for_error(error: AnyError) -> ! { util::result::any_and_jserrorbox_downcast_ref::(&error) { error_string = format_js_error(e); - } else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) = - util::result::any_and_jserrorbox_downcast_ref::( + } else if let Some(e @ ResolveSnapshotError { .. }) = + util::result::any_and_jserrorbox_downcast_ref::( &error, ) { - error_string = e.to_string(); - error_code = 10; + if let Some(e) = e.maybe_integrity_check_error() { + error_string = e.to_string(); + error_code = 10; + } } exit_with_message(&error_string, error_code); diff --git a/cli/npm/managed/installers/common/bin_entries.rs b/cli/npm/installer/common/bin_entries.rs similarity index 99% rename from cli/npm/managed/installers/common/bin_entries.rs rename to cli/npm/installer/common/bin_entries.rs index bc69786b6c..2f7bed285a 100644 --- a/cli/npm/managed/installers/common/bin_entries.rs +++ b/cli/npm/installer/common/bin_entries.rs @@ -8,8 +8,7 @@ use std::path::PathBuf; use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::NpmPackageId; - -use crate::npm::managed::NpmResolutionPackage; +use deno_npm::NpmResolutionPackage; #[derive(Default)] pub struct BinEntries<'a> { diff --git a/cli/npm/managed/installers/common/lifecycle_scripts.rs b/cli/npm/installer/common/lifecycle_scripts.rs similarity index 100% rename from cli/npm/managed/installers/common/lifecycle_scripts.rs rename to cli/npm/installer/common/lifecycle_scripts.rs diff --git a/cli/npm/managed/installers/common/mod.rs b/cli/npm/installer/common/mod.rs similarity index 79% rename from cli/npm/managed/installers/common/mod.rs rename to cli/npm/installer/common/mod.rs index 9659649a2e..bd22a58f03 100644 --- a/cli/npm/managed/installers/common/mod.rs +++ b/cli/npm/installer/common/mod.rs @@ -3,14 +3,14 @@ use async_trait::async_trait; use deno_error::JsErrorBox; -use crate::npm::PackageCaching; +use super::PackageCaching; pub mod bin_entries; pub mod lifecycle_scripts; /// Part of the resolution that interacts with the file system. #[async_trait(?Send)] -pub trait NpmPackageFsInstaller: Send + Sync { +pub trait NpmPackageFsInstaller: std::fmt::Debug + Send + Sync { async fn cache_packages<'a>( &self, caching: PackageCaching<'a>, diff --git a/cli/npm/managed/installers/global.rs b/cli/npm/installer/global.rs similarity index 97% rename from cli/npm/managed/installers/global.rs rename to cli/npm/installer/global.rs index 477d73dbfb..a6b296c6d8 100644 --- a/cli/npm/managed/installers/global.rs +++ b/cli/npm/installer/global.rs @@ -11,14 +11,14 @@ use deno_core::futures::StreamExt; use deno_error::JsErrorBox; use deno_npm::NpmResolutionPackage; use deno_npm::NpmSystemInfo; -use deno_resolver::npm::managed::NpmResolution; +use deno_resolver::npm::managed::NpmResolutionCell; use super::common::lifecycle_scripts::LifecycleScriptsStrategy; use super::common::NpmPackageFsInstaller; +use super::PackageCaching; use crate::args::LifecycleScriptsConfig; use crate::cache::FastInsecureHasher; use crate::colors; -use crate::npm::managed::PackageCaching; use crate::npm::CliNpmCache; use crate::npm::CliNpmTarballCache; @@ -27,25 +27,25 @@ use crate::npm::CliNpmTarballCache; pub struct GlobalNpmPackageInstaller { cache: Arc, tarball_cache: Arc, - resolution: Arc, - system_info: NpmSystemInfo, + resolution: Arc, lifecycle_scripts: LifecycleScriptsConfig, + system_info: NpmSystemInfo, } impl GlobalNpmPackageInstaller { pub fn new( cache: Arc, tarball_cache: Arc, - resolution: Arc, - system_info: NpmSystemInfo, + resolution: Arc, lifecycle_scripts: LifecycleScriptsConfig, + system_info: NpmSystemInfo, ) -> Self { Self { cache, tarball_cache, resolution, - system_info, lifecycle_scripts, + system_info, } } } diff --git a/cli/npm/managed/installers/local.rs b/cli/npm/installer/local.rs similarity index 99% rename from cli/npm/managed/installers/local.rs rename to cli/npm/installer/local.rs index a8efaaeb00..87288c6c8e 100644 --- a/cli/npm/managed/installers/local.rs +++ b/cli/npm/installer/local.rs @@ -25,7 +25,7 @@ use deno_npm::NpmResolutionPackage; use deno_npm::NpmSystemInfo; use deno_path_util::fs::atomic_write_file_with_retries; use deno_resolver::npm::get_package_folder_id_folder_name; -use deno_resolver::npm::managed::NpmResolution; +use deno_resolver::npm::managed::NpmResolutionCell; use deno_semver::package::PackageNv; use deno_semver::StackString; use serde::Deserialize; @@ -33,11 +33,11 @@ use serde::Serialize; use super::common::bin_entries; use super::common::NpmPackageFsInstaller; +use super::PackageCaching; use crate::args::LifecycleScriptsConfig; use crate::args::NpmInstallDepsProvider; use crate::cache::CACHE_PERM; use crate::colors; -use crate::npm::managed::PackageCaching; use crate::npm::CliNpmCache; use crate::npm::CliNpmTarballCache; use crate::sys::CliSys; @@ -54,12 +54,12 @@ pub struct LocalNpmPackageInstaller { cache: Arc, npm_install_deps_provider: Arc, progress_bar: ProgressBar, - resolution: Arc, + resolution: Arc, sys: CliSys, tarball_cache: Arc, + lifecycle_scripts: LifecycleScriptsConfig, root_node_modules_path: PathBuf, system_info: NpmSystemInfo, - lifecycle_scripts: LifecycleScriptsConfig, } impl LocalNpmPackageInstaller { @@ -68,12 +68,12 @@ impl LocalNpmPackageInstaller { cache: Arc, npm_install_deps_provider: Arc, progress_bar: ProgressBar, - resolution: Arc, + resolution: Arc, sys: CliSys, tarball_cache: Arc, node_modules_folder: PathBuf, - system_info: NpmSystemInfo, lifecycle_scripts: LifecycleScriptsConfig, + system_info: NpmSystemInfo, ) -> Self { Self { cache, @@ -82,9 +82,9 @@ impl LocalNpmPackageInstaller { resolution, tarball_cache, sys, + lifecycle_scripts, root_node_modules_path: node_modules_folder, system_info, - lifecycle_scripts, } } } diff --git a/cli/npm/installer/mod.rs b/cli/npm/installer/mod.rs new file mode 100644 index 0000000000..58b9cb1bc7 --- /dev/null +++ b/cli/npm/installer/mod.rs @@ -0,0 +1,283 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +use std::borrow::Cow; +use std::path::PathBuf; +use std::sync::Arc; + +use deno_core::error::AnyError; +use deno_core::unsync::sync::AtomicFlag; +use deno_error::JsErrorBox; +use deno_npm::registry::NpmPackageInfo; +use deno_npm::registry::NpmRegistryPackageInfoLoadError; +use deno_npm::NpmSystemInfo; +use deno_resolver::npm::managed::NpmResolutionCell; +use deno_runtime::colors; +use deno_semver::package::PackageReq; + +pub use self::common::NpmPackageFsInstaller; +use self::global::GlobalNpmPackageInstaller; +use self::local::LocalNpmPackageInstaller; +pub use self::resolution::AddPkgReqsResult; +pub use self::resolution::NpmResolutionInstaller; +use super::NpmResolutionInitializer; +use crate::args::CliLockfile; +use crate::args::LifecycleScriptsConfig; +use crate::args::NpmInstallDepsProvider; +use crate::args::PackageJsonDepValueParseWithLocationError; +use crate::npm::CliNpmCache; +use crate::npm::CliNpmTarballCache; +use crate::sys::CliSys; +use crate::util::progress_bar::ProgressBar; + +mod common; +mod global; +mod local; +mod resolution; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum PackageCaching<'a> { + Only(Cow<'a, [PackageReq]>), + All, +} + +#[derive(Debug)] +pub struct NpmInstaller { + fs_installer: Arc, + npm_install_deps_provider: Arc, + npm_resolution_initializer: Arc, + npm_resolution_installer: Arc, + maybe_lockfile: Option>, + npm_resolution: Arc, + top_level_install_flag: AtomicFlag, +} + +impl NpmInstaller { + #[allow(clippy::too_many_arguments)] + pub fn new( + npm_cache: Arc, + npm_install_deps_provider: Arc, + npm_resolution: Arc, + npm_resolution_initializer: Arc, + npm_resolution_installer: Arc, + progress_bar: &ProgressBar, + sys: CliSys, + tarball_cache: Arc, + maybe_lockfile: Option>, + maybe_node_modules_path: Option, + lifecycle_scripts: LifecycleScriptsConfig, + system_info: NpmSystemInfo, + ) -> Self { + let fs_installer: Arc = + match maybe_node_modules_path { + Some(node_modules_folder) => Arc::new(LocalNpmPackageInstaller::new( + npm_cache, + npm_install_deps_provider.clone(), + progress_bar.clone(), + npm_resolution.clone(), + sys, + tarball_cache, + node_modules_folder, + lifecycle_scripts, + system_info, + )), + None => Arc::new(GlobalNpmPackageInstaller::new( + npm_cache, + tarball_cache, + npm_resolution.clone(), + lifecycle_scripts, + system_info, + )), + }; + Self { + fs_installer, + npm_install_deps_provider, + npm_resolution, + npm_resolution_initializer, + npm_resolution_installer, + maybe_lockfile, + top_level_install_flag: Default::default(), + } + } + + /// Adds package requirements to the resolver and ensures everything is setup. + /// This includes setting up the `node_modules` directory, if applicable. + pub async fn add_and_cache_package_reqs( + &self, + packages: &[PackageReq], + ) -> Result<(), JsErrorBox> { + self.npm_resolution_initializer.ensure_initialized().await?; + self + .add_package_reqs_raw( + packages, + Some(PackageCaching::Only(packages.into())), + ) + .await + .dependencies_result + } + + pub async fn add_package_reqs_no_cache( + &self, + packages: &[PackageReq], + ) -> Result<(), JsErrorBox> { + self.npm_resolution_initializer.ensure_initialized().await?; + self + .add_package_reqs_raw(packages, None) + .await + .dependencies_result + } + + pub async fn add_package_reqs( + &self, + packages: &[PackageReq], + caching: PackageCaching<'_>, + ) -> Result<(), JsErrorBox> { + self + .add_package_reqs_raw(packages, Some(caching)) + .await + .dependencies_result + } + + pub async fn add_package_reqs_raw<'a>( + &self, + packages: &[PackageReq], + caching: Option>, + ) -> AddPkgReqsResult { + if packages.is_empty() { + return AddPkgReqsResult { + dependencies_result: Ok(()), + results: vec![], + }; + } + + #[cfg(debug_assertions)] + self.npm_resolution_initializer.debug_assert_initialized(); + + let mut result = self + .npm_resolution_installer + .add_package_reqs(packages) + .await; + + if result.dependencies_result.is_ok() { + if let Some(lockfile) = self.maybe_lockfile.as_ref() { + result.dependencies_result = lockfile.error_if_changed(); + } + } + if result.dependencies_result.is_ok() { + if let Some(caching) = caching { + result.dependencies_result = self.cache_packages(caching).await; + } + } + + result + } + + /// Sets package requirements to the resolver, removing old requirements and adding new ones. + /// + /// This will retrieve and resolve package information, but not cache any package files. + pub async fn set_package_reqs( + &self, + packages: &[PackageReq], + ) -> Result<(), AnyError> { + self + .npm_resolution_installer + .set_package_reqs(packages) + .await + } + + pub async fn inject_synthetic_types_node_package( + &self, + ) -> Result<(), JsErrorBox> { + self.npm_resolution_initializer.ensure_initialized().await?; + let reqs = &[PackageReq::from_str("@types/node").unwrap()]; + // add and ensure this isn't added to the lockfile + self + .add_package_reqs(reqs, PackageCaching::Only(reqs.into())) + .await?; + + Ok(()) + } + + pub async fn cache_package_info( + &self, + package_name: &str, + ) -> Result, NpmRegistryPackageInfoLoadError> { + self + .npm_resolution_installer + .cache_package_info(package_name) + .await + } + + pub async fn cache_packages( + &self, + caching: PackageCaching<'_>, + ) -> Result<(), JsErrorBox> { + self.npm_resolution_initializer.ensure_initialized().await?; + self.fs_installer.cache_packages(caching).await + } + + pub fn ensure_no_pkg_json_dep_errors( + &self, + ) -> Result<(), Box> { + for err in self.npm_install_deps_provider.pkg_json_dep_errors() { + match err.source.as_kind() { + deno_package_json::PackageJsonDepValueParseErrorKind::VersionReq(_) => { + return Err(Box::new(err.clone())); + } + deno_package_json::PackageJsonDepValueParseErrorKind::Unsupported { + .. + } => { + // only warn for this one + log::warn!( + "{} {}\n at {}", + colors::yellow("Warning"), + err.source, + err.location, + ) + } + } + } + Ok(()) + } + + /// Ensures that the top level `package.json` dependencies are installed. + /// This may set up the `node_modules` directory. + /// + /// Returns `true` if the top level packages are already installed. A + /// return value of `false` means that new packages were added to the NPM resolution. + pub async fn ensure_top_level_package_json_install( + &self, + ) -> Result { + if !self.top_level_install_flag.raise() { + return Ok(true); // already did this + } + + self.npm_resolution_initializer.ensure_initialized().await?; + + let pkg_json_remote_pkgs = self.npm_install_deps_provider.remote_pkgs(); + if pkg_json_remote_pkgs.is_empty() { + return Ok(true); + } + + // check if something needs resolving before bothering to load all + // the package information (which is slow) + if pkg_json_remote_pkgs.iter().all(|pkg| { + self + .npm_resolution + .resolve_pkg_id_from_pkg_req(&pkg.req) + .is_ok() + }) { + log::debug!( + "All package.json deps resolvable. Skipping top level install." + ); + return Ok(true); // everything is already resolvable + } + + let pkg_reqs = pkg_json_remote_pkgs + .iter() + .map(|pkg| pkg.req.clone()) + .collect::>(); + self.add_package_reqs_no_cache(&pkg_reqs).await?; + + Ok(false) + } +} diff --git a/cli/npm/managed/installer.rs b/cli/npm/installer/resolution.rs similarity index 92% rename from cli/npm/managed/installer.rs rename to cli/npm/installer/resolution.rs index 9f1cc05968..06bbcd4f76 100644 --- a/cli/npm/managed/installer.rs +++ b/cli/npm/installer/resolution.rs @@ -8,12 +8,14 @@ use deno_core::error::AnyError; use deno_error::JsErrorBox; use deno_lockfile::NpmPackageDependencyLockfileInfo; use deno_lockfile::NpmPackageLockfileInfo; +use deno_npm::registry::NpmPackageInfo; use deno_npm::registry::NpmRegistryApi; +use deno_npm::registry::NpmRegistryPackageInfoLoadError; use deno_npm::resolution::AddPkgReqsOptions; use deno_npm::resolution::NpmResolutionError; use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::NpmResolutionPackage; -use deno_resolver::npm::managed::NpmResolution; +use deno_resolver::npm::managed::NpmResolutionCell; use deno_semver::jsr::JsrDepPackageReq; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; @@ -35,9 +37,10 @@ pub struct AddPkgReqsResult { } /// Updates the npm resolution with the provided package requirements. +#[derive(Debug)] pub struct NpmResolutionInstaller { registry_info_provider: Arc, - resolution: Arc, + resolution: Arc, maybe_lockfile: Option>, update_queue: TaskQueue, } @@ -45,7 +48,7 @@ pub struct NpmResolutionInstaller { impl NpmResolutionInstaller { pub fn new( registry_info_provider: Arc, - resolution: Arc, + resolution: Arc, maybe_lockfile: Option>, ) -> Self { Self { @@ -56,6 +59,14 @@ impl NpmResolutionInstaller { } } + pub async fn cache_package_info( + &self, + package_name: &str, + ) -> Result, NpmRegistryPackageInfoLoadError> { + // this will internally cache the package information + self.registry_info_provider.package_info(package_name).await + } + pub async fn add_package_reqs( &self, package_reqs: &[PackageReq], diff --git a/cli/npm/managed.rs b/cli/npm/managed.rs new file mode 100644 index 0000000000..0d4c209acc --- /dev/null +++ b/cli/npm/managed.rs @@ -0,0 +1,496 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; + +use deno_ast::ModuleSpecifier; +use deno_cache_dir::npm::NpmCacheDir; +use deno_core::parking_lot::Mutex; +use deno_core::serde_json; +use deno_core::url::Url; +use deno_error::JsError; +use deno_error::JsErrorBox; +use deno_npm::npm_rc::ResolvedNpmRc; +use deno_npm::registry::NpmRegistryApi; +use deno_npm::resolution::NpmResolutionSnapshot; +use deno_npm::resolution::PackageReqNotFoundError; +use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; +use deno_npm::NpmPackageId; +use deno_npm::NpmResolutionPackage; +use deno_npm::NpmSystemInfo; +use deno_resolver::npm::managed::NpmResolutionCell; +use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError; +use deno_resolver::npm::managed::ResolvePkgFolderFromPkgIdError; +use deno_resolver::npm::managed::ResolvePkgIdFromSpecifierError; +use deno_resolver::npm::ByonmOrManagedNpmResolver; +use deno_resolver::npm::ManagedNpmResolver; +use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; +use deno_runtime::ops::process::NpmProcessStateProvider; +use deno_semver::package::PackageNv; +use deno_semver::package::PackageReq; +use node_resolver::NpmPackageFolderResolver; +use sys_traits::FsMetadata; +use thiserror::Error; + +use super::CliNpmRegistryInfoProvider; +use super::CliNpmResolver; +use super::InnerCliNpmResolverRef; +use crate::args::CliLockfile; +use crate::args::NpmProcessState; +use crate::args::NpmProcessStateKind; +use crate::cache::FastInsecureHasher; +use crate::sys::CliSys; + +#[derive(Debug, Clone)] +pub enum CliNpmResolverManagedSnapshotOption { + ResolveFromLockfile(Arc), + Specified(Option), +} + +#[derive(Debug)] +enum SyncState { + Pending(Option), + Err(ResolveSnapshotError), + Success, +} + +#[derive(Debug)] +pub struct NpmResolutionInitializer { + npm_registry_info_provider: Arc, + npm_resolution: Arc, + queue: tokio::sync::Mutex<()>, + sync_state: Mutex, +} + +impl NpmResolutionInitializer { + pub fn new( + npm_registry_info_provider: Arc, + npm_resolution: Arc, + snapshot_option: CliNpmResolverManagedSnapshotOption, + ) -> Self { + Self { + npm_registry_info_provider, + npm_resolution, + queue: tokio::sync::Mutex::new(()), + sync_state: Mutex::new(SyncState::Pending(Some(snapshot_option))), + } + } + + #[cfg(debug_assertions)] + pub fn debug_assert_initialized(&self) { + if !matches!(*self.sync_state.lock(), SyncState::Success) { + panic!("debug assert: npm resolution must be initialized before calling this code"); + } + } + + pub async fn ensure_initialized(&self) -> Result<(), JsErrorBox> { + // fast exit if not pending + { + match &*self.sync_state.lock() { + SyncState::Pending(_) => {} + SyncState::Err(err) => return Err(JsErrorBox::from_err(err.clone())), + SyncState::Success => return Ok(()), + } + } + + // only allow one task in here at a time + let _guard = self.queue.lock().await; + + let snapshot_option = { + let mut sync_state = self.sync_state.lock(); + match &mut *sync_state { + SyncState::Pending(snapshot_option) => { + // this should never panic, but if it does it means that a + // previous future was dropped while initialization occurred... + // that should never happen because this is initialized during + // startup + snapshot_option.take().unwrap() + } + // another thread updated the state while we were waiting + SyncState::Err(resolve_snapshot_error) => { + return Err(JsErrorBox::from_err(resolve_snapshot_error.clone())); + } + SyncState::Success => { + return Ok(()); + } + } + }; + + match resolve_snapshot(&self.npm_registry_info_provider, snapshot_option) + .await + { + Ok(maybe_snapshot) => { + if let Some(snapshot) = maybe_snapshot { + self + .npm_resolution + .set_snapshot(NpmResolutionSnapshot::new(snapshot)); + } + let mut sync_state = self.sync_state.lock(); + *sync_state = SyncState::Success; + Ok(()) + } + Err(err) => { + let mut sync_state = self.sync_state.lock(); + *sync_state = SyncState::Err(err.clone()); + Err(JsErrorBox::from_err(err)) + } + } + } +} + +pub struct CliManagedNpmResolverCreateOptions { + pub npm_cache_dir: Arc, + pub sys: CliSys, + pub maybe_node_modules_path: Option, + pub npm_system_info: NpmSystemInfo, + pub npmrc: Arc, + pub npm_resolution: Arc, +} + +pub fn create_managed_npm_resolver( + options: CliManagedNpmResolverCreateOptions, +) -> Arc { + let managed_npm_resolver = + Arc::new(ManagedNpmResolver::::new::( + &options.npm_cache_dir, + &options.npmrc, + options.npm_resolution.clone(), + options.sys.clone(), + options.maybe_node_modules_path, + )); + Arc::new(ManagedCliNpmResolver::new( + managed_npm_resolver, + options.npm_cache_dir, + options.npmrc, + options.npm_resolution, + options.sys, + options.npm_system_info, + )) +} + +#[derive(Debug, Error, Clone, JsError)] +#[error("failed reading lockfile '{}'", lockfile_path.display())] +#[class(inherit)] +pub struct ResolveSnapshotError { + lockfile_path: PathBuf, + #[inherit] + #[source] + source: SnapshotFromLockfileError, +} + +impl ResolveSnapshotError { + pub fn maybe_integrity_check_error( + &self, + ) -> Option<&deno_npm::resolution::IntegrityCheckFailedError> { + match &self.source { + SnapshotFromLockfileError::SnapshotFromLockfile( + deno_npm::resolution::SnapshotFromLockfileError::IntegrityCheckFailed( + err, + ), + ) => Some(err), + _ => None, + } + } +} + +async fn resolve_snapshot( + registry_info_provider: &Arc, + snapshot: CliNpmResolverManagedSnapshotOption, +) -> Result, ResolveSnapshotError> +{ + match snapshot { + CliNpmResolverManagedSnapshotOption::ResolveFromLockfile(lockfile) => { + if !lockfile.overwrite() { + let snapshot = snapshot_from_lockfile( + lockfile.clone(), + ®istry_info_provider.as_npm_registry_api(), + ) + .await + .map_err(|source| ResolveSnapshotError { + lockfile_path: lockfile.filename.clone(), + source, + })?; + Ok(Some(snapshot)) + } else { + Ok(None) + } + } + CliNpmResolverManagedSnapshotOption::Specified(snapshot) => Ok(snapshot), + } +} + +#[derive(Debug, Error, Clone, JsError)] +pub enum SnapshotFromLockfileError { + #[error(transparent)] + #[class(inherit)] + IncompleteError( + #[from] deno_npm::resolution::IncompleteSnapshotFromLockfileError, + ), + #[error(transparent)] + #[class(inherit)] + SnapshotFromLockfile(#[from] deno_npm::resolution::SnapshotFromLockfileError), +} + +async fn snapshot_from_lockfile( + lockfile: Arc, + api: &dyn NpmRegistryApi, +) -> Result { + let (incomplete_snapshot, skip_integrity_check) = { + let lock = lockfile.lock(); + ( + deno_npm::resolution::incomplete_snapshot_from_lockfile(&lock)?, + lock.overwrite, + ) + }; + let snapshot = deno_npm::resolution::snapshot_from_lockfile( + deno_npm::resolution::SnapshotFromLockfileParams { + incomplete_snapshot, + api, + skip_integrity_check, + }, + ) + .await?; + Ok(snapshot) +} + +/// An npm resolver where the resolution is managed by Deno rather than +/// the user bringing their own node_modules (BYONM) on the file system. +pub struct ManagedCliNpmResolver { + managed_npm_resolver: Arc>, + npm_cache_dir: Arc, + npm_rc: Arc, + sys: CliSys, + resolution: Arc, + system_info: NpmSystemInfo, +} + +impl std::fmt::Debug for ManagedCliNpmResolver { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ManagedCliNpmResolver") + .field("", &"") + .finish() + } +} + +impl ManagedCliNpmResolver { + #[allow(clippy::too_many_arguments)] + pub fn new( + managed_npm_resolver: Arc>, + npm_cache_dir: Arc, + npm_rc: Arc, + resolution: Arc, + sys: CliSys, + system_info: NpmSystemInfo, + ) -> Self { + Self { + managed_npm_resolver, + npm_cache_dir, + npm_rc, + resolution, + sys, + system_info, + } + } + + pub fn resolve_pkg_folder_from_pkg_id( + &self, + pkg_id: &NpmPackageId, + ) -> Result { + self + .managed_npm_resolver + .resolve_pkg_folder_from_pkg_id(pkg_id) + } + + /// Resolves the package id from the provided specifier. + pub fn resolve_pkg_id_from_specifier( + &self, + specifier: &ModuleSpecifier, + ) -> Result, ResolvePkgIdFromSpecifierError> { + self + .managed_npm_resolver + .resolve_pkg_id_from_specifier(specifier) + } + + pub fn resolve_pkg_reqs_from_pkg_id( + &self, + id: &NpmPackageId, + ) -> Vec { + self.resolution.resolve_pkg_reqs_from_pkg_id(id) + } + + pub fn all_system_packages( + &self, + system_info: &NpmSystemInfo, + ) -> Vec { + self.resolution.all_system_packages(system_info) + } + + /// Checks if the provided package req's folder is cached. + pub fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool { + self + .resolve_pkg_id_from_pkg_req(req) + .ok() + .and_then(|id| { + self + .managed_npm_resolver + .resolve_pkg_folder_from_pkg_id(&id) + .ok() + }) + .map(|folder| self.sys.fs_exists_no_err(folder)) + .unwrap_or(false) + } + + pub fn snapshot(&self) -> NpmResolutionSnapshot { + self.resolution.snapshot() + } + + pub fn top_package_req_for_name(&self, name: &str) -> Option { + let package_reqs = self.resolution.package_reqs(); + let mut entries = package_reqs + .iter() + .filter(|(_, nv)| nv.name == name) + .collect::>(); + entries.sort_by_key(|(_, nv)| &nv.version); + Some(entries.last()?.0.clone()) + } + + pub fn serialized_valid_snapshot_for_system( + &self, + system_info: &NpmSystemInfo, + ) -> ValidSerializedNpmResolutionSnapshot { + self + .resolution + .serialized_valid_snapshot_for_system(system_info) + } + + pub fn resolve_pkg_folder_from_deno_module( + &self, + nv: &PackageNv, + ) -> Result { + self + .managed_npm_resolver + .resolve_pkg_folder_from_deno_module(nv) + } + + pub fn resolve_pkg_id_from_pkg_req( + &self, + req: &PackageReq, + ) -> Result { + self.resolution.resolve_pkg_id_from_pkg_req(req) + } + + pub fn maybe_node_modules_path(&self) -> Option<&Path> { + self.managed_npm_resolver.node_modules_path() + } + + pub fn global_cache_root_path(&self) -> &Path { + self.npm_cache_dir.root_dir() + } + + pub fn global_cache_root_url(&self) -> &Url { + self.npm_cache_dir.root_dir_url() + } +} + +pub fn npm_process_state( + snapshot: ValidSerializedNpmResolutionSnapshot, + node_modules_path: Option<&Path>, +) -> String { + serde_json::to_string(&NpmProcessState { + kind: NpmProcessStateKind::Snapshot(snapshot.into_serialized()), + local_node_modules_path: node_modules_path + .map(|p| p.to_string_lossy().to_string()), + }) + .unwrap() +} + +impl NpmProcessStateProvider for ManagedCliNpmResolver { + fn get_npm_process_state(&self) -> String { + npm_process_state( + self.resolution.serialized_valid_snapshot(), + self.managed_npm_resolver.node_modules_path(), + ) + } +} + +impl CliNpmResolver for ManagedCliNpmResolver { + fn into_npm_pkg_folder_resolver( + self: Arc, + ) -> Arc { + self.managed_npm_resolver.clone() + } + + fn into_process_state_provider( + self: Arc, + ) -> Arc { + self + } + + fn into_byonm_or_managed( + self: Arc, + ) -> ByonmOrManagedNpmResolver { + ByonmOrManagedNpmResolver::Managed(self.managed_npm_resolver.clone()) + } + + fn clone_snapshotted(&self) -> Arc { + // create a new snapshotted npm resolution and resolver + let npm_resolution = + Arc::new(NpmResolutionCell::new(self.resolution.snapshot())); + + Arc::new(ManagedCliNpmResolver::new( + Arc::new(ManagedNpmResolver::::new::( + &self.npm_cache_dir, + &self.npm_rc, + npm_resolution.clone(), + self.sys.clone(), + self.root_node_modules_path().map(ToOwned::to_owned), + )), + self.npm_cache_dir.clone(), + self.npm_rc.clone(), + npm_resolution, + self.sys.clone(), + self.system_info.clone(), + )) + } + + fn as_inner(&self) -> InnerCliNpmResolverRef { + InnerCliNpmResolverRef::Managed(self) + } + + fn root_node_modules_path(&self) -> Option<&Path> { + self.managed_npm_resolver.node_modules_path() + } + + fn check_state_hash(&self) -> Option { + // We could go further and check all the individual + // npm packages, but that's probably overkill. + let mut package_reqs = self + .resolution + .package_reqs() + .into_iter() + .collect::>(); + package_reqs.sort_by(|a, b| a.0.cmp(&b.0)); // determinism + let mut hasher = FastInsecureHasher::new_without_deno_version(); + // ensure the cache gets busted when turning nodeModulesDir on or off + // as this could cause changes in resolution + hasher + .write_hashable(self.managed_npm_resolver.node_modules_path().is_some()); + for (pkg_req, pkg_nv) in package_reqs { + hasher.write_hashable(&pkg_req); + hasher.write_hashable(&pkg_nv); + } + Some(hasher.finish()) + } + + fn resolve_pkg_folder_from_deno_module_req( + &self, + req: &PackageReq, + referrer: &Url, + ) -> Result { + self + .managed_npm_resolver + .resolve_pkg_folder_from_deno_module_req(req, referrer) + .map_err(ResolvePkgFolderFromDenoReqError::Managed) + } +} diff --git a/cli/npm/managed/installers/mod.rs b/cli/npm/managed/installers/mod.rs deleted file mode 100644 index 39e0d6f77c..0000000000 --- a/cli/npm/managed/installers/mod.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2018-2025 the Deno authors. MIT license. - -use std::path::PathBuf; -use std::sync::Arc; - -use deno_npm::NpmSystemInfo; -use deno_resolver::npm::managed::NpmResolution; - -pub use self::common::NpmPackageFsInstaller; -use self::global::GlobalNpmPackageInstaller; -use self::local::LocalNpmPackageInstaller; -use crate::args::LifecycleScriptsConfig; -use crate::args::NpmInstallDepsProvider; -use crate::npm::CliNpmCache; -use crate::npm::CliNpmTarballCache; -use crate::sys::CliSys; -use crate::util::progress_bar::ProgressBar; - -mod common; -mod global; -mod local; - -#[allow(clippy::too_many_arguments)] -pub fn create_npm_fs_installer( - npm_cache: Arc, - npm_install_deps_provider: &Arc, - progress_bar: &ProgressBar, - resolution: Arc, - sys: CliSys, - tarball_cache: Arc, - maybe_node_modules_path: Option, - system_info: NpmSystemInfo, - lifecycle_scripts: LifecycleScriptsConfig, -) -> Arc { - match maybe_node_modules_path { - Some(node_modules_folder) => Arc::new(LocalNpmPackageInstaller::new( - npm_cache, - npm_install_deps_provider.clone(), - progress_bar.clone(), - resolution, - sys, - tarball_cache, - node_modules_folder, - system_info, - lifecycle_scripts, - )), - None => Arc::new(GlobalNpmPackageInstaller::new( - npm_cache, - tarball_cache, - resolution, - system_info, - lifecycle_scripts, - )), - } -} diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs deleted file mode 100644 index 8d2ede7e67..0000000000 --- a/cli/npm/managed/mod.rs +++ /dev/null @@ -1,768 +0,0 @@ -// Copyright 2018-2025 the Deno authors. MIT license. - -use std::borrow::Cow; -use std::path::Path; -use std::path::PathBuf; -use std::sync::Arc; - -use deno_ast::ModuleSpecifier; -use deno_cache_dir::npm::NpmCacheDir; -use deno_core::anyhow::Context; -use deno_core::error::AnyError; -use deno_core::serde_json; -use deno_core::url::Url; -use deno_error::JsErrorBox; -use deno_npm::npm_rc::ResolvedNpmRc; -use deno_npm::registry::NpmPackageInfo; -use deno_npm::registry::NpmRegistryApi; -use deno_npm::resolution::NpmResolutionSnapshot; -use deno_npm::resolution::PackageReqNotFoundError; -use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; -use deno_npm::NpmPackageId; -use deno_npm::NpmResolutionPackage; -use deno_npm::NpmSystemInfo; -use deno_npm_cache::NpmCacheSetting; -use deno_resolver::npm::managed::NpmResolution; -use deno_resolver::npm::managed::ResolvePkgFolderFromPkgIdError; -use deno_resolver::npm::ByonmOrManagedNpmResolver; -use deno_resolver::npm::ManagedNpmResolver; -use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; -use deno_runtime::colors; -use deno_runtime::ops::process::NpmProcessStateProvider; -use deno_semver::package::PackageNv; -use deno_semver::package::PackageReq; -use installer::AddPkgReqsResult; -use installer::NpmResolutionInstaller; -use installers::create_npm_fs_installer; -use installers::NpmPackageFsInstaller; -use node_resolver::NpmPackageFolderResolver; - -use super::CliNpmCache; -use super::CliNpmCacheHttpClient; -use super::CliNpmRegistryInfoProvider; -use super::CliNpmResolver; -use super::CliNpmTarballCache; -use super::InnerCliNpmResolverRef; -use crate::args::CliLockfile; -use crate::args::LifecycleScriptsConfig; -use crate::args::NpmInstallDepsProvider; -use crate::args::NpmProcessState; -use crate::args::NpmProcessStateKind; -use crate::args::PackageJsonDepValueParseWithLocationError; -use crate::cache::FastInsecureHasher; -use crate::sys::CliSys; -use crate::util::progress_bar::ProgressBar; -use crate::util::sync::AtomicFlag; - -mod installer; -mod installers; - -pub enum CliNpmResolverManagedSnapshotOption { - ResolveFromLockfile(Arc), - Specified(Option), -} - -pub struct CliManagedNpmResolverCreateOptions { - pub snapshot: CliNpmResolverManagedSnapshotOption, - pub maybe_lockfile: Option>, - pub http_client_provider: Arc, - pub npm_cache_dir: Arc, - pub sys: CliSys, - pub cache_setting: deno_cache_dir::file_fetcher::CacheSetting, - pub text_only_progress_bar: crate::util::progress_bar::ProgressBar, - pub maybe_node_modules_path: Option, - pub npm_system_info: NpmSystemInfo, - pub npm_install_deps_provider: Arc, - pub npmrc: Arc, - pub lifecycle_scripts: LifecycleScriptsConfig, -} - -pub async fn create_managed_npm_resolver_for_lsp( - options: CliManagedNpmResolverCreateOptions, -) -> Arc { - let npm_cache = create_cache(&options); - let http_client = Arc::new(CliNpmCacheHttpClient::new( - options.http_client_provider.clone(), - options.text_only_progress_bar.clone(), - )); - let npm_api = create_api(npm_cache.clone(), http_client.clone(), &options); - // spawn due to the lsp's `Send` requirement - deno_core::unsync::spawn(async move { - let snapshot = match resolve_snapshot(&npm_api, options.snapshot).await { - Ok(snapshot) => snapshot, - Err(err) => { - log::warn!("failed to resolve snapshot: {}", err); - None - } - }; - create_inner( - http_client, - npm_cache, - options.npm_cache_dir, - options.npm_install_deps_provider, - npm_api, - options.sys, - options.text_only_progress_bar, - options.maybe_lockfile, - options.npmrc, - options.maybe_node_modules_path, - options.npm_system_info, - snapshot, - options.lifecycle_scripts, - ) - }) - .await - .unwrap() -} - -pub async fn create_managed_npm_resolver( - options: CliManagedNpmResolverCreateOptions, -) -> Result, AnyError> { - let npm_cache = create_cache(&options); - let http_client = Arc::new(CliNpmCacheHttpClient::new( - options.http_client_provider.clone(), - options.text_only_progress_bar.clone(), - )); - let api = create_api(npm_cache.clone(), http_client.clone(), &options); - let snapshot = resolve_snapshot(&api, options.snapshot).await?; - Ok(create_inner( - http_client, - npm_cache, - options.npm_cache_dir, - options.npm_install_deps_provider, - api, - options.sys, - options.text_only_progress_bar, - options.maybe_lockfile, - options.npmrc, - options.maybe_node_modules_path, - options.npm_system_info, - snapshot, - options.lifecycle_scripts, - )) -} - -#[allow(clippy::too_many_arguments)] -fn create_inner( - http_client: Arc, - npm_cache: Arc, - npm_cache_dir: Arc, - npm_install_deps_provider: Arc, - registry_info_provider: Arc, - sys: CliSys, - text_only_progress_bar: crate::util::progress_bar::ProgressBar, - maybe_lockfile: Option>, - npm_rc: Arc, - node_modules_dir_path: Option, - npm_system_info: NpmSystemInfo, - snapshot: Option, - lifecycle_scripts: LifecycleScriptsConfig, -) -> Arc { - let resolution = Arc::new(NpmResolution::from_serialized(snapshot)); - let tarball_cache = Arc::new(CliNpmTarballCache::new( - npm_cache.clone(), - http_client, - sys.clone(), - npm_rc.clone(), - )); - - let fs_installer = create_npm_fs_installer( - npm_cache.clone(), - &npm_install_deps_provider, - &text_only_progress_bar, - resolution.clone(), - sys.clone(), - tarball_cache.clone(), - node_modules_dir_path.clone(), - npm_system_info.clone(), - lifecycle_scripts.clone(), - ); - let managed_npm_resolver = - Arc::new(ManagedNpmResolver::::new::( - &npm_cache_dir, - &npm_rc, - resolution.clone(), - sys.clone(), - node_modules_dir_path, - )); - Arc::new(ManagedCliNpmResolver::new( - fs_installer, - maybe_lockfile, - managed_npm_resolver, - npm_cache, - npm_cache_dir, - npm_install_deps_provider, - npm_rc, - registry_info_provider, - resolution, - sys, - tarball_cache, - text_only_progress_bar, - npm_system_info, - lifecycle_scripts, - )) -} - -fn create_cache( - options: &CliManagedNpmResolverCreateOptions, -) -> Arc { - Arc::new(CliNpmCache::new( - options.npm_cache_dir.clone(), - options.sys.clone(), - NpmCacheSetting::from_cache_setting(&options.cache_setting), - options.npmrc.clone(), - )) -} - -fn create_api( - cache: Arc, - http_client: Arc, - options: &CliManagedNpmResolverCreateOptions, -) -> Arc { - Arc::new(CliNpmRegistryInfoProvider::new( - cache, - http_client, - options.npmrc.clone(), - )) -} - -async fn resolve_snapshot( - registry_info_provider: &Arc, - snapshot: CliNpmResolverManagedSnapshotOption, -) -> Result, AnyError> { - match snapshot { - CliNpmResolverManagedSnapshotOption::ResolveFromLockfile(lockfile) => { - if !lockfile.overwrite() { - let snapshot = snapshot_from_lockfile( - lockfile.clone(), - ®istry_info_provider.as_npm_registry_api(), - ) - .await - .with_context(|| { - format!("failed reading lockfile '{}'", lockfile.filename.display()) - })?; - Ok(Some(snapshot)) - } else { - Ok(None) - } - } - CliNpmResolverManagedSnapshotOption::Specified(snapshot) => Ok(snapshot), - } -} - -async fn snapshot_from_lockfile( - lockfile: Arc, - api: &dyn NpmRegistryApi, -) -> Result { - let (incomplete_snapshot, skip_integrity_check) = { - let lock = lockfile.lock(); - ( - deno_npm::resolution::incomplete_snapshot_from_lockfile(&lock)?, - lock.overwrite, - ) - }; - let snapshot = deno_npm::resolution::snapshot_from_lockfile( - deno_npm::resolution::SnapshotFromLockfileParams { - incomplete_snapshot, - api, - skip_integrity_check, - }, - ) - .await?; - Ok(snapshot) -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum PackageCaching<'a> { - Only(Cow<'a, [PackageReq]>), - All, -} - -#[derive(Debug, thiserror::Error, deno_error::JsError)] -pub enum ResolvePkgFolderFromDenoModuleError { - #[class(inherit)] - #[error(transparent)] - PackageNvNotFound(#[from] deno_npm::resolution::PackageNvNotFoundError), - #[class(inherit)] - #[error(transparent)] - ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError), -} - -/// An npm resolver where the resolution is managed by Deno rather than -/// the user bringing their own node_modules (BYONM) on the file system. -pub struct ManagedCliNpmResolver { - fs_installer: Arc, - maybe_lockfile: Option>, - registry_info_provider: Arc, - managed_npm_resolver: Arc>, - npm_cache: Arc, - npm_cache_dir: Arc, - npm_install_deps_provider: Arc, - npm_rc: Arc, - sys: CliSys, - resolution: Arc, - resolution_installer: NpmResolutionInstaller, - tarball_cache: Arc, - text_only_progress_bar: ProgressBar, - npm_system_info: NpmSystemInfo, - top_level_install_flag: AtomicFlag, - lifecycle_scripts: LifecycleScriptsConfig, -} - -impl std::fmt::Debug for ManagedCliNpmResolver { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ManagedCliNpmResolver") - .field("", &"") - .finish() - } -} - -impl ManagedCliNpmResolver { - #[allow(clippy::too_many_arguments)] - pub fn new( - fs_installer: Arc, - maybe_lockfile: Option>, - managed_npm_resolver: Arc>, - npm_cache: Arc, - npm_cache_dir: Arc, - npm_install_deps_provider: Arc, - npm_rc: Arc, - registry_info_provider: Arc, - resolution: Arc, - sys: CliSys, - tarball_cache: Arc, - text_only_progress_bar: ProgressBar, - npm_system_info: NpmSystemInfo, - lifecycle_scripts: LifecycleScriptsConfig, - ) -> Self { - let resolution_installer = NpmResolutionInstaller::new( - registry_info_provider.clone(), - resolution.clone(), - maybe_lockfile.clone(), - ); - Self { - fs_installer, - maybe_lockfile, - managed_npm_resolver, - npm_cache, - npm_cache_dir, - npm_install_deps_provider, - npm_rc, - registry_info_provider, - text_only_progress_bar, - resolution, - resolution_installer, - sys, - tarball_cache, - npm_system_info, - top_level_install_flag: Default::default(), - lifecycle_scripts, - } - } - - pub fn resolve_pkg_folder_from_pkg_id( - &self, - pkg_id: &NpmPackageId, - ) -> Result { - self - .managed_npm_resolver - .resolve_pkg_folder_from_pkg_id(pkg_id) - } - - /// Resolves the package id from the provided specifier. - pub fn resolve_pkg_id_from_specifier( - &self, - specifier: &ModuleSpecifier, - ) -> Result, AnyError> { - let Some(cache_folder_id) = self - .managed_npm_resolver - .resolve_package_cache_folder_id_from_specifier(specifier)? - else { - return Ok(None); - }; - Ok(Some( - self - .resolution - .resolve_pkg_id_from_pkg_cache_folder_id(&cache_folder_id)?, - )) - } - - pub fn resolve_pkg_reqs_from_pkg_id( - &self, - id: &NpmPackageId, - ) -> Vec { - self.resolution.resolve_pkg_reqs_from_pkg_id(id) - } - - /// Attempts to get the package size in bytes. - pub fn package_size( - &self, - package_id: &NpmPackageId, - ) -> Result { - let package_folder = self - .managed_npm_resolver - .resolve_pkg_folder_from_pkg_id(package_id)?; - Ok(crate::util::fs::dir_size(&package_folder)?) - } - - pub fn all_system_packages( - &self, - system_info: &NpmSystemInfo, - ) -> Vec { - self.resolution.all_system_packages(system_info) - } - - /// Checks if the provided package req's folder is cached. - pub fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool { - self - .resolve_pkg_id_from_pkg_req(req) - .ok() - .and_then(|id| { - self - .managed_npm_resolver - .resolve_pkg_folder_from_pkg_id(&id) - .ok() - }) - .map(|folder| folder.exists()) - .unwrap_or(false) - } - - /// Adds package requirements to the resolver and ensures everything is setup. - /// This includes setting up the `node_modules` directory, if applicable. - pub async fn add_and_cache_package_reqs( - &self, - packages: &[PackageReq], - ) -> Result<(), JsErrorBox> { - self - .add_package_reqs_raw( - packages, - Some(PackageCaching::Only(packages.into())), - ) - .await - .dependencies_result - } - - pub async fn add_package_reqs_no_cache( - &self, - packages: &[PackageReq], - ) -> Result<(), JsErrorBox> { - self - .add_package_reqs_raw(packages, None) - .await - .dependencies_result - } - - pub async fn add_package_reqs( - &self, - packages: &[PackageReq], - caching: PackageCaching<'_>, - ) -> Result<(), JsErrorBox> { - self - .add_package_reqs_raw(packages, Some(caching)) - .await - .dependencies_result - } - - pub async fn add_package_reqs_raw<'a>( - &self, - packages: &[PackageReq], - caching: Option>, - ) -> AddPkgReqsResult { - if packages.is_empty() { - return AddPkgReqsResult { - dependencies_result: Ok(()), - results: vec![], - }; - } - - let mut result = self.resolution_installer.add_package_reqs(packages).await; - - if result.dependencies_result.is_ok() { - if let Some(lockfile) = self.maybe_lockfile.as_ref() { - result.dependencies_result = lockfile.error_if_changed(); - } - } - if result.dependencies_result.is_ok() { - if let Some(caching) = caching { - result.dependencies_result = self.cache_packages(caching).await; - } - } - - result - } - - /// Sets package requirements to the resolver, removing old requirements and adding new ones. - /// - /// This will retrieve and resolve package information, but not cache any package files. - pub async fn set_package_reqs( - &self, - packages: &[PackageReq], - ) -> Result<(), AnyError> { - self.resolution_installer.set_package_reqs(packages).await - } - - pub fn snapshot(&self) -> NpmResolutionSnapshot { - self.resolution.snapshot() - } - - pub fn top_package_req_for_name(&self, name: &str) -> Option { - let package_reqs = self.resolution.package_reqs(); - let mut entries = package_reqs - .iter() - .filter(|(_, nv)| nv.name == name) - .collect::>(); - entries.sort_by_key(|(_, nv)| &nv.version); - Some(entries.last()?.0.clone()) - } - - pub fn serialized_valid_snapshot_for_system( - &self, - system_info: &NpmSystemInfo, - ) -> ValidSerializedNpmResolutionSnapshot { - self - .resolution - .serialized_valid_snapshot_for_system(system_info) - } - - pub async fn inject_synthetic_types_node_package( - &self, - ) -> Result<(), JsErrorBox> { - let reqs = &[PackageReq::from_str("@types/node").unwrap()]; - // add and ensure this isn't added to the lockfile - self - .add_package_reqs(reqs, PackageCaching::Only(reqs.into())) - .await?; - - Ok(()) - } - - pub async fn cache_packages( - &self, - caching: PackageCaching<'_>, - ) -> Result<(), JsErrorBox> { - self.fs_installer.cache_packages(caching).await - } - - pub fn resolve_pkg_folder_from_deno_module( - &self, - nv: &PackageNv, - ) -> Result { - let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?; - Ok(self.resolve_pkg_folder_from_pkg_id(&pkg_id)?) - } - - pub fn resolve_pkg_id_from_pkg_req( - &self, - req: &PackageReq, - ) -> Result { - self.resolution.resolve_pkg_id_from_pkg_req(req) - } - - pub fn ensure_no_pkg_json_dep_errors( - &self, - ) -> Result<(), Box> { - for err in self.npm_install_deps_provider.pkg_json_dep_errors() { - match err.source.as_kind() { - deno_package_json::PackageJsonDepValueParseErrorKind::VersionReq(_) => { - return Err(Box::new(err.clone())); - } - deno_package_json::PackageJsonDepValueParseErrorKind::Unsupported { - .. - } => { - // only warn for this one - log::warn!( - "{} {}\n at {}", - colors::yellow("Warning"), - err.source, - err.location, - ) - } - } - } - Ok(()) - } - - /// Ensures that the top level `package.json` dependencies are installed. - /// This may set up the `node_modules` directory. - /// - /// Returns `true` if the top level packages are already installed. A - /// return value of `false` means that new packages were added to the NPM resolution. - pub async fn ensure_top_level_package_json_install( - &self, - ) -> Result { - if !self.top_level_install_flag.raise() { - return Ok(true); // already did this - } - - let pkg_json_remote_pkgs = self.npm_install_deps_provider.remote_pkgs(); - if pkg_json_remote_pkgs.is_empty() { - return Ok(true); - } - - // check if something needs resolving before bothering to load all - // the package information (which is slow) - if pkg_json_remote_pkgs.iter().all(|pkg| { - self - .resolution - .resolve_pkg_id_from_pkg_req(&pkg.req) - .is_ok() - }) { - log::debug!( - "All package.json deps resolvable. Skipping top level install." - ); - return Ok(true); // everything is already resolvable - } - - let pkg_reqs = pkg_json_remote_pkgs - .iter() - .map(|pkg| pkg.req.clone()) - .collect::>(); - self.add_package_reqs_no_cache(&pkg_reqs).await?; - - Ok(false) - } - - pub async fn cache_package_info( - &self, - package_name: &str, - ) -> Result, AnyError> { - // this will internally cache the package information - self - .registry_info_provider - .package_info(package_name) - .await - .map_err(|err| err.into()) - } - - pub fn maybe_node_modules_path(&self) -> Option<&Path> { - self.managed_npm_resolver.node_modules_path() - } - - pub fn global_cache_root_path(&self) -> &Path { - self.npm_cache_dir.root_dir() - } - - pub fn global_cache_root_url(&self) -> &Url { - self.npm_cache_dir.root_dir_url() - } -} - -fn npm_process_state( - snapshot: ValidSerializedNpmResolutionSnapshot, - node_modules_path: Option<&Path>, -) -> String { - serde_json::to_string(&NpmProcessState { - kind: NpmProcessStateKind::Snapshot(snapshot.into_serialized()), - local_node_modules_path: node_modules_path - .map(|p| p.to_string_lossy().to_string()), - }) - .unwrap() -} - -impl NpmProcessStateProvider for ManagedCliNpmResolver { - fn get_npm_process_state(&self) -> String { - npm_process_state( - self.resolution.serialized_valid_snapshot(), - self.managed_npm_resolver.node_modules_path(), - ) - } -} - -impl CliNpmResolver for ManagedCliNpmResolver { - fn into_npm_pkg_folder_resolver( - self: Arc, - ) -> Arc { - self.managed_npm_resolver.clone() - } - - fn into_process_state_provider( - self: Arc, - ) -> Arc { - self - } - - fn into_byonm_or_managed( - self: Arc, - ) -> ByonmOrManagedNpmResolver { - ByonmOrManagedNpmResolver::Managed(self.managed_npm_resolver.clone()) - } - - fn clone_snapshotted(&self) -> Arc { - // create a new snapshotted npm resolution and resolver - let npm_resolution = - Arc::new(NpmResolution::new(self.resolution.snapshot())); - - Arc::new(ManagedCliNpmResolver::new( - create_npm_fs_installer( - self.npm_cache.clone(), - &self.npm_install_deps_provider, - &self.text_only_progress_bar, - npm_resolution.clone(), - self.sys.clone(), - self.tarball_cache.clone(), - self.root_node_modules_path().map(ToOwned::to_owned), - self.npm_system_info.clone(), - self.lifecycle_scripts.clone(), - ), - self.maybe_lockfile.clone(), - Arc::new(ManagedNpmResolver::::new::( - &self.npm_cache_dir, - &self.npm_rc, - npm_resolution.clone(), - self.sys.clone(), - self.root_node_modules_path().map(ToOwned::to_owned), - )), - self.npm_cache.clone(), - self.npm_cache_dir.clone(), - self.npm_install_deps_provider.clone(), - self.npm_rc.clone(), - self.registry_info_provider.clone(), - npm_resolution, - self.sys.clone(), - self.tarball_cache.clone(), - self.text_only_progress_bar.clone(), - self.npm_system_info.clone(), - self.lifecycle_scripts.clone(), - )) - } - - fn as_inner(&self) -> InnerCliNpmResolverRef { - InnerCliNpmResolverRef::Managed(self) - } - - fn root_node_modules_path(&self) -> Option<&Path> { - self.managed_npm_resolver.node_modules_path() - } - - fn check_state_hash(&self) -> Option { - // We could go further and check all the individual - // npm packages, but that's probably overkill. - let mut package_reqs = self - .resolution - .package_reqs() - .into_iter() - .collect::>(); - package_reqs.sort_by(|a, b| a.0.cmp(&b.0)); // determinism - let mut hasher = FastInsecureHasher::new_without_deno_version(); - // ensure the cache gets busted when turning nodeModulesDir on or off - // as this could cause changes in resolution - hasher - .write_hashable(self.managed_npm_resolver.node_modules_path().is_some()); - for (pkg_req, pkg_nv) in package_reqs { - hasher.write_hashable(&pkg_req); - hasher.write_hashable(&pkg_nv); - } - Some(hasher.finish()) - } - - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - referrer: &Url, - ) -> Result { - self - .managed_npm_resolver - .resolve_pkg_folder_from_deno_module_req(req, referrer) - .map_err(ResolvePkgFolderFromDenoReqError::Managed) - } -} diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 052a98e6cf..6ad7ad610e 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -1,6 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. mod byonm; +pub mod installer; mod managed; mod permission_checker; @@ -9,7 +10,6 @@ use std::path::PathBuf; use std::sync::Arc; use dashmap::DashMap; -use deno_core::error::AnyError; use deno_core::serde_json; use deno_core::url::Url; use deno_error::JsErrorBox; @@ -30,8 +30,8 @@ pub use self::byonm::CliByonmNpmResolverCreateOptions; pub use self::managed::CliManagedNpmResolverCreateOptions; pub use self::managed::CliNpmResolverManagedSnapshotOption; pub use self::managed::ManagedCliNpmResolver; -pub use self::managed::PackageCaching; -pub use self::managed::ResolvePkgFolderFromDenoModuleError; +pub use self::managed::NpmResolutionInitializer; +pub use self::managed::ResolveSnapshotError; pub use self::permission_checker::NpmRegistryReadPermissionChecker; pub use self::permission_checker::NpmRegistryReadPermissionCheckerMode; use crate::file_fetcher::CliFileFetcher; @@ -109,28 +109,16 @@ pub enum CliNpmResolverCreateOptions { Byonm(CliByonmNpmResolverCreateOptions), } -pub async fn create_cli_npm_resolver_for_lsp( +pub fn create_cli_npm_resolver( options: CliNpmResolverCreateOptions, ) -> Arc { use CliNpmResolverCreateOptions::*; match options { - Managed(options) => { - managed::create_managed_npm_resolver_for_lsp(options).await - } + Managed(options) => managed::create_managed_npm_resolver(options), Byonm(options) => Arc::new(ByonmNpmResolver::new(options)), } } -pub async fn create_cli_npm_resolver( - options: CliNpmResolverCreateOptions, -) -> Result, AnyError> { - use CliNpmResolverCreateOptions::*; - match options { - Managed(options) => managed::create_managed_npm_resolver(options).await, - Byonm(options) => Ok(Arc::new(ByonmNpmResolver::new(options))), - } -} - pub enum InnerCliNpmResolverRef<'a> { Managed(&'a ManagedCliNpmResolver), #[allow(dead_code)] diff --git a/cli/resolver.rs b/cli/resolver.rs index 1d12d5f8b7..2f3d42e9e1 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -33,8 +33,8 @@ use thiserror::Error; use crate::args::NpmCachingStrategy; use crate::args::DENO_DISABLE_PEDANTIC_NODE_WARNINGS; use crate::node::CliNodeCodeTranslator; -use crate::npm::CliNpmResolver; -use crate::npm::InnerCliNpmResolverRef; +use crate::npm::installer::NpmInstaller; +use crate::npm::installer::PackageCaching; use crate::sys::CliSys; use crate::util::sync::AtomicFlag; use crate::util::text_encoding::from_utf8_lossy_cow; @@ -164,48 +164,30 @@ impl NpmModuleLoader { } } -pub struct CliResolverOptions { - pub deno_resolver: Arc, - pub npm_resolver: Option>, - pub bare_node_builtins_enabled: bool, -} +#[derive(Debug, Default)] +pub struct FoundPackageJsonDepFlag(AtomicFlag); /// A resolver that takes care of resolution, taking into account loaded /// import map, JSX settings. #[derive(Debug)] pub struct CliResolver { deno_resolver: Arc, - npm_resolver: Option>, - found_package_json_dep_flag: AtomicFlag, - bare_node_builtins_enabled: bool, + found_package_json_dep_flag: Arc, warned_pkgs: DashSet, } impl CliResolver { - pub fn new(options: CliResolverOptions) -> Self { + pub fn new( + deno_resolver: Arc, + found_package_json_dep_flag: Arc, + ) -> Self { Self { - deno_resolver: options.deno_resolver, - npm_resolver: options.npm_resolver, - found_package_json_dep_flag: Default::default(), - bare_node_builtins_enabled: options.bare_node_builtins_enabled, + deno_resolver, + found_package_json_dep_flag, warned_pkgs: Default::default(), } } - // todo(dsherret): move this off CliResolver as CliResolver is acting - // like a factory by doing this (it's beyond its responsibility) - pub fn create_graph_npm_resolver( - &self, - npm_caching: NpmCachingStrategy, - ) -> WorkerCliNpmGraphResolver { - WorkerCliNpmGraphResolver { - npm_resolver: self.npm_resolver.as_ref(), - found_package_json_dep_flag: &self.found_package_json_dep_flag, - bare_node_builtins_enabled: self.bare_node_builtins_enabled, - npm_caching, - } - } - pub fn resolve( &self, raw_specifier: &str, @@ -233,7 +215,7 @@ impl CliResolver { if resolution.found_package_json_dep { // mark that we need to do an "npm install" later - self.found_package_json_dep_flag.raise(); + self.found_package_json_dep_flag.0.raise(); } if let Some(diagnostic) = resolution.maybe_diagnostic { @@ -260,15 +242,31 @@ impl CliResolver { } #[derive(Debug)] -pub struct WorkerCliNpmGraphResolver<'a> { - npm_resolver: Option<&'a Arc>, - found_package_json_dep_flag: &'a AtomicFlag, +pub struct CliNpmGraphResolver { + npm_installer: Option>, + found_package_json_dep_flag: Arc, bare_node_builtins_enabled: bool, npm_caching: NpmCachingStrategy, } +impl CliNpmGraphResolver { + pub fn new( + npm_installer: Option>, + found_package_json_dep_flag: Arc, + bare_node_builtins_enabled: bool, + npm_caching: NpmCachingStrategy, + ) -> Self { + Self { + npm_installer, + found_package_json_dep_flag, + bare_node_builtins_enabled, + npm_caching, + } + } +} + #[async_trait(?Send)] -impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> { +impl deno_graph::source::NpmResolver for CliNpmGraphResolver { fn resolve_builtin_node_module( &self, specifier: &ModuleSpecifier, @@ -298,17 +296,12 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> { } fn load_and_cache_npm_package_info(&self, package_name: &str) { - match self.npm_resolver { - Some(npm_resolver) if npm_resolver.as_managed().is_some() => { - let npm_resolver = npm_resolver.clone(); - let package_name = package_name.to_string(); - deno_core::unsync::spawn(async move { - if let Some(managed) = npm_resolver.as_managed() { - let _ignore = managed.cache_package_info(&package_name).await; - } - }); - } - _ => {} + if let Some(npm_installer) = &self.npm_installer { + let npm_installer = npm_installer.clone(); + let package_name = package_name.to_string(); + deno_core::unsync::spawn(async move { + let _ignore = npm_installer.cache_package_info(&package_name).await; + }); } } @@ -316,17 +309,11 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> { &self, package_reqs: &[PackageReq], ) -> NpmResolvePkgReqsResult { - match &self.npm_resolver { - Some(npm_resolver) => { - let npm_resolver = match npm_resolver.as_inner() { - InnerCliNpmResolverRef::Managed(npm_resolver) => npm_resolver, - // if we are using byonm, then this should never be called because - // we don't use deno_graph's npm resolution in this case - InnerCliNpmResolverRef::Byonm(_) => unreachable!(), - }; - - let top_level_result = if self.found_package_json_dep_flag.is_raised() { - npm_resolver + match &self.npm_installer { + Some(npm_installer) => { + let top_level_result = if self.found_package_json_dep_flag.0.is_raised() + { + npm_installer .ensure_top_level_package_json_install() .await .map(|_| ()) @@ -334,15 +321,13 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> { Ok(()) }; - let result = npm_resolver + let result = npm_installer .add_package_reqs_raw( package_reqs, match self.npm_caching { - NpmCachingStrategy::Eager => { - Some(crate::npm::PackageCaching::All) - } + NpmCachingStrategy::Eager => Some(PackageCaching::All), NpmCachingStrategy::Lazy => { - Some(crate::npm::PackageCaching::Only(package_reqs.into())) + Some(PackageCaching::Only(package_reqs.into())) } NpmCachingStrategy::Manual => None, }, diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index ff38912a89..4ca82f6b7d 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -37,10 +37,12 @@ use deno_core::ResolutionKind; use deno_core::SourceCodeCacheInfo; use deno_error::JsErrorBox; use deno_npm::npm_rc::ResolvedNpmRc; +use deno_npm::resolution::NpmResolutionSnapshot; use deno_package_json::PackageJsonDepValue; use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::npm::create_in_npm_pkg_checker; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; +use deno_resolver::npm::managed::NpmResolutionCell; use deno_resolver::npm::CreateInNpmPkgCheckerOptions; use deno_resolver::npm::NpmReqResolverOptions; use deno_runtime::deno_fs; @@ -91,6 +93,7 @@ use crate::npm::CliNpmResolverCreateOptions; use crate::npm::CliNpmResolverManagedSnapshotOption; use crate::npm::NpmRegistryReadPermissionChecker; use crate::npm::NpmRegistryReadPermissionCheckerMode; +use crate::npm::NpmResolutionInitializer; use crate::resolver::CjsTracker; use crate::resolver::CliNpmReqResolver; use crate::resolver::NpmModuleLoader; @@ -687,18 +690,12 @@ pub async fn run( ca_data: metadata.ca_data.map(CaData::Bytes), cell: Default::default(), }); - let progress_bar = ProgressBar::new(ProgressBarStyle::TextOnly); - let http_client_provider = Arc::new(HttpClientProvider::new( - Some(root_cert_store_provider.clone()), - metadata.unsafely_ignore_certificate_errors.clone(), - )); // use a dummy npm registry url let npm_registry_url = ModuleSpecifier::parse("https://localhost/").unwrap(); let root_dir_url = Arc::new(ModuleSpecifier::from_directory_path(&root_path).unwrap()); let main_module = root_dir_url.join(&metadata.entrypoint_key).unwrap(); let npm_global_cache_dir = root_path.join(".deno_compile_node_modules"); - let cache_setting = CacheSetting::Only; let pkg_json_resolver = Arc::new(CliPackageJsonResolver::new(sys.clone())); let npm_registry_permission_checker = { let mode = match &metadata.node_modules { @@ -743,29 +740,19 @@ pub async fn run( maybe_node_modules_path: maybe_node_modules_path.as_deref(), }, )); + let npm_resolution = + Arc::new(NpmResolutionCell::new(NpmResolutionSnapshot::new(snapshot))); let npm_resolver = create_cli_npm_resolver(CliNpmResolverCreateOptions::Managed( CliManagedNpmResolverCreateOptions { - snapshot: CliNpmResolverManagedSnapshotOption::Specified(Some( - snapshot, - )), - maybe_lockfile: None, - http_client_provider: http_client_provider.clone(), + npm_resolution, npm_cache_dir, - npm_install_deps_provider: Arc::new( - // this is only used for installing packages, which isn't necessary with deno compile - NpmInstallDepsProvider::empty(), - ), sys: sys.clone(), - text_only_progress_bar: progress_bar, - cache_setting, maybe_node_modules_path, npm_system_info: Default::default(), npmrc, - lifecycle_scripts: Default::default(), }, - )) - .await?; + )); (in_npm_pkg_checker, npm_resolver) } Some(binary::NodeModules::Byonm { @@ -781,8 +768,7 @@ pub async fn run( pkg_json_resolver: pkg_json_resolver.clone(), root_node_modules_dir, }), - ) - .await?; + ); (in_npm_pkg_checker, npm_resolver) } None => { @@ -801,27 +787,18 @@ pub async fn run( maybe_node_modules_path: None, }, )); + let npm_resolution = Arc::new(NpmResolutionCell::default()); let npm_resolver = create_cli_npm_resolver(CliNpmResolverCreateOptions::Managed( CliManagedNpmResolverCreateOptions { - snapshot: CliNpmResolverManagedSnapshotOption::Specified(None), - http_client_provider: http_client_provider.clone(), - npm_install_deps_provider: Arc::new( - // this is only used for installing packages, which isn't necessary with deno compile - NpmInstallDepsProvider::empty(), - ), + npm_resolution, sys: sys.clone(), - cache_setting, - text_only_progress_bar: progress_bar, npm_cache_dir, - maybe_lockfile: None, maybe_node_modules_path: None, npm_system_info: Default::default(), npmrc: create_default_npmrc(), - lifecycle_scripts: Default::default(), }, - )) - .await?; + )); (in_npm_pkg_checker, npm_resolver) } }; @@ -995,6 +972,7 @@ pub async fn run( None, Box::new(module_loader_factory), node_resolver, + None, npm_resolver, pkg_json_resolver, root_cert_store_provider, diff --git a/cli/tools/check.rs b/cli/tools/check.rs index 53fd5c5db9..c3a285a9b2 100644 --- a/cli/tools/check.rs +++ b/cli/tools/check.rs @@ -34,6 +34,7 @@ use crate::graph_util::maybe_additional_sloppy_imports_message; use crate::graph_util::BuildFastCheckGraphOptions; use crate::graph_util::ModuleGraphBuilder; use crate::node::CliNodeResolver; +use crate::npm::installer::NpmInstaller; use crate::npm::CliNpmResolver; use crate::sys::CliSys; use crate::tsc; @@ -109,6 +110,7 @@ pub struct TypeChecker { cjs_tracker: Arc, cli_options: Arc, module_graph_builder: Arc, + npm_installer: Option>, node_resolver: Arc, npm_resolver: Arc, sys: CliSys, @@ -136,12 +138,14 @@ pub enum CheckError { } impl TypeChecker { + #[allow(clippy::too_many_arguments)] pub fn new( caches: Arc, cjs_tracker: Arc, cli_options: Arc, module_graph_builder: Arc, node_resolver: Arc, + npm_installer: Option>, npm_resolver: Arc, sys: CliSys, ) -> Self { @@ -151,6 +155,7 @@ impl TypeChecker { cli_options, module_graph_builder, node_resolver, + npm_installer, npm_resolver, sys, } @@ -191,9 +196,9 @@ impl TypeChecker { // node built-in specifiers use the @types/node package to determine // types, so inject that now (the caller should do this after the lockfile // has been written) - if let Some(npm_resolver) = self.npm_resolver.as_managed() { + if let Some(npm_installer) = &self.npm_installer { if graph.has_node_specifier { - npm_resolver.inject_synthetic_types_node_package().await?; + npm_installer.inject_synthetic_types_node_package().await?; } } diff --git a/cli/tools/info.rs b/cli/tools/info.rs index 81b0af0a66..50faeda7d3 100644 --- a/cli/tools/info.rs +++ b/cli/tools/info.rs @@ -386,8 +386,11 @@ impl NpmInfo { npm_snapshot: &'a NpmResolutionSnapshot, ) { self.packages.insert(package.id.clone(), package.clone()); - if let Ok(size) = npm_resolver.package_size(&package.id) { - self.package_sizes.insert(package.id.clone(), size); + if let Ok(folder) = npm_resolver.resolve_pkg_folder_from_pkg_id(&package.id) + { + if let Ok(size) = crate::util::fs::dir_size(&folder) { + self.package_sizes.insert(package.id.clone(), size); + } } for id in package.dependencies.values() { if !self.packages.contains_key(id) { diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs index ff5744c07a..596d087589 100644 --- a/cli/tools/installer.rs +++ b/cli/tools/installer.rs @@ -300,8 +300,8 @@ async fn install_local( InstallFlagsLocal::TopLevel => { let factory = CliFactory::from_flags(flags); // surface any errors in the package.json - if let Some(npm_resolver) = factory.npm_resolver().await?.as_managed() { - npm_resolver.ensure_no_pkg_json_dep_errors()?; + if let Some(npm_installer) = factory.npm_installer_if_managed()? { + npm_installer.ensure_no_pkg_json_dep_errors()?; } crate::tools::registry::cache_top_level_deps(&factory, None).await?; diff --git a/cli/tools/jupyter/mod.rs b/cli/tools/jupyter/mod.rs index 78b7675420..67c604118c 100644 --- a/cli/tools/jupyter/mod.rs +++ b/cli/tools/jupyter/mod.rs @@ -67,7 +67,7 @@ pub async fn kernel( // TODO(bartlomieju): should we run with all permissions? let permissions = PermissionsContainer::allow_all(factory.permission_desc_parser()?.clone()); - let npm_resolver = factory.npm_resolver().await?.clone(); + let npm_installer = factory.npm_installer_if_managed()?.cloned(); let resolver = factory.resolver().await?.clone(); let worker_factory = factory.create_cli_main_worker_factory().await?; let (stdio_tx, stdio_rx) = mpsc::unbounded_channel(); @@ -115,7 +115,7 @@ pub async fn kernel( let worker = worker.into_main_worker(); let mut repl_session = repl::ReplSession::initialize( cli_options, - npm_resolver, + npm_installer, resolver, worker, main_module, diff --git a/cli/tools/registry/pm.rs b/cli/tools/registry/pm.rs index 2b1266bafb..0b27b1a3e3 100644 --- a/cli/tools/registry/pm.rs +++ b/cli/tools/registry/pm.rs @@ -861,10 +861,8 @@ async fn npm_install_after_modification( // make a new CliFactory to pick up the updated config file let cli_factory = CliFactory::from_flags(flags); // surface any errors in the package.json - let npm_resolver = cli_factory.npm_resolver().await?; - if let Some(npm_resolver) = npm_resolver.as_managed() { - npm_resolver.ensure_no_pkg_json_dep_errors()?; - } + let npm_installer = cli_factory.npm_installer()?; + npm_installer.ensure_no_pkg_json_dep_errors()?; // npm install cache_deps::cache_top_level_deps(&cli_factory, jsr_resolver).await?; diff --git a/cli/tools/registry/pm/cache_deps.rs b/cli/tools/registry/pm/cache_deps.rs index 3137939cea..5683a30cc8 100644 --- a/cli/tools/registry/pm/cache_deps.rs +++ b/cli/tools/registry/pm/cache_deps.rs @@ -12,16 +12,19 @@ use crate::factory::CliFactory; use crate::graph_container::ModuleGraphContainer; use crate::graph_container::ModuleGraphUpdatePermit; use crate::graph_util::CreateGraphOptions; +use crate::npm::installer::PackageCaching; pub async fn cache_top_level_deps( // todo(dsherret): don't pass the factory into this function. Instead use ctor deps factory: &CliFactory, jsr_resolver: Option>, ) -> Result<(), AnyError> { - let npm_resolver = factory.npm_resolver().await?; + let npm_installer = factory.npm_installer_if_managed()?; let cli_options = factory.cli_options()?; - if let Some(npm_resolver) = npm_resolver.as_managed() { - npm_resolver.ensure_top_level_package_json_install().await?; + if let Some(npm_installer) = &npm_installer { + npm_installer + .ensure_top_level_package_json_install() + .await?; if let Some(lockfile) = cli_options.maybe_lockfile() { lockfile.error_if_changed()?; } @@ -138,10 +141,8 @@ pub async fn cache_top_level_deps( maybe_graph_error = graph_builder.graph_roots_valid(graph, &roots); } - if let Some(npm_resolver) = npm_resolver.as_managed() { - npm_resolver - .cache_packages(crate::npm::PackageCaching::All) - .await?; + if let Some(npm_installer) = &npm_installer { + npm_installer.cache_packages(PackageCaching::All).await?; } maybe_graph_error?; diff --git a/cli/tools/registry/pm/deps.rs b/cli/tools/registry/pm/deps.rs index 708f95f987..1dbb464dbe 100644 --- a/cli/tools/registry/pm/deps.rs +++ b/cli/tools/registry/pm/deps.rs @@ -42,6 +42,7 @@ use crate::graph_container::ModuleGraphContainer; use crate::graph_container::ModuleGraphUpdatePermit; use crate::jsr::JsrFetchResolver; use crate::module_loader::ModuleLoadPreparer; +use crate::npm::installer::NpmInstaller; use crate::npm::CliNpmResolver; use crate::npm::NpmFetchResolver; use crate::util::sync::AtomicFlag; @@ -451,6 +452,7 @@ pub struct DepManager { pub(crate) jsr_fetch_resolver: Arc, pub(crate) npm_fetch_resolver: Arc, npm_resolver: Arc, + npm_installer: Arc, permissions_container: PermissionsContainer, main_module_graph_container: Arc, lockfile: Option>, @@ -460,6 +462,7 @@ pub struct DepManagerArgs { pub module_load_preparer: Arc, pub jsr_fetch_resolver: Arc, pub npm_fetch_resolver: Arc, + pub npm_installer: Arc, pub npm_resolver: Arc, pub permissions_container: PermissionsContainer, pub main_module_graph_container: Arc, @@ -477,6 +480,7 @@ impl DepManager { module_load_preparer, jsr_fetch_resolver, npm_fetch_resolver, + npm_installer, npm_resolver, permissions_container, main_module_graph_container, @@ -490,6 +494,7 @@ impl DepManager { dependencies_resolved: AtomicFlag::lowered(), module_load_preparer, npm_fetch_resolver, + npm_installer, npm_resolver, permissions_container, main_module_graph_container, @@ -556,7 +561,10 @@ impl DepManager { return Ok(()); } - npm_resolver.ensure_top_level_package_json_install().await?; + self + .npm_installer + .ensure_top_level_package_json_install() + .await?; let mut roots = Vec::new(); let mut info_futures = FuturesUnordered::new(); for dep in &self.deps { diff --git a/cli/tools/registry/pm/outdated.rs b/cli/tools/registry/pm/outdated.rs index e7fc88c31f..939c30b5c1 100644 --- a/cli/tools/registry/pm/outdated.rs +++ b/cli/tools/registry/pm/outdated.rs @@ -445,6 +445,7 @@ async fn dep_manager_args( jsr_fetch_resolver, npm_fetch_resolver, npm_resolver: factory.npm_resolver().await?.clone(), + npm_installer: factory.npm_installer()?.clone(), permissions_container: factory.root_permissions_container()?.clone(), main_module_graph_container: factory .main_module_graph_container() diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index 1bc6a2f9ea..05e2f320eb 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -164,7 +164,7 @@ pub async fn run( let cli_options = factory.cli_options()?; let main_module = cli_options.resolve_main_module()?; let permissions = factory.root_permissions_container()?; - let npm_resolver = factory.npm_resolver().await?.clone(); + let npm_installer = factory.npm_installer_if_managed()?.cloned(); let resolver = factory.resolver().await?.clone(); let file_fetcher = factory.file_fetcher()?; let worker_factory = factory.create_cli_main_worker_factory().await?; @@ -187,7 +187,7 @@ pub async fn run( let worker = worker.into_main_worker(); let session = ReplSession::initialize( cli_options, - npm_resolver, + npm_installer, resolver, worker, main_module.clone(), diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs index ed9dd61e2d..5ea4523c48 100644 --- a/cli/tools/repl/session.rs +++ b/cli/tools/repl/session.rs @@ -45,7 +45,7 @@ use crate::args::CliOptions; use crate::cdp; use crate::colors; use crate::lsp::ReplLanguageServer; -use crate::npm::CliNpmResolver; +use crate::npm::installer::NpmInstaller; use crate::resolver::CliResolver; use crate::tools::test::report_tests; use crate::tools::test::reporters::PrettyTestReporter; @@ -181,7 +181,7 @@ struct ReplJsxState { } pub struct ReplSession { - npm_resolver: Arc, + npm_installer: Option>, resolver: Arc, pub worker: MainWorker, session: LocalInspectorSession, @@ -200,7 +200,7 @@ pub struct ReplSession { impl ReplSession { pub async fn initialize( cli_options: &CliOptions, - npm_resolver: Arc, + npm_installer: Option>, resolver: Arc, mut worker: MainWorker, main_module: ModuleSpecifier, @@ -265,7 +265,7 @@ impl ReplSession { )?; let experimental_decorators = transpile_options.use_ts_decorators; let mut repl_session = ReplSession { - npm_resolver, + npm_installer, resolver, worker, session, @@ -704,8 +704,8 @@ impl ReplSession { &mut self, program: &swc_ast::Program, ) -> Result<(), AnyError> { - let Some(npm_resolver) = self.npm_resolver.as_managed() else { - return Ok(()); // don't auto-install for byonm + let Some(npm_installer) = &self.npm_installer else { + return Ok(()); }; let mut collector = ImportCollector::new(); @@ -737,13 +737,13 @@ impl ReplSession { let has_node_specifier = resolved_imports.iter().any(|url| url.scheme() == "node"); if !npm_imports.is_empty() || has_node_specifier { - npm_resolver + npm_installer .add_and_cache_package_reqs(&npm_imports) .await?; // prevent messages in the repl about @types/node not being cached if has_node_specifier { - npm_resolver.inject_synthetic_types_node_package().await?; + npm_installer.inject_synthetic_types_node_package().await?; } } Ok(()) diff --git a/cli/tools/run/mod.rs b/cli/tools/run/mod.rs index a10ce32947..ecf1bd52f3 100644 --- a/cli/tools/run/mod.rs +++ b/cli/tools/run/mod.rs @@ -12,6 +12,7 @@ use crate::args::EvalFlags; use crate::args::Flags; use crate::args::WatchFlagsWithPaths; use crate::factory::CliFactory; +use crate::npm::installer::PackageCaching; use crate::util; use crate::util::file_watcher::WatcherRestartMode; @@ -202,18 +203,17 @@ pub async fn maybe_npm_install(factory: &CliFactory) -> Result<(), AnyError> { // ensure an "npm install" is done if the user has explicitly // opted into using a managed node_modules directory if cli_options.node_modules_dir()? == Some(NodeModulesDirMode::Auto) { - if let Some(npm_resolver) = factory.npm_resolver().await?.as_managed() { - let already_done = - npm_resolver.ensure_top_level_package_json_install().await?; + if let Some(npm_installer) = factory.npm_installer_if_managed()? { + let already_done = npm_installer + .ensure_top_level_package_json_install() + .await?; if !already_done && matches!( cli_options.default_npm_caching_strategy(), crate::graph_util::NpmCachingStrategy::Eager ) { - npm_resolver - .cache_packages(crate::npm::PackageCaching::All) - .await?; + npm_installer.cache_packages(PackageCaching::All).await?; } } } diff --git a/cli/tools/task.rs b/cli/tools/task.rs index 85834a0bfc..d6d87dd45e 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -36,6 +36,8 @@ use crate::args::TaskFlags; use crate::colors; use crate::factory::CliFactory; use crate::node::CliNodeResolver; +use crate::npm::installer::NpmInstaller; +use crate::npm::installer::PackageCaching; use crate::npm::CliNpmResolver; use crate::task_runner; use crate::task_runner::run_future_forwarding_signals; @@ -203,6 +205,7 @@ pub async fn execute_script( }] }; + let npm_installer = factory.npm_installer_if_managed()?; let npm_resolver = factory.npm_resolver().await?; let node_resolver = factory.node_resolver().await?; let env_vars = task_runner::real_env_vars(); @@ -216,6 +219,7 @@ pub async fn execute_script( let task_runner = TaskRunner { task_flags: &task_flags, + npm_installer: npm_installer.map(|n| n.as_ref()), npm_resolver: npm_resolver.as_ref(), node_resolver: node_resolver.as_ref(), env_vars, @@ -266,6 +270,7 @@ struct RunSingleOptions<'a> { struct TaskRunner<'a> { task_flags: &'a TaskFlags, + npm_installer: Option<&'a NpmInstaller>, npm_resolver: &'a dyn CliNpmResolver, node_resolver: &'a CliNodeResolver, env_vars: HashMap, @@ -458,11 +463,11 @@ impl<'a> TaskRunner<'a> { return Ok(0); }; - if let Some(npm_resolver) = self.npm_resolver.as_managed() { - npm_resolver.ensure_top_level_package_json_install().await?; - npm_resolver - .cache_packages(crate::npm::PackageCaching::All) + if let Some(npm_installer) = self.npm_installer { + npm_installer + .ensure_top_level_package_json_install() .await?; + npm_installer.cache_packages(PackageCaching::All).await?; } let cwd = match &self.task_flags.cwd { @@ -497,11 +502,11 @@ impl<'a> TaskRunner<'a> { argv: &[String], ) -> Result { // ensure the npm packages are installed if using a managed resolver - if let Some(npm_resolver) = self.npm_resolver.as_managed() { - npm_resolver.ensure_top_level_package_json_install().await?; - npm_resolver - .cache_packages(crate::npm::PackageCaching::All) + if let Some(npm_installer) = self.npm_installer { + npm_installer + .ensure_top_level_package_json_install() .await?; + npm_installer.cache_packages(PackageCaching::All).await?; } let cwd = match &self.task_flags.cwd { diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index f645a5f6b8..b6cf691c38 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -28,6 +28,7 @@ use deno_graph::GraphKind; use deno_graph::Module; use deno_graph::ModuleGraph; use deno_graph::ResolutionResolved; +use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_semver::npm::NpmPackageReqReference; use node_resolver::errors::NodeJsErrorCode; @@ -709,9 +710,7 @@ pub enum ResolveError { PackageSubpathResolve(PackageSubpathResolveError), #[class(inherit)] #[error("{0}")] - ResolvePkgFolderFromDenoModule( - #[from] crate::npm::ResolvePkgFolderFromDenoModuleError, - ), + ResolvePkgFolderFromDenoModule(#[from] ResolvePkgFolderFromDenoModuleError), #[class(inherit)] #[error("{0}")] ResolveNonGraphSpecifierTypes(#[from] ResolveNonGraphSpecifierTypesError), diff --git a/cli/worker.rs b/cli/worker.rs index eee89d663c..d93c6c5f40 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -54,6 +54,8 @@ use crate::args::NpmCachingStrategy; use crate::args::StorageKeyResolver; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; +use crate::npm::installer::NpmInstaller; +use crate::npm::installer::PackageCaching; use crate::npm::CliNpmResolver; use crate::sys::CliSys; use crate::util::checksum; @@ -148,6 +150,7 @@ struct SharedWorkerState { maybe_lockfile: Option>, module_loader_factory: Box, node_resolver: Arc, + npm_installer: Option>, npm_resolver: Arc, pkg_json_resolver: Arc, root_cert_store_provider: Arc, @@ -423,6 +426,7 @@ impl CliMainWorkerFactory { maybe_lockfile: Option>, module_loader_factory: Box, node_resolver: Arc, + npm_installer: Option>, npm_resolver: Arc, pkg_json_resolver: Arc, root_cert_store_provider: Arc, @@ -447,6 +451,7 @@ impl CliMainWorkerFactory { maybe_lockfile, module_loader_factory, node_resolver, + npm_installer, npm_resolver, pkg_json_resolver, root_cert_store_provider, @@ -496,18 +501,18 @@ impl CliMainWorkerFactory { let main_module = if let Ok(package_ref) = NpmPackageReqReference::from_specifier(&main_module) { - if let Some(npm_resolver) = shared.npm_resolver.as_managed() { + if let Some(npm_installer) = &shared.npm_installer { let reqs = &[package_ref.req().clone()]; - npm_resolver + npm_installer .add_package_reqs( reqs, if matches!( shared.default_npm_caching_strategy, NpmCachingStrategy::Lazy ) { - crate::npm::PackageCaching::Only(reqs.into()) + PackageCaching::Only(reqs.into()) } else { - crate::npm::PackageCaching::All + PackageCaching::All }, ) .await?; diff --git a/resolvers/deno/npm/managed/global.rs b/resolvers/deno/npm/managed/global.rs index cffe68a30e..d16234d8f4 100644 --- a/resolvers/deno/npm/managed/global.rs +++ b/resolvers/deno/npm/managed/global.rs @@ -16,7 +16,7 @@ use node_resolver::errors::ReferrerNotFoundError; use node_resolver::NpmPackageFolderResolver; use url::Url; -use super::resolution::NpmResolutionRc; +use super::resolution::NpmResolutionCellRc; use super::NpmCacheDirRc; use super::NpmPackageFsResolver; use crate::ResolvedNpmRcRc; @@ -26,14 +26,14 @@ use crate::ResolvedNpmRcRc; pub struct GlobalNpmPackageResolver { cache: NpmCacheDirRc, npm_rc: ResolvedNpmRcRc, - resolution: NpmResolutionRc, + resolution: NpmResolutionCellRc, } impl GlobalNpmPackageResolver { pub fn new( cache: NpmCacheDirRc, npm_rc: ResolvedNpmRcRc, - resolution: NpmResolutionRc, + resolution: NpmResolutionCellRc, ) -> Self { Self { cache, diff --git a/resolvers/deno/npm/managed/local.rs b/resolvers/deno/npm/managed/local.rs index 3aa1275d66..72b0b0d451 100644 --- a/resolvers/deno/npm/managed/local.rs +++ b/resolvers/deno/npm/managed/local.rs @@ -19,7 +19,7 @@ use sys_traits::FsCanonicalize; use sys_traits::FsMetadata; use url::Url; -use super::resolution::NpmResolutionRc; +use super::resolution::NpmResolutionCellRc; use super::NpmPackageFsResolver; use crate::npm::local::get_package_folder_id_folder_name_from_parts; use crate::npm::local::get_package_folder_id_from_folder_name; @@ -32,7 +32,7 @@ use crate::sync::MaybeSync; pub struct LocalNpmPackageResolver< TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync, > { - resolution: NpmResolutionRc, + resolution: NpmResolutionCellRc, sys: TSys, root_node_modules_path: PathBuf, root_node_modules_url: Url, @@ -43,7 +43,7 @@ impl { #[allow(clippy::too_many_arguments)] pub fn new( - resolution: NpmResolutionRc, + resolution: NpmResolutionCellRc, sys: TSys, node_modules_folder: PathBuf, ) -> Self { diff --git a/resolvers/deno/npm/managed/mod.rs b/resolvers/deno/npm/managed/mod.rs index a9775ee374..62147b2ac3 100644 --- a/resolvers/deno/npm/managed/mod.rs +++ b/resolvers/deno/npm/managed/mod.rs @@ -8,10 +8,13 @@ mod resolution; use std::path::Path; use std::path::PathBuf; +use deno_npm::resolution::PackageCacheFolderIdNotFoundError; +use deno_npm::resolution::PackageNvNotFoundError; use deno_npm::resolution::PackageReqNotFoundError; use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageId; use deno_path_util::fs::canonicalize_path_maybe_not_exists; +use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use node_resolver::InNpmPackageChecker; use node_resolver::NpmPackageFolderResolver; @@ -23,14 +26,24 @@ use self::common::NpmPackageFsResolver; use self::common::NpmPackageFsResolverRc; use self::global::GlobalNpmPackageResolver; use self::local::LocalNpmPackageResolver; -pub use self::resolution::NpmResolution; -pub use self::resolution::NpmResolutionRc; +pub use self::resolution::NpmResolutionCell; +pub use self::resolution::NpmResolutionCellRc; use crate::sync::new_rc; use crate::sync::MaybeSend; use crate::sync::MaybeSync; use crate::NpmCacheDirRc; use crate::ResolvedNpmRcRc; +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum ResolvePkgFolderFromDenoModuleError { + #[class(inherit)] + #[error(transparent)] + PackageNvNotFound(#[from] PackageNvNotFoundError), + #[class(inherit)] + #[error(transparent)] + ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError), +} + #[derive(Debug, thiserror::Error, deno_error::JsError)] #[error(transparent)] pub enum ResolvePkgFolderFromPkgIdError { @@ -66,6 +79,16 @@ pub enum ManagedResolvePkgFolderFromDenoReqError { ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError), } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum ResolvePkgIdFromSpecifierError { + #[class(inherit)] + #[error(transparent)] + Io(#[from] std::io::Error), + #[class(inherit)] + #[error(transparent)] + NotFound(#[from] PackageCacheFolderIdNotFoundError), +} + #[allow(clippy::disallowed_types)] pub type ManagedNpmResolverRc = crate::sync::MaybeArc>; @@ -73,7 +96,7 @@ pub type ManagedNpmResolverRc = #[derive(Debug)] pub struct ManagedNpmResolver { fs_resolver: NpmPackageFsResolverRc, - resolution: NpmResolutionRc, + resolution: NpmResolutionCellRc, sys: TSys, } @@ -89,7 +112,7 @@ impl ManagedNpmResolver { >( npm_cache_dir: &NpmCacheDirRc, npm_rc: &ResolvedNpmRcRc, - resolution: NpmResolutionRc, + resolution: NpmResolutionCellRc, sys: TCreateSys, maybe_node_modules_path: Option, ) -> ManagedNpmResolver { @@ -144,6 +167,14 @@ impl ManagedNpmResolver { Ok(path) } + pub fn resolve_pkg_folder_from_deno_module( + &self, + nv: &PackageNv, + ) -> Result { + let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?; + Ok(self.resolve_pkg_folder_from_pkg_id(&pkg_id)?) + } + pub fn resolve_pkg_folder_from_deno_module_req( &self, req: &PackageReq, @@ -162,6 +193,24 @@ impl ManagedNpmResolver { .fs_resolver .resolve_package_cache_folder_id_from_specifier(specifier) } + + /// Resolves the package id from the provided specifier. + pub fn resolve_pkg_id_from_specifier( + &self, + specifier: &Url, + ) -> Result, ResolvePkgIdFromSpecifierError> { + let Some(cache_folder_id) = self + .fs_resolver + .resolve_package_cache_folder_id_from_specifier(specifier)? + else { + return Ok(None); + }; + Ok(Some( + self + .resolution + .resolve_pkg_id_from_pkg_cache_folder_id(&cache_folder_id)?, + )) + } } impl diff --git a/resolvers/deno/npm/managed/resolution.rs b/resolvers/deno/npm/managed/resolution.rs index 8ddd1ac70f..08dabf5a76 100644 --- a/resolvers/deno/npm/managed/resolution.rs +++ b/resolvers/deno/npm/managed/resolution.rs @@ -18,16 +18,17 @@ use deno_semver::package::PackageReq; use parking_lot::RwLock; #[allow(clippy::disallowed_types)] -pub type NpmResolutionRc = crate::sync::MaybeArc; +pub type NpmResolutionCellRc = crate::sync::MaybeArc; /// Handles updating and storing npm resolution in memory. /// /// This does not interact with the file system. -pub struct NpmResolution { +#[derive(Default)] +pub struct NpmResolutionCell { snapshot: RwLock, } -impl std::fmt::Debug for NpmResolution { +impl std::fmt::Debug for NpmResolutionCell { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let snapshot = self.snapshot.read(); f.debug_struct("NpmResolution") @@ -36,7 +37,7 @@ impl std::fmt::Debug for NpmResolution { } } -impl NpmResolution { +impl NpmResolutionCell { pub fn from_serialized( initial_snapshot: Option, ) -> Self { diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index 4c737f1126..4682085aea 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -140,7 +140,9 @@ pub trait NpmProcessStateProvider: #[derive(Debug)] pub struct EmptyNpmProcessStateProvider; + impl NpmProcessStateProvider for EmptyNpmProcessStateProvider {} + deno_core::extension!( deno_process, ops = [ From 7616429436c8799bfc0c04287712814423485458 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 13 Jan 2025 22:29:21 -0500 Subject: [PATCH 11/38] fix(compile/windows): better handling of deno_dir on different drive letter than code (#27654) Closes https://github.com/denoland/deno/issues/27651 --- cli/standalone/binary.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index 296d6825a7..ff0343e27f 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -1007,8 +1007,16 @@ impl<'a> DenoCompileBinaryWriter<'a> { // this is not as optimized as it could be let mut last_name = Cow::Borrowed(DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME); - for ancestor in parent.ancestors() { - let dir = vfs.get_dir_mut(ancestor).unwrap(); + for ancestor in + parent.ancestors().map(Some).chain(std::iter::once(None)) + { + let dir = if let Some(ancestor) = ancestor { + vfs.get_dir_mut(ancestor).unwrap() + } else if cfg!(windows) { + vfs.get_system_root_dir_mut() + } else { + break; + }; if let Ok(index) = dir.entries.binary_search(&last_name, case_sensitivity) { From 9cb089f6db5574f091e54e222e8082ddd9ea779f Mon Sep 17 00:00:00 2001 From: Aaron Ang <67321817+aaron-ang@users.noreply.github.com> Date: Tue, 14 Jan 2025 04:01:14 -0500 Subject: [PATCH 12/38] fix(ext/node): add `writev` method to `FileHandle` (#27563) Part of #25554 --- ext/node/lib.rs | 2 +- ext/node/polyfills/_fs/_fs_writev.d.ts | 65 ----------------- .../_fs/{_fs_writev.mjs => _fs_writev.ts} | 73 +++++++++++++++++-- ext/node/polyfills/fs.ts | 2 +- ext/node/polyfills/internal/fs/handle.ts | 13 +++- ext/node/polyfills/internal/fs/streams.mjs | 2 +- tests/unit_node/_fs/_fs_handle_test.ts | 39 ++++++++++ tools/core_import_map.json | 2 +- 8 files changed, 118 insertions(+), 80 deletions(-) delete mode 100644 ext/node/polyfills/_fs/_fs_writev.d.ts rename ext/node/polyfills/_fs/{_fs_writev.mjs => _fs_writev.ts} (52%) diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 64b6c006a1..731cd3a9c7 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -487,7 +487,7 @@ deno_core::extension!(deno_node, "_fs/_fs_watch.ts", "_fs/_fs_write.mjs", "_fs/_fs_writeFile.ts", - "_fs/_fs_writev.mjs", + "_fs/_fs_writev.ts", "_next_tick.ts", "_process/exiting.ts", "_process/process.ts", diff --git a/ext/node/polyfills/_fs/_fs_writev.d.ts b/ext/node/polyfills/_fs/_fs_writev.d.ts deleted file mode 100644 index 1ba5511ff1..0000000000 --- a/ext/node/polyfills/_fs/_fs_writev.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2018-2025 the Deno authors. MIT license. -// Forked from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d9df51e34526f48bef4e2546a006157b391ad96c/types/node/fs.d.ts - -import { ErrnoException } from "ext:deno_node/_global.d.ts"; - -/** - * Write an array of `ArrayBufferView`s to the file specified by `fd` using`writev()`. - * - * `position` is the offset from the beginning of the file where this data - * should be written. If `typeof position !== 'number'`, the data will be written - * at the current position. - * - * The callback will be given three arguments: `err`, `bytesWritten`, and`buffers`. `bytesWritten` is how many bytes were written from `buffers`. - * - * If this method is `util.promisify()` ed, it returns a promise for an`Object` with `bytesWritten` and `buffers` properties. - * - * It is unsafe to use `fs.writev()` multiple times on the same file without - * waiting for the callback. For this scenario, use {@link createWriteStream}. - * - * On Linux, positional writes don't work when the file is opened in append mode. - * The kernel ignores the position argument and always appends the data to - * the end of the file. - * @since v12.9.0 - */ -export function writev( - fd: number, - buffers: ReadonlyArray, - cb: ( - err: ErrnoException | null, - bytesWritten: number, - buffers: ArrayBufferView[], - ) => void, -): void; -export function writev( - fd: number, - buffers: ReadonlyArray, - position: number | null, - cb: ( - err: ErrnoException | null, - bytesWritten: number, - buffers: ArrayBufferView[], - ) => void, -): void; -export interface WriteVResult { - bytesWritten: number; - buffers: ArrayBufferView[]; -} -export namespace writev { - function __promisify__( - fd: number, - buffers: ReadonlyArray, - position?: number, - ): Promise; -} -/** - * For detailed information, see the documentation of the asynchronous version of - * this API: {@link writev}. - * @since v12.9.0 - * @return The number of bytes written. - */ -export function writevSync( - fd: number, - buffers: ReadonlyArray, - position?: number, -): number; diff --git a/ext/node/polyfills/_fs/_fs_writev.mjs b/ext/node/polyfills/_fs/_fs_writev.ts similarity index 52% rename from ext/node/polyfills/_fs/_fs_writev.mjs rename to ext/node/polyfills/_fs/_fs_writev.ts index 61807c7f68..e38b44b19a 100644 --- a/ext/node/polyfills/_fs/_fs_writev.mjs +++ b/ext/node/polyfills/_fs/_fs_writev.ts @@ -5,15 +5,53 @@ // deno-lint-ignore-file prefer-primordials import { Buffer } from "node:buffer"; +import process from "node:process"; +import { ErrnoException } from "ext:deno_node/_global.d.ts"; import { validateBufferArray } from "ext:deno_node/internal/fs/utils.mjs"; import { getValidatedFd } from "ext:deno_node/internal/fs/utils.mjs"; +import { WriteVResult } from "ext:deno_node/internal/fs/handle.ts"; import { maybeCallback } from "ext:deno_node/_fs/_fs_common.ts"; import * as io from "ext:deno_io/12_io.js"; import { op_fs_seek_async, op_fs_seek_sync } from "ext:core/ops"; -export function writev(fd, buffers, position, callback) { +export interface WriteVResult { + bytesWritten: number; + buffers: ReadonlyArray; +} + +type writeVCallback = ( + err: ErrnoException | null, + bytesWritten: number, + buffers: ReadonlyArray, +) => void; + +/** + * Write an array of `ArrayBufferView`s to the file specified by `fd` using`writev()`. + * + * `position` is the offset from the beginning of the file where this data + * should be written. If `typeof position !== 'number'`, the data will be written + * at the current position. + * + * The callback will be given three arguments: `err`, `bytesWritten`, and`buffers`. `bytesWritten` is how many bytes were written from `buffers`. + * + * If this method is `util.promisify()` ed, it returns a promise for an`Object` with `bytesWritten` and `buffers` properties. + * + * It is unsafe to use `fs.writev()` multiple times on the same file without + * waiting for the callback. For this scenario, use {@link createWriteStream}. + * + * On Linux, positional writes don't work when the file is opened in append mode. + * The kernel ignores the position argument and always appends the data to + * the end of the file. + * @since v12.9.0 + */ +export function writev( + fd: number, + buffers: ReadonlyArray, + position?: number | null, + callback?: writeVCallback, +): void { const innerWritev = async (fd, buffers, position) => { - const chunks = []; + const chunks: Buffer[] = []; const offset = 0; for (let i = 0; i < buffers.length; i++) { if (Buffer.isBuffer(buffers[i])) { @@ -45,16 +83,24 @@ export function writev(fd, buffers, position, callback) { if (typeof position !== "number") position = null; innerWritev(fd, buffers, position).then( - (nwritten) => { - callback(null, nwritten, buffers); - }, + (nwritten) => callback(null, nwritten, buffers), (err) => callback(err), ); } -export function writevSync(fd, buffers, position) { +/** + * For detailed information, see the documentation of the asynchronous version of + * this API: {@link writev}. + * @since v12.9.0 + * @return The number of bytes written. + */ +export function writevSync( + fd: number, + buffers: ArrayBufferView[], + position?: number | null, +): number { const innerWritev = (fd, buffers, position) => { - const chunks = []; + const chunks: Buffer[] = []; const offset = 0; for (let i = 0; i < buffers.length; i++) { if (Buffer.isBuffer(buffers[i])) { @@ -85,3 +131,16 @@ export function writevSync(fd, buffers, position) { return innerWritev(fd, buffers, position); } + +export function writevPromise( + fd: number, + buffers: ArrayBufferView[], + position?: number, +): Promise { + return new Promise((resolve, reject) => { + writev(fd, buffers, position, (err, bytesWritten, buffers) => { + if (err) reject(err); + else resolve({ bytesWritten, buffers }); + }); + }); +} diff --git a/ext/node/polyfills/fs.ts b/ext/node/polyfills/fs.ts index 76ff9ebd12..a6e43b5baa 100644 --- a/ext/node/polyfills/fs.ts +++ b/ext/node/polyfills/fs.ts @@ -119,7 +119,7 @@ import { // @deno-types="./_fs/_fs_write.d.ts" import { write, writeSync } from "ext:deno_node/_fs/_fs_write.mjs"; // @deno-types="./_fs/_fs_writev.d.ts" -import { writev, writevSync } from "ext:deno_node/_fs/_fs_writev.mjs"; +import { writev, writevSync } from "ext:deno_node/_fs/_fs_writev.ts"; import { readv, readvSync } from "ext:deno_node/_fs/_fs_readv.ts"; import { writeFile, diff --git a/ext/node/polyfills/internal/fs/handle.ts b/ext/node/polyfills/internal/fs/handle.ts index 2d787a9f3b..4244d159b7 100644 --- a/ext/node/polyfills/internal/fs/handle.ts +++ b/ext/node/polyfills/internal/fs/handle.ts @@ -6,7 +6,7 @@ import { EventEmitter } from "node:events"; import { Buffer } from "node:buffer"; import { Mode, promises, read, write } from "node:fs"; -export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts"; +import { core } from "ext:core/mod.js"; import { BinaryOptionsArgument, FileOptionsArgument, @@ -14,7 +14,8 @@ import { TextOptionsArgument, } from "ext:deno_node/_fs/_fs_common.ts"; import { ftruncatePromise } from "ext:deno_node/_fs/_fs_ftruncate.ts"; -import { core } from "ext:core/mod.js"; +export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts"; +import { writevPromise, WriteVResult } from "ext:deno_node/_fs/_fs_writev.ts"; interface WriteResult { bytesWritten: number; @@ -64,7 +65,7 @@ export class FileHandle extends EventEmitter { position, (err, bytesRead, buffer) => { if (err) reject(err); - else resolve({ buffer: buffer, bytesRead: bytesRead }); + else resolve({ buffer, bytesRead }); }, ); }); @@ -72,7 +73,7 @@ export class FileHandle extends EventEmitter { return new Promise((resolve, reject) => { read(this.fd, bufferOrOpt, (err, bytesRead, buffer) => { if (err) reject(err); - else resolve({ buffer: buffer, bytesRead: bytesRead }); + else resolve({ buffer, bytesRead }); }); }); } @@ -137,6 +138,10 @@ export class FileHandle extends EventEmitter { return fsCall(promises.writeFile, this, data, options); } + writev(buffers: ArrayBufferView[], position?: number): Promise { + return fsCall(writevPromise, this, buffers, position); + } + close(): Promise { // Note that Deno.close is not async return Promise.resolve(core.close(this.fd)); diff --git a/ext/node/polyfills/internal/fs/streams.mjs b/ext/node/polyfills/internal/fs/streams.mjs index 5adb8da225..d2ebecbe9a 100644 --- a/ext/node/polyfills/internal/fs/streams.mjs +++ b/ext/node/polyfills/internal/fs/streams.mjs @@ -18,7 +18,7 @@ import { errorOrDestroy } from "ext:deno_node/internal/streams/destroy.mjs"; import { open as fsOpen } from "ext:deno_node/_fs/_fs_open.ts"; import { read as fsRead } from "ext:deno_node/_fs/_fs_read.ts"; import { write as fsWrite } from "ext:deno_node/_fs/_fs_write.mjs"; -import { writev as fsWritev } from "ext:deno_node/_fs/_fs_writev.mjs"; +import { writev as fsWritev } from "ext:deno_node/_fs/_fs_writev.ts"; import { close as fsClose } from "ext:deno_node/_fs/_fs_close.ts"; import { Buffer } from "node:buffer"; import { diff --git a/tests/unit_node/_fs/_fs_handle_test.ts b/tests/unit_node/_fs/_fs_handle_test.ts index e4a41f8ba7..a8ca826329 100644 --- a/tests/unit_node/_fs/_fs_handle_test.ts +++ b/tests/unit_node/_fs/_fs_handle_test.ts @@ -118,6 +118,45 @@ Deno.test("[node/fs filehandle.writeFile] Write to file", async function () { assertEquals(decoder.decode(data), "hello world"); }); +Deno.test( + "[node/fs filehandle.writev] Write array of buffers to file", + async function () { + const tempFile: string = await Deno.makeTempFile(); + const fileHandle = await fs.open(tempFile, "w"); + + const buffer1 = Buffer.from("hello "); + const buffer2 = Buffer.from("world"); + const res = await fileHandle.writev([buffer1, buffer2]); + + const data = Deno.readFileSync(tempFile); + await Deno.remove(tempFile); + await fileHandle.close(); + + assertEquals(res.bytesWritten, 11); + assertEquals(decoder.decode(data), "hello world"); + }, +); + +Deno.test( + "[node/fs filehandle.writev] Write array of buffers to file with position", + async function () { + const tempFile: string = await Deno.makeTempFile(); + const fileHandle = await fs.open(tempFile, "w"); + + const buffer1 = Buffer.from("hello "); + const buffer2 = Buffer.from("world"); + await fileHandle.writev([buffer1, buffer2], 0); + const buffer3 = Buffer.from("lorem ipsum"); + await fileHandle.writev([buffer3], 6); + + const data = Deno.readFileSync(tempFile); + await Deno.remove(tempFile); + await fileHandle.close(); + + assertEquals(decoder.decode(data), "hello lorem ipsum"); + }, +); + Deno.test( "[node/fs filehandle.truncate] Truncate file with length", async function () { diff --git a/tools/core_import_map.json b/tools/core_import_map.json index d38221eb4c..feeae1ac70 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -38,7 +38,7 @@ "ext:deno_node/_fs/_fs_stat.ts": "../ext/node/polyfills/_fs/_fs_stat.ts", "ext:deno_node/_fs/_fs_watch.ts": "../ext/node/polyfills/_fs/_fs_watch.ts", "ext:deno_node/_fs/_fs_write.mjs": "../ext/node/polyfills/_fs/_fs_write.mjs", - "ext:deno_node/_fs/_fs_writev.mjs": "../ext/node/polyfills/_fs/_fs_writev.mjs", + "ext:deno_node/_fs/_fs_writev.ts": "../ext/node/polyfills/_fs/_fs_writev.ts", "ext:deno_node/_global.d.ts": "../ext/node/polyfills/_global.d.ts", "node:_http_agent": "../ext/node/polyfills/_http_agent.mjs", "node:_http_common": "../ext/node/polyfills/_http_common.ts", From a1f50a742219f6da78234412fe11a1456bfd3a0d Mon Sep 17 00:00:00 2001 From: siaeyy <75006429+siaeyy@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:08:22 +0300 Subject: [PATCH 13/38] fix(node/fs): add utimes method to the FileHandle class (#27582) --- ext/node/polyfills/internal/fs/handle.ts | 8 ++++++++ tests/unit_node/_fs/_fs_handle_test.ts | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ext/node/polyfills/internal/fs/handle.ts b/ext/node/polyfills/internal/fs/handle.ts index 4244d159b7..774b36dfc2 100644 --- a/ext/node/polyfills/internal/fs/handle.ts +++ b/ext/node/polyfills/internal/fs/handle.ts @@ -157,6 +157,14 @@ export class FileHandle extends EventEmitter { assertNotClosed(this, promises.chmod.name); return promises.chmod(this.#path, mode); } + + utimes( + atime: number | string | Date, + mtime: number | string | Date, + ): Promise { + assertNotClosed(this, promises.utimes.name); + return promises.utimes(this.#path, atime, mtime); + } } function assertNotClosed(handle: FileHandle, syscall: string) { diff --git a/tests/unit_node/_fs/_fs_handle_test.ts b/tests/unit_node/_fs/_fs_handle_test.ts index a8ca826329..9134c2cb0a 100644 --- a/tests/unit_node/_fs/_fs_handle_test.ts +++ b/tests/unit_node/_fs/_fs_handle_test.ts @@ -256,3 +256,20 @@ Deno.test({ await fileHandle.close(); }, }); + +Deno.test({ + name: + "[node/fs filehandle.utimes] Change the file system timestamps of the file", + async fn() { + const fileHandle = await fs.open(testData); + + const atime = new Date(); + const mtime = new Date(0); + + await fileHandle.utimes(atime, mtime); + assertEquals(Deno.statSync(testData).atime!, atime); + assertEquals(Deno.statSync(testData).mtime!, mtime); + + await fileHandle.close(); + }, +}); From 1e95c2056169c9b5de165b58bfd9296d5e5ce98e Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 14 Jan 2025 07:00:31 -0500 Subject: [PATCH 14/38] refactor: deno_config 0.45 (#27660) --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- cli/args/mod.rs | 20 +++---------------- cli/lsp/config.rs | 15 ++------------ cli/lsp/diagnostics.rs | 7 +------ cli/lsp/documents.rs | 3 --- cli/lsp/language_server.rs | 2 -- cli/lsp/tsc.rs | 1 - .../with_malformed_config.out | 2 +- .../with_malformed_config2.out | 2 +- 10 files changed, 12 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2a78300c0..aa13ae0ccd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1497,11 +1497,12 @@ dependencies = [ [[package]] name = "deno_config" -version = "0.43.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c4c11bd51ef6738cabfc3c53f16c209a0b8615cb1e4e5bf3b14e3b5deebfe21" +checksum = "47a47412627aa0d08414eca0e8329128013ab70bdb2cdfdc5456c2214cf24c8f" dependencies = [ "boxed_error", + "capacity_builder 0.5.0", "deno_error", "deno_package_json", "deno_path_util", diff --git a/Cargo.toml b/Cargo.toml index 2b52664a7f..48aeccdaef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ deno_ast = { version = "=0.44.0", features = ["transpiling"] } deno_core = { version = "0.330.0" } deno_bench_util = { version = "0.179.0", path = "./bench_util" } -deno_config = { version = "=0.43.0", features = ["workspace", "sync"] } +deno_config = { version = "=0.45.0", features = ["workspace", "sync"] } deno_lockfile = "=0.24.0" deno_media_type = { version = "0.2.3", features = ["module_specifier"] } deno_npm = "=0.27.2" diff --git a/cli/args/mod.rs b/cli/args/mod.rs index ebd321a20a..4ba85f1706 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -56,7 +56,6 @@ use deno_core::error::AnyError; use deno_core::resolve_url_or_path; use deno_core::serde_json; use deno_core::url::Url; -use deno_error::JsErrorBox; use deno_graph::GraphKind; pub use deno_json::check_warn_tsconfig; use deno_lint::linter::LintConfig as DenoLintConfig; @@ -842,8 +841,6 @@ impl CliOptions { } else { &[] }; - let config_parse_options = - deno_config::deno_json::ConfigParseOptions::default(); let discover_pkg_json = flags.config_flag != ConfigFlag::Disabled && !flags.no_npm && !has_flag_env_var("DENO_NO_PACKAGE_JSON"); @@ -854,7 +851,6 @@ impl CliOptions { deno_json_cache: None, pkg_json_cache: Some(&node_resolver::PackageJsonThreadLocalCache), workspace_cache: None, - config_parse_options, additional_config_file_names, discover_pkg_json, maybe_vendor_override, @@ -1103,11 +1099,11 @@ impl CliOptions { } }; Ok(self.workspace().create_resolver( + &CliSys::default(), CreateResolverOptions { pkg_json_dep_resolution, specified_import_map: cli_arg_specified_import_map, }, - |path| std::fs::read_to_string(path).map_err(JsErrorBox::from_err), )?) } @@ -2126,12 +2122,7 @@ mod test { let cwd = &std::env::current_dir().unwrap(); let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); - let config_file = ConfigFile::new( - config_text, - config_specifier, - &deno_config::deno_json::ConfigParseOptions::default(), - ) - .unwrap(); + let config_file = ConfigFile::new(config_text, config_specifier).unwrap(); let actual = resolve_import_map_specifier( Some("import-map.json"), Some(&config_file), @@ -2150,12 +2141,7 @@ mod test { let config_text = r#"{}"#; let config_specifier = ModuleSpecifier::parse("file:///deno/deno.jsonc").unwrap(); - let config_file = ConfigFile::new( - config_text, - config_specifier, - &deno_config::deno_json::ConfigParseOptions::default(), - ) - .unwrap(); + let config_file = ConfigFile::new(config_text, config_specifier).unwrap(); let actual = resolve_import_map_specifier( None, Some(&config_file), diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 7841ee0783..ba57502298 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -41,7 +41,6 @@ use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::url::Url; use deno_core::ModuleSpecifier; -use deno_error::JsErrorBox; use deno_lint::linter::LintConfig as DenoLintConfig; use deno_npm::npm_rc::ResolvedNpmRc; use deno_package_json::PackageJsonCache; @@ -1247,7 +1246,6 @@ impl ConfigData { pkg_json_cache: Some(pkg_json_cache), workspace_cache: Some(workspace_cache), discover_pkg_json: !has_flag_env_var("DENO_NO_PACKAGE_JSON"), - config_parse_options: Default::default(), maybe_vendor_override: None, }, ) @@ -1572,11 +1570,11 @@ impl ConfigData { let resolver = member_dir .workspace .create_resolver( + &CliSys::default(), CreateResolverOptions { pkg_json_dep_resolution, specified_import_map, }, - |path| std::fs::read_to_string(path).map_err(JsErrorBox::from_err), ) .inspect_err(|err| { lsp_warn!( @@ -2078,7 +2076,6 @@ impl deno_config::workspace::WorkspaceCache for WorkspaceMemCache { #[cfg(test)] mod tests { - use deno_config::deno_json::ConfigParseOptions; use deno_core::resolve_url; use deno_core::serde_json; use deno_core::serde_json::json; @@ -2352,12 +2349,7 @@ mod tests { config .tree .inject_config_file( - ConfigFile::new( - "{}", - root_uri.join("deno.json").unwrap(), - &ConfigParseOptions::default(), - ) - .unwrap(), + ConfigFile::new("{}", root_uri.join("deno.json").unwrap()).unwrap(), ) .await; assert!(config.specifier_enabled(&root_uri)); @@ -2413,7 +2405,6 @@ mod tests { }) .to_string(), root_uri.join("deno.json").unwrap(), - &ConfigParseOptions::default(), ) .unwrap(), ) @@ -2439,7 +2430,6 @@ mod tests { }) .to_string(), root_uri.join("deno.json").unwrap(), - &ConfigParseOptions::default(), ) .unwrap(), ) @@ -2457,7 +2447,6 @@ mod tests { }) .to_string(), root_uri.join("deno.json").unwrap(), - &ConfigParseOptions::default(), ) .unwrap(), ) diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 42a1a0c52a..fe8dc4c8d5 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -1695,12 +1695,7 @@ mod tests { let mut config = Config::new_with_roots([root_uri.clone()]); if let Some((relative_path, json_string)) = maybe_import_map { let base_url = root_uri.join(relative_path).unwrap(); - let config_file = ConfigFile::new( - json_string, - base_url, - &deno_config::deno_json::ConfigParseOptions::default(), - ) - .unwrap(); + let config_file = ConfigFile::new(json_string, base_url).unwrap(); config.tree.inject_config_file(config_file).await; } let resolver = diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 70f55ffd62..6a7a08b5a1 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -1767,7 +1767,6 @@ fn bytes_to_content( #[cfg(test)] mod tests { use deno_config::deno_json::ConfigFile; - use deno_config::deno_json::ConfigParseOptions; use deno_core::serde_json; use deno_core::serde_json::json; use pretty_assertions::assert_eq; @@ -1924,7 +1923,6 @@ console.log(b, "hello deno"); }) .to_string(), config.root_uri().unwrap().join("deno.json").unwrap(), - &ConfigParseOptions::default(), ) .unwrap(), ) @@ -1968,7 +1966,6 @@ console.log(b, "hello deno"); }) .to_string(), config.root_uri().unwrap().join("deno.json").unwrap(), - &ConfigParseOptions::default(), ) .unwrap(), ) diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 03f63e5f25..0f3bfcdf59 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -3621,8 +3621,6 @@ impl Inner { deno_json_cache: None, pkg_json_cache: None, workspace_cache: None, - config_parse_options: - deno_config::deno_json::ConfigParseOptions::default(), additional_config_file_names: &[], discover_pkg_json: !has_flag_env_var("DENO_NO_PACKAGE_JSON"), maybe_vendor_override: if force_global_cache { diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 8d9a5a46a1..e2a0fc430d 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -5589,7 +5589,6 @@ mod tests { }) .to_string(), temp_dir.url().join("deno.json").unwrap(), - &Default::default(), ) .unwrap(), ) diff --git a/tests/specs/lint/with_malformed_config/with_malformed_config.out b/tests/specs/lint/with_malformed_config/with_malformed_config.out index 1c0f0fff6e..928ec02fb1 100644 --- a/tests/specs/lint/with_malformed_config/with_malformed_config.out +++ b/tests/specs/lint/with_malformed_config/with_malformed_config.out @@ -1,4 +1,4 @@ error: Failed to parse "lint" configuration Caused by: - unknown field `dont_know_this_field`, expected one of `rules`, `include`, `exclude`, `files`, `report` + unknown field `dont_know_this_field`, expected one of `rules`, `include`, `exclude`, `files`, `report`, `plugins` diff --git a/tests/specs/lint/with_malformed_config2/with_malformed_config2.out b/tests/specs/lint/with_malformed_config2/with_malformed_config2.out index 1c0f0fff6e..928ec02fb1 100644 --- a/tests/specs/lint/with_malformed_config2/with_malformed_config2.out +++ b/tests/specs/lint/with_malformed_config2/with_malformed_config2.out @@ -1,4 +1,4 @@ error: Failed to parse "lint" configuration Caused by: - unknown field `dont_know_this_field`, expected one of `rules`, `include`, `exclude`, `files`, `report` + unknown field `dont_know_this_field`, expected one of `rules`, `include`, `exclude`, `files`, `report`, `plugins` From 3fb8fc1ba78ae7ded63dd2c1bb3249338bf14cac Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Tue, 14 Jan 2025 13:31:02 +0100 Subject: [PATCH 15/38] feat(unstable): refactor js lint plugin AST (#27615) This PR changes the underlying buffer backed AST format we use for JavaScript-based linting plugins. It adds support for various new types, makes traversal code a lot easier and is more polished compared to previous iterations. Here is a quick summary (in no particular order): - Node prop data is separate from traversal, which makes traversal code so much easier to reason about. Previously, it was interleaved with node prop data - spans are in a separate table as well, as they are rarely needed. - schema is separate from SWC conversion logic, which makes - supports recursive plain objects - supports numbers - supports bigint - supports regex - adds all SWC nodes Apologies, this is kinda a big PR, but it's worth it imo. _Marking as draft because I need to update some tests tomorrow._ --- cli/js/40_lint.js | 873 +- cli/js/40_lint_selector.js | 36 +- cli/js/40_lint_types.d.ts | 9 +- cli/tools/lint/ast_buffer/buffer.rs | 591 +- cli/tools/lint/ast_buffer/swc.rs | 3540 +++---- cli/tools/lint/ast_buffer/ts_estree.rs | 2356 ++++- .../__snapshots__/lint_plugin_test.ts.snap | 8608 +++++++++++++++++ tests/unit/lint_plugin_test.ts | 989 +- 8 files changed, 13757 insertions(+), 3245 deletions(-) create mode 100644 tests/unit/__snapshots__/lint_plugin_test.ts.snap diff --git a/cli/js/40_lint.js b/cli/js/40_lint.js index 4adbc1baa1..9f85f0871d 100644 --- a/cli/js/40_lint.js +++ b/cli/js/40_lint.js @@ -8,10 +8,27 @@ import { splitSelectors, } from "ext:cli/40_lint_selector.js"; import { core, internals } from "ext:core/mod.js"; + const { op_lint_create_serialized_ast, } = core.ops; +// Keep these in sync with Rust +const AST_IDX_INVALID = 0; +const AST_GROUP_TYPE = 1; +/// +/// +/// +/// +/// +const NODE_SIZE = 1 + 4 + 4 + 4 + 4; +const PROP_OFFSET = 1; +const CHILD_OFFSET = 1 + 4; +const NEXT_OFFSET = 1 + 4 + 4; +const PARENT_OFFSET = 1 + 4 + 4 + 4; +// Span size in buffer: u32 + u32 +const SPAN_SIZE = 4 + 4; + // Keep in sync with Rust // These types are expected to be present on every node. Note that this // isn't set in stone. We could revise this at a future point. @@ -34,12 +51,21 @@ const PropFlags = { * the string table that was included in the message. */ String: 2, + /** + * A numnber field. Numbers are represented as strings internally. + */ + Number: 3, /** This value is either 0 = false, or 1 = true */ - Bool: 3, + Bool: 4, /** No value, it's null */ - Null: 4, + Null: 5, /** No value, it's undefined */ - Undefined: 5, + Undefined: 6, + /** An object */ + Obj: 7, + Regex: 8, + BigInt: 9, + Array: 10, }; /** @typedef {import("./40_lint_types.d.ts").AstContext} AstContext */ @@ -51,6 +77,7 @@ const PropFlags = { /** @typedef {import("./40_lint_types.d.ts").LintPlugin} LintPlugin */ /** @typedef {import("./40_lint_types.d.ts").TransformFn} TransformFn */ /** @typedef {import("./40_lint_types.d.ts").MatchContext} MatchContext */ +/** @typedef {import("./40_lint_types.d.ts").Node} Node */ /** @type {LintState} */ const state = { @@ -100,17 +127,17 @@ export function installPlugin(plugin) { /** * @param {AstContext} ctx - * @param {number} offset - * @returns + * @param {number} idx + * @returns {FacadeNode | null} */ -function getNode(ctx, offset) { - if (offset === 0) return null; - const cached = ctx.nodes.get(offset); - if (cached !== undefined) return cached; +function getNode(ctx, idx) { + if (idx === AST_IDX_INVALID) return null; + const cached = ctx.nodes.get(idx); + if (cached !== undefined) return /** @type {*} */ (cached); - const node = new Node(ctx, offset); - ctx.nodes.set(offset, /** @type {*} */ (cached)); - return node; + const node = new FacadeNode(ctx, idx); + ctx.nodes.set(idx, /** @type {*} */ (node)); + return /** @type {*} */ (node); } /** @@ -122,31 +149,22 @@ function getNode(ctx, offset) { * @returns {number} */ function findPropOffset(buf, offset, search) { - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; - - const propCount = buf[offset]; + const count = buf[offset]; offset += 1; - for (let i = 0; i < propCount; i++) { + for (let i = 0; i < count; i++) { const maybe = offset; const prop = buf[offset++]; const kind = buf[offset++]; if (prop === search) return maybe; - if (kind === PropFlags.Ref) { - offset += 4; - } else if (kind === PropFlags.RefArr) { + if (kind === PropFlags.Obj) { const len = readU32(buf, offset); - offset += 4 + (len * 4); - } else if (kind === PropFlags.String) { offset += 4; - } else if (kind === PropFlags.Bool) { - offset++; - } else if (kind === PropFlags.Null || kind === PropFlags.Undefined) { - // No value + // prop + kind + value + offset += len * (1 + 1 + 4); } else { - offset++; + offset += 4; } } @@ -154,23 +172,23 @@ function findPropOffset(buf, offset, search) { } const INTERNAL_CTX = Symbol("ctx"); -const INTERNAL_OFFSET = Symbol("offset"); +const INTERNAL_IDX = Symbol("offset"); // This class is a facade for all materialized nodes. Instead of creating a // unique class per AST node, we have one class with getters for every // possible node property. This allows us to lazily materialize child node // only when they are needed. -class Node { +class FacadeNode { [INTERNAL_CTX]; - [INTERNAL_OFFSET]; + [INTERNAL_IDX]; /** * @param {AstContext} ctx - * @param {number} offset + * @param {number} idx */ - constructor(ctx, offset) { + constructor(ctx, idx) { this[INTERNAL_CTX] = ctx; - this[INTERNAL_OFFSET] = offset; + this[INTERNAL_IDX] = idx; } /** @@ -186,12 +204,12 @@ class Node { * @returns {string} */ [Symbol.for("Deno.customInspect")](_, options) { - const json = toJsValue(this[INTERNAL_CTX], this[INTERNAL_OFFSET]); + const json = nodeToJson(this[INTERNAL_CTX], this[INTERNAL_IDX]); return Deno.inspect(json, options); } [Symbol.for("Deno.lint.toJsValue")]() { - return toJsValue(this[INTERNAL_CTX], this[INTERNAL_OFFSET]); + return nodeToJson(this[INTERNAL_CTX], this[INTERNAL_IDX]); } } @@ -212,125 +230,243 @@ function setNodeGetters(ctx) { const name = getString(ctx.strTable, id); - Object.defineProperty(Node.prototype, name, { + Object.defineProperty(FacadeNode.prototype, name, { get() { - return readValue(this[INTERNAL_CTX], this[INTERNAL_OFFSET], i); + return readValue( + this[INTERNAL_CTX], + this[INTERNAL_IDX], + i, + getNode, + ); }, }); } } /** - * Serialize a node recursively to plain JSON * @param {AstContext} ctx - * @param {number} offset - * @returns {*} + * @param {number} idx */ -function toJsValue(ctx, offset) { - const { buf } = ctx; - +function nodeToJson(ctx, idx) { /** @type {Record} */ const node = { - type: readValue(ctx, offset, AST_PROP_TYPE), - range: readValue(ctx, offset, AST_PROP_RANGE), + type: readValue(ctx, idx, AST_PROP_TYPE, nodeToJson), + range: readValue(ctx, idx, AST_PROP_RANGE, nodeToJson), }; - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; + const { buf } = ctx; + let offset = readPropOffset(ctx, idx); const count = buf[offset++]; - for (let i = 0; i < count; i++) { - const prop = buf[offset++]; - const kind = buf[offset++]; - const name = getString(ctx.strTable, ctx.strByProp[prop]); - if (kind === PropFlags.Ref) { - const v = readU32(buf, offset); - offset += 4; - node[name] = v === 0 ? null : toJsValue(ctx, v); - } else if (kind === PropFlags.RefArr) { - const len = readU32(buf, offset); - offset += 4; - const nodes = new Array(len); - for (let i = 0; i < len; i++) { - const v = readU32(buf, offset); - if (v === 0) continue; - nodes[i] = toJsValue(ctx, v); - offset += 4; - } - node[name] = nodes; - } else if (kind === PropFlags.Bool) { - const v = buf[offset++]; - node[name] = v === 1; - } else if (kind === PropFlags.String) { - const v = readU32(buf, offset); - offset += 4; - node[name] = getString(ctx.strTable, v); - } else if (kind === PropFlags.Null) { - node[name] = null; - } else if (kind === PropFlags.Undefined) { - node[name] = undefined; - } + for (let i = 0; i < count; i++) { + const prop = buf[offset]; + const _kind = buf[offset + 1]; + + const name = getString(ctx.strTable, ctx.strByProp[prop]); + node[name] = readProperty(ctx, offset, nodeToJson); + + // prop + type + value + offset += 1 + 1 + 4; } return node; } /** - * Read a specific property from a node + * @param {AstContext["buf"]} buf + * @param {number} idx + * @returns {number} + */ +function readType(buf, idx) { + return buf[idx * NODE_SIZE]; +} + +/** + * @param {AstContext} ctx + * @param {number} idx + * @returns {Node["range"]} + */ +function readSpan(ctx, idx) { + let offset = ctx.spansOffset + (idx * SPAN_SIZE); + const start = readU32(ctx.buf, offset); + offset += 4; + const end = readU32(ctx.buf, offset); + + return [start, end]; +} + +/** + * @param {AstContext["buf"]} buf + * @param {number} idx + * @returns {number} + */ +function readRawPropOffset(buf, idx) { + const offset = (idx * NODE_SIZE) + PROP_OFFSET; + return readU32(buf, offset); +} + +/** + * @param {AstContext} ctx + * @param {number} idx + * @returns {number} + */ +function readPropOffset(ctx, idx) { + return readRawPropOffset(ctx.buf, idx) + ctx.propsOffset; +} + +/** + * @param {AstContext["buf"]} buf + * @param {number} idx + * @returns {number} + */ +function readChild(buf, idx) { + const offset = (idx * NODE_SIZE) + CHILD_OFFSET; + return readU32(buf, offset); +} +/** + * @param {AstContext["buf"]} buf + * @param {number} idx + * @returns {number} + */ +function readNext(buf, idx) { + const offset = (idx * NODE_SIZE) + NEXT_OFFSET; + return readU32(buf, offset); +} + +/** + * @param {AstContext["buf"]} buf + * @param {number} idx + * @returns {number} + */ +function readParent(buf, idx) { + const offset = (idx * NODE_SIZE) + PARENT_OFFSET; + return readU32(buf, offset); +} + +/** + * @param {AstContext["strTable"]} strTable + * @param {number} strId + * @returns {RegExp} + */ +function readRegex(strTable, strId) { + const raw = getString(strTable, strId); + const idx = raw.lastIndexOf("/"); + const pattern = raw.slice(1, idx); + const flags = idx < raw.length - 1 ? raw.slice(idx + 1) : undefined; + + return new RegExp(pattern, flags); +} + +/** * @param {AstContext} ctx * @param {number} offset - * @param {number} search - * @returns {*} + * @param {(ctx: AstContext, idx: number) => any} parseNode + * @returns {Record} */ -function readValue(ctx, offset, search) { - const { buf } = ctx; - const type = buf[offset]; +function readObject(ctx, offset, parseNode) { + const { buf, strTable, strByProp } = ctx; - if (search === AST_PROP_TYPE) { - return getString(ctx.strTable, ctx.strByType[type]); - } else if (search === AST_PROP_RANGE) { - const start = readU32(buf, offset + 1 + 4); - const end = readU32(buf, offset + 1 + 4 + 4); - return [start, end]; - } else if (search === AST_PROP_PARENT) { - const pos = readU32(buf, offset + 1); - return getNode(ctx, pos); + /** @type {Record} */ + const obj = {}; + + const count = readU32(buf, offset); + offset += 4; + + for (let i = 0; i < count; i++) { + const prop = buf[offset]; + const name = getString(strTable, strByProp[prop]); + obj[name] = readProperty(ctx, offset, parseNode); + // name + kind + value + offset += 1 + 1 + 4; } - offset = findPropOffset(ctx.buf, offset, search); - if (offset === -1) return undefined; + return obj; +} - const kind = buf[offset + 1]; - offset += 2; +/** + * @param {AstContext} ctx + * @param {number} offset + * @param {(ctx: AstContext, idx: number) => any} parseNode + * @returns {any} + */ +function readProperty(ctx, offset, parseNode) { + const { buf } = ctx; + + // skip over name + const _name = buf[offset++]; + const kind = buf[offset++]; if (kind === PropFlags.Ref) { const value = readU32(buf, offset); - return getNode(ctx, value); + return parseNode(ctx, value); } else if (kind === PropFlags.RefArr) { - const len = readU32(buf, offset); - offset += 4; + const groupId = readU32(buf, offset); - const nodes = new Array(len); - for (let i = 0; i < len; i++) { - nodes[i] = getNode(ctx, readU32(buf, offset)); - offset += 4; + const nodes = []; + let next = readChild(buf, groupId); + while (next > AST_IDX_INVALID) { + nodes.push(parseNode(ctx, next)); + next = readNext(buf, next); } + return nodes; } else if (kind === PropFlags.Bool) { - return buf[offset] === 1; + const v = readU32(buf, offset); + return v === 1; } else if (kind === PropFlags.String) { const v = readU32(buf, offset); return getString(ctx.strTable, v); + } else if (kind === PropFlags.Number) { + const v = readU32(buf, offset); + return Number(getString(ctx.strTable, v)); + } else if (kind === PropFlags.BigInt) { + const v = readU32(buf, offset); + return BigInt(getString(ctx.strTable, v)); + } else if (kind === PropFlags.Regex) { + const v = readU32(buf, offset); + return readRegex(ctx.strTable, v); } else if (kind === PropFlags.Null) { return null; } else if (kind === PropFlags.Undefined) { return undefined; + } else if (kind === PropFlags.Obj) { + const objOffset = readU32(buf, offset) + ctx.propsOffset; + return readObject(ctx, objOffset, parseNode); } throw new Error(`Unknown prop kind: ${kind}`); } +/** + * Read a specific property from a node + * @param {AstContext} ctx + * @param {number} idx + * @param {number} search + * @param {(ctx: AstContext, idx: number) => any} parseNode + * @returns {*} + */ +function readValue(ctx, idx, search, parseNode) { + const { buf } = ctx; + + if (search === AST_PROP_TYPE) { + const type = readType(buf, idx); + return getString(ctx.strTable, ctx.strByType[type]); + } else if (search === AST_PROP_RANGE) { + return readSpan(ctx, idx); + } else if (search === AST_PROP_PARENT) { + const parent = readParent(buf, idx); + return getNode(ctx, parent); + } + + const propOffset = readPropOffset(ctx, idx); + + const offset = findPropOffset(ctx.buf, propOffset, search); + if (offset === -1) return undefined; + + return readProperty(ctx, offset, parseNode); +} + const DECODER = new TextDecoder(); /** @@ -359,322 +495,149 @@ function getString(strTable, id) { return name; } -/** - * @param {AstContext["buf"]} buf - * @param {number} child - * @returns {null | [number, number]} - */ -function findChildOffset(buf, child) { - let offset = readU32(buf, child + 1); - - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; - - const propCount = buf[offset++]; - for (let i = 0; i < propCount; i++) { - const _prop = buf[offset++]; - const kind = buf[offset++]; - - switch (kind) { - case PropFlags.Ref: { - const start = offset; - const value = readU32(buf, offset); - offset += 4; - if (value === child) { - return [start, -1]; - } - break; - } - case PropFlags.RefArr: { - const start = offset; - - const len = readU32(buf, offset); - offset += 4; - - for (let j = 0; j < len; j++) { - const value = readU32(buf, offset); - offset += 4; - if (value === child) { - return [start, j]; - } - } - - break; - } - case PropFlags.String: - offset += 4; - break; - case PropFlags.Bool: - offset++; - break; - case PropFlags.Null: - case PropFlags.Undefined: - break; - } - } - - return null; -} - /** @implements {MatchContext} */ class MatchCtx { /** - * @param {AstContext["buf"]} buf - * @param {AstContext["strTable"]} strTable - * @param {AstContext["strByType"]} strByType + * @param {AstContext} ctx */ - constructor(buf, strTable, strByType) { - this.buf = buf; - this.strTable = strTable; - this.strByType = strByType; + constructor(ctx) { + this.ctx = ctx; } /** - * @param {number} offset - * @returns {number} - */ - getParent(offset) { - return readU32(this.buf, offset + 1); - } - - /** - * @param {number} offset - * @returns {number} - */ - getType(offset) { - return this.buf[offset]; - } - - /** - * @param {number} offset - * @param {number[]} propIds * @param {number} idx + * @returns {number} + */ + getParent(idx) { + return readParent(this.ctx.buf, idx); + } + + /** + * @param {number} idx + * @returns {number} + */ + getType(idx) { + return readType(this.ctx.buf, idx); + } + + /** + * @param {number} idx - Node idx + * @param {number[]} propIds + * @param {number} propIdx * @returns {unknown} */ - getAttrPathValue(offset, propIds, idx) { - const { buf } = this; + getAttrPathValue(idx, propIds, propIdx) { + if (idx === 0) throw -1; - const propId = propIds[idx]; + const { buf, strTable, strByType } = this.ctx; + + const propId = propIds[propIdx]; switch (propId) { case AST_PROP_TYPE: { - const type = this.getType(offset); - return getString(this.strTable, this.strByType[type]); + const type = readType(buf, idx); + return getString(strTable, strByType[type]); } case AST_PROP_PARENT: case AST_PROP_RANGE: - throw new Error(`Not supported`); + throw -1; } + let offset = readPropOffset(this.ctx, idx); + offset = findPropOffset(buf, offset, propId); - if (offset === -1) return undefined; + if (offset === -1) throw -1; const _prop = buf[offset++]; const kind = buf[offset++]; if (kind === PropFlags.Ref) { const value = readU32(buf, offset); // Checks need to end with a value, not a node - if (idx === propIds.length - 1) return undefined; - return this.getAttrPathValue(value, propIds, idx + 1); + if (propIdx === propIds.length - 1) throw -1; + return this.getAttrPathValue(value, propIds, propIdx + 1); } else if (kind === PropFlags.RefArr) { - const count = readU32(buf, offset); + const arrIdx = readU32(buf, offset); offset += 4; - if (idx < propIds.length - 1 && propIds[idx + 1] === AST_PROP_LENGTH) { + let count = 0; + let child = readChild(buf, arrIdx); + while (child > AST_IDX_INVALID) { + count++; + child = readNext(buf, child); + } + + if ( + propIdx < propIds.length - 1 && propIds[propIdx + 1] === AST_PROP_LENGTH + ) { return count; } // TODO(@marvinhagemeister): Allow traversing into array children? + throw -1; + } else if (kind === PropFlags.Obj) { + // TODO(@marvinhagemeister) } // Cannot traverse into primitives further - if (idx < propIds.length - 1) return undefined; + if (propIdx < propIds.length - 1) throw -1; if (kind === PropFlags.String) { const s = readU32(buf, offset); - return getString(this.strTable, s); + return getString(strTable, s); + } else if (kind === PropFlags.Number) { + const s = readU32(buf, offset); + return Number(getString(strTable, s)); + } else if (kind === PropFlags.Regex) { + const v = readU32(buf, offset); + return readRegex(strTable, v); } else if (kind === PropFlags.Bool) { - return buf[offset] === 1; + return readU32(buf, offset) === 1; } else if (kind === PropFlags.Null) { return null; } else if (kind === PropFlags.Undefined) { return undefined; } - return undefined; + throw -1; } /** - * @param {number} offset - * @param {number[]} propIds * @param {number} idx - * @returns {boolean} - */ - hasAttrPath(offset, propIds, idx) { - const { buf } = this; - - const propId = propIds[idx]; - // If propId is 0 then the property doesn't exist in the AST - if (propId === 0) return false; - - switch (propId) { - case AST_PROP_TYPE: - case AST_PROP_PARENT: - case AST_PROP_RANGE: - return true; - } - - offset = findPropOffset(buf, offset, propId); - if (offset === -1) return false; - if (idx === propIds.length - 1) return true; - - const _prop = buf[offset++]; - const kind = buf[offset++]; - if (kind === PropFlags.Ref) { - const value = readU32(buf, offset); - return this.hasAttrPath(value, propIds, idx + 1); - } else if (kind === PropFlags.RefArr) { - const _count = readU32(buf, offset); - offset += 4; - - if (idx < propIds.length - 1 && propIds[idx + 1] === AST_PROP_LENGTH) { - return true; - } - - // TODO(@marvinhagemeister): Allow traversing into array children? - } - - // Primitives cannot be traversed further. This means we - // didn't found the attribute. - if (idx < propIds.length - 1) return false; - - return true; - } - - /** - * @param {number} offset * @returns {number} */ - getFirstChild(offset) { - const { buf } = this; - - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; - - const count = buf[offset++]; - for (let i = 0; i < count; i++) { - const _prop = buf[offset++]; - const kind = buf[offset++]; - - switch (kind) { - case PropFlags.Ref: { - const v = readU32(buf, offset); - offset += 4; - return v; - } - case PropFlags.RefArr: { - const len = readU32(buf, offset); - offset += 4; - for (let j = 0; j < len; j++) { - const v = readU32(buf, offset); - offset += 4; - return v; - } - - return len; - } - - case PropFlags.String: - offset += 4; - break; - case PropFlags.Bool: - offset++; - break; - case PropFlags.Null: - case PropFlags.Undefined: - break; - } - } - - return -1; + getFirstChild(idx) { + const siblings = this.getSiblings(idx); + return siblings[0] ?? -1; } /** - * @param {number} offset + * @param {number} idx * @returns {number} */ - getLastChild(offset) { - const { buf } = this; - - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; - - let last = -1; - - const count = buf[offset++]; - for (let i = 0; i < count; i++) { - const _prop = buf[offset++]; - const kind = buf[offset++]; - - switch (kind) { - case PropFlags.Ref: { - const v = readU32(buf, offset); - offset += 4; - last = v; - break; - } - case PropFlags.RefArr: { - const len = readU32(buf, offset); - offset += 4; - for (let j = 0; j < len; j++) { - const v = readU32(buf, offset); - last = v; - offset += 4; - } - - break; - } - - case PropFlags.String: - offset += 4; - break; - case PropFlags.Bool: - offset++; - break; - case PropFlags.Null: - case PropFlags.Undefined: - break; - } - } - - return last; + getLastChild(idx) { + const siblings = this.getSiblings(idx); + return siblings.at(-1) ?? -1; } /** - * @param {number} id + * @param {number} idx * @returns {number[]} */ - getSiblings(id) { - const { buf } = this; + getSiblings(idx) { + const { buf } = this.ctx; + const parent = readParent(buf, idx); - const result = findChildOffset(buf, id); - // Happens for program nodes - if (result === null) return []; - - if (result[1] === -1) { - return [id]; + // Only RefArrays have siblings + const parentType = readType(buf, parent); + if (parentType !== AST_GROUP_TYPE) { + return []; } - let offset = result[0]; - const count = readU32(buf, offset); - offset += 4; - - /** @type {number[]} */ const out = []; - for (let i = 0; i < count; i++) { - const v = readU32(buf, offset); - offset += 4; - out.push(v); + let child = readChild(buf, parent); + while (child > AST_IDX_INVALID) { + out.push(child); + child = readNext(buf, child); } return out; @@ -683,7 +646,7 @@ class MatchCtx { /** * @param {Uint8Array} buf - * @param {AstContext} buf + * @returns {AstContext} */ function createAstContext(buf) { /** @type {Map} */ @@ -691,6 +654,8 @@ function createAstContext(buf) { // The buffer has a few offsets at the end which allows us to easily // jump to the relevant sections of the message. + const propsOffset = readU32(buf, buf.length - 24); + const spansOffset = readU32(buf, buf.length - 20); const typeMapOffset = readU32(buf, buf.length - 16); const propMapOffset = readU32(buf, buf.length - 12); const strTableOffset = readU32(buf, buf.length - 8); @@ -702,9 +667,7 @@ function createAstContext(buf) { const stringCount = readU32(buf, offset); offset += 4; - // TODO(@marvinhagemeister): We could lazily decode the strings on an as needed basis. - // Not sure if this matters much in practice though. - let id = 0; + let strId = 0; for (let i = 0; i < stringCount; i++) { const len = readU32(buf, offset); offset += 4; @@ -712,8 +675,8 @@ function createAstContext(buf) { const strBytes = buf.slice(offset, offset + len); offset += len; const s = DECODER.decode(strBytes); - strTable.set(id, s); - id++; + strTable.set(strId, s); + strId++; } if (strTable.size !== stringCount) { @@ -755,14 +718,17 @@ function createAstContext(buf) { buf, strTable, rootOffset, + spansOffset, + propsOffset, nodes: new Map(), strTableOffset, strByProp, strByType, typeByStr, propByStr, - matcher: new MatchCtx(buf, strTable, strByType), + matcher: /** @type {*} */ (null), }; + ctx.matcher = new MatchCtx(ctx); setNodeGetters(ctx); @@ -903,76 +869,53 @@ export function runPluginsForFile(fileName, serializedAst) { /** * @param {AstContext} ctx * @param {CompiledVisitor[]} visitors - * @param {number} offset + * @param {number} idx */ -function traverse(ctx, visitors, offset) { - // The 0 offset is used to denote an empty/placeholder node - if (offset === 0) return; - - const originalOffset = offset; +function traverse(ctx, visitors, idx) { + if (idx === AST_IDX_INVALID) return; const { buf } = ctx; + const nodeType = readType(ctx.buf, idx); /** @type {VisitorFn[] | null} */ let exits = null; - for (let i = 0; i < visitors.length; i++) { - const v = visitors[i]; - - if (v.matcher(ctx.matcher, offset)) { - if (v.info.exit !== NOOP) { - if (exits === null) { - exits = [v.info.exit]; - } else { - exits.push(v.info.exit); + // Only visit if it's an actual node + if (nodeType !== AST_GROUP_TYPE) { + // Loop over visitors and check if any selector matches + for (let i = 0; i < visitors.length; i++) { + const v = visitors[i]; + if (v.matcher(ctx.matcher, idx)) { + if (v.info.exit !== NOOP) { + if (exits === null) { + exits = [v.info.exit]; + } else { + exits.push(v.info.exit); + } } - } - if (v.info.enter !== NOOP) { - const node = /** @type {*} */ (getNode(ctx, offset)); - v.info.enter(node); + if (v.info.enter !== NOOP) { + const node = /** @type {*} */ (getNode(ctx, idx)); + v.info.enter(node); + } } } } - // Search for node references in the properties of the current node. All - // other properties can be ignored. try { - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; + const childIdx = readChild(buf, idx); + if (childIdx > AST_IDX_INVALID) { + traverse(ctx, visitors, childIdx); + } - const propCount = buf[offset]; - offset += 1; - - for (let i = 0; i < propCount; i++) { - const kind = buf[offset + 1]; - offset += 2; // propId + propFlags - - if (kind === PropFlags.Ref) { - const next = readU32(buf, offset); - offset += 4; - traverse(ctx, visitors, next); - } else if (kind === PropFlags.RefArr) { - const len = readU32(buf, offset); - offset += 4; - - for (let j = 0; j < len; j++) { - const child = readU32(buf, offset); - offset += 4; - traverse(ctx, visitors, child); - } - } else if (kind === PropFlags.String) { - offset += 4; - } else if (kind === PropFlags.Bool) { - offset += 1; - } else if (kind === PropFlags.Null || kind === PropFlags.Undefined) { - // No value - } + const nextIdx = readNext(buf, idx); + if (nextIdx > AST_IDX_INVALID) { + traverse(ctx, visitors, nextIdx); } } finally { if (exits !== null) { for (let i = 0; i < exits.length; i++) { - const node = /** @type {*} */ (getNode(ctx, originalOffset)); + const node = /** @type {*} */ (getNode(ctx, idx)); exits[i](node); } } @@ -1009,38 +952,46 @@ function _dump(ctx) { // deno-lint-ignore no-console console.log(); - let offset = 0; + // @ts-ignore dump fn + // deno-lint-ignore no-console + console.log(); - while (offset < strTableOffset) { - const type = buf[offset]; - const name = getString(ctx.strTable, ctx.strByType[type]); + let idx = 0; + while (idx < (strTableOffset / NODE_SIZE)) { + const type = readType(buf, idx); + const child = readChild(buf, idx); + const next = readNext(buf, idx); + const parent = readParent(buf, idx); + const range = readSpan(ctx, idx); + + const name = type === AST_IDX_INVALID + ? "" + : type === AST_GROUP_TYPE + ? "" + : getString(ctx.strTable, ctx.strByType[type]); // @ts-ignore dump fn // deno-lint-ignore no-console - console.log(`${name}, offset: ${offset}, type: ${type}`); - offset += 1; + console.log(`${name}, idx: ${idx}, type: ${type}`); - const parent = readU32(buf, offset); - offset += 4; // @ts-ignore dump fn // deno-lint-ignore no-console - console.log(` parent: ${parent}`); - - const start = readU32(buf, offset); - offset += 4; - const end = readU32(buf, offset); - offset += 4; + console.log(` child: ${child}, next: ${next}, parent: ${parent}`); // @ts-ignore dump fn // deno-lint-ignore no-console - console.log(` range: ${start} -> ${end}`); + console.log(` range: ${range[0]}, ${range[1]}`); - const count = buf[offset++]; + const rawOffset = readRawPropOffset(ctx.buf, idx); + let propOffset = readPropOffset(ctx, idx); + const count = buf[propOffset++]; // @ts-ignore dump fn // deno-lint-ignore no-console - console.log(` prop count: ${count}`); + console.log( + ` prop count: ${count}, prop offset: ${propOffset} raw offset: ${rawOffset}`, + ); for (let i = 0; i < count; i++) { - const prop = buf[offset++]; - const kind = buf[offset++]; + const prop = buf[propOffset++]; + const kind = buf[propOffset++]; const name = getString(ctx.strTable, ctx.strByProp[prop]); let kindName = "unknown"; @@ -1051,40 +1002,36 @@ function _dump(ctx) { } } + const v = readU32(buf, propOffset); + propOffset += 4; + if (kind === PropFlags.Ref) { - const v = readU32(buf, offset); - offset += 4; // @ts-ignore dump fn // deno-lint-ignore no-console console.log(` ${name}: ${v} (${kindName}, ${prop})`); } else if (kind === PropFlags.RefArr) { - const len = readU32(buf, offset); - offset += 4; // @ts-ignore dump fn // deno-lint-ignore no-console - console.log(` ${name}: Array(${len}) (${kindName}, ${prop})`); - - for (let j = 0; j < len; j++) { - const v = readU32(buf, offset); - offset += 4; - // @ts-ignore dump fn - // deno-lint-ignore no-console - console.log(` - ${v} (${prop})`); - } + console.log(` ${name}: RefArray: ${v}, (${kindName}, ${prop})`); } else if (kind === PropFlags.Bool) { - const v = buf[offset]; - offset += 1; // @ts-ignore dump fn // deno-lint-ignore no-console console.log(` ${name}: ${v} (${kindName}, ${prop})`); } else if (kind === PropFlags.String) { - const v = readU32(buf, offset); - offset += 4; + const raw = getString(ctx.strTable, v); // @ts-ignore dump fn // deno-lint-ignore no-console - console.log( - ` ${name}: ${getString(ctx.strTable, v)} (${kindName}, ${prop})`, - ); + console.log(` ${name}: ${raw} (${kindName}, ${prop})`); + } else if (kind === PropFlags.Number) { + const raw = getString(ctx.strTable, v); + // @ts-ignore dump fn + // deno-lint-ignore no-console + console.log(` ${name}: ${raw} (${kindName}, ${prop})`); + } else if (kind === PropFlags.Regex) { + const raw = getString(ctx.strTable, v); + // @ts-ignore dump fn + // deno-lint-ignore no-console + console.log(` ${name}: ${raw} (${kindName}, ${prop})`); } else if (kind === PropFlags.Null) { // @ts-ignore dump fn // deno-lint-ignore no-console @@ -1093,8 +1040,27 @@ function _dump(ctx) { // @ts-ignore dump fn // deno-lint-ignore no-console console.log(` ${name}: undefined (${kindName}, ${prop})`); + } else if (kind === PropFlags.BigInt) { + const raw = getString(ctx.strTable, v); + // @ts-ignore dump fn + // deno-lint-ignore no-console + console.log(` ${name}: ${raw} (${kindName}, ${prop})`); + } else if (kind === PropFlags.Obj) { + let offset = v + ctx.propsOffset; + const count = readU32(ctx.buf, offset); + offset += 4; + + // @ts-ignore dump fn + // deno-lint-ignore no-console + console.log( + ` ${name}: Object (${count}) (${kindName}, ${prop}), raw offset ${v}`, + ); + + // TODO(@marvinhagemeister): Show object } } + + idx++; } } @@ -1107,9 +1073,10 @@ function _dump(ctx) { */ function runLintPlugin(plugin, fileName, sourceText) { installPlugin(plugin); - const serializedAst = op_lint_create_serialized_ast(fileName, sourceText); try { + const serializedAst = op_lint_create_serialized_ast(fileName, sourceText); + runPluginsForFile(fileName, serializedAst); } finally { // During testing we don't want to keep plugins around diff --git a/cli/js/40_lint_selector.js b/cli/js/40_lint_selector.js index c4cd523f9f..362130076a 100644 --- a/cli/js/40_lint_selector.js +++ b/cli/js/40_lint_selector.js @@ -744,8 +744,7 @@ export function compileSelector(selector) { fn = matchNthChild(node, fn); break; case PSEUDO_HAS: - // FIXME - // fn = matchIs(part, fn); + // TODO(@marvinhagemeister) throw new Error("TODO: :has"); case PSEUDO_NOT: fn = matchNot(node.selectors, fn); @@ -767,8 +766,7 @@ export function compileSelector(selector) { */ function matchFirstChild(next) { return (ctx, id) => { - const parent = ctx.getParent(id); - const first = ctx.getFirstChild(parent); + const first = ctx.getFirstChild(id); return first === id && next(ctx, first); }; } @@ -779,8 +777,7 @@ function matchFirstChild(next) { */ function matchLastChild(next) { return (ctx, id) => { - const parent = ctx.getParent(id); - const last = ctx.getLastChild(parent); + const last = ctx.getLastChild(id); return last === id && next(ctx, id); }; } @@ -955,7 +952,9 @@ function matchElem(part, next) { else if (part.elem === 0) return false; const type = ctx.getType(id); - if (type > 0 && type === part.elem) return next(ctx, id); + if (type > 0 && type === part.elem) { + return next(ctx, id); + } return false; }; @@ -968,7 +967,16 @@ function matchElem(part, next) { */ function matchAttrExists(attr, next) { return (ctx, id) => { - return ctx.hasAttrPath(id, attr.prop, 0) ? next(ctx, id) : false; + try { + ctx.getAttrPathValue(id, attr.prop, 0); + return next(ctx, id); + } catch (err) { + if (err === -1) { + return false; + } + + throw err; + } }; } @@ -979,9 +987,15 @@ function matchAttrExists(attr, next) { */ function matchAttrBin(attr, next) { return (ctx, id) => { - if (!ctx.hasAttrPath(id, attr.prop, 0)) return false; - const value = ctx.getAttrPathValue(id, attr.prop, 0); - if (!matchAttrValue(attr, value)) return false; + try { + const value = ctx.getAttrPathValue(id, attr.prop, 0); + if (!matchAttrValue(attr, value)) return false; + } catch (err) { + if (err === -1) { + return false; + } + throw err; + } return next(ctx, id); }; } diff --git a/cli/js/40_lint_types.d.ts b/cli/js/40_lint_types.d.ts index db2202981a..f07d16581e 100644 --- a/cli/js/40_lint_types.d.ts +++ b/cli/js/40_lint_types.d.ts @@ -12,6 +12,8 @@ export interface AstContext { strTableOffset: number; rootOffset: number; nodes: Map; + spansOffset: number; + propsOffset: number; strByType: number[]; strByProp: number[]; typeByStr: Map; @@ -19,6 +21,12 @@ export interface AstContext { matcher: MatchContext; } +export interface Node { + range: Range; +} + +export type Range = [number, number]; + // TODO(@marvinhagemeister) Remove once we land "official" types export interface RuleContext { id: string; @@ -121,7 +129,6 @@ export interface MatchContext { getSiblings(id: number): number[]; getParent(id: number): number; getType(id: number): number; - hasAttrPath(id: number, propIds: number[], idx: number): boolean; getAttrPathValue(id: number, propIds: number[], idx: number): unknown; } diff --git a/cli/tools/lint/ast_buffer/buffer.rs b/cli/tools/lint/ast_buffer/buffer.rs index 517c3b14dc..a884ee24f9 100644 --- a/cli/tools/lint/ast_buffer/buffer.rs +++ b/cli/tools/lint/ast_buffer/buffer.rs @@ -14,9 +14,14 @@ pub enum PropFlags { Ref, RefArr, String, + Number, Bool, Null, Undefined, + Object, + Regex, + BigInt, + Array, } impl From for u8 { @@ -33,21 +38,29 @@ impl TryFrom for PropFlags { 0 => Ok(PropFlags::Ref), 1 => Ok(PropFlags::RefArr), 2 => Ok(PropFlags::String), - 3 => Ok(PropFlags::Bool), - 4 => Ok(PropFlags::Null), - 5 => Ok(PropFlags::Undefined), + 3 => Ok(PropFlags::Number), + 4 => Ok(PropFlags::Bool), + 5 => Ok(PropFlags::Null), + 6 => Ok(PropFlags::Undefined), + 7 => Ok(PropFlags::Object), + 8 => Ok(PropFlags::Regex), + 9 => Ok(PropFlags::BigInt), + 10 => Ok(PropFlags::Array), _ => Err("Unknown Prop flag"), } } } +pub type Index = u32; + +const GROUP_KIND: u8 = 1; const MASK_U32_1: u32 = 0b11111111_00000000_00000000_00000000; const MASK_U32_2: u32 = 0b00000000_11111111_00000000_00000000; const MASK_U32_3: u32 = 0b00000000_00000000_11111111_00000000; const MASK_U32_4: u32 = 0b00000000_00000000_00000000_11111111; -// TODO: There is probably a native Rust function to do this. -pub fn append_u32(result: &mut Vec, value: u32) { +#[inline] +fn append_u32(result: &mut Vec, value: u32) { let v1: u8 = ((value & MASK_U32_1) >> 24) as u8; let v2: u8 = ((value & MASK_U32_2) >> 16) as u8; let v3: u8 = ((value & MASK_U32_3) >> 8) as u8; @@ -59,25 +72,11 @@ pub fn append_u32(result: &mut Vec, value: u32) { result.push(v4); } -pub fn append_usize(result: &mut Vec, value: usize) { +fn append_usize(result: &mut Vec, value: usize) { let raw = u32::try_from(value).unwrap(); append_u32(result, raw); } -pub fn write_usize(result: &mut [u8], value: usize, idx: usize) { - let raw = u32::try_from(value).unwrap(); - - let v1: u8 = ((raw & MASK_U32_1) >> 24) as u8; - let v2: u8 = ((raw & MASK_U32_2) >> 16) as u8; - let v3: u8 = ((raw & MASK_U32_3) >> 8) as u8; - let v4: u8 = (raw & MASK_U32_4) as u8; - - result[idx] = v1; - result[idx + 1] = v2; - result[idx + 2] = v3; - result[idx + 3] = v4; -} - #[derive(Debug)] pub struct StringTable { id: usize, @@ -119,71 +118,47 @@ impl StringTable { } #[derive(Debug, Clone, Copy, PartialEq)] -pub struct NodeRef(pub usize); - -/// Represents an offset to a node whose schema hasn't been committed yet +pub struct NodeRef(pub Index); #[derive(Debug, Clone, Copy, PartialEq)] -pub struct PendingNodeRef(pub NodeRef); +pub struct PendingRef(pub Index); -#[derive(Debug)] -pub struct BoolPos(pub usize); -#[derive(Debug)] -pub struct FieldPos(pub usize); -#[derive(Debug)] -pub struct FieldArrPos(pub usize); -#[derive(Debug)] -pub struct StrPos(pub usize); -#[derive(Debug)] -pub struct UndefPos(pub usize); -#[derive(Debug)] -pub struct NullPos(pub usize); - -#[derive(Debug)] -pub enum NodePos { - Bool(BoolPos), - #[allow(dead_code)] - Field(FieldPos), - #[allow(dead_code)] - FieldArr(FieldArrPos), - Str(StrPos), - Undef(UndefPos), - #[allow(dead_code)] - Null(NullPos), +pub trait AstBufSerializer { + fn serialize(&mut self) -> Vec; } -pub trait AstBufSerializer -where - K: Into + Display, - P: Into + Display, -{ - fn header(&mut self, kind: K, parent: NodeRef, span: &Span) - -> PendingNodeRef; - fn ref_field(&mut self, prop: P) -> FieldPos; - fn ref_vec_field(&mut self, prop: P, len: usize) -> FieldArrPos; - fn str_field(&mut self, prop: P) -> StrPos; - fn bool_field(&mut self, prop: P) -> BoolPos; - fn undefined_field(&mut self, prop: P) -> UndefPos; - #[allow(dead_code)] - fn null_field(&mut self, prop: P) -> NullPos; - fn commit_schema(&mut self, offset: PendingNodeRef) -> NodeRef; - - fn write_ref(&mut self, pos: FieldPos, value: NodeRef); - fn write_maybe_ref(&mut self, pos: FieldPos, value: Option); - fn write_refs(&mut self, pos: FieldArrPos, value: Vec); - fn write_str(&mut self, pos: StrPos, value: &str); - fn write_bool(&mut self, pos: BoolPos, value: bool); - - fn serialize(&mut self) -> Vec; +/// +/// +/// +/// +/// +#[derive(Debug)] +struct Node { + kind: u8, + prop_offset: u32, + child: u32, + next: u32, + parent: u32, } #[derive(Debug)] pub struct SerializeCtx { - buf: Vec, - start_buf: NodeRef, + root_idx: Index, + + nodes: Vec, + prop_stack: Vec>, + field_count: Vec, + field_buf: Vec, + prev_sibling_stack: Vec, + + /// Vec of spans + spans: Vec, + + /// Maps string id to the actual string str_table: StringTable, - kind_map: Vec, - prop_map: Vec, - field_count: u8, + /// Maps kind id to string id + kind_name_map: Vec, + /// Maps prop id to string id + prop_name_map: Vec, } /// This is the internal context used to allocate and fill the buffer. The point @@ -198,20 +173,24 @@ impl SerializeCtx { let kind_size = kind_len as usize; let prop_size = prop_len as usize; let mut ctx = Self { - start_buf: NodeRef(0), - buf: vec![], + spans: Vec::with_capacity(512), + root_idx: 0, + nodes: Vec::with_capacity(512), + prop_stack: vec![vec![]], + prev_sibling_stack: vec![0], + field_count: vec![0], + field_buf: Vec::with_capacity(1024), str_table: StringTable::new(), - kind_map: vec![0; kind_size], - prop_map: vec![0; prop_size], - field_count: 0, + kind_name_map: vec![0; kind_size], + prop_name_map: vec![0; prop_size], }; let empty_str = ctx.str_table.insert(""); // Placeholder node is always 0 - ctx.append_node(0, NodeRef(0), &DUMMY_SP, 0); - ctx.kind_map[0] = empty_str; - ctx.start_buf = NodeRef(ctx.buf.len()); + ctx.append_node(0, &DUMMY_SP); + ctx.kind_name_map[0] = empty_str; + ctx.kind_name_map[1] = empty_str; // Insert default props that are always present let type_str = ctx.str_table.insert("type"); @@ -220,258 +199,306 @@ impl SerializeCtx { let length_str = ctx.str_table.insert("length"); // These values are expected to be in this order on the JS side - ctx.prop_map[0] = empty_str; - ctx.prop_map[1] = type_str; - ctx.prop_map[2] = parent_str; - ctx.prop_map[3] = range_str; - ctx.prop_map[4] = length_str; + ctx.prop_name_map[0] = empty_str; + ctx.prop_name_map[1] = type_str; + ctx.prop_name_map[2] = parent_str; + ctx.prop_name_map[3] = range_str; + ctx.prop_name_map[4] = length_str; ctx } + pub fn set_root_idx(&mut self, idx: Index) { + self.root_idx = idx; + } + /// Allocate a node's header - fn field_header

(&mut self, prop: P, prop_flags: PropFlags) -> usize + fn field_header

(&mut self, prop: P, prop_flags: PropFlags) where P: Into + Display + Clone, { - self.field_count += 1; - - let offset = self.buf.len(); - + let flags: u8 = prop_flags.into(); let n: u8 = prop.clone().into(); - self.buf.push(n); - if let Some(v) = self.prop_map.get::(n.into()) { + if let Some(v) = self.prop_name_map.get::(n.into()) { if *v == 0 { let id = self.str_table.insert(&format!("{prop}")); - self.prop_map[n as usize] = id; + self.prop_name_map[n as usize] = id; } } - let flags: u8 = prop_flags.into(); - self.buf.push(flags); + // Increment field counter + let idx = self.field_count.len() - 1; + let count = self.field_count[idx]; + self.field_count[idx] = count + 1; - offset + let buf = self.prop_stack.last_mut().unwrap(); + buf.push(n); + buf.push(flags); } - /// Allocate a property pointing to another node. - fn field

(&mut self, prop: P, prop_flags: PropFlags) -> usize + fn get_node(&mut self, id: Index) -> &mut Node { + self.nodes.get_mut(id as usize).unwrap() + } + + fn set_parent(&mut self, child_id: Index, parent_id: Index) { + let child = self.get_node(child_id); + child.parent = parent_id; + } + + fn set_child(&mut self, parent_id: Index, child_id: Index) { + let parent = self.get_node(parent_id); + parent.child = child_id; + } + + fn set_next(&mut self, node_id: Index, next_id: Index) { + let node = self.get_node(node_id); + node.next = next_id; + } + + fn update_ref_links(&mut self, parent_id: Index, child_id: Index) { + let last_idx = self.prev_sibling_stack.len() - 1; + let parent = self.get_node(parent_id); + if parent.child == 0 { + parent.child = child_id; + } else { + let prev_id = self.prev_sibling_stack[last_idx]; + self.set_next(prev_id, child_id); + } + + self.prev_sibling_stack[last_idx] = child_id; + self.set_parent(child_id, parent_id); + } + + pub fn append_node(&mut self, kind: K, span: &Span) -> PendingRef where - P: Into + Display + Clone, + K: Into + Display + Clone, { - let offset = self.field_header(prop, prop_flags); - - append_usize(&mut self.buf, 0); - - offset + self.append_inner(kind, span.lo.0, span.hi.0) } - fn append_node( + pub fn append_inner( &mut self, - kind: u8, - parent: NodeRef, - span: &Span, - prop_count: usize, - ) -> PendingNodeRef { - let offset = self.buf.len(); - - // Node type fits in a u8 - self.buf.push(kind); - - // Offset to the parent node. Will be 0 if none exists - append_usize(&mut self.buf, parent.0); - - // Span, the start and end location of this node - append_u32(&mut self.buf, span.lo.0); - append_u32(&mut self.buf, span.hi.0); - - // No node has more than <10 properties - debug_assert!(prop_count < 10); - self.buf.push(prop_count as u8); - - PendingNodeRef(NodeRef(offset)) - } - - pub fn commit_schema(&mut self, node_ref: PendingNodeRef) -> NodeRef { - let mut offset = node_ref.0 .0; - - // type + parentId + span lo + span hi - offset += 1 + 4 + 4 + 4; - - self.buf[offset] = self.field_count; - self.field_count = 0; - - node_ref.0 - } - - /// Allocate the node header. It's always the same for every node. - /// - /// - /// - /// - /// (There is no node with more than 10 properties) - pub fn header( - &mut self, - kind: N, - parent: NodeRef, - span: &Span, - ) -> PendingNodeRef + kind: K, + span_lo: u32, + span_hi: u32, + ) -> PendingRef where - N: Into + Display + Clone, + K: Into + Display + Clone, { - let n: u8 = kind.clone().into(); + let kind_u8: u8 = kind.clone().into(); - if let Some(v) = self.kind_map.get::(n.into()) { + let id: Index = self.nodes.len() as u32; + + self.nodes.push(Node { + kind: kind_u8, + prop_offset: 0, + child: 0, + next: 0, + parent: 0, + }); + + if let Some(v) = self.kind_name_map.get::(kind_u8.into()) { if *v == 0 { - let id = self.str_table.insert(&format!("{kind}")); - self.kind_map[n as usize] = id; + let s_id = self.str_table.insert(&format!("{kind}")); + self.kind_name_map[kind_u8 as usize] = s_id; } } - // Prop count will be filled with the actual value when the - // schema is committed. - self.append_node(n, parent, span, 0) + self.field_count.push(0); + self.prop_stack.push(vec![]); + self.prev_sibling_stack.push(0); + + // write spans + self.spans.push(span_lo); + self.spans.push(span_hi); + + PendingRef(id) } - /// Allocate a reference property that will hold the offset of - /// another node. - pub fn ref_field

(&mut self, prop: P) -> usize + pub fn commit_node(&mut self, id: PendingRef) -> NodeRef { + let mut buf = self.prop_stack.pop().unwrap(); + let count = self.field_count.pop().unwrap(); + let offset = self.field_buf.len(); + + // All nodes have <10 fields + self.field_buf.push(count as u8); + self.field_buf.append(&mut buf); + + let node = self.nodes.get_mut(id.0 as usize).unwrap(); + node.prop_offset = offset as u32; + + self.prev_sibling_stack.pop(); + + NodeRef(id.0) + } + + // Allocate an object field + pub fn open_obj(&mut self) { + self.field_count.push(0); + self.prop_stack.push(vec![]); + } + + pub fn commit_obj

(&mut self, prop: P) where P: Into + Display + Clone, { - self.field(prop, PropFlags::Ref) + let mut buf = self.prop_stack.pop().unwrap(); + let count = self.field_count.pop().unwrap(); + let offset = self.field_buf.len(); + append_usize(&mut self.field_buf, count); + self.field_buf.append(&mut buf); + + self.field_header(prop, PropFlags::Object); + let buf = self.prop_stack.last_mut().unwrap(); + append_usize(buf, offset); } - /// Allocate a property that is a vec of node offsets pointing to other - /// nodes. - pub fn ref_vec_field

(&mut self, prop: P, len: usize) -> usize + /// Allocate an null field + pub fn write_null

(&mut self, prop: P) where P: Into + Display + Clone, { - let offset = self.field(prop, PropFlags::RefArr); + self.field_header(prop, PropFlags::Null); - for _ in 0..len { - append_u32(&mut self.buf, 0); - } - - offset + let buf = self.prop_stack.last_mut().unwrap(); + append_u32(buf, 0); } - // Allocate a property representing a string. Strings are deduplicated - // in the message and the property will only contain the string id. - pub fn str_field

(&mut self, prop: P) -> usize + /// Allocate an null field + pub fn write_undefined

(&mut self, prop: P) where P: Into + Display + Clone, { - self.field(prop, PropFlags::String) + self.field_header(prop, PropFlags::Undefined); + + let buf = self.prop_stack.last_mut().unwrap(); + append_u32(buf, 0); } - /// Allocate a bool field - pub fn bool_field

(&mut self, prop: P) -> usize + /// Allocate a number field + pub fn write_num

(&mut self, prop: P, value: &str) where P: Into + Display + Clone, { - let offset = self.field_header(prop, PropFlags::Bool); - self.buf.push(0); - offset + self.field_header(prop, PropFlags::Number); + + let id = self.str_table.insert(value); + let buf = self.prop_stack.last_mut().unwrap(); + append_usize(buf, id); } - /// Allocate an undefined field - pub fn undefined_field

(&mut self, prop: P) -> usize + /// Allocate a bigint field + pub fn write_bigint

(&mut self, prop: P, value: &str) where P: Into + Display + Clone, { - self.field_header(prop, PropFlags::Undefined) + self.field_header(prop, PropFlags::BigInt); + + let id = self.str_table.insert(value); + let buf = self.prop_stack.last_mut().unwrap(); + append_usize(buf, id); } - /// Allocate an undefined field - #[allow(dead_code)] - pub fn null_field

(&mut self, prop: P) -> usize + /// Allocate a RegExp field + pub fn write_regex

(&mut self, prop: P, value: &str) where P: Into + Display + Clone, { - self.field_header(prop, PropFlags::Null) - } + self.field_header(prop, PropFlags::Regex); - /// Replace the placeholder of a reference field with the actual offset - /// to the node we want to point to. - pub fn write_ref(&mut self, field_offset: usize, value: NodeRef) { - #[cfg(debug_assertions)] - { - let value_kind = self.buf[field_offset + 1]; - if PropFlags::try_from(value_kind).unwrap() != PropFlags::Ref { - panic!("Trying to write a ref into a non-ref field") - } - } - - write_usize(&mut self.buf, value.0, field_offset + 2); - } - - /// Helper for writing optional node offsets - pub fn write_maybe_ref( - &mut self, - field_offset: usize, - value: Option, - ) { - #[cfg(debug_assertions)] - { - let value_kind = self.buf[field_offset + 1]; - if PropFlags::try_from(value_kind).unwrap() != PropFlags::Ref { - panic!("Trying to write a ref into a non-ref field") - } - } - - let ref_value = if let Some(v) = value { v } else { NodeRef(0) }; - write_usize(&mut self.buf, ref_value.0, field_offset + 2); - } - - /// Write a vec of node offsets into the property. The necessary space - /// has been reserved earlier. - pub fn write_refs(&mut self, field_offset: usize, value: Vec) { - #[cfg(debug_assertions)] - { - let value_kind = self.buf[field_offset + 1]; - if PropFlags::try_from(value_kind).unwrap() != PropFlags::RefArr { - panic!("Trying to write a ref into a non-ref array field") - } - } - - let mut offset = field_offset + 2; - write_usize(&mut self.buf, value.len(), offset); - offset += 4; - - for item in value { - write_usize(&mut self.buf, item.0, offset); - offset += 4; - } + let id = self.str_table.insert(value); + let buf = self.prop_stack.last_mut().unwrap(); + append_usize(buf, id); } /// Store the string in our string table and save the id of the string /// in the current field. - pub fn write_str(&mut self, field_offset: usize, value: &str) { - #[cfg(debug_assertions)] - { - let value_kind = self.buf[field_offset + 1]; - if PropFlags::try_from(value_kind).unwrap() != PropFlags::String { - panic!("Trying to write a ref into a non-string field") - } - } + pub fn write_str

(&mut self, prop: P, value: &str) + where + P: Into + Display + Clone, + { + self.field_header(prop, PropFlags::String); let id = self.str_table.insert(value); - write_usize(&mut self.buf, id, field_offset + 2); + let buf = self.prop_stack.last_mut().unwrap(); + append_usize(buf, id); } /// Write a bool to a field. - pub fn write_bool(&mut self, field_offset: usize, value: bool) { - #[cfg(debug_assertions)] - { - let value_kind = self.buf[field_offset + 1]; - if PropFlags::try_from(value_kind).unwrap() != PropFlags::Bool { - panic!("Trying to write a ref into a non-bool field") - } - } + pub fn write_bool

(&mut self, prop: P, value: bool) + where + P: Into + Display + Clone, + { + self.field_header(prop, PropFlags::Bool); - self.buf[field_offset + 2] = if value { 1 } else { 0 }; + let n = if value { 1 } else { 0 }; + let buf = self.prop_stack.last_mut().unwrap(); + append_u32(buf, n); + } + + /// Replace the placeholder of a reference field with the actual offset + /// to the node we want to point to. + pub fn write_ref

(&mut self, prop: P, parent: &PendingRef, value: NodeRef) + where + P: Into + Display + Clone, + { + self.field_header(prop, PropFlags::Ref); + let buf = self.prop_stack.last_mut().unwrap(); + append_u32(buf, value.0); + + if parent.0 > 0 { + self.update_ref_links(parent.0, value.0); + } + } + + /// Helper for writing optional node offsets + pub fn write_maybe_ref

( + &mut self, + prop: P, + parent: &PendingRef, + value: Option, + ) where + P: Into + Display + Clone, + { + if let Some(v) = value { + self.write_ref(prop, parent, v); + } else { + self.write_null(prop); + }; + } + + /// Write a vec of node offsets into the property. The necessary space + /// has been reserved earlier. + pub fn write_ref_vec

( + &mut self, + prop: P, + parent_ref: &PendingRef, + value: Vec, + ) where + P: Into + Display + Clone, + { + self.field_header(prop, PropFlags::RefArr); + let group_id = self.append_node(GROUP_KIND, &DUMMY_SP); + let group_id = self.commit_node(group_id).0; + + let buf = self.prop_stack.last_mut().unwrap(); + append_u32(buf, group_id); + + self.update_ref_links(parent_ref.0, group_id); + + let mut prev_id = 0; + for (i, item) in value.iter().enumerate() { + self.set_parent(item.0, group_id); + + if i == 0 { + self.set_child(group_id, item.0); + } else { + self.set_next(prev_id, item.0); + } + + prev_id = item.0; + } } /// Serialize all information we have into a buffer that can be sent to JS. @@ -481,6 +508,8 @@ impl SerializeCtx { /// /// <- node kind id maps to string id /// <- node property id maps to string id + /// <- List of spans, rarely needed + /// /// /// /// @@ -490,7 +519,13 @@ impl SerializeCtx { // The buffer starts with the serialized AST first, because that // contains absolute offsets. By butting this at the start of the // message we don't have to waste time updating any offsets. - buf.append(&mut self.buf); + for node in &self.nodes { + buf.push(node.kind); + append_u32(&mut buf, node.prop_offset); + append_u32(&mut buf, node.child); + append_u32(&mut buf, node.next); + append_u32(&mut buf, node.parent); + } // Next follows the string table. We'll keep track of the offset // in the message of where the string table begins @@ -507,8 +542,8 @@ impl SerializeCtx { // Write the total number of entries in the kind -> str mapping table // TODO: make this a u8 - append_usize(&mut buf, self.kind_map.len()); - for v in &self.kind_map { + append_usize(&mut buf, self.kind_name_map.len()); + for v in &self.kind_name_map { append_usize(&mut buf, *v); } @@ -517,19 +552,35 @@ impl SerializeCtx { // as u8. let offset_prop_map = buf.len(); // Write the total number of entries in the kind -> str mapping table - append_usize(&mut buf, self.prop_map.len()); - for v in &self.prop_map { + append_usize(&mut buf, self.prop_name_map.len()); + for v in &self.prop_name_map { append_usize(&mut buf, *v); } + // Spans are rarely needed, so they're stored in a separate array. + // They're indexed by the node id. + let offset_spans = buf.len(); + for v in &self.spans { + append_u32(&mut buf, *v); + } + + // The field value table. They're detached from nodes as they're not + // as frequently needed as the nodes themselves. The most common + // operation is traversal and we can traverse nodes without knowing + // about the fields. + let offset_props = buf.len(); + buf.append(&mut self.field_buf); + // Putting offsets of relevant parts of the buffer at the end. This // allows us to hop to the relevant part by merely looking at the last // for values in the message. Each value represents an offset into the // buffer. + append_usize(&mut buf, offset_props); + append_usize(&mut buf, offset_spans); append_usize(&mut buf, offset_kind_map); append_usize(&mut buf, offset_prop_map); append_usize(&mut buf, offset_str_table); - append_usize(&mut buf, self.start_buf.0); + append_u32(&mut buf, self.root_idx); buf } diff --git a/cli/tools/lint/ast_buffer/swc.rs b/cli/tools/lint/ast_buffer/swc.rs index 7652756c9b..925d1bcd17 100644 --- a/cli/tools/lint/ast_buffer/swc.rs +++ b/cli/tools/lint/ast_buffer/swc.rs @@ -2,10 +2,13 @@ use deno_ast::swc::ast::AssignTarget; use deno_ast::swc::ast::AssignTargetPat; +use deno_ast::swc::ast::BindingIdent; use deno_ast::swc::ast::BlockStmtOrExpr; use deno_ast::swc::ast::Callee; use deno_ast::swc::ast::ClassMember; use deno_ast::swc::ast::Decl; +use deno_ast::swc::ast::Decorator; +use deno_ast::swc::ast::DefaultDecl; use deno_ast::swc::ast::ExportSpecifier; use deno_ast::swc::ast::Expr; use deno_ast::swc::ast::ExprOrSpread; @@ -14,13 +17,13 @@ use deno_ast::swc::ast::ForHead; use deno_ast::swc::ast::Function; use deno_ast::swc::ast::Ident; use deno_ast::swc::ast::IdentName; +use deno_ast::swc::ast::ImportSpecifier; use deno_ast::swc::ast::JSXAttrName; use deno_ast::swc::ast::JSXAttrOrSpread; use deno_ast::swc::ast::JSXAttrValue; use deno_ast::swc::ast::JSXElement; use deno_ast::swc::ast::JSXElementChild; use deno_ast::swc::ast::JSXElementName; -use deno_ast::swc::ast::JSXEmptyExpr; use deno_ast::swc::ast::JSXExpr; use deno_ast::swc::ast::JSXExprContainer; use deno_ast::swc::ast::JSXFragment; @@ -28,12 +31,14 @@ use deno_ast::swc::ast::JSXMemberExpr; use deno_ast::swc::ast::JSXNamespacedName; use deno_ast::swc::ast::JSXObject; use deno_ast::swc::ast::JSXOpeningElement; +use deno_ast::swc::ast::Key; use deno_ast::swc::ast::Lit; use deno_ast::swc::ast::MemberExpr; use deno_ast::swc::ast::MemberProp; use deno_ast::swc::ast::ModuleDecl; use deno_ast::swc::ast::ModuleExportName; use deno_ast::swc::ast::ModuleItem; +use deno_ast::swc::ast::ObjectLit; use deno_ast::swc::ast::ObjectPatProp; use deno_ast::swc::ast::OptChainBase; use deno_ast::swc::ast::Param; @@ -47,14 +52,18 @@ use deno_ast::swc::ast::PropOrSpread; use deno_ast::swc::ast::SimpleAssignTarget; use deno_ast::swc::ast::Stmt; use deno_ast::swc::ast::SuperProp; -use deno_ast::swc::ast::Tpl; use deno_ast::swc::ast::TsEntityName; use deno_ast::swc::ast::TsEnumMemberId; +use deno_ast::swc::ast::TsExprWithTypeArgs; use deno_ast::swc::ast::TsFnOrConstructorType; use deno_ast::swc::ast::TsFnParam; use deno_ast::swc::ast::TsIndexSignature; use deno_ast::swc::ast::TsLit; use deno_ast::swc::ast::TsLitType; +use deno_ast::swc::ast::TsModuleName; +use deno_ast::swc::ast::TsModuleRef; +use deno_ast::swc::ast::TsNamespaceBody; +use deno_ast::swc::ast::TsParamPropParam; use deno_ast::swc::ast::TsThisTypeOrIdent; use deno_ast::swc::ast::TsType; use deno_ast::swc::ast::TsTypeAnn; @@ -71,7 +80,7 @@ use deno_ast::swc::common::SyntaxContext; use deno_ast::view::Accessibility; use deno_ast::view::AssignOp; use deno_ast::view::BinaryOp; -use deno_ast::view::TruePlusMinus; +use deno_ast::view::MethodKind; use deno_ast::view::TsKeywordTypeKind; use deno_ast::view::TsTypeOperatorOp; use deno_ast::view::UnaryOp; @@ -80,53 +89,39 @@ use deno_ast::view::VarDeclKind; use deno_ast::ParsedSource; use super::buffer::AstBufSerializer; -use super::buffer::BoolPos; -use super::buffer::NodePos; use super::buffer::NodeRef; -use super::buffer::StrPos; use super::ts_estree::AstNode; -use super::ts_estree::AstProp; use super::ts_estree::TsEsTreeBuilder; +use super::ts_estree::TsKeywordKind; pub fn serialize_swc_to_buffer(parsed_source: &ParsedSource) -> Vec { let mut ctx = TsEsTreeBuilder::new(); let program = &parsed_source.program(); - let raw = ctx.header(AstNode::Program, NodeRef(0), &program.span()); - let source_type_pos = ctx.str_field(AstProp::SourceType); - match program.as_ref() { Program::Module(module) => { - let body_pos = ctx.ref_vec_field(AstProp::Body, module.body.len()); - let pos = ctx.commit_schema(raw); - let children = module .body .iter() .map(|item| match item { ModuleItem::ModuleDecl(module_decl) => { - serialize_module_decl(&mut ctx, module_decl, pos) + serialize_module_decl(&mut ctx, module_decl) } - ModuleItem::Stmt(stmt) => serialize_stmt(&mut ctx, stmt, pos), + ModuleItem::Stmt(stmt) => serialize_stmt(&mut ctx, stmt), }) .collect::>(); - ctx.write_str(source_type_pos, "module"); - ctx.write_refs(body_pos, children); + ctx.write_program(&module.span, "module", children); } Program::Script(script) => { - let body_pos = ctx.ref_vec_field(AstProp::Body, script.body.len()); - let pos = ctx.commit_schema(raw); - let children = script .body .iter() - .map(|stmt| serialize_stmt(&mut ctx, stmt, pos)) + .map(|stmt| serialize_stmt(&mut ctx, stmt)) .collect::>(); - ctx.write_str(source_type_pos, "script"); - ctx.write_refs(body_pos, children); + ctx.write_program(&script.span, "script", children); } } @@ -136,539 +131,521 @@ pub fn serialize_swc_to_buffer(parsed_source: &ParsedSource) -> Vec { fn serialize_module_decl( ctx: &mut TsEsTreeBuilder, module_decl: &ModuleDecl, - parent: NodeRef, ) -> NodeRef { match module_decl { ModuleDecl::Import(node) => { - let raw = ctx.header(AstNode::ImportExpression, parent, &node.span); - ctx.commit_schema(raw) - } - ModuleDecl::ExportDecl(node) => { - let raw = ctx.header(AstNode::ExportNamedDeclaration, parent, &node.span); - let decl_pos = ctx.ref_field(AstProp::Declarations); - let pos = ctx.commit_schema(raw); + let src = serialize_lit(ctx, &Lit::Str(node.src.as_ref().clone())); + let attrs = serialize_import_attrs(ctx, &node.with); - let decl = serialize_decl(ctx, &node.decl, pos); - - ctx.write_ref(decl_pos, decl); - - pos - } - ModuleDecl::ExportNamed(node) => { - let raw = ctx.header(AstNode::ExportNamedDeclaration, parent, &node.span); - let src_pos = ctx.ref_field(AstProp::Source); - let spec_pos = - ctx.ref_vec_field(AstProp::Specifiers, node.specifiers.len()); - let id = ctx.commit_schema(raw); - - // FIXME: Flags - // let mut flags = FlagValue::new(); - // flags.set(Flag::ExportType); - - let src_id = node - .src - .as_ref() - .map(|src| serialize_lit(ctx, &Lit::Str(*src.clone()), id)); - - let spec_ids = node + let specifiers = node .specifiers .iter() - .map(|spec| { - match spec { - ExportSpecifier::Named(child) => { - let raw = ctx.header(AstNode::ExportSpecifier, id, &child.span); - let local_pos = ctx.ref_field(AstProp::Local); - let exp_pos = ctx.ref_field(AstProp::Exported); - let spec_pos = ctx.commit_schema(raw); - - // let mut flags = FlagValue::new(); - // flags.set(Flag::ExportType); - - let local = - serialize_module_exported_name(ctx, &child.orig, spec_pos); - - let exported = child.exported.as_ref().map(|exported| { - serialize_module_exported_name(ctx, exported, spec_pos) + .map(|spec| match spec { + ImportSpecifier::Named(spec) => { + let local = serialize_ident(ctx, &spec.local, None); + let imported = spec + .imported + .as_ref() + .map_or(serialize_ident(ctx, &spec.local, None), |v| { + serialize_module_export_name(ctx, v) }); - - // ctx.write_flags(&flags); - ctx.write_ref(local_pos, local); - ctx.write_maybe_ref(exp_pos, exported); - - spec_pos - } - - // These two aren't syntactically valid - ExportSpecifier::Namespace(_) => todo!(), - ExportSpecifier::Default(_) => todo!(), + ctx.write_import_spec( + &spec.span, + spec.is_type_only, + local, + imported, + ) + } + ImportSpecifier::Default(spec) => { + let local = serialize_ident(ctx, &spec.local, None); + ctx.write_import_default_spec(&spec.span, local) + } + ImportSpecifier::Namespace(spec) => { + let local = serialize_ident(ctx, &spec.local, None); + ctx.write_import_ns_spec(&spec.span, local) } }) .collect::>(); - // ctx.write_flags(&flags); - ctx.write_maybe_ref(src_pos, src_id); - ctx.write_refs(spec_pos, spec_ids); + ctx.write_import_decl(&node.span, node.type_only, src, specifiers, attrs) + } + ModuleDecl::ExportDecl(node) => { + let decl = serialize_decl(ctx, &node.decl); + ctx.write_export_decl(&node.span, decl) + } + ModuleDecl::ExportNamed(node) => { + let attrs = serialize_import_attrs(ctx, &node.with); + let source = node + .src + .as_ref() + .map(|src| serialize_lit(ctx, &Lit::Str(*src.clone()))); - id + if let Some(ExportSpecifier::Namespace(ns)) = node.specifiers.first() { + let exported = serialize_module_export_name(ctx, &ns.name); + ctx.write_export_all_decl( + &node.span, + node.type_only, + exported, + source, + attrs, + ) + } else { + let specifiers = node + .specifiers + .iter() + .map(|spec| { + match spec { + ExportSpecifier::Named(spec) => { + let local = serialize_module_export_name(ctx, &spec.orig); + + let exported = spec.exported.as_ref().map_or( + serialize_module_export_name(ctx, &spec.orig), + |exported| serialize_module_export_name(ctx, exported), + ); + + ctx.write_export_spec( + &spec.span, + spec.is_type_only, + local, + exported, + ) + } + + // Already handled earlier + ExportSpecifier::Namespace(_) => unreachable!(), + // this is not syntactically valid + ExportSpecifier::Default(_) => unreachable!(), + } + }) + .collect::>(); + + ctx.write_export_named_decl(&node.span, specifiers, source, attrs) + } } ModuleDecl::ExportDefaultDecl(node) => { - let raw = - ctx.header(AstNode::ExportDefaultDeclaration, parent, &node.span); - ctx.commit_schema(raw) + let (is_type_only, decl) = match &node.decl { + DefaultDecl::Class(node) => { + let ident = node + .ident + .as_ref() + .map(|ident| serialize_ident(ctx, ident, None)); + + let super_class = node + .class + .super_class + .as_ref() + .map(|expr| serialize_expr(ctx, expr.as_ref())); + + let implements = node + .class + .implements + .iter() + .map(|item| serialize_ts_expr_with_type_args(ctx, item)) + .collect::>(); + + let members = node + .class + .body + .iter() + .filter_map(|member| serialize_class_member(ctx, member)) + .collect::>(); + + let body = ctx.write_class_body(&node.class.span, members); + + let decl = ctx.write_class_decl( + &node.class.span, + false, + node.class.is_abstract, + ident, + super_class, + implements, + body, + ); + + (false, decl) + } + DefaultDecl::Fn(node) => { + let ident = node + .ident + .as_ref() + .map(|ident| serialize_ident(ctx, ident, None)); + + let fn_obj = node.function.as_ref(); + + let type_params = + maybe_serialize_ts_type_param_decl(ctx, &fn_obj.type_params); + + let params = fn_obj + .params + .iter() + .map(|param| serialize_pat(ctx, ¶m.pat)) + .collect::>(); + + let return_type = + maybe_serialize_ts_type_ann(ctx, &fn_obj.return_type); + let body = fn_obj + .body + .as_ref() + .map(|block| serialize_stmt(ctx, &Stmt::Block(block.clone()))); + + let decl = ctx.write_fn_decl( + &fn_obj.span, + false, + fn_obj.is_async, + fn_obj.is_generator, + ident, + type_params, + return_type, + body, + params, + ); + + (false, decl) + } + DefaultDecl::TsInterfaceDecl(node) => { + let ident_id = serialize_ident(ctx, &node.id, None); + let type_param = + maybe_serialize_ts_type_param_decl(ctx, &node.type_params); + + let extend_ids = node + .extends + .iter() + .map(|item| { + let expr = serialize_expr(ctx, &item.expr); + let type_args = item + .type_args + .clone() + .map(|params| serialize_ts_param_inst(ctx, params.as_ref())); + + ctx.write_ts_interface_heritage(&item.span, expr, type_args) + }) + .collect::>(); + + let body_elem_ids = node + .body + .body + .iter() + .map(|item| serialize_ts_type_elem(ctx, item)) + .collect::>(); + + let body_pos = + ctx.write_ts_interface_body(&node.body.span, body_elem_ids); + + let decl = ctx.write_ts_interface_decl( + &node.span, + node.declare, + ident_id, + type_param, + extend_ids, + body_pos, + ); + + (true, decl) + } + }; + + ctx.write_export_default_decl(&node.span, is_type_only, decl) } ModuleDecl::ExportDefaultExpr(node) => { - let raw = - ctx.header(AstNode::ExportDefaultDeclaration, parent, &node.span); - ctx.commit_schema(raw) + let expr = serialize_expr(ctx, &node.expr); + ctx.write_export_default_decl(&node.span, false, expr) } ModuleDecl::ExportAll(node) => { - let raw = ctx.header(AstNode::ExportAllDeclaration, parent, &node.span); - ctx.commit_schema(raw) + let src = serialize_lit(ctx, &Lit::Str(node.src.as_ref().clone())); + let attrs = serialize_import_attrs(ctx, &node.with); + + ctx.write_export_all_decl(&node.span, node.type_only, src, None, attrs) } ModuleDecl::TsImportEquals(node) => { - let raw = ctx.header(AstNode::TsImportEquals, parent, &node.span); - ctx.commit_schema(raw) + let ident = serialize_ident(ctx, &node.id, None); + let module_ref = match &node.module_ref { + TsModuleRef::TsEntityName(entity) => { + serialize_ts_entity_name(ctx, entity) + } + TsModuleRef::TsExternalModuleRef(external) => { + let expr = serialize_lit(ctx, &Lit::Str(external.expr.clone())); + ctx.write_ts_external_mod_ref(&external.span, expr) + } + }; + + ctx.write_export_ts_import_equals( + &node.span, + node.is_type_only, + ident, + module_ref, + ) } ModuleDecl::TsExportAssignment(node) => { - let raw = ctx.header(AstNode::TsExportAssignment, parent, &node.span); - ctx.commit_schema(raw) + let expr = serialize_expr(ctx, &node.expr); + ctx.write_export_assign(&node.span, expr) } ModuleDecl::TsNamespaceExport(node) => { - let raw = ctx.header(AstNode::TsNamespaceExport, parent, &node.span); - ctx.commit_schema(raw) + let decl = serialize_ident(ctx, &node.id, None); + ctx.write_export_ts_namespace(&node.span, decl) } } } -fn serialize_stmt( +fn serialize_import_attrs( ctx: &mut TsEsTreeBuilder, - stmt: &Stmt, - parent: NodeRef, -) -> NodeRef { + raw_attrs: &Option>, +) -> Vec { + raw_attrs.as_ref().map_or(vec![], |obj| { + obj + .props + .iter() + .map(|prop| { + let (key, value) = match prop { + // Invalid syntax + PropOrSpread::Spread(_) => unreachable!(), + PropOrSpread::Prop(prop) => { + match prop.as_ref() { + Prop::Shorthand(ident) => ( + serialize_ident(ctx, ident, None), + serialize_ident(ctx, ident, None), + ), + Prop::KeyValue(kv) => ( + serialize_prop_name(ctx, &kv.key), + serialize_expr(ctx, kv.value.as_ref()), + ), + // Invalid syntax + Prop::Assign(_) + | Prop::Getter(_) + | Prop::Setter(_) + | Prop::Method(_) => unreachable!(), + } + } + }; + + ctx.write_import_attr(&prop.span(), key, value) + }) + .collect::>() + }) +} + +fn serialize_stmt(ctx: &mut TsEsTreeBuilder, stmt: &Stmt) -> NodeRef { match stmt { Stmt::Block(node) => { - let raw = ctx.header(AstNode::BlockStatement, parent, &node.span); - let body_pos = ctx.ref_vec_field(AstProp::Body, node.stmts.len()); - let pos = ctx.commit_schema(raw); - let children = node .stmts .iter() - .map(|stmt| serialize_stmt(ctx, stmt, pos)) + .map(|stmt| serialize_stmt(ctx, stmt)) .collect::>(); - ctx.write_refs(body_pos, children); - - pos + ctx.write_block_stmt(&node.span, children) } Stmt::Empty(_) => NodeRef(0), - Stmt::Debugger(node) => { - let raw = ctx.header(AstNode::DebuggerStatement, parent, &node.span); - ctx.commit_schema(raw) + Stmt::Debugger(node) => ctx.write_debugger_stmt(&node.span), + Stmt::With(node) => { + let obj = serialize_expr(ctx, &node.obj); + let body = serialize_stmt(ctx, &node.body); + + ctx.write_with_stmt(&node.span, obj, body) } - Stmt::With(_) => todo!(), Stmt::Return(node) => { - let raw = ctx.header(AstNode::ReturnStatement, parent, &node.span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); - - let arg = node.arg.as_ref().map(|arg| serialize_expr(ctx, arg, pos)); - ctx.write_maybe_ref(arg_pos, arg); - - pos + let arg = node.arg.as_ref().map(|arg| serialize_expr(ctx, arg)); + ctx.write_return_stmt(&node.span, arg) } Stmt::Labeled(node) => { - let raw = ctx.header(AstNode::LabeledStatement, parent, &node.span); - let label_pos = ctx.ref_field(AstProp::Label); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); + let ident = serialize_ident(ctx, &node.label, None); + let stmt = serialize_stmt(ctx, &node.body); - let ident = serialize_ident(ctx, &node.label, pos); - let stmt = serialize_stmt(ctx, &node.body, pos); - - ctx.write_ref(label_pos, ident); - ctx.write_ref(body_pos, stmt); - - pos + ctx.write_labeled_stmt(&node.span, ident, stmt) } Stmt::Break(node) => { - let raw = ctx.header(AstNode::BreakStatement, parent, &node.span); - let label_pos = ctx.ref_field(AstProp::Label); - let pos = ctx.commit_schema(raw); - let arg = node .label .as_ref() - .map(|label| serialize_ident(ctx, label, pos)); - - ctx.write_maybe_ref(label_pos, arg); - - pos + .map(|label| serialize_ident(ctx, label, None)); + ctx.write_break_stmt(&node.span, arg) } Stmt::Continue(node) => { - let raw = ctx.header(AstNode::ContinueStatement, parent, &node.span); - let label_pos = ctx.ref_field(AstProp::Label); - let pos = ctx.commit_schema(raw); - let arg = node .label .as_ref() - .map(|label| serialize_ident(ctx, label, pos)); + .map(|label| serialize_ident(ctx, label, None)); - ctx.write_maybe_ref(label_pos, arg); - - pos + ctx.write_continue_stmt(&node.span, arg) } Stmt::If(node) => { - let raw = ctx.header(AstNode::IfStatement, parent, &node.span); - let test_pos = ctx.ref_field(AstProp::Test); - let cons_pos = ctx.ref_field(AstProp::Consequent); - let alt_pos = ctx.ref_field(AstProp::Alternate); - let pos = ctx.commit_schema(raw); + let test = serialize_expr(ctx, node.test.as_ref()); + let cons = serialize_stmt(ctx, node.cons.as_ref()); + let alt = node.alt.as_ref().map(|alt| serialize_stmt(ctx, alt)); - let test = serialize_expr(ctx, node.test.as_ref(), pos); - let cons = serialize_stmt(ctx, node.cons.as_ref(), pos); - let alt = node.alt.as_ref().map(|alt| serialize_stmt(ctx, alt, pos)); - - ctx.write_ref(test_pos, test); - ctx.write_ref(cons_pos, cons); - ctx.write_maybe_ref(alt_pos, alt); - - pos + ctx.write_if_stmt(&node.span, test, cons, alt) } Stmt::Switch(node) => { - let raw = ctx.header(AstNode::SwitchStatement, parent, &node.span); - let disc_pos = ctx.ref_field(AstProp::Discriminant); - let cases_pos = ctx.ref_vec_field(AstProp::Cases, node.cases.len()); - let pos = ctx.commit_schema(raw); - - let disc = serialize_expr(ctx, &node.discriminant, pos); + let disc = serialize_expr(ctx, &node.discriminant); let cases = node .cases .iter() .map(|case| { - let raw = ctx.header(AstNode::SwitchCase, pos, &case.span); - let test_pos = ctx.ref_field(AstProp::Test); - let cons_pos = - ctx.ref_vec_field(AstProp::Consequent, case.cons.len()); - let case_pos = ctx.commit_schema(raw); - - let test = case - .test - .as_ref() - .map(|test| serialize_expr(ctx, test, case_pos)); + let test = case.test.as_ref().map(|test| serialize_expr(ctx, test)); let cons = case .cons .iter() - .map(|cons| serialize_stmt(ctx, cons, case_pos)) + .map(|cons| serialize_stmt(ctx, cons)) .collect::>(); - ctx.write_maybe_ref(test_pos, test); - ctx.write_refs(cons_pos, cons); - - case_pos + ctx.write_switch_case(&case.span, test, cons) }) .collect::>(); - ctx.write_ref(disc_pos, disc); - ctx.write_refs(cases_pos, cases); - - pos + ctx.write_switch_stmt(&node.span, disc, cases) } Stmt::Throw(node) => { - let raw = ctx.header(AstNode::ThrowStatement, parent, &node.span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); - - let arg = serialize_expr(ctx, &node.arg, pos); - ctx.write_ref(arg_pos, arg); - - pos + let arg = serialize_expr(ctx, &node.arg); + ctx.write_throw_stmt(&node.span, arg) } Stmt::Try(node) => { - let raw = ctx.header(AstNode::TryStatement, parent, &node.span); - let block_pos = ctx.ref_field(AstProp::Block); - let handler_pos = ctx.ref_field(AstProp::Handler); - let finalizer_pos = ctx.ref_field(AstProp::Finalizer); - let pos = ctx.commit_schema(raw); - - let block = serialize_stmt(ctx, &Stmt::Block(node.block.clone()), pos); + let block = serialize_stmt(ctx, &Stmt::Block(node.block.clone())); let handler = node.handler.as_ref().map(|catch| { - let raw = ctx.header(AstNode::CatchClause, pos, &catch.span); - let param_pos = ctx.ref_field(AstProp::Param); - let body_pos = ctx.ref_field(AstProp::Body); - let clause_pos = ctx.commit_schema(raw); + let param = catch.param.as_ref().map(|param| serialize_pat(ctx, param)); - let param = catch - .param - .as_ref() - .map(|param| serialize_pat(ctx, param, clause_pos)); + let body = serialize_stmt(ctx, &Stmt::Block(catch.body.clone())); - let body = - serialize_stmt(ctx, &Stmt::Block(catch.body.clone()), clause_pos); - - ctx.write_maybe_ref(param_pos, param); - ctx.write_ref(body_pos, body); - - clause_pos + ctx.write_catch_clause(&catch.span, param, body) }); - let finalizer = node.finalizer.as_ref().map(|finalizer| { - serialize_stmt(ctx, &Stmt::Block(finalizer.clone()), pos) - }); + let finalizer = node + .finalizer + .as_ref() + .map(|finalizer| serialize_stmt(ctx, &Stmt::Block(finalizer.clone()))); - ctx.write_ref(block_pos, block); - ctx.write_maybe_ref(handler_pos, handler); - ctx.write_maybe_ref(finalizer_pos, finalizer); - - pos + ctx.write_try_stmt(&node.span, block, handler, finalizer) } Stmt::While(node) => { - let raw = ctx.header(AstNode::WhileStatement, parent, &node.span); - let test_pos = ctx.ref_field(AstProp::Test); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); + let test = serialize_expr(ctx, node.test.as_ref()); + let stmt = serialize_stmt(ctx, node.body.as_ref()); - let test = serialize_expr(ctx, node.test.as_ref(), pos); - let stmt = serialize_stmt(ctx, node.body.as_ref(), pos); - - ctx.write_ref(test_pos, test); - ctx.write_ref(body_pos, stmt); - - pos + ctx.write_while_stmt(&node.span, test, stmt) } Stmt::DoWhile(node) => { - let raw = ctx.header(AstNode::DoWhileStatement, parent, &node.span); - let test_pos = ctx.ref_field(AstProp::Test); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); + let expr = serialize_expr(ctx, node.test.as_ref()); + let stmt = serialize_stmt(ctx, node.body.as_ref()); - let expr = serialize_expr(ctx, node.test.as_ref(), pos); - let stmt = serialize_stmt(ctx, node.body.as_ref(), pos); - - ctx.write_ref(test_pos, expr); - ctx.write_ref(body_pos, stmt); - - pos + ctx.write_do_while_stmt(&node.span, expr, stmt) } Stmt::For(node) => { - let raw = ctx.header(AstNode::ForStatement, parent, &node.span); - let init_pos = ctx.ref_field(AstProp::Init); - let test_pos = ctx.ref_field(AstProp::Test); - let update_pos = ctx.ref_field(AstProp::Update); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); - let init = node.init.as_ref().map(|init| match init { VarDeclOrExpr::VarDecl(var_decl) => { - serialize_stmt(ctx, &Stmt::Decl(Decl::Var(var_decl.clone())), pos) + serialize_stmt(ctx, &Stmt::Decl(Decl::Var(var_decl.clone()))) } - VarDeclOrExpr::Expr(expr) => serialize_expr(ctx, expr, pos), + VarDeclOrExpr::Expr(expr) => serialize_expr(ctx, expr), }); - let test = node - .test - .as_ref() - .map(|expr| serialize_expr(ctx, expr, pos)); - let update = node - .update - .as_ref() - .map(|expr| serialize_expr(ctx, expr, pos)); - let body = serialize_stmt(ctx, node.body.as_ref(), pos); + let test = node.test.as_ref().map(|expr| serialize_expr(ctx, expr)); + let update = node.update.as_ref().map(|expr| serialize_expr(ctx, expr)); + let body = serialize_stmt(ctx, node.body.as_ref()); - ctx.write_maybe_ref(init_pos, init); - ctx.write_maybe_ref(test_pos, test); - ctx.write_maybe_ref(update_pos, update); - ctx.write_ref(body_pos, body); - - pos + ctx.write_for_stmt(&node.span, init, test, update, body) } Stmt::ForIn(node) => { - let raw = ctx.header(AstNode::ForInStatement, parent, &node.span); - let left_pos = ctx.ref_field(AstProp::Left); - let right_pos = ctx.ref_field(AstProp::Right); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); + let left = serialize_for_head(ctx, &node.left); + let right = serialize_expr(ctx, node.right.as_ref()); + let body = serialize_stmt(ctx, node.body.as_ref()); - let left = serialize_for_head(ctx, &node.left, pos); - let right = serialize_expr(ctx, node.right.as_ref(), pos); - let body = serialize_stmt(ctx, node.body.as_ref(), pos); - - ctx.write_ref(left_pos, left); - ctx.write_ref(right_pos, right); - ctx.write_ref(body_pos, body); - - pos + ctx.write_for_in_stmt(&node.span, left, right, body) } Stmt::ForOf(node) => { - let raw = ctx.header(AstNode::ForOfStatement, parent, &node.span); - let await_pos = ctx.bool_field(AstProp::Await); - let left_pos = ctx.ref_field(AstProp::Left); - let right_pos = ctx.ref_field(AstProp::Right); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); + let left = serialize_for_head(ctx, &node.left); + let right = serialize_expr(ctx, node.right.as_ref()); + let body = serialize_stmt(ctx, node.body.as_ref()); - let left = serialize_for_head(ctx, &node.left, pos); - let right = serialize_expr(ctx, node.right.as_ref(), pos); - let body = serialize_stmt(ctx, node.body.as_ref(), pos); - - ctx.write_bool(await_pos, node.is_await); - ctx.write_ref(left_pos, left); - ctx.write_ref(right_pos, right); - ctx.write_ref(body_pos, body); - - pos + ctx.write_for_of_stmt(&node.span, node.is_await, left, right, body) } - Stmt::Decl(node) => serialize_decl(ctx, node, parent), + Stmt::Decl(node) => serialize_decl(ctx, node), Stmt::Expr(node) => { - let raw = ctx.header(AstNode::ExpressionStatement, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let pos = ctx.commit_schema(raw); - - let expr = serialize_expr(ctx, node.expr.as_ref(), pos); - ctx.write_ref(expr_pos, expr); - - pos + let expr = serialize_expr(ctx, node.expr.as_ref()); + ctx.write_expr_stmt(&node.span, expr) } } } -fn serialize_expr( - ctx: &mut TsEsTreeBuilder, - expr: &Expr, - parent: NodeRef, -) -> NodeRef { +fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef { match expr { - Expr::This(node) => { - let raw = ctx.header(AstNode::ThisExpression, parent, &node.span); - ctx.commit_schema(raw) - } + Expr::This(node) => ctx.write_this_expr(&node.span), Expr::Array(node) => { - let raw = ctx.header(AstNode::ArrayExpression, parent, &node.span); - let elems_pos = ctx.ref_vec_field(AstProp::Elements, node.elems.len()); - let pos = ctx.commit_schema(raw); - let elems = node .elems .iter() .map(|item| { item .as_ref() - .map_or(NodeRef(0), |item| serialize_expr_or_spread(ctx, item, pos)) + .map_or(NodeRef(0), |item| serialize_expr_or_spread(ctx, item)) }) .collect::>(); - ctx.write_refs(elems_pos, elems); - - pos + ctx.write_arr_expr(&node.span, elems) } Expr::Object(node) => { - let raw = ctx.header(AstNode::ObjectExpression, parent, &node.span); - let props_pos = ctx.ref_vec_field(AstProp::Properties, node.props.len()); - let pos = ctx.commit_schema(raw); - - let prop_ids = node + let props = node .props .iter() - .map(|prop| serialize_prop_or_spread(ctx, prop, pos)) + .map(|prop| serialize_prop_or_spread(ctx, prop)) .collect::>(); - ctx.write_refs(props_pos, prop_ids); - - pos + ctx.write_obj_expr(&node.span, props) } Expr::Fn(node) => { let fn_obj = node.function.as_ref(); - let raw = ctx.header(AstNode::FunctionExpression, parent, &fn_obj.span); - - let async_pos = ctx.bool_field(AstProp::Async); - let gen_pos = ctx.bool_field(AstProp::Generator); - let id_pos = ctx.ref_field(AstProp::Id); - let tparams_pos = ctx.ref_field(AstProp::TypeParameters); - let params_pos = ctx.ref_vec_field(AstProp::Params, fn_obj.params.len()); - let return_pos = ctx.ref_field(AstProp::ReturnType); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); - let ident = node .ident .as_ref() - .map(|ident| serialize_ident(ctx, ident, pos)); + .map(|ident| serialize_ident(ctx, ident, None)); let type_params = - maybe_serialize_ts_type_param(ctx, &fn_obj.type_params, pos); + maybe_serialize_ts_type_param_decl(ctx, &fn_obj.type_params); let params = fn_obj .params .iter() - .map(|param| serialize_pat(ctx, ¶m.pat, pos)) + .map(|param| serialize_pat(ctx, ¶m.pat)) .collect::>(); - let return_id = - maybe_serialize_ts_type_ann(ctx, &fn_obj.return_type, pos); + let return_id = maybe_serialize_ts_type_ann(ctx, &fn_obj.return_type); let body = fn_obj .body .as_ref() - .map(|block| serialize_stmt(ctx, &Stmt::Block(block.clone()), pos)); + .map(|block| serialize_stmt(ctx, &Stmt::Block(block.clone()))); - ctx.write_bool(async_pos, fn_obj.is_async); - ctx.write_bool(gen_pos, fn_obj.is_generator); - ctx.write_maybe_ref(id_pos, ident); - ctx.write_maybe_ref(tparams_pos, type_params); - ctx.write_refs(params_pos, params); - ctx.write_maybe_ref(return_pos, return_id); - ctx.write_maybe_ref(body_pos, body); - - pos + ctx.write_fn_expr( + &fn_obj.span, + fn_obj.is_async, + fn_obj.is_generator, + ident, + type_params, + params, + return_id, + body, + ) } Expr::Unary(node) => { - let raw = ctx.header(AstNode::UnaryExpression, parent, &node.span); - let flag_pos = ctx.str_field(AstProp::Operator); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); + let arg = serialize_expr(ctx, &node.arg); + let op = match node.op { + UnaryOp::Minus => "-", + UnaryOp::Plus => "+", + UnaryOp::Bang => "!", + UnaryOp::Tilde => "~", + UnaryOp::TypeOf => "typeof", + UnaryOp::Void => "void", + UnaryOp::Delete => "delete", + }; - let arg = serialize_expr(ctx, &node.arg, pos); - - ctx.write_str( - flag_pos, - match node.op { - UnaryOp::Minus => "-", - UnaryOp::Plus => "+", - UnaryOp::Bang => "!", - UnaryOp::Tilde => "~", - UnaryOp::TypeOf => "typeof", - UnaryOp::Void => "void", - UnaryOp::Delete => "delete", - }, - ); - ctx.write_ref(arg_pos, arg); - - pos + ctx.write_unary_expr(&node.span, op, arg) } Expr::Update(node) => { - let raw = ctx.header(AstNode::UpdateExpression, parent, &node.span); - let prefix_pos = ctx.bool_field(AstProp::Prefix); - let arg_pos = ctx.ref_field(AstProp::Argument); - let op_ops = ctx.str_field(AstProp::Operator); - let pos = ctx.commit_schema(raw); + let arg = serialize_expr(ctx, node.arg.as_ref()); + let op = match node.op { + UpdateOp::PlusPlus => "++", + UpdateOp::MinusMinus => "--", + }; - let arg = serialize_expr(ctx, node.arg.as_ref(), pos); - - ctx.write_bool(prefix_pos, node.prefix); - ctx.write_ref(arg_pos, arg); - ctx.write_str( - op_ops, - match node.op { - UpdateOp::PlusPlus => "++", - UpdateOp::MinusMinus => "--", - }, - ); - - pos + ctx.write_update_expr(&node.span, node.prefix, op, arg) } Expr::Bin(node) => { let (node_type, flag_str) = match node.op { @@ -699,501 +676,361 @@ fn serialize_expr( BinaryOp::Exp => (AstNode::BinaryExpression, "**"), }; - let raw = ctx.header(node_type, parent, &node.span); - let op_pos = ctx.str_field(AstProp::Operator); - let left_pos = ctx.ref_field(AstProp::Left); - let right_pos = ctx.ref_field(AstProp::Right); - let pos = ctx.commit_schema(raw); + let left = serialize_expr(ctx, node.left.as_ref()); + let right = serialize_expr(ctx, node.right.as_ref()); - let left_id = serialize_expr(ctx, node.left.as_ref(), pos); - let right_id = serialize_expr(ctx, node.right.as_ref(), pos); - - ctx.write_str(op_pos, flag_str); - ctx.write_ref(left_pos, left_id); - ctx.write_ref(right_pos, right_id); - - pos + match node_type { + AstNode::LogicalExpression => { + ctx.write_logical_expr(&node.span, flag_str, left, right) + } + AstNode::BinaryExpression => { + ctx.write_bin_expr(&node.span, flag_str, left, right) + } + _ => unreachable!(), + } } Expr::Assign(node) => { - let raw = ctx.header(AstNode::AssignmentExpression, parent, &node.span); - let op_pos = ctx.str_field(AstProp::Operator); - let left_pos = ctx.ref_field(AstProp::Left); - let right_pos = ctx.ref_field(AstProp::Right); - let pos = ctx.commit_schema(raw); - let left = match &node.left { AssignTarget::Simple(simple_assign_target) => { match simple_assign_target { SimpleAssignTarget::Ident(target) => { - serialize_ident(ctx, &target.id, pos) + serialize_binding_ident(ctx, target) } SimpleAssignTarget::Member(target) => { - serialize_expr(ctx, &Expr::Member(target.clone()), pos) + serialize_expr(ctx, &Expr::Member(target.clone())) } SimpleAssignTarget::SuperProp(target) => { - serialize_expr(ctx, &Expr::SuperProp(target.clone()), pos) + serialize_expr(ctx, &Expr::SuperProp(target.clone())) } SimpleAssignTarget::Paren(target) => { - serialize_expr(ctx, &target.expr, pos) + serialize_expr(ctx, &target.expr) } SimpleAssignTarget::OptChain(target) => { - serialize_expr(ctx, &Expr::OptChain(target.clone()), pos) + serialize_expr(ctx, &Expr::OptChain(target.clone())) } SimpleAssignTarget::TsAs(target) => { - serialize_expr(ctx, &Expr::TsAs(target.clone()), pos) + serialize_expr(ctx, &Expr::TsAs(target.clone())) } SimpleAssignTarget::TsSatisfies(target) => { - serialize_expr(ctx, &Expr::TsSatisfies(target.clone()), pos) + serialize_expr(ctx, &Expr::TsSatisfies(target.clone())) } SimpleAssignTarget::TsNonNull(target) => { - serialize_expr(ctx, &Expr::TsNonNull(target.clone()), pos) + serialize_expr(ctx, &Expr::TsNonNull(target.clone())) } SimpleAssignTarget::TsTypeAssertion(target) => { - serialize_expr(ctx, &Expr::TsTypeAssertion(target.clone()), pos) + serialize_expr(ctx, &Expr::TsTypeAssertion(target.clone())) } SimpleAssignTarget::TsInstantiation(target) => { - serialize_expr(ctx, &Expr::TsInstantiation(target.clone()), pos) + serialize_expr(ctx, &Expr::TsInstantiation(target.clone())) } SimpleAssignTarget::Invalid(_) => unreachable!(), } } AssignTarget::Pat(target) => match target { AssignTargetPat::Array(array_pat) => { - serialize_pat(ctx, &Pat::Array(array_pat.clone()), pos) + serialize_pat(ctx, &Pat::Array(array_pat.clone())) } AssignTargetPat::Object(object_pat) => { - serialize_pat(ctx, &Pat::Object(object_pat.clone()), pos) + serialize_pat(ctx, &Pat::Object(object_pat.clone())) } AssignTargetPat::Invalid(_) => unreachable!(), }, }; - let right = serialize_expr(ctx, node.right.as_ref(), pos); + let right = serialize_expr(ctx, node.right.as_ref()); - ctx.write_str( - op_pos, - match node.op { - AssignOp::Assign => "=", - AssignOp::AddAssign => "+=", - AssignOp::SubAssign => "-=", - AssignOp::MulAssign => "*=", - AssignOp::DivAssign => "/=", - AssignOp::ModAssign => "%=", - AssignOp::LShiftAssign => "<<=", - AssignOp::RShiftAssign => ">>=", - AssignOp::ZeroFillRShiftAssign => ">>>=", - AssignOp::BitOrAssign => "|=", - AssignOp::BitXorAssign => "^=", - AssignOp::BitAndAssign => "&=", - AssignOp::ExpAssign => "**=", - AssignOp::AndAssign => "&&=", - AssignOp::OrAssign => "||=", - AssignOp::NullishAssign => "??=", - }, - ); - ctx.write_ref(left_pos, left); - ctx.write_ref(right_pos, right); + let op = match node.op { + AssignOp::Assign => "=", + AssignOp::AddAssign => "+=", + AssignOp::SubAssign => "-=", + AssignOp::MulAssign => "*=", + AssignOp::DivAssign => "/=", + AssignOp::ModAssign => "%=", + AssignOp::LShiftAssign => "<<=", + AssignOp::RShiftAssign => ">>=", + AssignOp::ZeroFillRShiftAssign => ">>>=", + AssignOp::BitOrAssign => "|=", + AssignOp::BitXorAssign => "^=", + AssignOp::BitAndAssign => "&=", + AssignOp::ExpAssign => "**=", + AssignOp::AndAssign => "&&=", + AssignOp::OrAssign => "||=", + AssignOp::NullishAssign => "??=", + }; - pos + ctx.write_assignment_expr(&node.span, op, left, right) } - Expr::Member(node) => serialize_member_expr(ctx, node, parent, false), + Expr::Member(node) => serialize_member_expr(ctx, node, false), Expr::SuperProp(node) => { - let raw = ctx.header(AstNode::MemberExpression, parent, &node.span); - let computed_pos = ctx.bool_field(AstProp::Computed); - let obj_pos = ctx.ref_field(AstProp::Object); - let prop_pos = ctx.ref_field(AstProp::Property); - let pos = ctx.commit_schema(raw); - - let raw = ctx.header(AstNode::Super, pos, &node.obj.span); - let obj = ctx.commit_schema(raw); + let obj = ctx.write_super(&node.obj.span); let mut computed = false; let prop = match &node.prop { - SuperProp::Ident(ident_name) => { - serialize_ident_name(ctx, ident_name, pos) - } + SuperProp::Ident(ident_name) => serialize_ident_name(ctx, ident_name), SuperProp::Computed(prop) => { computed = true; - serialize_expr(ctx, &prop.expr, pos) + serialize_expr(ctx, &prop.expr) } }; - ctx.write_bool(computed_pos, computed); - ctx.write_ref(obj_pos, obj); - ctx.write_ref(prop_pos, prop); - - pos + ctx.write_member_expr(&node.span, false, computed, obj, prop) } Expr::Cond(node) => { - let raw = ctx.header(AstNode::ConditionalExpression, parent, &node.span); - let test_pos = ctx.ref_field(AstProp::Test); - let cons_pos = ctx.ref_field(AstProp::Consequent); - let alt_pos = ctx.ref_field(AstProp::Alternate); - let pos = ctx.commit_schema(raw); + let test = serialize_expr(ctx, node.test.as_ref()); + let cons = serialize_expr(ctx, node.cons.as_ref()); + let alt = serialize_expr(ctx, node.alt.as_ref()); - let test = serialize_expr(ctx, node.test.as_ref(), pos); - let cons = serialize_expr(ctx, node.cons.as_ref(), pos); - let alt = serialize_expr(ctx, node.alt.as_ref(), pos); - - ctx.write_ref(test_pos, test); - ctx.write_ref(cons_pos, cons); - ctx.write_ref(alt_pos, alt); - - pos + ctx.write_conditional_expr(&node.span, test, cons, alt) } Expr::Call(node) => { - let raw = ctx.header(AstNode::CallExpression, parent, &node.span); - let opt_pos = ctx.bool_field(AstProp::Optional); - let callee_pos = ctx.ref_field(AstProp::Callee); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let args_pos = ctx.ref_vec_field(AstProp::Arguments, node.args.len()); - let pos = ctx.commit_schema(raw); + if let Callee::Import(_) = node.callee { + let source = node + .args + .first() + .map_or(NodeRef(0), |arg| serialize_expr_or_spread(ctx, arg)); - let callee = match &node.callee { - Callee::Super(super_node) => { - let raw = ctx.header(AstNode::Super, pos, &super_node.span); - ctx.commit_schema(raw) - } - Callee::Import(_) => todo!(), - Callee::Expr(expr) => serialize_expr(ctx, expr, pos), - }; + let options = node + .args + .get(1) + .map_or(NodeRef(0), |arg| serialize_expr_or_spread(ctx, arg)); - let type_arg = node.type_args.clone().map(|param_node| { - serialize_ts_param_inst(ctx, param_node.as_ref(), pos) - }); + ctx.write_import_expr(&node.span, source, options) + } else { + let callee = match &node.callee { + Callee::Super(super_node) => ctx.write_super(&super_node.span), + Callee::Import(_) => unreachable!("Already handled"), + Callee::Expr(expr) => serialize_expr(ctx, expr), + }; - let args = node - .args - .iter() - .map(|arg| serialize_expr_or_spread(ctx, arg, pos)) - .collect::>(); + let type_arg = node + .type_args + .clone() + .map(|param_node| serialize_ts_param_inst(ctx, param_node.as_ref())); - ctx.write_bool(opt_pos, false); - ctx.write_ref(callee_pos, callee); - ctx.write_maybe_ref(type_args_pos, type_arg); - ctx.write_refs(args_pos, args); + let args = node + .args + .iter() + .map(|arg| serialize_expr_or_spread(ctx, arg)) + .collect::>(); - pos + ctx.write_call_expr(&node.span, false, callee, type_arg, args) + } } Expr::New(node) => { - let raw = ctx.header(AstNode::NewExpression, parent, &node.span); - let callee_pos = ctx.ref_field(AstProp::Callee); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let args_pos = ctx.ref_vec_field( - AstProp::Arguments, - node.args.as_ref().map_or(0, |v| v.len()), - ); - let pos = ctx.commit_schema(raw); - - let callee = serialize_expr(ctx, node.callee.as_ref(), pos); + let callee = serialize_expr(ctx, node.callee.as_ref()); let args: Vec = node.args.as_ref().map_or(vec![], |args| { args .iter() - .map(|arg| serialize_expr_or_spread(ctx, arg, pos)) + .map(|arg| serialize_expr_or_spread(ctx, arg)) .collect::>() }); - let type_args = node.type_args.clone().map(|param_node| { - serialize_ts_param_inst(ctx, param_node.as_ref(), pos) - }); + let type_args = node + .type_args + .clone() + .map(|param_node| serialize_ts_param_inst(ctx, param_node.as_ref())); - ctx.write_ref(callee_pos, callee); - ctx.write_maybe_ref(type_args_pos, type_args); - ctx.write_refs(args_pos, args); - - pos + ctx.write_new_expr(&node.span, callee, type_args, args) } Expr::Seq(node) => { - let raw = ctx.header(AstNode::SequenceExpression, parent, &node.span); - let exprs_pos = ctx.ref_vec_field(AstProp::Expressions, node.exprs.len()); - let pos = ctx.commit_schema(raw); - let children = node .exprs .iter() - .map(|expr| serialize_expr(ctx, expr, pos)) + .map(|expr| serialize_expr(ctx, expr)) .collect::>(); - ctx.write_refs(exprs_pos, children); - - pos + ctx.write_sequence_expr(&node.span, children) } - Expr::Ident(node) => serialize_ident(ctx, node, parent), - Expr::Lit(node) => serialize_lit(ctx, node, parent), + Expr::Ident(node) => serialize_ident(ctx, node, None), + Expr::Lit(node) => serialize_lit(ctx, node), Expr::Tpl(node) => { - let raw = ctx.header(AstNode::TemplateLiteral, parent, &node.span); - let quasis_pos = ctx.ref_vec_field(AstProp::Quasis, node.quasis.len()); - let exprs_pos = ctx.ref_vec_field(AstProp::Expressions, node.exprs.len()); - let pos = ctx.commit_schema(raw); - let quasis = node .quasis .iter() .map(|quasi| { - let raw = ctx.header(AstNode::TemplateElement, pos, &quasi.span); - let tail_pos = ctx.bool_field(AstProp::Tail); - let raw_pos = ctx.str_field(AstProp::Raw); - let cooked_pos = ctx.str_field(AstProp::Cooked); - let tpl_pos = ctx.commit_schema(raw); - - ctx.write_bool(tail_pos, quasi.tail); - ctx.write_str(raw_pos, &quasi.raw); - ctx.write_str( - cooked_pos, + ctx.write_template_elem( + &quasi.span, + quasi.tail, + &quasi.raw, &quasi .cooked .as_ref() .map_or("".to_string(), |v| v.to_string()), - ); - - tpl_pos + ) }) .collect::>(); let exprs = node .exprs .iter() - .map(|expr| serialize_expr(ctx, expr, pos)) + .map(|expr| serialize_expr(ctx, expr)) .collect::>(); - ctx.write_refs(quasis_pos, quasis); - ctx.write_refs(exprs_pos, exprs); - - pos + ctx.write_template_lit(&node.span, quasis, exprs) } Expr::TaggedTpl(node) => { - let raw = - ctx.header(AstNode::TaggedTemplateExpression, parent, &node.span); - let tag_pos = ctx.ref_field(AstProp::Tag); - let type_arg_pos = ctx.ref_field(AstProp::TypeArguments); - let quasi_pos = ctx.ref_field(AstProp::Quasi); - let pos = ctx.commit_schema(raw); - - let tag = serialize_expr(ctx, &node.tag, pos); - - let type_param_id = node + let tag = serialize_expr(ctx, &node.tag); + let type_param = node .type_params .clone() - .map(|params| serialize_ts_param_inst(ctx, params.as_ref(), pos)); - let quasi = serialize_expr(ctx, &Expr::Tpl(*node.tpl.clone()), pos); + .map(|params| serialize_ts_param_inst(ctx, params.as_ref())); + let quasi = serialize_expr(ctx, &Expr::Tpl(*node.tpl.clone())); - ctx.write_ref(tag_pos, tag); - ctx.write_maybe_ref(type_arg_pos, type_param_id); - ctx.write_ref(quasi_pos, quasi); - - pos + ctx.write_tagged_template_expr(&node.span, tag, type_param, quasi) } Expr::Arrow(node) => { - let raw = - ctx.header(AstNode::ArrowFunctionExpression, parent, &node.span); - let async_pos = ctx.bool_field(AstProp::Async); - let gen_pos = ctx.bool_field(AstProp::Generator); - let type_param_pos = ctx.ref_field(AstProp::TypeParameters); - let params_pos = ctx.ref_vec_field(AstProp::Params, node.params.len()); - let body_pos = ctx.ref_field(AstProp::Body); - let return_type_pos = ctx.ref_field(AstProp::ReturnType); - let pos = ctx.commit_schema(raw); - let type_param = - maybe_serialize_ts_type_param(ctx, &node.type_params, pos); + maybe_serialize_ts_type_param_decl(ctx, &node.type_params); let params = node .params .iter() - .map(|param| serialize_pat(ctx, param, pos)) + .map(|param| serialize_pat(ctx, param)) .collect::>(); let body = match node.body.as_ref() { BlockStmtOrExpr::BlockStmt(block_stmt) => { - serialize_stmt(ctx, &Stmt::Block(block_stmt.clone()), pos) + serialize_stmt(ctx, &Stmt::Block(block_stmt.clone())) } - BlockStmtOrExpr::Expr(expr) => serialize_expr(ctx, expr.as_ref(), pos), + BlockStmtOrExpr::Expr(expr) => serialize_expr(ctx, expr.as_ref()), }; - let return_type = - maybe_serialize_ts_type_ann(ctx, &node.return_type, pos); + let return_type = maybe_serialize_ts_type_ann(ctx, &node.return_type); - ctx.write_bool(async_pos, node.is_async); - ctx.write_bool(gen_pos, node.is_generator); - ctx.write_maybe_ref(type_param_pos, type_param); - ctx.write_refs(params_pos, params); - ctx.write_ref(body_pos, body); - ctx.write_maybe_ref(return_type_pos, return_type); - - pos + ctx.write_arrow_fn_expr( + &node.span, + node.is_async, + node.is_generator, + type_param, + params, + return_type, + body, + ) } Expr::Class(node) => { - // FIXME - let raw = ctx.header(AstNode::ClassExpression, parent, &node.class.span); - ctx.commit_schema(raw) + let ident = node + .ident + .as_ref() + .map(|ident| serialize_ident(ctx, ident, None)); + + let super_class = node + .class + .super_class + .as_ref() + .map(|expr| serialize_expr(ctx, expr.as_ref())); + + let implements = node + .class + .implements + .iter() + .map(|item| serialize_ts_expr_with_type_args(ctx, item)) + .collect::>(); + + let members = node + .class + .body + .iter() + .filter_map(|member| serialize_class_member(ctx, member)) + .collect::>(); + + let body = ctx.write_class_body(&node.class.span, members); + + ctx.write_class_expr( + &node.class.span, + false, + node.class.is_abstract, + ident, + super_class, + implements, + body, + ) } Expr::Yield(node) => { - let raw = ctx.header(AstNode::YieldExpression, parent, &node.span); - let delegate_pos = ctx.bool_field(AstProp::Delegate); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); - let arg = node .arg .as_ref() - .map(|arg| serialize_expr(ctx, arg.as_ref(), pos)); + .map(|arg| serialize_expr(ctx, arg.as_ref())); - ctx.write_bool(delegate_pos, node.delegate); - ctx.write_maybe_ref(arg_pos, arg); - - pos + ctx.write_yield_expr(&node.span, node.delegate, arg) } Expr::MetaProp(node) => { - let raw = ctx.header(AstNode::MetaProp, parent, &node.span); - ctx.commit_schema(raw) + let prop = ctx.write_identifier(&node.span, "meta", false, None); + ctx.write_meta_prop(&node.span, prop) } Expr::Await(node) => { - let raw = ctx.header(AstNode::AwaitExpression, parent, &node.span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); - - let arg = serialize_expr(ctx, node.arg.as_ref(), pos); - - ctx.write_ref(arg_pos, arg); - - pos + let arg = serialize_expr(ctx, node.arg.as_ref()); + ctx.write_await_expr(&node.span, arg) } Expr::Paren(node) => { // Paren nodes are treated as a syntax only thing in TSEStree // and are never materialized to actual AST nodes. - serialize_expr(ctx, &node.expr, parent) + serialize_expr(ctx, &node.expr) } - Expr::JSXMember(node) => serialize_jsx_member_expr(ctx, node, parent), - Expr::JSXNamespacedName(node) => { - serialize_jsx_namespaced_name(ctx, node, parent) - } - Expr::JSXEmpty(node) => serialize_jsx_empty_expr(ctx, node, parent), - Expr::JSXElement(node) => serialize_jsx_element(ctx, node, parent), - Expr::JSXFragment(node) => serialize_jsx_fragment(ctx, node, parent), + Expr::JSXMember(node) => serialize_jsx_member_expr(ctx, node), + Expr::JSXNamespacedName(node) => serialize_jsx_namespaced_name(ctx, node), + Expr::JSXEmpty(node) => ctx.write_jsx_empty_expr(&node.span), + Expr::JSXElement(node) => serialize_jsx_element(ctx, node), + Expr::JSXFragment(node) => serialize_jsx_fragment(ctx, node), Expr::TsTypeAssertion(node) => { - let raw = ctx.header(AstNode::TSTypeAssertion, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); + let expr = serialize_expr(ctx, &node.expr); + let type_ann = serialize_ts_type(ctx, &node.type_ann); - let expr = serialize_expr(ctx, &node.expr, parent); - let type_ann = serialize_ts_type(ctx, &node.type_ann, pos); - - ctx.write_ref(expr_pos, expr); - ctx.write_ref(type_ann_pos, type_ann); - - pos + ctx.write_ts_type_assertion(&node.span, expr, type_ann) } Expr::TsConstAssertion(node) => { - let raw = ctx.header(AstNode::TsConstAssertion, parent, &node.span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); + let expr = serialize_expr(ctx, node.expr.as_ref()); - let arg = serialize_expr(ctx, node.expr.as_ref(), pos); + let type_name = ctx.write_identifier(&node.span, "const", false, None); + let type_ann = ctx.write_ts_type_ref(&node.span, type_name, None); - // FIXME - ctx.write_ref(arg_pos, arg); - - pos + ctx.write_ts_as_expr(&node.span, expr, type_ann) } Expr::TsNonNull(node) => { - let raw = ctx.header(AstNode::TSNonNullExpression, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let pos = ctx.commit_schema(raw); - - let expr_id = serialize_expr(ctx, node.expr.as_ref(), pos); - - ctx.write_ref(expr_pos, expr_id); - - pos + let expr = serialize_expr(ctx, node.expr.as_ref()); + ctx.write_ts_non_null(&node.span, expr) } Expr::TsAs(node) => { - let raw = ctx.header(AstNode::TSAsExpression, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); + let expr = serialize_expr(ctx, node.expr.as_ref()); + let type_ann = serialize_ts_type(ctx, node.type_ann.as_ref()); - let expr = serialize_expr(ctx, node.expr.as_ref(), pos); - let type_ann = serialize_ts_type(ctx, node.type_ann.as_ref(), pos); - - ctx.write_ref(expr_pos, expr); - ctx.write_ref(type_ann_pos, type_ann); - - pos + ctx.write_ts_as_expr(&node.span, expr, type_ann) } - Expr::TsInstantiation(node) => { - let raw = ctx.header(AstNode::TsInstantiation, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let pos = ctx.commit_schema(raw); - - let expr = serialize_expr(ctx, node.expr.as_ref(), pos); - - let type_arg = serialize_ts_param_inst(ctx, node.type_args.as_ref(), pos); - - ctx.write_ref(expr_pos, expr); - ctx.write_ref(type_args_pos, type_arg); - - pos + Expr::TsInstantiation(_) => { + // Invalid syntax + unreachable!() } Expr::TsSatisfies(node) => { - let raw = ctx.header(AstNode::TSSatisfiesExpression, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); + let expr = serialize_expr(ctx, node.expr.as_ref()); + let type_ann = serialize_ts_type(ctx, node.type_ann.as_ref()); - let epxr = serialize_expr(ctx, node.expr.as_ref(), pos); - let type_ann = serialize_ts_type(ctx, node.type_ann.as_ref(), pos); - - ctx.write_ref(expr_pos, epxr); - ctx.write_ref(type_ann_pos, type_ann); - - pos + ctx.write_ts_satisfies_expr(&node.span, expr, type_ann) } - Expr::PrivateName(node) => serialize_private_name(ctx, node, parent), + Expr::PrivateName(node) => serialize_private_name(ctx, node), Expr::OptChain(node) => { - let raw = ctx.header(AstNode::ChainExpression, parent, &node.span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); - - let arg = match node.base.as_ref() { + let expr = match node.base.as_ref() { OptChainBase::Member(member_expr) => { - serialize_member_expr(ctx, member_expr, pos, true) + serialize_member_expr(ctx, member_expr, true) } OptChainBase::Call(opt_call) => { - let raw = ctx.header(AstNode::CallExpression, pos, &opt_call.span); - let opt_pos = ctx.bool_field(AstProp::Optional); - let callee_pos = ctx.ref_field(AstProp::Callee); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let args_pos = - ctx.ref_vec_field(AstProp::Arguments, opt_call.args.len()); - let call_pos = ctx.commit_schema(raw); + let callee = serialize_expr(ctx, &opt_call.callee); - let callee = serialize_expr(ctx, &opt_call.callee, pos); - - let type_param_id = opt_call.type_args.clone().map(|params| { - serialize_ts_param_inst(ctx, params.as_ref(), call_pos) - }); + let type_param_id = opt_call + .type_args + .clone() + .map(|params| serialize_ts_param_inst(ctx, params.as_ref())); let args = opt_call .args .iter() - .map(|arg| serialize_expr_or_spread(ctx, arg, pos)) + .map(|arg| serialize_expr_or_spread(ctx, arg)) .collect::>(); - ctx.write_bool(opt_pos, true); - ctx.write_ref(callee_pos, callee); - ctx.write_maybe_ref(type_args_pos, type_param_id); - ctx.write_refs(args_pos, args); - - call_pos + ctx.write_call_expr(&opt_call.span, true, callee, type_param_id, args) } }; - ctx.write_ref(arg_pos, arg); - - pos + ctx.write_chain_expr(&node.span, expr) } Expr::Invalid(_) => { unreachable!() @@ -1204,69 +1041,49 @@ fn serialize_expr( fn serialize_prop_or_spread( ctx: &mut TsEsTreeBuilder, prop: &PropOrSpread, - parent: NodeRef, ) -> NodeRef { match prop { PropOrSpread::Spread(spread_element) => serialize_spread( ctx, spread_element.expr.as_ref(), &spread_element.dot3_token, - parent, ), PropOrSpread::Prop(prop) => { - let raw = ctx.header(AstNode::Property, parent, &prop.span()); - - let shorthand_pos = ctx.bool_field(AstProp::Shorthand); - let computed_pos = ctx.bool_field(AstProp::Computed); - let method_pos = ctx.bool_field(AstProp::Method); - let kind_pos = ctx.str_field(AstProp::Kind); - let key_pos = ctx.ref_field(AstProp::Key); - let value_pos = ctx.ref_field(AstProp::Value); - let pos = ctx.commit_schema(raw); - let mut shorthand = false; let mut computed = false; let mut method = false; let mut kind = "init"; - // FIXME: optional - let (key_id, value_id) = match prop.as_ref() { + let (key, value) = match prop.as_ref() { Prop::Shorthand(ident) => { shorthand = true; - let value = serialize_ident(ctx, ident, pos); - (value, value) + let value = serialize_ident(ctx, ident, None); + let value2 = serialize_ident(ctx, ident, None); + (value, value2) } Prop::KeyValue(key_value_prop) => { if let PropName::Computed(_) = key_value_prop.key { computed = true; } - let key = serialize_prop_name(ctx, &key_value_prop.key, pos); - let value = serialize_expr(ctx, key_value_prop.value.as_ref(), pos); + let key = serialize_prop_name(ctx, &key_value_prop.key); + let value = serialize_expr(ctx, key_value_prop.value.as_ref()); (key, value) } Prop::Assign(assign_prop) => { - let raw = - ctx.header(AstNode::AssignmentPattern, pos, &assign_prop.span); - let left_pos = ctx.ref_field(AstProp::Left); - let right_pos = ctx.ref_field(AstProp::Right); - let child_pos = ctx.commit_schema(raw); + let left = serialize_ident(ctx, &assign_prop.key, None); + let right = serialize_expr(ctx, assign_prop.value.as_ref()); - let left = serialize_ident(ctx, &assign_prop.key, child_pos); - let right = - serialize_expr(ctx, assign_prop.value.as_ref(), child_pos); - - ctx.write_ref(left_pos, left); - ctx.write_ref(right_pos, right); + let child_pos = ctx.write_assign_pat(&assign_prop.span, left, right); (left, child_pos) } Prop::Getter(getter_prop) => { kind = "get"; - let key = serialize_prop_name(ctx, &getter_prop.key, pos); + let key = serialize_prop_name(ctx, &getter_prop.key); let value = serialize_expr( ctx, @@ -1280,11 +1097,10 @@ fn serialize_prop_or_spread( body: getter_prop.body.clone(), is_generator: false, is_async: false, - type_params: None, // FIXME - return_type: None, + type_params: None, + return_type: getter_prop.type_ann.clone(), }), }), - pos, ); (key, value) @@ -1292,7 +1108,7 @@ fn serialize_prop_or_spread( Prop::Setter(setter_prop) => { kind = "set"; - let key_id = serialize_prop_name(ctx, &setter_prop.key, pos); + let key_id = serialize_prop_name(ctx, &setter_prop.key); let param = Param::from(*setter_prop.param.clone()); @@ -1312,7 +1128,6 @@ fn serialize_prop_or_spread( return_type: None, }), }), - pos, ); (key_id, value_id) @@ -1320,7 +1135,7 @@ fn serialize_prop_or_spread( Prop::Method(method_prop) => { method = true; - let key_id = serialize_prop_name(ctx, &method_prop.key, pos); + let key_id = serialize_prop_name(ctx, &method_prop.key); let value_id = serialize_expr( ctx, @@ -1328,21 +1143,21 @@ fn serialize_prop_or_spread( ident: None, function: method_prop.function.clone(), }), - pos, ); (key_id, value_id) } }; - ctx.write_bool(shorthand_pos, shorthand); - ctx.write_bool(computed_pos, computed); - ctx.write_bool(method_pos, method); - ctx.write_str(kind_pos, kind); - ctx.write_ref(key_pos, key_id); - ctx.write_ref(value_pos, value_id); - - pos + ctx.write_property( + &prop.span(), + shorthand, + computed, + method, + kind, + key, + value, + ) } } } @@ -1350,396 +1165,190 @@ fn serialize_prop_or_spread( fn serialize_member_expr( ctx: &mut TsEsTreeBuilder, node: &MemberExpr, - parent: NodeRef, optional: bool, ) -> NodeRef { - let raw = ctx.header(AstNode::MemberExpression, parent, &node.span); - let opt_pos = ctx.bool_field(AstProp::Optional); - let computed_pos = ctx.bool_field(AstProp::Computed); - let obj_pos = ctx.ref_field(AstProp::Object); - let prop_pos = ctx.ref_field(AstProp::Property); - let pos = ctx.commit_schema(raw); - - let obj = serialize_expr(ctx, node.obj.as_ref(), pos); - let mut computed = false; + let obj = serialize_expr(ctx, node.obj.as_ref()); let prop = match &node.prop { - MemberProp::Ident(ident_name) => serialize_ident_name(ctx, ident_name, pos), + MemberProp::Ident(ident_name) => serialize_ident_name(ctx, ident_name), MemberProp::PrivateName(private_name) => { - serialize_private_name(ctx, private_name, pos) + serialize_private_name(ctx, private_name) } MemberProp::Computed(computed_prop_name) => { computed = true; - serialize_expr(ctx, computed_prop_name.expr.as_ref(), pos) + serialize_expr(ctx, computed_prop_name.expr.as_ref()) } }; - ctx.write_bool(opt_pos, optional); - ctx.write_bool(computed_pos, computed); - ctx.write_ref(obj_pos, obj); - ctx.write_ref(prop_pos, prop); - - pos -} - -fn serialize_class_member( - ctx: &mut TsEsTreeBuilder, - member: &ClassMember, - parent: NodeRef, -) -> NodeRef { - match member { - ClassMember::Constructor(constructor) => { - let raw = - ctx.header(AstNode::MethodDefinition, parent, &constructor.span); - let key_pos = ctx.ref_field(AstProp::Key); - let body_pos = ctx.ref_field(AstProp::Body); - let args_pos = - ctx.ref_vec_field(AstProp::Arguments, constructor.params.len()); - let acc_pos = if constructor.accessibility.is_some() { - NodePos::Str(ctx.str_field(AstProp::Accessibility)) - } else { - NodePos::Undef(ctx.undefined_field(AstProp::Accessibility)) - }; - let member_id = ctx.commit_schema(raw); - - // FIXME flags - - let key = serialize_prop_name(ctx, &constructor.key, member_id); - let body = constructor - .body - .as_ref() - .map(|body| serialize_stmt(ctx, &Stmt::Block(body.clone()), member_id)); - - let params = constructor - .params - .iter() - .map(|param| match param { - ParamOrTsParamProp::TsParamProp(_) => { - todo!() - } - ParamOrTsParamProp::Param(param) => { - serialize_pat(ctx, ¶m.pat, member_id) - } - }) - .collect::>(); - - if let Some(acc) = constructor.accessibility { - if let NodePos::Str(str_pos) = acc_pos { - ctx.write_str(str_pos, &accessibility_to_str(acc)); - } - } - - ctx.write_ref(key_pos, key); - ctx.write_maybe_ref(body_pos, body); - // FIXME - ctx.write_refs(args_pos, params); - - member_id - } - ClassMember::Method(method) => { - let raw = ctx.header(AstNode::MethodDefinition, parent, &method.span); - - let member_id = ctx.commit_schema(raw); - - // let mut flags = FlagValue::new(); - // flags.set(Flag::ClassMethod); - if method.function.is_async { - // FIXME - } - - // accessibility_to_flag(&mut flags, method.accessibility); - - let _key_id = serialize_prop_name(ctx, &method.key, member_id); - - let _body_id = - method.function.body.as_ref().map(|body| { - serialize_stmt(ctx, &Stmt::Block(body.clone()), member_id) - }); - - let _params = method - .function - .params - .iter() - .map(|param| serialize_pat(ctx, ¶m.pat, member_id)) - .collect::>(); - - // ctx.write_node(member_id, ); - // ctx.write_flags(&flags); - // ctx.write_id(key_id); - // ctx.write_id(body_id); - // ctx.write_ids(AstProp::Params, params); - - member_id - } - ClassMember::PrivateMethod(_) => todo!(), - ClassMember::ClassProp(_) => todo!(), - ClassMember::PrivateProp(_) => todo!(), - ClassMember::TsIndexSignature(member) => { - serialize_ts_index_sig(ctx, member, parent) - } - ClassMember::Empty(_) => unreachable!(), - ClassMember::StaticBlock(_) => todo!(), - ClassMember::AutoAccessor(_) => todo!(), - } + ctx.write_member_expr(&node.span, optional, computed, obj, prop) } fn serialize_expr_or_spread( ctx: &mut TsEsTreeBuilder, arg: &ExprOrSpread, - parent: NodeRef, ) -> NodeRef { if let Some(spread) = &arg.spread { - serialize_spread(ctx, &arg.expr, spread, parent) + serialize_spread(ctx, &arg.expr, spread) } else { - serialize_expr(ctx, arg.expr.as_ref(), parent) + serialize_expr(ctx, arg.expr.as_ref()) } } fn serialize_ident( ctx: &mut TsEsTreeBuilder, ident: &Ident, - parent: NodeRef, + type_ann: Option, ) -> NodeRef { - let raw = ctx.header(AstNode::Identifier, parent, &ident.span); - let name_pos = ctx.str_field(AstProp::Name); - let pos = ctx.commit_schema(raw); - - ctx.write_str(name_pos, ident.sym.as_str()); - - pos + ctx.write_identifier( + &ident.span, + ident.sym.as_str(), + ident.optional, + type_ann, + ) } -fn serialize_module_exported_name( +fn serialize_module_export_name( ctx: &mut TsEsTreeBuilder, name: &ModuleExportName, - parent: NodeRef, ) -> NodeRef { match &name { - ModuleExportName::Ident(ident) => serialize_ident(ctx, ident, parent), - ModuleExportName::Str(lit) => { - serialize_lit(ctx, &Lit::Str(lit.clone()), parent) - } + ModuleExportName::Ident(ident) => serialize_ident(ctx, ident, None), + ModuleExportName::Str(lit) => serialize_lit(ctx, &Lit::Str(lit.clone())), } } -fn serialize_decl( - ctx: &mut TsEsTreeBuilder, - decl: &Decl, - parent: NodeRef, -) -> NodeRef { +fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef { match decl { Decl::Class(node) => { - let raw = ctx.header(AstNode::ClassDeclaration, parent, &node.class.span); - let declare_pos = ctx.bool_field(AstProp::Declare); - let abstract_pos = ctx.bool_field(AstProp::Abstract); - let id_pos = ctx.ref_field(AstProp::Id); - let body_pos = ctx.ref_field(AstProp::Body); - let type_params_pos = ctx.ref_field(AstProp::TypeParameters); - let super_pos = ctx.ref_field(AstProp::SuperClass); - let super_type_pos = ctx.ref_field(AstProp::SuperTypeArguments); - let impl_pos = - ctx.ref_vec_field(AstProp::Implements, node.class.implements.len()); - let id = ctx.commit_schema(raw); - - let body_raw = ctx.header(AstNode::ClassBody, id, &node.class.span); - let body_body_pos = - ctx.ref_vec_field(AstProp::Body, node.class.body.len()); - let body_id = ctx.commit_schema(body_raw); - - let ident = serialize_ident(ctx, &node.ident, id); - let type_params = - maybe_serialize_ts_type_param(ctx, &node.class.type_params, id); + let ident = serialize_ident(ctx, &node.ident, None); let super_class = node .class .super_class .as_ref() - .map(|super_class| serialize_expr(ctx, super_class, id)); + .map(|expr| serialize_expr(ctx, expr.as_ref())); - let super_type_params = node - .class - .super_type_params - .as_ref() - .map(|super_params| serialize_ts_param_inst(ctx, super_params, id)); - - let implement_ids = node + let implements = node .class .implements .iter() - .map(|implements| { - let raw = - ctx.header(AstNode::TSClassImplements, id, &implements.span); - - let expr_pos = ctx.ref_field(AstProp::Expression); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let child_pos = ctx.commit_schema(raw); - - let type_args = implements - .type_args - .clone() - .map(|args| serialize_ts_param_inst(ctx, &args, child_pos)); - - let expr = serialize_expr(ctx, &implements.expr, child_pos); - - ctx.write_ref(expr_pos, expr); - ctx.write_maybe_ref(type_args_pos, type_args); - - child_pos - }) + .map(|item| serialize_ts_expr_with_type_args(ctx, item)) .collect::>(); - let member_ids = node + let members = node .class .body .iter() - .map(|member| serialize_class_member(ctx, member, parent)) + .filter_map(|member| serialize_class_member(ctx, member)) .collect::>(); - ctx.write_ref(body_pos, body_id); + let body = ctx.write_class_body(&node.class.span, members); - ctx.write_bool(declare_pos, node.declare); - ctx.write_bool(abstract_pos, node.class.is_abstract); - ctx.write_ref(id_pos, ident); - ctx.write_maybe_ref(type_params_pos, type_params); - ctx.write_maybe_ref(super_pos, super_class); - ctx.write_maybe_ref(super_type_pos, super_type_params); - ctx.write_refs(impl_pos, implement_ids); - - // body - ctx.write_refs(body_body_pos, member_ids); - - id + ctx.write_class_decl( + &node.class.span, + false, + node.class.is_abstract, + Some(ident), + super_class, + implements, + body, + ) } Decl::Fn(node) => { - let raw = - ctx.header(AstNode::FunctionDeclaration, parent, &node.function.span); - let declare_pos = ctx.bool_field(AstProp::Declare); - let async_pos = ctx.bool_field(AstProp::Async); - let gen_pos = ctx.bool_field(AstProp::Generator); - let id_pos = ctx.ref_field(AstProp::Id); - let type_params_pos = ctx.ref_field(AstProp::TypeParameters); - let return_pos = ctx.ref_field(AstProp::ReturnType); - let body_pos = ctx.ref_field(AstProp::Body); - let params_pos = - ctx.ref_vec_field(AstProp::Params, node.function.params.len()); - let pos = ctx.commit_schema(raw); - - let ident_id = serialize_ident(ctx, &node.ident, parent); + let ident_id = serialize_ident(ctx, &node.ident, None); let type_param_id = - maybe_serialize_ts_type_param(ctx, &node.function.type_params, pos); + maybe_serialize_ts_type_param_decl(ctx, &node.function.type_params); let return_type = - maybe_serialize_ts_type_ann(ctx, &node.function.return_type, pos); + maybe_serialize_ts_type_ann(ctx, &node.function.return_type); let body = node .function .body .as_ref() - .map(|body| serialize_stmt(ctx, &Stmt::Block(body.clone()), pos)); + .map(|body| serialize_stmt(ctx, &Stmt::Block(body.clone()))); let params = node .function .params .iter() - .map(|param| serialize_pat(ctx, ¶m.pat, pos)) + .map(|param| serialize_pat(ctx, ¶m.pat)) .collect::>(); - ctx.write_bool(declare_pos, node.declare); - ctx.write_bool(async_pos, node.function.is_async); - ctx.write_bool(gen_pos, node.function.is_generator); - ctx.write_ref(id_pos, ident_id); - ctx.write_maybe_ref(type_params_pos, type_param_id); - ctx.write_maybe_ref(return_pos, return_type); - ctx.write_maybe_ref(body_pos, body); - ctx.write_refs(params_pos, params); - - pos + ctx.write_fn_decl( + &node.function.span, + node.declare, + node.function.is_async, + node.function.is_generator, + Some(ident_id), + type_param_id, + return_type, + body, + params, + ) } Decl::Var(node) => { - let raw = ctx.header(AstNode::VariableDeclaration, parent, &node.span); - let declare_pos = ctx.bool_field(AstProp::Declare); - let kind_pos = ctx.str_field(AstProp::Kind); - let decls_pos = - ctx.ref_vec_field(AstProp::Declarations, node.decls.len()); - let id = ctx.commit_schema(raw); + let children = node + .decls + .iter() + .map(|decl| { + let ident = serialize_pat(ctx, &decl.name); + let init = decl + .init + .as_ref() + .map(|init| serialize_expr(ctx, init.as_ref())); + + ctx.write_var_declarator(&decl.span, ident, init) + }) + .collect::>(); + + let kind = match node.kind { + VarDeclKind::Var => "var", + VarDeclKind::Let => "let", + VarDeclKind::Const => "const", + }; + + ctx.write_var_decl(&node.span, node.declare, kind, children) + } + Decl::Using(node) => { + let kind = if node.is_await { + "await using" + } else { + "using" + }; let children = node .decls .iter() .map(|decl| { - let raw = ctx.header(AstNode::VariableDeclarator, id, &decl.span); - let id_pos = ctx.ref_field(AstProp::Id); - let init_pos = ctx.ref_field(AstProp::Init); - let child_id = ctx.commit_schema(raw); - - // FIXME: Definite? - - let ident = serialize_pat(ctx, &decl.name, child_id); - + let ident = serialize_pat(ctx, &decl.name); let init = decl .init .as_ref() - .map(|init| serialize_expr(ctx, init.as_ref(), child_id)); + .map(|init| serialize_expr(ctx, init.as_ref())); - ctx.write_ref(id_pos, ident); - ctx.write_maybe_ref(init_pos, init); - - child_id + ctx.write_var_declarator(&decl.span, ident, init) }) .collect::>(); - ctx.write_bool(declare_pos, node.declare); - ctx.write_str( - kind_pos, - match node.kind { - VarDeclKind::Var => "var", - VarDeclKind::Let => "let", - VarDeclKind::Const => "const", - }, - ); - ctx.write_refs(decls_pos, children); - - id - } - Decl::Using(_) => { - todo!(); + ctx.write_var_decl(&node.span, false, kind, children) } Decl::TsInterface(node) => { - let raw = ctx.header(AstNode::TSInterface, parent, &node.span); - let declare_pos = ctx.bool_field(AstProp::Declare); - let id_pos = ctx.ref_field(AstProp::Id); - let extends_pos = ctx.ref_vec_field(AstProp::Extends, node.extends.len()); - let type_param_pos = ctx.ref_field(AstProp::TypeParameters); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); - - let body_raw = ctx.header(AstNode::TSInterfaceBody, pos, &node.body.span); - let body_body_pos = - ctx.ref_vec_field(AstProp::Body, node.body.body.len()); - let body_id = ctx.commit_schema(body_raw); - - let ident_id = serialize_ident(ctx, &node.id, pos); + let ident_id = serialize_ident(ctx, &node.id, None); let type_param = - maybe_serialize_ts_type_param(ctx, &node.type_params, pos); + maybe_serialize_ts_type_param_decl(ctx, &node.type_params); let extend_ids = node .extends .iter() .map(|item| { - let raw = ctx.header(AstNode::TSInterfaceHeritage, pos, &item.span); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let expr_pos = ctx.ref_field(AstProp::Expression); - let child_pos = ctx.commit_schema(raw); + let expr = serialize_expr(ctx, &item.expr); + let type_args = item + .type_args + .clone() + .map(|params| serialize_ts_param_inst(ctx, params.as_ref())); - let expr = serialize_expr(ctx, &item.expr, child_pos); - let type_args = item.type_args.clone().map(|params| { - serialize_ts_param_inst(ctx, params.as_ref(), child_pos) - }); - - ctx.write_ref(expr_pos, expr); - ctx.write_maybe_ref(type_args_pos, type_args); - - child_pos + ctx.write_ts_interface_heritage(&item.span, expr, type_args) }) .collect::>(); @@ -1747,269 +1356,211 @@ fn serialize_decl( .body .body .iter() - .map(|item| match item { - TsTypeElement::TsCallSignatureDecl(ts_call) => { - let raw = ctx.header( - AstNode::TsCallSignatureDeclaration, - pos, - &ts_call.span, - ); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let params_pos = - ctx.ref_vec_field(AstProp::Params, ts_call.params.len()); - let return_pos = ctx.ref_field(AstProp::ReturnType); - let item_id = ctx.commit_schema(raw); - - let type_param = - maybe_serialize_ts_type_param(ctx, &ts_call.type_params, pos); - let return_type = - maybe_serialize_ts_type_ann(ctx, &ts_call.type_ann, pos); - let params = ts_call - .params - .iter() - .map(|param| serialize_ts_fn_param(ctx, param, pos)) - .collect::>(); - - ctx.write_maybe_ref(type_ann_pos, type_param); - ctx.write_refs(params_pos, params); - ctx.write_maybe_ref(return_pos, return_type); - - item_id - } - TsTypeElement::TsConstructSignatureDecl(_) => todo!(), - TsTypeElement::TsPropertySignature(sig) => { - let raw = ctx.header(AstNode::TSPropertySignature, pos, &sig.span); - - let computed_pos = ctx.bool_field(AstProp::Computed); - let optional_pos = ctx.bool_field(AstProp::Optional); - let readonly_pos = ctx.bool_field(AstProp::Readonly); - // TODO: where is this coming from? - let _static_bos = ctx.bool_field(AstProp::Static); - let key_pos = ctx.ref_field(AstProp::Key); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let item_pos = ctx.commit_schema(raw); - - let key = serialize_expr(ctx, &sig.key, item_pos); - let type_ann = - maybe_serialize_ts_type_ann(ctx, &sig.type_ann, item_pos); - - ctx.write_bool(computed_pos, sig.computed); - ctx.write_bool(optional_pos, sig.optional); - ctx.write_bool(readonly_pos, sig.readonly); - ctx.write_ref(key_pos, key); - ctx.write_maybe_ref(type_ann_pos, type_ann); - - item_pos - } - TsTypeElement::TsGetterSignature(sig) => { - let raw = ctx.header(AstNode::TSMethodSignature, pos, &sig.span); - let computed_pos = ctx.bool_field(AstProp::Computed); - let optional_pos = ctx.bool_field(AstProp::Optional); - let readonly_pos = ctx.bool_field(AstProp::Readonly); - // TODO: where is this coming from? - let _static_bos = ctx.bool_field(AstProp::Static); - let kind_pos = ctx.str_field(AstProp::Kind); - let key_pos = ctx.ref_field(AstProp::Key); - let return_type_pos = ctx.ref_field(AstProp::ReturnType); - let item_pos = ctx.commit_schema(raw); - - let key = serialize_expr(ctx, sig.key.as_ref(), item_pos); - let return_type = - maybe_serialize_ts_type_ann(ctx, &sig.type_ann, item_pos); - - ctx.write_bool(computed_pos, false); - ctx.write_bool(optional_pos, false); - ctx.write_bool(readonly_pos, false); - ctx.write_str(kind_pos, "getter"); - ctx.write_maybe_ref(return_type_pos, return_type); - ctx.write_ref(key_pos, key); - - item_pos - } - TsTypeElement::TsSetterSignature(sig) => { - let raw = ctx.header(AstNode::TSMethodSignature, pos, &sig.span); - let computed_pos = ctx.bool_field(AstProp::Computed); - let optional_pos = ctx.bool_field(AstProp::Optional); - let readonly_pos = ctx.bool_field(AstProp::Readonly); - // TODO: where is this coming from? - let _static_bos = ctx.bool_field(AstProp::Static); - let kind_pos = ctx.str_field(AstProp::Kind); - let key_pos = ctx.ref_field(AstProp::Key); - let params_pos = ctx.ref_vec_field(AstProp::Params, 1); - let item_pos = ctx.commit_schema(raw); - - let key = serialize_expr(ctx, sig.key.as_ref(), item_pos); - let params = serialize_ts_fn_param(ctx, &sig.param, item_pos); - - ctx.write_bool(computed_pos, false); - ctx.write_bool(optional_pos, false); - ctx.write_bool(readonly_pos, false); - ctx.write_str(kind_pos, "setter"); - ctx.write_ref(key_pos, key); - ctx.write_refs(params_pos, vec![params]); - - item_pos - } - TsTypeElement::TsMethodSignature(sig) => { - let raw = ctx.header(AstNode::TSMethodSignature, pos, &sig.span); - let computed_pos = ctx.bool_field(AstProp::Computed); - let optional_pos = ctx.bool_field(AstProp::Optional); - let readonly_pos = ctx.bool_field(AstProp::Readonly); - // TODO: where is this coming from? - let _static_bos = ctx.bool_field(AstProp::Static); - let kind_pos = ctx.str_field(AstProp::Kind); - let key_pos = ctx.ref_field(AstProp::Key); - let params_pos = - ctx.ref_vec_field(AstProp::Params, sig.params.len()); - let return_type_pos = ctx.ref_field(AstProp::ReturnType); - let item_pos = ctx.commit_schema(raw); - - let key = serialize_expr(ctx, sig.key.as_ref(), item_pos); - let params = sig - .params - .iter() - .map(|param| serialize_ts_fn_param(ctx, param, item_pos)) - .collect::>(); - let return_type = - maybe_serialize_ts_type_ann(ctx, &sig.type_ann, item_pos); - - ctx.write_bool(computed_pos, false); - ctx.write_bool(optional_pos, false); - ctx.write_bool(readonly_pos, false); - ctx.write_str(kind_pos, "method"); - ctx.write_ref(key_pos, key); - ctx.write_refs(params_pos, params); - ctx.write_maybe_ref(return_type_pos, return_type); - - item_pos - } - TsTypeElement::TsIndexSignature(sig) => { - serialize_ts_index_sig(ctx, sig, pos) - } - }) + .map(|item| serialize_ts_type_elem(ctx, item)) .collect::>(); - ctx.write_bool(declare_pos, node.declare); - ctx.write_ref(id_pos, ident_id); - ctx.write_maybe_ref(type_param_pos, type_param); - ctx.write_refs(extends_pos, extend_ids); - ctx.write_ref(body_pos, body_id); - - // Body - ctx.write_refs(body_body_pos, body_elem_ids); - - pos + let body_pos = + ctx.write_ts_interface_body(&node.body.span, body_elem_ids); + ctx.write_ts_interface( + &node.span, + node.declare, + ident_id, + type_param, + extend_ids, + body_pos, + ) } Decl::TsTypeAlias(node) => { - let raw = ctx.header(AstNode::TsTypeAlias, parent, &node.span); - let declare_pos = ctx.bool_field(AstProp::Declare); - let id_pos = ctx.ref_field(AstProp::Id); - let type_params_pos = ctx.ref_field(AstProp::TypeParameters); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); - - let ident = serialize_ident(ctx, &node.id, pos); - let type_ann = serialize_ts_type(ctx, &node.type_ann, pos); + let ident = serialize_ident(ctx, &node.id, None); + let type_ann = serialize_ts_type(ctx, &node.type_ann); let type_param = - maybe_serialize_ts_type_param(ctx, &node.type_params, pos); + maybe_serialize_ts_type_param_decl(ctx, &node.type_params); - ctx.write_bool(declare_pos, node.declare); - ctx.write_ref(id_pos, ident); - ctx.write_maybe_ref(type_params_pos, type_param); - ctx.write_ref(type_ann_pos, type_ann); - - pos + ctx.write_ts_type_alias( + &node.span, + node.declare, + ident, + type_param, + type_ann, + ) } Decl::TsEnum(node) => { - let raw = ctx.header(AstNode::TSEnumDeclaration, parent, &node.span); - let declare_pos = ctx.bool_field(AstProp::Declare); - let const_pos = ctx.bool_field(AstProp::Const); - let id_pos = ctx.ref_field(AstProp::Id); - let body_pos = ctx.ref_field(AstProp::Body); - let pos = ctx.commit_schema(raw); - - let body_raw = ctx.header(AstNode::TSEnumBody, pos, &node.span); - let members_pos = ctx.ref_vec_field(AstProp::Members, node.members.len()); - let body = ctx.commit_schema(body_raw); - - let ident_id = serialize_ident(ctx, &node.id, parent); + let id = serialize_ident(ctx, &node.id, None); let members = node .members .iter() .map(|member| { - let raw = ctx.header(AstNode::TSEnumMember, body, &member.span); - let id_pos = ctx.ref_field(AstProp::Id); - let init_pos = ctx.ref_field(AstProp::Initializer); - let member_id = ctx.commit_schema(raw); - let ident = match &member.id { - TsEnumMemberId::Ident(ident) => { - serialize_ident(ctx, ident, member_id) - } + TsEnumMemberId::Ident(ident) => serialize_ident(ctx, ident, None), TsEnumMemberId::Str(lit_str) => { - serialize_lit(ctx, &Lit::Str(lit_str.clone()), member_id) + serialize_lit(ctx, &Lit::Str(lit_str.clone())) } }; - let init = member - .init - .as_ref() - .map(|init| serialize_expr(ctx, init, member_id)); + let init = member.init.as_ref().map(|init| serialize_expr(ctx, init)); - ctx.write_ref(id_pos, ident); - ctx.write_maybe_ref(init_pos, init); - - member_id + ctx.write_ts_enum_member(&member.span, ident, init) }) .collect::>(); - ctx.write_refs(members_pos, members); - - ctx.write_bool(declare_pos, node.declare); - ctx.write_bool(const_pos, node.is_const); - ctx.write_ref(id_pos, ident_id); - ctx.write_ref(body_pos, body); - - pos + let body = ctx.write_ts_enum_body(&node.span, members); + ctx.write_ts_enum(&node.span, node.declare, node.is_const, id, body) } - Decl::TsModule(ts_module_decl) => { - let raw = ctx.header(AstNode::TsModule, parent, &ts_module_decl.span); - ctx.commit_schema(raw) + Decl::TsModule(node) => { + let ident = match &node.id { + TsModuleName::Ident(ident) => serialize_ident(ctx, ident, None), + TsModuleName::Str(str_lit) => { + serialize_lit(ctx, &Lit::Str(str_lit.clone())) + } + }; + + let body = node + .body + .as_ref() + .map(|body| serialize_ts_namespace_body(ctx, body)); + + ctx.write_ts_module_decl( + &node.span, + node.declare, + node.global, + ident, + body, + ) } } } +fn serialize_ts_namespace_body( + ctx: &mut TsEsTreeBuilder, + node: &TsNamespaceBody, +) -> NodeRef { + match node { + TsNamespaceBody::TsModuleBlock(mod_block) => { + let items = mod_block + .body + .iter() + .map(|item| match item { + ModuleItem::ModuleDecl(decl) => serialize_module_decl(ctx, decl), + ModuleItem::Stmt(stmt) => serialize_stmt(ctx, stmt), + }) + .collect::>(); + + ctx.write_ts_module_block(&mod_block.span, items) + } + TsNamespaceBody::TsNamespaceDecl(node) => { + let ident = serialize_ident(ctx, &node.id, None); + let body = serialize_ts_namespace_body(ctx, &node.body); + + ctx.write_ts_module_decl( + &node.span, + node.declare, + node.global, + ident, + Some(body), + ) + } + } +} + +fn serialize_ts_type_elem( + ctx: &mut TsEsTreeBuilder, + node: &TsTypeElement, +) -> NodeRef { + match node { + TsTypeElement::TsCallSignatureDecl(ts_call) => { + let type_ann = + maybe_serialize_ts_type_param_decl(ctx, &ts_call.type_params); + let return_type = maybe_serialize_ts_type_ann(ctx, &ts_call.type_ann); + let params = ts_call + .params + .iter() + .map(|param| serialize_ts_fn_param(ctx, param)) + .collect::>(); + + ctx.write_ts_call_sig_decl(&ts_call.span, type_ann, params, return_type) + } + TsTypeElement::TsConstructSignatureDecl(sig) => { + let type_params = + maybe_serialize_ts_type_param_decl(ctx, &sig.type_params); + + let params = sig + .params + .iter() + .map(|param| serialize_ts_fn_param(ctx, param)) + .collect::>(); + + // Must be present + let return_type = + maybe_serialize_ts_type_ann(ctx, &sig.type_ann).unwrap(); + + ctx.write_ts_construct_sig(&sig.span, type_params, params, return_type) + } + TsTypeElement::TsPropertySignature(sig) => { + let key = serialize_expr(ctx, &sig.key); + let type_ann = maybe_serialize_ts_type_ann(ctx, &sig.type_ann); + + ctx.write_ts_property_sig( + &sig.span, + sig.computed, + sig.optional, + sig.readonly, + key, + type_ann, + ) + } + TsTypeElement::TsGetterSignature(sig) => { + let key = serialize_expr(ctx, sig.key.as_ref()); + let return_type = maybe_serialize_ts_type_ann(ctx, &sig.type_ann); + + ctx.write_ts_getter_sig(&sig.span, key, return_type) + } + TsTypeElement::TsSetterSignature(sig) => { + let key = serialize_expr(ctx, sig.key.as_ref()); + let param = serialize_ts_fn_param(ctx, &sig.param); + + ctx.write_ts_setter_sig(&sig.span, key, param) + } + TsTypeElement::TsMethodSignature(sig) => { + let key = serialize_expr(ctx, &sig.key); + let type_parms = + maybe_serialize_ts_type_param_decl(ctx, &sig.type_params); + let params = sig + .params + .iter() + .map(|param| serialize_ts_fn_param(ctx, param)) + .collect::>(); + let return_type = maybe_serialize_ts_type_ann(ctx, &sig.type_ann); + + ctx.write_ts_method_sig( + &sig.span, + sig.computed, + sig.optional, + key, + type_parms, + params, + return_type, + ) + } + TsTypeElement::TsIndexSignature(sig) => serialize_ts_index_sig(ctx, sig), + } +} + fn serialize_ts_index_sig( ctx: &mut TsEsTreeBuilder, node: &TsIndexSignature, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::TSMethodSignature, parent, &node.span); - let readonly_pos = ctx.bool_field(AstProp::Readonly); - // TODO: where is this coming from? - let static_pos = ctx.bool_field(AstProp::Static); - let params_pos = ctx.ref_vec_field(AstProp::Params, node.params.len()); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); - - let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann, pos); - let params = node .params .iter() - .map(|param| serialize_ts_fn_param(ctx, param, pos)) + .map(|param| serialize_ts_fn_param(ctx, param)) .collect::>(); + let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann); - ctx.write_bool(readonly_pos, false); - ctx.write_bool(static_pos, node.is_static); - ctx.write_refs(params_pos, params); - ctx.write_maybe_ref(type_ann_pos, type_ann); - - pos + ctx.write_ts_index_sig(&node.span, node.readonly, params, type_ann) } -fn accessibility_to_str(accessibility: Accessibility) -> String { +fn accessibility_to_str(accessibility: &Accessibility) -> String { match accessibility { Accessibility::Public => "public".to_string(), Accessibility::Protected => "protected".to_string(), @@ -2020,106 +1571,53 @@ fn accessibility_to_str(accessibility: Accessibility) -> String { fn serialize_private_name( ctx: &mut TsEsTreeBuilder, node: &PrivateName, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::PrivateIdentifier, parent, &node.span); - let name_pos = ctx.str_field(AstProp::Name); - let pos = ctx.commit_schema(raw); - - ctx.write_str(name_pos, node.name.as_str()); - - pos + ctx.write_private_identifier(&node.span, node.name.as_str()) } fn serialize_jsx_element( ctx: &mut TsEsTreeBuilder, node: &JSXElement, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXElement, parent, &node.span); - let open_pos = ctx.ref_field(AstProp::OpeningElement); - let close_pos = ctx.ref_field(AstProp::ClosingElement); - let children_pos = ctx.ref_vec_field(AstProp::Children, node.children.len()); - let pos = ctx.commit_schema(raw); - - let open = serialize_jsx_opening_element(ctx, &node.opening, pos); + let open = serialize_jsx_opening_element(ctx, &node.opening); let close = node.closing.as_ref().map(|closing| { - let raw = ctx.header(AstNode::JSXClosingElement, pos, &closing.span); - let name_pos = ctx.ref_field(AstProp::Name); - let closing_pos = ctx.commit_schema(raw); - - let name = serialize_jsx_element_name(ctx, &closing.name, closing_pos); - ctx.write_ref(name_pos, name); - - closing_pos + let name = serialize_jsx_element_name(ctx, &closing.name); + ctx.write_jsx_closing_elem(&closing.span, name) }); - let children = serialize_jsx_children(ctx, &node.children, pos); + let children = serialize_jsx_children(ctx, &node.children); - ctx.write_ref(open_pos, open); - ctx.write_maybe_ref(close_pos, close); - ctx.write_refs(children_pos, children); - - pos + ctx.write_jsx_elem(&node.span, open, close, children) } fn serialize_jsx_fragment( ctx: &mut TsEsTreeBuilder, node: &JSXFragment, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXFragment, parent, &node.span); + let opening = ctx.write_jsx_opening_frag(&node.opening.span); + let closing = ctx.write_jsx_closing_frag(&node.closing.span); + let children = serialize_jsx_children(ctx, &node.children); - let opening_pos = ctx.ref_field(AstProp::OpeningFragment); - let closing_pos = ctx.ref_field(AstProp::ClosingFragment); - let children_pos = ctx.ref_vec_field(AstProp::Children, node.children.len()); - let pos = ctx.commit_schema(raw); - - let raw = ctx.header(AstNode::JSXOpeningFragment, pos, &node.opening.span); - let opening_id = ctx.commit_schema(raw); - - let raw = ctx.header(AstNode::JSXClosingFragment, pos, &node.closing.span); - let closing_id = ctx.commit_schema(raw); - - let children = serialize_jsx_children(ctx, &node.children, pos); - - ctx.write_ref(opening_pos, opening_id); - ctx.write_ref(closing_pos, closing_id); - ctx.write_refs(children_pos, children); - - pos + ctx.write_jsx_frag(&node.span, opening, closing, children) } fn serialize_jsx_children( ctx: &mut TsEsTreeBuilder, children: &[JSXElementChild], - parent: NodeRef, ) -> Vec { children .iter() .map(|child| { match child { JSXElementChild::JSXText(text) => { - let raw = ctx.header(AstNode::JSXText, parent, &text.span); - let raw_pos = ctx.str_field(AstProp::Raw); - let value_pos = ctx.str_field(AstProp::Value); - let pos = ctx.commit_schema(raw); - - ctx.write_str(raw_pos, &text.raw); - ctx.write_str(value_pos, &text.value); - - pos + ctx.write_jsx_text(&text.span, &text.raw, &text.value) } JSXElementChild::JSXExprContainer(container) => { - serialize_jsx_container_expr(ctx, container, parent) - } - JSXElementChild::JSXElement(el) => { - serialize_jsx_element(ctx, el, parent) - } - JSXElementChild::JSXFragment(frag) => { - serialize_jsx_fragment(ctx, frag, parent) + serialize_jsx_container_expr(ctx, container) } + JSXElementChild::JSXElement(el) => serialize_jsx_element(ctx, el), + JSXElementChild::JSXFragment(frag) => serialize_jsx_fragment(ctx, frag), // No parser supports this JSXElementChild::JSXSpreadChild(_) => unreachable!(), } @@ -2130,42 +1628,28 @@ fn serialize_jsx_children( fn serialize_jsx_member_expr( ctx: &mut TsEsTreeBuilder, node: &JSXMemberExpr, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXMemberExpression, parent, &node.span); - let obj_ref = ctx.ref_field(AstProp::Object); - let prop_ref = ctx.ref_field(AstProp::Property); - let pos = ctx.commit_schema(raw); - let obj = match &node.obj { - JSXObject::JSXMemberExpr(member) => { - serialize_jsx_member_expr(ctx, member, pos) - } - JSXObject::Ident(ident) => serialize_jsx_identifier(ctx, ident, parent), + JSXObject::JSXMemberExpr(member) => serialize_jsx_member_expr(ctx, member), + JSXObject::Ident(ident) => serialize_jsx_identifier(ctx, ident), }; - let prop = serialize_ident_name_as_jsx_identifier(ctx, &node.prop, pos); + let prop = serialize_ident_name_as_jsx_identifier(ctx, &node.prop); - ctx.write_ref(obj_ref, obj); - ctx.write_ref(prop_ref, prop); - - pos + ctx.write_jsx_member_expr(&node.span, obj, prop) } fn serialize_jsx_element_name( ctx: &mut TsEsTreeBuilder, node: &JSXElementName, - parent: NodeRef, ) -> NodeRef { match &node { - JSXElementName::Ident(ident) => { - serialize_jsx_identifier(ctx, ident, parent) - } + JSXElementName::Ident(ident) => serialize_jsx_identifier(ctx, ident), JSXElementName::JSXMemberExpr(member) => { - serialize_jsx_member_expr(ctx, member, parent) + serialize_jsx_member_expr(ctx, member) } JSXElementName::JSXNamespacedName(ns) => { - serialize_jsx_namespaced_name(ctx, ns, parent) + serialize_jsx_namespaced_name(ctx, ns) } } } @@ -2173,294 +1657,183 @@ fn serialize_jsx_element_name( fn serialize_jsx_opening_element( ctx: &mut TsEsTreeBuilder, node: &JSXOpeningElement, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXOpeningElement, parent, &node.span); - let sclose_pos = ctx.bool_field(AstProp::SelfClosing); - let name_pos = ctx.ref_field(AstProp::Name); - let attrs_pos = ctx.ref_vec_field(AstProp::Attributes, node.attrs.len()); - let pos = ctx.commit_schema(raw); + let name = serialize_jsx_element_name(ctx, &node.name); - let name = serialize_jsx_element_name(ctx, &node.name, pos); - - // FIXME: type args + let type_args = node + .type_args + .as_ref() + .map(|arg| serialize_ts_param_inst(ctx, arg)); let attrs = node .attrs .iter() .map(|attr| match attr { JSXAttrOrSpread::JSXAttr(attr) => { - let raw = ctx.header(AstNode::JSXAttribute, pos, &attr.span); - let name_pos = ctx.ref_field(AstProp::Name); - let value_pos = ctx.ref_field(AstProp::Value); - let attr_pos = ctx.commit_schema(raw); - let name = match &attr.name { JSXAttrName::Ident(name) => { - serialize_ident_name_as_jsx_identifier(ctx, name, attr_pos) + serialize_ident_name_as_jsx_identifier(ctx, name) } JSXAttrName::JSXNamespacedName(node) => { - serialize_jsx_namespaced_name(ctx, node, attr_pos) + serialize_jsx_namespaced_name(ctx, node) } }; let value = attr.value.as_ref().map(|value| match value { - JSXAttrValue::Lit(lit) => serialize_lit(ctx, lit, attr_pos), + JSXAttrValue::Lit(lit) => serialize_lit(ctx, lit), JSXAttrValue::JSXExprContainer(container) => { - serialize_jsx_container_expr(ctx, container, attr_pos) - } - JSXAttrValue::JSXElement(el) => { - serialize_jsx_element(ctx, el, attr_pos) - } - JSXAttrValue::JSXFragment(frag) => { - serialize_jsx_fragment(ctx, frag, attr_pos) + serialize_jsx_container_expr(ctx, container) } + JSXAttrValue::JSXElement(el) => serialize_jsx_element(ctx, el), + JSXAttrValue::JSXFragment(frag) => serialize_jsx_fragment(ctx, frag), }); - ctx.write_ref(name_pos, name); - ctx.write_maybe_ref(value_pos, value); - - attr_pos + ctx.write_jsx_attr(&attr.span, name, value) } JSXAttrOrSpread::SpreadElement(spread) => { - let raw = ctx.header(AstNode::JSXAttribute, pos, &spread.dot3_token); - let arg_pos = ctx.ref_field(AstProp::Argument); - let attr_pos = ctx.commit_schema(raw); - - let arg = serialize_expr(ctx, &spread.expr, attr_pos); - - ctx.write_ref(arg_pos, arg); - - attr_pos + let arg = serialize_expr(ctx, &spread.expr); + ctx.write_jsx_spread_attr(&spread.dot3_token, arg) } }) .collect::>(); - ctx.write_bool(sclose_pos, node.self_closing); - ctx.write_ref(name_pos, name); - ctx.write_refs(attrs_pos, attrs); - - pos + ctx.write_jsx_opening_elem( + &node.span, + node.self_closing, + name, + attrs, + type_args, + ) } fn serialize_jsx_container_expr( ctx: &mut TsEsTreeBuilder, node: &JSXExprContainer, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXExpressionContainer, parent, &node.span); - let expr_pos = ctx.ref_field(AstProp::Expression); - let pos = ctx.commit_schema(raw); - let expr = match &node.expr { - JSXExpr::JSXEmptyExpr(expr) => serialize_jsx_empty_expr(ctx, expr, pos), - JSXExpr::Expr(expr) => serialize_expr(ctx, expr, pos), + JSXExpr::JSXEmptyExpr(expr) => ctx.write_jsx_empty_expr(&expr.span), + JSXExpr::Expr(expr) => serialize_expr(ctx, expr), }; - ctx.write_ref(expr_pos, expr); - - pos -} - -fn serialize_jsx_empty_expr( - ctx: &mut TsEsTreeBuilder, - node: &JSXEmptyExpr, - parent: NodeRef, -) -> NodeRef { - let raw = ctx.header(AstNode::JSXEmptyExpression, parent, &node.span); - ctx.commit_schema(raw) + ctx.write_jsx_expr_container(&node.span, expr) } fn serialize_jsx_namespaced_name( ctx: &mut TsEsTreeBuilder, node: &JSXNamespacedName, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXNamespacedName, parent, &node.span); - let ns_pos = ctx.ref_field(AstProp::Namespace); - let name_pos = ctx.ref_field(AstProp::Name); - let pos = ctx.commit_schema(raw); + let ns = ctx.write_jsx_identifier(&node.ns.span, &node.ns.sym); + let name = ctx.write_jsx_identifier(&node.name.span, &node.name.sym); - let ns_id = serialize_ident_name_as_jsx_identifier(ctx, &node.ns, pos); - let name_id = serialize_ident_name_as_jsx_identifier(ctx, &node.name, pos); - - ctx.write_ref(ns_pos, ns_id); - ctx.write_ref(name_pos, name_id); - - pos + ctx.write_jsx_namespaced_name(&node.span, ns, name) } fn serialize_ident_name_as_jsx_identifier( ctx: &mut TsEsTreeBuilder, node: &IdentName, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXIdentifier, parent, &node.span); - let name_pos = ctx.str_field(AstProp::Name); - let pos = ctx.commit_schema(raw); - - ctx.write_str(name_pos, &node.sym); - - pos + ctx.write_jsx_identifier(&node.span, &node.sym) } fn serialize_jsx_identifier( ctx: &mut TsEsTreeBuilder, node: &Ident, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::JSXIdentifier, parent, &node.span); - let name_pos = ctx.str_field(AstProp::Name); - let pos = ctx.commit_schema(raw); - - ctx.write_str(name_pos, &node.sym); - - pos + ctx.write_jsx_identifier(&node.span, &node.sym) } -fn serialize_pat( - ctx: &mut TsEsTreeBuilder, - pat: &Pat, - parent: NodeRef, -) -> NodeRef { +fn serialize_pat(ctx: &mut TsEsTreeBuilder, pat: &Pat) -> NodeRef { match pat { - Pat::Ident(node) => serialize_ident(ctx, &node.id, parent), + Pat::Ident(node) => serialize_binding_ident(ctx, node), Pat::Array(node) => { - let raw = ctx.header(AstNode::ArrayPattern, parent, &node.span); - let opt_pos = ctx.bool_field(AstProp::Optional); - let type_pos = ctx.ref_field(AstProp::TypeAnnotation); - let elems_pos = ctx.ref_vec_field(AstProp::Elements, node.elems.len()); - let pos = ctx.commit_schema(raw); - - let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann, pos); + let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann); let children = node .elems .iter() - .map(|pat| { - pat - .as_ref() - .map_or(NodeRef(0), |v| serialize_pat(ctx, v, pos)) - }) + .map(|pat| pat.as_ref().map_or(NodeRef(0), |v| serialize_pat(ctx, v))) .collect::>(); - ctx.write_bool(opt_pos, node.optional); - ctx.write_maybe_ref(type_pos, type_ann); - ctx.write_refs(elems_pos, children); - - pos + ctx.write_arr_pat(&node.span, node.optional, type_ann, children) } Pat::Rest(node) => { - let raw = ctx.header(AstNode::RestElement, parent, &node.span); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); + let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann); + let arg = serialize_pat(ctx, &node.arg); - let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann, pos); - let arg = serialize_pat(ctx, &node.arg, parent); - - ctx.write_maybe_ref(type_ann_pos, type_ann); - ctx.write_ref(arg_pos, arg); - - pos + ctx.write_rest_elem(&node.span, type_ann, arg) } Pat::Object(node) => { - let raw = ctx.header(AstNode::ObjectPattern, parent, &node.span); - let opt_pos = ctx.bool_field(AstProp::Optional); - let props_pos = ctx.ref_vec_field(AstProp::Properties, node.props.len()); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); - - let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann, pos); + let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann); let children = node .props .iter() .map(|prop| match prop { ObjectPatProp::KeyValue(key_value_prop) => { - let raw = - ctx.header(AstNode::Property, pos, &key_value_prop.span()); - let computed_pos = ctx.bool_field(AstProp::Computed); - let key_pos = ctx.ref_field(AstProp::Key); - let value_pos = ctx.ref_field(AstProp::Value); - let child_pos = ctx.commit_schema(raw); - let computed = matches!(key_value_prop.key, PropName::Computed(_)); - let key = serialize_prop_name(ctx, &key_value_prop.key, child_pos); - let value = - serialize_pat(ctx, key_value_prop.value.as_ref(), child_pos); + let key = serialize_prop_name(ctx, &key_value_prop.key); + let value = serialize_pat(ctx, key_value_prop.value.as_ref()); - ctx.write_bool(computed_pos, computed); - ctx.write_ref(key_pos, key); - ctx.write_ref(value_pos, value); - - child_pos + ctx.write_property( + &key_value_prop.span(), + false, + computed, + false, + "init", + key, + value, + ) } ObjectPatProp::Assign(assign_pat_prop) => { - let raw = ctx.header(AstNode::Property, pos, &assign_pat_prop.span); - // TOOD: Doesn't seem to be present in SWC ast - let _computed_pos = ctx.bool_field(AstProp::Computed); - let key_pos = ctx.ref_field(AstProp::Key); - let value_pos = ctx.ref_field(AstProp::Value); - let child_pos = ctx.commit_schema(raw); - - let ident = serialize_ident(ctx, &assign_pat_prop.key.id, parent); + let ident = serialize_binding_ident(ctx, &assign_pat_prop.key); let value = assign_pat_prop .value .as_ref() - .map(|value| serialize_expr(ctx, value, child_pos)); + .map_or(NodeRef(0), |value| serialize_expr(ctx, value)); - ctx.write_ref(key_pos, ident); - ctx.write_maybe_ref(value_pos, value); - - child_pos + ctx.write_property( + &assign_pat_prop.span, + false, + false, + false, + "init", + ident, + value, + ) } ObjectPatProp::Rest(rest_pat) => { - serialize_pat(ctx, &Pat::Rest(rest_pat.clone()), parent) + serialize_pat(ctx, &Pat::Rest(rest_pat.clone())) } }) .collect::>(); - ctx.write_bool(opt_pos, node.optional); - ctx.write_maybe_ref(type_ann_pos, type_ann); - ctx.write_refs(props_pos, children); - - pos + ctx.write_obj_pat(&node.span, node.optional, type_ann, children) } Pat::Assign(node) => { - let raw = ctx.header(AstNode::AssignmentPattern, parent, &node.span); - let left_pos = ctx.ref_field(AstProp::Left); - let right_pos = ctx.ref_field(AstProp::Right); - let pos = ctx.commit_schema(raw); + let left = serialize_pat(ctx, &node.left); + let right = serialize_expr(ctx, &node.right); - let left = serialize_pat(ctx, &node.left, pos); - let right = serialize_expr(ctx, &node.right, pos); - - ctx.write_ref(left_pos, left); - ctx.write_ref(right_pos, right); - - pos + ctx.write_assign_pat(&node.span, left, right) } Pat::Invalid(_) => unreachable!(), - Pat::Expr(node) => serialize_expr(ctx, node, parent), + Pat::Expr(node) => serialize_expr(ctx, node), } } fn serialize_for_head( ctx: &mut TsEsTreeBuilder, for_head: &ForHead, - parent: NodeRef, ) -> NodeRef { match for_head { ForHead::VarDecl(var_decl) => { - serialize_decl(ctx, &Decl::Var(var_decl.clone()), parent) + serialize_decl(ctx, &Decl::Var(var_decl.clone())) } ForHead::UsingDecl(using_decl) => { - serialize_decl(ctx, &Decl::Using(using_decl.clone()), parent) + serialize_decl(ctx, &Decl::Using(using_decl.clone())) } - ForHead::Pat(pat) => serialize_pat(ctx, pat, parent), + ForHead::Pat(pat) => serialize_pat(ctx, pat), } } @@ -2468,471 +1841,634 @@ fn serialize_spread( ctx: &mut TsEsTreeBuilder, expr: &Expr, span: &Span, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::SpreadElement, parent, span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let pos = ctx.commit_schema(raw); - - let expr_pos = serialize_expr(ctx, expr, parent); - ctx.write_ref(arg_pos, expr_pos); - - pos + let expr = serialize_expr(ctx, expr); + ctx.write_spread(span, expr) } fn serialize_ident_name( ctx: &mut TsEsTreeBuilder, ident_name: &IdentName, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::Identifier, parent, &ident_name.span); - let name_pos = ctx.str_field(AstProp::Name); - let pos = ctx.commit_schema(raw); - - ctx.write_str(name_pos, ident_name.sym.as_str()); - - pos + ctx.write_identifier(&ident_name.span, ident_name.sym.as_str(), false, None) } fn serialize_prop_name( ctx: &mut TsEsTreeBuilder, prop_name: &PropName, - parent: NodeRef, ) -> NodeRef { match prop_name { - PropName::Ident(ident_name) => { - serialize_ident_name(ctx, ident_name, parent) - } - PropName::Str(str_prop) => { - let raw = ctx.header(AstNode::StringLiteral, parent, &str_prop.span); - let value_pos = ctx.str_field(AstProp::Value); - ctx.write_str(value_pos, &str_prop.value); - ctx.commit_schema(raw) - } - PropName::Num(number) => { - serialize_lit(ctx, &Lit::Num(number.clone()), parent) - } - PropName::Computed(node) => serialize_expr(ctx, &node.expr, parent), + PropName::Ident(ident_name) => serialize_ident_name(ctx, ident_name), + PropName::Str(str_prop) => serialize_lit(ctx, &Lit::Str(str_prop.clone())), + PropName::Num(number) => serialize_lit(ctx, &Lit::Num(number.clone())), + PropName::Computed(node) => serialize_expr(ctx, &node.expr), PropName::BigInt(big_int) => { - serialize_lit(ctx, &Lit::BigInt(big_int.clone()), parent) + serialize_lit(ctx, &Lit::BigInt(big_int.clone())) } } } -fn serialize_lit( - ctx: &mut TsEsTreeBuilder, - lit: &Lit, - parent: NodeRef, -) -> NodeRef { +fn serialize_lit(ctx: &mut TsEsTreeBuilder, lit: &Lit) -> NodeRef { match lit { Lit::Str(node) => { - let raw = ctx.header(AstNode::StringLiteral, parent, &node.span); - let value_pos = ctx.str_field(AstProp::Value); - let pos = ctx.commit_schema(raw); + let raw_value = if let Some(v) = &node.raw { + v.to_string() + } else { + format!("{}", node.value).to_string() + }; - ctx.write_str(value_pos, &node.value); - - pos - } - Lit::Bool(lit_bool) => { - let raw = ctx.header(AstNode::Bool, parent, &lit_bool.span); - let value_pos = ctx.bool_field(AstProp::Value); - let pos = ctx.commit_schema(raw); - - ctx.write_bool(value_pos, lit_bool.value); - - pos - } - Lit::Null(node) => { - let raw = ctx.header(AstNode::Null, parent, &node.span); - ctx.commit_schema(raw) + ctx.write_str_lit(&node.span, &node.value, &raw_value) } + Lit::Bool(node) => ctx.write_bool_lit(&node.span, node.value), + Lit::Null(node) => ctx.write_null_lit(&node.span), Lit::Num(node) => { - let raw = ctx.header(AstNode::NumericLiteral, parent, &node.span); - let value_pos = ctx.str_field(AstProp::Value); - let pos = ctx.commit_schema(raw); + let raw_value = if let Some(v) = &node.raw { + v.to_string() + } else { + format!("{}", node.value).to_string() + }; let value = node.raw.as_ref().unwrap(); - ctx.write_str(value_pos, value); - - pos + ctx.write_num_lit(&node.span, value, &raw_value) } Lit::BigInt(node) => { - let raw = ctx.header(AstNode::BigIntLiteral, parent, &node.span); - let value_pos = ctx.str_field(AstProp::Value); - let pos = ctx.commit_schema(raw); + let raw_bigint_value = if let Some(v) = &node.raw { + let mut s = v.to_string(); + s.pop(); + s.to_string() + } else { + format!("{}", node.value).to_string() + }; - ctx.write_str(value_pos, &node.value.to_string()); + let raw_value = if let Some(v) = &node.raw { + v.to_string() + } else { + format!("{}", node.value).to_string() + }; - pos + ctx.write_bigint_lit( + &node.span, + &node.value.to_string(), + &raw_value, + &raw_bigint_value, + ) } Lit::Regex(node) => { - let raw = ctx.header(AstNode::RegExpLiteral, parent, &node.span); - let pattern_pos = ctx.str_field(AstProp::Pattern); - let flags_pos = ctx.str_field(AstProp::Flags); - let pos = ctx.commit_schema(raw); + let raw = format!("/{}/{}", node.exp.as_str(), node.flags.as_str()); - ctx.write_str(pattern_pos, node.exp.as_str()); - ctx.write_str(flags_pos, node.flags.as_str()); - - pos + ctx.write_regex_lit( + &node.span, + node.exp.as_str(), + node.flags.as_str(), + &raw, + &raw, + ) } - Lit::JSXText(jsxtext) => { - let raw = ctx.header(AstNode::JSXText, parent, &jsxtext.span); - ctx.commit_schema(raw) + Lit::JSXText(node) => { + ctx.write_jsx_text(&node.span, &node.raw, &node.value) } } } +fn serialize_class_member( + ctx: &mut TsEsTreeBuilder, + member: &ClassMember, +) -> Option { + match member { + ClassMember::Constructor(node) => { + let a11y = node.accessibility.as_ref().map(accessibility_to_str); + + let key = serialize_prop_name(ctx, &node.key); + let params = node + .params + .iter() + .map(|param| match param { + ParamOrTsParamProp::TsParamProp(prop) => { + let a11y = node.accessibility.as_ref().map(accessibility_to_str); + + let decorators = prop + .decorators + .iter() + .map(|deco| serialize_decorator(ctx, deco)) + .collect::>(); + + let paramter = match &prop.param { + TsParamPropParam::Ident(binding_ident) => { + serialize_binding_ident(ctx, binding_ident) + } + TsParamPropParam::Assign(assign_pat) => { + serialize_pat(ctx, &Pat::Assign(assign_pat.clone())) + } + }; + + ctx.write_ts_param_prop( + &prop.span, + prop.is_override, + prop.readonly, + a11y, + decorators, + paramter, + ) + } + ParamOrTsParamProp::Param(param) => serialize_pat(ctx, ¶m.pat), + }) + .collect::>(); + + let body = node + .body + .as_ref() + .map(|body| serialize_stmt(ctx, &Stmt::Block(body.clone()))); + + let value = ctx.write_fn_expr( + &node.span, false, false, None, None, params, None, body, + ); + + Some(ctx.write_class_method( + &node.span, + false, + false, + node.is_optional, + false, + false, + "constructor", + a11y, + key, + value, + )) + } + ClassMember::Method(node) => { + let key = serialize_prop_name(ctx, &node.key); + + Some(serialize_class_method( + ctx, + &node.span, + node.is_abstract, + node.is_override, + node.is_optional, + node.is_static, + node.accessibility, + &node.kind, + key, + &node.function, + )) + } + ClassMember::PrivateMethod(node) => { + let key = serialize_private_name(ctx, &node.key); + + Some(serialize_class_method( + ctx, + &node.span, + node.is_abstract, + node.is_override, + node.is_optional, + node.is_static, + node.accessibility, + &node.kind, + key, + &node.function, + )) + } + ClassMember::ClassProp(node) => { + let a11y = node.accessibility.as_ref().map(accessibility_to_str); + + let key = serialize_prop_name(ctx, &node.key); + let value = node.value.as_ref().map(|expr| serialize_expr(ctx, expr)); + + let decorators = node + .decorators + .iter() + .map(|deco| serialize_decorator(ctx, deco)) + .collect::>(); + + Some(ctx.write_class_prop( + &node.span, + node.declare, + false, + node.is_optional, + node.is_override, + node.readonly, + node.is_static, + a11y, + decorators, + key, + value, + )) + } + ClassMember::PrivateProp(node) => { + let a11y = node.accessibility.as_ref().map(accessibility_to_str); + + let decorators = node + .decorators + .iter() + .map(|deco| serialize_decorator(ctx, deco)) + .collect::>(); + + let key = serialize_private_name(ctx, &node.key); + + let value = node.value.as_ref().map(|expr| serialize_expr(ctx, expr)); + + Some(ctx.write_class_prop( + &node.span, + false, + false, + node.is_optional, + node.is_override, + node.readonly, + node.is_static, + a11y, + decorators, + key, + value, + )) + } + ClassMember::TsIndexSignature(node) => { + Some(serialize_ts_index_sig(ctx, node)) + } + ClassMember::Empty(_) => None, + ClassMember::StaticBlock(node) => { + let body = serialize_stmt(ctx, &Stmt::Block(node.body.clone())); + Some(ctx.write_static_block(&node.span, body)) + } + ClassMember::AutoAccessor(node) => { + let a11y = node.accessibility.as_ref().map(accessibility_to_str); + let decorators = node + .decorators + .iter() + .map(|deco| serialize_decorator(ctx, deco)) + .collect::>(); + + let key = match &node.key { + Key::Private(private_name) => serialize_private_name(ctx, private_name), + Key::Public(prop_name) => serialize_prop_name(ctx, prop_name), + }; + + let value = node.value.as_ref().map(|expr| serialize_expr(ctx, expr)); + + Some(ctx.write_accessor_property( + &node.span, + false, + false, + false, + node.is_override, + false, + node.is_static, + a11y, + decorators, + key, + value, + )) + } + } +} + +#[allow(clippy::too_many_arguments)] +fn serialize_class_method( + ctx: &mut TsEsTreeBuilder, + span: &Span, + is_abstract: bool, + is_override: bool, + is_optional: bool, + is_static: bool, + accessibility: Option, + method_kind: &MethodKind, + key: NodeRef, + function: &Function, +) -> NodeRef { + let kind = match method_kind { + MethodKind::Method => "method", + MethodKind::Getter => "getter", + MethodKind::Setter => "setter", + }; + + let type_params = + maybe_serialize_ts_type_param_decl(ctx, &function.type_params); + let params = function + .params + .iter() + .map(|param| serialize_pat(ctx, ¶m.pat)) + .collect::>(); + + let return_type = maybe_serialize_ts_type_ann(ctx, &function.return_type); + + let body = function + .body + .as_ref() + .map(|body| serialize_stmt(ctx, &Stmt::Block(body.clone()))); + + let value = if let Some(body) = body { + ctx.write_fn_expr( + &function.span, + function.is_async, + function.is_generator, + None, + type_params, + params, + return_type, + Some(body), + ) + } else { + ctx.write_ts_empty_body_fn_expr( + span, + false, + false, + function.is_async, + function.is_generator, + None, + type_params, + params, + return_type, + ) + }; + + let a11y = accessibility.as_ref().map(accessibility_to_str); + + if is_abstract { + ctx.write_ts_abstract_method_def( + span, + false, + is_optional, + is_override, + false, + a11y, + key, + value, + ) + } else { + ctx.write_class_method( + span, + false, + false, + is_optional, + is_override, + is_static, + kind, + a11y, + key, + value, + ) + } +} + +fn serialize_ts_expr_with_type_args( + ctx: &mut TsEsTreeBuilder, + node: &TsExprWithTypeArgs, +) -> NodeRef { + let expr = serialize_expr(ctx, &node.expr); + let type_args = node + .type_args + .as_ref() + .map(|arg| serialize_ts_param_inst(ctx, arg)); + + ctx.write_ts_class_implements(&node.span, expr, type_args) +} + +fn serialize_decorator(ctx: &mut TsEsTreeBuilder, node: &Decorator) -> NodeRef { + let expr = serialize_expr(ctx, &node.expr); + ctx.write_decorator(&node.span, expr) +} + +fn serialize_binding_ident( + ctx: &mut TsEsTreeBuilder, + node: &BindingIdent, +) -> NodeRef { + let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann); + ctx.write_identifier(&node.span, &node.sym, node.optional, type_ann) +} + fn serialize_ts_param_inst( ctx: &mut TsEsTreeBuilder, node: &TsTypeParamInstantiation, - parent: NodeRef, ) -> NodeRef { - let raw = - ctx.header(AstNode::TSTypeParameterInstantiation, parent, &node.span); - let params_pos = ctx.ref_vec_field(AstProp::Params, node.params.len()); - let pos = ctx.commit_schema(raw); - let params = node .params .iter() - .map(|param| serialize_ts_type(ctx, param, pos)) + .map(|param| serialize_ts_type(ctx, param)) .collect::>(); - ctx.write_refs(params_pos, params); - - pos + ctx.write_ts_type_param_inst(&node.span, params) } -fn serialize_ts_type( - ctx: &mut TsEsTreeBuilder, - node: &TsType, - parent: NodeRef, -) -> NodeRef { +fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef { match node { TsType::TsKeywordType(node) => { let kind = match node.kind { - TsKeywordTypeKind::TsAnyKeyword => AstNode::TSAnyKeyword, - TsKeywordTypeKind::TsUnknownKeyword => AstNode::TSUnknownKeyword, - TsKeywordTypeKind::TsNumberKeyword => AstNode::TSNumberKeyword, - TsKeywordTypeKind::TsObjectKeyword => AstNode::TSObjectKeyword, - TsKeywordTypeKind::TsBooleanKeyword => AstNode::TSBooleanKeyword, - TsKeywordTypeKind::TsBigIntKeyword => AstNode::TSBigIntKeyword, - TsKeywordTypeKind::TsStringKeyword => AstNode::TSStringKeyword, - TsKeywordTypeKind::TsSymbolKeyword => AstNode::TSSymbolKeyword, - TsKeywordTypeKind::TsVoidKeyword => AstNode::TSVoidKeyword, - TsKeywordTypeKind::TsUndefinedKeyword => AstNode::TSUndefinedKeyword, - TsKeywordTypeKind::TsNullKeyword => AstNode::TSNullKeyword, - TsKeywordTypeKind::TsNeverKeyword => AstNode::TSNeverKeyword, - TsKeywordTypeKind::TsIntrinsicKeyword => AstNode::TSIntrinsicKeyword, + TsKeywordTypeKind::TsAnyKeyword => TsKeywordKind::Any, + TsKeywordTypeKind::TsUnknownKeyword => TsKeywordKind::Unknown, + TsKeywordTypeKind::TsNumberKeyword => TsKeywordKind::Number, + TsKeywordTypeKind::TsObjectKeyword => TsKeywordKind::Object, + TsKeywordTypeKind::TsBooleanKeyword => TsKeywordKind::Boolean, + TsKeywordTypeKind::TsBigIntKeyword => TsKeywordKind::BigInt, + TsKeywordTypeKind::TsStringKeyword => TsKeywordKind::String, + TsKeywordTypeKind::TsSymbolKeyword => TsKeywordKind::Symbol, + TsKeywordTypeKind::TsVoidKeyword => TsKeywordKind::Void, + TsKeywordTypeKind::TsUndefinedKeyword => TsKeywordKind::Undefined, + TsKeywordTypeKind::TsNullKeyword => TsKeywordKind::Null, + TsKeywordTypeKind::TsNeverKeyword => TsKeywordKind::Never, + TsKeywordTypeKind::TsIntrinsicKeyword => TsKeywordKind::Intrinsic, }; - let raw = ctx.header(kind, parent, &node.span); - ctx.commit_schema(raw) - } - TsType::TsThisType(node) => { - let raw = ctx.header(AstNode::TSThisType, parent, &node.span); - ctx.commit_schema(raw) + ctx.write_ts_keyword(kind, &node.span) } + TsType::TsThisType(node) => ctx.write_ts_this_type(&node.span), TsType::TsFnOrConstructorType(node) => match node { TsFnOrConstructorType::TsFnType(node) => { - let raw = ctx.header(AstNode::TSFunctionType, parent, &node.span); - let params_pos = ctx.ref_vec_field(AstProp::Params, node.params.len()); - let pos = ctx.commit_schema(raw); - let param_ids = node .params .iter() - .map(|param| serialize_ts_fn_param(ctx, param, pos)) + .map(|param| serialize_ts_fn_param(ctx, param)) .collect::>(); - ctx.write_refs(params_pos, param_ids); - - pos + ctx.write_ts_fn_type(&node.span, param_ids) } - TsFnOrConstructorType::TsConstructorType(_) => { - todo!() + TsFnOrConstructorType::TsConstructorType(node) => { + // interface Foo { new(arg1: any): any } + let type_params = node + .type_params + .as_ref() + .map(|param| serialize_ts_type_param_decl(ctx, param)); + + let params = node + .params + .iter() + .map(|param| serialize_ts_fn_param(ctx, param)) + .collect::>(); + + let return_type = serialize_ts_type_ann(ctx, node.type_ann.as_ref()); + + ctx.write_ts_construct_sig(&node.span, type_params, params, return_type) } }, TsType::TsTypeRef(node) => { - let raw = ctx.header(AstNode::TSTypeReference, parent, &node.span); - let name_pos = ctx.ref_field(AstProp::TypeName); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let pos = ctx.commit_schema(raw); - - let name = serialize_ts_entity_name(ctx, &node.type_name, pos); + let name = serialize_ts_entity_name(ctx, &node.type_name); let type_args = node .type_params .clone() - .map(|param| serialize_ts_param_inst(ctx, ¶m, pos)); + .map(|param| serialize_ts_param_inst(ctx, ¶m)); - ctx.write_ref(name_pos, name); - ctx.write_maybe_ref(type_args_pos, type_args); - - pos + ctx.write_ts_type_ref(&node.span, name, type_args) } TsType::TsTypeQuery(node) => { - let raw = ctx.header(AstNode::TSTypeQuery, parent, &node.span); - let name_pos = ctx.ref_field(AstProp::ExprName); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let pos = ctx.commit_schema(raw); - let expr_name = match &node.expr_name { TsTypeQueryExpr::TsEntityName(entity) => { - serialize_ts_entity_name(ctx, entity, pos) + serialize_ts_entity_name(ctx, entity) } TsTypeQueryExpr::Import(child) => { - serialize_ts_type(ctx, &TsType::TsImportType(child.clone()), pos) + serialize_ts_type(ctx, &TsType::TsImportType(child.clone())) } }; let type_args = node .type_args .clone() - .map(|param| serialize_ts_param_inst(ctx, ¶m, pos)); + .map(|param| serialize_ts_param_inst(ctx, ¶m)); - ctx.write_ref(name_pos, expr_name); - ctx.write_maybe_ref(type_args_pos, type_args); - - pos + ctx.write_ts_type_query(&node.span, expr_name, type_args) } - TsType::TsTypeLit(_) => { - // TODO: Not sure what this is - todo!() + TsType::TsTypeLit(node) => { + let members = node + .members + .iter() + .map(|member| serialize_ts_type_elem(ctx, member)) + .collect::>(); + + ctx.write_ts_type_lit(&node.span, members) } TsType::TsArrayType(node) => { - let raw = ctx.header(AstNode::TSArrayType, parent, &node.span); - let elem_pos = ctx.ref_field(AstProp::ElementType); - let pos = ctx.commit_schema(raw); - - let elem = serialize_ts_type(ctx, &node.elem_type, pos); - - ctx.write_ref(elem_pos, elem); - - pos + let elem = serialize_ts_type(ctx, &node.elem_type); + ctx.write_ts_array_type(&node.span, elem) } TsType::TsTupleType(node) => { - let raw = ctx.header(AstNode::TSTupleType, parent, &node.span); - let children_pos = - ctx.ref_vec_field(AstProp::ElementTypes, node.elem_types.len()); - let pos = ctx.commit_schema(raw); - let children = node .elem_types .iter() .map(|elem| { if let Some(label) = &elem.label { - let raw = ctx.header(AstNode::TSNamedTupleMember, pos, &elem.span); - let label_pos = ctx.ref_field(AstProp::Label); - let type_pos = ctx.ref_field(AstProp::ElementType); - let child_pos = ctx.commit_schema(raw); + let label = serialize_pat(ctx, label); + let type_id = serialize_ts_type(ctx, elem.ty.as_ref()); - let label_id = serialize_pat(ctx, label, child_pos); - let type_id = serialize_ts_type(ctx, elem.ty.as_ref(), child_pos); - - ctx.write_ref(label_pos, label_id); - ctx.write_ref(type_pos, type_id); - - child_pos + ctx.write_ts_named_tuple_member(&elem.span, label, type_id) } else { - serialize_ts_type(ctx, elem.ty.as_ref(), pos) + serialize_ts_type(ctx, elem.ty.as_ref()) } }) .collect::>(); - ctx.write_refs(children_pos, children); - - pos + ctx.write_ts_tuple_type(&node.span, children) + } + TsType::TsOptionalType(node) => { + let type_ann = serialize_ts_type(ctx, &node.type_ann); + ctx.write_ts_optional_type(&node.span, type_ann) } - TsType::TsOptionalType(_) => todo!(), TsType::TsRestType(node) => { - let raw = ctx.header(AstNode::TSRestType, parent, &node.span); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); - - let type_ann = serialize_ts_type(ctx, &node.type_ann, pos); - - ctx.write_ref(type_ann_pos, type_ann); - - pos + let type_ann = serialize_ts_type(ctx, &node.type_ann); + ctx.write_ts_rest_type(&node.span, type_ann) } TsType::TsUnionOrIntersectionType(node) => match node { TsUnionOrIntersectionType::TsUnionType(node) => { - let raw = ctx.header(AstNode::TSUnionType, parent, &node.span); - let types_pos = ctx.ref_vec_field(AstProp::Types, node.types.len()); - let pos = ctx.commit_schema(raw); - let children = node .types .iter() - .map(|item| serialize_ts_type(ctx, item, pos)) + .map(|item| serialize_ts_type(ctx, item)) .collect::>(); - ctx.write_refs(types_pos, children); - - pos + ctx.write_ts_union_type(&node.span, children) } TsUnionOrIntersectionType::TsIntersectionType(node) => { - let raw = ctx.header(AstNode::TSIntersectionType, parent, &node.span); - let types_pos = ctx.ref_vec_field(AstProp::Types, node.types.len()); - let pos = ctx.commit_schema(raw); - let children = node .types .iter() - .map(|item| serialize_ts_type(ctx, item, pos)) + .map(|item| serialize_ts_type(ctx, item)) .collect::>(); - ctx.write_refs(types_pos, children); - - pos + ctx.write_ts_intersection_type(&node.span, children) } }, TsType::TsConditionalType(node) => { - let raw = ctx.header(AstNode::TSConditionalType, parent, &node.span); - let check_pos = ctx.ref_field(AstProp::CheckType); - let extends_pos = ctx.ref_field(AstProp::ExtendsType); - let true_pos = ctx.ref_field(AstProp::TrueType); - let false_pos = ctx.ref_field(AstProp::FalseType); - let pos = ctx.commit_schema(raw); + let check = serialize_ts_type(ctx, &node.check_type); + let extends = serialize_ts_type(ctx, &node.extends_type); + let v_true = serialize_ts_type(ctx, &node.true_type); + let v_false = serialize_ts_type(ctx, &node.false_type); - let check = serialize_ts_type(ctx, &node.check_type, pos); - let extends = serialize_ts_type(ctx, &node.extends_type, pos); - let v_true = serialize_ts_type(ctx, &node.true_type, pos); - let v_false = serialize_ts_type(ctx, &node.false_type, pos); - - ctx.write_ref(check_pos, check); - ctx.write_ref(extends_pos, extends); - ctx.write_ref(true_pos, v_true); - ctx.write_ref(false_pos, v_false); - - pos + ctx.write_ts_conditional_type(&node.span, check, extends, v_true, v_false) } TsType::TsInferType(node) => { - let raw = ctx.header(AstNode::TSInferType, parent, &node.span); - let param_pos = ctx.ref_field(AstProp::TypeParameter); - let pos = ctx.commit_schema(raw); - - let param = serialize_ts_type_param(ctx, &node.type_param, parent); - - ctx.write_ref(param_pos, param); - - pos + let param = serialize_ts_type_param(ctx, &node.type_param); + ctx.write_ts_infer_type(&node.span, param) + } + TsType::TsParenthesizedType(node) => { + // Not materialized in TSEstree + serialize_ts_type(ctx, &node.type_ann) } - TsType::TsParenthesizedType(_) => todo!(), TsType::TsTypeOperator(node) => { - let raw = ctx.header(AstNode::TSTypeOperator, parent, &node.span); - let operator_pos = ctx.str_field(AstProp::Operator); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); + let type_ann = serialize_ts_type(ctx, &node.type_ann); - let type_ann = serialize_ts_type(ctx, &node.type_ann, pos); - - ctx.write_str( - operator_pos, - match node.op { - TsTypeOperatorOp::KeyOf => "keyof", - TsTypeOperatorOp::Unique => "unique", - TsTypeOperatorOp::ReadOnly => "readonly", - }, - ); - ctx.write_ref(type_ann_pos, type_ann); - - pos - } - TsType::TsIndexedAccessType(node) => { - let raw = ctx.header(AstNode::TSIndexedAccessType, parent, &node.span); - let index_type_pos = ctx.ref_field(AstProp::IndexType); - let obj_type_pos = ctx.ref_field(AstProp::ObjectType); - let pos = ctx.commit_schema(raw); - - let index = serialize_ts_type(ctx, &node.index_type, pos); - let obj = serialize_ts_type(ctx, &node.obj_type, pos); - - ctx.write_ref(index_type_pos, index); - ctx.write_ref(obj_type_pos, obj); - - pos - } - TsType::TsMappedType(node) => { - let raw = ctx.header(AstNode::TSMappedType, parent, &node.span); - let name_pos = ctx.ref_field(AstProp::NameType); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let type_param_pos = ctx.ref_field(AstProp::TypeParameter); - let pos = ctx.commit_schema(raw); - - let opt_pos = - create_true_plus_minus_field(ctx, AstProp::Optional, node.optional); - let readonly_pos = - create_true_plus_minus_field(ctx, AstProp::Readonly, node.readonly); - - let name_id = maybe_serialize_ts_type(ctx, &node.name_type, pos); - let type_ann = maybe_serialize_ts_type(ctx, &node.type_ann, pos); - let type_param = serialize_ts_type_param(ctx, &node.type_param, pos); - - write_true_plus_minus(ctx, opt_pos, node.optional); - write_true_plus_minus(ctx, readonly_pos, node.readonly); - ctx.write_maybe_ref(name_pos, name_id); - ctx.write_maybe_ref(type_ann_pos, type_ann); - ctx.write_ref(type_param_pos, type_param); - - pos - } - TsType::TsLitType(node) => serialize_ts_lit_type(ctx, node, parent), - TsType::TsTypePredicate(node) => { - let raw = ctx.header(AstNode::TSTypePredicate, parent, &node.span); - let asserts_pos = ctx.bool_field(AstProp::Asserts); - let param_name_pos = ctx.ref_field(AstProp::ParameterName); - let type_ann_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); - - let param_name = match &node.param_name { - TsThisTypeOrIdent::TsThisType(ts_this_type) => { - let raw = ctx.header(AstNode::TSThisType, pos, &ts_this_type.span); - ctx.commit_schema(raw) - } - TsThisTypeOrIdent::Ident(ident) => serialize_ident(ctx, ident, pos), + let op = match node.op { + TsTypeOperatorOp::KeyOf => "keyof", + TsTypeOperatorOp::Unique => "unique", + TsTypeOperatorOp::ReadOnly => "readonly", }; - let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann, pos); + ctx.write_ts_type_op(&node.span, op, type_ann) + } + TsType::TsIndexedAccessType(node) => { + let index = serialize_ts_type(ctx, &node.index_type); + let obj = serialize_ts_type(ctx, &node.obj_type); - ctx.write_bool(asserts_pos, node.asserts); - ctx.write_ref(param_name_pos, param_name); - ctx.write_maybe_ref(type_ann_pos, type_ann); + ctx.write_ts_indexed_access_type(&node.span, index, obj) + } + TsType::TsMappedType(node) => { + let name = maybe_serialize_ts_type(ctx, &node.name_type); + let type_ann = maybe_serialize_ts_type(ctx, &node.type_ann); + let type_param = serialize_ts_type_param(ctx, &node.type_param); - pos + ctx.write_ts_mapped_type( + &node.span, + node.readonly, + node.optional, + name, + type_ann, + type_param, + ) + } + TsType::TsLitType(node) => serialize_ts_lit_type(ctx, node), + TsType::TsTypePredicate(node) => { + let param_name = match &node.param_name { + TsThisTypeOrIdent::TsThisType(node) => { + ctx.write_ts_this_type(&node.span) + } + TsThisTypeOrIdent::Ident(ident) => serialize_ident(ctx, ident, None), + }; + + let type_ann = maybe_serialize_ts_type_ann(ctx, &node.type_ann); + + ctx.write_ts_type_predicate( + &node.span, + node.asserts, + param_name, + type_ann, + ) } TsType::TsImportType(node) => { - let raw = ctx.header(AstNode::TSTypePredicate, parent, &node.span); - let arg_pos = ctx.ref_field(AstProp::Argument); - let type_args_pos = ctx.ref_field(AstProp::TypeArguments); - let qualifier_pos = ctx.ref_field(AstProp::Qualifier); - let pos = ctx.commit_schema(raw); - let arg = serialize_ts_lit_type( ctx, &TsLitType { lit: TsLit::Str(node.arg.clone()), span: node.arg.span, }, - pos, ); - let type_arg = node.type_args.clone().map(|param_node| { - serialize_ts_param_inst(ctx, param_node.as_ref(), pos) - }); + let type_arg = node + .type_args + .clone() + .map(|param_node| serialize_ts_param_inst(ctx, param_node.as_ref())); - let qualifier = node.qualifier.clone().map_or(NodeRef(0), |quali| { - serialize_ts_entity_name(ctx, &quali, pos) - }); + let qualifier = node + .qualifier + .clone() + .map(|quali| serialize_ts_entity_name(ctx, &quali)); - ctx.write_ref(arg_pos, arg); - ctx.write_ref(qualifier_pos, qualifier); - ctx.write_maybe_ref(type_args_pos, type_arg); - - pos + ctx.write_ts_import_type(&node.span, arg, qualifier, type_arg) } } } @@ -2940,80 +2476,47 @@ fn serialize_ts_type( fn serialize_ts_lit_type( ctx: &mut TsEsTreeBuilder, node: &TsLitType, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::TSLiteralType, parent, &node.span); - let lit_pos = ctx.ref_field(AstProp::Literal); - let pos = ctx.commit_schema(raw); - - let lit = match &node.lit { - TsLit::Number(lit) => serialize_lit(ctx, &Lit::Num(lit.clone()), pos), - TsLit::Str(lit) => serialize_lit(ctx, &Lit::Str(lit.clone()), pos), - TsLit::Bool(lit) => serialize_lit(ctx, &Lit::Bool(*lit), pos), - TsLit::BigInt(lit) => serialize_lit(ctx, &Lit::BigInt(lit.clone()), pos), - TsLit::Tpl(lit) => serialize_expr( - ctx, - &Expr::Tpl(Tpl { - span: lit.span, - exprs: vec![], - quasis: lit.quasis.clone(), - }), - pos, - ), - }; - - ctx.write_ref(lit_pos, lit); - - pos -} - -fn create_true_plus_minus_field( - ctx: &mut TsEsTreeBuilder, - prop: AstProp, - value: Option, -) -> NodePos { - if let Some(v) = value { - match v { - TruePlusMinus::True => NodePos::Bool(ctx.bool_field(prop)), - TruePlusMinus::Plus | TruePlusMinus::Minus => { - NodePos::Str(ctx.str_field(prop)) - } + match &node.lit { + TsLit::Number(lit) => { + let lit = serialize_lit(ctx, &Lit::Num(lit.clone())); + ctx.write_ts_lit_type(&node.span, lit) } - } else { - NodePos::Undef(ctx.undefined_field(prop)) - } -} + TsLit::Str(lit) => { + let lit = serialize_lit(ctx, &Lit::Str(lit.clone())); + ctx.write_ts_lit_type(&node.span, lit) + } + TsLit::Bool(lit) => { + let lit = serialize_lit(ctx, &Lit::Bool(*lit)); + ctx.write_ts_lit_type(&node.span, lit) + } + TsLit::BigInt(lit) => { + let lit = serialize_lit(ctx, &Lit::BigInt(lit.clone())); + ctx.write_ts_lit_type(&node.span, lit) + } + TsLit::Tpl(lit) => { + let quasis = lit + .quasis + .iter() + .map(|quasi| { + ctx.write_template_elem( + &quasi.span, + quasi.tail, + &quasi.raw, + &quasi + .cooked + .as_ref() + .map_or("".to_string(), |v| v.to_string()), + ) + }) + .collect::>(); + let types = lit + .types + .iter() + .map(|ts_type| serialize_ts_type(ctx, ts_type)) + .collect::>(); -fn extract_pos(pos: NodePos) -> usize { - match pos { - NodePos::Bool(bool_pos) => bool_pos.0, - NodePos::Field(field_pos) => field_pos.0, - NodePos::FieldArr(field_arr_pos) => field_arr_pos.0, - NodePos::Str(str_pos) => str_pos.0, - NodePos::Undef(undef_pos) => undef_pos.0, - NodePos::Null(null_pos) => null_pos.0, - } -} - -fn write_true_plus_minus( - ctx: &mut TsEsTreeBuilder, - pos: NodePos, - value: Option, -) { - if let Some(v) = value { - match v { - TruePlusMinus::True => { - let bool_pos = BoolPos(extract_pos(pos)); - ctx.write_bool(bool_pos, true); - } - TruePlusMinus::Plus => { - let str_pos = StrPos(extract_pos(pos)); - ctx.write_str(str_pos, "+") - } - TruePlusMinus::Minus => { - let str_pos = StrPos(extract_pos(pos)); - ctx.write_str(str_pos, "-") - } + ctx.write_ts_tpl_lit(&node.span, quasis, types) } } } @@ -3021,114 +2524,91 @@ fn write_true_plus_minus( fn serialize_ts_entity_name( ctx: &mut TsEsTreeBuilder, node: &TsEntityName, - parent: NodeRef, ) -> NodeRef { match &node { - TsEntityName::TsQualifiedName(_) => todo!(), - TsEntityName::Ident(ident) => serialize_ident(ctx, ident, parent), + TsEntityName::TsQualifiedName(node) => { + let left = serialize_ts_entity_name(ctx, &node.left); + let right = serialize_ident_name(ctx, &node.right); + + ctx.write_ts_qualified_name(&node.span, left, right) + } + TsEntityName::Ident(ident) => serialize_ident(ctx, ident, None), } } fn maybe_serialize_ts_type_ann( ctx: &mut TsEsTreeBuilder, node: &Option>, - parent: NodeRef, ) -> Option { node .as_ref() - .map(|type_ann| serialize_ts_type_ann(ctx, type_ann, parent)) + .map(|type_ann| serialize_ts_type_ann(ctx, type_ann)) } fn serialize_ts_type_ann( ctx: &mut TsEsTreeBuilder, node: &TsTypeAnn, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::TSTypeAnnotation, parent, &node.span); - let type_pos = ctx.ref_field(AstProp::TypeAnnotation); - let pos = ctx.commit_schema(raw); - - let v_type = serialize_ts_type(ctx, &node.type_ann, pos); - - ctx.write_ref(type_pos, v_type); - - pos + let v_type = serialize_ts_type(ctx, &node.type_ann); + ctx.write_ts_type_ann(&node.span, v_type) } fn maybe_serialize_ts_type( ctx: &mut TsEsTreeBuilder, node: &Option>, - parent: NodeRef, ) -> Option { - node - .as_ref() - .map(|item| serialize_ts_type(ctx, item, parent)) + node.as_ref().map(|item| serialize_ts_type(ctx, item)) } fn serialize_ts_type_param( ctx: &mut TsEsTreeBuilder, node: &TsTypeParam, - parent: NodeRef, ) -> NodeRef { - let raw = ctx.header(AstNode::TSTypeParameter, parent, &node.span); - let name_pos = ctx.ref_field(AstProp::Name); - let constraint_pos = ctx.ref_field(AstProp::Constraint); - let default_pos = ctx.ref_field(AstProp::Default); - let const_pos = ctx.bool_field(AstProp::Const); - let in_pos = ctx.bool_field(AstProp::In); - let out_pos = ctx.bool_field(AstProp::Out); - let pos = ctx.commit_schema(raw); + let name = serialize_ident(ctx, &node.name, None); + let constraint = maybe_serialize_ts_type(ctx, &node.constraint); + let default = maybe_serialize_ts_type(ctx, &node.default); - let name = serialize_ident(ctx, &node.name, pos); - let constraint = maybe_serialize_ts_type(ctx, &node.constraint, pos); - let default = maybe_serialize_ts_type(ctx, &node.default, pos); - - ctx.write_bool(const_pos, node.is_const); - ctx.write_bool(in_pos, node.is_in); - ctx.write_bool(out_pos, node.is_out); - ctx.write_ref(name_pos, name); - ctx.write_maybe_ref(constraint_pos, constraint); - ctx.write_maybe_ref(default_pos, default); - - pos + ctx.write_ts_type_param( + &node.span, + node.is_in, + node.is_out, + node.is_const, + name, + constraint, + default, + ) } -fn maybe_serialize_ts_type_param( +fn maybe_serialize_ts_type_param_decl( ctx: &mut TsEsTreeBuilder, node: &Option>, - parent: NodeRef, ) -> Option { - node.as_ref().map(|node| { - let raw = - ctx.header(AstNode::TSTypeParameterDeclaration, parent, &node.span); - let params_pos = ctx.ref_vec_field(AstProp::Params, node.params.len()); - let pos = ctx.commit_schema(raw); + node + .as_ref() + .map(|node| serialize_ts_type_param_decl(ctx, node)) +} - let params = node - .params - .iter() - .map(|param| serialize_ts_type_param(ctx, param, pos)) - .collect::>(); +fn serialize_ts_type_param_decl( + ctx: &mut TsEsTreeBuilder, + node: &TsTypeParamDecl, +) -> NodeRef { + let params = node + .params + .iter() + .map(|param| serialize_ts_type_param(ctx, param)) + .collect::>(); - ctx.write_refs(params_pos, params); - - pos - }) + ctx.write_ts_type_param_decl(&node.span, params) } fn serialize_ts_fn_param( ctx: &mut TsEsTreeBuilder, node: &TsFnParam, - parent: NodeRef, ) -> NodeRef { match node { - TsFnParam::Ident(ident) => serialize_ident(ctx, ident, parent), - TsFnParam::Array(pat) => { - serialize_pat(ctx, &Pat::Array(pat.clone()), parent) - } - TsFnParam::Rest(pat) => serialize_pat(ctx, &Pat::Rest(pat.clone()), parent), - TsFnParam::Object(pat) => { - serialize_pat(ctx, &Pat::Object(pat.clone()), parent) - } + TsFnParam::Ident(ident) => serialize_binding_ident(ctx, ident), + TsFnParam::Array(pat) => serialize_pat(ctx, &Pat::Array(pat.clone())), + TsFnParam::Rest(pat) => serialize_pat(ctx, &Pat::Rest(pat.clone())), + TsFnParam::Object(pat) => serialize_pat(ctx, &Pat::Object(pat.clone())), } } diff --git a/cli/tools/lint/ast_buffer/ts_estree.rs b/cli/tools/lint/ast_buffer/ts_estree.rs index 967bbef32a..340f9f3225 100644 --- a/cli/tools/lint/ast_buffer/ts_estree.rs +++ b/cli/tools/lint/ast_buffer/ts_estree.rs @@ -5,22 +5,17 @@ use std::fmt::Debug; use std::fmt::Display; use deno_ast::swc::common::Span; +use deno_ast::view::TruePlusMinus; use super::buffer::AstBufSerializer; -use super::buffer::BoolPos; -use super::buffer::FieldArrPos; -use super::buffer::FieldPos; use super::buffer::NodeRef; -use super::buffer::NullPos; -use super::buffer::PendingNodeRef; use super::buffer::SerializeCtx; -use super::buffer::StrPos; -use super::buffer::UndefPos; #[derive(Debug, Clone, PartialEq)] pub enum AstNode { // First node must always be the empty/invalid node Invalid, + RefArray, // Typically the Program, @@ -29,17 +24,27 @@ pub enum AstNode { ExportDefaultDeclaration, ExportNamedDeclaration, ImportDeclaration, - TsExportAssignment, - TsImportEquals, - TsNamespaceExport, + ImportSpecifier, + ImportAttribute, + ImportDefaultSpecifier, + ImportNamespaceSpecifier, + TSExportAssignment, + TSImportEqualss, + TSNamespaceExport, + TSNamespaceExportDeclaration, + TSImportEqualsDeclaration, + TSExternalModuleReference, + TSModuleDeclaration, + TSModuleBlock, // Decls ClassDeclaration, FunctionDeclaration, TSEnumDeclaration, TSInterface, - TsModule, - TsTypeAlias, + TSInterfaceDeclaration, + TSModule, + TSTypeAliasDeclaration, Using, VariableDeclaration, @@ -74,12 +79,13 @@ pub enum AstNode { ChainExpression, ClassExpression, ConditionalExpression, + EmptyExpr, FunctionExpression, Identifier, ImportExpression, LogicalExpression, MemberExpression, - MetaProp, + MetaProperty, NewExpression, ObjectExpression, PrivateIdentifier, @@ -89,8 +95,6 @@ pub enum AstNode { TemplateLiteral, ThisExpression, TSAsExpression, - TsConstAssertion, - TsInstantiation, TSNonNullExpression, TSSatisfiesExpression, TSTypeAssertion, @@ -98,16 +102,8 @@ pub enum AstNode { UpdateExpression, YieldExpression, - // TODO: TSEsTree uses a single literal node - // Literals - StringLiteral, - Bool, - Null, - NumericLiteral, - BigIntLiteral, - RegExpLiteral, - - EmptyExpr, + // Other + Literal, SpreadElement, Property, VariableDeclarator, @@ -117,6 +113,10 @@ pub enum AstNode { TemplateElement, MethodDefinition, ClassBody, + PropertyDefinition, + Decorator, + StaticBlock, + AccessorProperty, // Patterns ArrayPattern, @@ -150,6 +150,7 @@ pub enum AstNode { TSTypeReference, TSThisType, TSLiteralType, + TSTypeLiteral, TSInferType, TSConditionalType, TSUnionType, @@ -159,7 +160,7 @@ pub enum AstNode { TSTupleType, TSNamedTupleMember, TSFunctionType, - TsCallSignatureDeclaration, + TSCallSignatureDeclaration, TSPropertySignature, TSMethodSignature, TSIndexSignature, @@ -170,6 +171,13 @@ pub enum AstNode { TSRestType, TSArrayType, TSClassImplements, + TSAbstractMethodDefinition, + TSEmptyBodyFunctionExpression, + TSParameterProperty, + TSConstructSignatureDeclaration, + TSQualifiedName, + TSOptionalType, + TSTemplateLiteralType, TSAnyKeyword, TSBigIntKeyword, @@ -219,6 +227,7 @@ pub enum AstProp { Async, Attributes, Await, + BigInt, Block, Body, Callee, @@ -235,6 +244,7 @@ pub enum AstProp { Declaration, Declarations, Declare, + Decorators, Default, Definite, Delegate, @@ -246,12 +256,14 @@ pub enum AstProp { Expression, Expressions, Exported, + ExportKind, Extends, ExtendsType, FalseType, Finalizer, Flags, Generator, + Global, Handler, Id, In, @@ -259,6 +271,8 @@ pub enum AstProp { Init, Initializer, Implements, + Imported, + ImportKind, Key, Kind, Label, @@ -268,6 +282,7 @@ pub enum AstProp { Members, Meta, Method, + ModuleReference, Name, Namespace, NameType, @@ -277,8 +292,12 @@ pub enum AstProp { OpeningFragment, Operator, Optional, + Options, Out, + Override, Param, + Parameter, + Parameters, ParameterName, Params, Pattern, @@ -290,6 +309,7 @@ pub enum AstProp { Quasis, Raw, Readonly, + Regex, ReturnType, Right, SelfClosing, @@ -314,8 +334,6 @@ pub enum AstProp { Value, // Last value is used for max value } -// TODO: Feels like there should be an easier way to iterater over an -// enum in Rust and lowercase the first letter. impl Display for AstProp { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match self { @@ -333,6 +351,7 @@ impl Display for AstProp { AstProp::Async => "async", AstProp::Attributes => "attributes", AstProp::Await => "await", + AstProp::BigInt => "bigint", AstProp::Block => "block", AstProp::Body => "body", AstProp::Callee => "callee", @@ -349,6 +368,7 @@ impl Display for AstProp { AstProp::Declaration => "declaration", AstProp::Declarations => "declarations", AstProp::Declare => "declare", + AstProp::Decorators => "decorators", AstProp::Default => "default", AstProp::Definite => "definite", AstProp::Delegate => "delegate", @@ -359,6 +379,7 @@ impl Display for AstProp { AstProp::ExprName => "exprName", AstProp::Expression => "expression", AstProp::Expressions => "expressions", + AstProp::ExportKind => "exportKind", AstProp::Exported => "exported", AstProp::Extends => "extends", AstProp::ExtendsType => "extendsType", @@ -366,6 +387,7 @@ impl Display for AstProp { AstProp::Finalizer => "finalizer", AstProp::Flags => "flags", AstProp::Generator => "generator", + AstProp::Global => "global", AstProp::Handler => "handler", AstProp::Id => "id", AstProp::In => "in", @@ -373,6 +395,8 @@ impl Display for AstProp { AstProp::Init => "init", AstProp::Initializer => "initializer", AstProp::Implements => "implements", + AstProp::Imported => "imported", + AstProp::ImportKind => "importKind", AstProp::Key => "key", AstProp::Kind => "kind", AstProp::Label => "label", @@ -382,6 +406,7 @@ impl Display for AstProp { AstProp::Members => "members", AstProp::Meta => "meta", AstProp::Method => "method", + AstProp::ModuleReference => "moduleReference", AstProp::Name => "name", AstProp::Namespace => "namespace", AstProp::NameType => "nameType", @@ -391,8 +416,12 @@ impl Display for AstProp { AstProp::OpeningFragment => "openingFragment", AstProp::Operator => "operator", AstProp::Optional => "optional", + AstProp::Options => "options", AstProp::Out => "out", + AstProp::Override => "override", AstProp::Param => "param", + AstProp::Parameter => "parameter", + AstProp::Parameters => "parameters", AstProp::ParameterName => "parameterName", AstProp::Params => "params", AstProp::Pattern => "pattern", @@ -404,6 +433,7 @@ impl Display for AstProp { AstProp::Quasis => "quasis", AstProp::Raw => "raw", AstProp::Readonly => "readonly", + AstProp::Regex => "regex", AstProp::ReturnType => "returnType", AstProp::Right => "right", AstProp::SelfClosing => "selfClosing", @@ -442,79 +472,2277 @@ pub struct TsEsTreeBuilder { ctx: SerializeCtx, } -// TODO: Add a builder API to make it easier to convert from different source -// ast formats. +impl AstBufSerializer for TsEsTreeBuilder { + fn serialize(&mut self) -> Vec { + self.ctx.serialize() + } +} + impl TsEsTreeBuilder { pub fn new() -> Self { // Max values - // TODO: Maybe there is a rust macro to grab the last enum value? let kind_max_count: u8 = u8::from(AstNode::TSEnumBody) + 1; let prop_max_count: u8 = u8::from(AstProp::Value) + 1; Self { ctx: SerializeCtx::new(kind_max_count, prop_max_count), } } -} -impl AstBufSerializer for TsEsTreeBuilder { - fn header( + pub fn write_program( &mut self, - kind: AstNode, - parent: NodeRef, span: &Span, - ) -> PendingNodeRef { - self.ctx.header(kind, parent, span) + source_kind: &str, + body: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Program, span); + + self.ctx.write_str(AstProp::SourceType, source_kind); + self.ctx.write_ref_vec(AstProp::Body, &id, body); + + self.ctx.set_root_idx(id.0); + + self.ctx.commit_node(id) } - fn commit_schema(&mut self, offset: PendingNodeRef) -> NodeRef { - self.ctx.commit_schema(offset) + pub fn write_import_decl( + &mut self, + span: &Span, + type_only: bool, + source: NodeRef, + specifiers: Vec, + attributes: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ImportDeclaration, span); + + let kind = if type_only { "type" } else { "value" }; + self.ctx.write_str(AstProp::ImportKind, kind); + self.ctx.write_ref(AstProp::Source, &id, source); + self.ctx.write_ref_vec(AstProp::Specifiers, &id, specifiers); + self.ctx.write_ref_vec(AstProp::Attributes, &id, attributes); + + self.ctx.commit_node(id) } - fn ref_field(&mut self, prop: AstProp) -> FieldPos { - FieldPos(self.ctx.ref_field(prop)) + pub fn write_import_spec( + &mut self, + span: &Span, + type_only: bool, + local: NodeRef, + imported: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ImportSpecifier, span); + + let kind = if type_only { "type" } else { "value" }; + self.ctx.write_str(AstProp::ImportKind, kind); + + self.ctx.write_ref(AstProp::Imported, &id, imported); + self.ctx.write_ref(AstProp::Local, &id, local); + + self.ctx.commit_node(id) } - fn ref_vec_field(&mut self, prop: AstProp, len: usize) -> FieldArrPos { - FieldArrPos(self.ctx.ref_vec_field(prop, len)) + pub fn write_import_attr( + &mut self, + span: &Span, + key: NodeRef, + value: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ImportAttribute, span); + + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_ref(AstProp::Value, &id, value); + + self.ctx.commit_node(id) } - fn str_field(&mut self, prop: AstProp) -> StrPos { - StrPos(self.ctx.str_field(prop)) + pub fn write_import_default_spec( + &mut self, + span: &Span, + local: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ImportDefaultSpecifier, span); + self.ctx.write_ref(AstProp::Local, &id, local); + self.ctx.commit_node(id) } - fn bool_field(&mut self, prop: AstProp) -> BoolPos { - BoolPos(self.ctx.bool_field(prop)) + pub fn write_import_ns_spec( + &mut self, + span: &Span, + local: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::ImportNamespaceSpecifier, span); + self.ctx.write_ref(AstProp::Local, &id, local); + self.ctx.commit_node(id) } - fn undefined_field(&mut self, prop: AstProp) -> UndefPos { - UndefPos(self.ctx.undefined_field(prop)) + pub fn write_export_decl(&mut self, span: &Span, decl: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::ExportNamedDeclaration, span); + self.ctx.write_ref(AstProp::Declaration, &id, decl); + self.ctx.commit_node(id) } - fn null_field(&mut self, prop: AstProp) -> NullPos { - NullPos(self.ctx.null_field(prop)) + pub fn write_export_all_decl( + &mut self, + span: &Span, + is_type_only: bool, + source: NodeRef, + exported: Option, + attributes: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ExportAllDeclaration, span); + + let value = if is_type_only { "type" } else { "value" }; + self.ctx.write_str(AstProp::ExportKind, value); + + self.ctx.write_maybe_ref(AstProp::Exported, &id, exported); + self.ctx.write_ref(AstProp::Source, &id, source); + self.ctx.write_ref_vec(AstProp::Attributes, &id, attributes); + self.ctx.commit_node(id) } - fn write_ref(&mut self, pos: FieldPos, value: NodeRef) { - self.ctx.write_ref(pos.0, value); + pub fn write_export_default_decl( + &mut self, + span: &Span, + is_type_only: bool, + decl: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::ExportDefaultDeclaration, span); + + let value = if is_type_only { "type" } else { "value" }; + self.ctx.write_str(AstProp::ExportKind, value); + self.ctx.write_ref(AstProp::Declaration, &id, decl); + self.ctx.commit_node(id) } - fn write_maybe_ref(&mut self, pos: FieldPos, value: Option) { - self.ctx.write_maybe_ref(pos.0, value); + pub fn write_export_named_decl( + &mut self, + span: &Span, + specifiers: Vec, + source: Option, + attributes: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ExportNamedDeclaration, span); + + self.ctx.write_ref_vec(AstProp::Specifiers, &id, specifiers); + self.ctx.write_maybe_ref(AstProp::Source, &id, source); + self.ctx.write_ref_vec(AstProp::Attributes, &id, attributes); + + self.ctx.commit_node(id) } - fn write_refs(&mut self, pos: FieldArrPos, value: Vec) { - self.ctx.write_refs(pos.0, value); + pub fn write_export_ts_namespace( + &mut self, + span: &Span, + ident: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSNamespaceExportDeclaration, span); + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.commit_node(id) } - fn write_str(&mut self, pos: StrPos, value: &str) { - self.ctx.write_str(pos.0, value); + pub fn write_export_ts_import_equals( + &mut self, + span: &Span, + is_type_only: bool, + ident: NodeRef, + reference: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSImportEqualsDeclaration, span); + + let value = if is_type_only { "type" } else { "value" }; + self.ctx.write_str(AstProp::ImportKind, value); + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_ref(AstProp::ModuleReference, &id, reference); + + self.ctx.commit_node(id) } - fn write_bool(&mut self, pos: BoolPos, value: bool) { - self.ctx.write_bool(pos.0, value); + pub fn write_ts_external_mod_ref( + &mut self, + span: &Span, + expr: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSExternalModuleReference, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) } - fn serialize(&mut self) -> Vec { - self.ctx.serialize() + pub fn write_export_spec( + &mut self, + span: &Span, + type_only: bool, + local: NodeRef, + exported: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ExportSpecifier, span); + + let kind = if type_only { "type" } else { "value" }; + self.ctx.write_str(AstProp::ExportKind, kind); + + self.ctx.write_ref(AstProp::Exported, &id, exported); + self.ctx.write_ref(AstProp::Local, &id, local); + + self.ctx.commit_node(id) + } + + pub fn write_var_decl( + &mut self, + span: &Span, + declare: bool, + kind: &str, + decls: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::VariableDeclaration, span); + + self.ctx.write_bool(AstProp::Declare, declare); + self.ctx.write_str(AstProp::Kind, kind); + self.ctx.write_ref_vec(AstProp::Declarations, &id, decls); + + self.ctx.commit_node(id) + } + + pub fn write_var_declarator( + &mut self, + span: &Span, + ident: NodeRef, + init: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::VariableDeclarator, span); + + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_maybe_ref(AstProp::Init, &id, init); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_fn_decl( + &mut self, + span: &Span, + is_declare: bool, + is_async: bool, + is_generator: bool, + // Ident is required in most cases, but optional as default export + // declaration. TsEstree is weird... + ident: Option, + type_param: Option, + return_type: Option, + body: Option, + params: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::FunctionDeclaration, span); + + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Async, is_async); + self.ctx.write_bool(AstProp::Generator, is_generator); + self.ctx.write_maybe_ref(AstProp::Id, &id, ident); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_param); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + self.ctx.write_maybe_ref(AstProp::Body, &id, body); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + + self.ctx.commit_node(id) + } + + pub fn write_decorator(&mut self, span: &Span, expr: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::Decorator, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_class_decl( + &mut self, + span: &Span, + is_declare: bool, + is_abstract: bool, + // Ident is required in most cases, but optional as default export + // declaration. TsEstree is weird... + ident: Option, + super_class: Option, + implements: Vec, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ClassDeclaration, span); + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Abstract, is_abstract); + self.ctx.write_maybe_ref(AstProp::Id, &id, ident); + self + .ctx + .write_maybe_ref(AstProp::SuperClass, &id, super_class); + self.ctx.write_ref_vec(AstProp::Implements, &id, implements); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_class_expr( + &mut self, + span: &Span, + is_declare: bool, + is_abstract: bool, + ident: Option, + super_class: Option, + implements: Vec, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ClassExpression, span); + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Abstract, is_abstract); + self.ctx.write_maybe_ref(AstProp::Id, &id, ident); + self + .ctx + .write_maybe_ref(AstProp::SuperClass, &id, super_class); + self.ctx.write_ref_vec(AstProp::Implements, &id, implements); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_class_body( + &mut self, + span: &Span, + body: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ClassBody, span); + self.ctx.write_ref_vec(AstProp::Body, &id, body); + self.ctx.commit_node(id) + } + + pub fn write_static_block(&mut self, span: &Span, body: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::StaticBlock, span); + self.ctx.write_ref(AstProp::Body, &id, body); + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_accessor_property( + &mut self, + span: &Span, + is_declare: bool, + is_computed: bool, + is_optional: bool, + is_override: bool, + is_readonly: bool, + is_static: bool, + accessibility: Option, + decorators: Vec, + key: NodeRef, + value: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::AccessorProperty, span); + + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Computed, is_computed); + self.ctx.write_bool(AstProp::Optional, is_optional); + self.ctx.write_bool(AstProp::Override, is_override); + self.ctx.write_bool(AstProp::Readonly, is_readonly); + self.ctx.write_bool(AstProp::Static, is_static); + self.write_accessibility(accessibility); + self.ctx.write_ref_vec(AstProp::Decorators, &id, decorators); + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_maybe_ref(AstProp::Value, &id, value); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_class_prop( + &mut self, + span: &Span, + is_declare: bool, + is_computed: bool, + is_optional: bool, + is_override: bool, + is_readonly: bool, + is_static: bool, + accessibility: Option, + decorators: Vec, + key: NodeRef, + value: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::PropertyDefinition, span); + + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Computed, is_computed); + self.ctx.write_bool(AstProp::Optional, is_optional); + self.ctx.write_bool(AstProp::Override, is_override); + self.ctx.write_bool(AstProp::Readonly, is_readonly); + self.ctx.write_bool(AstProp::Static, is_static); + + self.write_accessibility(accessibility); + self.ctx.write_ref_vec(AstProp::Decorators, &id, decorators); + + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_maybe_ref(AstProp::Value, &id, value); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_class_method( + &mut self, + span: &Span, + is_declare: bool, + is_computed: bool, + is_optional: bool, + is_override: bool, + is_static: bool, + kind: &str, + accessibility: Option, + key: NodeRef, + value: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::MethodDefinition, span); + + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Computed, is_computed); + self.ctx.write_bool(AstProp::Optional, is_optional); + self.ctx.write_bool(AstProp::Override, is_override); + self.ctx.write_bool(AstProp::Static, is_static); + self.ctx.write_str(AstProp::Kind, kind); + self.write_accessibility(accessibility); + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_ref(AstProp::Value, &id, value); + + self.ctx.commit_node(id) + } + + pub fn write_block_stmt( + &mut self, + span: &Span, + body: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::BlockStatement, span); + self.ctx.write_ref_vec(AstProp::Body, &id, body); + self.ctx.commit_node(id) + } + + pub fn write_debugger_stmt(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::DebuggerStatement, span); + self.ctx.commit_node(id) + } + + pub fn write_with_stmt( + &mut self, + span: &Span, + obj: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::WithStatement, span); + + self.ctx.write_ref(AstProp::Object, &id, obj); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_return_stmt( + &mut self, + span: &Span, + arg: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ReturnStatement, span); + self.ctx.write_maybe_ref(AstProp::Argument, &id, arg); + self.ctx.commit_node(id) + } + + pub fn write_labeled_stmt( + &mut self, + span: &Span, + label: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::LabeledStatement, span); + + self.ctx.write_ref(AstProp::Label, &id, label); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_break_stmt( + &mut self, + span: &Span, + label: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::BreakStatement, span); + self.ctx.write_maybe_ref(AstProp::Label, &id, label); + self.ctx.commit_node(id) + } + + pub fn write_continue_stmt( + &mut self, + span: &Span, + label: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ContinueStatement, span); + self.ctx.write_maybe_ref(AstProp::Label, &id, label); + self.ctx.commit_node(id) + } + + pub fn write_if_stmt( + &mut self, + span: &Span, + test: NodeRef, + consequent: NodeRef, + alternate: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::IfStatement, span); + + self.ctx.write_ref(AstProp::Test, &id, test); + self.ctx.write_ref(AstProp::Consequent, &id, consequent); + self.ctx.write_maybe_ref(AstProp::Alternate, &id, alternate); + + self.ctx.commit_node(id) + } + + pub fn write_switch_stmt( + &mut self, + span: &Span, + discriminant: NodeRef, + cases: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::SwitchStatement, span); + + self.ctx.write_ref(AstProp::Discriminant, &id, discriminant); + self.ctx.write_ref_vec(AstProp::Cases, &id, cases); + + self.ctx.commit_node(id) + } + + pub fn write_switch_case( + &mut self, + span: &Span, + test: Option, + consequent: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::SwitchCase, span); + + self.ctx.write_maybe_ref(AstProp::Test, &id, test); + self.ctx.write_ref_vec(AstProp::Consequent, &id, consequent); + + self.ctx.commit_node(id) + } + + pub fn write_throw_stmt(&mut self, span: &Span, arg: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::ThrowStatement, span); + self.ctx.write_ref(AstProp::Argument, &id, arg); + self.ctx.commit_node(id) + } + + pub fn write_while_stmt( + &mut self, + span: &Span, + test: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::WhileStatement, span); + + self.ctx.write_ref(AstProp::Test, &id, test); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_do_while_stmt( + &mut self, + span: &Span, + test: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::DoWhileStatement, span); + + self.ctx.write_ref(AstProp::Test, &id, test); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_for_stmt( + &mut self, + span: &Span, + init: Option, + test: Option, + update: Option, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ForStatement, span); + + self.ctx.write_maybe_ref(AstProp::Init, &id, init); + self.ctx.write_maybe_ref(AstProp::Test, &id, test); + self.ctx.write_maybe_ref(AstProp::Update, &id, update); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_for_in_stmt( + &mut self, + span: &Span, + left: NodeRef, + right: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ForInStatement, span); + + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_for_of_stmt( + &mut self, + span: &Span, + is_await: bool, + left: NodeRef, + right: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ForOfStatement, span); + + self.ctx.write_bool(AstProp::Await, is_await); + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_expr_stmt(&mut self, span: &Span, expr: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::ExpressionStatement, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) + } + + pub fn write_try_stmt( + &mut self, + span: &Span, + block: NodeRef, + handler: Option, + finalizer: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TryStatement, span); + + self.ctx.write_ref(AstProp::Block, &id, block); + self.ctx.write_maybe_ref(AstProp::Handler, &id, handler); + self.ctx.write_maybe_ref(AstProp::Finalizer, &id, finalizer); + + self.ctx.commit_node(id) + } + + pub fn write_catch_clause( + &mut self, + span: &Span, + param: Option, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::CatchClause, span); + + self.ctx.write_maybe_ref(AstProp::Param, &id, param); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_arr_expr( + &mut self, + span: &Span, + elems: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ArrayExpression, span); + self.ctx.write_ref_vec(AstProp::Elements, &id, elems); + self.ctx.commit_node(id) + } + + pub fn write_obj_expr( + &mut self, + span: &Span, + props: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ObjectExpression, span); + self.ctx.write_ref_vec(AstProp::Properties, &id, props); + self.ctx.commit_node(id) + } + + pub fn write_bin_expr( + &mut self, + span: &Span, + operator: &str, + left: NodeRef, + right: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::BinaryExpression, span); + + self.ctx.write_str(AstProp::Operator, operator); + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + + self.ctx.commit_node(id) + } + + pub fn write_logical_expr( + &mut self, + span: &Span, + operator: &str, + left: NodeRef, + right: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::LogicalExpression, span); + + self.ctx.write_str(AstProp::Operator, operator); + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_fn_expr( + &mut self, + span: &Span, + is_async: bool, + is_generator: bool, + ident: Option, + type_params: Option, + params: Vec, + return_type: Option, + body: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::FunctionExpression, span); + + self.ctx.write_bool(AstProp::Async, is_async); + self.ctx.write_bool(AstProp::Generator, is_generator); + self.ctx.write_maybe_ref(AstProp::Id, &id, ident); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_params); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + self.ctx.write_maybe_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_arrow_fn_expr( + &mut self, + span: &Span, + is_async: bool, + is_generator: bool, + type_params: Option, + params: Vec, + return_type: Option, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ArrowFunctionExpression, span); + + self.ctx.write_bool(AstProp::Async, is_async); + self.ctx.write_bool(AstProp::Generator, is_generator); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_params); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_this_expr(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::ThisExpression, span); + self.ctx.commit_node(id) + } + + pub fn write_super(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::Super, span); + self.ctx.commit_node(id) + } + + pub fn write_unary_expr( + &mut self, + span: &Span, + operator: &str, + arg: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::UnaryExpression, span); + + self.ctx.write_str(AstProp::Operator, operator); + self.ctx.write_ref(AstProp::Argument, &id, arg); + + self.ctx.commit_node(id) + } + + pub fn write_new_expr( + &mut self, + span: &Span, + callee: NodeRef, + type_args: Option, + args: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::NewExpression, span); + + self.ctx.write_ref(AstProp::Callee, &id, callee); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + self.ctx.write_ref_vec(AstProp::Arguments, &id, args); + + self.ctx.commit_node(id) + } + + pub fn write_import_expr( + &mut self, + span: &Span, + source: NodeRef, + options: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ImportExpression, span); + + self.ctx.write_ref(AstProp::Source, &id, source); + self.ctx.write_ref(AstProp::Options, &id, options); + + self.ctx.commit_node(id) + } + + pub fn write_call_expr( + &mut self, + span: &Span, + optional: bool, + callee: NodeRef, + type_args: Option, + args: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::CallExpression, span); + + self.ctx.write_bool(AstProp::Optional, optional); + self.ctx.write_ref(AstProp::Callee, &id, callee); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + self.ctx.write_ref_vec(AstProp::Arguments, &id, args); + + self.ctx.commit_node(id) + } + + pub fn write_update_expr( + &mut self, + span: &Span, + prefix: bool, + operator: &str, + arg: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::UpdateExpression, span); + + self.ctx.write_bool(AstProp::Prefix, prefix); + self.ctx.write_str(AstProp::Operator, operator); + self.ctx.write_ref(AstProp::Argument, &id, arg); + + self.ctx.commit_node(id) + } + + pub fn write_assignment_expr( + &mut self, + span: &Span, + operator: &str, + left: NodeRef, + right: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::AssignmentExpression, span); + + self.ctx.write_str(AstProp::Operator, operator); + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + + self.ctx.commit_node(id) + } + + pub fn write_conditional_expr( + &mut self, + span: &Span, + test: NodeRef, + consequent: NodeRef, + alternate: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ConditionalExpression, span); + + self.ctx.write_ref(AstProp::Test, &id, test); + self.ctx.write_ref(AstProp::Consequent, &id, consequent); + self.ctx.write_ref(AstProp::Alternate, &id, alternate); + + self.ctx.commit_node(id) + } + + pub fn write_member_expr( + &mut self, + span: &Span, + optional: bool, + computed: bool, + obj: NodeRef, + prop: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::MemberExpression, span); + + self.ctx.write_bool(AstProp::Optional, optional); + self.ctx.write_bool(AstProp::Computed, computed); + self.ctx.write_ref(AstProp::Object, &id, obj); + self.ctx.write_ref(AstProp::Property, &id, prop); + + self.ctx.commit_node(id) + } + + pub fn write_chain_expr(&mut self, span: &Span, expr: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::ChainExpression, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) + } + + pub fn write_sequence_expr( + &mut self, + span: &Span, + exprs: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::SequenceExpression, span); + self.ctx.write_ref_vec(AstProp::Expressions, &id, exprs); + self.ctx.commit_node(id) + } + + pub fn write_template_lit( + &mut self, + span: &Span, + quasis: Vec, + exprs: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TemplateLiteral, span); + + self.ctx.write_ref_vec(AstProp::Quasis, &id, quasis); + self.ctx.write_ref_vec(AstProp::Expressions, &id, exprs); + + self.ctx.commit_node(id) + } + + pub fn write_template_elem( + &mut self, + span: &Span, + tail: bool, + raw: &str, + cooked: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TemplateElement, span); + + self.ctx.write_bool(AstProp::Tail, tail); + self.ctx.write_str(AstProp::Raw, raw); + self.ctx.write_str(AstProp::Cooked, cooked); + + self.ctx.commit_node(id) + } + + pub fn write_tagged_template_expr( + &mut self, + span: &Span, + tag: NodeRef, + type_args: Option, + quasi: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TaggedTemplateExpression, span); + + self.ctx.write_ref(AstProp::Tag, &id, tag); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + self.ctx.write_ref(AstProp::Quasi, &id, quasi); + + self.ctx.commit_node(id) + } + + pub fn write_yield_expr( + &mut self, + span: &Span, + delegate: bool, + arg: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::YieldExpression, span); + + self.ctx.write_bool(AstProp::Delegate, delegate); + self.ctx.write_maybe_ref(AstProp::Argument, &id, arg); + + self.ctx.commit_node(id) + } + + pub fn write_await_expr(&mut self, span: &Span, arg: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::AwaitExpression, span); + self.ctx.write_ref(AstProp::Argument, &id, arg); + self.ctx.commit_node(id) + } + + pub fn write_meta_prop(&mut self, span: &Span, prop: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::MetaProperty, span); + self.ctx.write_ref(AstProp::Property, &id, prop); + self.ctx.commit_node(id) + } + + pub fn write_identifier( + &mut self, + span: &Span, + name: &str, + optional: bool, + type_annotation: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Identifier, span); + + self.ctx.write_str(AstProp::Name, name); + self.ctx.write_bool(AstProp::Optional, optional); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_annotation); + + self.ctx.commit_node(id) + } + + pub fn write_private_identifier( + &mut self, + span: &Span, + name: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::PrivateIdentifier, span); + self.ctx.write_str(AstProp::Name, name); + self.ctx.commit_node(id) + } + + pub fn write_assign_pat( + &mut self, + span: &Span, + left: NodeRef, + right: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::AssignmentPattern, span); + + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + + self.ctx.commit_node(id) + } + + pub fn write_arr_pat( + &mut self, + span: &Span, + optional: bool, + type_ann: Option, + elems: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ArrayPattern, span); + + self.ctx.write_bool(AstProp::Optional, optional); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.write_ref_vec(AstProp::Elements, &id, elems); + + self.ctx.commit_node(id) + } + + pub fn write_obj_pat( + &mut self, + span: &Span, + optional: bool, + type_ann: Option, + props: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::ObjectPattern, span); + + self.ctx.write_bool(AstProp::Optional, optional); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.write_ref_vec(AstProp::Properties, &id, props); + + self.ctx.commit_node(id) + } + + pub fn write_rest_elem( + &mut self, + span: &Span, + type_ann: Option, + arg: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::RestElement, span); + + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.write_ref(AstProp::Argument, &id, arg); + + self.ctx.commit_node(id) + } + + pub fn write_spread(&mut self, span: &Span, arg: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::SpreadElement, span); + self.ctx.write_ref(AstProp::Argument, &id, arg); + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_property( + &mut self, + span: &Span, + shorthand: bool, + computed: bool, + method: bool, + kind: &str, + key: NodeRef, + value: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Property, span); + + self.ctx.write_bool(AstProp::Shorthand, shorthand); + self.ctx.write_bool(AstProp::Computed, computed); + self.ctx.write_bool(AstProp::Method, method); + self.ctx.write_str(AstProp::Kind, kind); + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_ref(AstProp::Value, &id, value); + + self.ctx.commit_node(id) + } + + pub fn write_str_lit( + &mut self, + span: &Span, + value: &str, + raw: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Literal, span); + + self.ctx.write_str(AstProp::Value, value); + self.ctx.write_str(AstProp::Raw, raw); + + self.ctx.commit_node(id) + } + + pub fn write_bool_lit(&mut self, span: &Span, value: bool) -> NodeRef { + let id = self.ctx.append_node(AstNode::Literal, span); + + let raw = &format!("{}", value); + self.ctx.write_str(AstProp::Raw, raw); + self.ctx.write_bool(AstProp::Value, value); + + self.ctx.commit_node(id) + } + + pub fn write_null_lit(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::Literal, span); + + self.ctx.write_null(AstProp::Value); + self.ctx.write_str(AstProp::Raw, "null"); + + self.ctx.commit_node(id) + } + + pub fn write_num_lit( + &mut self, + span: &Span, + value: &str, + raw: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Literal, span); + + self.ctx.write_num(AstProp::Value, value); + self.ctx.write_str(AstProp::Raw, raw); + + self.ctx.commit_node(id) + } + + pub fn write_bigint_lit( + &mut self, + span: &Span, + value: &str, + raw: &str, + bigint_value: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Literal, span); + + self.ctx.write_bigint(AstProp::Value, value); + self.ctx.write_str(AstProp::Raw, raw); + self.ctx.write_str(AstProp::BigInt, bigint_value); + + self.ctx.commit_node(id) + } + + pub fn write_regex_lit( + &mut self, + span: &Span, + pattern: &str, + flags: &str, + value: &str, + raw: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::Literal, span); + + self.ctx.write_regex(AstProp::Value, value); + self.ctx.write_str(AstProp::Raw, raw); + self.ctx.open_obj(); + self.ctx.write_str(AstProp::Flags, flags); + self.ctx.write_str(AstProp::Pattern, pattern); + self.ctx.commit_obj(AstProp::Regex); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_identifier(&mut self, span: &Span, name: &str) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXIdentifier, span); + self.ctx.write_str(AstProp::Name, name); + self.ctx.commit_node(id) + } + + pub fn write_jsx_namespaced_name( + &mut self, + span: &Span, + namespace: NodeRef, + name: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXNamespacedName, span); + + self.ctx.write_ref(AstProp::Namespace, &id, namespace); + self.ctx.write_ref(AstProp::Name, &id, name); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_empty_expr(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXEmptyExpression, span); + self.ctx.commit_node(id) + } + + pub fn write_jsx_elem( + &mut self, + span: &Span, + opening: NodeRef, + closing: Option, + children: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXElement, span); + + self.ctx.write_ref(AstProp::OpeningElement, &id, opening); + self + .ctx + .write_maybe_ref(AstProp::ClosingElement, &id, closing); + self.ctx.write_ref_vec(AstProp::Children, &id, children); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_opening_elem( + &mut self, + span: &Span, + self_closing: bool, + name: NodeRef, + attrs: Vec, + type_args: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXOpeningElement, span); + + self.ctx.write_bool(AstProp::SelfClosing, self_closing); + self.ctx.write_ref(AstProp::Name, &id, name); + self.ctx.write_ref_vec(AstProp::Attributes, &id, attrs); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_attr( + &mut self, + span: &Span, + name: NodeRef, + value: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXAttribute, span); + + self.ctx.write_ref(AstProp::Name, &id, name); + self.ctx.write_maybe_ref(AstProp::Value, &id, value); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_spread_attr( + &mut self, + span: &Span, + arg: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXSpreadAttribute, span); + self.ctx.write_ref(AstProp::Argument, &id, arg); + self.ctx.commit_node(id) + } + + pub fn write_jsx_closing_elem( + &mut self, + span: &Span, + name: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXClosingElement, span); + self.ctx.write_ref(AstProp::Name, &id, name); + self.ctx.commit_node(id) + } + + pub fn write_jsx_frag( + &mut self, + span: &Span, + opening: NodeRef, + closing: NodeRef, + children: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXFragment, span); + + self.ctx.write_ref(AstProp::OpeningFragment, &id, opening); + self.ctx.write_ref(AstProp::ClosingFragment, &id, closing); + self.ctx.write_ref_vec(AstProp::Children, &id, children); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_opening_frag(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXOpeningFragment, span); + self.ctx.commit_node(id) + } + + pub fn write_jsx_closing_frag(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXClosingFragment, span); + self.ctx.commit_node(id) + } + + pub fn write_jsx_expr_container( + &mut self, + span: &Span, + expr: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXExpressionContainer, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) + } + + pub fn write_jsx_text( + &mut self, + span: &Span, + raw: &str, + value: &str, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXText, span); + + self.ctx.write_str(AstProp::Raw, raw); + self.ctx.write_str(AstProp::Value, value); + + self.ctx.commit_node(id) + } + + pub fn write_jsx_member_expr( + &mut self, + span: &Span, + obj: NodeRef, + prop: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::JSXMemberExpression, span); + + self.ctx.write_ref(AstProp::Object, &id, obj); + self.ctx.write_ref(AstProp::Property, &id, prop); + + self.ctx.commit_node(id) + } + + pub fn write_ts_module_decl( + &mut self, + span: &Span, + is_declare: bool, + is_global: bool, + ident: NodeRef, + body: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSModuleDeclaration, span); + + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Global, is_global); + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_maybe_ref(AstProp::Body, &id, body); + self.ctx.commit_node(id) + } + + pub fn write_ts_module_block( + &mut self, + span: &Span, + body: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSModuleBlock, span); + self.ctx.write_ref_vec(AstProp::Body, &id, body); + self.ctx.commit_node(id) + } + + pub fn write_ts_class_implements( + &mut self, + span: &Span, + expr: NodeRef, + type_args: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSClassImplements, span); + + self.ctx.write_ref(AstProp::Expression, &id, expr); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_ts_abstract_method_def( + &mut self, + span: &Span, + is_computed: bool, + is_optional: bool, + is_override: bool, + is_static: bool, + accessibility: Option, + key: NodeRef, + value: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSAbstractMethodDefinition, span); + + self.ctx.write_bool(AstProp::Computed, is_computed); + self.ctx.write_bool(AstProp::Optional, is_optional); + self.ctx.write_bool(AstProp::Override, is_override); + self.ctx.write_bool(AstProp::Static, is_static); + + self.write_accessibility(accessibility); + + self.ctx.write_str(AstProp::Kind, "method"); + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_ref(AstProp::Key, &id, value); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_ts_empty_body_fn_expr( + &mut self, + span: &Span, + is_declare: bool, + is_expression: bool, + is_async: bool, + is_generator: bool, + ident: Option, + type_params: Option, + params: Vec, + return_type: Option, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSEmptyBodyFunctionExpression, span); + + self.ctx.write_bool(AstProp::Declare, is_declare); + self.ctx.write_bool(AstProp::Expression, is_expression); + self.ctx.write_bool(AstProp::Async, is_async); + self.ctx.write_bool(AstProp::Generator, is_generator); + self.ctx.write_maybe_ref(AstProp::Id, &id, ident); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_params); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + + self.ctx.commit_node(id) + } + + pub fn write_ts_param_prop( + &mut self, + span: &Span, + is_override: bool, + is_readonly: bool, + accessibility: Option, + decorators: Vec, + param: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSParameterProperty, span); + + self.ctx.write_bool(AstProp::Override, is_override); + self.ctx.write_bool(AstProp::Readonly, is_readonly); + self.ctx.write_bool(AstProp::Static, false); + self.write_accessibility(accessibility); + self.ctx.write_ref_vec(AstProp::Decorators, &id, decorators); + self.ctx.write_ref(AstProp::Parameter, &id, param); + + self.ctx.commit_node(id) + } + + pub fn write_ts_call_sig_decl( + &mut self, + span: &Span, + type_ann: Option, + params: Vec, + return_type: Option, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSCallSignatureDeclaration, span); + + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + + self.ctx.commit_node(id) + } + + pub fn write_ts_property_sig( + &mut self, + span: &Span, + computed: bool, + optional: bool, + readonly: bool, + key: NodeRef, + type_ann: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSPropertySignature, span); + + self.ctx.write_bool(AstProp::Computed, computed); + self.ctx.write_bool(AstProp::Optional, optional); + self.ctx.write_bool(AstProp::Readonly, readonly); + // TODO(@marvinhagemeister) not sure where this is coming from + self.ctx.write_bool(AstProp::Static, false); + + self.ctx.write_ref(AstProp::Key, &id, key); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_enum( + &mut self, + span: &Span, + declare: bool, + is_const: bool, + ident: NodeRef, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSEnumDeclaration, span); + + self.ctx.write_bool(AstProp::Declare, declare); + self.ctx.write_bool(AstProp::Const, is_const); + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_ts_enum_body( + &mut self, + span: &Span, + members: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSEnumBody, span); + self.ctx.write_ref_vec(AstProp::Members, &id, members); + self.ctx.commit_node(id) + } + + pub fn write_ts_enum_member( + &mut self, + span: &Span, + ident: NodeRef, + init: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSEnumMember, span); + + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_maybe_ref(AstProp::Initializer, &id, init); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_assertion( + &mut self, + span: &Span, + expr: NodeRef, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeAssertion, span); + + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_param_inst( + &mut self, + span: &Span, + params: Vec, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSTypeParameterInstantiation, span); + + self.ctx.write_ref_vec(AstProp::Params, &id, params); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_alias( + &mut self, + span: &Span, + declare: bool, + ident: NodeRef, + type_param: Option, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeAliasDeclaration, span); + + self.ctx.write_bool(AstProp::Declare, declare); + self.ctx.write_ref(AstProp::Id, &id, ident); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_param); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_satisfies_expr( + &mut self, + span: &Span, + expr: NodeRef, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSSatisfiesExpression, span); + + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_as_expr( + &mut self, + span: &Span, + expr: NodeRef, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSAsExpression, span); + + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_non_null(&mut self, span: &Span, expr: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSNonNullExpression, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) + } + + pub fn write_ts_this_type(&mut self, span: &Span) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSThisType, span); + self.ctx.commit_node(id) + } + + pub fn write_ts_interface( + &mut self, + span: &Span, + declare: bool, + ident: NodeRef, + type_param: Option, + extends: Vec, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSInterface, span); + + self.ctx.write_bool(AstProp::Declare, declare); + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_maybe_ref(AstProp::Extends, &id, type_param); + self + .ctx + .write_ref_vec(AstProp::TypeParameters, &id, extends); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_ts_interface_decl( + &mut self, + span: &Span, + declare: bool, + ident: NodeRef, + type_param: Option, + extends: Vec, + body: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSInterfaceDeclaration, span); + + self.ctx.write_bool(AstProp::Declare, declare); + self.ctx.write_ref(AstProp::Id, &id, ident); + self.ctx.write_maybe_ref(AstProp::Extends, &id, type_param); + self + .ctx + .write_ref_vec(AstProp::TypeParameters, &id, extends); + self.ctx.write_ref(AstProp::Body, &id, body); + + self.ctx.commit_node(id) + } + + pub fn write_ts_interface_body( + &mut self, + span: &Span, + body: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSInterfaceBody, span); + self.ctx.write_ref_vec(AstProp::Body, &id, body); + self.ctx.commit_node(id) + } + + pub fn write_ts_construct_sig( + &mut self, + span: &Span, + type_params: Option, + params: Vec, + return_type: NodeRef, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSConstructSignatureDeclaration, span); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_params); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self.ctx.write_ref(AstProp::ReturnType, &id, return_type); + self.ctx.commit_node(id) + } + + pub fn write_ts_getter_sig( + &mut self, + span: &Span, + key: NodeRef, + return_type: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSMethodSignature, span); + + self.ctx.write_bool(AstProp::Computed, false); + self.ctx.write_bool(AstProp::Optional, false); + self.ctx.write_bool(AstProp::Readonly, false); + self.ctx.write_bool(AstProp::Static, false); + self.ctx.write_str(AstProp::Kind, "getter"); + self.ctx.write_ref(AstProp::Key, &id, key); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + + self.ctx.commit_node(id) + } + + pub fn write_ts_setter_sig( + &mut self, + span: &Span, + key: NodeRef, + param: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSMethodSignature, span); + + self.ctx.write_bool(AstProp::Computed, false); + self.ctx.write_bool(AstProp::Optional, false); + self.ctx.write_bool(AstProp::Readonly, false); + self.ctx.write_bool(AstProp::Static, false); + self.ctx.write_str(AstProp::Kind, "setter"); + self.ctx.write_ref(AstProp::Key, &id, key); + self.ctx.write_ref_vec(AstProp::Params, &id, vec![param]); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_ts_method_sig( + &mut self, + span: &Span, + is_computed: bool, + is_optional: bool, + key: NodeRef, + type_params: Option, + params: Vec, + return_type: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSMethodSignature, span); + + self.ctx.write_bool(AstProp::Computed, is_computed); + self.ctx.write_bool(AstProp::Optional, is_optional); + self.ctx.write_bool(AstProp::Readonly, false); + self.ctx.write_bool(AstProp::Static, false); + self.ctx.write_str(AstProp::Kind, "method"); + self.ctx.write_ref(AstProp::Key, &id, key); + self + .ctx + .write_maybe_ref(AstProp::TypeParameters, &id, type_params); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self + .ctx + .write_maybe_ref(AstProp::ReturnType, &id, return_type); + + self.ctx.commit_node(id) + } + + pub fn write_ts_interface_heritage( + &mut self, + span: &Span, + expr: NodeRef, + type_args: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSInterfaceHeritage, span); + + self.ctx.write_ref(AstProp::Expression, &id, expr); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + + self.ctx.commit_node(id) + } + + pub fn write_ts_index_sig( + &mut self, + span: &Span, + is_readonly: bool, + params: Vec, + type_ann: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSIndexSignature, span); + + self.ctx.write_bool(AstProp::Readonly, is_readonly); + self.ctx.write_ref_vec(AstProp::Parameters, &id, params); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_union_type( + &mut self, + span: &Span, + types: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSUnionType, span); + self.ctx.write_ref_vec(AstProp::Types, &id, types); + self.ctx.commit_node(id) + } + + pub fn write_ts_intersection_type( + &mut self, + span: &Span, + types: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSIntersectionType, span); + self.ctx.write_ref_vec(AstProp::Types, &id, types); + self.ctx.commit_node(id) + } + + pub fn write_ts_infer_type( + &mut self, + span: &Span, + type_param: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSInferType, span); + self.ctx.write_ref(AstProp::TypeParameter, &id, type_param); + self.ctx.commit_node(id) + } + + pub fn write_ts_type_op( + &mut self, + span: &Span, + op: &str, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeOperator, span); + + self.ctx.write_str(AstProp::Operator, op); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_indexed_access_type( + &mut self, + span: &Span, + index: NodeRef, + obj: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSIndexedAccessType, span); + + self.ctx.write_ref(AstProp::IndexType, &id, index); + self.ctx.write_ref(AstProp::ObjectType, &id, obj); + + self.ctx.commit_node(id) + } + + pub fn write_ts_keyword( + &mut self, + kind: TsKeywordKind, + span: &Span, + ) -> NodeRef { + let kind = match kind { + TsKeywordKind::Any => AstNode::TSAnyKeyword, + TsKeywordKind::Unknown => AstNode::TSUnknownKeyword, + TsKeywordKind::Number => AstNode::TSNumberKeyword, + TsKeywordKind::Object => AstNode::TSObjectKeyword, + TsKeywordKind::Boolean => AstNode::TSBooleanKeyword, + TsKeywordKind::BigInt => AstNode::TSBigIntKeyword, + TsKeywordKind::String => AstNode::TSStringKeyword, + TsKeywordKind::Symbol => AstNode::TSSymbolKeyword, + TsKeywordKind::Void => AstNode::TSVoidKeyword, + TsKeywordKind::Undefined => AstNode::TSUndefinedKeyword, + TsKeywordKind::Null => AstNode::TSNullKeyword, + TsKeywordKind::Never => AstNode::TSNeverKeyword, + TsKeywordKind::Intrinsic => AstNode::TSIntrinsicKeyword, + }; + + let id = self.ctx.append_node(kind, span); + self.ctx.commit_node(id) + } + + pub fn write_ts_rest_type( + &mut self, + span: &Span, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSRestType, span); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.commit_node(id) + } + + pub fn write_ts_conditional_type( + &mut self, + span: &Span, + check: NodeRef, + extends: NodeRef, + true_type: NodeRef, + false_type: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSConditionalType, span); + + self.ctx.write_ref(AstProp::CheckType, &id, check); + self.ctx.write_ref(AstProp::ExtendsType, &id, extends); + self.ctx.write_ref(AstProp::TrueType, &id, true_type); + self.ctx.write_ref(AstProp::FalseType, &id, false_type); + + self.ctx.commit_node(id) + } + + pub fn write_ts_mapped_type( + &mut self, + span: &Span, + readonly: Option, + optional: Option, + name: Option, + type_ann: Option, + type_param: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSMappedType, span); + + self.write_plus_minus_true(AstProp::Readonly, readonly); + self.write_plus_minus_true(AstProp::Optional, optional); + self.ctx.write_maybe_ref(AstProp::NameType, &id, name); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.write_ref(AstProp::TypeParameter, &id, type_param); + + self.ctx.commit_node(id) + } + + pub fn write_ts_lit_type(&mut self, span: &Span, lit: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSLiteralType, span); + self.ctx.write_ref(AstProp::Literal, &id, lit); + self.ctx.commit_node(id) + } + + pub fn write_ts_tpl_lit( + &mut self, + span: &Span, + quasis: Vec, + types: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTemplateLiteralType, span); + + self.ctx.write_ref_vec(AstProp::Quasis, &id, quasis); + self.ctx.write_ref_vec(AstProp::Types, &id, types); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_lit( + &mut self, + span: &Span, + members: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeLiteral, span); + self.ctx.write_ref_vec(AstProp::Members, &id, members); + self.ctx.commit_node(id) + } + + pub fn write_ts_optional_type( + &mut self, + span: &Span, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSOptionalType, span); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.commit_node(id) + } + + pub fn write_ts_type_ann( + &mut self, + span: &Span, + type_ann: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeAnnotation, span); + self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann); + self.ctx.commit_node(id) + } + + pub fn write_ts_array_type( + &mut self, + span: &Span, + elem_type: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSArrayType, span); + self.ctx.write_ref(AstProp::ElementType, &id, elem_type); + self.ctx.commit_node(id) + } + + pub fn write_ts_type_query( + &mut self, + span: &Span, + expr_name: NodeRef, + type_arg: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeQuery, span); + + self.ctx.write_ref(AstProp::ExprName, &id, expr_name); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_arg); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_ref( + &mut self, + span: &Span, + type_name: NodeRef, + type_arg: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeReference, span); + + self.ctx.write_ref(AstProp::TypeName, &id, type_name); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_arg); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_predicate( + &mut self, + span: &Span, + asserts: bool, + param_name: NodeRef, + type_ann: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypePredicate, span); + + self.ctx.write_bool(AstProp::Asserts, asserts); + self.ctx.write_ref(AstProp::ParameterName, &id, param_name); + self + .ctx + .write_maybe_ref(AstProp::TypeAnnotation, &id, type_ann); + + self.ctx.commit_node(id) + } + + pub fn write_ts_tuple_type( + &mut self, + span: &Span, + elem_types: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTupleType, span); + + self + .ctx + .write_ref_vec(AstProp::ElementTypes, &id, elem_types); + + self.ctx.commit_node(id) + } + + pub fn write_ts_named_tuple_member( + &mut self, + span: &Span, + label: NodeRef, + elem_type: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSNamedTupleMember, span); + + self.ctx.write_ref(AstProp::Label, &id, label); + self.ctx.write_ref(AstProp::ElementType, &id, elem_type); + + self.ctx.commit_node(id) + } + + pub fn write_ts_type_param_decl( + &mut self, + span: &Span, + params: Vec, + ) -> NodeRef { + let id = self + .ctx + .append_node(AstNode::TSTypeParameterDeclaration, span); + + self.ctx.write_ref_vec(AstProp::Params, &id, params); + + self.ctx.commit_node(id) + } + + #[allow(clippy::too_many_arguments)] + pub fn write_ts_type_param( + &mut self, + span: &Span, + is_in: bool, + is_out: bool, + is_const: bool, + name: NodeRef, + constraint: Option, + default: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSTypeParameter, span); + + self.ctx.write_bool(AstProp::In, is_in); + self.ctx.write_bool(AstProp::Out, is_out); + self.ctx.write_bool(AstProp::Const, is_const); + self.ctx.write_ref(AstProp::Name, &id, name); + self + .ctx + .write_maybe_ref(AstProp::Constraint, &id, constraint); + self.ctx.write_maybe_ref(AstProp::Default, &id, default); + + self.ctx.commit_node(id) + } + + pub fn write_ts_import_type( + &mut self, + span: &Span, + arg: NodeRef, + qualifier: Option, + type_args: Option, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSImportType, span); + + self.ctx.write_ref(AstProp::Argument, &id, arg); + self.ctx.write_maybe_ref(AstProp::Qualifier, &id, qualifier); + self + .ctx + .write_maybe_ref(AstProp::TypeArguments, &id, type_args); + + self.ctx.commit_node(id) + } + + pub fn write_export_assign(&mut self, span: &Span, expr: NodeRef) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSExportAssignment, span); + self.ctx.write_ref(AstProp::Expression, &id, expr); + self.ctx.commit_node(id) + } + + pub fn write_ts_fn_type( + &mut self, + span: &Span, + params: Vec, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSFunctionType, span); + self.ctx.write_ref_vec(AstProp::Params, &id, params); + self.ctx.commit_node(id) + } + + pub fn write_ts_qualified_name( + &mut self, + span: &Span, + left: NodeRef, + right: NodeRef, + ) -> NodeRef { + let id = self.ctx.append_node(AstNode::TSQualifiedName, span); + + self.ctx.write_ref(AstProp::Left, &id, left); + self.ctx.write_ref(AstProp::Right, &id, right); + + self.ctx.commit_node(id) + } + + fn write_accessibility(&mut self, accessibility: Option) { + if let Some(value) = accessibility { + self.ctx.write_str(AstProp::Accessibility, &value); + } else { + self.ctx.write_undefined(AstProp::Accessibility); + } + } + + fn write_plus_minus_true( + &mut self, + prop: AstProp, + value: Option, + ) { + match value { + Some(TruePlusMinus::Plus) => self.ctx.write_str(prop, "+"), + Some(TruePlusMinus::Minus) => self.ctx.write_str(prop, "-"), + Some(TruePlusMinus::True) => self.ctx.write_bool(prop, true), + _ => self.ctx.write_undefined(prop), + } } } + +#[derive(Debug)] +pub enum TsKeywordKind { + Any, + Unknown, + Number, + Object, + Boolean, + BigInt, + String, + Symbol, + Void, + Undefined, + Null, + Never, + Intrinsic, +} diff --git a/tests/unit/__snapshots__/lint_plugin_test.ts.snap b/tests/unit/__snapshots__/lint_plugin_test.ts.snap new file mode 100644 index 0000000000..337fcecc8f --- /dev/null +++ b/tests/unit/__snapshots__/lint_plugin_test.ts.snap @@ -0,0 +1,8608 @@ +export const snapshot = {}; + +snapshot[`Plugin - Program 1`] = ` +{ + body: [], + range: [ + 1, + 1, + ], + sourceType: "script", + type: "Program", +} +`; + +snapshot[`Plugin - ImportDeclaration 1`] = ` +{ + attributes: [], + importKind: "value", + range: [ + 1, + 14, + ], + source: { + range: [ + 8, + 13, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [], + type: "ImportDeclaration", +} +`; + +snapshot[`Plugin - ImportDeclaration 2`] = ` +{ + attributes: [], + importKind: "value", + range: [ + 1, + 23, + ], + source: { + range: [ + 17, + 22, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + local: { + name: "foo", + optional: false, + range: [ + 8, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 8, + 11, + ], + type: "ImportDefaultSpecifier", + }, + ], + type: "ImportDeclaration", +} +`; + +snapshot[`Plugin - ImportDeclaration 3`] = ` +{ + attributes: [], + importKind: "value", + range: [ + 1, + 28, + ], + source: { + range: [ + 22, + 27, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + local: { + name: "foo", + optional: false, + range: [ + 13, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 8, + 16, + ], + type: "ImportNamespaceSpecifier", + }, + ], + type: "ImportDeclaration", +} +`; + +snapshot[`Plugin - ImportDeclaration 4`] = ` +{ + attributes: [], + importKind: "value", + range: [ + 1, + 39, + ], + source: { + range: [ + 33, + 38, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + importKind: "value", + imported: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + local: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 10, + 13, + ], + type: "ImportSpecifier", + }, + { + importKind: "value", + imported: { + name: "bar", + optional: false, + range: [ + 15, + 18, + ], + type: "Identifier", + typeAnnotation: null, + }, + local: { + name: "baz", + optional: false, + range: [ + 22, + 25, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 15, + 25, + ], + type: "ImportSpecifier", + }, + ], + type: "ImportDeclaration", +} +`; + +snapshot[`Plugin - ImportDeclaration 5`] = ` +{ + attributes: [ + { + key: { + name: "type", + optional: false, + range: [ + 30, + 34, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 30, + 42, + ], + type: "ImportAttribute", + value: { + range: [ + 36, + 42, + ], + raw: '"json"', + type: "Literal", + value: "json", + }, + }, + ], + importKind: "value", + range: [ + 1, + 45, + ], + source: { + range: [ + 17, + 22, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + local: { + name: "foo", + optional: false, + range: [ + 8, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 8, + 11, + ], + type: "ImportDefaultSpecifier", + }, + ], + type: "ImportDeclaration", +} +`; + +snapshot[`Plugin - ExportNamedDeclaration 1`] = ` +{ + attributes: [], + range: [ + 1, + 27, + ], + source: { + range: [ + 21, + 26, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + exportKind: "value", + exported: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + local: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 10, + 13, + ], + type: "ExportSpecifier", + }, + ], + type: "ExportNamedDeclaration", +} +`; + +snapshot[`Plugin - ExportNamedDeclaration 2`] = ` +{ + attributes: [], + range: [ + 1, + 34, + ], + source: { + range: [ + 28, + 33, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + exportKind: "value", + exported: { + name: "baz", + optional: false, + range: [ + 17, + 20, + ], + type: "Identifier", + typeAnnotation: null, + }, + local: { + name: "bar", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 10, + 20, + ], + type: "ExportSpecifier", + }, + ], + type: "ExportNamedDeclaration", +} +`; + +snapshot[`Plugin - ExportNamedDeclaration 3`] = ` +{ + attributes: [ + { + key: { + name: "type", + optional: false, + range: [ + 34, + 38, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 34, + 46, + ], + type: "ImportAttribute", + value: { + range: [ + 40, + 46, + ], + raw: '"json"', + type: "Literal", + value: "json", + }, + }, + ], + range: [ + 1, + 49, + ], + source: { + range: [ + 21, + 26, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + specifiers: [ + { + exportKind: "value", + exported: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + local: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 10, + 13, + ], + type: "ExportSpecifier", + }, + ], + type: "ExportNamedDeclaration", +} +`; + +snapshot[`Plugin - ExportDefaultDeclaration 1`] = ` +{ + declaration: { + async: false, + body: { + body: [], + range: [ + 31, + 33, + ], + type: "BlockStatement", + }, + declare: false, + generator: false, + id: { + name: "foo", + optional: false, + range: [ + 25, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + params: [], + range: [ + 16, + 33, + ], + returnType: null, + type: "FunctionDeclaration", + typeParameters: null, + }, + exportKind: "value", + range: [ + 1, + 33, + ], + type: "ExportDefaultDeclaration", +} +`; + +snapshot[`Plugin - ExportDefaultDeclaration 2`] = ` +{ + declaration: { + async: false, + body: { + body: [], + range: [ + 28, + 30, + ], + type: "BlockStatement", + }, + declare: false, + generator: false, + id: null, + params: [], + range: [ + 16, + 30, + ], + returnType: null, + type: "FunctionDeclaration", + typeParameters: null, + }, + exportKind: "value", + range: [ + 1, + 30, + ], + type: "ExportDefaultDeclaration", +} +`; + +snapshot[`Plugin - ExportDefaultDeclaration 3`] = ` +{ + declaration: { + abstract: false, + body: { + body: [], + range: [ + 16, + 28, + ], + type: "ClassBody", + }, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 22, + 25, + ], + type: "Identifier", + typeAnnotation: null, + }, + implements: [], + range: [ + 16, + 28, + ], + superClass: null, + type: "ClassDeclaration", + }, + exportKind: "value", + range: [ + 1, + 28, + ], + type: "ExportDefaultDeclaration", +} +`; + +snapshot[`Plugin - ExportDefaultDeclaration 4`] = ` +{ + declaration: { + abstract: false, + body: { + body: [], + range: [ + 16, + 24, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 16, + 24, + ], + superClass: null, + type: "ClassDeclaration", + }, + exportKind: "value", + range: [ + 1, + 24, + ], + type: "ExportDefaultDeclaration", +} +`; + +snapshot[`Plugin - ExportDefaultDeclaration 5`] = ` +{ + declaration: { + name: "bar", + optional: false, + range: [ + 16, + 19, + ], + type: "Identifier", + typeAnnotation: null, + }, + exportKind: "value", + range: [ + 1, + 20, + ], + type: "ExportDefaultDeclaration", +} +`; + +snapshot[`Plugin - ExportDefaultDeclaration 6`] = ` +{ + declaration: { + body: { + body: [], + range: [ + 30, + 32, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "Foo", + optional: false, + range: [ + 26, + 29, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 16, + 32, + ], + type: "TSInterfaceDeclaration", + typeParameters: [], + }, + exportKind: "type", + range: [ + 1, + 32, + ], + type: "ExportDefaultDeclaration", +} +`; + +snapshot[`Plugin - ExportAllDeclaration 1`] = ` +{ + attributes: [], + exportKind: "value", + exported: null, + range: [ + 1, + 21, + ], + source: { + range: [ + 15, + 20, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + type: "ExportAllDeclaration", +} +`; + +snapshot[`Plugin - ExportAllDeclaration 2`] = ` +{ + attributes: [], + exportKind: "value", + exported: { + range: [ + 22, + 27, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + range: [ + 1, + 28, + ], + source: { + name: "foo", + optional: false, + range: [ + 13, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ExportAllDeclaration", +} +`; + +snapshot[`Plugin - ExportAllDeclaration 3`] = ` +{ + attributes: [ + { + key: { + name: "type", + optional: false, + range: [ + 28, + 32, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 28, + 40, + ], + type: "ImportAttribute", + value: { + range: [ + 34, + 40, + ], + raw: '"json"', + type: "Literal", + value: "json", + }, + }, + ], + exportKind: "value", + exported: null, + range: [ + 1, + 43, + ], + source: { + range: [ + 15, + 20, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + type: "ExportAllDeclaration", +} +`; + +snapshot[`Plugin - TSExportAssignment 1`] = ` +{ + expression: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 14, + ], + type: "TSExportAssignment", +} +`; + +snapshot[`Plugin - TSNamespaceExportDeclaration 1`] = ` +{ + id: { + name: "A", + optional: false, + range: [ + 21, + 22, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 23, + ], + type: "TSNamespaceExportDeclaration", +} +`; + +snapshot[`Plugin - TSImportEqualsDeclaration 1`] = ` +{ + id: { + name: "a", + optional: false, + range: [ + 8, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + importKind: "value", + moduleReference: { + name: "b", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 13, + ], + type: "TSImportEqualsDeclaration", +} +`; + +snapshot[`Plugin - TSImportEqualsDeclaration 2`] = ` +{ + id: { + name: "a", + optional: false, + range: [ + 8, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + importKind: "value", + moduleReference: { + expression: { + range: [ + 20, + 25, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + range: [ + 12, + 26, + ], + type: "TSExternalModuleReference", + }, + range: [ + 1, + 26, + ], + type: "TSImportEqualsDeclaration", +} +`; + +snapshot[`Plugin - BlockStatement 1`] = ` +{ + body: [ + { + expression: { + name: "foo", + optional: false, + range: [ + 3, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 3, + 7, + ], + type: "ExpressionStatement", + }, + ], + range: [ + 1, + 9, + ], + type: "BlockStatement", +} +`; + +snapshot[`Plugin - BreakStatement 1`] = ` +{ + label: null, + range: [ + 15, + 21, + ], + type: "BreakStatement", +} +`; + +snapshot[`Plugin - BreakStatement 2`] = ` +{ + label: { + name: "foo", + optional: false, + range: [ + 26, + 29, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 20, + 30, + ], + type: "BreakStatement", +} +`; + +snapshot[`Plugin - ContinueStatement 1`] = ` +{ + label: null, + range: [ + 1, + 10, + ], + type: "ContinueStatement", +} +`; + +snapshot[`Plugin - ContinueStatement 2`] = ` +{ + label: { + name: "foo", + optional: false, + range: [ + 10, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 14, + ], + type: "ContinueStatement", +} +`; + +snapshot[`Plugin - DebuggerStatement 1`] = ` +{ + range: [ + 1, + 10, + ], + type: "DebuggerStatement", +} +`; + +snapshot[`Plugin - DoWhileStatement 1`] = ` +{ + body: { + body: [], + range: [ + 4, + 6, + ], + type: "BlockStatement", + }, + range: [ + 1, + 19, + ], + test: { + name: "foo", + optional: false, + range: [ + 14, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "DoWhileStatement", +} +`; + +snapshot[`Plugin - ExpressionStatement 1`] = ` +{ + expression: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 5, + ], + type: "ExpressionStatement", +} +`; + +snapshot[`Plugin - ForInStatement 1`] = ` +{ + body: { + body: [], + range: [ + 14, + 16, + ], + type: "BlockStatement", + }, + left: { + name: "a", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 16, + ], + right: { + name: "b", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ForInStatement", +} +`; + +snapshot[`Plugin - ForOfStatement 1`] = ` +{ + await: false, + body: { + body: [], + range: [ + 14, + 16, + ], + type: "BlockStatement", + }, + left: { + name: "a", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 16, + ], + right: { + name: "b", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ForOfStatement", +} +`; + +snapshot[`Plugin - ForOfStatement 2`] = ` +{ + await: true, + body: { + body: [], + range: [ + 20, + 22, + ], + type: "BlockStatement", + }, + left: { + name: "a", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 22, + ], + right: { + name: "b", + optional: false, + range: [ + 17, + 18, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ForOfStatement", +} +`; + +snapshot[`Plugin - ForStatement 1`] = ` +{ + body: { + body: [], + range: [ + 10, + 12, + ], + type: "BlockStatement", + }, + init: null, + range: [ + 1, + 12, + ], + test: null, + type: "ForStatement", + update: null, +} +`; + +snapshot[`Plugin - ForStatement 2`] = ` +{ + body: { + body: [], + range: [ + 15, + 17, + ], + type: "BlockStatement", + }, + init: { + name: "a", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 17, + ], + test: { + name: "b", + optional: false, + range: [ + 9, + 10, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ForStatement", + update: { + name: "c", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, +} +`; + +snapshot[`Plugin - IfStatement 1`] = ` +{ + alternate: null, + consequent: { + body: [], + range: [ + 10, + 12, + ], + type: "BlockStatement", + }, + range: [ + 1, + 12, + ], + test: { + name: "foo", + optional: false, + range: [ + 5, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "IfStatement", +} +`; + +snapshot[`Plugin - IfStatement 2`] = ` +{ + alternate: { + body: [], + range: [ + 18, + 20, + ], + type: "BlockStatement", + }, + consequent: { + body: [], + range: [ + 10, + 12, + ], + type: "BlockStatement", + }, + range: [ + 1, + 20, + ], + test: { + name: "foo", + optional: false, + range: [ + 5, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "IfStatement", +} +`; + +snapshot[`Plugin - LabeledStatement 1`] = ` +{ + body: { + body: [], + range: [ + 6, + 8, + ], + type: "BlockStatement", + }, + label: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 8, + ], + type: "LabeledStatement", +} +`; + +snapshot[`Plugin - ReturnStatement 1`] = ` +{ + argument: null, + range: [ + 1, + 7, + ], + type: "ReturnStatement", +} +`; + +snapshot[`Plugin - ReturnStatement 2`] = ` +{ + argument: { + name: "foo", + optional: false, + range: [ + 8, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 12, + ], + type: "ReturnStatement", +} +`; + +snapshot[`Plugin - SwitchStatement 1`] = ` +{ + cases: [ + { + consequent: [], + range: [ + 22, + 31, + ], + test: { + name: "foo", + optional: false, + range: [ + 27, + 30, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "SwitchCase", + }, + { + consequent: [ + { + label: null, + range: [ + 56, + 62, + ], + type: "BreakStatement", + }, + ], + range: [ + 38, + 62, + ], + test: { + name: "bar", + optional: false, + range: [ + 43, + 46, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "SwitchCase", + }, + { + consequent: [ + { + body: [], + range: [ + 86, + 88, + ], + type: "BlockStatement", + }, + ], + range: [ + 69, + 88, + ], + test: null, + type: "SwitchCase", + }, + ], + discriminant: { + name: "foo", + optional: false, + range: [ + 9, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 94, + ], + type: "SwitchStatement", +} +`; + +snapshot[`Plugin - ThrowStatement 1`] = ` +{ + argument: { + name: "foo", + optional: false, + range: [ + 7, + 10, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 11, + ], + type: "ThrowStatement", +} +`; + +snapshot[`Plugin - TryStatement 1`] = ` +{ + block: { + body: [], + range: [ + 5, + 7, + ], + type: "BlockStatement", + }, + finalizer: null, + handler: { + body: { + body: [], + range: [ + 14, + 16, + ], + type: "BlockStatement", + }, + param: null, + range: [ + 8, + 16, + ], + type: "CatchClause", + }, + range: [ + 1, + 16, + ], + type: "TryStatement", +} +`; + +snapshot[`Plugin - TryStatement 2`] = ` +{ + block: { + body: [], + range: [ + 5, + 7, + ], + type: "BlockStatement", + }, + finalizer: null, + handler: { + body: { + body: [], + range: [ + 18, + 20, + ], + type: "BlockStatement", + }, + param: { + name: "e", + optional: false, + range: [ + 15, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 8, + 20, + ], + type: "CatchClause", + }, + range: [ + 1, + 20, + ], + type: "TryStatement", +} +`; + +snapshot[`Plugin - TryStatement 3`] = ` +{ + block: { + body: [], + range: [ + 5, + 7, + ], + type: "BlockStatement", + }, + finalizer: { + body: [], + range: [ + 16, + 18, + ], + type: "BlockStatement", + }, + handler: null, + range: [ + 1, + 18, + ], + type: "TryStatement", +} +`; + +snapshot[`Plugin - WhileStatement 1`] = ` +{ + body: { + body: [], + range: [ + 13, + 15, + ], + type: "BlockStatement", + }, + range: [ + 1, + 15, + ], + test: { + name: "foo", + optional: false, + range: [ + 8, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "WhileStatement", +} +`; + +snapshot[`Plugin - WithStatement 1`] = ` +{ + body: { + body: [], + range: [ + 11, + 13, + ], + type: "BlockStatement", + }, + object: { + elements: [], + range: [ + 7, + 9, + ], + type: "ArrayExpression", + }, + range: [ + 1, + 13, + ], + type: "WithStatement", +} +`; + +snapshot[`Plugin - ArrayExpression 1`] = ` +{ + elements: [ + { + elements: [], + range: [ + 2, + 4, + ], + type: "ArrayExpression", + }, + ], + range: [ + 1, + 9, + ], + type: "ArrayExpression", +} +`; + +snapshot[`Plugin - ArrowFunctionExpression 1`] = ` +{ + async: false, + body: { + body: [], + range: [ + 7, + 9, + ], + type: "BlockStatement", + }, + generator: false, + params: [], + range: [ + 1, + 9, + ], + returnType: null, + type: "ArrowFunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - ArrowFunctionExpression 2`] = ` +{ + async: true, + body: { + body: [], + range: [ + 13, + 15, + ], + type: "BlockStatement", + }, + generator: false, + params: [], + range: [ + 1, + 15, + ], + returnType: null, + type: "ArrowFunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - ArrowFunctionExpression 3`] = ` +{ + async: false, + body: { + body: [], + range: [ + 34, + 36, + ], + type: "BlockStatement", + }, + generator: false, + params: [ + { + name: "a", + optional: false, + range: [ + 2, + 11, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 3, + 11, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 5, + 11, + ], + type: "TSNumberKeyword", + }, + }, + }, + { + argument: { + name: "b", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 13, + 24, + ], + type: "RestElement", + typeAnnotation: { + range: [ + 17, + 24, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + elementType: { + range: [ + 19, + 22, + ], + type: "TSAnyKeyword", + }, + range: [ + 19, + 24, + ], + type: "TSArrayType", + }, + }, + }, + ], + range: [ + 1, + 36, + ], + returnType: { + range: [ + 25, + 30, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 27, + 30, + ], + type: "TSAnyKeyword", + }, + }, + type: "ArrowFunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - AssignmentExpression 1`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "=", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "AssignmentExpression", +} +`; + +snapshot[`Plugin - AssignmentExpression 2`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "=", + range: [ + 1, + 12, + ], + right: { + left: { + name: "a", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "??=", + range: [ + 5, + 12, + ], + right: { + name: "b", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "AssignmentExpression", + }, + type: "AssignmentExpression", +} +`; + +snapshot[`Plugin - AwaitExpression 1`] = ` +{ + argument: { + name: "foo", + optional: false, + range: [ + 7, + 10, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 10, + ], + type: "AwaitExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 1`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: ">", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 2`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: ">=", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 3`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "<", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 4`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "<=", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 5`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "==", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 6`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "===", + range: [ + 1, + 8, + ], + right: { + name: "b", + optional: false, + range: [ + 7, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 7`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "!=", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 8`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "!=", + range: [ + 1, + 8, + ], + right: { + name: "b", + optional: false, + range: [ + 7, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 9`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "<<", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 10`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: ">>", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 11`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: ">>>", + range: [ + 1, + 8, + ], + right: { + name: "b", + optional: false, + range: [ + 7, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 12`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "+", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 13`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "-", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 14`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "*", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 15`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "/", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 16`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "%", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 17`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "|", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 18`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "^", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 19`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "&", + range: [ + 1, + 6, + ], + right: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 20`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "in", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - BinaryExpression 21`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "**", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", +} +`; + +snapshot[`Plugin - CallExpression 1`] = ` +{ + arguments: [], + callee: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 1, + 6, + ], + type: "CallExpression", + typeArguments: null, +} +`; + +snapshot[`Plugin - CallExpression 2`] = ` +{ + arguments: [ + { + name: "a", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + { + argument: { + name: "b", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 8, + 11, + ], + type: "SpreadElement", + }, + ], + callee: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 1, + 13, + ], + type: "CallExpression", + typeArguments: null, +} +`; + +snapshot[`Plugin - CallExpression 3`] = ` +{ + arguments: [], + callee: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: true, + range: [ + 1, + 8, + ], + type: "CallExpression", + typeArguments: null, +} +`; + +snapshot[`Plugin - CallExpression 4`] = ` +{ + arguments: [], + callee: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 1, + 9, + ], + type: "CallExpression", + typeArguments: { + params: [ + { + range: [ + 5, + 6, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 4, + 7, + ], + type: "TSTypeParameterInstantiation", + }, +} +`; + +snapshot[`Plugin - ChainExpression 1`] = ` +{ + expression: { + computed: false, + object: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: true, + property: { + name: "b", + optional: false, + range: [ + 4, + 5, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 5, + ], + type: "MemberExpression", + }, + range: [ + 1, + 5, + ], + type: "ChainExpression", +} +`; + +snapshot[`Plugin - ClassExpression 1`] = ` +{ + abstract: false, + body: { + body: [], + range: [ + 5, + 13, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 13, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 2`] = ` +{ + abstract: false, + body: { + body: [], + range: [ + 5, + 17, + ], + type: "ClassBody", + }, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 11, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + implements: [], + range: [ + 5, + 17, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 3`] = ` +{ + abstract: false, + body: { + body: [], + range: [ + 5, + 29, + ], + type: "ClassBody", + }, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 11, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + implements: [], + range: [ + 5, + 29, + ], + superClass: { + name: "Bar", + optional: false, + range: [ + 23, + 26, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 4`] = ` +{ + abstract: false, + body: { + body: [], + range: [ + 5, + 50, + ], + type: "ClassBody", + }, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 11, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + implements: [ + { + expression: { + name: "Baz", + optional: false, + range: [ + 38, + 41, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 38, + 41, + ], + type: "TSClassImplements", + typeArguments: null, + }, + { + expression: { + name: "Baz2", + optional: false, + range: [ + 43, + 47, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 43, + 47, + ], + type: "TSClassImplements", + typeArguments: null, + }, + ], + range: [ + 5, + 50, + ], + superClass: { + name: "Bar", + optional: false, + range: [ + 23, + 26, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 5`] = ` +{ + abstract: false, + body: { + body: [], + range: [ + 5, + 20, + ], + type: "ClassBody", + }, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 11, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + implements: [], + range: [ + 5, + 20, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 6`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + key: { + name: "foo", + optional: false, + range: [ + 13, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "method", + optional: false, + override: false, + range: [ + 13, + 21, + ], + static: false, + type: "MethodDefinition", + value: { + async: false, + body: { + body: [], + range: [ + 19, + 21, + ], + type: "BlockStatement", + }, + generator: false, + id: null, + params: [], + range: [ + 13, + 21, + ], + returnType: null, + type: "FunctionExpression", + typeParameters: null, + }, + }, + ], + range: [ + 5, + 23, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 23, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 7`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + key: { + name: "foo", + range: [ + 13, + 17, + ], + type: "PrivateIdentifier", + }, + kind: "method", + optional: false, + override: false, + range: [ + 13, + 22, + ], + static: false, + type: "MethodDefinition", + value: { + async: false, + body: { + body: [], + range: [ + 20, + 22, + ], + type: "BlockStatement", + }, + generator: false, + id: null, + params: [], + range: [ + 13, + 22, + ], + returnType: null, + type: "FunctionExpression", + typeParameters: null, + }, + }, + ], + range: [ + 5, + 24, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 24, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 8`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + decorators: [], + key: { + name: "foo", + optional: false, + range: [ + 13, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + override: false, + range: [ + 13, + 24, + ], + readonly: false, + static: false, + type: "PropertyDefinition", + value: null, + }, + ], + range: [ + 5, + 26, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 26, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 9`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + decorators: [], + key: { + name: "foo", + optional: false, + range: [ + 13, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + override: false, + range: [ + 13, + 22, + ], + readonly: false, + static: false, + type: "PropertyDefinition", + value: { + name: "bar", + optional: false, + range: [ + 19, + 22, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 5, + 24, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 24, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 10`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + key: { + name: "constructor", + optional: false, + range: [ + 13, + 24, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "constructor", + optional: false, + override: false, + range: [ + 13, + 47, + ], + static: false, + type: "MethodDefinition", + value: { + async: false, + body: { + body: [], + range: [ + 45, + 47, + ], + type: "BlockStatement", + }, + generator: false, + id: null, + params: [ + { + accessibility: undefined, + decorators: [], + override: false, + parameter: { + name: "foo", + optional: false, + range: [ + 32, + 35, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 35, + 43, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 37, + 43, + ], + type: "TSStringKeyword", + }, + }, + }, + range: [ + 25, + 43, + ], + readonly: false, + static: false, + type: "TSParameterProperty", + }, + ], + range: [ + 13, + 47, + ], + returnType: null, + type: "FunctionExpression", + typeParameters: null, + }, + }, + ], + range: [ + 5, + 49, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 49, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 11`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + decorators: [], + key: { + name: "foo", + range: [ + 13, + 17, + ], + type: "PrivateIdentifier", + }, + optional: false, + override: false, + range: [ + 13, + 31, + ], + readonly: false, + static: false, + type: "PropertyDefinition", + value: { + name: "bar", + optional: false, + range: [ + 28, + 31, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 5, + 33, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 33, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 12`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + decorators: [], + key: { + name: "foo", + optional: false, + range: [ + 20, + 23, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + override: false, + range: [ + 13, + 29, + ], + readonly: false, + static: true, + type: "PropertyDefinition", + value: { + name: "bar", + optional: false, + range: [ + 26, + 29, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 5, + 31, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 31, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ClassExpression 13`] = ` +{ + abstract: false, + body: { + body: [ + { + accessibility: undefined, + computed: false, + declare: false, + decorators: [], + key: { + name: "foo", + optional: false, + range: [ + 20, + 23, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + override: false, + range: [ + 13, + 24, + ], + readonly: false, + static: true, + type: "PropertyDefinition", + value: null, + }, + { + body: { + body: [ + { + expression: { + left: { + name: "foo", + optional: false, + range: [ + 34, + 37, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "=", + range: [ + 34, + 43, + ], + right: { + name: "bar", + optional: false, + range: [ + 40, + 43, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "AssignmentExpression", + }, + range: [ + 34, + 43, + ], + type: "ExpressionStatement", + }, + ], + range: [ + 32, + 45, + ], + type: "BlockStatement", + }, + range: [ + 25, + 45, + ], + type: "StaticBlock", + }, + ], + range: [ + 5, + 47, + ], + type: "ClassBody", + }, + declare: false, + id: null, + implements: [], + range: [ + 5, + 47, + ], + superClass: null, + type: "ClassExpression", +} +`; + +snapshot[`Plugin - ConditionalExpression 1`] = ` +{ + alternate: { + name: "c", + optional: false, + range: [ + 9, + 10, + ], + type: "Identifier", + typeAnnotation: null, + }, + consequent: { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 10, + ], + test: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "ConditionalExpression", +} +`; + +snapshot[`Plugin - FunctionExpression 1`] = ` +{ + async: false, + body: { + body: [], + range: [ + 17, + 19, + ], + type: "BlockStatement", + }, + generator: false, + id: null, + params: [], + range: [ + 5, + 19, + ], + returnType: null, + type: "FunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - FunctionExpression 2`] = ` +{ + async: false, + body: { + body: [], + range: [ + 20, + 22, + ], + type: "BlockStatement", + }, + generator: false, + id: { + name: "foo", + optional: false, + range: [ + 14, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + params: [], + range: [ + 5, + 22, + ], + returnType: null, + type: "FunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - FunctionExpression 3`] = ` +{ + async: false, + body: { + body: [], + range: [ + 45, + 47, + ], + type: "BlockStatement", + }, + generator: false, + id: null, + params: [ + { + name: "a", + optional: true, + range: [ + 15, + 16, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 17, + 25, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 19, + 25, + ], + type: "TSNumberKeyword", + }, + }, + }, + { + argument: { + name: "b", + optional: false, + range: [ + 30, + 31, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 27, + 38, + ], + type: "RestElement", + typeAnnotation: { + range: [ + 31, + 38, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + elementType: { + range: [ + 33, + 36, + ], + type: "TSAnyKeyword", + }, + range: [ + 33, + 38, + ], + type: "TSArrayType", + }, + }, + }, + ], + range: [ + 5, + 47, + ], + returnType: { + range: [ + 39, + 44, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 41, + 44, + ], + type: "TSAnyKeyword", + }, + }, + type: "FunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - FunctionExpression 4`] = ` +{ + async: true, + body: { + body: [], + range: [ + 24, + 26, + ], + type: "BlockStatement", + }, + generator: true, + id: null, + params: [], + range: [ + 5, + 26, + ], + returnType: null, + type: "FunctionExpression", + typeParameters: null, +} +`; + +snapshot[`Plugin - Identifier 1`] = ` +{ + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, +} +`; + +snapshot[`Plugin - ImportExpression 1`] = ` +{ + options: { + properties: [ + { + computed: false, + key: { + name: "with", + optional: false, + range: [ + 17, + 21, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "init", + method: false, + range: [ + 17, + 39, + ], + shorthand: false, + type: "Property", + value: { + properties: [ + { + computed: false, + key: { + name: "type", + optional: false, + range: [ + 25, + 29, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "init", + method: false, + range: [ + 25, + 37, + ], + shorthand: false, + type: "Property", + value: { + range: [ + 31, + 37, + ], + raw: "'json'", + type: "Literal", + value: "json", + }, + }, + ], + range: [ + 23, + 39, + ], + type: "ObjectExpression", + }, + }, + ], + range: [ + 15, + 41, + ], + type: "ObjectExpression", + }, + range: [ + 1, + 42, + ], + source: { + range: [ + 8, + 13, + ], + raw: "'foo'", + type: "Literal", + value: "foo", + }, + type: "ImportExpression", +} +`; + +snapshot[`Plugin - LogicalExpression 1`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "&&", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "LogicalExpression", +} +`; + +snapshot[`Plugin - LogicalExpression 2`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "||", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "LogicalExpression", +} +`; + +snapshot[`Plugin - LogicalExpression 3`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "??", + range: [ + 1, + 7, + ], + right: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "LogicalExpression", +} +`; + +snapshot[`Plugin - MemberExpression 1`] = ` +{ + computed: false, + object: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + property: { + name: "b", + optional: false, + range: [ + 3, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 4, + ], + type: "MemberExpression", +} +`; + +snapshot[`Plugin - MemberExpression 2`] = ` +{ + computed: true, + object: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + property: { + range: [ + 3, + 6, + ], + raw: "'b'", + type: "Literal", + value: "b", + }, + range: [ + 1, + 7, + ], + type: "MemberExpression", +} +`; + +snapshot[`Plugin - MetaProperty 1`] = ` +{ + property: { + name: "meta", + optional: false, + range: [ + 1, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 12, + ], + type: "MetaProperty", +} +`; + +snapshot[`Plugin - NewExpression 1`] = ` +{ + arguments: [], + callee: { + name: "Foo", + optional: false, + range: [ + 5, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 10, + ], + type: "NewExpression", + typeArguments: null, +} +`; + +snapshot[`Plugin - NewExpression 2`] = ` +{ + arguments: [ + { + name: "a", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + { + argument: { + name: "b", + optional: false, + range: [ + 18, + 19, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 15, + 18, + ], + type: "SpreadElement", + }, + ], + callee: { + name: "Foo", + optional: false, + range: [ + 5, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 20, + ], + type: "NewExpression", + typeArguments: { + params: [ + { + range: [ + 9, + 10, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 9, + 10, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 8, + 11, + ], + type: "TSTypeParameterInstantiation", + }, +} +`; + +snapshot[`Plugin - ObjectExpression 1`] = ` +{ + properties: [], + range: [ + 5, + 7, + ], + type: "ObjectExpression", +} +`; + +snapshot[`Plugin - ObjectExpression 2`] = ` +{ + properties: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 7, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "init", + method: false, + range: [ + 7, + 8, + ], + shorthand: true, + type: "Property", + value: { + name: "a", + optional: false, + range: [ + 7, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 5, + 10, + ], + type: "ObjectExpression", +} +`; + +snapshot[`Plugin - ObjectExpression 3`] = ` +{ + properties: [ + { + computed: false, + key: { + name: "b", + optional: false, + range: [ + 7, + 8, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "init", + method: false, + range: [ + 7, + 11, + ], + shorthand: false, + type: "Property", + value: { + name: "c", + optional: false, + range: [ + 10, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + { + computed: true, + key: { + name: "c", + optional: false, + range: [ + 14, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "init", + method: false, + range: [ + 13, + 19, + ], + shorthand: false, + type: "Property", + value: { + name: "d", + optional: false, + range: [ + 18, + 19, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 5, + 21, + ], + type: "ObjectExpression", +} +`; + +snapshot[`Plugin - PrivateIdentifier 1`] = ` +{ + name: "foo", + range: [ + 13, + 17, + ], + type: "PrivateIdentifier", +} +`; + +snapshot[`Plugin - SequenceExpression 1`] = ` +{ + expressions: [ + { + name: "a", + optional: false, + range: [ + 2, + 3, + ], + type: "Identifier", + typeAnnotation: null, + }, + { + name: "b", + optional: false, + range: [ + 5, + 6, + ], + type: "Identifier", + typeAnnotation: null, + }, + ], + range: [ + 2, + 6, + ], + type: "SequenceExpression", +} +`; + +snapshot[`Plugin - Super 1`] = ` +{ + range: [ + 41, + 46, + ], + type: "Super", +} +`; + +snapshot[`Plugin - TaggedTemplateExpression 1`] = ` +{ + quasi: { + expressions: [ + { + name: "bar", + optional: false, + range: [ + 11, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + ], + quasis: [ + { + cooked: "foo ", + range: [ + 5, + 9, + ], + raw: "foo ", + tail: false, + type: "TemplateElement", + }, + { + cooked: " baz", + range: [ + 15, + 19, + ], + raw: " baz", + tail: true, + type: "TemplateElement", + }, + ], + range: [ + 4, + 20, + ], + type: "TemplateLiteral", + }, + range: [ + 1, + 20, + ], + tag: { + name: "foo", + optional: false, + range: [ + 1, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "TaggedTemplateExpression", + typeArguments: null, +} +`; + +snapshot[`Plugin - TemplateLiteral 1`] = ` +{ + expressions: [ + { + name: "bar", + optional: false, + range: [ + 8, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + ], + quasis: [ + { + cooked: "foo ", + range: [ + 2, + 6, + ], + raw: "foo ", + tail: false, + type: "TemplateElement", + }, + { + cooked: " baz", + range: [ + 12, + 16, + ], + raw: " baz", + tail: true, + type: "TemplateElement", + }, + ], + range: [ + 1, + 17, + ], + type: "TemplateLiteral", +} +`; + +snapshot[`Plugin - ThisExpression 1`] = ` +{ + range: [ + 1, + 5, + ], + type: "ThisExpression", +} +`; + +snapshot[`Plugin - TSAsExpression 1`] = ` +{ + expression: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 7, + ], + type: "TSAsExpression", + typeAnnotation: { + range: [ + 6, + 7, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "b", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, +} +`; + +snapshot[`Plugin - TSAsExpression 2`] = ` +{ + expression: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 11, + ], + type: "TSAsExpression", + typeAnnotation: { + range: [ + 1, + 11, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "const", + optional: false, + range: [ + 1, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, +} +`; + +snapshot[`Plugin - TSNonNullExpression 1`] = ` +{ + expression: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 3, + ], + type: "TSNonNullExpression", +} +`; + +snapshot[`Plugin - TSSatisfiesExpression 1`] = ` +{ + expression: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 14, + ], + type: "TSSatisfiesExpression", + typeAnnotation: { + range: [ + 13, + 14, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "b", + optional: false, + range: [ + 13, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, +} +`; + +snapshot[`Plugin - UnaryExpression 1`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 8, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "typeof", + range: [ + 1, + 9, + ], + type: "UnaryExpression", +} +`; + +snapshot[`Plugin - UnaryExpression 2`] = ` +{ + argument: { + range: [ + 6, + 7, + ], + raw: "0", + type: "Literal", + value: 0, + }, + operator: "void", + range: [ + 1, + 7, + ], + type: "UnaryExpression", +} +`; + +snapshot[`Plugin - UnaryExpression 3`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 2, + 3, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "-", + range: [ + 1, + 3, + ], + type: "UnaryExpression", +} +`; + +snapshot[`Plugin - UnaryExpression 4`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 2, + 3, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "+", + range: [ + 1, + 3, + ], + type: "UnaryExpression", +} +`; + +snapshot[`Plugin - UpdateExpression 1`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "++", + prefix: false, + range: [ + 1, + 4, + ], + type: "UpdateExpression", +} +`; + +snapshot[`Plugin - UpdateExpression 2`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 3, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "++", + prefix: true, + range: [ + 1, + 4, + ], + type: "UpdateExpression", +} +`; + +snapshot[`Plugin - UpdateExpression 3`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "--", + prefix: false, + range: [ + 1, + 4, + ], + type: "UpdateExpression", +} +`; + +snapshot[`Plugin - UpdateExpression 4`] = ` +{ + argument: { + name: "a", + optional: false, + range: [ + 3, + 4, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "--", + prefix: true, + range: [ + 1, + 4, + ], + type: "UpdateExpression", +} +`; + +snapshot[`Plugin - YieldExpression 1`] = ` +{ + argument: { + name: "bar", + optional: false, + range: [ + 25, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + delegate: false, + range: [ + 19, + 28, + ], + type: "YieldExpression", +} +`; + +snapshot[`Plugin - Literal 1`] = ` +{ + range: [ + 1, + 2, + ], + raw: "1", + type: "Literal", + value: 1, +} +`; + +snapshot[`Plugin - Literal 2`] = ` +{ + range: [ + 1, + 6, + ], + raw: "'foo'", + type: "Literal", + value: "foo", +} +`; + +snapshot[`Plugin - Literal 3`] = ` +{ + range: [ + 1, + 6, + ], + raw: '"foo"', + type: "Literal", + value: "foo", +} +`; + +snapshot[`Plugin - Literal 4`] = ` +{ + range: [ + 1, + 5, + ], + raw: "true", + type: "Literal", + value: true, +} +`; + +snapshot[`Plugin - Literal 5`] = ` +{ + range: [ + 1, + 6, + ], + raw: "false", + type: "Literal", + value: false, +} +`; + +snapshot[`Plugin - Literal 6`] = ` +{ + range: [ + 1, + 5, + ], + raw: "null", + type: "Literal", + value: null, +} +`; + +snapshot[`Plugin - Literal 7`] = ` +{ + bigint: "1", + range: [ + 1, + 3, + ], + raw: "1n", + type: "Literal", + value: 1n, +} +`; + +snapshot[`Plugin - Literal 8`] = ` +{ + range: [ + 1, + 7, + ], + raw: "/foo/g", + regex: { + flags: "g", + pattern: "foo", + }, + type: "Literal", + value: /foo/g, +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 1`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 8, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 8, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 2`] = ` +{ + children: [], + closingElement: { + name: { + name: "div", + range: [ + 8, + 11, + ], + type: "JSXIdentifier", + }, + range: [ + 6, + 12, + ], + type: "JSXClosingElement", + }, + openingElement: { + attributes: [], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 6, + ], + selfClosing: false, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 12, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 3`] = ` +{ + children: [], + closingElement: { + name: { + name: "div", + range: [ + 10, + 13, + ], + type: "JSXIdentifier", + }, + range: [ + 8, + 14, + ], + type: "JSXClosingElement", + }, + openingElement: { + attributes: [ + { + name: { + name: "a", + range: [ + 6, + 7, + ], + type: "JSXIdentifier", + }, + range: [ + 6, + 7, + ], + type: "JSXAttribute", + value: null, + }, + ], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 8, + ], + selfClosing: false, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 14, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 4`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [ + { + name: { + name: "a", + range: [ + 6, + 7, + ], + type: "JSXIdentifier", + }, + range: [ + 6, + 11, + ], + type: "JSXAttribute", + value: { + range: [ + 8, + 11, + ], + raw: '"b"', + type: "Literal", + value: "b", + }, + }, + ], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 14, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 14, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 5`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [ + { + name: { + name: "a", + range: [ + 6, + 7, + ], + type: "JSXIdentifier", + }, + range: [ + 6, + 11, + ], + type: "JSXAttribute", + value: { + expression: { + range: [ + 9, + 10, + ], + raw: "2", + type: "Literal", + value: 2, + }, + range: [ + 8, + 11, + ], + type: "JSXExpressionContainer", + }, + }, + ], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 14, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 14, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 6`] = ` +{ + children: [ + { + range: [ + 6, + 9, + ], + raw: "foo", + type: "JSXText", + value: "foo", + }, + { + expression: { + range: [ + 10, + 11, + ], + raw: "2", + type: "Literal", + value: 2, + }, + range: [ + 9, + 12, + ], + type: "JSXExpressionContainer", + }, + ], + closingElement: { + name: { + name: "div", + range: [ + 14, + 17, + ], + type: "JSXIdentifier", + }, + range: [ + 12, + 18, + ], + type: "JSXClosingElement", + }, + openingElement: { + attributes: [], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 6, + ], + selfClosing: false, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 18, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 7`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [], + name: { + object: { + name: "a", + range: [ + 2, + 3, + ], + type: "JSXIdentifier", + }, + property: { + name: "b", + range: [ + 4, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 2, + 5, + ], + type: "JSXMemberExpression", + }, + range: [ + 1, + 8, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 8, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 8`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [ + { + name: { + name: { + name: "b", + range: [ + 8, + 9, + ], + type: "JSXIdentifier", + }, + namespace: { + name: "a", + range: [ + 6, + 7, + ], + type: "JSXIdentifier", + }, + range: [ + 6, + 9, + ], + type: "JSXNamespacedName", + }, + range: [ + 6, + 13, + ], + type: "JSXAttribute", + value: { + expression: { + range: [ + 11, + 12, + ], + raw: "2", + type: "Literal", + value: 2, + }, + range: [ + 10, + 13, + ], + type: "JSXExpressionContainer", + }, + }, + ], + name: { + name: "div", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 16, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 16, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 9`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [], + name: { + name: "Foo", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 8, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: null, + }, + range: [ + 1, + 8, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr 10`] = ` +{ + children: [], + closingElement: null, + openingElement: { + attributes: [], + name: { + name: "Foo", + range: [ + 2, + 5, + ], + type: "JSXIdentifier", + }, + range: [ + 1, + 11, + ], + selfClosing: true, + type: "JSXOpeningElement", + typeArguments: { + params: [ + { + range: [ + 6, + 7, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 5, + 8, + ], + type: "TSTypeParameterInstantiation", + }, + }, + range: [ + 1, + 11, + ], + type: "JSXElement", +} +`; + +snapshot[`Plugin - JSXFragment + JSXOpeningFragment + JSXClosingFragment 1`] = ` +{ + children: [], + closingFragment: { + range: [ + 3, + 6, + ], + type: "JSXClosingFragment", + }, + openingFragment: { + range: [ + 1, + 3, + ], + type: "JSXOpeningFragment", + }, + range: [ + 1, + 6, + ], + type: "JSXFragment", +} +`; + +snapshot[`Plugin - JSXFragment + JSXOpeningFragment + JSXClosingFragment 2`] = ` +{ + children: [ + { + range: [ + 3, + 6, + ], + raw: "foo", + type: "JSXText", + value: "foo", + }, + { + expression: { + range: [ + 7, + 8, + ], + raw: "2", + type: "Literal", + value: 2, + }, + range: [ + 6, + 9, + ], + type: "JSXExpressionContainer", + }, + ], + closingFragment: { + range: [ + 9, + 12, + ], + type: "JSXClosingFragment", + }, + openingFragment: { + range: [ + 1, + 3, + ], + type: "JSXOpeningFragment", + }, + range: [ + 1, + 12, + ], + type: "JSXFragment", +} +`; + +snapshot[`Plugin - TSAsExpression 3`] = ` +{ + expression: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 9, + ], + type: "TSAsExpression", + typeAnnotation: { + range: [ + 6, + 9, + ], + type: "TSAnyKeyword", + }, +} +`; + +snapshot[`Plugin - TSAsExpression 4`] = ` +{ + expression: { + range: [ + 1, + 6, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + range: [ + 1, + 15, + ], + type: "TSAsExpression", + typeAnnotation: { + range: [ + 1, + 15, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "const", + optional: false, + range: [ + 1, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, +} +`; + +snapshot[`Plugin - TSEnumDeclaration 1`] = ` +{ + body: { + members: [], + range: [ + 1, + 12, + ], + type: "TSEnumBody", + }, + const: false, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 6, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 12, + ], + type: "TSEnumDeclaration", +} +`; + +snapshot[`Plugin - TSEnumDeclaration 2`] = ` +{ + body: { + members: [], + range: [ + 1, + 18, + ], + type: "TSEnumBody", + }, + const: true, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 12, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 18, + ], + type: "TSEnumDeclaration", +} +`; + +snapshot[`Plugin - TSEnumDeclaration 3`] = ` +{ + body: { + members: [ + { + id: { + name: "A", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + initializer: null, + range: [ + 12, + 13, + ], + type: "TSEnumMember", + }, + { + id: { + name: "B", + optional: false, + range: [ + 15, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + initializer: null, + range: [ + 15, + 16, + ], + type: "TSEnumMember", + }, + ], + range: [ + 1, + 18, + ], + type: "TSEnumBody", + }, + const: false, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 6, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 18, + ], + type: "TSEnumDeclaration", +} +`; + +snapshot[`Plugin - TSEnumDeclaration 4`] = ` +{ + body: { + members: [ + { + id: { + range: [ + 12, + 17, + ], + raw: '"a-b"', + type: "Literal", + value: "a-b", + }, + initializer: null, + range: [ + 12, + 17, + ], + type: "TSEnumMember", + }, + ], + range: [ + 1, + 19, + ], + type: "TSEnumBody", + }, + const: false, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 6, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 19, + ], + type: "TSEnumDeclaration", +} +`; + +snapshot[`Plugin - TSEnumDeclaration 5`] = ` +{ + body: { + members: [ + { + id: { + name: "A", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + initializer: { + range: [ + 16, + 17, + ], + raw: "1", + type: "Literal", + value: 1, + }, + range: [ + 12, + 17, + ], + type: "TSEnumMember", + }, + { + id: { + name: "B", + optional: false, + range: [ + 19, + 20, + ], + type: "Identifier", + typeAnnotation: null, + }, + initializer: { + range: [ + 23, + 24, + ], + raw: "2", + type: "Literal", + value: 2, + }, + range: [ + 19, + 24, + ], + type: "TSEnumMember", + }, + { + id: { + name: "C", + optional: false, + range: [ + 26, + 27, + ], + type: "Identifier", + typeAnnotation: null, + }, + initializer: { + left: { + name: "A", + optional: false, + range: [ + 30, + 31, + ], + type: "Identifier", + typeAnnotation: null, + }, + operator: "|", + range: [ + 30, + 35, + ], + right: { + name: "B", + optional: false, + range: [ + 34, + 35, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "BinaryExpression", + }, + range: [ + 26, + 35, + ], + type: "TSEnumMember", + }, + ], + range: [ + 1, + 37, + ], + type: "TSEnumBody", + }, + const: false, + declare: false, + id: { + name: "Foo", + optional: false, + range: [ + 6, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 37, + ], + type: "TSEnumDeclaration", +} +`; + +snapshot[`Plugin - TSInterface 1`] = ` +{ + body: { + body: [], + range: [ + 13, + 15, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 15, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 2`] = ` +{ + body: { + body: [], + range: [ + 16, + 18, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 13, + 14, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 13, + 14, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 12, + 15, + ], + type: "TSTypeParameterDeclaration", + }, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 18, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 3`] = ` +{ + body: { + body: [], + range: [ + 36, + 38, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 38, + ], + type: "TSInterface", + typeParameters: [ + { + expression: { + name: "Foo", + optional: false, + range: [ + 21, + 24, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 21, + 27, + ], + type: "TSInterfaceHeritage", + typeArguments: { + params: [ + { + range: [ + 25, + 26, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 25, + 26, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 24, + 27, + ], + type: "TSTypeParameterInstantiation", + }, + }, + { + expression: { + name: "Bar", + optional: false, + range: [ + 29, + 32, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 29, + 35, + ], + type: "TSInterfaceHeritage", + typeArguments: { + params: [ + { + range: [ + 33, + 34, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 33, + 34, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], + range: [ + 32, + 35, + ], + type: "TSTypeParameterInstantiation", + }, + }, + ], +} +`; + +snapshot[`Plugin - TSInterface 4`] = ` +{ + body: { + body: [ + { + computed: false, + key: { + name: "foo", + optional: false, + range: [ + 15, + 18, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 15, + 24, + ], + readonly: false, + static: false, + type: "TSPropertySignature", + typeAnnotation: { + range: [ + 18, + 23, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 20, + 23, + ], + type: "TSAnyKeyword", + }, + }, + }, + { + computed: false, + key: { + name: "bar", + optional: false, + range: [ + 25, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: true, + range: [ + 25, + 34, + ], + readonly: false, + static: false, + type: "TSPropertySignature", + typeAnnotation: { + range: [ + 29, + 34, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 31, + 34, + ], + type: "TSAnyKeyword", + }, + }, + }, + ], + range: [ + 13, + 36, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 36, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 5`] = ` +{ + body: { + body: [ + { + parameters: [ + { + name: "key", + optional: false, + range: [ + 25, + 36, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 28, + 36, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 30, + 36, + ], + type: "TSStringKeyword", + }, + }, + }, + ], + range: [ + 15, + 42, + ], + readonly: true, + type: "TSIndexSignature", + typeAnnotation: { + range: [ + 37, + 42, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 39, + 42, + ], + type: "TSAnyKeyword", + }, + }, + }, + ], + range: [ + 13, + 44, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 44, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 6`] = ` +{ + body: { + body: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 24, + 25, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 15, + 30, + ], + readonly: true, + static: false, + type: "TSPropertySignature", + typeAnnotation: { + range: [ + 25, + 30, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 27, + 30, + ], + type: "TSAnyKeyword", + }, + }, + }, + ], + range: [ + 13, + 32, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 32, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 7`] = ` +{ + body: { + body: [ + { + params: [ + { + name: "a", + optional: false, + range: [ + 19, + 20, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 20, + 23, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 22, + 23, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 22, + 23, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + }, + ], + range: [ + 15, + 27, + ], + returnType: { + range: [ + 24, + 27, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 26, + 27, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 26, + 27, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + type: "TSCallSignatureDeclaration", + typeAnnotation: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 16, + 17, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 15, + 18, + ], + type: "TSTypeParameterDeclaration", + }, + }, + ], + range: [ + 13, + 29, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 29, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 8`] = ` +{ + body: { + body: [ + { + params: [ + { + name: "a", + optional: false, + range: [ + 23, + 24, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 24, + 27, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 26, + 27, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 26, + 27, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + }, + ], + range: [ + 15, + 31, + ], + returnType: { + range: [ + 28, + 31, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 30, + 31, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 30, + 31, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + type: "TSConstructSignatureDeclaration", + typeParameters: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 20, + 21, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 20, + 21, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 19, + 22, + ], + type: "TSTypeParameterDeclaration", + }, + }, + ], + range: [ + 13, + 33, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 33, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 9`] = ` +{ + body: { + body: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 15, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 15, + 36, + ], + readonly: false, + static: false, + type: "TSPropertySignature", + typeAnnotation: { + range: [ + 16, + 36, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + params: [ + { + name: "a", + optional: false, + range: [ + 26, + 27, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 27, + 30, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 29, + 30, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 29, + 30, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + }, + ], + range: [ + 18, + 36, + ], + returnType: { + range: [ + 32, + 36, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 35, + 36, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 35, + 36, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + type: "TSConstructSignatureDeclaration", + typeParameters: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 23, + 24, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 23, + 24, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 22, + 25, + ], + type: "TSTypeParameterDeclaration", + }, + }, + }, + }, + ], + range: [ + 13, + 38, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 38, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 10`] = ` +{ + body: { + body: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 19, + 20, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "getter", + optional: false, + range: [ + 15, + 30, + ], + readonly: false, + returnType: { + range: [ + 22, + 30, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 24, + 30, + ], + type: "TSStringKeyword", + }, + }, + static: false, + type: "TSMethodSignature", + }, + ], + range: [ + 13, + 32, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 32, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 11`] = ` +{ + body: { + body: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 19, + 20, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "setter", + optional: false, + params: [ + { + name: "v", + optional: false, + range: [ + 21, + 22, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 22, + 30, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 24, + 30, + ], + type: "TSStringKeyword", + }, + }, + }, + ], + range: [ + 15, + 31, + ], + readonly: false, + static: false, + type: "TSMethodSignature", + }, + ], + range: [ + 13, + 33, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 33, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSInterface 12`] = ` +{ + body: { + body: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 15, + 16, + ], + type: "Identifier", + typeAnnotation: null, + }, + kind: "method", + optional: false, + params: [ + { + name: "arg", + optional: true, + range: [ + 20, + 23, + ], + type: "Identifier", + typeAnnotation: { + range: [ + 24, + 29, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 26, + 29, + ], + type: "TSAnyKeyword", + }, + }, + }, + { + argument: { + name: "args", + optional: false, + range: [ + 34, + 38, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 31, + 45, + ], + type: "RestElement", + typeAnnotation: { + range: [ + 38, + 45, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + elementType: { + range: [ + 40, + 43, + ], + type: "TSAnyKeyword", + }, + range: [ + 40, + 45, + ], + type: "TSArrayType", + }, + }, + }, + ], + range: [ + 15, + 51, + ], + readonly: false, + returnType: { + range: [ + 46, + 51, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 48, + 51, + ], + type: "TSAnyKeyword", + }, + }, + static: false, + type: "TSMethodSignature", + typeParameters: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 17, + 18, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 17, + 18, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 16, + 19, + ], + type: "TSTypeParameterDeclaration", + }, + }, + ], + range: [ + 13, + 53, + ], + type: "TSInterfaceBody", + }, + declare: false, + extends: null, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 53, + ], + type: "TSInterface", + typeParameters: [], +} +`; + +snapshot[`Plugin - TSSatisfiesExpression 2`] = ` +{ + expression: { + properties: [], + range: [ + 11, + 13, + ], + type: "ObjectExpression", + }, + range: [ + 11, + 25, + ], + type: "TSSatisfiesExpression", + typeAnnotation: { + range: [ + 24, + 25, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "A", + optional: false, + range: [ + 24, + 25, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, +} +`; + +snapshot[`Plugin - TSTypeAliasDeclaration 1`] = ` +{ + declare: false, + id: { + name: "A", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 13, + ], + type: "TSTypeAliasDeclaration", + typeAnnotation: { + range: [ + 10, + 13, + ], + type: "TSAnyKeyword", + }, + typeParameters: null, +} +`; + +snapshot[`Plugin - TSTypeAliasDeclaration 2`] = ` +{ + declare: false, + id: { + name: "A", + optional: false, + range: [ + 6, + 7, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 16, + ], + type: "TSTypeAliasDeclaration", + typeAnnotation: { + range: [ + 13, + 16, + ], + type: "TSAnyKeyword", + }, + typeParameters: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 8, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 8, + 9, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 7, + 10, + ], + type: "TSTypeParameterDeclaration", + }, +} +`; + +snapshot[`Plugin - TSTypeAliasDeclaration 3`] = ` +{ + declare: true, + id: { + name: "A", + optional: false, + range: [ + 14, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 24, + ], + type: "TSTypeAliasDeclaration", + typeAnnotation: { + range: [ + 21, + 24, + ], + type: "TSAnyKeyword", + }, + typeParameters: { + params: [ + { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "T", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 16, + 17, + ], + type: "TSTypeParameter", + }, + ], + range: [ + 15, + 18, + ], + type: "TSTypeParameterDeclaration", + }, +} +`; + +snapshot[`Plugin - TSNonNullExpression 2`] = ` +{ + expression: { + name: "a", + optional: false, + range: [ + 1, + 2, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 3, + ], + type: "TSNonNullExpression", +} +`; + +snapshot[`Plugin - TSUnionType 1`] = ` +{ + range: [ + 10, + 15, + ], + type: "TSUnionType", + types: [ + { + range: [ + 10, + 11, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "B", + optional: false, + range: [ + 10, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + { + range: [ + 14, + 15, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "C", + optional: false, + range: [ + 14, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], +} +`; + +snapshot[`Plugin - TSIntersectionType 1`] = ` +{ + range: [ + 10, + 15, + ], + type: "TSIntersectionType", + types: [ + { + range: [ + 10, + 11, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "B", + optional: false, + range: [ + 10, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + { + range: [ + 14, + 15, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "C", + optional: false, + range: [ + 14, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + ], +} +`; + +snapshot[`Plugin - TSModuleDeclaration 1`] = ` +{ + body: { + body: [], + range: [ + 10, + 12, + ], + type: "TSModuleBlock", + }, + declare: false, + global: false, + id: { + name: "A", + optional: false, + range: [ + 8, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 12, + ], + type: "TSModuleDeclaration", +} +`; + +snapshot[`Plugin - TSModuleDeclaration 2`] = ` +{ + body: { + body: [ + { + declaration: { + async: false, + body: null, + declare: false, + generator: false, + id: { + name: "A", + optional: false, + range: [ + 36, + 37, + ], + type: "Identifier", + typeAnnotation: null, + }, + params: [], + range: [ + 27, + 45, + ], + returnType: { + range: [ + 39, + 45, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + range: [ + 41, + 45, + ], + type: "TSVoidKeyword", + }, + }, + type: "FunctionDeclaration", + typeParameters: null, + }, + range: [ + 20, + 45, + ], + type: "ExportNamedDeclaration", + }, + ], + range: [ + 18, + 47, + ], + type: "TSModuleBlock", + }, + declare: true, + global: false, + id: { + name: "A", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 47, + ], + type: "TSModuleDeclaration", +} +`; + +snapshot[`Plugin - TSModuleDeclaration + TSModuleBlock 1`] = ` +{ + body: { + body: [], + range: [ + 10, + 12, + ], + type: "TSModuleBlock", + }, + declare: false, + global: false, + id: { + name: "A", + optional: false, + range: [ + 8, + 9, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 12, + ], + type: "TSModuleDeclaration", +} +`; + +snapshot[`Plugin - TSModuleDeclaration + TSModuleBlock 2`] = ` +{ + body: { + body: [ + { + body: { + body: [], + range: [ + 27, + 29, + ], + type: "TSModuleBlock", + }, + declare: false, + global: false, + id: { + name: "B", + optional: false, + range: [ + 25, + 26, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 15, + 29, + ], + type: "TSModuleDeclaration", + }, + ], + range: [ + 13, + 31, + ], + type: "TSModuleBlock", + }, + declare: false, + global: false, + id: { + name: "A", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 1, + 31, + ], + type: "TSModuleDeclaration", +} +`; + +snapshot[`Plugin - TSQualifiedName 1`] = ` +{ + left: { + name: "a", + optional: false, + range: [ + 10, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 10, + 13, + ], + right: { + name: "b", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + type: "TSQualifiedName", +} +`; + +snapshot[`Plugin - TSTypeLiteral 1`] = ` +{ + members: [ + { + computed: false, + key: { + name: "a", + optional: false, + range: [ + 12, + 13, + ], + type: "Identifier", + typeAnnotation: null, + }, + optional: false, + range: [ + 12, + 16, + ], + readonly: false, + static: false, + type: "TSPropertySignature", + typeAnnotation: { + range: [ + 13, + 16, + ], + type: "TSTypeAnnotation", + typeAnnotation: { + literal: { + range: [ + 15, + 16, + ], + raw: "1", + type: "Literal", + value: 1, + }, + range: [ + 15, + 16, + ], + type: "TSLiteralType", + }, + }, + }, + ], + range: [ + 10, + 18, + ], + type: "TSTypeLiteral", +} +`; + +snapshot[`Plugin - TSOptionalType 1`] = ` +{ + range: [ + 11, + 18, + ], + type: "TSOptionalType", + typeAnnotation: { + range: [ + 11, + 17, + ], + type: "TSNumberKeyword", + }, +} +`; + +snapshot[`Plugin - TSRestType 1`] = ` +{ + range: [ + 11, + 22, + ], + type: "TSRestType", + typeAnnotation: { + elementType: { + range: [ + 14, + 20, + ], + type: "TSNumberKeyword", + }, + range: [ + 14, + 22, + ], + type: "TSArrayType", + }, +} +`; + +snapshot[`Plugin - TSConditionalType 1`] = ` +{ + checkType: { + range: [ + 10, + 11, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "B", + optional: false, + range: [ + 10, + 11, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + extendsType: { + range: [ + 20, + 21, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "C", + optional: false, + range: [ + 20, + 21, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + falseType: { + range: [ + 33, + 39, + ], + type: "TSStringKeyword", + }, + range: [ + 10, + 39, + ], + trueType: { + range: [ + 24, + 30, + ], + type: "TSNumberKeyword", + }, + type: "TSConditionalType", +} +`; + +snapshot[`Plugin - TSInferType 1`] = ` +{ + range: [ + 29, + 39, + ], + type: "TSInferType", + typeParameter: { + const: false, + constraint: null, + default: null, + in: false, + name: { + name: "Item", + optional: false, + range: [ + 35, + 39, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 35, + 39, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSTypeOperator 1`] = ` +{ + operator: "keyof", + range: [ + 10, + 17, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 16, + 17, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "B", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, +} +`; + +snapshot[`Plugin - TSTypeOperator 2`] = ` +{ + operator: "unique", + range: [ + 21, + 34, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 28, + 34, + ], + type: "TSSymbolKeyword", + }, +} +`; + +snapshot[`Plugin - TSTypeOperator 3`] = ` +{ + operator: "readonly", + range: [ + 10, + 21, + ], + type: "TSTypeOperator", + typeAnnotation: { + elementTypes: [], + range: [ + 19, + 21, + ], + type: "TSTupleType", + }, +} +`; + +snapshot[`Plugin - TSMappedType 1`] = ` +{ + nameType: null, + optional: undefined, + range: [ + 13, + 41, + ], + readonly: undefined, + type: "TSMappedType", + typeAnnotation: { + range: [ + 31, + 38, + ], + type: "TSBooleanKeyword", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 21, + 28, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 27, + 28, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 27, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 16, + 28, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSMappedType 2`] = ` +{ + nameType: null, + optional: undefined, + range: [ + 13, + 45, + ], + readonly: true, + type: "TSMappedType", + typeAnnotation: { + elementTypes: [], + range: [ + 40, + 42, + ], + type: "TSTupleType", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 30, + 37, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 36, + 37, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 36, + 37, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 25, + 26, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 25, + 37, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSMappedType 3`] = ` +{ + nameType: null, + optional: undefined, + range: [ + 13, + 46, + ], + readonly: "-", + type: "TSMappedType", + typeAnnotation: { + elementTypes: [], + range: [ + 41, + 43, + ], + type: "TSTupleType", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 31, + 38, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 37, + 38, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 37, + 38, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 26, + 27, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 26, + 38, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSMappedType 4`] = ` +{ + nameType: null, + optional: undefined, + range: [ + 13, + 46, + ], + readonly: "+", + type: "TSMappedType", + typeAnnotation: { + elementTypes: [], + range: [ + 41, + 43, + ], + type: "TSTupleType", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 31, + 38, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 37, + 38, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 37, + 38, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 26, + 27, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 26, + 38, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSMappedType 5`] = ` +{ + nameType: null, + optional: true, + range: [ + 13, + 42, + ], + readonly: undefined, + type: "TSMappedType", + typeAnnotation: { + range: [ + 32, + 39, + ], + type: "TSBooleanKeyword", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 21, + 28, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 27, + 28, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 27, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 16, + 28, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSMappedType 6`] = ` +{ + nameType: null, + optional: "-", + range: [ + 13, + 43, + ], + readonly: undefined, + type: "TSMappedType", + typeAnnotation: { + range: [ + 33, + 40, + ], + type: "TSBooleanKeyword", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 21, + 28, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 27, + 28, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 27, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 16, + 28, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSMappedType 7`] = ` +{ + nameType: null, + optional: "+", + range: [ + 13, + 43, + ], + readonly: undefined, + type: "TSMappedType", + typeAnnotation: { + range: [ + 33, + 40, + ], + type: "TSBooleanKeyword", + }, + typeParameter: { + const: false, + constraint: { + operator: "keyof", + range: [ + 21, + 28, + ], + type: "TSTypeOperator", + typeAnnotation: { + range: [ + 27, + 28, + ], + type: "TSTypeReference", + typeArguments: null, + typeName: { + name: "T", + optional: false, + range: [ + 27, + 28, + ], + type: "Identifier", + typeAnnotation: null, + }, + }, + }, + default: null, + in: false, + name: { + name: "P", + optional: false, + range: [ + 16, + 17, + ], + type: "Identifier", + typeAnnotation: null, + }, + out: false, + range: [ + 16, + 28, + ], + type: "TSTypeParameter", + }, +} +`; + +snapshot[`Plugin - TSLiteralType 1`] = ` +{ + literal: { + range: [ + 10, + 14, + ], + raw: "true", + type: "Literal", + value: true, + }, + range: [ + 10, + 14, + ], + type: "TSLiteralType", +} +`; + +snapshot[`Plugin - TSLiteralType 2`] = ` +{ + literal: { + range: [ + 10, + 15, + ], + raw: "false", + type: "Literal", + value: false, + }, + range: [ + 10, + 15, + ], + type: "TSLiteralType", +} +`; + +snapshot[`Plugin - TSLiteralType 3`] = ` +{ + literal: { + range: [ + 10, + 11, + ], + raw: "1", + type: "Literal", + value: 1, + }, + range: [ + 10, + 11, + ], + type: "TSLiteralType", +} +`; + +snapshot[`Plugin - TSLiteralType 4`] = ` +{ + literal: { + range: [ + 10, + 15, + ], + raw: '"foo"', + type: "Literal", + value: "foo", + }, + range: [ + 10, + 15, + ], + type: "TSLiteralType", +} +`; + +snapshot[`Plugin - TSTemplateLiteralType 1`] = ` +{ + quasis: [ + { + cooked: "a ", + range: [ + 11, + 13, + ], + raw: "a ", + tail: false, + type: "TemplateElement", + }, + { + cooked: "", + range: [ + 22, + 22, + ], + raw: "", + tail: true, + type: "TemplateElement", + }, + ], + range: [ + 10, + 23, + ], + type: "TSTemplateLiteralType", + types: [ + { + range: [ + 15, + 21, + ], + type: "TSStringKeyword", + }, + ], +} +`; + +snapshot[`Plugin - TSTupleType + TSArrayType 1`] = ` +{ + elementTypes: [ + { + range: [ + 11, + 17, + ], + type: "TSNumberKeyword", + }, + ], + range: [ + 10, + 18, + ], + type: "TSTupleType", +} +`; + +snapshot[`Plugin - TSTupleType + TSArrayType 2`] = ` +{ + elementTypes: [ + { + elementType: { + range: [ + 14, + 20, + ], + type: "TSNumberKeyword", + }, + label: { + name: "x", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 11, + 20, + ], + type: "TSNamedTupleMember", + }, + ], + range: [ + 10, + 21, + ], + type: "TSTupleType", +} +`; + +snapshot[`Plugin - TSTupleType + TSArrayType 3`] = ` +{ + elementTypes: [ + { + elementType: { + range: [ + 14, + 20, + ], + type: "TSNumberKeyword", + }, + label: { + name: "x", + optional: false, + range: [ + 11, + 12, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 11, + 20, + ], + type: "TSNamedTupleMember", + }, + ], + range: [ + 10, + 21, + ], + type: "TSTupleType", +} +`; + +snapshot[`Plugin - TSTupleType + TSArrayType 4`] = ` +{ + elementTypes: [ + { + elementType: { + elementType: { + range: [ + 17, + 23, + ], + type: "TSNumberKeyword", + }, + range: [ + 17, + 25, + ], + type: "TSArrayType", + }, + label: { + argument: { + name: "x", + optional: false, + range: [ + 14, + 15, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 11, + 16, + ], + type: "RestElement", + typeAnnotation: null, + }, + range: [ + 11, + 25, + ], + type: "TSNamedTupleMember", + }, + ], + range: [ + 10, + 26, + ], + type: "TSTupleType", +} +`; + +snapshot[`Plugin - TSArrayType 1`] = ` +{ + elementType: { + range: [ + 10, + 16, + ], + type: "TSNumberKeyword", + }, + range: [ + 10, + 18, + ], + type: "TSArrayType", +} +`; + +snapshot[`Plugin - TSTypeQuery 1`] = ` +{ + exprName: { + name: "B", + optional: false, + range: [ + 17, + 18, + ], + type: "Identifier", + typeAnnotation: null, + }, + range: [ + 10, + 18, + ], + type: "TSTypeQuery", + typeArguments: null, +} +`; + +snapshot[`Plugin - TS keywords 1`] = ` +{ + range: [ + 10, + 13, + ], + type: "TSAnyKeyword", +} +`; + +snapshot[`Plugin - TS keywords 2`] = ` +{ + range: [ + 10, + 16, + ], + type: "TSBigIntKeyword", +} +`; + +snapshot[`Plugin - TS keywords 3`] = ` +{ + range: [ + 10, + 17, + ], + type: "TSBooleanKeyword", +} +`; + +snapshot[`Plugin - TS keywords 4`] = ` +{ + range: [ + 10, + 19, + ], + type: "TSIntrinsicKeyword", +} +`; + +snapshot[`Plugin - TS keywords 5`] = ` +{ + range: [ + 10, + 15, + ], + type: "TSNeverKeyword", +} +`; + +snapshot[`Plugin - TS keywords 6`] = ` +{ + range: [ + 10, + 14, + ], + type: "TSNullKeyword", +} +`; + +snapshot[`Plugin - TS keywords 7`] = ` +{ + range: [ + 10, + 16, + ], + type: "TSNumberKeyword", +} +`; + +snapshot[`Plugin - TS keywords 8`] = ` +{ + range: [ + 10, + 16, + ], + type: "TSObjectKeyword", +} +`; + +snapshot[`Plugin - TS keywords 9`] = ` +{ + range: [ + 10, + 16, + ], + type: "TSStringKeyword", +} +`; + +snapshot[`Plugin - TS keywords 10`] = ` +{ + range: [ + 10, + 16, + ], + type: "TSSymbolKeyword", +} +`; + +snapshot[`Plugin - TS keywords 11`] = ` +{ + range: [ + 10, + 19, + ], + type: "TSUndefinedKeyword", +} +`; + +snapshot[`Plugin - TS keywords 12`] = ` +{ + range: [ + 10, + 17, + ], + type: "TSUnknownKeyword", +} +`; + +snapshot[`Plugin - TS keywords 13`] = ` +{ + range: [ + 10, + 14, + ], + type: "TSVoidKeyword", +} +`; diff --git a/tests/unit/lint_plugin_test.ts b/tests/unit/lint_plugin_test.ts index 5b00f49d01..6c71501c46 100644 --- a/tests/unit/lint_plugin_test.ts +++ b/tests/unit/lint_plugin_test.ts @@ -1,6 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { assertEquals } from "./test_util.ts"; +import { assertSnapshot } from "@std/testing/snapshot"; // TODO(@marvinhagemeister) Remove once we land "official" types export interface LintReportData { @@ -85,9 +86,12 @@ function testVisit( return result; } -function testLintNode(source: string, ...selectors: string[]) { - // deno-lint-ignore no-explicit-any - const log: any[] = []; +async function testSnapshot( + t: Deno.TestContext, + source: string, + ...selectors: string[] +) { + const log: unknown[] = []; testPlugin(source, { create() { @@ -103,7 +107,8 @@ function testLintNode(source: string, ...selectors: string[]) { }, }); - return log; + assertEquals(log.length > 0, true); + await assertSnapshot(t, log[0]); } Deno.test("Plugin - visitor enter/exit", () => { @@ -313,303 +318,157 @@ Deno.test("Plugin - visitor :nth-child", () => { assertEquals(result[1].node.name, "foobar"); }); -Deno.test("Plugin - Program", () => { - const node = testLintNode("", "Program"); - assertEquals(node[0], { - type: "Program", - sourceType: "script", - range: [1, 1], - body: [], - }); +Deno.test("Plugin - Program", async (t) => { + await testSnapshot(t, "", "Program"); }); -Deno.test("Plugin - BlockStatement", () => { - const node = testLintNode("{ foo; }", "BlockStatement"); - assertEquals(node[0], { - type: "BlockStatement", - range: [1, 9], - body: [{ - type: "ExpressionStatement", - range: [3, 7], - expression: { - type: "Identifier", - name: "foo", - range: [3, 6], - }, - }], - }); +Deno.test("Plugin - ImportDeclaration", async (t) => { + await testSnapshot(t, 'import "foo";', "ImportDeclaration"); + await testSnapshot(t, 'import foo from "foo";', "ImportDeclaration"); + await testSnapshot(t, 'import * as foo from "foo";', "ImportDeclaration"); + await testSnapshot( + t, + 'import { foo, bar as baz } from "foo";', + "ImportDeclaration", + ); + await testSnapshot( + t, + 'import foo from "foo" with { type: "json" };', + "ImportDeclaration", + ); }); -Deno.test("Plugin - BreakStatement", () => { - let node = testLintNode("break;", "BreakStatement"); - assertEquals(node[0], { - type: "BreakStatement", - range: [1, 7], - label: null, - }); - - node = testLintNode("break foo;", "BreakStatement"); - assertEquals(node[0], { - type: "BreakStatement", - range: [1, 11], - label: { - type: "Identifier", - range: [7, 10], - name: "foo", - }, - }); +Deno.test("Plugin - ExportNamedDeclaration", async (t) => { + await testSnapshot(t, 'export { foo } from "foo";', "ExportNamedDeclaration"); + await testSnapshot( + t, + 'export { bar as baz } from "foo";', + "ExportNamedDeclaration", + ); + await testSnapshot( + t, + 'export { foo } from "foo" with { type: "json" };', + "ExportNamedDeclaration", + ); }); -Deno.test("Plugin - ContinueStatement", () => { - let node = testLintNode("continue;", "ContinueStatement"); - assertEquals(node[0], { - type: "ContinueStatement", - range: [1, 10], - label: null, - }); - - node = testLintNode("continue foo;", "ContinueStatement"); - assertEquals(node[0], { - type: "ContinueStatement", - range: [1, 14], - label: { - type: "Identifier", - range: [10, 13], - name: "foo", - }, - }); +Deno.test("Plugin - ExportDefaultDeclaration", async (t) => { + await testSnapshot( + t, + "export default function foo() {}", + "ExportDefaultDeclaration", + ); + await testSnapshot( + t, + "export default function () {}", + "ExportDefaultDeclaration", + ); + await testSnapshot( + t, + "export default class Foo {}", + "ExportDefaultDeclaration", + ); + await testSnapshot( + t, + "export default class {}", + "ExportDefaultDeclaration", + ); + await testSnapshot(t, "export default bar;", "ExportDefaultDeclaration"); + await testSnapshot( + t, + "export default interface Foo {};", + "ExportDefaultDeclaration", + ); }); -Deno.test("Plugin - DebuggerStatement", () => { - const node = testLintNode("debugger;", "DebuggerStatement"); - assertEquals(node[0], { - type: "DebuggerStatement", - range: [1, 10], - }); +Deno.test("Plugin - ExportAllDeclaration", async (t) => { + await testSnapshot(t, 'export * from "foo";', "ExportAllDeclaration"); + await testSnapshot(t, 'export * as foo from "foo";', "ExportAllDeclaration"); + await testSnapshot( + t, + 'export * from "foo" with { type: "json" };', + "ExportAllDeclaration", + ); }); -Deno.test("Plugin - DoWhileStatement", () => { - const node = testLintNode("do {} while (foo);", "DoWhileStatement"); - assertEquals(node[0], { - type: "DoWhileStatement", - range: [1, 19], - test: { - type: "Identifier", - range: [14, 17], - name: "foo", - }, - body: { - type: "BlockStatement", - range: [4, 6], - body: [], - }, - }); +Deno.test("Plugin - TSExportAssignment", async (t) => { + await testSnapshot(t, "export = foo;", "TSExportAssignment"); }); -Deno.test("Plugin - ExpressionStatement", () => { - const node = testLintNode("foo;", "ExpressionStatement"); - assertEquals(node[0], { - type: "ExpressionStatement", - range: [1, 5], - expression: { - type: "Identifier", - range: [1, 4], - name: "foo", - }, - }); +Deno.test("Plugin - TSNamespaceExportDeclaration", async (t) => { + await testSnapshot( + t, + "export as namespace A;", + "TSNamespaceExportDeclaration", + ); }); -Deno.test("Plugin - ForInStatement", () => { - const node = testLintNode("for (a in b) {}", "ForInStatement"); - assertEquals(node[0], { - type: "ForInStatement", - range: [1, 16], - left: { - type: "Identifier", - range: [6, 7], - name: "a", - }, - right: { - type: "Identifier", - range: [11, 12], - name: "b", - }, - body: { - type: "BlockStatement", - range: [14, 16], - body: [], - }, - }); +Deno.test("Plugin - TSImportEqualsDeclaration", async (t) => { + await testSnapshot(t, "import a = b", "TSImportEqualsDeclaration"); + await testSnapshot( + t, + 'import a = require("foo")', + "TSImportEqualsDeclaration", + ); }); -Deno.test("Plugin - ForOfStatement", () => { - let node = testLintNode("for (a of b) {}", "ForOfStatement"); - assertEquals(node[0], { - type: "ForOfStatement", - range: [1, 16], - await: false, - left: { - type: "Identifier", - range: [6, 7], - name: "a", - }, - right: { - type: "Identifier", - range: [11, 12], - name: "b", - }, - body: { - type: "BlockStatement", - range: [14, 16], - body: [], - }, - }); - - node = testLintNode("for await (a of b) {}", "ForOfStatement"); - assertEquals(node[0], { - type: "ForOfStatement", - range: [1, 22], - await: true, - left: { - type: "Identifier", - range: [12, 13], - name: "a", - }, - right: { - type: "Identifier", - range: [17, 18], - name: "b", - }, - body: { - type: "BlockStatement", - range: [20, 22], - body: [], - }, - }); +Deno.test("Plugin - BlockStatement", async (t) => { + await testSnapshot(t, "{ foo; }", "BlockStatement"); }); -Deno.test("Plugin - ForStatement", () => { - let node = testLintNode("for (;;) {}", "ForStatement"); - assertEquals(node[0], { - type: "ForStatement", - range: [1, 12], - init: null, - test: null, - update: null, - body: { - type: "BlockStatement", - range: [10, 12], - body: [], - }, - }); - - node = testLintNode("for (a; b; c) {}", "ForStatement"); - assertEquals(node[0], { - type: "ForStatement", - range: [1, 17], - init: { - type: "Identifier", - range: [6, 7], - name: "a", - }, - test: { - type: "Identifier", - range: [9, 10], - name: "b", - }, - update: { - type: "Identifier", - range: [12, 13], - name: "c", - }, - body: { - type: "BlockStatement", - range: [15, 17], - body: [], - }, - }); +Deno.test("Plugin - BreakStatement", async (t) => { + await testSnapshot(t, "while (false) break;", "BreakStatement"); + await testSnapshot(t, "foo: while (false) break foo;", "BreakStatement"); }); -Deno.test("Plugin - IfStatement", () => { - let node = testLintNode("if (foo) {}", "IfStatement"); - assertEquals(node[0], { - type: "IfStatement", - range: [1, 12], - test: { - type: "Identifier", - name: "foo", - range: [5, 8], - }, - consequent: { - type: "BlockStatement", - range: [10, 12], - body: [], - }, - alternate: null, - }); - - node = testLintNode("if (foo) {} else {}", "IfStatement"); - assertEquals(node[0], { - type: "IfStatement", - range: [1, 20], - test: { - type: "Identifier", - name: "foo", - range: [5, 8], - }, - consequent: { - type: "BlockStatement", - range: [10, 12], - body: [], - }, - alternate: { - type: "BlockStatement", - range: [18, 20], - body: [], - }, - }); +Deno.test("Plugin - ContinueStatement", async (t) => { + await testSnapshot(t, "continue;", "ContinueStatement"); + await testSnapshot(t, "continue foo;", "ContinueStatement"); }); -Deno.test("Plugin - LabeledStatement", () => { - const node = testLintNode("foo: {};", "LabeledStatement"); - assertEquals(node[0], { - type: "LabeledStatement", - range: [1, 8], - label: { - type: "Identifier", - name: "foo", - range: [1, 4], - }, - body: { - type: "BlockStatement", - range: [6, 8], - body: [], - }, - }); +Deno.test("Plugin - DebuggerStatement", async (t) => { + await testSnapshot(t, "debugger;", "DebuggerStatement"); }); -Deno.test("Plugin - ReturnStatement", () => { - let node = testLintNode("return", "ReturnStatement"); - assertEquals(node[0], { - type: "ReturnStatement", - range: [1, 7], - argument: null, - }); - - node = testLintNode("return foo;", "ReturnStatement"); - assertEquals(node[0], { - type: "ReturnStatement", - range: [1, 12], - argument: { - type: "Identifier", - name: "foo", - range: [8, 11], - }, - }); +Deno.test("Plugin - DoWhileStatement", async (t) => { + await testSnapshot(t, "do {} while (foo);", "DoWhileStatement"); }); -Deno.test("Plugin - SwitchStatement", () => { - const node = testLintNode( +Deno.test("Plugin - ExpressionStatement", async (t) => { + await testSnapshot(t, "foo;", "ExpressionStatement"); +}); + +Deno.test("Plugin - ForInStatement", async (t) => { + await testSnapshot(t, "for (a in b) {}", "ForInStatement"); +}); + +Deno.test("Plugin - ForOfStatement", async (t) => { + await testSnapshot(t, "for (a of b) {}", "ForOfStatement"); + await testSnapshot(t, "for await (a of b) {}", "ForOfStatement"); +}); + +Deno.test("Plugin - ForStatement", async (t) => { + await testSnapshot(t, "for (;;) {}", "ForStatement"); + await testSnapshot(t, "for (a; b; c) {}", "ForStatement"); +}); + +Deno.test("Plugin - IfStatement", async (t) => { + await testSnapshot(t, "if (foo) {}", "IfStatement"); + await testSnapshot(t, "if (foo) {} else {}", "IfStatement"); +}); + +Deno.test("Plugin - LabeledStatement", async (t) => { + await testSnapshot(t, "foo: {};", "LabeledStatement"); +}); + +Deno.test("Plugin - ReturnStatement", async (t) => { + await testSnapshot(t, "return", "ReturnStatement"); + await testSnapshot(t, "return foo;", "ReturnStatement"); +}); + +Deno.test("Plugin - SwitchStatement", async (t) => { + await testSnapshot( + t, `switch (foo) { case foo: case bar: @@ -619,151 +478,449 @@ Deno.test("Plugin - SwitchStatement", () => { }`, "SwitchStatement", ); - assertEquals(node[0], { - type: "SwitchStatement", - range: [1, 94], - discriminant: { - type: "Identifier", - range: [9, 12], - name: "foo", - }, - cases: [ - { - type: "SwitchCase", - range: [22, 31], - test: { - type: "Identifier", - range: [27, 30], - name: "foo", - }, - consequent: [], - }, - { - type: "SwitchCase", - range: [38, 62], - test: { - type: "Identifier", - range: [43, 46], - name: "bar", - }, - consequent: [ - { - type: "BreakStatement", - label: null, - range: [56, 62], - }, - ], - }, - { - type: "SwitchCase", - range: [69, 88], - test: null, - consequent: [ - { - type: "BlockStatement", - range: [86, 88], - body: [], - }, - ], - }, - ], - }); }); -Deno.test("Plugin - ThrowStatement", () => { - const node = testLintNode("throw foo;", "ThrowStatement"); - assertEquals(node[0], { - type: "ThrowStatement", - range: [1, 11], - argument: { - type: "Identifier", - range: [7, 10], - name: "foo", - }, - }); +Deno.test("Plugin - ThrowStatement", async (t) => { + await testSnapshot(t, "throw foo;", "ThrowStatement"); }); -Deno.test("Plugin - TryStatement", () => { - let node = testLintNode("try {} catch {};", "TryStatement"); - assertEquals(node[0], { - type: "TryStatement", - range: [1, 16], - block: { - type: "BlockStatement", - range: [5, 7], - body: [], - }, - handler: { - type: "CatchClause", - range: [8, 16], - param: null, - body: { - type: "BlockStatement", - range: [14, 16], - body: [], - }, - }, - finalizer: null, - }); - - node = testLintNode("try {} catch (e) {};", "TryStatement"); - assertEquals(node[0], { - type: "TryStatement", - range: [1, 20], - block: { - type: "BlockStatement", - range: [5, 7], - body: [], - }, - handler: { - type: "CatchClause", - range: [8, 20], - param: { - type: "Identifier", - range: [15, 16], - name: "e", - }, - body: { - type: "BlockStatement", - range: [18, 20], - body: [], - }, - }, - finalizer: null, - }); - - node = testLintNode("try {} finally {};", "TryStatement"); - assertEquals(node[0], { - type: "TryStatement", - range: [1, 18], - block: { - type: "BlockStatement", - range: [5, 7], - body: [], - }, - handler: null, - finalizer: { - type: "BlockStatement", - range: [16, 18], - body: [], - }, - }); +Deno.test("Plugin - TryStatement", async (t) => { + await testSnapshot(t, "try {} catch {};", "TryStatement"); + await testSnapshot(t, "try {} catch (e) {};", "TryStatement"); + await testSnapshot(t, "try {} finally {};", "TryStatement"); }); -Deno.test("Plugin - WhileStatement", () => { - const node = testLintNode("while (foo) {}", "WhileStatement"); - assertEquals(node[0], { - type: "WhileStatement", - range: [1, 15], - test: { - type: "Identifier", - range: [8, 11], - name: "foo", - }, - body: { - type: "BlockStatement", - range: [13, 15], - body: [], - }, - }); +Deno.test("Plugin - WhileStatement", async (t) => { + await testSnapshot(t, "while (foo) {}", "WhileStatement"); +}); + +Deno.test("Plugin - WithStatement", async (t) => { + await testSnapshot(t, "with ([]) {}", "WithStatement"); +}); + +Deno.test("Plugin - ArrayExpression", async (t) => { + await testSnapshot(t, "[[],,[]]", "ArrayExpression"); +}); + +Deno.test("Plugin - ArrowFunctionExpression", async (t) => { + await testSnapshot(t, "() => {}", "ArrowFunctionExpression"); + await testSnapshot(t, "async () => {}", "ArrowFunctionExpression"); + await testSnapshot( + t, + "(a: number, ...b: any[]): any => {}", + "ArrowFunctionExpression", + ); +}); + +Deno.test("Plugin - AssignmentExpression", async (t) => { + await testSnapshot(t, "a = b", "AssignmentExpression"); + await testSnapshot(t, "a = a ??= b", "AssignmentExpression"); +}); + +Deno.test("Plugin - AwaitExpression", async (t) => { + await testSnapshot(t, "await foo;", "AwaitExpression"); +}); + +Deno.test("Plugin - BinaryExpression", async (t) => { + await testSnapshot(t, "a > b", "BinaryExpression"); + await testSnapshot(t, "a >= b", "BinaryExpression"); + await testSnapshot(t, "a < b", "BinaryExpression"); + await testSnapshot(t, "a <= b", "BinaryExpression"); + await testSnapshot(t, "a == b", "BinaryExpression"); + await testSnapshot(t, "a === b", "BinaryExpression"); + await testSnapshot(t, "a != b", "BinaryExpression"); + await testSnapshot(t, "a !== b", "BinaryExpression"); + await testSnapshot(t, "a << b", "BinaryExpression"); + await testSnapshot(t, "a >> b", "BinaryExpression"); + await testSnapshot(t, "a >>> b", "BinaryExpression"); + await testSnapshot(t, "a + b", "BinaryExpression"); + await testSnapshot(t, "a - b", "BinaryExpression"); + await testSnapshot(t, "a * b", "BinaryExpression"); + await testSnapshot(t, "a / b", "BinaryExpression"); + await testSnapshot(t, "a % b", "BinaryExpression"); + await testSnapshot(t, "a | b", "BinaryExpression"); + await testSnapshot(t, "a ^ b", "BinaryExpression"); + await testSnapshot(t, "a & b", "BinaryExpression"); + await testSnapshot(t, "a in b", "BinaryExpression"); + await testSnapshot(t, "a ** b", "BinaryExpression"); +}); + +Deno.test("Plugin - CallExpression", async (t) => { + await testSnapshot(t, "foo();", "CallExpression"); + await testSnapshot(t, "foo(a, ...b);", "CallExpression"); + await testSnapshot(t, "foo?.();", "CallExpression"); + await testSnapshot(t, "foo();", "CallExpression"); +}); + +Deno.test("Plugin - ChainExpression", async (t) => { + await testSnapshot(t, "a?.b", "ChainExpression"); +}); + +Deno.test("Plugin - ClassExpression", async (t) => { + await testSnapshot(t, "a = class {}", "ClassExpression"); + await testSnapshot(t, "a = class Foo {}", "ClassExpression"); + await testSnapshot(t, "a = class Foo extends Bar {}", "ClassExpression"); + await testSnapshot( + t, + "a = class Foo extends Bar implements Baz, Baz2 {}", + "ClassExpression", + ); + await testSnapshot(t, "a = class Foo {}", "ClassExpression"); + await testSnapshot(t, "a = class { foo() {} }", "ClassExpression"); + await testSnapshot(t, "a = class { #foo() {} }", "ClassExpression"); + await testSnapshot(t, "a = class { foo: number }", "ClassExpression"); + await testSnapshot(t, "a = class { foo = bar }", "ClassExpression"); + await testSnapshot( + t, + "a = class { constructor(public foo: string) {} }", + "ClassExpression", + ); + await testSnapshot(t, "a = class { #foo: number = bar }", "ClassExpression"); + await testSnapshot(t, "a = class { static foo = bar }", "ClassExpression"); + await testSnapshot( + t, + "a = class { static foo; static { foo = bar } }", + "ClassExpression", + ); +}); + +Deno.test("Plugin - ConditionalExpression", async (t) => { + await testSnapshot(t, "a ? b : c", "ConditionalExpression"); +}); + +Deno.test("Plugin - FunctionExpression", async (t) => { + await testSnapshot(t, "a = function () {}", "FunctionExpression"); + await testSnapshot(t, "a = function foo() {}", "FunctionExpression"); + await testSnapshot( + t, + "a = function (a?: number, ...b: any[]): any {}", + "FunctionExpression", + ); + await testSnapshot(t, "a = async function* () {}", "FunctionExpression"); +}); + +Deno.test("Plugin - Identifier", async (t) => { + await testSnapshot(t, "a", "Identifier"); +}); + +Deno.test("Plugin - ImportExpression", async (t) => { + await testSnapshot( + t, + "import('foo', { with: { type: 'json' } })", + "ImportExpression", + ); +}); + +Deno.test("Plugin - LogicalExpression", async (t) => { + await testSnapshot(t, "a && b", "LogicalExpression"); + await testSnapshot(t, "a || b", "LogicalExpression"); + await testSnapshot(t, "a ?? b", "LogicalExpression"); +}); + +Deno.test("Plugin - MemberExpression", async (t) => { + await testSnapshot(t, "a.b", "MemberExpression"); + await testSnapshot(t, "a['b']", "MemberExpression"); +}); + +Deno.test("Plugin - MetaProperty", async (t) => { + await testSnapshot(t, "import.meta", "MetaProperty"); +}); + +Deno.test("Plugin - NewExpression", async (t) => { + await testSnapshot(t, "new Foo()", "NewExpression"); + await testSnapshot(t, "new Foo(a, ...b)", "NewExpression"); +}); + +Deno.test("Plugin - ObjectExpression", async (t) => { + await testSnapshot(t, "a = {}", "ObjectExpression"); + await testSnapshot(t, "a = { a }", "ObjectExpression"); + await testSnapshot(t, "a = { b: c, [c]: d }", "ObjectExpression"); +}); + +Deno.test("Plugin - PrivateIdentifier", async (t) => { + await testSnapshot(t, "class Foo { #foo = foo }", "PrivateIdentifier"); +}); + +Deno.test("Plugin - SequenceExpression", async (t) => { + await testSnapshot(t, "(a, b)", "SequenceExpression"); +}); + +Deno.test("Plugin - Super", async (t) => { + await testSnapshot( + t, + "class Foo extends Bar { constructor() { super(); } }", + "Super", + ); +}); + +Deno.test("Plugin - TaggedTemplateExpression", async (t) => { + await testSnapshot(t, "foo`foo ${bar} baz`", "TaggedTemplateExpression"); +}); + +Deno.test("Plugin - TemplateLiteral", async (t) => { + await testSnapshot(t, "`foo ${bar} baz`", "TemplateLiteral"); +}); + +Deno.test("Plugin - ThisExpression", async (t) => { + await testSnapshot(t, "this", "ThisExpression"); +}); + +Deno.test("Plugin - TSAsExpression", async (t) => { + await testSnapshot(t, "a as b", "TSAsExpression"); + await testSnapshot(t, "a as const", "TSAsExpression"); +}); + +Deno.test("Plugin - TSNonNullExpression", async (t) => { + await testSnapshot(t, "a!", "TSNonNullExpression"); +}); + +Deno.test("Plugin - TSSatisfiesExpression", async (t) => { + await testSnapshot(t, "a satisfies b", "TSSatisfiesExpression"); +}); + +Deno.test("Plugin - UnaryExpression", async (t) => { + await testSnapshot(t, "typeof a", "UnaryExpression"); + await testSnapshot(t, "void 0", "UnaryExpression"); + await testSnapshot(t, "-a", "UnaryExpression"); + await testSnapshot(t, "+a", "UnaryExpression"); +}); + +Deno.test("Plugin - UpdateExpression", async (t) => { + await testSnapshot(t, "a++", "UpdateExpression"); + await testSnapshot(t, "++a", "UpdateExpression"); + await testSnapshot(t, "a--", "UpdateExpression"); + await testSnapshot(t, "--a", "UpdateExpression"); +}); + +Deno.test("Plugin - YieldExpression", async (t) => { + await testSnapshot(t, "function* foo() { yield bar; }", "YieldExpression"); +}); + +Deno.test("Plugin - Literal", async (t) => { + await testSnapshot(t, "1", "Literal"); + await testSnapshot(t, "'foo'", "Literal"); + await testSnapshot(t, '"foo"', "Literal"); + await testSnapshot(t, "true", "Literal"); + await testSnapshot(t, "false", "Literal"); + await testSnapshot(t, "null", "Literal"); + await testSnapshot(t, "1n", "Literal"); + await testSnapshot(t, "/foo/g", "Literal"); +}); + +Deno.test("Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr", async (t) => { + await testSnapshot(t, "

", "JSXElement"); + await testSnapshot(t, "
", "JSXElement"); + await testSnapshot(t, "
", "JSXElement"); + await testSnapshot(t, '
', "JSXElement"); + await testSnapshot(t, "
", "JSXElement"); + await testSnapshot(t, "
foo{2}
", "JSXElement"); + await testSnapshot(t, "", "JSXElement"); + await testSnapshot(t, "
", "JSXElement"); + await testSnapshot(t, "", "JSXElement"); + await testSnapshot(t, " />", "JSXElement"); +}); + +Deno.test("Plugin - JSXFragment + JSXOpeningFragment + JSXClosingFragment", async (t) => { + await testSnapshot(t, "<>", "JSXFragment"); + await testSnapshot(t, "<>foo{2}", "JSXFragment"); +}); + +Deno.test("Plugin - TSAsExpression", async (t) => { + await testSnapshot(t, "a as any", "TSAsExpression"); + await testSnapshot(t, '"foo" as const', "TSAsExpression"); +}); + +Deno.test("Plugin - TSEnumDeclaration", async (t) => { + await testSnapshot(t, "enum Foo {}", "TSEnumDeclaration"); + await testSnapshot(t, "const enum Foo {}", "TSEnumDeclaration"); + await testSnapshot(t, "enum Foo { A, B }", "TSEnumDeclaration"); + await testSnapshot(t, 'enum Foo { "a-b" }', "TSEnumDeclaration"); + await testSnapshot( + t, + "enum Foo { A = 1, B = 2, C = A | B }", + "TSEnumDeclaration", + ); +}); + +Deno.test("Plugin - TSInterface", async (t) => { + await testSnapshot(t, "interface A {}", "TSInterface"); + await testSnapshot(t, "interface A {}", "TSInterface"); + await testSnapshot(t, "interface A extends Foo, Bar {}", "TSInterface"); + await testSnapshot(t, "interface A { foo: any, bar?: any }", "TSInterface"); + await testSnapshot( + t, + "interface A { readonly [key: string]: any }", + "TSInterface", + ); + + await testSnapshot(t, "interface A { readonly a: any }", "TSInterface"); + await testSnapshot(t, "interface A { (a: T): T }", "TSInterface"); + await testSnapshot(t, "interface A { new (a: T): T }", "TSInterface"); + await testSnapshot(t, "interface A { a: new (a: T) => T }", "TSInterface"); + await testSnapshot(t, "interface A { get a(): string }", "TSInterface"); + await testSnapshot(t, "interface A { set a(v: string) }", "TSInterface"); + + await testSnapshot( + t, + "interface A { a(arg?: any, ...args: any[]): any }", + "TSInterface", + ); +}); + +Deno.test("Plugin - TSSatisfiesExpression", async (t) => { + await testSnapshot(t, "const a = {} satisfies A", "TSSatisfiesExpression"); +}); + +Deno.test("Plugin - TSTypeAliasDeclaration", async (t) => { + await testSnapshot(t, "type A = any", "TSTypeAliasDeclaration"); + await testSnapshot(t, "type A = any", "TSTypeAliasDeclaration"); + await testSnapshot(t, "declare type A = any", "TSTypeAliasDeclaration"); +}); + +Deno.test("Plugin - TSNonNullExpression", async (t) => { + await testSnapshot(t, "a!", "TSNonNullExpression"); +}); + +Deno.test("Plugin - TSUnionType", async (t) => { + await testSnapshot(t, "type A = B | C", "TSUnionType"); +}); + +Deno.test("Plugin - TSIntersectionType", async (t) => { + await testSnapshot(t, "type A = B & C", "TSIntersectionType"); +}); + +Deno.test("Plugin - TSModuleDeclaration", async (t) => { + await testSnapshot(t, "module A {}", "TSModuleDeclaration"); + await testSnapshot( + t, + "declare module A { export function A(): void }", + "TSModuleDeclaration", + ); +}); + +Deno.test("Plugin - TSModuleDeclaration + TSModuleBlock", async (t) => { + await testSnapshot(t, "module A {}", "TSModuleDeclaration"); + await testSnapshot( + t, + "namespace A { namespace B {} }", + "TSModuleDeclaration", + ); +}); + +Deno.test("Plugin - TSQualifiedName", async (t) => { + await testSnapshot(t, "type A = a.b;", "TSQualifiedName"); +}); + +Deno.test("Plugin - TSTypeLiteral", async (t) => { + await testSnapshot(t, "type A = { a: 1 };", "TSTypeLiteral"); +}); + +Deno.test("Plugin - TSOptionalType", async (t) => { + await testSnapshot(t, "type A = [number?]", "TSOptionalType"); +}); + +Deno.test("Plugin - TSRestType", async (t) => { + await testSnapshot(t, "type A = [...number[]]", "TSRestType"); +}); + +Deno.test("Plugin - TSConditionalType", async (t) => { + await testSnapshot( + t, + "type A = B extends C ? number : string;", + "TSConditionalType", + ); +}); + +Deno.test("Plugin - TSInferType", async (t) => { + await testSnapshot( + t, + "type A = T extends Array ? Item : T;", + "TSInferType", + ); +}); + +Deno.test("Plugin - TSTypeOperator", async (t) => { + await testSnapshot(t, "type A = keyof B", "TSTypeOperator"); + await testSnapshot(t, "declare const sym1: unique symbol;", "TSTypeOperator"); + await testSnapshot(t, "type A = readonly []", "TSTypeOperator"); +}); + +Deno.test("Plugin - TSMappedType", async (t) => { + await testSnapshot( + t, + "type A = { [P in keyof T]: boolean; };", + "TSMappedType", + ); + await testSnapshot( + t, + "type A = { readonly [P in keyof T]: []; };", + "TSMappedType", + ); + await testSnapshot( + t, + "type A = { -readonly [P in keyof T]: []; };", + "TSMappedType", + ); + await testSnapshot( + t, + "type A = { +readonly [P in keyof T]: []; };", + "TSMappedType", + ); + await testSnapshot( + t, + "type A = { [P in keyof T]?: boolean; };", + "TSMappedType", + ); + await testSnapshot( + t, + "type A = { [P in keyof T]-?: boolean; };", + "TSMappedType", + ); + await testSnapshot( + t, + "type A = { [P in keyof T]+?: boolean; };", + "TSMappedType", + ); +}); + +Deno.test("Plugin - TSLiteralType", async (t) => { + await testSnapshot(t, "type A = true", "TSLiteralType"); + await testSnapshot(t, "type A = false", "TSLiteralType"); + await testSnapshot(t, "type A = 1", "TSLiteralType"); + await testSnapshot(t, 'type A = "foo"', "TSLiteralType"); +}); + +Deno.test("Plugin - TSTemplateLiteralType", async (t) => { + await testSnapshot(t, "type A = `a ${string}`", "TSTemplateLiteralType"); +}); + +Deno.test("Plugin - TSTupleType + TSArrayType", async (t) => { + await testSnapshot(t, "type A = [number]", "TSTupleType"); + await testSnapshot(t, "type A = [x: number]", "TSTupleType"); + await testSnapshot(t, "type A = [x: number]", "TSTupleType"); + await testSnapshot(t, "type A = [...x: number[]]", "TSTupleType"); +}); + +Deno.test("Plugin - TSArrayType", async (t) => { + await testSnapshot(t, "type A = number[]", "TSArrayType"); +}); + +Deno.test("Plugin - TSTypeQuery", async (t) => { + await testSnapshot(t, "type A = typeof B", "TSTypeQuery"); +}); + +Deno.test("Plugin - TS keywords", async (t) => { + await testSnapshot(t, "type A = any", "TSAnyKeyword"); + await testSnapshot(t, "type A = bigint", "TSBigIntKeyword"); + await testSnapshot(t, "type A = boolean", "TSBooleanKeyword"); + await testSnapshot(t, "type A = intrinsic", "TSIntrinsicKeyword"); + await testSnapshot(t, "type A = never", "TSNeverKeyword"); + await testSnapshot(t, "type A = null", "TSNullKeyword"); + await testSnapshot(t, "type A = number", "TSNumberKeyword"); + await testSnapshot(t, "type A = object", "TSObjectKeyword"); + await testSnapshot(t, "type A = string", "TSStringKeyword"); + await testSnapshot(t, "type A = symbol", "TSSymbolKeyword"); + await testSnapshot(t, "type A = undefined", "TSUndefinedKeyword"); + await testSnapshot(t, "type A = unknown", "TSUnknownKeyword"); + await testSnapshot(t, "type A = void", "TSVoidKeyword"); }); From 0b033140c07b5abee231711b0fbc3fa24f5f9eec Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 14 Jan 2025 10:01:05 -0500 Subject: [PATCH 16/38] refactor: move `CliNpmResolver` to `deno_resolver::npm::NpmResolver` (#27659) As title. After this PR all npm resolution will be out of the CLI crate. --- Cargo.lock | 1 + cli/cache/mod.rs | 5 +- cli/emit.rs | 6 +- cli/factory.rs | 41 ++-- cli/graph_util.rs | 21 +- cli/lsp/analysis.rs | 26 ++- cli/lsp/resolver.rs | 135 +++++++---- cli/module_loader.rs | 19 +- cli/node.rs | 16 +- cli/npm/byonm.rs | 64 +---- cli/npm/managed.rs | 285 +---------------------- cli/npm/mod.rs | 91 ++------ cli/resolver.rs | 22 +- cli/standalone/binary.rs | 45 ++-- cli/standalone/mod.rs | 30 +-- cli/task_runner.rs | 18 +- cli/tools/check.rs | 29 ++- cli/tools/coverage/mod.rs | 5 +- cli/tools/info.rs | 50 ++-- cli/tools/registry/pm/deps.rs | 18 +- cli/tools/task.rs | 4 +- cli/tsc/mod.rs | 8 +- cli/worker.rs | 16 +- ext/node/lib.rs | 42 ++-- ext/node/ops/require.rs | 51 +++- resolvers/deno/cjs.rs | 25 +- resolvers/deno/lib.rs | 60 ++++- resolvers/deno/npm/byonm.rs | 17 +- resolvers/deno/npm/managed/common.rs | 73 ++++-- resolvers/deno/npm/managed/global.rs | 48 ++-- resolvers/deno/npm/managed/local.rs | 119 +++++----- resolvers/deno/npm/managed/mod.rs | 97 +++++--- resolvers/deno/npm/managed/resolution.rs | 21 +- resolvers/deno/npm/mod.rs | 197 +++++++++++++--- resolvers/node/analyze.rs | 39 +++- resolvers/node/lib.rs | 2 - resolvers/node/npm.rs | 15 +- resolvers/node/resolution.rs | 50 +++- resolvers/node/sync.rs | 7 - runtime/Cargo.toml | 1 + runtime/examples/extension/main.rs | 8 +- runtime/snapshot.rs | 4 + runtime/web_worker.rs | 50 +++- runtime/worker.rs | 50 +++- 44 files changed, 1030 insertions(+), 901 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa13ae0ccd..95633e3ce9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2242,6 +2242,7 @@ dependencies = [ "deno_node", "deno_path_util", "deno_permissions", + "deno_resolver", "deno_telemetry", "deno_terminal 0.2.0", "deno_tls", diff --git a/cli/cache/mod.rs b/cli/cache/mod.rs index ff9f07fc4e..0d7808cba6 100644 --- a/cli/cache/mod.rs +++ b/cli/cache/mod.rs @@ -15,6 +15,7 @@ use deno_graph::source::CacheInfo; use deno_graph::source::LoadFuture; use deno_graph::source::LoadResponse; use deno_graph::source::Loader; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::deno_permissions::PermissionsContainer; use node_resolver::InNpmPackageChecker; @@ -76,7 +77,7 @@ pub struct FetchCacher { pub file_header_overrides: HashMap>, file_fetcher: Arc, global_http_cache: Arc, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, module_info_cache: Arc, permissions: PermissionsContainer, sys: CliSys, @@ -88,7 +89,7 @@ impl FetchCacher { pub fn new( file_fetcher: Arc, global_http_cache: Arc, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, module_info_cache: Arc, sys: CliSys, options: FetchCacherOptions, diff --git a/cli/emit.rs b/cli/emit.rs index e9b5a4e250..69ac8323bb 100644 --- a/cli/emit.rs +++ b/cli/emit.rs @@ -24,11 +24,11 @@ use deno_graph::ModuleGraph; use crate::cache::EmitCache; use crate::cache::FastInsecureHasher; use crate::cache::ParsedSourceCache; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; #[derive(Debug)] pub struct Emitter { - cjs_tracker: Arc, + cjs_tracker: Arc, emit_cache: Arc, parsed_source_cache: Arc, transpile_and_emit_options: @@ -39,7 +39,7 @@ pub struct Emitter { impl Emitter { pub fn new( - cjs_tracker: Arc, + cjs_tracker: Arc, emit_cache: Arc, parsed_source_cache: Arc, transpile_options: deno_ast::TranspileOptions, diff --git a/cli/factory.rs b/cli/factory.rs index e3873b5164..3280fd379b 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -16,6 +16,7 @@ use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; use deno_resolver::npm::managed::NpmResolutionCell; use deno_resolver::npm::CreateInNpmPkgCheckerOptions; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::npm::NpmReqResolverOptions; use deno_resolver::sloppy_imports::SloppyImportsCachedFs; use deno_resolver::DenoResolverOptions; @@ -32,7 +33,6 @@ use deno_runtime::inspector_server::InspectorServer; use deno_runtime::permissions::RuntimePermissionDescriptorParser; use log::warn; use node_resolver::analyze::NodeCodeTranslator; -use node_resolver::InNpmPackageChecker; use once_cell::sync::OnceCell; use crate::args::check_warn_tsconfig; @@ -68,7 +68,6 @@ use crate::node::CliCjsCodeAnalyzer; use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; -use crate::npm::create_cli_npm_resolver; use crate::npm::installer::NpmInstaller; use crate::npm::installer::NpmResolutionInstaller; use crate::npm::CliByonmNpmResolverCreateOptions; @@ -83,7 +82,7 @@ use crate::npm::CliNpmTarballCache; use crate::npm::NpmRegistryReadPermissionChecker; use crate::npm::NpmRegistryReadPermissionCheckerMode; use crate::npm::NpmResolutionInitializer; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; use crate::resolver::CliDenoResolver; use crate::resolver::CliNpmGraphResolver; use crate::resolver::CliNpmReqResolver; @@ -190,7 +189,7 @@ impl Deferred { struct CliFactoryServices { blob_store: Deferred>, caches: Deferred>, - cjs_tracker: Deferred>, + cjs_tracker: Deferred>, cli_options: Deferred>, code_cache: Deferred>, deno_resolver: Deferred>, @@ -203,7 +202,7 @@ struct CliFactoryServices { global_http_cache: Deferred>, http_cache: Deferred>, http_client_provider: Deferred>, - in_npm_pkg_checker: Deferred>, + in_npm_pkg_checker: Deferred, main_graph_container: Deferred>, maybe_file_watcher_reporter: Deferred>, maybe_inspector_server: Deferred>>, @@ -223,7 +222,7 @@ struct CliFactoryServices { npm_resolution: Arc, npm_resolution_initializer: Deferred>, npm_resolution_installer: Deferred>, - npm_resolver: Deferred>, + npm_resolver: Deferred, npm_tarball_cache: Deferred>, parsed_source_cache: Deferred>, permission_desc_parser: @@ -399,7 +398,7 @@ impl CliFactory { pub fn in_npm_pkg_checker( &self, - ) -> Result<&Arc, AnyError> { + ) -> Result<&DenoInNpmPackageChecker, AnyError> { self.services.in_npm_pkg_checker.get_or_try_init(|| { let cli_options = self.cli_options()?; let options = if cli_options.use_byonm() { @@ -414,7 +413,7 @@ impl CliFactory { }, ) }; - Ok(deno_resolver::npm::create_in_npm_pkg_checker(options)) + Ok(DenoInNpmPackageChecker::new(options)) }) } @@ -559,16 +558,14 @@ impl CliFactory { }) } - pub async fn npm_resolver( - &self, - ) -> Result<&Arc, AnyError> { + pub async fn npm_resolver(&self) -> Result<&CliNpmResolver, AnyError> { self .services .npm_resolver .get_or_try_init_async( async { let cli_options = self.cli_options()?; - Ok(create_cli_npm_resolver(if cli_options.use_byonm() { + Ok(CliNpmResolver::new(if cli_options.use_byonm() { CliNpmResolverCreateOptions::Byonm( CliByonmNpmResolverCreateOptions { sys: self.sys(), @@ -796,11 +793,7 @@ impl CliFactory { Ok(Arc::new(CliNodeResolver::new( self.in_npm_pkg_checker()?.clone(), RealIsBuiltInNodeModuleChecker, - self - .npm_resolver() - .await? - .clone() - .into_npm_pkg_folder_resolver(), + self.npm_resolver().await?.clone(), self.pkg_json_resolver().clone(), self.sys(), node_resolver::ConditionsFromResolutionMode::default(), @@ -833,11 +826,7 @@ impl CliFactory { cjs_esm_analyzer, self.in_npm_pkg_checker()?.clone(), node_resolver, - self - .npm_resolver() - .await? - .clone() - .into_npm_pkg_folder_resolver(), + self.npm_resolver().await?.clone(), self.pkg_json_resolver().clone(), self.sys(), ))) @@ -857,7 +846,7 @@ impl CliFactory { sys: self.sys(), in_npm_pkg_checker: self.in_npm_pkg_checker()?.clone(), node_resolver: self.node_resolver().await?.clone(), - npm_resolver: npm_resolver.clone().into_byonm_or_managed(), + npm_resolver: npm_resolver.clone(), }))) }) .await @@ -988,10 +977,10 @@ impl CliFactory { .await } - pub fn cjs_tracker(&self) -> Result<&Arc, AnyError> { + pub fn cjs_tracker(&self) -> Result<&Arc, AnyError> { self.services.cjs_tracker.get_or_try_init(|| { let options = self.cli_options()?; - Ok(Arc::new(CjsTracker::new( + Ok(Arc::new(CliCjsTracker::new( self.in_npm_pkg_checker()?.clone(), self.pkg_json_resolver().clone(), if options.is_node_main() || options.unstable_detect_cjs() { @@ -1040,7 +1029,7 @@ impl CliFactory { self.emitter()?, self.file_fetcher()?, self.http_client_provider(), - self.npm_resolver().await?.as_ref(), + self.npm_resolver().await?, self.workspace_resolver().await?.as_ref(), cli_options.npm_system_info(), )) diff --git a/cli/graph_util.rs b/cli/graph_util.rs index 17d4fef553..e57fcf8a94 100644 --- a/cli/graph_util.rs +++ b/cli/graph_util.rs @@ -30,6 +30,7 @@ use deno_graph::ResolutionError; use deno_graph::SpecifierError; use deno_graph::WorkspaceFastCheckOption; use deno_path_util::url_to_file_path; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::sloppy_imports::SloppyImportsCachedFs; use deno_resolver::sloppy_imports::SloppyImportsResolutionKind; use deno_runtime::deno_node; @@ -37,7 +38,6 @@ use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::jsr::JsrDepPackageReq; use deno_semver::package::PackageNv; use deno_semver::SmallStackString; -use node_resolver::InNpmPackageChecker; use crate::args::config_to_deno_graph_workspace_member; use crate::args::jsr_url; @@ -55,7 +55,7 @@ use crate::file_fetcher::CliFileFetcher; use crate::npm::installer::NpmInstaller; use crate::npm::installer::PackageCaching; use crate::npm::CliNpmResolver; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; use crate::resolver::CliNpmGraphResolver; use crate::resolver::CliResolver; use crate::resolver::CliSloppyImportsResolver; @@ -493,17 +493,17 @@ pub enum BuildGraphWithNpmResolutionError { pub struct ModuleGraphBuilder { caches: Arc, - cjs_tracker: Arc, + cjs_tracker: Arc, cli_options: Arc, file_fetcher: Arc, global_http_cache: Arc, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, lockfile: Option>, maybe_file_watcher_reporter: Option, module_info_cache: Arc, npm_graph_resolver: Arc, npm_installer: Option>, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, parsed_source_cache: Arc, resolver: Arc, root_permissions_container: PermissionsContainer, @@ -514,17 +514,17 @@ impl ModuleGraphBuilder { #[allow(clippy::too_many_arguments)] pub fn new( caches: Arc, - cjs_tracker: Arc, + cjs_tracker: Arc, cli_options: Arc, file_fetcher: Arc, global_http_cache: Arc, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, lockfile: Option>, maybe_file_watcher_reporter: Option, module_info_cache: Arc, npm_graph_resolver: Arc, npm_installer: Option>, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, parsed_source_cache: Arc, resolver: Arc, root_permissions_container: PermissionsContainer, @@ -712,8 +712,7 @@ impl ModuleGraphBuilder { let initial_package_deps_len = graph.packages.package_deps_sum(); let initial_package_mappings_len = graph.packages.mappings().len(); - if roots.iter().any(|r| r.scheme() == "npm") - && self.npm_resolver.as_byonm().is_some() + if roots.iter().any(|r| r.scheme() == "npm") && self.npm_resolver.is_byonm() { return Err(BuildGraphWithNpmResolutionError::UnsupportedNpmSpecifierEntrypointResolutionWay); } @@ -1226,7 +1225,7 @@ fn format_deno_graph_error(err: &dyn Error) -> String { #[derive(Debug)] struct CliGraphResolver<'a> { - cjs_tracker: &'a CjsTracker, + cjs_tracker: &'a CliCjsTracker, resolver: &'a CliResolver, jsx_import_source_config: Option, } diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index f7b487f055..f8f382f594 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -19,6 +19,7 @@ use deno_core::ModuleSpecifier; use deno_error::JsErrorBox; use deno_lint::diagnostic::LintDiagnosticRange; use deno_path_util::url_to_file_path; +use deno_resolver::npm::managed::NpmResolutionCell; use deno_runtime::deno_node::PathClean; use deno_semver::jsr::JsrPackageNvReference; use deno_semver::jsr::JsrPackageReqReference; @@ -31,6 +32,7 @@ use deno_semver::SmallStackString; use deno_semver::StackString; use deno_semver::Version; use import_map::ImportMap; +use node_resolver::InNpmPackageChecker; use node_resolver::NodeResolutionKind; use node_resolver::ResolutionMode; use once_cell::sync::Lazy; @@ -365,7 +367,9 @@ impl<'a> TsResponseImportMapper<'a> { if let Ok(Some(pkg_id)) = npm_resolver.resolve_pkg_id_from_specifier(specifier) { - let pkg_reqs = npm_resolver.resolve_pkg_reqs_from_pkg_id(&pkg_id); + let pkg_reqs = npm_resolver + .resolution() + .resolve_pkg_reqs_from_pkg_id(&pkg_id); // check if any pkg reqs match what is found in an import map if !pkg_reqs.is_empty() { let sub_path = npm_resolver @@ -1295,6 +1299,19 @@ impl CodeActionCollection { range: &lsp::Range, language_server: &language_server::Inner, ) -> Option { + fn top_package_req_for_name( + resolution: &NpmResolutionCell, + name: &str, + ) -> Option { + let package_reqs = resolution.package_reqs(); + let mut entries = package_reqs + .into_iter() + .filter(|(_, nv)| nv.name == name) + .collect::>(); + entries.sort_by(|a, b| a.1.version.cmp(&b.1.version)); + Some(entries.pop()?.0) + } + let (dep_key, dependency, _) = document.get_maybe_dependency(&range.end)?; if dependency.maybe_deno_types_specifier.is_some() { @@ -1382,9 +1399,10 @@ impl CodeActionCollection { .and_then(|versions| versions.first().cloned())?; let types_specifier_text = if let Some(npm_resolver) = managed_npm_resolver { - let mut specifier_text = if let Some(req) = - npm_resolver.top_package_req_for_name(&types_package_name) - { + let mut specifier_text = if let Some(req) = top_package_req_for_name( + npm_resolver.resolution(), + &types_package_name, + ) { format!("npm:{req}") } else { format!("npm:{}@^{}", &types_package_name, types_package_version) diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index af4ab6571f..1b393ad22b 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -26,6 +26,7 @@ use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; use deno_resolver::npm::managed::NpmResolutionCell; use deno_resolver::npm::CreateInNpmPkgCheckerOptions; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::npm::NpmReqResolverOptions; use deno_resolver::DenoResolverOptions; use deno_resolver::NodeAndNpmReqResolver; @@ -35,7 +36,6 @@ use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use indexmap::IndexMap; -use node_resolver::InNpmPackageChecker; use node_resolver::NodeResolutionKind; use node_resolver::ResolutionMode; @@ -56,10 +56,10 @@ use crate::lsp::config::ConfigData; use crate::lsp::logging::lsp_warn; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; -use crate::npm::create_cli_npm_resolver; use crate::npm::installer::NpmInstaller; use crate::npm::installer::NpmResolutionInstaller; use crate::npm::CliByonmNpmResolverCreateOptions; +use crate::npm::CliManagedNpmResolver; use crate::npm::CliManagedNpmResolverCreateOptions; use crate::npm::CliNpmCache; use crate::npm::CliNpmCacheHttpClient; @@ -67,14 +67,13 @@ use crate::npm::CliNpmRegistryInfoProvider; use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolverCreateOptions; use crate::npm::CliNpmResolverManagedSnapshotOption; -use crate::npm::ManagedCliNpmResolver; use crate::npm::NpmResolutionInitializer; use crate::resolver::CliDenoResolver; +use crate::resolver::CliIsCjsResolver; use crate::resolver::CliNpmGraphResolver; use crate::resolver::CliNpmReqResolver; use crate::resolver::CliResolver; use crate::resolver::FoundPackageJsonDepFlag; -use crate::resolver::IsCjsResolver; use crate::sys::CliSys; use crate::tsc::into_specifier_and_media_type; use crate::util::progress_bar::ProgressBar; @@ -83,12 +82,13 @@ use crate::util::progress_bar::ProgressBarStyle; #[derive(Debug, Clone)] struct LspScopeResolver { resolver: Arc, - in_npm_pkg_checker: Arc, - is_cjs_resolver: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, + is_cjs_resolver: Arc, jsr_resolver: Option>, npm_graph_resolver: Arc, npm_installer: Option>, - npm_resolver: Option>, + npm_resolution: Arc, + npm_resolver: Option, node_resolver: Option>, npm_pkg_req_resolver: Option>, pkg_json_resolver: Arc, @@ -111,6 +111,7 @@ impl Default for LspScopeResolver { npm_installer: None, npm_resolver: None, node_resolver: None, + npm_resolution: factory.services.npm_resolution.clone(), npm_pkg_req_resolver: None, pkg_json_resolver: factory.pkg_json_resolver().clone(), redirect_resolver: None, @@ -224,6 +225,7 @@ impl LspScopeResolver { npm_pkg_req_resolver, npm_resolver, npm_installer, + npm_resolution: factory.services.npm_resolution.clone(), node_resolver, pkg_json_resolver, redirect_resolver, @@ -235,12 +237,58 @@ impl LspScopeResolver { } fn snapshot(&self) -> Arc { + // create a copy of the resolution and then re-initialize the npm resolver from that + // todo(dsherret): this is pretty terrible... we should improve this. It should + // be possible to just change the npm_resolution on the new factory then access + // another method to create a new npm resolver let mut factory = ResolverFactory::new(self.config_data.as_ref()); - let npm_resolver = - self.npm_resolver.as_ref().map(|r| r.clone_snapshotted()); + factory + .services + .npm_resolution + .set_snapshot(self.npm_resolution.snapshot()); + let npm_resolver = self.npm_resolver.as_ref(); if let Some(npm_resolver) = &npm_resolver { - factory.set_npm_resolver(npm_resolver.clone()); + factory.set_npm_resolver(CliNpmResolver::new::( + match npm_resolver { + CliNpmResolver::Byonm(byonm_npm_resolver) => { + CliNpmResolverCreateOptions::Byonm( + CliByonmNpmResolverCreateOptions { + root_node_modules_dir: byonm_npm_resolver + .root_node_modules_path() + .map(|p| p.to_path_buf()), + sys: CliSys::default(), + pkg_json_resolver: self.pkg_json_resolver.clone(), + }, + ) + } + CliNpmResolver::Managed(managed_npm_resolver) => { + CliNpmResolverCreateOptions::Managed({ + let npmrc = self + .config_data + .as_ref() + .and_then(|d| d.npmrc.clone()) + .unwrap_or_else(create_default_npmrc); + let npm_cache_dir = Arc::new(NpmCacheDir::new( + &CliSys::default(), + managed_npm_resolver.global_cache_root_path().to_path_buf(), + npmrc.get_all_known_registries_urls(), + )); + CliManagedNpmResolverCreateOptions { + sys: CliSys::default(), + npm_cache_dir, + maybe_node_modules_path: managed_npm_resolver + .root_node_modules_path() + .map(|p| p.to_path_buf()), + npmrc, + npm_resolution: factory.services.npm_resolution.clone(), + npm_system_info: NpmSystemInfo::default(), + } + }) + } + }, + )); } + Arc::new(Self { resolver: factory.cli_resolver().clone(), in_npm_pkg_checker: factory.in_npm_pkg_checker().clone(), @@ -250,6 +298,7 @@ impl LspScopeResolver { // npm installer isn't necessary for a snapshot npm_installer: None, npm_pkg_req_resolver: factory.npm_pkg_req_resolver().cloned(), + npm_resolution: factory.services.npm_resolution.clone(), npm_resolver: factory.npm_resolver().cloned(), node_resolver: factory.node_resolver().cloned(), redirect_resolver: self.redirect_resolver.clone(), @@ -366,7 +415,7 @@ impl LspResolver { pub fn as_is_cjs_resolver( &self, file_referrer: Option<&ModuleSpecifier>, - ) -> &IsCjsResolver { + ) -> &CliIsCjsResolver { let resolver = self.get_scope_resolver(file_referrer); resolver.is_cjs_resolver.as_ref() } @@ -382,7 +431,7 @@ impl LspResolver { pub fn in_npm_pkg_checker( &self, file_referrer: Option<&ModuleSpecifier>, - ) -> &Arc { + ) -> &DenoInNpmPackageChecker { let resolver = self.get_scope_resolver(file_referrer); &resolver.in_npm_pkg_checker } @@ -390,7 +439,7 @@ impl LspResolver { pub fn maybe_managed_npm_resolver( &self, file_referrer: Option<&ModuleSpecifier>, - ) -> Option<&ManagedCliNpmResolver> { + ) -> Option<&CliManagedNpmResolver> { let resolver = self.get_scope_resolver(file_referrer); resolver.npm_resolver.as_ref().and_then(|r| r.as_managed()) } @@ -605,13 +654,14 @@ pub struct ScopeDepInfo { struct ResolverFactoryServices { cli_resolver: Deferred>, found_pkg_json_dep_flag: Arc, - in_npm_pkg_checker: Deferred>, - is_cjs_resolver: Deferred>, + in_npm_pkg_checker: Deferred, + is_cjs_resolver: Deferred>, node_resolver: Deferred>>, npm_graph_resolver: Deferred>, npm_installer: Option>, npm_pkg_req_resolver: Deferred>>, - npm_resolver: Option>, + npm_resolver: Option, + npm_resolution: Arc, } struct ResolverFactory<'a> { @@ -686,10 +736,9 @@ impl<'a> ResolverFactory<'a> { npm_client.clone(), npmrc.clone(), )); - let npm_resolution = Arc::new(NpmResolutionCell::default()); let npm_resolution_initializer = Arc::new(NpmResolutionInitializer::new( registry_info_provider.clone(), - npm_resolution.clone(), + self.services.npm_resolution.clone(), match self.config_data.and_then(|d| d.lockfile.as_ref()) { Some(lockfile) => { CliNpmResolverManagedSnapshotOption::ResolveFromLockfile( @@ -712,13 +761,13 @@ impl<'a> ResolverFactory<'a> { )); let npm_resolution_installer = Arc::new(NpmResolutionInstaller::new( registry_info_provider, - npm_resolution.clone(), + self.services.npm_resolution.clone(), maybe_lockfile.clone(), )); let npm_installer = Arc::new(NpmInstaller::new( npm_cache.clone(), Arc::new(NpmInstallDepsProvider::empty()), - npm_resolution.clone(), + self.services.npm_resolution.clone(), npm_resolution_initializer.clone(), npm_resolution_installer, &pb, @@ -745,22 +794,22 @@ impl<'a> ResolverFactory<'a> { npm_cache_dir, maybe_node_modules_path, npmrc, - npm_resolution, + npm_resolution: self.services.npm_resolution.clone(), npm_system_info: NpmSystemInfo::default(), }) }; - self.set_npm_resolver(create_cli_npm_resolver(options)); + self.set_npm_resolver(CliNpmResolver::new(options)); } pub fn set_npm_installer(&mut self, npm_installer: Arc) { self.services.npm_installer = Some(npm_installer); } - pub fn set_npm_resolver(&mut self, npm_resolver: Arc) { + pub fn set_npm_resolver(&mut self, npm_resolver: CliNpmResolver) { self.services.npm_resolver = Some(npm_resolver); } - pub fn npm_resolver(&self) -> Option<&Arc> { + pub fn npm_resolver(&self) -> Option<&CliNpmResolver> { self.services.npm_resolver.as_ref() } @@ -825,29 +874,27 @@ impl<'a> ResolverFactory<'a> { &self.pkg_json_resolver } - pub fn in_npm_pkg_checker(&self) -> &Arc { + pub fn in_npm_pkg_checker(&self) -> &DenoInNpmPackageChecker { self.services.in_npm_pkg_checker.get_or_init(|| { - deno_resolver::npm::create_in_npm_pkg_checker( - match self.services.npm_resolver.as_ref().map(|r| r.as_inner()) { - Some(crate::npm::InnerCliNpmResolverRef::Byonm(_)) | None => { - CreateInNpmPkgCheckerOptions::Byonm - } - Some(crate::npm::InnerCliNpmResolverRef::Managed(m)) => { - CreateInNpmPkgCheckerOptions::Managed( - ManagedInNpmPkgCheckerCreateOptions { - root_cache_dir_url: m.global_cache_root_url(), - maybe_node_modules_path: m.maybe_node_modules_path(), - }, - ) - } - }, - ) + DenoInNpmPackageChecker::new(match &self.services.npm_resolver { + Some(CliNpmResolver::Byonm(_)) | None => { + CreateInNpmPkgCheckerOptions::Byonm + } + Some(CliNpmResolver::Managed(m)) => { + CreateInNpmPkgCheckerOptions::Managed( + ManagedInNpmPkgCheckerCreateOptions { + root_cache_dir_url: m.global_cache_root_url(), + maybe_node_modules_path: m.root_node_modules_path(), + }, + ) + } + }) }) } - pub fn is_cjs_resolver(&self) -> &Arc { + pub fn is_cjs_resolver(&self) -> &Arc { self.services.is_cjs_resolver.get_or_init(|| { - Arc::new(IsCjsResolver::new( + Arc::new(CliIsCjsResolver::new( self.in_npm_pkg_checker().clone(), self.pkg_json_resolver().clone(), if self @@ -871,7 +918,7 @@ impl<'a> ResolverFactory<'a> { Some(Arc::new(CliNodeResolver::new( self.in_npm_pkg_checker().clone(), RealIsBuiltInNodeModuleChecker, - npm_resolver.clone().into_npm_pkg_folder_resolver(), + npm_resolver.clone(), self.pkg_json_resolver.clone(), self.sys.clone(), node_resolver::ConditionsFromResolutionMode::default(), @@ -890,7 +937,7 @@ impl<'a> ResolverFactory<'a> { Some(Arc::new(CliNpmReqResolver::new(NpmReqResolverOptions { in_npm_pkg_checker: self.in_npm_pkg_checker().clone(), node_resolver: node_resolver.clone(), - npm_resolver: npm_resolver.clone().into_byonm_or_managed(), + npm_resolver: npm_resolver.clone(), sys: self.sys.clone(), }))) }) diff --git a/cli/module_loader.rs b/cli/module_loader.rs index ba53077a3c..daeb4dda37 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -39,6 +39,7 @@ use deno_graph::ModuleGraph; use deno_graph::ModuleGraphError; use deno_graph::Resolution; use deno_graph::WasmModule; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::code_cache; use deno_runtime::deno_node::create_host_defined_options; use deno_runtime::deno_node::NodeRequireLoader; @@ -70,7 +71,7 @@ use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::npm::CliNpmResolver; use crate::npm::NpmRegistryReadPermissionChecker; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; use crate::resolver::CliNpmReqResolver; use crate::resolver::CliResolver; use crate::resolver::ModuleCodeStringSource; @@ -233,10 +234,10 @@ struct SharedCliModuleLoaderState { initial_cwd: PathBuf, is_inspecting: bool, is_repl: bool, - cjs_tracker: Arc, + cjs_tracker: Arc, code_cache: Option>, emitter: Arc, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, main_module_graph_container: Arc, module_load_preparer: Arc, node_code_translator: Arc, @@ -244,7 +245,7 @@ struct SharedCliModuleLoaderState { npm_module_loader: NpmModuleLoader, npm_registry_permission_checker: Arc, npm_req_resolver: Arc, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, parsed_source_cache: Arc, resolver: Arc, sys: CliSys, @@ -294,10 +295,10 @@ impl CliModuleLoaderFactory { #[allow(clippy::too_many_arguments)] pub fn new( options: &CliOptions, - cjs_tracker: Arc, + cjs_tracker: Arc, code_cache: Option>, emitter: Arc, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, main_module_graph_container: Arc, module_load_preparer: Arc, node_code_translator: Arc, @@ -305,7 +306,7 @@ impl CliModuleLoaderFactory { npm_module_loader: NpmModuleLoader, npm_registry_permission_checker: Arc, npm_req_resolver: Arc, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, parsed_source_cache: Arc, resolver: Arc, sys: CliSys, @@ -1139,11 +1140,11 @@ impl ModuleGraphUpdatePermit for WorkerModuleGraphUpdatePermit { #[derive(Debug)] struct CliNodeRequireLoader { - cjs_tracker: Arc, + cjs_tracker: Arc, emitter: Arc, sys: CliSys, graph_container: TGraphContainer, - in_npm_pkg_checker: Arc, + in_npm_pkg_checker: DenoInNpmPackageChecker, npm_registry_permission_checker: Arc, } diff --git a/cli/node.rs b/cli/node.rs index aa44dcab18..892e25914a 100644 --- a/cli/node.rs +++ b/cli/node.rs @@ -7,6 +7,7 @@ use deno_ast::MediaType; use deno_ast::ModuleSpecifier; use deno_core::error::AnyError; use deno_graph::ParsedSourceStore; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::deno_fs; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use node_resolver::analyze::CjsAnalysis as ExtNodeCjsAnalysis; @@ -19,15 +20,22 @@ use serde::Serialize; use crate::cache::CacheDBHash; use crate::cache::NodeAnalysisCache; use crate::cache::ParsedSourceCache; -use crate::resolver::CjsTracker; +use crate::npm::CliNpmResolver; +use crate::resolver::CliCjsTracker; use crate::sys::CliSys; pub type CliNodeCodeTranslator = NodeCodeTranslator< CliCjsCodeAnalyzer, + DenoInNpmPackageChecker, RealIsBuiltInNodeModuleChecker, + CliNpmResolver, + CliSys, +>; +pub type CliNodeResolver = deno_runtime::deno_node::NodeResolver< + DenoInNpmPackageChecker, + CliNpmResolver, CliSys, >; -pub type CliNodeResolver = deno_runtime::deno_node::NodeResolver; pub type CliPackageJsonResolver = node_resolver::PackageJsonResolver; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -43,7 +51,7 @@ pub enum CliCjsAnalysis { pub struct CliCjsCodeAnalyzer { cache: NodeAnalysisCache, - cjs_tracker: Arc, + cjs_tracker: Arc, fs: deno_fs::FileSystemRc, parsed_source_cache: Option>, } @@ -51,7 +59,7 @@ pub struct CliCjsCodeAnalyzer { impl CliCjsCodeAnalyzer { pub fn new( cache: NodeAnalysisCache, - cjs_tracker: Arc, + cjs_tracker: Arc, fs: deno_fs::FileSystemRc, parsed_source_cache: Option>, ) -> Self { diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index bd29a6ec72..8dc498bb04 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -1,21 +1,12 @@ // Copyright 2018-2025 the Deno authors. MIT license. -use std::path::Path; -use std::path::PathBuf; use std::sync::Arc; use deno_core::serde_json; -use deno_core::url::Url; use deno_resolver::npm::ByonmNpmResolver; use deno_resolver::npm::ByonmNpmResolverCreateOptions; -use deno_resolver::npm::ByonmOrManagedNpmResolver; -use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_runtime::ops::process::NpmProcessStateProvider; -use deno_semver::package::PackageReq; -use node_resolver::NpmPackageFolderResolver; -use super::CliNpmResolver; -use super::InnerCliNpmResolverRef; use crate::args::NpmProcessState; use crate::args::NpmProcessStateKind; use crate::sys::CliSys; @@ -24,67 +15,18 @@ pub type CliByonmNpmResolverCreateOptions = ByonmNpmResolverCreateOptions; pub type CliByonmNpmResolver = ByonmNpmResolver; -// todo(dsherret): the services hanging off `CliNpmResolver` doesn't seem ideal. We should probably decouple. #[derive(Debug)] -struct CliByonmWrapper(Arc); +pub struct CliByonmNpmProcessStateProvider(pub Arc); -impl NpmProcessStateProvider for CliByonmWrapper { +impl NpmProcessStateProvider for CliByonmNpmProcessStateProvider { fn get_npm_process_state(&self) -> String { serde_json::to_string(&NpmProcessState { kind: NpmProcessStateKind::Byonm, local_node_modules_path: self .0 - .root_node_modules_dir() + .root_node_modules_path() .map(|p| p.to_string_lossy().to_string()), }) .unwrap() } } - -impl CliNpmResolver for CliByonmNpmResolver { - fn into_npm_pkg_folder_resolver( - self: Arc, - ) -> Arc { - self - } - - fn into_process_state_provider( - self: Arc, - ) -> Arc { - Arc::new(CliByonmWrapper(self)) - } - - fn into_byonm_or_managed( - self: Arc, - ) -> ByonmOrManagedNpmResolver { - ByonmOrManagedNpmResolver::Byonm(self) - } - - fn clone_snapshotted(&self) -> Arc { - Arc::new(self.clone()) - } - - fn as_inner(&self) -> InnerCliNpmResolverRef { - InnerCliNpmResolverRef::Byonm(self) - } - - fn root_node_modules_path(&self) -> Option<&Path> { - self.root_node_modules_dir() - } - - fn check_state_hash(&self) -> Option { - // it is very difficult to determine the check state hash for byonm - // so we just return None to signify check caching is not supported - None - } - - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - referrer: &Url, - ) -> Result { - self - .resolve_pkg_folder_from_deno_module_req(req, referrer) - .map_err(ResolvePkgFolderFromDenoReqError::Byonm) - } -} diff --git a/cli/npm/managed.rs b/cli/npm/managed.rs index 0d4c209acc..4122c881f1 100644 --- a/cli/npm/managed.rs +++ b/cli/npm/managed.rs @@ -4,44 +4,28 @@ use std::path::Path; use std::path::PathBuf; use std::sync::Arc; -use deno_ast::ModuleSpecifier; -use deno_cache_dir::npm::NpmCacheDir; use deno_core::parking_lot::Mutex; use deno_core::serde_json; -use deno_core::url::Url; use deno_error::JsError; use deno_error::JsErrorBox; -use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmRegistryApi; use deno_npm::resolution::NpmResolutionSnapshot; -use deno_npm::resolution::PackageReqNotFoundError; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; -use deno_npm::NpmPackageId; -use deno_npm::NpmResolutionPackage; -use deno_npm::NpmSystemInfo; +use deno_resolver::npm::managed::ManagedNpmResolverCreateOptions; use deno_resolver::npm::managed::NpmResolutionCell; -use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError; -use deno_resolver::npm::managed::ResolvePkgFolderFromPkgIdError; -use deno_resolver::npm::managed::ResolvePkgIdFromSpecifierError; -use deno_resolver::npm::ByonmOrManagedNpmResolver; -use deno_resolver::npm::ManagedNpmResolver; -use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; +use deno_resolver::npm::ManagedNpmResolverRc; use deno_runtime::ops::process::NpmProcessStateProvider; -use deno_semver::package::PackageNv; -use deno_semver::package::PackageReq; -use node_resolver::NpmPackageFolderResolver; -use sys_traits::FsMetadata; use thiserror::Error; use super::CliNpmRegistryInfoProvider; -use super::CliNpmResolver; -use super::InnerCliNpmResolverRef; use crate::args::CliLockfile; use crate::args::NpmProcessState; use crate::args::NpmProcessStateKind; -use crate::cache::FastInsecureHasher; use crate::sys::CliSys; +pub type CliManagedNpmResolverCreateOptions = + ManagedNpmResolverCreateOptions; + #[derive(Debug, Clone)] pub enum CliNpmResolverManagedSnapshotOption { ResolveFromLockfile(Arc), @@ -139,36 +123,6 @@ impl NpmResolutionInitializer { } } -pub struct CliManagedNpmResolverCreateOptions { - pub npm_cache_dir: Arc, - pub sys: CliSys, - pub maybe_node_modules_path: Option, - pub npm_system_info: NpmSystemInfo, - pub npmrc: Arc, - pub npm_resolution: Arc, -} - -pub fn create_managed_npm_resolver( - options: CliManagedNpmResolverCreateOptions, -) -> Arc { - let managed_npm_resolver = - Arc::new(ManagedNpmResolver::::new::( - &options.npm_cache_dir, - &options.npmrc, - options.npm_resolution.clone(), - options.sys.clone(), - options.maybe_node_modules_path, - )); - Arc::new(ManagedCliNpmResolver::new( - managed_npm_resolver, - options.npm_cache_dir, - options.npmrc, - options.npm_resolution, - options.sys, - options.npm_system_info, - )) -} - #[derive(Debug, Error, Clone, JsError)] #[error("failed reading lockfile '{}'", lockfile_path.display())] #[class(inherit)] @@ -254,145 +208,6 @@ async fn snapshot_from_lockfile( Ok(snapshot) } -/// An npm resolver where the resolution is managed by Deno rather than -/// the user bringing their own node_modules (BYONM) on the file system. -pub struct ManagedCliNpmResolver { - managed_npm_resolver: Arc>, - npm_cache_dir: Arc, - npm_rc: Arc, - sys: CliSys, - resolution: Arc, - system_info: NpmSystemInfo, -} - -impl std::fmt::Debug for ManagedCliNpmResolver { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ManagedCliNpmResolver") - .field("", &"") - .finish() - } -} - -impl ManagedCliNpmResolver { - #[allow(clippy::too_many_arguments)] - pub fn new( - managed_npm_resolver: Arc>, - npm_cache_dir: Arc, - npm_rc: Arc, - resolution: Arc, - sys: CliSys, - system_info: NpmSystemInfo, - ) -> Self { - Self { - managed_npm_resolver, - npm_cache_dir, - npm_rc, - resolution, - sys, - system_info, - } - } - - pub fn resolve_pkg_folder_from_pkg_id( - &self, - pkg_id: &NpmPackageId, - ) -> Result { - self - .managed_npm_resolver - .resolve_pkg_folder_from_pkg_id(pkg_id) - } - - /// Resolves the package id from the provided specifier. - pub fn resolve_pkg_id_from_specifier( - &self, - specifier: &ModuleSpecifier, - ) -> Result, ResolvePkgIdFromSpecifierError> { - self - .managed_npm_resolver - .resolve_pkg_id_from_specifier(specifier) - } - - pub fn resolve_pkg_reqs_from_pkg_id( - &self, - id: &NpmPackageId, - ) -> Vec { - self.resolution.resolve_pkg_reqs_from_pkg_id(id) - } - - pub fn all_system_packages( - &self, - system_info: &NpmSystemInfo, - ) -> Vec { - self.resolution.all_system_packages(system_info) - } - - /// Checks if the provided package req's folder is cached. - pub fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool { - self - .resolve_pkg_id_from_pkg_req(req) - .ok() - .and_then(|id| { - self - .managed_npm_resolver - .resolve_pkg_folder_from_pkg_id(&id) - .ok() - }) - .map(|folder| self.sys.fs_exists_no_err(folder)) - .unwrap_or(false) - } - - pub fn snapshot(&self) -> NpmResolutionSnapshot { - self.resolution.snapshot() - } - - pub fn top_package_req_for_name(&self, name: &str) -> Option { - let package_reqs = self.resolution.package_reqs(); - let mut entries = package_reqs - .iter() - .filter(|(_, nv)| nv.name == name) - .collect::>(); - entries.sort_by_key(|(_, nv)| &nv.version); - Some(entries.last()?.0.clone()) - } - - pub fn serialized_valid_snapshot_for_system( - &self, - system_info: &NpmSystemInfo, - ) -> ValidSerializedNpmResolutionSnapshot { - self - .resolution - .serialized_valid_snapshot_for_system(system_info) - } - - pub fn resolve_pkg_folder_from_deno_module( - &self, - nv: &PackageNv, - ) -> Result { - self - .managed_npm_resolver - .resolve_pkg_folder_from_deno_module(nv) - } - - pub fn resolve_pkg_id_from_pkg_req( - &self, - req: &PackageReq, - ) -> Result { - self.resolution.resolve_pkg_id_from_pkg_req(req) - } - - pub fn maybe_node_modules_path(&self) -> Option<&Path> { - self.managed_npm_resolver.node_modules_path() - } - - pub fn global_cache_root_path(&self) -> &Path { - self.npm_cache_dir.root_dir() - } - - pub fn global_cache_root_url(&self) -> &Url { - self.npm_cache_dir.root_dir_url() - } -} - pub fn npm_process_state( snapshot: ValidSerializedNpmResolutionSnapshot, node_modules_path: Option<&Path>, @@ -405,92 +220,14 @@ pub fn npm_process_state( .unwrap() } -impl NpmProcessStateProvider for ManagedCliNpmResolver { +#[derive(Debug)] +pub struct CliManagedNpmProcessStateProvider(pub ManagedNpmResolverRc); + +impl NpmProcessStateProvider for CliManagedNpmProcessStateProvider { fn get_npm_process_state(&self) -> String { npm_process_state( - self.resolution.serialized_valid_snapshot(), - self.managed_npm_resolver.node_modules_path(), + self.0.resolution().serialized_valid_snapshot(), + self.0.root_node_modules_path(), ) } } - -impl CliNpmResolver for ManagedCliNpmResolver { - fn into_npm_pkg_folder_resolver( - self: Arc, - ) -> Arc { - self.managed_npm_resolver.clone() - } - - fn into_process_state_provider( - self: Arc, - ) -> Arc { - self - } - - fn into_byonm_or_managed( - self: Arc, - ) -> ByonmOrManagedNpmResolver { - ByonmOrManagedNpmResolver::Managed(self.managed_npm_resolver.clone()) - } - - fn clone_snapshotted(&self) -> Arc { - // create a new snapshotted npm resolution and resolver - let npm_resolution = - Arc::new(NpmResolutionCell::new(self.resolution.snapshot())); - - Arc::new(ManagedCliNpmResolver::new( - Arc::new(ManagedNpmResolver::::new::( - &self.npm_cache_dir, - &self.npm_rc, - npm_resolution.clone(), - self.sys.clone(), - self.root_node_modules_path().map(ToOwned::to_owned), - )), - self.npm_cache_dir.clone(), - self.npm_rc.clone(), - npm_resolution, - self.sys.clone(), - self.system_info.clone(), - )) - } - - fn as_inner(&self) -> InnerCliNpmResolverRef { - InnerCliNpmResolverRef::Managed(self) - } - - fn root_node_modules_path(&self) -> Option<&Path> { - self.managed_npm_resolver.node_modules_path() - } - - fn check_state_hash(&self) -> Option { - // We could go further and check all the individual - // npm packages, but that's probably overkill. - let mut package_reqs = self - .resolution - .package_reqs() - .into_iter() - .collect::>(); - package_reqs.sort_by(|a, b| a.0.cmp(&b.0)); // determinism - let mut hasher = FastInsecureHasher::new_without_deno_version(); - // ensure the cache gets busted when turning nodeModulesDir on or off - // as this could cause changes in resolution - hasher - .write_hashable(self.managed_npm_resolver.node_modules_path().is_some()); - for (pkg_req, pkg_nv) in package_reqs { - hasher.write_hashable(&pkg_req); - hasher.write_hashable(&pkg_nv); - } - Some(hasher.finish()) - } - - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - referrer: &Url, - ) -> Result { - self - .managed_npm_resolver - .resolve_pkg_folder_from_deno_module_req(req, referrer) - .map_err(ResolvePkgFolderFromDenoReqError::Managed) - } -} diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 6ad7ad610e..1c12ce6c59 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -5,8 +5,6 @@ pub mod installer; mod managed; mod permission_checker; -use std::path::Path; -use std::path::PathBuf; use std::sync::Arc; use dashmap::DashMap; @@ -15,21 +13,15 @@ use deno_core::url::Url; use deno_error::JsErrorBox; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageInfo; -use deno_resolver::npm::ByonmNpmResolver; -use deno_resolver::npm::ByonmOrManagedNpmResolver; -use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; -use deno_runtime::ops::process::NpmProcessStateProvider; +use deno_runtime::ops::process::NpmProcessStateProviderRc; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use http::HeaderName; use http::HeaderValue; -use node_resolver::NpmPackageFolderResolver; -pub use self::byonm::CliByonmNpmResolver; pub use self::byonm::CliByonmNpmResolverCreateOptions; pub use self::managed::CliManagedNpmResolverCreateOptions; pub use self::managed::CliNpmResolverManagedSnapshotOption; -pub use self::managed::ManagedCliNpmResolver; pub use self::managed::NpmResolutionInitializer; pub use self::managed::ResolveSnapshotError; pub use self::permission_checker::NpmRegistryReadPermissionChecker; @@ -44,6 +36,10 @@ pub type CliNpmTarballCache = pub type CliNpmCache = deno_npm_cache::NpmCache; pub type CliNpmRegistryInfoProvider = deno_npm_cache::RegistryInfoProvider; +pub type CliNpmResolver = deno_resolver::npm::NpmResolver; +pub type CliManagedNpmResolver = deno_resolver::npm::ManagedNpmResolver; +pub type CliNpmResolverCreateOptions = + deno_resolver::npm::NpmResolverCreateOptions; #[derive(Debug)] pub struct CliNpmCacheHttpClient { @@ -63,6 +59,19 @@ impl CliNpmCacheHttpClient { } } +pub fn create_npm_process_state_provider( + npm_resolver: &CliNpmResolver, +) -> NpmProcessStateProviderRc { + match npm_resolver { + CliNpmResolver::Byonm(byonm_npm_resolver) => Arc::new( + byonm::CliByonmNpmProcessStateProvider(byonm_npm_resolver.clone()), + ), + CliNpmResolver::Managed(managed_npm_resolver) => Arc::new( + managed::CliManagedNpmProcessStateProvider(managed_npm_resolver.clone()), + ), + } +} + #[async_trait::async_trait(?Send)] impl deno_npm_cache::NpmCacheHttpClient for CliNpmCacheHttpClient { async fn download_with_retries_on_any_tokio_runtime( @@ -104,70 +113,6 @@ impl deno_npm_cache::NpmCacheHttpClient for CliNpmCacheHttpClient { } } -pub enum CliNpmResolverCreateOptions { - Managed(CliManagedNpmResolverCreateOptions), - Byonm(CliByonmNpmResolverCreateOptions), -} - -pub fn create_cli_npm_resolver( - options: CliNpmResolverCreateOptions, -) -> Arc { - use CliNpmResolverCreateOptions::*; - match options { - Managed(options) => managed::create_managed_npm_resolver(options), - Byonm(options) => Arc::new(ByonmNpmResolver::new(options)), - } -} - -pub enum InnerCliNpmResolverRef<'a> { - Managed(&'a ManagedCliNpmResolver), - #[allow(dead_code)] - Byonm(&'a CliByonmNpmResolver), -} - -// todo(dsherret): replace with an enum -pub trait CliNpmResolver: Send + Sync + std::fmt::Debug { - fn into_npm_pkg_folder_resolver( - self: Arc, - ) -> Arc; - fn into_process_state_provider( - self: Arc, - ) -> Arc; - fn into_byonm_or_managed( - self: Arc, - ) -> ByonmOrManagedNpmResolver; - - fn clone_snapshotted(&self) -> Arc; - - fn as_inner(&self) -> InnerCliNpmResolverRef; - - fn as_managed(&self) -> Option<&ManagedCliNpmResolver> { - match self.as_inner() { - InnerCliNpmResolverRef::Managed(inner) => Some(inner), - InnerCliNpmResolverRef::Byonm(_) => None, - } - } - - fn as_byonm(&self) -> Option<&CliByonmNpmResolver> { - match self.as_inner() { - InnerCliNpmResolverRef::Managed(_) => None, - InnerCliNpmResolverRef::Byonm(inner) => Some(inner), - } - } - - fn resolve_pkg_folder_from_deno_module_req( - &self, - req: &PackageReq, - referrer: &Url, - ) -> Result; - - fn root_node_modules_path(&self) -> Option<&Path>; - - /// Returns a hash returning the state of the npm resolver - /// or `None` if the state currently can't be determined. - fn check_state_hash(&self) -> Option; -} - #[derive(Debug)] pub struct NpmFetchResolver { nv_by_req: DashMap>, diff --git a/cli/resolver.rs b/cli/resolver.rs index 2f3d42e9e1..5677767fdd 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -19,6 +19,7 @@ use deno_graph::source::UnknownBuiltInNodeModuleError; use deno_graph::NpmLoadError; use deno_graph::NpmResolvePkgReqsResult; use deno_npm::resolution::NpmResolutionError; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::sloppy_imports::SloppyImportsCachedFs; use deno_resolver::sloppy_imports::SloppyImportsResolver; use deno_runtime::colors; @@ -35,22 +36,31 @@ use crate::args::DENO_DISABLE_PEDANTIC_NODE_WARNINGS; use crate::node::CliNodeCodeTranslator; use crate::npm::installer::NpmInstaller; use crate::npm::installer::PackageCaching; +use crate::npm::CliNpmResolver; use crate::sys::CliSys; use crate::util::sync::AtomicFlag; use crate::util::text_encoding::from_utf8_lossy_cow; -pub type CjsTracker = deno_resolver::cjs::CjsTracker; -pub type IsCjsResolver = deno_resolver::cjs::IsCjsResolver; +pub type CliCjsTracker = + deno_resolver::cjs::CjsTracker; +pub type CliIsCjsResolver = + deno_resolver::cjs::IsCjsResolver; pub type CliSloppyImportsCachedFs = SloppyImportsCachedFs; pub type CliSloppyImportsResolver = SloppyImportsResolver; pub type CliDenoResolver = deno_resolver::DenoResolver< + DenoInNpmPackageChecker, RealIsBuiltInNodeModuleChecker, + CliNpmResolver, CliSloppyImportsCachedFs, CliSys, >; -pub type CliNpmReqResolver = - deno_resolver::npm::NpmReqResolver; +pub type CliNpmReqResolver = deno_resolver::npm::NpmReqResolver< + DenoInNpmPackageChecker, + RealIsBuiltInNodeModuleChecker, + CliNpmResolver, + CliSys, +>; pub struct ModuleCodeStringSource { pub code: ModuleSourceCode, @@ -69,14 +79,14 @@ pub struct NotSupportedKindInNpmError { // todo(dsherret): move to module_loader.rs (it seems to be here due to use in standalone) #[derive(Clone)] pub struct NpmModuleLoader { - cjs_tracker: Arc, + cjs_tracker: Arc, fs: Arc, node_code_translator: Arc, } impl NpmModuleLoader { pub fn new( - cjs_tracker: Arc, + cjs_tracker: Arc, fs: Arc, node_code_translator: Arc, ) -> Self { diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index ff0343e27f..c9b57f3d6b 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -92,8 +92,7 @@ use crate::emit::Emitter; use crate::file_fetcher::CliFileFetcher; use crate::http_util::HttpClientProvider; use crate::npm::CliNpmResolver; -use crate::npm::InnerCliNpmResolverRef; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; use crate::shared::ReleaseChannel; use crate::standalone::virtual_fs::VfsEntry; use crate::util::archive; @@ -410,13 +409,13 @@ pub struct WriteBinOptions<'a> { } pub struct DenoCompileBinaryWriter<'a> { - cjs_tracker: &'a CjsTracker, + cjs_tracker: &'a CliCjsTracker, cli_options: &'a CliOptions, deno_dir: &'a DenoDir, emitter: &'a Emitter, file_fetcher: &'a CliFileFetcher, http_client_provider: &'a HttpClientProvider, - npm_resolver: &'a dyn CliNpmResolver, + npm_resolver: &'a CliNpmResolver, workspace_resolver: &'a WorkspaceResolver, npm_system_info: NpmSystemInfo, } @@ -424,13 +423,13 @@ pub struct DenoCompileBinaryWriter<'a> { impl<'a> DenoCompileBinaryWriter<'a> { #[allow(clippy::too_many_arguments)] pub fn new( - cjs_tracker: &'a CjsTracker, + cjs_tracker: &'a CliCjsTracker, cli_options: &'a CliOptions, deno_dir: &'a DenoDir, emitter: &'a Emitter, file_fetcher: &'a CliFileFetcher, http_client_provider: &'a HttpClientProvider, - npm_resolver: &'a dyn CliNpmResolver, + npm_resolver: &'a CliNpmResolver, workspace_resolver: &'a WorkspaceResolver, npm_system_info: NpmSystemInfo, ) -> Self { @@ -599,10 +598,11 @@ impl<'a> DenoCompileBinaryWriter<'a> { None => None, }; let mut vfs = VfsBuilder::new(); - let npm_snapshot = match self.npm_resolver.as_inner() { - InnerCliNpmResolverRef::Managed(managed) => { - let snapshot = - managed.serialized_valid_snapshot_for_system(&self.npm_system_info); + let npm_snapshot = match &self.npm_resolver { + CliNpmResolver::Managed(managed) => { + let snapshot = managed + .resolution() + .serialized_valid_snapshot_for_system(&self.npm_system_info); if !snapshot.as_serialized().packages.is_empty() { self.fill_npm_vfs(&mut vfs).context("Building npm vfs.")?; Some(snapshot) @@ -610,7 +610,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { None } } - InnerCliNpmResolverRef::Byonm(_) => { + CliNpmResolver::Byonm(_) => { self.fill_npm_vfs(&mut vfs)?; None } @@ -751,8 +751,8 @@ impl<'a> DenoCompileBinaryWriter<'a> { ); } - let node_modules = match self.npm_resolver.as_inner() { - InnerCliNpmResolverRef::Managed(_) => { + let node_modules = match &self.npm_resolver { + CliNpmResolver::Managed(_) => { npm_snapshot.as_ref().map(|_| NodeModules::Managed { node_modules_dir: self.npm_resolver.root_node_modules_path().map( |path| { @@ -765,7 +765,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { ), }) } - InnerCliNpmResolverRef::Byonm(resolver) => Some(NodeModules::Byonm { + CliNpmResolver::Byonm(resolver) => Some(NodeModules::Byonm { root_node_modules_dir: resolver.root_node_modules_path().map( |node_modules_dir| { root_dir_url @@ -880,16 +880,17 @@ impl<'a> DenoCompileBinaryWriter<'a> { } } - match self.npm_resolver.as_inner() { - InnerCliNpmResolverRef::Managed(npm_resolver) => { + match &self.npm_resolver { + CliNpmResolver::Managed(npm_resolver) => { if let Some(node_modules_path) = npm_resolver.root_node_modules_path() { maybe_warn_different_system(&self.npm_system_info); builder.add_dir_recursive(node_modules_path)?; Ok(()) } else { // we'll flatten to remove any custom registries later - let mut packages = - npm_resolver.all_system_packages(&self.npm_system_info); + let mut packages = npm_resolver + .resolution() + .all_system_packages(&self.npm_system_info); packages.sort_by(|a, b| a.id.cmp(&b.id)); // determinism for package in packages { let folder = @@ -899,7 +900,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { Ok(()) } } - InnerCliNpmResolverRef::Byonm(_) => { + CliNpmResolver::Byonm(_) => { maybe_warn_different_system(&self.npm_system_info); for pkg_json in self.cli_options.workspace().package_jsons() { builder.add_file_at_path(&pkg_json.path)?; @@ -942,8 +943,8 @@ impl<'a> DenoCompileBinaryWriter<'a> { &self, mut vfs: VfsBuilder, ) -> BuiltVfs { - match self.npm_resolver.as_inner() { - InnerCliNpmResolverRef::Managed(npm_resolver) => { + match &self.npm_resolver { + CliNpmResolver::Managed(npm_resolver) => { if npm_resolver.root_node_modules_path().is_some() { return vfs.build(); } @@ -1035,7 +1036,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { .insert(npm_global_cache_dir_entry, case_sensitivity); built_vfs } - InnerCliNpmResolverRef::Byonm(_) => vfs.build(), + CliNpmResolver::Byonm(_) => vfs.build(), } } } diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index 4ca82f6b7d..876c194ed1 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -40,10 +40,11 @@ use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::resolution::NpmResolutionSnapshot; use deno_package_json::PackageJsonDepValue; use deno_resolver::cjs::IsCjsResolutionMode; -use deno_resolver::npm::create_in_npm_pkg_checker; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; use deno_resolver::npm::managed::NpmResolutionCell; +use deno_resolver::npm::ByonmNpmResolverCreateOptions; use deno_resolver::npm::CreateInNpmPkgCheckerOptions; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_resolver::npm::NpmReqResolverOptions; use deno_runtime::deno_fs; use deno_runtime::deno_fs::FileSystem; @@ -85,7 +86,6 @@ use crate::node::CliCjsCodeAnalyzer; use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; -use crate::npm::create_cli_npm_resolver; use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliManagedNpmResolverCreateOptions; use crate::npm::CliNpmResolver; @@ -94,7 +94,7 @@ use crate::npm::CliNpmResolverManagedSnapshotOption; use crate::npm::NpmRegistryReadPermissionChecker; use crate::npm::NpmRegistryReadPermissionCheckerMode; use crate::npm::NpmResolutionInitializer; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; use crate::resolver::CliNpmReqResolver; use crate::resolver::NpmModuleLoader; use crate::sys::CliSys; @@ -122,7 +122,7 @@ use self::binary::Metadata; pub use self::file_system::DenoCompileFileSystem; struct SharedModuleLoaderState { - cjs_tracker: Arc, + cjs_tracker: Arc, code_cache: Option>, fs: Arc, modules: StandaloneModules, @@ -131,7 +131,7 @@ struct SharedModuleLoaderState { npm_module_loader: Arc, npm_registry_permission_checker: NpmRegistryReadPermissionChecker, npm_req_resolver: Arc, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, source_maps: SourceMapStore, vfs: Arc, workspace_resolver: WorkspaceResolver, @@ -734,7 +734,7 @@ pub async fn run( let maybe_node_modules_path = node_modules_dir .map(|node_modules_dir| root_path.join(node_modules_dir)); let in_npm_pkg_checker = - create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed( + DenoInNpmPackageChecker::new(CreateInNpmPkgCheckerOptions::Managed( ManagedInNpmPkgCheckerCreateOptions { root_cache_dir_url: npm_cache_dir.root_dir_url(), maybe_node_modules_path: maybe_node_modules_path.as_deref(), @@ -743,7 +743,7 @@ pub async fn run( let npm_resolution = Arc::new(NpmResolutionCell::new(NpmResolutionSnapshot::new(snapshot))); let npm_resolver = - create_cli_npm_resolver(CliNpmResolverCreateOptions::Managed( + CliNpmResolver::new(CliNpmResolverCreateOptions::Managed( CliManagedNpmResolverCreateOptions { npm_resolution, npm_cache_dir, @@ -761,8 +761,8 @@ pub async fn run( let root_node_modules_dir = root_node_modules_dir.map(|p| vfs.root().join(p)); let in_npm_pkg_checker = - create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Byonm); - let npm_resolver = create_cli_npm_resolver( + DenoInNpmPackageChecker::new(CreateInNpmPkgCheckerOptions::Byonm); + let npm_resolver = CliNpmResolver::new( CliNpmResolverCreateOptions::Byonm(CliByonmNpmResolverCreateOptions { sys: sys.clone(), pkg_json_resolver: pkg_json_resolver.clone(), @@ -781,7 +781,7 @@ pub async fn run( npmrc.get_all_known_registries_urls(), )); let in_npm_pkg_checker = - create_in_npm_pkg_checker(CreateInNpmPkgCheckerOptions::Managed( + DenoInNpmPackageChecker::new(CreateInNpmPkgCheckerOptions::Managed( ManagedInNpmPkgCheckerCreateOptions { root_cache_dir_url: npm_cache_dir.root_dir_url(), maybe_node_modules_path: None, @@ -789,7 +789,7 @@ pub async fn run( )); let npm_resolution = Arc::new(NpmResolutionCell::default()); let npm_resolver = - create_cli_npm_resolver(CliNpmResolverCreateOptions::Managed( + CliNpmResolver::new(CliNpmResolverCreateOptions::Managed( CliManagedNpmResolverCreateOptions { npm_resolution, sys: sys.clone(), @@ -807,12 +807,12 @@ pub async fn run( let node_resolver = Arc::new(NodeResolver::new( in_npm_pkg_checker.clone(), RealIsBuiltInNodeModuleChecker, - npm_resolver.clone().into_npm_pkg_folder_resolver(), + npm_resolver.clone(), pkg_json_resolver.clone(), sys.clone(), node_resolver::ConditionsFromResolutionMode::default(), )); - let cjs_tracker = Arc::new(CjsTracker::new( + let cjs_tracker = Arc::new(CliCjsTracker::new( in_npm_pkg_checker.clone(), pkg_json_resolver.clone(), if metadata.unstable_config.detect_cjs { @@ -830,7 +830,7 @@ pub async fn run( sys: sys.clone(), in_npm_pkg_checker: in_npm_pkg_checker.clone(), node_resolver: node_resolver.clone(), - npm_resolver: npm_resolver.clone().into_byonm_or_managed(), + npm_resolver: npm_resolver.clone(), })); let cjs_esm_code_analyzer = CliCjsCodeAnalyzer::new( node_analysis_cache, @@ -842,7 +842,7 @@ pub async fn run( cjs_esm_code_analyzer, in_npm_pkg_checker, node_resolver.clone(), - npm_resolver.clone().into_npm_pkg_folder_resolver(), + npm_resolver.clone(), pkg_json_resolver.clone(), sys.clone(), )); diff --git a/cli/task_runner.rs b/cli/task_runner.rs index 8510a650e7..50dcd64dc7 100644 --- a/cli/task_runner.rs +++ b/cli/task_runner.rs @@ -25,9 +25,8 @@ use tokio::task::LocalSet; use tokio_util::sync::CancellationToken; use crate::node::CliNodeResolver; +use crate::npm::CliManagedNpmResolver; use crate::npm::CliNpmResolver; -use crate::npm::InnerCliNpmResolverRef; -use crate::npm::ManagedCliNpmResolver; pub fn get_script_with_args(script: &str, argv: &[String]) -> String { let additional_args = argv @@ -414,15 +413,15 @@ impl ShellCommand for NodeModulesFileRunCommand { } pub fn resolve_custom_commands( - npm_resolver: &dyn CliNpmResolver, + npm_resolver: &CliNpmResolver, node_resolver: &CliNodeResolver, ) -> Result>, AnyError> { - let mut commands = match npm_resolver.as_inner() { - InnerCliNpmResolverRef::Byonm(npm_resolver) => { + let mut commands = match npm_resolver { + CliNpmResolver::Byonm(npm_resolver) => { let node_modules_dir = npm_resolver.root_node_modules_path().unwrap(); resolve_npm_commands_from_bin_dir(node_modules_dir) } - InnerCliNpmResolverRef::Managed(npm_resolver) => { + CliNpmResolver::Managed(npm_resolver) => { resolve_managed_npm_commands(npm_resolver, node_resolver)? } }; @@ -521,13 +520,12 @@ fn resolve_execution_path_from_npx_shim( } fn resolve_managed_npm_commands( - npm_resolver: &ManagedCliNpmResolver, + npm_resolver: &CliManagedNpmResolver, node_resolver: &CliNodeResolver, ) -> Result>, AnyError> { let mut result = HashMap::new(); - let snapshot = npm_resolver.snapshot(); - for id in snapshot.top_level_packages() { - let package_folder = npm_resolver.resolve_pkg_folder_from_pkg_id(id)?; + for id in npm_resolver.resolution().top_level_packages() { + let package_folder = npm_resolver.resolve_pkg_folder_from_pkg_id(&id)?; let bin_commands = node_resolver.resolve_binary_commands(&package_folder)?; for bin_command in bin_commands { diff --git a/cli/tools/check.rs b/cli/tools/check.rs index c3a285a9b2..8c584113cb 100644 --- a/cli/tools/check.rs +++ b/cli/tools/check.rs @@ -112,7 +112,7 @@ pub struct TypeChecker { module_graph_builder: Arc, npm_installer: Option>, node_resolver: Arc, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, sys: CliSys, } @@ -146,7 +146,7 @@ impl TypeChecker { module_graph_builder: Arc, node_resolver: Arc, npm_installer: Option>, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, sys: CliSys, ) -> Self { Self { @@ -189,6 +189,29 @@ impl TypeChecker { mut graph: ModuleGraph, options: CheckOptions, ) -> Result<(Arc, Diagnostics), CheckError> { + fn check_state_hash(resolver: &CliNpmResolver) -> Option { + match resolver { + CliNpmResolver::Byonm(_) => { + // not feasible and probably slower to compute + None + } + CliNpmResolver::Managed(resolver) => { + // we should probably go further and check all the individual npm packages + let mut package_reqs = resolver.resolution().package_reqs(); + package_reqs.sort_by(|a, b| a.0.cmp(&b.0)); // determinism + let mut hasher = FastInsecureHasher::new_without_deno_version(); + // ensure the cache gets busted when turning nodeModulesDir on or off + // as this could cause changes in resolution + hasher.write_hashable(resolver.root_node_modules_path().is_some()); + for (pkg_req, pkg_nv) in package_reqs { + hasher.write_hashable(&pkg_req); + hasher.write_hashable(&pkg_nv); + } + Some(hasher.finish()) + } + } + } + if !options.type_check_mode.is_true() || graph.roots.is_empty() { return Ok((graph.into(), Default::default())); } @@ -240,7 +263,7 @@ impl TypeChecker { &self.sys, &graph, check_js, - self.npm_resolver.check_state_hash(), + check_state_hash(&self.npm_resolver), type_check_mode, &ts_config, ); diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs index 06afa5fac2..9b6ef81ea3 100644 --- a/cli/tools/coverage/mod.rs +++ b/cli/tools/coverage/mod.rs @@ -22,6 +22,7 @@ use deno_core::serde_json; use deno_core::sourcemap::SourceMap; use deno_core::url::Url; use deno_core::LocalInspectorSession; +use deno_resolver::npm::DenoInNpmPackageChecker; use node_resolver::InNpmPackageChecker; use regex::Regex; use text_lines::TextLines; @@ -464,7 +465,7 @@ fn filter_coverages( coverages: Vec, include: Vec, exclude: Vec, - in_npm_pkg_checker: &dyn InNpmPackageChecker, + in_npm_pkg_checker: &DenoInNpmPackageChecker, ) -> Vec { let include: Vec = include.iter().map(|e| Regex::new(e).unwrap()).collect(); @@ -532,7 +533,7 @@ pub fn cover_files( script_coverages, coverage_flags.include, coverage_flags.exclude, - in_npm_pkg_checker.as_ref(), + in_npm_pkg_checker, ); if script_coverages.is_empty() { return Err(anyhow!("No covered files included in the report")); diff --git a/cli/tools/info.rs b/cli/tools/info.rs index 50faeda7d3..8c3b2665c5 100644 --- a/cli/tools/info.rs +++ b/cli/tools/info.rs @@ -32,8 +32,7 @@ use crate::args::InfoFlags; use crate::display; use crate::factory::CliFactory; use crate::graph_util::graph_exit_integrity_errors; -use crate::npm::CliNpmResolver; -use crate::npm::ManagedCliNpmResolver; +use crate::npm::CliManagedNpmResolver; use crate::util::checksum; use crate::util::display::DisplayTreeNode; @@ -138,6 +137,10 @@ pub async fn info( lockfile.write_if_changed()?; } + let maybe_npm_info = npm_resolver + .as_managed() + .map(|r| (r, r.resolution().snapshot())); + if info_flags.json { let mut json_graph = serde_json::json!(graph); if let Some(output) = json_graph.as_object_mut() { @@ -148,11 +151,19 @@ pub async fn info( ); } - add_npm_packages_to_json(&mut json_graph, npm_resolver.as_ref(), npmrc); + add_npm_packages_to_json( + &mut json_graph, + maybe_npm_info.as_ref().map(|(_, s)| s), + npmrc, + ); display::write_json_to_stdout(&json_graph)?; } else { let mut output = String::new(); - GraphDisplayContext::write(&graph, npm_resolver.as_ref(), &mut output)?; + GraphDisplayContext::write( + &graph, + maybe_npm_info.as_ref().map(|(r, s)| (*r, s)), + &mut output, + )?; display::write_to_stdout_ignore_sigpipe(output.as_bytes())?; } } else { @@ -251,15 +262,14 @@ fn print_cache_info( fn add_npm_packages_to_json( json: &mut serde_json::Value, - npm_resolver: &dyn CliNpmResolver, + npm_snapshot: Option<&NpmResolutionSnapshot>, npmrc: &ResolvedNpmRc, ) { - let Some(npm_resolver) = npm_resolver.as_managed() else { + let Some(npm_snapshot) = npm_snapshot else { return; // does not include byonm to deno info's output }; // ideally deno_graph could handle this, but for now we just modify the json here - let snapshot = npm_resolver.snapshot(); let json = json.as_object_mut().unwrap(); let modules = json.get_mut("modules").and_then(|m| m.as_array_mut()); if let Some(modules) = modules { @@ -273,7 +283,7 @@ fn add_npm_packages_to_json( .and_then(|k| k.as_str()) .and_then(|specifier| NpmPackageNvReference::from_str(specifier).ok()) .and_then(|package_ref| { - snapshot + npm_snapshot .resolve_package_from_deno_module(package_ref.nv()) .ok() }); @@ -295,7 +305,8 @@ fn add_npm_packages_to_json( if let Some(specifier) = dep.get("specifier").and_then(|s| s.as_str()) { if let Ok(npm_ref) = NpmPackageReqReference::from_str(specifier) { - if let Ok(pkg) = snapshot.resolve_pkg_from_pkg_req(npm_ref.req()) + if let Ok(pkg) = + npm_snapshot.resolve_pkg_from_pkg_req(npm_ref.req()) { dep.insert( "npmPackage".to_string(), @@ -321,8 +332,9 @@ fn add_npm_packages_to_json( } } - let mut sorted_packages = - snapshot.all_packages_for_every_system().collect::>(); + let mut sorted_packages = npm_snapshot + .all_packages_for_every_system() + .collect::>(); sorted_packages.sort_by(|a, b| a.id.cmp(&b.id)); let mut json_packages = serde_json::Map::with_capacity(sorted_packages.len()); for pkg in sorted_packages { @@ -356,7 +368,7 @@ struct NpmInfo { impl NpmInfo { pub fn build<'a>( graph: &'a ModuleGraph, - npm_resolver: &'a ManagedCliNpmResolver, + npm_resolver: &'a CliManagedNpmResolver, npm_snapshot: &'a NpmResolutionSnapshot, ) -> Self { let mut info = NpmInfo::default(); @@ -382,7 +394,7 @@ impl NpmInfo { fn fill_package_info<'a>( &mut self, package: &NpmResolutionPackage, - npm_resolver: &'a ManagedCliNpmResolver, + npm_resolver: &'a CliManagedNpmResolver, npm_snapshot: &'a NpmResolutionSnapshot, ) { self.packages.insert(package.id.clone(), package.clone()); @@ -419,13 +431,15 @@ struct GraphDisplayContext<'a> { impl<'a> GraphDisplayContext<'a> { pub fn write( graph: &'a ModuleGraph, - npm_resolver: &'a dyn CliNpmResolver, + managed_npm_info: Option<( + &'a CliManagedNpmResolver, + &'a NpmResolutionSnapshot, + )>, writer: &mut TWrite, ) -> Result<(), AnyError> { - let npm_info = match npm_resolver.as_managed() { - Some(npm_resolver) => { - let npm_snapshot = npm_resolver.snapshot(); - NpmInfo::build(graph, npm_resolver, &npm_snapshot) + let npm_info = match managed_npm_info { + Some((npm_resolver, npm_snapshot)) => { + NpmInfo::build(graph, npm_resolver, npm_snapshot) } None => NpmInfo::default(), }; diff --git a/cli/tools/registry/pm/deps.rs b/cli/tools/registry/pm/deps.rs index 1dbb464dbe..3d152490e8 100644 --- a/cli/tools/registry/pm/deps.rs +++ b/cli/tools/registry/pm/deps.rs @@ -451,7 +451,7 @@ pub struct DepManager { // TODO(nathanwhit): probably shouldn't be pub pub(crate) jsr_fetch_resolver: Arc, pub(crate) npm_fetch_resolver: Arc, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, npm_installer: Arc, permissions_container: PermissionsContainer, main_module_graph_container: Arc, @@ -463,7 +463,7 @@ pub struct DepManagerArgs { pub jsr_fetch_resolver: Arc, pub npm_fetch_resolver: Arc, pub npm_installer: Arc, - pub npm_resolver: Arc, + pub npm_resolver: CliNpmResolver, pub permissions_container: PermissionsContainer, pub main_module_graph_container: Arc, pub lockfile: Option>, @@ -551,9 +551,10 @@ impl DepManager { let npm_resolver = self.npm_resolver.as_managed().unwrap(); if self.deps.iter().all(|dep| match dep.kind { - DepKind::Npm => { - npm_resolver.resolve_pkg_id_from_pkg_req(&dep.req).is_ok() - } + DepKind::Npm => npm_resolver + .resolution() + .resolve_pkg_id_from_pkg_req(&dep.req) + .is_ok(), DepKind::Jsr => graph.packages.mappings().contains_key(&dep.req), }) { self.dependencies_resolved.raise(); @@ -630,7 +631,12 @@ impl DepManager { let graph = self.main_module_graph_container.graph(); let mut resolved = Vec::with_capacity(self.deps.len()); - let snapshot = self.npm_resolver.as_managed().unwrap().snapshot(); + let snapshot = self + .npm_resolver + .as_managed() + .unwrap() + .resolution() + .snapshot(); let resolved_npm = snapshot.package_reqs(); let resolved_jsr = graph.packages.mappings(); for dep in &self.deps { diff --git a/cli/tools/task.rs b/cli/tools/task.rs index d6d87dd45e..329195ab46 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -220,7 +220,7 @@ pub async fn execute_script( let task_runner = TaskRunner { task_flags: &task_flags, npm_installer: npm_installer.map(|n| n.as_ref()), - npm_resolver: npm_resolver.as_ref(), + npm_resolver, node_resolver: node_resolver.as_ref(), env_vars, cli_options, @@ -271,7 +271,7 @@ struct RunSingleOptions<'a> { struct TaskRunner<'a> { task_flags: &'a TaskFlags, npm_installer: Option<&'a NpmInstaller>, - npm_resolver: &'a dyn CliNpmResolver, + npm_resolver: &'a CliNpmResolver, node_resolver: &'a CliNodeResolver, env_vars: HashMap, cli_options: &'a CliOptions, diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index b6cf691c38..37d52c6cf2 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -46,7 +46,7 @@ use crate::cache::FastInsecureHasher; use crate::cache::ModuleInfoCache; use crate::node::CliNodeResolver; use crate::npm::CliNpmResolver; -use crate::resolver::CjsTracker; +use crate::resolver::CliCjsTracker; use crate::sys::CliSys; use crate::util::checksum; use crate::util::path::mapped_specifier_for_tsc; @@ -300,13 +300,13 @@ pub fn into_specifier_and_media_type( #[derive(Debug)] pub struct TypeCheckingCjsTracker { - cjs_tracker: Arc, + cjs_tracker: Arc, module_info_cache: Arc, } impl TypeCheckingCjsTracker { pub fn new( - cjs_tracker: Arc, + cjs_tracker: Arc, module_info_cache: Arc, ) -> Self { Self { @@ -358,7 +358,7 @@ impl TypeCheckingCjsTracker { pub struct RequestNpmState { pub cjs_tracker: Arc, pub node_resolver: Arc, - pub npm_resolver: Arc, + pub npm_resolver: CliNpmResolver, } /// A structure representing a request to be sent to the tsc runtime. diff --git a/cli/worker.rs b/cli/worker.rs index d93c6c5f40..45d4b0af70 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -19,6 +19,7 @@ use deno_core::ModuleLoader; use deno_core::PollEventLoopOptions; use deno_core::SharedArrayBufferStore; use deno_error::JsErrorBox; +use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::code_cache; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; use deno_runtime::deno_fs; @@ -151,7 +152,7 @@ struct SharedWorkerState { module_loader_factory: Box, node_resolver: Arc, npm_installer: Option>, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, pkg_json_resolver: Arc, root_cert_store_provider: Arc, root_permissions: PermissionsContainer, @@ -168,18 +169,17 @@ impl SharedWorkerState { pub fn create_node_init_services( &self, node_require_loader: NodeRequireLoaderRc, - ) -> NodeExtInitServices { + ) -> NodeExtInitServices { NodeExtInitServices { node_require_loader, node_resolver: self.node_resolver.clone(), - npm_resolver: self.npm_resolver.clone().into_npm_pkg_folder_resolver(), pkg_json_resolver: self.pkg_json_resolver.clone(), sys: self.sys.clone(), } } pub fn npm_process_state_provider(&self) -> NpmProcessStateProviderRc { - self.npm_resolver.clone().into_process_state_provider() + crate::npm::create_npm_process_state_provider(&self.npm_resolver) } } @@ -427,7 +427,7 @@ impl CliMainWorkerFactory { module_loader_factory: Box, node_resolver: Arc, npm_installer: Option>, - npm_resolver: Arc, + npm_resolver: CliNpmResolver, pkg_json_resolver: Arc, root_cert_store_provider: Arc, root_permissions: PermissionsContainer, @@ -886,7 +886,11 @@ mod tests { ..Default::default() }; - MainWorker::bootstrap_from_options::( + MainWorker::bootstrap_from_options::< + DenoInNpmPackageChecker, + CliNpmResolver, + CliSys, + >( main_module, WorkerServiceOptions { module_loader: Rc::new(FsModuleLoader), diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 731cd3a9c7..325cec6f5b 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -15,8 +15,9 @@ use deno_core::v8; use deno_core::v8::ExternalReference; use deno_error::JsErrorBox; use node_resolver::errors::ClosestPkgJsonError; +use node_resolver::InNpmPackageChecker; use node_resolver::IsBuiltInNodeModuleChecker; -use node_resolver::NpmPackageFolderResolverRc; +use node_resolver::NpmPackageFolderResolver; use node_resolver::PackageJsonResolverRc; use once_cell::sync::Lazy; @@ -185,17 +186,21 @@ fn op_node_build_os() -> String { } #[derive(Clone)] -pub struct NodeExtInitServices { +pub struct NodeExtInitServices< + TInNpmPackageChecker: InNpmPackageChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, + TSys: ExtNodeSys, +> { pub node_require_loader: NodeRequireLoaderRc, - pub node_resolver: NodeResolverRc, - pub npm_resolver: NpmPackageFolderResolverRc, + pub node_resolver: + NodeResolverRc, pub pkg_json_resolver: PackageJsonResolverRc, pub sys: TSys, } deno_core::extension!(deno_node, deps = [ deno_io, deno_fs ], - parameters = [P: NodePermissions, TSys: ExtNodeSys], + parameters = [P: NodePermissions, TInNpmPackageChecker: InNpmPackageChecker, TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: ExtNodeSys], ops = [ ops::blocklist::op_socket_address_parse, ops::blocklist::op_socket_address_get_serialization, @@ -395,13 +400,13 @@ deno_core::extension!(deno_node, ops::require::op_require_init_paths, ops::require::op_require_node_module_paths, ops::require::op_require_proxy_path, - ops::require::op_require_is_deno_dir_package, - ops::require::op_require_resolve_deno_dir, + ops::require::op_require_is_deno_dir_package, + ops::require::op_require_resolve_deno_dir, ops::require::op_require_is_maybe_cjs, ops::require::op_require_is_request_relative, ops::require::op_require_resolve_lookup_paths, ops::require::op_require_try_self_parent_path, - ops::require::op_require_try_self, + ops::require::op_require_try_self, ops::require::op_require_real_path, ops::require::op_require_path_is_absolute, ops::require::op_require_path_dirname, @@ -410,9 +415,9 @@ deno_core::extension!(deno_node, ops::require::op_require_path_basename, ops::require::op_require_read_file

, ops::require::op_require_as_file_path, - ops::require::op_require_resolve_exports, + ops::require::op_require_resolve_exports, ops::require::op_require_read_package_scope, - ops::require::op_require_package_imports_resolve, + ops::require::op_require_package_imports_resolve, ops::require::op_require_break_on_next_statement, ops::util::op_node_guess_handle_type, ops::worker_threads::op_worker_threads_filename, @@ -681,7 +686,7 @@ deno_core::extension!(deno_node, "node:zlib" = "zlib.ts", ], options = { - maybe_init: Option>, + maybe_init: Option>, fs: deno_fs::FileSystemRc, }, state = |state, options| { @@ -691,7 +696,6 @@ deno_core::extension!(deno_node, state.put(init.sys.clone()); state.put(init.node_require_loader.clone()); state.put(init.node_resolver.clone()); - state.put(init.npm_resolver.clone()); state.put(init.pkg_json_resolver.clone()); } }, @@ -833,10 +837,18 @@ pub trait ExtNodeSys: impl ExtNodeSys for sys_traits::impls::RealSys {} -pub type NodeResolver = - node_resolver::NodeResolver; +pub type NodeResolver = + node_resolver::NodeResolver< + TInNpmPackageChecker, + RealIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >; #[allow(clippy::disallowed_types)] -pub type NodeResolverRc = deno_fs::sync::MaybeArc>; +pub type NodeResolverRc = + deno_fs::sync::MaybeArc< + NodeResolver, + >; #[allow(clippy::disallowed_types)] pub fn create_host_defined_options<'s>( diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs index 3135ba1e86..bff0cd79ed 100644 --- a/ext/node/ops/require.rs +++ b/ext/node/ops/require.rs @@ -19,7 +19,9 @@ use deno_path_util::normalize_path; use deno_path_util::url_from_file_path; use deno_path_util::url_to_file_path; use node_resolver::errors::ClosestPkgJsonError; +use node_resolver::InNpmPackageChecker; use node_resolver::NodeResolutionKind; +use node_resolver::NpmPackageFolderResolver; use node_resolver::ResolutionMode; use node_resolver::REQUIRE_CONDITIONS; use sys_traits::FsCanonicalize; @@ -30,7 +32,6 @@ use crate::ExtNodeSys; use crate::NodePermissions; use crate::NodeRequireLoaderRc; use crate::NodeResolverRc; -use crate::NpmPackageFolderResolverRc; use crate::PackageJsonResolverRc; #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] @@ -256,12 +257,20 @@ pub fn op_require_is_request_relative(#[string] request: String) -> bool { #[op2] #[string] -pub fn op_require_resolve_deno_dir( +pub fn op_require_resolve_deno_dir< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TSys: ExtNodeSys + 'static, +>( state: &mut OpState, #[string] request: String, #[string] parent_filename: String, ) -> Result, deno_path_util::PathToUrlError> { - let resolver = state.borrow::(); + let resolver = state.borrow::>(); Ok( resolver @@ -275,11 +284,19 @@ pub fn op_require_resolve_deno_dir( } #[op2(fast)] -pub fn op_require_is_deno_dir_package( +pub fn op_require_is_deno_dir_package< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TSys: ExtNodeSys + 'static, +>( state: &mut OpState, #[string] path: String, ) -> bool { - let resolver = state.borrow::>(); + let resolver = state.borrow::>(); match deno_path_util::url_from_file_path(&PathBuf::from(path)) { Ok(specifier) => resolver.in_npm_package(&specifier), Err(_) => false, @@ -451,6 +468,8 @@ pub fn op_require_try_self_parent_path< #[string] pub fn op_require_try_self< P: NodePermissions + 'static, + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TSys: ExtNodeSys + 'static, >( state: &mut OpState, @@ -493,7 +512,11 @@ pub fn op_require_try_self< let referrer = deno_core::url::Url::from_file_path(&pkg.path).unwrap(); if let Some(exports) = &pkg.exports { - let node_resolver = state.borrow::>(); + let node_resolver = state.borrow::>(); let r = node_resolver.package_exports_resolve( &pkg.path, &expansion, @@ -552,6 +575,8 @@ pub fn op_require_as_file_path(#[string] file_or_url: String) -> String { #[string] pub fn op_require_resolve_exports< P: NodePermissions + 'static, + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TSys: ExtNodeSys + 'static, >( state: &mut OpState, @@ -563,7 +588,11 @@ pub fn op_require_resolve_exports< #[string] parent_path: String, ) -> Result, RequireError> { let sys = state.borrow::(); - let node_resolver = state.borrow::>(); + let node_resolver = state.borrow::>(); let pkg_json_resolver = state.borrow::>(); let modules_path = PathBuf::from(&modules_path_str); @@ -655,6 +684,8 @@ pub fn op_require_read_package_scope< #[string] pub fn op_require_package_imports_resolve< P: NodePermissions + 'static, + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TSys: ExtNodeSys + 'static, >( state: &mut OpState, @@ -672,7 +703,11 @@ pub fn op_require_package_imports_resolve< }; if pkg.imports.is_some() { - let node_resolver = state.borrow::>(); + let node_resolver = state.borrow::>(); let referrer_url = Url::from_file_path(&referrer_filename).unwrap(); let url = node_resolver.package_imports_resolve( &request, diff --git a/resolvers/deno/cjs.rs b/resolvers/deno/cjs.rs index bae645b481..4358b0ced2 100644 --- a/resolvers/deno/cjs.rs +++ b/resolvers/deno/cjs.rs @@ -2,7 +2,7 @@ use deno_media_type::MediaType; use node_resolver::errors::ClosestPkgJsonError; -use node_resolver::InNpmPackageCheckerRc; +use node_resolver::InNpmPackageChecker; use node_resolver::PackageJsonResolverRc; use node_resolver::ResolutionMode; use sys_traits::FsRead; @@ -16,14 +16,16 @@ use crate::sync::MaybeDashMap; /// be CJS or ESM after they're loaded based on their contents. So these /// files will be "maybe CJS" until they're loaded. #[derive(Debug)] -pub struct CjsTracker { - is_cjs_resolver: IsCjsResolver, +pub struct CjsTracker { + is_cjs_resolver: IsCjsResolver, known: MaybeDashMap, } -impl CjsTracker { +impl + CjsTracker +{ pub fn new( - in_npm_pkg_checker: InNpmPackageCheckerRc, + in_npm_pkg_checker: TInNpmPackageChecker, pkg_json_resolver: PackageJsonResolverRc, mode: IsCjsResolutionMode, ) -> Self { @@ -125,15 +127,20 @@ pub enum IsCjsResolutionMode { /// Resolves whether a module is CJS or ESM. #[derive(Debug)] -pub struct IsCjsResolver { - in_npm_pkg_checker: InNpmPackageCheckerRc, +pub struct IsCjsResolver< + TInNpmPackageChecker: InNpmPackageChecker, + TSys: FsRead, +> { + in_npm_pkg_checker: TInNpmPackageChecker, pkg_json_resolver: PackageJsonResolverRc, mode: IsCjsResolutionMode, } -impl IsCjsResolver { +impl + IsCjsResolver +{ pub fn new( - in_npm_pkg_checker: InNpmPackageCheckerRc, + in_npm_pkg_checker: TInNpmPackageChecker, pkg_json_resolver: PackageJsonResolverRc, mode: IsCjsResolutionMode, ) -> Self { diff --git a/resolvers/deno/lib.rs b/resolvers/deno/lib.rs index 12d8effc46..454c7f12e2 100644 --- a/resolvers/deno/lib.rs +++ b/resolvers/deno/lib.rs @@ -19,11 +19,12 @@ use deno_package_json::PackageJsonDepValueParseError; use deno_semver::npm::NpmPackageReqReference; use node_resolver::errors::NodeResolveError; use node_resolver::errors::PackageSubpathResolveError; -use node_resolver::InNpmPackageCheckerRc; +use node_resolver::InNpmPackageChecker; use node_resolver::IsBuiltInNodeModuleChecker; use node_resolver::NodeResolution; use node_resolver::NodeResolutionKind; use node_resolver::NodeResolverRc; +use node_resolver::NpmPackageFolderResolver; use node_resolver::ResolutionMode; use npm::MissingPackageNodeModulesFolderError; use npm::NodeModulesOutOfDateError; @@ -101,22 +102,42 @@ pub enum DenoResolveErrorKind { #[derive(Debug)] pub struct NodeAndNpmReqResolver< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { - pub node_resolver: NodeResolverRc, - pub npm_req_resolver: NpmReqResolverRc, + pub node_resolver: NodeResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + pub npm_req_resolver: NpmReqResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, } pub struct DenoResolverOptions< 'a, + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSloppyImportResolverFs: SloppyImportResolverFs, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { - pub in_npm_pkg_checker: InNpmPackageCheckerRc, - pub node_and_req_resolver: - Option>, + pub in_npm_pkg_checker: TInNpmPackageChecker, + pub node_and_req_resolver: Option< + NodeAndNpmReqResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + >, pub sloppy_imports_resolver: Option>, pub workspace_resolver: WorkspaceResolverRc, @@ -131,13 +152,21 @@ pub struct DenoResolverOptions< /// import map, JSX settings. #[derive(Debug)] pub struct DenoResolver< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSloppyImportResolverFs: SloppyImportResolverFs, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { - in_npm_pkg_checker: InNpmPackageCheckerRc, - node_and_npm_resolver: - Option>, + in_npm_pkg_checker: TInNpmPackageChecker, + node_and_npm_resolver: Option< + NodeAndNpmReqResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + >, sloppy_imports_resolver: Option>, workspace_resolver: WorkspaceResolverRc, @@ -146,14 +175,25 @@ pub struct DenoResolver< } impl< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSloppyImportResolverFs: SloppyImportResolverFs, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, - > DenoResolver + > + DenoResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSloppyImportResolverFs, + TSys, + > { pub fn new( options: DenoResolverOptions< + TInNpmPackageChecker, TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, TSloppyImportResolverFs, TSys, >, diff --git a/resolvers/deno/npm/byonm.rs b/resolvers/deno/npm/byonm.rs index bf25ba5646..4f72692f8b 100644 --- a/resolvers/deno/npm/byonm.rs +++ b/resolvers/deno/npm/byonm.rs @@ -27,8 +27,6 @@ use thiserror::Error; use url::Url; use super::local::normalize_pkg_name_for_node_modules_deno_folder; -use crate::sync::MaybeSend; -use crate::sync::MaybeSync; #[derive(Debug, Error, deno_error::JsError)] pub enum ByonmResolvePkgFolderFromDenoReqError { @@ -89,7 +87,7 @@ impl } } - pub fn root_node_modules_dir(&self) -> Option<&Path> { + pub fn root_node_modules_path(&self) -> Option<&Path> { self.root_node_modules_dir.as_deref() } @@ -377,15 +375,8 @@ impl } } -impl< - TSys: FsCanonicalize - + FsMetadata - + FsRead - + FsReadDir - + MaybeSend - + MaybeSync - + std::fmt::Debug, - > NpmPackageFolderResolver for ByonmNpmResolver +impl + NpmPackageFolderResolver for ByonmNpmResolver { fn resolve_package_folder_from_package( &self, @@ -438,7 +429,7 @@ impl< } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ByonmInNpmPackageChecker; impl InNpmPackageChecker for ByonmInNpmPackageChecker { diff --git a/resolvers/deno/npm/managed/common.rs b/resolvers/deno/npm/managed/common.rs index 6569a4594f..a92fe226dd 100644 --- a/resolvers/deno/npm/managed/common.rs +++ b/resolvers/deno/npm/managed/common.rs @@ -6,26 +6,69 @@ use std::path::PathBuf; use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageId; use node_resolver::NpmPackageFolderResolver; +use sys_traits::FsCanonicalize; +use sys_traits::FsMetadata; use url::Url; -use crate::sync::MaybeSend; -use crate::sync::MaybeSync; +#[derive(Debug)] +pub enum NpmPackageFsResolver { + Local(super::local::LocalNpmPackageResolver), + Global(super::global::GlobalNpmPackageResolver), +} -#[allow(clippy::disallowed_types)] -pub type NpmPackageFsResolverRc = - crate::sync::MaybeArc; +impl NpmPackageFsResolver { + /// The local node_modules folder (only for the local resolver). + pub fn node_modules_path(&self) -> Option<&Path> { + match self { + NpmPackageFsResolver::Local(resolver) => resolver.node_modules_path(), + NpmPackageFsResolver::Global(_) => None, + } + } -/// Part of the resolution that interacts with the file system. -pub trait NpmPackageFsResolver: - NpmPackageFolderResolver + MaybeSend + MaybeSync -{ - /// The local node_modules folder if it is applicable to the implementation. - fn node_modules_path(&self) -> Option<&Path>; + pub fn maybe_package_folder( + &self, + package_id: &NpmPackageId, + ) -> Option { + match self { + NpmPackageFsResolver::Local(resolver) => { + resolver.maybe_package_folder(package_id) + } + NpmPackageFsResolver::Global(resolver) => { + resolver.maybe_package_folder(package_id) + } + } + } - fn maybe_package_folder(&self, package_id: &NpmPackageId) -> Option; - - fn resolve_package_cache_folder_id_from_specifier( + pub fn resolve_package_cache_folder_id_from_specifier( &self, specifier: &Url, - ) -> Result, std::io::Error>; + ) -> Result, std::io::Error> { + match self { + NpmPackageFsResolver::Local(resolver) => { + resolver.resolve_package_cache_folder_id_from_specifier(specifier) + } + NpmPackageFsResolver::Global(resolver) => { + resolver.resolve_package_cache_folder_id_from_specifier(specifier) + } + } + } +} + +impl NpmPackageFolderResolver + for NpmPackageFsResolver +{ + fn resolve_package_folder_from_package( + &self, + specifier: &str, + referrer: &Url, + ) -> Result { + match self { + NpmPackageFsResolver::Local(r) => { + r.resolve_package_folder_from_package(specifier, referrer) + } + NpmPackageFsResolver::Global(r) => { + r.resolve_package_folder_from_package(specifier, referrer) + } + } + } } diff --git a/resolvers/deno/npm/managed/global.rs b/resolvers/deno/npm/managed/global.rs index d16234d8f4..271851c79c 100644 --- a/resolvers/deno/npm/managed/global.rs +++ b/resolvers/deno/npm/managed/global.rs @@ -2,7 +2,6 @@ //! Code for global npm cache resolution. -use std::path::Path; use std::path::PathBuf; use deno_npm::NpmPackageCacheFolderId; @@ -18,7 +17,6 @@ use url::Url; use super::resolution::NpmResolutionCellRc; use super::NpmCacheDirRc; -use super::NpmPackageFsResolver; use crate::ResolvedNpmRcRc; /// Resolves packages from the global npm cache. @@ -42,6 +40,26 @@ impl GlobalNpmPackageResolver { } } + pub fn maybe_package_folder(&self, id: &NpmPackageId) -> Option { + let folder_copy_index = self + .resolution + .resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?; + let registry_url = self.npm_rc.get_registry_url(&id.nv.name); + Some(self.cache.package_folder_for_id( + &id.nv.name, + &id.nv.version.to_string(), + folder_copy_index, + registry_url, + )) + } + + pub fn resolve_package_cache_folder_id_from_specifier( + &self, + specifier: &Url, + ) -> Result, std::io::Error> { + Ok(self.resolve_package_cache_folder_id_from_specifier_inner(specifier)) + } + fn resolve_package_cache_folder_id_from_specifier_inner( &self, specifier: &Url, @@ -121,29 +139,3 @@ impl NpmPackageFolderResolver for GlobalNpmPackageResolver { } } } - -impl NpmPackageFsResolver for GlobalNpmPackageResolver { - fn node_modules_path(&self) -> Option<&Path> { - None - } - - fn maybe_package_folder(&self, id: &NpmPackageId) -> Option { - let folder_copy_index = self - .resolution - .resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?; - let registry_url = self.npm_rc.get_registry_url(&id.nv.name); - Some(self.cache.package_folder_for_id( - &id.nv.name, - &id.nv.version.to_string(), - folder_copy_index, - registry_url, - )) - } - - fn resolve_package_cache_folder_id_from_specifier( - &self, - specifier: &Url, - ) -> Result, std::io::Error> { - Ok(self.resolve_package_cache_folder_id_from_specifier_inner(specifier)) - } -} diff --git a/resolvers/deno/npm/managed/local.rs b/resolvers/deno/npm/managed/local.rs index 72b0b0d451..e453101df4 100644 --- a/resolvers/deno/npm/managed/local.rs +++ b/resolvers/deno/npm/managed/local.rs @@ -20,27 +20,20 @@ use sys_traits::FsMetadata; use url::Url; use super::resolution::NpmResolutionCellRc; -use super::NpmPackageFsResolver; use crate::npm::local::get_package_folder_id_folder_name_from_parts; use crate::npm::local::get_package_folder_id_from_folder_name; -use crate::sync::MaybeSend; -use crate::sync::MaybeSync; /// Resolver that creates a local node_modules directory /// and resolves packages from it. #[derive(Debug)] -pub struct LocalNpmPackageResolver< - TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync, -> { +pub struct LocalNpmPackageResolver { resolution: NpmResolutionCellRc, sys: TSys, root_node_modules_path: PathBuf, root_node_modules_url: Url, } -impl - LocalNpmPackageResolver -{ +impl LocalNpmPackageResolver { #[allow(clippy::too_many_arguments)] pub fn new( resolution: NpmResolutionCellRc, @@ -56,6 +49,55 @@ impl } } + pub fn node_modules_path(&self) -> Option<&Path> { + Some(self.root_node_modules_path.as_ref()) + } + + pub fn maybe_package_folder(&self, id: &NpmPackageId) -> Option { + let folder_copy_index = self + .resolution + .resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?; + // package is stored at: + // node_modules/.deno//node_modules/ + Some( + self + .root_node_modules_path + .join(".deno") + .join(get_package_folder_id_folder_name_from_parts( + &id.nv, + folder_copy_index, + )) + .join("node_modules") + .join(&id.nv.name), + ) + } + + pub fn resolve_package_cache_folder_id_from_specifier( + &self, + specifier: &Url, + ) -> Result, std::io::Error> { + let Some(folder_path) = + self.resolve_package_folder_from_specifier(specifier)? + else { + return Ok(None); + }; + // ex. project/node_modules/.deno/preact@10.24.3/node_modules/preact/ + let Some(node_modules_ancestor) = folder_path + .ancestors() + .find(|ancestor| ancestor.ends_with("node_modules")) + else { + return Ok(None); + }; + let Some(folder_name) = + node_modules_ancestor.parent().and_then(|p| p.file_name()) + else { + return Ok(None); + }; + Ok(get_package_folder_id_from_folder_name( + &folder_name.to_string_lossy(), + )) + } + fn resolve_package_root(&self, path: &Path) -> PathBuf { let mut last_found = path; loop { @@ -101,9 +143,8 @@ impl } } -impl< - TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync + std::fmt::Debug, - > NpmPackageFolderResolver for LocalNpmPackageResolver +impl NpmPackageFolderResolver + for LocalNpmPackageResolver { fn resolve_package_folder_from_package( &self, @@ -163,60 +204,6 @@ impl< } } -impl< - TSys: FsCanonicalize + FsMetadata + MaybeSend + MaybeSync + std::fmt::Debug, - > NpmPackageFsResolver for LocalNpmPackageResolver -{ - fn node_modules_path(&self) -> Option<&Path> { - Some(self.root_node_modules_path.as_ref()) - } - - fn maybe_package_folder(&self, id: &NpmPackageId) -> Option { - let folder_copy_index = self - .resolution - .resolve_pkg_cache_folder_copy_index_from_pkg_id(id)?; - // package is stored at: - // node_modules/.deno//node_modules/ - Some( - self - .root_node_modules_path - .join(".deno") - .join(get_package_folder_id_folder_name_from_parts( - &id.nv, - folder_copy_index, - )) - .join("node_modules") - .join(&id.nv.name), - ) - } - - fn resolve_package_cache_folder_id_from_specifier( - &self, - specifier: &Url, - ) -> Result, std::io::Error> { - let Some(folder_path) = - self.resolve_package_folder_from_specifier(specifier)? - else { - return Ok(None); - }; - // ex. project/node_modules/.deno/preact@10.24.3/node_modules/preact/ - let Some(node_modules_ancestor) = folder_path - .ancestors() - .find(|ancestor| ancestor.ends_with("node_modules")) - else { - return Ok(None); - }; - let Some(folder_name) = - node_modules_ancestor.parent().and_then(|p| p.file_name()) - else { - return Ok(None); - }; - Ok(get_package_folder_id_from_folder_name( - &folder_name.to_string_lossy(), - )) - } -} - fn join_package_name(path: &Path, package_name: &str) -> PathBuf { let mut path = path.to_path_buf(); // ensure backslashes are used on windows diff --git a/resolvers/deno/npm/managed/mod.rs b/resolvers/deno/npm/managed/mod.rs index 62147b2ac3..291e299bc8 100644 --- a/resolvers/deno/npm/managed/mod.rs +++ b/resolvers/deno/npm/managed/mod.rs @@ -13,6 +13,7 @@ use deno_npm::resolution::PackageNvNotFoundError; use deno_npm::resolution::PackageReqNotFoundError; use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageId; +use deno_npm::NpmSystemInfo; use deno_path_util::fs::canonicalize_path_maybe_not_exists; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; @@ -23,14 +24,10 @@ use sys_traits::FsMetadata; use url::Url; use self::common::NpmPackageFsResolver; -use self::common::NpmPackageFsResolverRc; use self::global::GlobalNpmPackageResolver; use self::local::LocalNpmPackageResolver; pub use self::resolution::NpmResolutionCell; pub use self::resolution::NpmResolutionCellRc; -use crate::sync::new_rc; -use crate::sync::MaybeSend; -use crate::sync::MaybeSync; use crate::NpmCacheDirRc; use crate::ResolvedNpmRcRc; @@ -89,58 +86,84 @@ pub enum ResolvePkgIdFromSpecifierError { NotFound(#[from] PackageCacheFolderIdNotFoundError), } +pub struct ManagedNpmResolverCreateOptions< + TSys: FsCanonicalize + FsMetadata + Clone, +> { + pub npm_cache_dir: NpmCacheDirRc, + pub sys: TSys, + pub maybe_node_modules_path: Option, + pub npm_system_info: NpmSystemInfo, + pub npmrc: ResolvedNpmRcRc, + pub npm_resolution: NpmResolutionCellRc, +} + #[allow(clippy::disallowed_types)] pub type ManagedNpmResolverRc = crate::sync::MaybeArc>; #[derive(Debug)] -pub struct ManagedNpmResolver { - fs_resolver: NpmPackageFsResolverRc, +pub struct ManagedNpmResolver { + fs_resolver: NpmPackageFsResolver, + npm_cache_dir: NpmCacheDirRc, resolution: NpmResolutionCellRc, sys: TSys, } -impl ManagedNpmResolver { - pub fn new< - TCreateSys: FsCanonicalize - + FsMetadata - + std::fmt::Debug - + MaybeSend - + MaybeSync - + Clone - + 'static, - >( - npm_cache_dir: &NpmCacheDirRc, - npm_rc: &ResolvedNpmRcRc, - resolution: NpmResolutionCellRc, - sys: TCreateSys, - maybe_node_modules_path: Option, +impl ManagedNpmResolver { + pub fn new( + options: ManagedNpmResolverCreateOptions, ) -> ManagedNpmResolver { - let fs_resolver: NpmPackageFsResolverRc = match maybe_node_modules_path { - Some(node_modules_folder) => new_rc(LocalNpmPackageResolver::new( - resolution.clone(), - sys.clone(), - node_modules_folder, - )), - None => new_rc(GlobalNpmPackageResolver::new( - npm_cache_dir.clone(), - npm_rc.clone(), - resolution.clone(), + let fs_resolver = match options.maybe_node_modules_path { + Some(node_modules_folder) => { + NpmPackageFsResolver::Local(LocalNpmPackageResolver::new( + options.npm_resolution.clone(), + options.sys.clone(), + node_modules_folder, + )) + } + None => NpmPackageFsResolver::Global(GlobalNpmPackageResolver::new( + options.npm_cache_dir.clone(), + options.npmrc.clone(), + options.npm_resolution.clone(), )), }; ManagedNpmResolver { fs_resolver, - sys, - resolution, + npm_cache_dir: options.npm_cache_dir, + sys: options.sys, + resolution: options.npm_resolution, } } #[inline] - pub fn node_modules_path(&self) -> Option<&Path> { + pub fn root_node_modules_path(&self) -> Option<&Path> { self.fs_resolver.node_modules_path() } + pub fn global_cache_root_path(&self) -> &Path { + self.npm_cache_dir.root_dir() + } + + pub fn global_cache_root_url(&self) -> &Url { + self.npm_cache_dir.root_dir_url() + } + + pub fn resolution(&self) -> &NpmResolutionCell { + self.resolution.as_ref() + } + + /// Checks if the provided package req's folder is cached. + pub fn is_pkg_req_folder_cached(&self, req: &PackageReq) -> bool { + self + .resolution + .resolve_pkg_id_from_pkg_req(req) + .ok() + .and_then(|id| self.resolve_pkg_folder_from_pkg_id(&id).ok()) + .map(|folder| self.sys.fs_exists_no_err(folder)) + .unwrap_or(false) + } + pub fn resolve_pkg_folder_from_pkg_id( &self, package_id: &NpmPackageId, @@ -213,8 +236,8 @@ impl ManagedNpmResolver { } } -impl - NpmPackageFolderResolver for ManagedNpmResolver +impl NpmPackageFolderResolver + for ManagedNpmResolver { fn resolve_package_folder_from_package( &self, @@ -234,7 +257,7 @@ impl } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ManagedInNpmPackageChecker { root_dir: Url, } diff --git a/resolvers/deno/npm/managed/resolution.rs b/resolvers/deno/npm/managed/resolution.rs index 08dabf5a76..faa0d43664 100644 --- a/resolvers/deno/npm/managed/resolution.rs +++ b/resolvers/deno/npm/managed/resolution.rs @@ -1,7 +1,5 @@ // Copyright 2018-2025 the Deno authors. MIT license. -use std::collections::HashMap; - use deno_npm::resolution::NpmPackagesPartitioned; use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::resolution::PackageCacheFolderIdNotFoundError; @@ -124,8 +122,23 @@ impl NpmResolutionCell { .map(|pkg| pkg.id.clone()) } - pub fn package_reqs(&self) -> HashMap { - self.snapshot.read().package_reqs().clone() + pub fn package_reqs(&self) -> Vec<(PackageReq, PackageNv)> { + self + .snapshot + .read() + .package_reqs() + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect() + } + + pub fn top_level_packages(&self) -> Vec { + self + .snapshot + .read() + .top_level_packages() + .cloned() + .collect::>() } pub fn all_system_packages( diff --git a/resolvers/deno/npm/mod.rs b/resolvers/deno/npm/mod.rs index 26b156d29d..fed3d388bf 100644 --- a/resolvers/deno/npm/mod.rs +++ b/resolvers/deno/npm/mod.rs @@ -1,6 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::fmt::Debug; +use std::path::Path; use std::path::PathBuf; use boxed_error::Boxed; @@ -14,11 +15,12 @@ use node_resolver::errors::PackageFolderResolveIoError; use node_resolver::errors::PackageNotFoundError; use node_resolver::errors::PackageResolveErrorKind; use node_resolver::errors::PackageSubpathResolveError; -use node_resolver::InNpmPackageCheckerRc; +use node_resolver::InNpmPackageChecker; use node_resolver::IsBuiltInNodeModuleChecker; use node_resolver::NodeResolution; use node_resolver::NodeResolutionKind; use node_resolver::NodeResolverRc; +use node_resolver::NpmPackageFolderResolver; use node_resolver::ResolutionMode; use sys_traits::FsCanonicalize; use sys_traits::FsMetadata; @@ -35,10 +37,14 @@ pub use self::byonm::ByonmResolvePkgFolderFromDenoReqError; pub use self::local::get_package_folder_id_folder_name; pub use self::local::normalize_pkg_name_for_node_modules_deno_folder; use self::managed::create_managed_in_npm_pkg_checker; +use self::managed::ManagedInNpmPackageChecker; use self::managed::ManagedInNpmPkgCheckerCreateOptions; pub use self::managed::ManagedNpmResolver; +use self::managed::ManagedNpmResolverCreateOptions; pub use self::managed::ManagedNpmResolverRc; use crate::sync::new_rc; +use crate::sync::MaybeSend; +use crate::sync::MaybeSync; mod byonm; mod local; @@ -49,14 +55,33 @@ pub enum CreateInNpmPkgCheckerOptions<'a> { Byonm, } -pub fn create_in_npm_pkg_checker( - options: CreateInNpmPkgCheckerOptions, -) -> InNpmPackageCheckerRc { - match options { - CreateInNpmPkgCheckerOptions::Managed(options) => { - new_rc(create_managed_in_npm_pkg_checker(options)) +#[derive(Debug, Clone)] +pub enum DenoInNpmPackageChecker { + Managed(ManagedInNpmPackageChecker), + Byonm(ByonmInNpmPackageChecker), +} + +impl DenoInNpmPackageChecker { + pub fn new(options: CreateInNpmPkgCheckerOptions) -> Self { + match options { + CreateInNpmPkgCheckerOptions::Managed(options) => { + DenoInNpmPackageChecker::Managed(create_managed_in_npm_pkg_checker( + options, + )) + } + CreateInNpmPkgCheckerOptions::Byonm => { + DenoInNpmPackageChecker::Byonm(ByonmInNpmPackageChecker) + } + } + } +} + +impl InNpmPackageChecker for DenoInNpmPackageChecker { + fn in_npm_package(&self, specifier: &Url) -> bool { + match self { + DenoInNpmPackageChecker::Managed(c) => c.in_npm_package(specifier), + DenoInNpmPackageChecker::Byonm(c) => c.in_npm_package(specifier), } - CreateInNpmPkgCheckerOptions::Byonm => new_rc(ByonmInNpmPackageChecker), } } @@ -115,10 +140,22 @@ pub enum ResolvePkgFolderFromDenoReqError { Byonm(byonm::ByonmResolvePkgFolderFromDenoReqError), } -#[derive(Debug, Clone)] -pub enum ByonmOrManagedNpmResolver< - TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, +pub enum NpmResolverCreateOptions< + TSys: FsRead + + FsCanonicalize + + FsMetadata + + std::fmt::Debug + + MaybeSend + + MaybeSync + + Clone + + 'static, > { + Managed(ManagedNpmResolverCreateOptions), + Byonm(ByonmNpmResolverCreateOptions), +} + +#[derive(Debug, Clone)] +pub enum NpmResolver { /// The resolver when "bring your own node_modules" is enabled where Deno /// does not setup the node_modules directories automatically, but instead /// uses what already exists on the file system. @@ -126,57 +163,158 @@ pub enum ByonmOrManagedNpmResolver< Managed(ManagedNpmResolverRc), } -impl - ByonmOrManagedNpmResolver -{ +impl NpmResolver { + pub fn new< + TCreateSys: FsCanonicalize + + FsMetadata + + FsRead + + FsReadDir + + std::fmt::Debug + + MaybeSend + + MaybeSync + + Clone + + 'static, + >( + options: NpmResolverCreateOptions, + ) -> NpmResolver { + match options { + NpmResolverCreateOptions::Managed(options) => { + NpmResolver::Managed(new_rc(ManagedNpmResolver::::new::< + TCreateSys, + >(options))) + } + NpmResolverCreateOptions::Byonm(options) => { + NpmResolver::Byonm(new_rc(ByonmNpmResolver::new(options))) + } + } + } + + pub fn is_byonm(&self) -> bool { + matches!(self, NpmResolver::Byonm(_)) + } + + pub fn is_managed(&self) -> bool { + matches!(self, NpmResolver::Managed(_)) + } + + pub fn as_managed(&self) -> Option<&ManagedNpmResolver> { + match self { + NpmResolver::Managed(resolver) => Some(resolver), + NpmResolver::Byonm(_) => None, + } + } + + pub fn root_node_modules_path(&self) -> Option<&Path> { + match self { + NpmResolver::Byonm(resolver) => resolver.root_node_modules_path(), + NpmResolver::Managed(resolver) => resolver.root_node_modules_path(), + } + } + pub fn resolve_pkg_folder_from_deno_module_req( &self, req: &PackageReq, referrer: &Url, ) -> Result { match self { - ByonmOrManagedNpmResolver::Byonm(byonm_resolver) => byonm_resolver + NpmResolver::Byonm(byonm_resolver) => byonm_resolver .resolve_pkg_folder_from_deno_module_req(req, referrer) .map_err(ResolvePkgFolderFromDenoReqError::Byonm), - ByonmOrManagedNpmResolver::Managed(managed_resolver) => managed_resolver + NpmResolver::Managed(managed_resolver) => managed_resolver .resolve_pkg_folder_from_deno_module_req(req, referrer) .map_err(ResolvePkgFolderFromDenoReqError::Managed), } } } +impl + NpmPackageFolderResolver for NpmResolver +{ + fn resolve_package_folder_from_package( + &self, + specifier: &str, + referrer: &Url, + ) -> Result { + match self { + NpmResolver::Byonm(byonm_resolver) => { + byonm_resolver.resolve_package_folder_from_package(specifier, referrer) + } + NpmResolver::Managed(managed_resolver) => managed_resolver + .resolve_package_folder_from_package(specifier, referrer), + } + } +} + pub struct NpmReqResolverOptions< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { - pub in_npm_pkg_checker: InNpmPackageCheckerRc, - pub node_resolver: NodeResolverRc, - pub npm_resolver: ByonmOrManagedNpmResolver, + pub in_npm_pkg_checker: TInNpmPackageChecker, + pub node_resolver: NodeResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + pub npm_resolver: NpmResolver, pub sys: TSys, } #[allow(clippy::disallowed_types)] -pub type NpmReqResolverRc = - crate::sync::MaybeArc>; +pub type NpmReqResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, +> = crate::sync::MaybeArc< + NpmReqResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, +>; #[derive(Debug)] pub struct NpmReqResolver< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, > { sys: TSys, - in_npm_pkg_checker: InNpmPackageCheckerRc, - node_resolver: NodeResolverRc, - npm_resolver: ByonmOrManagedNpmResolver, + in_npm_pkg_checker: TInNpmPackageChecker, + node_resolver: NodeResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + npm_resolver: NpmResolver, } impl< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead + FsReadDir, - > NpmReqResolver + > + NpmReqResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + > { pub fn new( - options: NpmReqResolverOptions, + options: NpmReqResolverOptions< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, ) -> Self { Self { sys: options.sys, @@ -224,7 +362,7 @@ impl< match resolution_result { Ok(url) => Ok(url), Err(err) => { - if matches!(self.npm_resolver, ByonmOrManagedNpmResolver::Byonm(_)) { + if matches!(self.npm_resolver, NpmResolver::Byonm(_)) { let package_json_path = package_folder.join("package.json"); if !self.sys.fs_exists_no_err(&package_json_path) { return Err( @@ -292,9 +430,8 @@ impl< .into_box(), ); } - if let ByonmOrManagedNpmResolver::Byonm( - byonm_npm_resolver, - ) = &self.npm_resolver + if let NpmResolver::Byonm(byonm_npm_resolver) = + &self.npm_resolver { if byonm_npm_resolver .find_ancestor_package_json_with_dep( diff --git a/resolvers/node/analyze.rs b/resolvers/node/analyze.rs index a6ba3927aa..e144e2b8fb 100644 --- a/resolvers/node/analyze.rs +++ b/resolvers/node/analyze.rs @@ -20,11 +20,11 @@ use sys_traits::FsMetadata; use sys_traits::FsRead; use url::Url; -use crate::npm::InNpmPackageCheckerRc; use crate::resolution::NodeResolverRc; +use crate::InNpmPackageChecker; use crate::IsBuiltInNodeModuleChecker; use crate::NodeResolutionKind; -use crate::NpmPackageFolderResolverRc; +use crate::NpmPackageFolderResolver; use crate::PackageJsonResolverRc; use crate::PathClean; use crate::ResolutionMode; @@ -62,28 +62,49 @@ pub trait CjsCodeAnalyzer { pub struct NodeCodeTranslator< TCjsCodeAnalyzer: CjsCodeAnalyzer, + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead, > { cjs_code_analyzer: TCjsCodeAnalyzer, - in_npm_pkg_checker: InNpmPackageCheckerRc, - node_resolver: NodeResolverRc, - npm_resolver: NpmPackageFolderResolverRc, + in_npm_pkg_checker: TInNpmPackageChecker, + node_resolver: NodeResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + npm_resolver: TNpmPackageFolderResolver, pkg_json_resolver: PackageJsonResolverRc, sys: TSys, } impl< TCjsCodeAnalyzer: CjsCodeAnalyzer, + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead, - > NodeCodeTranslator + > + NodeCodeTranslator< + TCjsCodeAnalyzer, + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + > { pub fn new( cjs_code_analyzer: TCjsCodeAnalyzer, - in_npm_pkg_checker: InNpmPackageCheckerRc, - node_resolver: NodeResolverRc, - npm_resolver: NpmPackageFolderResolverRc, + in_npm_pkg_checker: TInNpmPackageChecker, + node_resolver: NodeResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, + npm_resolver: TNpmPackageFolderResolver, pkg_json_resolver: PackageJsonResolverRc, sys: TSys, ) -> Self { diff --git a/resolvers/node/lib.rs b/resolvers/node/lib.rs index faee4f1645..c0e6383237 100644 --- a/resolvers/node/lib.rs +++ b/resolvers/node/lib.rs @@ -14,9 +14,7 @@ mod sync; pub use deno_package_json::PackageJson; pub use npm::InNpmPackageChecker; -pub use npm::InNpmPackageCheckerRc; pub use npm::NpmPackageFolderResolver; -pub use npm::NpmPackageFolderResolverRc; pub use package_json::PackageJsonResolver; pub use package_json::PackageJsonResolverRc; pub use package_json::PackageJsonThreadLocalCache; diff --git a/resolvers/node/npm.rs b/resolvers/node/npm.rs index f799d6ddee..bb3de2a7f5 100644 --- a/resolvers/node/npm.rs +++ b/resolvers/node/npm.rs @@ -9,16 +9,8 @@ use url::Url; use crate::errors; use crate::path::PathClean; -use crate::sync::MaybeSend; -use crate::sync::MaybeSync; -#[allow(clippy::disallowed_types)] -pub type NpmPackageFolderResolverRc = - crate::sync::MaybeArc; - -pub trait NpmPackageFolderResolver: - std::fmt::Debug + MaybeSend + MaybeSync -{ +pub trait NpmPackageFolderResolver { /// Resolves an npm package folder path from the specified referrer. fn resolve_package_folder_from_package( &self, @@ -27,11 +19,8 @@ pub trait NpmPackageFolderResolver: ) -> Result; } -#[allow(clippy::disallowed_types)] -pub type InNpmPackageCheckerRc = crate::sync::MaybeArc; - /// Checks if a provided specifier is in an npm package. -pub trait InNpmPackageChecker: std::fmt::Debug + MaybeSend + MaybeSync { +pub trait InNpmPackageChecker { fn in_npm_package(&self, specifier: &Url) -> bool; fn in_npm_package_at_dir_path(&self, path: &Path) -> bool { diff --git a/resolvers/node/resolution.rs b/resolvers/node/resolution.rs index a60a6bec9e..9ea5e17e41 100644 --- a/resolvers/node/resolution.rs +++ b/resolvers/node/resolution.rs @@ -46,8 +46,8 @@ use crate::errors::TypesNotFoundError; use crate::errors::TypesNotFoundErrorData; use crate::errors::UnsupportedDirImportError; use crate::errors::UnsupportedEsmUrlSchemeError; -use crate::npm::InNpmPackageCheckerRc; -use crate::NpmPackageFolderResolverRc; +use crate::InNpmPackageChecker; +use crate::NpmPackageFolderResolver; use crate::PackageJsonResolverRc; use crate::PathClean; @@ -137,31 +137,52 @@ pub trait IsBuiltInNodeModuleChecker: std::fmt::Debug { } #[allow(clippy::disallowed_types)] -pub type NodeResolverRc = - crate::sync::MaybeArc>; +pub type NodeResolverRc< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, +> = crate::sync::MaybeArc< + NodeResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + >, +>; #[derive(Debug)] pub struct NodeResolver< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead, > { - in_npm_pkg_checker: InNpmPackageCheckerRc, + in_npm_pkg_checker: TInNpmPackageChecker, is_built_in_node_module_checker: TIsBuiltInNodeModuleChecker, - npm_pkg_folder_resolver: NpmPackageFolderResolverRc, + npm_pkg_folder_resolver: TNpmPackageFolderResolver, pkg_json_resolver: PackageJsonResolverRc, sys: TSys, conditions_from_resolution_mode: ConditionsFromResolutionMode, } impl< + TInNpmPackageChecker: InNpmPackageChecker, TIsBuiltInNodeModuleChecker: IsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, TSys: FsCanonicalize + FsMetadata + FsRead, - > NodeResolver + > + NodeResolver< + TInNpmPackageChecker, + TIsBuiltInNodeModuleChecker, + TNpmPackageFolderResolver, + TSys, + > { pub fn new( - in_npm_pkg_checker: InNpmPackageCheckerRc, + in_npm_pkg_checker: TInNpmPackageChecker, is_built_in_node_module_checker: TIsBuiltInNodeModuleChecker, - npm_pkg_folder_resolver: NpmPackageFolderResolverRc, + npm_pkg_folder_resolver: TNpmPackageFolderResolver, pkg_json_resolver: PackageJsonResolverRc, sys: TSys, conditions_from_resolution_mode: ConditionsFromResolutionMode, @@ -444,6 +465,17 @@ impl< Ok(url) } + /// Resolves an npm package folder path from the specified referrer. + pub fn resolve_package_folder_from_package( + &self, + specifier: &str, + referrer: &Url, + ) -> Result { + self + .npm_pkg_folder_resolver + .resolve_package_folder_from_package(specifier, referrer) + } + /// Checks if the resolved file has a corresponding declaration file. fn path_to_declaration_url( &self, diff --git a/resolvers/node/sync.rs b/resolvers/node/sync.rs index 8cf06932ac..218253b453 100644 --- a/resolvers/node/sync.rs +++ b/resolvers/node/sync.rs @@ -6,17 +6,10 @@ pub use inner::*; mod inner { #![allow(clippy::disallowed_types)] - pub use core::marker::Send as MaybeSend; - pub use core::marker::Sync as MaybeSync; pub use std::sync::Arc as MaybeArc; } #[cfg(not(feature = "sync"))] mod inner { pub use std::rc::Rc as MaybeArc; - - pub trait MaybeSync {} - impl MaybeSync for T where T: ?Sized {} - pub trait MaybeSend {} - impl MaybeSend for T where T: ?Sized {} } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 5ecd911e8a..f59325962f 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -91,6 +91,7 @@ deno_net.workspace = true deno_node.workspace = true deno_path_util.workspace = true deno_permissions.workspace = true +deno_resolver.workspace = true deno_telemetry.workspace = true deno_terminal.workspace = true deno_tls.workspace = true diff --git a/runtime/examples/extension/main.rs b/runtime/examples/extension/main.rs index 9f0eb63b01..e1538b8b75 100644 --- a/runtime/examples/extension/main.rs +++ b/runtime/examples/extension/main.rs @@ -12,6 +12,8 @@ use deno_core::op2; use deno_core::FsModuleLoader; use deno_core::ModuleSpecifier; use deno_fs::RealFs; +use deno_resolver::npm::DenoInNpmPackageChecker; +use deno_resolver::npm::NpmResolver; use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::permissions::RuntimePermissionDescriptorParser; use deno_runtime::worker::MainWorker; @@ -42,7 +44,11 @@ async fn main() -> Result<(), AnyError> { ); let mut worker = MainWorker::bootstrap_from_options( main_module.clone(), - WorkerServiceOptions:: { + WorkerServiceOptions::< + DenoInNpmPackageChecker, + NpmResolver, + sys_traits::impls::RealSys, + > { module_loader: Rc::new(FsModuleLoader), permissions: PermissionsContainer::allow_all(permission_desc_parser), blob_store: Default::default(), diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 8d008eeab0..331369551c 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -14,6 +14,8 @@ use deno_core::Extension; use deno_http::DefaultHttpPropertyExtractor; use deno_io::fs::FsError; use deno_permissions::PermissionCheckError; +use deno_resolver::npm::DenoInNpmPackageChecker; +use deno_resolver::npm::NpmResolver; use crate::ops; use crate::ops::bootstrap::SnapshotOptions; @@ -310,6 +312,8 @@ pub fn create_runtime_snapshot( deno_fs::deno_fs::init_ops_and_esm::(fs.clone()), deno_node::deno_node::init_ops_and_esm::< Permissions, + DenoInNpmPackageChecker, + NpmResolver, sys_traits::impls::RealSys, >(None, fs.clone()), runtime::init_ops_and_esm(), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 64393bb64c..4389c7752c 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -54,6 +54,8 @@ use deno_web::JsMessageData; use deno_web::MessagePort; use deno_web::Transferable; use log::debug; +use node_resolver::InNpmPackageChecker; +use node_resolver::NpmPackageFolderResolver; use crate::inspector_server::InspectorServer; use crate::ops; @@ -334,7 +336,11 @@ fn create_handles( (internal_handle, external_handle) } -pub struct WebWorkerServiceOptions { +pub struct WebWorkerServiceOptions< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TExtNodeSys: ExtNodeSys + 'static, +> { pub blob_store: Arc, pub broadcast_channel: InMemoryBroadcastChannel, pub compiled_wasm_module_store: Option, @@ -342,7 +348,13 @@ pub struct WebWorkerServiceOptions { pub fs: Arc, pub maybe_inspector_server: Option>, pub module_loader: Rc, - pub node_services: Option>, + pub node_services: Option< + NodeExtInitServices< + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >, + >, pub npm_process_state_provider: Option, pub permissions: PermissionsContainer, pub root_cert_store_provider: Option>, @@ -398,8 +410,16 @@ impl Drop for WebWorker { } impl WebWorker { - pub fn bootstrap_from_options( - services: WebWorkerServiceOptions, + pub fn bootstrap_from_options< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TExtNodeSys: ExtNodeSys + 'static, + >( + services: WebWorkerServiceOptions< + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >, options: WebWorkerOptions, ) -> (Self, SendableWebWorkerHandle) { let (mut worker, handle, bootstrap_options) = @@ -408,8 +428,16 @@ impl WebWorker { (worker, handle) } - fn from_options( - services: WebWorkerServiceOptions, + fn from_options< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TExtNodeSys: ExtNodeSys + 'static, + >( + services: WebWorkerServiceOptions< + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >, mut options: WebWorkerOptions, ) -> (Self, SendableWebWorkerHandle, BootstrapOptions) { deno_core::extension!(deno_permissions_web_worker, @@ -500,10 +528,12 @@ impl WebWorker { deno_fs::deno_fs::init_ops_and_esm::( services.fs.clone(), ), - deno_node::deno_node::init_ops_and_esm::( - services.node_services, - services.fs, - ), + deno_node::deno_node::init_ops_and_esm::< + PermissionsContainer, + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >(services.node_services, services.fs), // Runtime ops that are always initialized for WebWorkers ops::runtime::deno_runtime::init_ops_and_esm(options.main_module.clone()), ops::worker_host::deno_worker_host::init_ops_and_esm( diff --git a/runtime/worker.rs b/runtime/worker.rs index a649c83d47..7cd6468fc5 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -45,6 +45,8 @@ use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; use deno_web::BlobStore; use log::debug; +use node_resolver::InNpmPackageChecker; +use node_resolver::NpmPackageFolderResolver; use crate::code_cache::CodeCache; use crate::code_cache::CodeCacheType; @@ -128,7 +130,11 @@ pub struct MainWorker { dispatch_process_exit_event_fn_global: v8::Global, } -pub struct WorkerServiceOptions { +pub struct WorkerServiceOptions< + TInNpmPackageChecker: InNpmPackageChecker, + TNpmPackageFolderResolver: NpmPackageFolderResolver, + TExtNodeSys: ExtNodeSys, +> { pub blob_store: Arc, pub broadcast_channel: InMemoryBroadcastChannel, pub feature_checker: Arc, @@ -139,7 +145,13 @@ pub struct WorkerServiceOptions { /// If not provided runtime will error if code being /// executed tries to load modules. pub module_loader: Rc, - pub node_services: Option>, + pub node_services: Option< + NodeExtInitServices< + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >, + >, pub npm_process_state_provider: Option, pub permissions: PermissionsContainer, pub root_cert_store_provider: Option>, @@ -300,9 +312,17 @@ pub fn create_op_metrics( } impl MainWorker { - pub fn bootstrap_from_options( + pub fn bootstrap_from_options< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TExtNodeSys: ExtNodeSys + 'static, + >( main_module: ModuleSpecifier, - services: WorkerServiceOptions, + services: WorkerServiceOptions< + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >, options: WorkerOptions, ) -> Self { let (mut worker, bootstrap_options) = @@ -311,9 +331,17 @@ impl MainWorker { worker } - fn from_options( + fn from_options< + TInNpmPackageChecker: InNpmPackageChecker + 'static, + TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, + TExtNodeSys: ExtNodeSys + 'static, + >( main_module: ModuleSpecifier, - services: WorkerServiceOptions, + services: WorkerServiceOptions< + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >, mut options: WorkerOptions, ) -> (Self, BootstrapOptions) { deno_core::extension!(deno_permissions_worker, @@ -413,10 +441,12 @@ impl MainWorker { deno_fs::deno_fs::init_ops_and_esm::( services.fs.clone(), ), - deno_node::deno_node::init_ops_and_esm::( - services.node_services, - services.fs, - ), + deno_node::deno_node::init_ops_and_esm::< + PermissionsContainer, + TInNpmPackageChecker, + TNpmPackageFolderResolver, + TExtNodeSys, + >(services.node_services, services.fs), // Ops from this crate ops::runtime::deno_runtime::init_ops_and_esm(main_module.clone()), ops::worker_host::deno_worker_host::init_ops_and_esm( From c943f56949d723ba891b26a0cc4aaaaf7b358d95 Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Wed, 15 Jan 2025 01:00:55 +0900 Subject: [PATCH 17/38] fix(ext/node): fix playwright http client (#27662) --- ext/node/polyfills/_tls_wrap.ts | 2 +- ext/node/polyfills/net.ts | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ext/node/polyfills/_tls_wrap.ts b/ext/node/polyfills/_tls_wrap.ts index 0edea1c053..dc7dac77ac 100644 --- a/ext/node/polyfills/_tls_wrap.ts +++ b/ext/node/polyfills/_tls_wrap.ts @@ -154,7 +154,7 @@ export class TLSSocket extends net.Socket { const afterConnect = handle.afterConnect; handle.afterConnect = async (req: any, status: number) => { options.hostname ??= undefined; // coerce to undefined if null, startTls expects hostname to be undefined - if (tlssock._isNpmAgent) { + if (tlssock._needsSockInitWorkaround) { // skips the TLS handshake for @npmcli/agent as it's handled by // onSocket handler of ClientRequest object. tlssock.emit("secure"); diff --git a/ext/node/polyfills/net.ts b/ext/node/polyfills/net.ts index bebdd8dade..2d57507c1b 100644 --- a/ext/node/polyfills/net.ts +++ b/ext/node/polyfills/net.ts @@ -1157,6 +1157,13 @@ function _emitCloseNT(s: Socket | Server) { s.emit("close"); } +// The packages that need socket initialization workaround +const pkgsNeedsSockInitWorkaround = [ + "@npmcli/agent", + "npm-check-updates", + "playwright-core", +]; + /** * This class is an abstraction of a TCP socket or a streaming `IPC` endpoint * (uses named pipes on Windows, and Unix domain sockets otherwise). It is also @@ -1201,9 +1208,11 @@ export class Socket extends Duplex { _host: string | null = null; // deno-lint-ignore no-explicit-any _parent: any = null; - // The flag for detecting if it's called in @npmcli/agent + // Skip some initialization (initial read and tls handshake if it's tls socket). + // If this flag is true, it's used as connection for http(s) request, and + // the reading and TLS handshake is done by the http client. // See discussions in https://github.com/denoland/deno/pull/25470 for more details. - _isNpmAgent = false; + _needsSockInitWorkaround = false; autoSelectFamilyAttemptedAddresses: AddressInfo[] | undefined = undefined; constructor(options: SocketOptions | number) { @@ -1224,21 +1233,20 @@ export class Socket extends Duplex { super(options); - // Note: If the socket is created from one of: - // - @npmcli/agent - // - npm-check-updates (bundles @npmcli/agent as a dependency) + // Note: If the socket is created from one of `pkgNeedsSockInitWorkaround`, // the 'socket' event on ClientRequest object happens after 'connect' event on Socket object. // That swaps the sequence of op_node_http_request_with_conn() call and // initial socket read. That causes op_node_http_request_with_conn() not // working. // To avoid the above situation, we detect the socket created from - // @npmcli/agent and pause the socket (and also skips the startTls call - // if it's TLSSocket) + // one of those packages using stack trace and pause the socket + // (and also skips the startTls call if it's TLSSocket) // TODO(kt3k): Remove this workaround const errorStack = new Error().stack; - this._isNpmAgent = errorStack?.includes("@npmcli/agent") || - errorStack?.includes("npm-check-updates") || false; - if (this._isNpmAgent) { + this._needsSockInitWorkaround = pkgsNeedsSockInitWorkaround.some((pkg) => + errorStack?.includes(pkg) + ); + if (this._needsSockInitWorkaround) { this.pause(); } From 974e2f44b2660a1cd13f8c901ff28a2f57ed391f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 14 Jan 2025 16:29:36 +0000 Subject: [PATCH 18/38] refactor: add 'deno_os' crate (#27655) This commit creates "deno_os" extension crate and moves numerous ops from "runtime/" crate to the new crate. --- Cargo.lock | 25 +++++++++-- Cargo.toml | 1 + cli/js/40_bench.js | 2 +- cli/js/40_test.js | 2 +- cli/task_runner.rs | 2 +- cli/worker.rs | 2 +- ext/node/polyfills/os.ts | 2 +- ext/node/polyfills/process.ts | 2 +- {runtime/js => ext/os}/30_os.js | 0 {runtime/js => ext/os}/40_signals.js | 0 ext/os/Cargo.toml | 33 ++++++++++++++ {runtime/ops => ext}/os/README.md | 4 +- runtime/ops/os/mod.rs => ext/os/lib.rs | 61 +++++++++++++++++++++++--- ext/os/ops/mod.rs | 3 ++ {runtime => ext/os}/ops/signal.rs | 19 ++------ {runtime => ext/os}/signal.rs | 0 {runtime => ext/os}/sys_info.rs | 0 runtime/Cargo.toml | 5 +-- runtime/js/90_deno_ns.js | 4 +- runtime/js/99_main.js | 2 +- runtime/lib.rs | 10 +---- runtime/ops/mod.rs | 2 - runtime/ops/process.rs | 9 ++-- runtime/shared.rs | 2 - runtime/snapshot.rs | 3 +- runtime/web_worker.rs | 3 +- runtime/worker.rs | 21 ++------- tests/integration/run_tests.rs | 2 +- tools/core_import_map.json | 4 +- 29 files changed, 145 insertions(+), 80 deletions(-) rename {runtime/js => ext/os}/30_os.js (100%) rename {runtime/js => ext/os}/40_signals.js (100%) create mode 100644 ext/os/Cargo.toml rename {runtime/ops => ext}/os/README.md (97%) rename runtime/ops/os/mod.rs => ext/os/lib.rs (90%) create mode 100644 ext/os/ops/mod.rs rename {runtime => ext/os}/ops/signal.rs (95%) rename {runtime => ext/os}/signal.rs (100%) rename {runtime => ext/os}/sys_info.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 95633e3ce9..aadd0c5f95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2140,6 +2140,27 @@ dependencies = [ "thiserror 2.0.3", ] +[[package]] +name = "deno_os" +version = "0.1.0" +dependencies = [ + "deno_core", + "deno_error", + "deno_path_util", + "deno_permissions", + "deno_telemetry", + "libc", + "netif", + "ntapi", + "once_cell", + "serde", + "signal-hook", + "signal-hook-registry", + "thiserror 2.0.3", + "tokio", + "winapi", +] + [[package]] name = "deno_package_json" version = "0.4.0" @@ -2240,6 +2261,7 @@ dependencies = [ "deno_napi", "deno_net", "deno_node", + "deno_os", "deno_path_util", "deno_permissions", "deno_resolver", @@ -2263,7 +2285,6 @@ dependencies = [ "hyper-util", "libc", "log", - "netif", "nix", "node_resolver", "notify", @@ -2274,8 +2295,6 @@ dependencies = [ "rustyline", "same-file", "serde", - "signal-hook", - "signal-hook-registry", "sys_traits", "tempfile", "test_server", diff --git a/Cargo.toml b/Cargo.toml index 48aeccdaef..d9f976d863 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,6 +84,7 @@ deno_kv = { version = "0.93.0", path = "./ext/kv" } deno_napi = { version = "0.116.0", path = "./ext/napi" } deno_net = { version = "0.177.0", path = "./ext/net" } deno_node = { version = "0.123.0", path = "./ext/node" } +deno_os = { version = "0.1.0", path = "./ext/os" } deno_telemetry = { version = "0.7.0", path = "./ext/telemetry" } deno_tls = { version = "0.172.0", path = "./ext/tls" } deno_url = { version = "0.185.0", path = "./ext/url" } diff --git a/cli/js/40_bench.js b/cli/js/40_bench.js index 0ad05c5197..fb0e86463d 100644 --- a/cli/js/40_bench.js +++ b/cli/js/40_bench.js @@ -8,7 +8,7 @@ import { restorePermissions, } from "ext:cli/40_test_common.js"; import { Console } from "ext:deno_console/01_console.js"; -import { setExitHandler } from "ext:runtime/30_os.js"; +import { setExitHandler } from "ext:deno_os/30_os.js"; const { op_register_bench, op_bench_get_origin, diff --git a/cli/js/40_test.js b/cli/js/40_test.js index 34d9ec6550..3dbb7ec340 100644 --- a/cli/js/40_test.js +++ b/cli/js/40_test.js @@ -26,7 +26,7 @@ const { TypeError, } = primordials; -import { setExitHandler } from "ext:runtime/30_os.js"; +import { setExitHandler } from "ext:deno_os/30_os.js"; // Capture `Deno` global so that users deleting or mangling it, won't // have impact on our sanitizers. diff --git a/cli/task_runner.rs b/cli/task_runner.rs index 50dcd64dc7..14e850ee76 100644 --- a/cli/task_runner.rs +++ b/cli/task_runner.rs @@ -596,7 +596,7 @@ async fn listen_ctrl_c(kill_signal: KillSignal) { #[cfg(unix)] async fn listen_and_forward_all_signals(kill_signal: KillSignal) { use deno_core::futures::FutureExt; - use deno_runtime::signal::SIGNAL_NUMS; + use deno_runtime::deno_os::signal::SIGNAL_NUMS; // listen and forward every signal we support let mut futures = Vec::with_capacity(SIGNAL_NUMS.len()); diff --git a/cli/worker.rs b/cli/worker.rs index 45d4b0af70..d9cdbd3fb0 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -855,7 +855,7 @@ fn create_web_worker_callback( /// Instead probe for the total memory on the system and use it instead /// as a default. pub fn create_isolate_create_params() -> Option { - let maybe_mem_info = deno_runtime::sys_info::mem_info(); + let maybe_mem_info = deno_runtime::deno_os::sys_info::mem_info(); maybe_mem_info.map(|mem_info| { v8::CreateParams::default() .heap_limits_from_system_memory(mem_info.total, 0) diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index bd4b285ba3..4901b20fa8 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -35,7 +35,7 @@ import { validateIntegerRange } from "ext:deno_node/_utils.ts"; import process from "node:process"; import { isWindows } from "ext:deno_node/_util/os.ts"; import { os } from "ext:deno_node/internal_binding/constants.ts"; -import { osUptime } from "ext:runtime/30_os.js"; +import { osUptime } from "ext:deno_os/30_os.js"; import { Buffer } from "ext:deno_node/internal/buffer.mjs"; import { primordials } from "ext:core/mod.js"; const { StringPrototypeEndsWith, StringPrototypeSlice } = primordials; diff --git a/ext/node/polyfills/process.ts b/ext/node/polyfills/process.ts index e91a2ee005..b3fe0883dc 100644 --- a/ext/node/polyfills/process.ts +++ b/ext/node/polyfills/process.ts @@ -58,7 +58,7 @@ import { } from "ext:deno_node/_next_tick.ts"; import { isWindows } from "ext:deno_node/_util/os.ts"; import * as io from "ext:deno_io/12_io.js"; -import * as denoOs from "ext:runtime/30_os.js"; +import * as denoOs from "ext:deno_os/30_os.js"; export let argv0 = ""; diff --git a/runtime/js/30_os.js b/ext/os/30_os.js similarity index 100% rename from runtime/js/30_os.js rename to ext/os/30_os.js diff --git a/runtime/js/40_signals.js b/ext/os/40_signals.js similarity index 100% rename from runtime/js/40_signals.js rename to ext/os/40_signals.js diff --git a/ext/os/Cargo.toml b/ext/os/Cargo.toml new file mode 100644 index 0000000000..fb553d1532 --- /dev/null +++ b/ext/os/Cargo.toml @@ -0,0 +1,33 @@ +# Copyright 2018-2025 the Deno authors. MIT license. + +[package] +name = "deno_os" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +repository.workspace = true +description = "OS specific APIs for Deno" + +[lib] +path = "lib.rs" + +[dependencies] +deno_core.workspace = true +deno_error.workspace = true +deno_path_util.workspace = true +deno_permissions.workspace = true +deno_telemetry.workspace = true +libc.workspace = true +netif = "0.1.6" +once_cell.workspace = true +serde.workspace = true +signal-hook = "0.3.17" +signal-hook-registry = "1.4.0" +thiserror.workspace = true +tokio.workspace = true + +[target.'cfg(windows)'.dependencies] +winapi = { workspace = true, features = ["commapi", "knownfolders", "mswsock", "objbase", "psapi", "shlobj", "tlhelp32", "winbase", "winerror", "winuser", "winsock2"] } +ntapi = "0.4.0" diff --git a/runtime/ops/os/README.md b/ext/os/README.md similarity index 97% rename from runtime/ops/os/README.md rename to ext/os/README.md index ae1a5958e4..f308ed3d2b 100644 --- a/runtime/ops/os/README.md +++ b/ext/os/README.md @@ -1,4 +1,6 @@ -## `os` ops +# deno_os + +This crate implements OS specific APIs for Deno `loadavg` diff --git a/runtime/ops/os/mod.rs b/ext/os/lib.rs similarity index 90% rename from runtime/ops/os/mod.rs rename to ext/os/lib.rs index ad3a292c3a..f084601678 100644 --- a/runtime/ops/os/mod.rs +++ b/ext/os/lib.rs @@ -1,19 +1,54 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::collections::HashMap; +use std::collections::HashSet; use std::env; +use std::sync::atomic::AtomicI32; +use std::sync::atomic::Ordering; +use std::sync::Arc; use deno_core::op2; use deno_core::v8; use deno_core::OpState; -use deno_node::NODE_ENV_VAR_ALLOWLIST; use deno_path_util::normalize_path; use deno_permissions::PermissionCheckError; use deno_permissions::PermissionsContainer; +use once_cell::sync::Lazy; use serde::Serialize; -use crate::sys_info; -use crate::worker::ExitCode; +mod ops; +pub mod signal; +pub mod sys_info; + +pub use ops::signal::SignalError; + +pub static NODE_ENV_VAR_ALLOWLIST: Lazy> = Lazy::new(|| { + // The full list of environment variables supported by Node.js is available + // at https://nodejs.org/api/cli.html#environment-variables + let mut set = HashSet::new(); + set.insert("NODE_DEBUG".to_string()); + set.insert("NODE_OPTIONS".to_string()); + set +}); + +#[derive(Clone, Default)] +pub struct ExitCode(Arc); + +impl ExitCode { + pub fn get(&self) -> i32 { + self.0.load(Ordering::Relaxed) + } + + pub fn set(&mut self, code: i32) { + self.0.store(code, Ordering::Relaxed); + } +} + +pub fn exit(code: i32) -> ! { + deno_telemetry::flush(); + #[allow(clippy::disallowed_methods)] + std::process::exit(code); +} deno_core::extension!( deno_os, @@ -35,13 +70,21 @@ deno_core::extension!( op_system_memory_info, op_uid, op_runtime_memory_usage, + ops::signal::op_signal_bind, + ops::signal::op_signal_unbind, + ops::signal::op_signal_poll, ], + esm = ["30_os.js", "40_signals.js"], options = { exit_code: ExitCode, }, state = |state, options| { state.put::(options.exit_code); - }, + #[cfg(unix)] + { + state.put(ops::signal::SignalState::default()); + } + } ); deno_core::extension!( @@ -64,12 +107,16 @@ deno_core::extension!( op_system_memory_info, op_uid, op_runtime_memory_usage, + ops::signal::op_signal_bind, + ops::signal::op_signal_unbind, + ops::signal::op_signal_poll, ], + esm = ["30_os.js", "40_signals.js"], middleware = |op| match op.name { "op_exit" | "op_set_exit_code" | "op_get_exit_code" => op.with_implementation_from(&deno_core::op_void_sync()), _ => op, - }, + } ); #[derive(Debug, thiserror::Error, deno_error::JsError)] @@ -196,7 +243,7 @@ fn op_get_exit_code(state: &mut OpState) -> i32 { #[op2(fast)] fn op_exit(state: &mut OpState) { let code = state.borrow::().get(); - crate::exit(code) + exit(code) } #[op2(stack_trace)] @@ -239,7 +286,7 @@ fn op_network_interfaces( Ok(netif::up()?.map(NetworkInterface::from).collect()) } -#[derive(serde::Serialize)] +#[derive(Serialize)] struct NetworkInterface { family: &'static str, name: String, diff --git a/ext/os/ops/mod.rs b/ext/os/ops/mod.rs new file mode 100644 index 0000000000..857d4688c7 --- /dev/null +++ b/ext/os/ops/mod.rs @@ -0,0 +1,3 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +pub mod signal; diff --git a/runtime/ops/signal.rs b/ext/os/ops/signal.rs similarity index 95% rename from runtime/ops/signal.rs rename to ext/os/ops/signal.rs index beefa1cd78..5b556e3a2c 100644 --- a/runtime/ops/signal.rs +++ b/ext/os/ops/signal.rs @@ -33,17 +33,6 @@ use tokio::signal::windows::CtrlBreak; #[cfg(windows)] use tokio::signal::windows::CtrlC; -deno_core::extension!( - deno_signal, - ops = [op_signal_bind, op_signal_unbind, op_signal_poll], - state = |state| { - #[cfg(unix)] - { - state.put(SignalState::default()); - } - } -); - #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum SignalError { #[class(type)] @@ -62,7 +51,7 @@ pub enum SignalError { #[cfg(unix)] #[derive(Default)] -struct SignalState { +pub struct SignalState { enable_default_handlers: BTreeMap>, } @@ -164,7 +153,7 @@ impl Resource for SignalStreamResource { #[cfg(unix)] #[op2(fast)] #[smi] -fn op_signal_bind( +pub fn op_signal_bind( state: &mut OpState, #[string] sig: &str, ) -> Result { @@ -201,7 +190,7 @@ fn op_signal_bind( #[cfg(windows)] #[op2(fast)] #[smi] -fn op_signal_bind( +pub fn op_signal_bind( state: &mut OpState, #[string] sig: &str, ) -> Result { @@ -225,7 +214,7 @@ fn op_signal_bind( } #[op2(async)] -async fn op_signal_poll( +pub async fn op_signal_poll( state: Rc>, #[smi] rid: ResourceId, ) -> Result { diff --git a/runtime/signal.rs b/ext/os/signal.rs similarity index 100% rename from runtime/signal.rs rename to ext/os/signal.rs diff --git a/runtime/sys_info.rs b/ext/os/sys_info.rs similarity index 100% rename from runtime/sys_info.rs rename to ext/os/sys_info.rs diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index f59325962f..808f79ab7b 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -49,6 +49,7 @@ deno_core.workspace = true deno_cron.workspace = true deno_crypto.workspace = true deno_fetch.workspace = true +deno_os.workspace = true deno_ffi.workspace = true deno_fs = { workspace = true, features = ["sync_fs"] } deno_http.workspace = true @@ -89,6 +90,7 @@ deno_kv.workspace = true deno_napi.workspace = true deno_net.workspace = true deno_node.workspace = true +deno_os.workspace = true deno_path_util.workspace = true deno_permissions.workspace = true deno_resolver.workspace = true @@ -114,7 +116,6 @@ hyper-util.workspace = true hyper_v014 = { workspace = true, features = ["server", "stream", "http1", "http2", "runtime"] } libc.workspace = true log.workspace = true -netif = "0.1.6" notify.workspace = true once_cell.workspace = true percent-encoding.workspace = true @@ -122,8 +123,6 @@ regex.workspace = true rustyline = { workspace = true, features = ["custom-bindings"] } same-file = "1.0.6" serde.workspace = true -signal-hook = "0.3.17" -signal-hook-registry = "1.4.0" sys_traits.workspace = true tempfile.workspace = true thiserror.workspace = true diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index 8127ac9618..b241028077 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -21,10 +21,10 @@ import * as version from "ext:runtime/01_version.ts"; import * as permissions from "ext:runtime/10_permissions.js"; import * as io from "ext:deno_io/12_io.js"; import * as fs from "ext:deno_fs/30_fs.js"; -import * as os from "ext:runtime/30_os.js"; +import * as os from "ext:deno_os/30_os.js"; import * as fsEvents from "ext:runtime/40_fs_events.js"; import * as process from "ext:runtime/40_process.js"; -import * as signals from "ext:runtime/40_signals.js"; +import * as signals from "ext:deno_os/40_signals.js"; import * as tty from "ext:runtime/40_tty.js"; import * as kv from "ext:deno_kv/01_db.ts"; import * as cron from "ext:deno_cron/01_cron.ts"; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 03c662bcab..2971fd2c00 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -55,7 +55,7 @@ import { registerDeclarativeServer } from "ext:deno_http/00_serve.ts"; import * as event from "ext:deno_web/02_event.js"; import * as location from "ext:deno_web/12_location.js"; import * as version from "ext:runtime/01_version.ts"; -import * as os from "ext:runtime/30_os.js"; +import * as os from "ext:deno_os/30_os.js"; import * as timers from "ext:deno_web/02_timers.js"; import { getDefaultInspectOptions, diff --git a/runtime/lib.rs b/runtime/lib.rs index 9afe91cd25..c104f5cd61 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -16,6 +16,7 @@ pub use deno_kv; pub use deno_napi; pub use deno_net; pub use deno_node; +pub use deno_os; pub use deno_permissions; pub use deno_terminal::colors; pub use deno_tls; @@ -33,9 +34,7 @@ pub mod inspector_server; pub mod js; pub mod ops; pub mod permissions; -pub mod signal; pub mod snapshot; -pub mod sys_info; pub mod tokio_util; pub mod web_worker; pub mod worker; @@ -46,6 +45,7 @@ pub use worker_bootstrap::WorkerExecutionMode; pub use worker_bootstrap::WorkerLogLevel; pub mod shared; +pub use deno_os::exit; pub use shared::runtime; pub struct UnstableGranularFlag { @@ -147,12 +147,6 @@ pub static UNSTABLE_GRANULAR_FLAGS: &[UnstableGranularFlag] = &[ }, ]; -pub fn exit(code: i32) -> ! { - deno_telemetry::flush(); - #[allow(clippy::disallowed_methods)] - std::process::exit(code); -} - #[cfg(test)] mod test { use super::*; diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs index 438c3896e6..d131e9aab5 100644 --- a/runtime/ops/mod.rs +++ b/runtime/ops/mod.rs @@ -3,11 +3,9 @@ pub mod bootstrap; pub mod fs_events; pub mod http; -pub mod os; pub mod permissions; pub mod process; pub mod runtime; -pub mod signal; pub mod tty; pub mod web_worker; pub mod worker_host; diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index 4682085aea..fc32f7e066 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -31,14 +31,13 @@ use deno_io::ChildStderrResource; use deno_io::ChildStdinResource; use deno_io::ChildStdoutResource; use deno_io::IntoRawIoHandle; +use deno_os::SignalError; use deno_permissions::PermissionsContainer; use deno_permissions::RunQueryDescriptor; use serde::Deserialize; use serde::Serialize; use tokio::process::Command; -use crate::ops::signal::SignalError; - pub const UNSTABLE_FEATURE_NAME: &str = "process"; #[derive(Copy, Clone, Eq, PartialEq, Deserialize)] @@ -296,7 +295,7 @@ impl TryFrom for ChildStatus { success: false, code: 128 + signal, #[cfg(unix)] - signal: Some(crate::signal::signal_int_to_str(signal)?.to_string()), + signal: Some(deno_os::signal::signal_int_to_str(signal)?.to_string()), #[cfg(not(unix))] signal: None, } @@ -1116,7 +1115,7 @@ mod deprecated { #[cfg(unix)] pub fn kill(pid: i32, signal: &str) -> Result<(), ProcessError> { - let signo = crate::signal::signal_str_to_int(signal) + let signo = deno_os::signal::signal_str_to_int(signal) .map_err(SignalError::InvalidSignalStr)?; use nix::sys::signal::kill as unix_kill; use nix::sys::signal::Signal; @@ -1144,7 +1143,7 @@ mod deprecated { if !matches!(signal, "SIGKILL" | "SIGTERM") { Err( - SignalError::InvalidSignalStr(crate::signal::InvalidSignalStrError( + SignalError::InvalidSignalStr(deno_os::signal::InvalidSignalStrError( signal.to_string(), )) .into(), diff --git a/runtime/shared.rs b/runtime/shared.rs index f8588dd72c..0e747b0565 100644 --- a/runtime/shared.rs +++ b/runtime/shared.rs @@ -42,10 +42,8 @@ extension!(runtime, "06_util.js", "10_permissions.js", "11_workers.js", - "30_os.js", "40_fs_events.js", "40_process.js", - "40_signals.js", "40_tty.js", "41_prompt.js", "90_deno_ns.js", diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 331369551c..08ea17a986 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -310,6 +310,7 @@ pub fn create_runtime_snapshot( ), deno_io::deno_io::init_ops_and_esm(Default::default()), deno_fs::deno_fs::init_ops_and_esm::(fs.clone()), + deno_os::deno_os::init_ops_and_esm(Default::default()), deno_node::deno_node::init_ops_and_esm::< Permissions, DenoInNpmPackageChecker, @@ -323,10 +324,8 @@ pub fn create_runtime_snapshot( None, ), ops::fs_events::deno_fs_events::init_ops(), - ops::os::deno_os::init_ops(Default::default()), ops::permissions::deno_permissions::init_ops(), ops::process::deno_process::init_ops(None), - ops::signal::deno_signal::init_ops(), ops::tty::deno_tty::init_ops(), ops::http::deno_http_runtime::init_ops(), ops::bootstrap::deno_bootstrap::init_ops(Some(snapshot_options)), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 4389c7752c..e4ea42a2f7 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -528,6 +528,7 @@ impl WebWorker { deno_fs::deno_fs::init_ops_and_esm::( services.fs.clone(), ), + deno_os::deno_os_worker::init_ops_and_esm(), deno_node::deno_node::init_ops_and_esm::< PermissionsContainer, TInNpmPackageChecker, @@ -541,12 +542,10 @@ impl WebWorker { options.format_js_error_fn, ), ops::fs_events::deno_fs_events::init_ops_and_esm(), - ops::os::deno_os_worker::init_ops_and_esm(), ops::permissions::deno_permissions::init_ops_and_esm(), ops::process::deno_process::init_ops_and_esm( services.npm_process_state_provider, ), - ops::signal::deno_signal::init_ops_and_esm(), ops::tty::deno_tty::init_ops_and_esm(), ops::http::deno_http_runtime::init_ops_and_esm(), ops::bootstrap::deno_bootstrap::init_ops_and_esm( diff --git a/runtime/worker.rs b/runtime/worker.rs index 7cd6468fc5..cfcadccc46 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -3,8 +3,6 @@ use std::borrow::Cow; use std::collections::HashMap; use std::rc::Rc; use std::sync::atomic::AtomicBool; -use std::sync::atomic::AtomicI32; -use std::sync::atomic::Ordering::Relaxed; use std::sync::Arc; use std::time::Duration; use std::time::Instant; @@ -40,6 +38,7 @@ use deno_io::Stdio; use deno_kv::dynamic::MultiBackendDbHandler; use deno_node::ExtNodeSys; use deno_node::NodeExtInitServices; +use deno_os::ExitCode; use deno_permissions::PermissionsContainer; use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; @@ -97,19 +96,6 @@ pub fn validate_import_attributes_callback( } } -#[derive(Clone, Default)] -pub struct ExitCode(Arc); - -impl ExitCode { - pub fn get(&self) -> i32 { - self.0.load(Relaxed) - } - - pub fn set(&mut self, code: i32) { - self.0.store(code, Relaxed); - } -} - /// This worker is created and used by almost all /// subcommands in Deno executable. /// @@ -363,7 +349,7 @@ impl MainWorker { // Permissions: many ops depend on this let enable_testing_features = options.bootstrap.enable_testing_features; - let exit_code = ExitCode(Arc::new(AtomicI32::new(0))); + let exit_code = ExitCode::default(); let create_cache = options.cache_storage_dir.map(|storage_dir| { let create_cache_fn = move || SqliteBackedCache::new(storage_dir.clone()); CreateCache(Arc::new(create_cache_fn)) @@ -441,6 +427,7 @@ impl MainWorker { deno_fs::deno_fs::init_ops_and_esm::( services.fs.clone(), ), + deno_os::deno_os::init_ops_and_esm(exit_code.clone()), deno_node::deno_node::init_ops_and_esm::< PermissionsContainer, TInNpmPackageChecker, @@ -454,12 +441,10 @@ impl MainWorker { options.format_js_error_fn.clone(), ), ops::fs_events::deno_fs_events::init_ops_and_esm(), - ops::os::deno_os::init_ops_and_esm(exit_code.clone()), ops::permissions::deno_permissions::init_ops_and_esm(), ops::process::deno_process::init_ops_and_esm( services.npm_process_state_provider, ), - ops::signal::deno_signal::init_ops_and_esm(), ops::tty::deno_tty::init_ops_and_esm(), ops::http::deno_http_runtime::init_ops_and_esm(), ops::bootstrap::deno_bootstrap::init_ops_and_esm( diff --git a/tests/integration/run_tests.rs b/tests/integration/run_tests.rs index 5e4db3d3e4..abf1c200d9 100644 --- a/tests/integration/run_tests.rs +++ b/tests/integration/run_tests.rs @@ -445,7 +445,7 @@ fn permissions_trace() { test_util::assertions::assert_wildcard_match(&text, concat!( "┏ ⚠️ Deno requests sys access to \"hostname\".\r\n", "┠─ Requested by `Deno.hostname()` API.\r\n", - "┃ ├─ Object.hostname (ext:runtime/30_os.js:43:10)\r\n", + "┃ ├─ Object.hostname (ext:deno_os/30_os.js:43:10)\r\n", "┃ ├─ foo (file://[WILDCARD]/run/permissions_trace.ts:2:8)\r\n", "┃ ├─ bar (file://[WILDCARD]/run/permissions_trace.ts:6:3)\r\n", "┃ └─ file://[WILDCARD]/run/permissions_trace.ts:9:1\r\n", diff --git a/tools/core_import_map.json b/tools/core_import_map.json index feeae1ac70..4843884015 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -239,10 +239,10 @@ "ext:runtime/06_util.js": "../runtime/js/06_util.js", "ext:runtime/10_permissions.js": "../runtime/js/10_permissions.js", "ext:runtime/11_workers.js": "../runtime/js/11_workers.js", - "ext:runtime/30_os.js": "../runtime/js/30_os.js", + "ext:deno_os/30_os.js": "../ext/os/30_os.js", "ext:runtime/40_fs_events.js": "../runtime/js/40_fs_events.js", "ext:runtime/40_process.js": "../runtime/js/40_process.js", - "ext:runtime/40_signals.js": "../runtime/js/40_signals.js", + "ext:deno_os/40_signals.js": "../ext/os/40_signals.js", "ext:runtime/40_tty.js": "../runtime/js/40_tty.js", "ext:runtime/41_prompt.js": "../runtime/js/41_prompt.js", "ext:runtime/90_deno_ns.js": "../runtime/js/90_deno_ns.js", From afc23fb2e007b521b9f4fcae632db2c4e41f8595 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 14 Jan 2025 23:06:57 -0500 Subject: [PATCH 19/38] chore: fix ci by removing remote server dependent test (#27674) This was using the lockfile and esm.sh changed breaking the lockfile. We could pin to a specific esm.sh version, but ideally we shouldn't have the test suite dependent on remote servers. --- tests/specs/info/import_map/__test__.jsonc | 2 +- tests/specs/info/import_map/deno.json | 3 +-- tests/specs/info/import_map/deno.lock | 8 ++----- .../specs/info/import_map/with_import_map.out | 21 ++++++------------- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/tests/specs/info/import_map/__test__.jsonc b/tests/specs/info/import_map/__test__.jsonc index 725276925e..275f8000dc 100644 --- a/tests/specs/info/import_map/__test__.jsonc +++ b/tests/specs/info/import_map/__test__.jsonc @@ -1,5 +1,5 @@ { - "args": "info preact/debug", + "args": "info --allow-import myentry/welcome.ts", "output": "with_import_map.out", "exitCode": 0 } diff --git a/tests/specs/info/import_map/deno.json b/tests/specs/info/import_map/deno.json index aaf7260c64..9741f29622 100644 --- a/tests/specs/info/import_map/deno.json +++ b/tests/specs/info/import_map/deno.json @@ -1,6 +1,5 @@ { "imports": { - "preact": "https://esm.sh/preact@10.15.1", - "preact/": "https://esm.sh/preact@10.15.1/" + "myentry/": "http://localhost:4545/" } } diff --git a/tests/specs/info/import_map/deno.lock b/tests/specs/info/import_map/deno.lock index cb5c6ca45d..b7b217cd6a 100644 --- a/tests/specs/info/import_map/deno.lock +++ b/tests/specs/info/import_map/deno.lock @@ -1,10 +1,6 @@ { - "version": "3", + "version": "4", "remote": { - "https://esm.sh/preact@10.15.1": "4bfd0b2c5a2d432e0c8cda295d6b7304152ae08c85f7d0a22f91289c97085b89", - "https://esm.sh/preact@10.15.1/debug": "4bfd0b2c5a2d432e0c8cda295d6b7304152ae08c85f7d0a22f91289c97085b89", - "https://esm.sh/stable/preact@10.15.1/denonext/debug.js": "e8e5e198bd48c93d484c91c4c78af1900bd81d9bfcfd543e8ac75216f5404c10", - "https://esm.sh/stable/preact@10.15.1/denonext/devtools.js": "f61430e179a84483f8ea8dc098d7d0d46b2f0546de4027518bfcef197cd665c9", - "https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs": "30710ac1d5ff3711ae0c04eddbeb706f34f82d97489f61aaf09897bc75d2a628" + "http://localhost:4545/welcome.ts": "7353d5fcbc36c45d26bcbca478cf973092523b07c45999f41319820092b4de31" } } diff --git a/tests/specs/info/import_map/with_import_map.out b/tests/specs/info/import_map/with_import_map.out index 29dc17737a..ef2f53d623 100644 --- a/tests/specs/info/import_map/with_import_map.out +++ b/tests/specs/info/import_map/with_import_map.out @@ -1,16 +1,7 @@ -Download https://esm.sh/preact@10.15.1/debug -Download https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs -Download https://esm.sh/stable/preact@10.15.1/denonext/devtools.js -Download https://esm.sh/stable/preact@10.15.1/denonext/debug.js -local: [WILDCARD] -type: JavaScript -dependencies: 3 unique -size: [WILDCARD] +Download http://localhost:4545/welcome.ts +local: [WILDLINE] +type: TypeScript +dependencies: 0 unique +size: [WILDLINE] -https://esm.sh/preact@10.15.1/debug [WILDCARD] -├── https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs [WILDCARD] -├─┬ https://esm.sh/stable/preact@10.15.1/denonext/devtools.js [WILDCARD] -│ └── https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs [WILDCARD] -└─┬ https://esm.sh/stable/preact@10.15.1/denonext/debug.js [WILDCARD] - ├── https://esm.sh/stable/preact@10.15.1/denonext/preact.mjs [WILDCARD] - └── https://esm.sh/stable/preact@10.15.1/denonext/devtools.js [WILDCARD] +http://localhost:4545/welcome.ts ([WILDLINE]) From b22a50cb0cc124e3d41041abc9d08f2c289e9963 Mon Sep 17 00:00:00 2001 From: Masato Yoshioka Date: Wed, 15 Jan 2025 17:15:07 +0900 Subject: [PATCH 20/38] fix(ext/node): add chown method to FileHandle class (#27638) --- ext/node/polyfills/internal/fs/handle.ts | 5 ++++ tests/unit_node/_fs/_fs_handle_test.ts | 29 +++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/ext/node/polyfills/internal/fs/handle.ts b/ext/node/polyfills/internal/fs/handle.ts index 774b36dfc2..e22c3e0ae6 100644 --- a/ext/node/polyfills/internal/fs/handle.ts +++ b/ext/node/polyfills/internal/fs/handle.ts @@ -165,6 +165,11 @@ export class FileHandle extends EventEmitter { assertNotClosed(this, promises.utimes.name); return promises.utimes(this.#path, atime, mtime); } + + chown(uid: number, gid: number): Promise { + assertNotClosed(this, promises.chown.name); + return promises.chown(this.#path, uid, gid); + } } function assertNotClosed(handle: FileHandle, syscall: string) { diff --git a/tests/unit_node/_fs/_fs_handle_test.ts b/tests/unit_node/_fs/_fs_handle_test.ts index 9134c2cb0a..d7ae32b5ea 100644 --- a/tests/unit_node/_fs/_fs_handle_test.ts +++ b/tests/unit_node/_fs/_fs_handle_test.ts @@ -2,7 +2,7 @@ import * as path from "@std/path"; import { Buffer } from "node:buffer"; import * as fs from "node:fs/promises"; -import { assert, assertEquals } from "@std/assert"; +import { assert, assertEquals, assertRejects } from "@std/assert"; const moduleDir = path.dirname(path.fromFileUrl(import.meta.url)); const testData = path.resolve(moduleDir, "testdata", "hello.txt"); @@ -273,3 +273,30 @@ Deno.test({ await fileHandle.close(); }, }); + +Deno.test({ + name: "[node/fs filehandle.chown] Change owner of the file", + ignore: Deno.build.os === "windows", + async fn() { + const fileHandle = await fs.open(testData); + + const nobodyUid = 65534; + const nobodyGid = 65534; + + await assertRejects( + async () => await fileHandle.chown(nobodyUid, nobodyGid), + Deno.errors.PermissionDenied, + "Operation not permitted", + ); + + const realUid = Deno.uid() || 1000; + const realGid = Deno.gid() || 1000; + + await fileHandle.chown(realUid, realGid); + + assertEquals(Deno.statSync(testData).uid, realUid); + assertEquals(Deno.statSync(testData).gid, realGid); + + await fileHandle.close(); + }, +}); From 836a623d998ea8f3b674a29bf7590ada49dbfa72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 15 Jan 2025 11:03:05 +0000 Subject: [PATCH 21/38] ci: use self-hosted mac arm runner (#27568) --- .github/workflows/ci.generate.ts | 8 ++++---- .github/workflows/ci.yml | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.generate.ts b/.github/workflows/ci.generate.ts index 3214fad509..55c88fbe85 100755 --- a/.github/workflows/ci.generate.ts +++ b/.github/workflows/ci.generate.ts @@ -5,7 +5,7 @@ import { stringify } from "jsr:@std/yaml@^0.221/stringify"; // Bump this number when you want to purge the cache. // Note: the tools/release/01_bump_crate_versions.ts script will update this version // automatically via regex, so ensure that this line maintains this format. -const cacheVersion = 33; +const cacheVersion = 34; const ubuntuX86Runner = "ubuntu-24.04"; const ubuntuX86XlRunner = "ubuntu-24.04-xl"; @@ -14,7 +14,7 @@ const windowsX86Runner = "windows-2022"; const windowsX86XlRunner = "windows-2022-xl"; const macosX86Runner = "macos-13"; const macosArmRunner = "macos-14"; -const selfHostedMacosArmRunner = "self-hosted"; +const selfHostedMacosArmRunner = "ghcr.io/cirruslabs/macos-runner:sonoma"; const Runners = { linuxX86: { @@ -42,7 +42,7 @@ const Runners = { os: "macos", arch: "aarch64", runner: - `\${{ github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`, + `\${{ github.repository == 'denoland/deno' && github.ref == 'refs/heads/main' && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`, }, windowsX86: { os: "windows", @@ -486,7 +486,7 @@ const ci = { }, { name: "Cache Cargo home", - uses: "actions/cache@v4", + uses: "cirruslabs/cache@v4", with: { // See https://doc.rust-lang.org/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci // Note that with the new sparse registry format, we no longer have to cache a `.git` dir diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e560840d2e..f217d85032 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,12 +68,12 @@ jobs: skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}' - os: macos arch: aarch64 - runner: '${{ github.repository == ''denoland/deno'' && startsWith(github.ref, ''refs/tags/'') && ''self-hosted'' || ''macos-14'' }}' + runner: '${{ github.repository == ''denoland/deno'' && github.ref == ''refs/heads/main'' && ''ghcr.io/cirruslabs/macos-runner:sonoma'' || ''macos-14'' }}' job: test profile: debug - os: macos arch: aarch64 - runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && startsWith(github.ref, ''refs/tags/'') && ''self-hosted'' || ''macos-14'' }}' + runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && github.ref == ''refs/heads/main'' && ''ghcr.io/cirruslabs/macos-runner:sonoma'' || ''macos-14'' }}' job: test profile: release skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}' @@ -175,7 +175,7 @@ jobs: tar --exclude=".git*" --exclude=target --exclude=third_party/prebuilt \ -czvf target/release/deno_src.tar.gz -C .. deno - name: Cache Cargo home - uses: actions/cache@v4 + uses: cirruslabs/cache@v4 with: path: |- ~/.cargo/.crates.toml @@ -184,8 +184,8 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: '33-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' - restore-keys: '33-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-' + key: '34-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' + restore-keys: '34-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-' if: '!(matrix.skip)' - uses: dsherret/rust-toolchain-file@v1 if: '!(matrix.skip)' @@ -379,7 +379,7 @@ jobs: !./target/*/*.zip !./target/*/*.tar.gz key: never_saved - restore-keys: '33-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' + restore-keys: '34-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' - name: Apply and update mtime cache if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))' uses: ./.github/mtime_cache @@ -689,7 +689,7 @@ jobs: !./target/*/gn_root !./target/*/*.zip !./target/*/*.tar.gz - key: '33-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' + key: '34-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' publish-canary: name: publish canary runs-on: ubuntu-24.04 From 05dc69932d45a656943898d216eb2edef95bd808 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 15 Jan 2025 09:35:46 -0500 Subject: [PATCH 22/38] refactor: create deno_lib crate (#27673) Shifts just some code down for now. I'll do the rest of the refactor in the next pr, but didn't want to drop a huge refactor. --- Cargo.lock | 26 ++ Cargo.toml | 4 +- cli/Cargo.toml | 1 + cli/args/mod.rs | 91 +--- cli/cache/caches.rs | 7 +- cli/cache/emit.rs | 7 +- cli/cache/mod.rs | 5 - cli/factory.rs | 166 ++++--- cli/lib/Cargo.toml | 37 ++ cli/lib/README.md | 4 + cli/{ => lib}/cache/deno_dir.rs | 25 +- cli/{ => lib}/cache/disk_cache.rs | 27 +- cli/lib/cache/mod.rs | 8 + cli/lib/env.rs | 10 + cli/lib/lib.rs | 9 + cli/lib/npm/mod.rs | 6 + cli/{ => lib}/npm/permission_checker.rs | 13 +- cli/lib/standalone/mod.rs | 3 + cli/lib/standalone/virtual_fs.rs | 296 ++++++++++++ cli/lib/sys.rs | 37 ++ cli/{ => lib}/util/checksum.rs | 0 cli/lib/util/mod.rs | 3 + cli/lib/worker.rs | 581 ++++++++++++++++++++++++ cli/lsp/cache.rs | 6 +- cli/lsp/config.rs | 2 +- cli/lsp/diagnostics.rs | 2 +- cli/lsp/language_server.rs | 2 +- cli/lsp/testing/definitions.rs | 2 +- cli/lsp/tsc.rs | 2 +- cli/lsp/urls.rs | 2 +- cli/module_loader.rs | 16 +- cli/npm/mod.rs | 3 - cli/standalone/binary.rs | 19 +- cli/standalone/file_system.rs | 2 +- cli/standalone/mod.rs | 110 +++-- cli/standalone/serialization.rs | 4 +- cli/standalone/virtual_fs.rs | 426 ++++------------- cli/sys.rs | 2 + cli/tools/clean.rs | 2 +- cli/tools/info.rs | 4 +- cli/tools/serve.rs | 10 +- cli/tsc/mod.rs | 4 +- cli/util/file_watcher.rs | 84 +++- cli/util/mod.rs | 1 - cli/worker.rs | 506 ++++----------------- runtime/examples/extension/main.rs | 2 +- runtime/lib.rs | 1 + runtime/worker.rs | 4 +- 48 files changed, 1518 insertions(+), 1066 deletions(-) create mode 100644 cli/lib/Cargo.toml create mode 100644 cli/lib/README.md rename cli/{ => lib}/cache/deno_dir.rs (90%) rename cli/{ => lib}/cache/disk_cache.rs (92%) create mode 100644 cli/lib/cache/mod.rs create mode 100644 cli/lib/env.rs create mode 100644 cli/lib/lib.rs create mode 100644 cli/lib/npm/mod.rs rename cli/{ => lib}/npm/permission_checker.rs (92%) create mode 100644 cli/lib/standalone/mod.rs create mode 100644 cli/lib/standalone/virtual_fs.rs create mode 100644 cli/lib/sys.rs rename cli/{ => lib}/util/checksum.rs (100%) create mode 100644 cli/lib/util/mod.rs create mode 100644 cli/lib/worker.rs diff --git a/Cargo.lock b/Cargo.lock index aadd0c5f95..7ec72aa3cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1270,6 +1270,7 @@ dependencies = [ "deno_doc", "deno_error", "deno_graph", + "deno_lib", "deno_lint", "deno_lockfile", "deno_npm", @@ -1891,6 +1892,31 @@ dependencies = [ "url", ] +[[package]] +name = "deno_lib" +version = "0.1.1" +dependencies = [ + "deno_cache_dir", + "deno_error", + "deno_fs", + "deno_node", + "deno_path_util", + "deno_resolver", + "deno_runtime", + "deno_terminal 0.2.0", + "faster-hex", + "log", + "node_resolver", + "parking_lot", + "ring", + "serde", + "sys_traits", + "test_server", + "thiserror 2.0.3", + "tokio", + "url", +] + [[package]] name = "deno_lint" version = "0.68.2" diff --git a/Cargo.toml b/Cargo.toml index d9f976d863..0c11ff9a69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ resolver = "2" members = [ "bench_util", "cli", + "cli/lib", "ext/broadcast_channel", "ext/cache", "ext/canvas", @@ -94,7 +95,8 @@ deno_webidl = { version = "0.185.0", path = "./ext/webidl" } deno_websocket = { version = "0.190.0", path = "./ext/websocket" } deno_webstorage = { version = "0.180.0", path = "./ext/webstorage" } -# resolvers +# workspace libraries +deno_lib = { version = "=0.1.1", path = "./cli/lib" } deno_npm_cache = { version = "0.4.0", path = "./resolvers/npm_cache" } deno_resolver = { version = "0.16.0", path = "./resolvers/deno" } node_resolver = { version = "0.23.0", path = "./resolvers/node" } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 8248d40701..4525a1bab4 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -76,6 +76,7 @@ deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] deno_doc = { version = "=0.164.0", features = ["rust", "comrak"] } deno_error.workspace = true deno_graph = { version = "=0.87.0" } +deno_lib.workspace = true deno_lint = { version = "=0.68.2", features = ["docs"] } deno_lockfile.workspace = true deno_npm.workspace = true diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 4ba85f1706..29b493046f 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -58,6 +58,9 @@ use deno_core::serde_json; use deno_core::url::Url; use deno_graph::GraphKind; pub use deno_json::check_warn_tsconfig; +use deno_lib::cache::DenoDirProvider; +use deno_lib::env::has_flag_env_var; +use deno_lib::worker::StorageKeyResolver; use deno_lint::linter::LintConfig as DenoLintConfig; use deno_npm::npm_rc::NpmRc; use deno_npm::npm_rc::ResolvedNpmRc; @@ -89,7 +92,6 @@ use serde::Serialize; use sys_traits::EnvHomeDir; use thiserror::Error; -use crate::cache::DenoDirProvider; use crate::file_fetcher::CliFileFetcher; use crate::sys::CliSys; use crate::util::fs::canonicalize_path_maybe_not_exists; @@ -768,7 +770,7 @@ pub struct CliOptions { maybe_external_import_map: Option<(PathBuf, serde_json::Value)>, overrides: CliOptionOverrides, pub start_dir: Arc, - pub deno_dir_provider: Arc, + pub deno_dir_provider: Arc>, } impl CliOptions { @@ -1227,6 +1229,16 @@ impl CliOptions { } } + pub fn resolve_storage_key_resolver(&self) -> StorageKeyResolver { + if let Some(location) = &self.flags.location { + StorageKeyResolver::from_flag(location) + } else if let Some(deno_json) = self.start_dir.maybe_deno_json() { + StorageKeyResolver::from_config_file_url(&deno_json.specifier) + } else { + StorageKeyResolver::new_use_main_module() + } + } + // If the main module should be treated as being in an npm package. // This is triggered via a secret environment variable which is used // for functionality like child_process.fork. Users should NOT depend @@ -1871,7 +1883,7 @@ fn resolve_node_modules_folder( cwd: &Path, flags: &Flags, workspace: &Workspace, - deno_dir_provider: &Arc, + deno_dir_provider: &Arc>, ) -> Result, AnyError> { fn resolve_from_root(root_folder: &FolderConfigs, cwd: &Path) -> PathBuf { root_folder @@ -1975,63 +1987,11 @@ fn resolve_import_map_specifier( } } -pub struct StorageKeyResolver(Option>); - -impl StorageKeyResolver { - pub fn from_options(options: &CliOptions) -> Self { - Self(if let Some(location) = &options.flags.location { - // if a location is set, then the ascii serialization of the location is - // used, unless the origin is opaque, and then no storage origin is set, as - // we can't expect the origin to be reproducible - let storage_origin = location.origin(); - if storage_origin.is_tuple() { - Some(Some(storage_origin.ascii_serialization())) - } else { - Some(None) - } - } else { - // otherwise we will use the path to the config file or None to - // fall back to using the main module's path - options - .start_dir - .maybe_deno_json() - .map(|config_file| Some(config_file.specifier.to_string())) - }) - } - - /// Creates a storage key resolver that will always resolve to being empty. - pub fn empty() -> Self { - Self(Some(None)) - } - - /// Resolves the storage key to use based on the current flags, config, or main module. - pub fn resolve_storage_key( - &self, - main_module: &ModuleSpecifier, - ) -> Option { - // use the stored value or fall back to using the path of the main module. - if let Some(maybe_value) = &self.0 { - maybe_value.clone() - } else { - Some(main_module.to_string()) - } - } -} - /// Resolves the no_prompt value based on the cli flags and environment. pub fn resolve_no_prompt(flags: &PermissionFlags) -> bool { flags.no_prompt || has_flag_env_var("DENO_NO_PROMPT") } -pub fn has_trace_permissions_enabled() -> bool { - has_flag_env_var("DENO_TRACE_PERMISSIONS") -} - -pub fn has_flag_env_var(name: &str) -> bool { - let value = env::var(name); - matches!(value.as_ref().map(|s| s.as_str()), Ok("1")) -} - pub fn npm_pkg_req_ref_to_binary_command( req_ref: &NpmPackageReqReference, ) -> String { @@ -2160,27 +2120,6 @@ mod test { assert_eq!(actual, None); } - #[test] - fn storage_key_resolver_test() { - let resolver = StorageKeyResolver(None); - let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap(); - assert_eq!( - resolver.resolve_storage_key(&specifier), - Some(specifier.to_string()) - ); - let resolver = StorageKeyResolver(Some(None)); - assert_eq!(resolver.resolve_storage_key(&specifier), None); - let resolver = StorageKeyResolver(Some(Some("value".to_string()))); - assert_eq!( - resolver.resolve_storage_key(&specifier), - Some("value".to_string()) - ); - - // test empty - let resolver = StorageKeyResolver::empty(); - assert_eq!(resolver.resolve_storage_key(&specifier), None); - } - #[test] fn jsr_urls() { let reg_url = jsr_url(); diff --git a/cli/cache/caches.rs b/cli/cache/caches.rs index b83364c61b..dd4a974814 100644 --- a/cli/cache/caches.rs +++ b/cli/cache/caches.rs @@ -3,20 +3,21 @@ use std::path::PathBuf; use std::sync::Arc; +use deno_lib::cache::DenoDirProvider; use once_cell::sync::OnceCell; use super::cache_db::CacheDB; use super::cache_db::CacheDBConfiguration; use super::check::TYPE_CHECK_CACHE_DB; use super::code_cache::CODE_CACHE_DB; -use super::deno_dir::DenoDirProvider; use super::fast_check::FAST_CHECK_CACHE_DB; use super::incremental::INCREMENTAL_CACHE_DB; use super::module_info::MODULE_INFO_CACHE_DB; use super::node::NODE_ANALYSIS_CACHE_DB; +use crate::sys::CliSys; pub struct Caches { - dir_provider: Arc, + dir_provider: Arc>, fmt_incremental_cache_db: OnceCell, lint_incremental_cache_db: OnceCell, dep_analysis_db: OnceCell, @@ -27,7 +28,7 @@ pub struct Caches { } impl Caches { - pub fn new(dir: Arc) -> Self { + pub fn new(dir: Arc>) -> Self { Self { dir_provider: dir, fmt_incremental_cache_db: Default::default(), diff --git a/cli/cache/emit.rs b/cli/cache/emit.rs index 2ba43d58b9..e8a940b3be 100644 --- a/cli/cache/emit.rs +++ b/cli/cache/emit.rs @@ -6,19 +6,20 @@ use deno_ast::ModuleSpecifier; use deno_core::anyhow::anyhow; use deno_core::error::AnyError; use deno_core::unsync::sync::AtomicFlag; +use deno_lib::cache::DiskCache; -use super::DiskCache; +use crate::sys::CliSys; /// The cache that stores previously emitted files. #[derive(Debug)] pub struct EmitCache { - disk_cache: DiskCache, + disk_cache: DiskCache, emit_failed_flag: AtomicFlag, file_serializer: EmitFileSerializer, } impl EmitCache { - pub fn new(disk_cache: DiskCache) -> Self { + pub fn new(disk_cache: DiskCache) -> Self { Self { disk_cache, emit_failed_flag: Default::default(), diff --git a/cli/cache/mod.rs b/cli/cache/mod.rs index 0d7808cba6..e16f95e56f 100644 --- a/cli/cache/mod.rs +++ b/cli/cache/mod.rs @@ -31,8 +31,6 @@ mod caches; mod check; mod code_cache; mod common; -mod deno_dir; -mod disk_cache; mod emit; mod fast_check; mod incremental; @@ -47,9 +45,6 @@ pub use code_cache::CodeCache; pub use common::FastInsecureHasher; /// Permissions used to save a file in the disk caches. pub use deno_cache_dir::CACHE_PERM; -pub use deno_dir::DenoDir; -pub use deno_dir::DenoDirProvider; -pub use disk_cache::DiskCache; pub use emit::EmitCache; pub use fast_check::FastCheckCache; pub use incremental::IncrementalCache; diff --git a/cli/factory.rs b/cli/factory.rs index 3280fd379b..bfe6d05570 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -11,6 +11,12 @@ use deno_core::error::AnyError; use deno_core::futures::FutureExt; use deno_core::FeatureChecker; use deno_error::JsErrorBox; +use deno_lib::cache::DenoDir; +use deno_lib::cache::DenoDirProvider; +use deno_lib::npm::NpmRegistryReadPermissionChecker; +use deno_lib::npm::NpmRegistryReadPermissionCheckerMode; +use deno_lib::worker::LibMainWorkerFactory; +use deno_lib::worker::LibMainWorkerOptions; use deno_npm_cache::NpmCacheSetting; use deno_resolver::cjs::IsCjsResolutionMode; use deno_resolver::npm::managed::ManagedInNpmPkgCheckerCreateOptions; @@ -42,12 +48,9 @@ use crate::args::CliOptions; use crate::args::DenoSubcommand; use crate::args::Flags; use crate::args::NpmInstallDepsProvider; -use crate::args::StorageKeyResolver; use crate::args::TsConfigType; use crate::cache::Caches; use crate::cache::CodeCache; -use crate::cache::DenoDir; -use crate::cache::DenoDirProvider; use crate::cache::EmitCache; use crate::cache::GlobalHttpCache; use crate::cache::HttpCache; @@ -68,6 +71,7 @@ use crate::node::CliCjsCodeAnalyzer; use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; +use crate::npm::create_npm_process_state_provider; use crate::npm::installer::NpmInstaller; use crate::npm::installer::NpmResolutionInstaller; use crate::npm::CliByonmNpmResolverCreateOptions; @@ -79,8 +83,6 @@ use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolverCreateOptions; use crate::npm::CliNpmResolverManagedSnapshotOption; use crate::npm::CliNpmTarballCache; -use crate::npm::NpmRegistryReadPermissionChecker; -use crate::npm::NpmRegistryReadPermissionCheckerMode; use crate::npm::NpmResolutionInitializer; use crate::resolver::CliCjsTracker; use crate::resolver::CliDenoResolver; @@ -281,11 +283,13 @@ impl CliFactory { }) } - pub fn deno_dir_provider(&self) -> Result<&Arc, AnyError> { + pub fn deno_dir_provider( + &self, + ) -> Result<&Arc>, AnyError> { Ok(&self.cli_options()?.deno_dir_provider) } - pub fn deno_dir(&self) -> Result<&DenoDir, AnyError> { + pub fn deno_dir(&self) -> Result<&DenoDir, AnyError> { Ok(self.deno_dir_provider()?.get_or_create()?) } @@ -1083,7 +1087,34 @@ impl CliFactory { Arc::new(NpmRegistryReadPermissionChecker::new(self.sys(), mode)) }; - Ok(CliMainWorkerFactory::new( + let module_loader_factory = CliModuleLoaderFactory::new( + cli_options, + cjs_tracker, + if cli_options.code_cache_enabled() { + Some(self.code_cache()?.clone()) + } else { + None + }, + self.emitter()?.clone(), + in_npm_pkg_checker.clone(), + self.main_module_graph_container().await?.clone(), + self.module_load_preparer().await?.clone(), + node_code_translator.clone(), + node_resolver.clone(), + NpmModuleLoader::new( + self.cjs_tracker()?.clone(), + fs.clone(), + node_code_translator.clone(), + ), + npm_registry_permission_checker, + npm_req_resolver.clone(), + cli_npm_resolver.clone(), + self.parsed_source_cache().clone(), + self.resolver().await?.clone(), + self.sys(), + ); + + let lib_main_worker_factory = LibMainWorkerFactory::new( self.blob_store().clone(), if cli_options.code_cache_enabled() { Some(self.code_cache()?.clone()) @@ -1092,50 +1123,70 @@ impl CliFactory { }, self.feature_checker()?.clone(), fs.clone(), - maybe_file_watcher_communicator, self.maybe_inspector_server()?.clone(), + Box::new(module_loader_factory), + node_resolver.clone(), + create_npm_process_state_provider(npm_resolver), + pkg_json_resolver, + self.root_cert_store_provider().clone(), + cli_options.resolve_storage_key_resolver(), + self.sys(), + self.create_lib_main_worker_options()?, + ); + + Ok(CliMainWorkerFactory::new( + lib_main_worker_factory, + maybe_file_watcher_communicator, cli_options.maybe_lockfile().cloned(), - Box::new(CliModuleLoaderFactory::new( - cli_options, - cjs_tracker, - if cli_options.code_cache_enabled() { - Some(self.code_cache()?.clone()) - } else { - None - }, - self.emitter()?.clone(), - in_npm_pkg_checker.clone(), - self.main_module_graph_container().await?.clone(), - self.module_load_preparer().await?.clone(), - node_code_translator.clone(), - node_resolver.clone(), - NpmModuleLoader::new( - self.cjs_tracker()?.clone(), - fs.clone(), - node_code_translator.clone(), - ), - npm_registry_permission_checker, - npm_req_resolver.clone(), - cli_npm_resolver.clone(), - self.parsed_source_cache().clone(), - self.resolver().await?.clone(), - self.sys(), - )), node_resolver.clone(), self.npm_installer_if_managed()?.cloned(), npm_resolver.clone(), - pkg_json_resolver, - self.root_cert_store_provider().clone(), - self.root_permissions_container()?.clone(), - StorageKeyResolver::from_options(cli_options), self.sys(), - cli_options.sub_command().clone(), self.create_cli_main_worker_options()?, - self.cli_options()?.otel_config(), - self.cli_options()?.default_npm_caching_strategy(), + self.root_permissions_container()?.clone(), )) } + fn create_lib_main_worker_options( + &self, + ) -> Result { + let cli_options = self.cli_options()?; + Ok(LibMainWorkerOptions { + argv: cli_options.argv().clone(), + // This optimization is only available for "run" subcommand + // because we need to register new ops for testing and jupyter + // integration. + skip_op_registration: cli_options.sub_command().is_run(), + log_level: cli_options.log_level().unwrap_or(log::Level::Info).into(), + enable_op_summary_metrics: cli_options.enable_op_summary_metrics(), + enable_testing_features: cli_options.enable_testing_features(), + has_node_modules_dir: cli_options.has_node_modules_dir(), + inspect_brk: cli_options.inspect_brk().is_some(), + inspect_wait: cli_options.inspect_wait().is_some(), + strace_ops: cli_options.strace_ops().clone(), + is_inspecting: cli_options.is_inspecting(), + location: cli_options.location_flag().clone(), + // if the user ran a binary command, we'll need to set process.argv[0] + // to be the name of the binary command instead of deno + argv0: cli_options + .take_binary_npm_command_name() + .or(std::env::args().next()), + node_debug: std::env::var("NODE_DEBUG").ok(), + origin_data_folder_path: Some(self.deno_dir()?.origin_data_folder_path()), + seed: cli_options.seed(), + unsafely_ignore_certificate_errors: cli_options + .unsafely_ignore_certificate_errors() + .clone(), + node_ipc: cli_options.node_ipc_fd(), + serve_port: cli_options.serve_port(), + serve_host: cli_options.serve_host(), + deno_version: crate::version::DENO_VERSION_INFO.deno, + deno_user_agent: crate::version::DENO_VERSION_INFO.user_agent, + otel_config: self.cli_options()?.otel_config(), + startup_snapshot: crate::js::deno_isolate_init(), + }) + } + fn create_cli_main_worker_options( &self, ) -> Result { @@ -1167,37 +1218,10 @@ impl CliFactory { }; Ok(CliMainWorkerOptions { - argv: cli_options.argv().clone(), - // This optimization is only available for "run" subcommand - // because we need to register new ops for testing and jupyter - // integration. - skip_op_registration: cli_options.sub_command().is_run(), - log_level: cli_options.log_level().unwrap_or(log::Level::Info).into(), - enable_op_summary_metrics: cli_options.enable_op_summary_metrics(), - enable_testing_features: cli_options.enable_testing_features(), - has_node_modules_dir: cli_options.has_node_modules_dir(), - hmr: cli_options.has_hmr(), - inspect_brk: cli_options.inspect_brk().is_some(), - inspect_wait: cli_options.inspect_wait().is_some(), - strace_ops: cli_options.strace_ops().clone(), - is_inspecting: cli_options.is_inspecting(), - location: cli_options.location_flag().clone(), - // if the user ran a binary command, we'll need to set process.argv[0] - // to be the name of the binary command instead of deno - argv0: cli_options - .take_binary_npm_command_name() - .or(std::env::args().next()), - node_debug: std::env::var("NODE_DEBUG").ok(), - origin_data_folder_path: Some(self.deno_dir()?.origin_data_folder_path()), - seed: cli_options.seed(), - unsafely_ignore_certificate_errors: cli_options - .unsafely_ignore_certificate_errors() - .clone(), + needs_test_modules: cli_options.sub_command().needs_test(), create_hmr_runner, create_coverage_collector, - node_ipc: cli_options.node_ipc_fd(), - serve_port: cli_options.serve_port(), - serve_host: cli_options.serve_host(), + default_npm_caching_strategy: cli_options.default_npm_caching_strategy(), }) } } diff --git a/cli/lib/Cargo.toml b/cli/lib/Cargo.toml new file mode 100644 index 0000000000..6a74b22c2b --- /dev/null +++ b/cli/lib/Cargo.toml @@ -0,0 +1,37 @@ +# Copyright 2018-2025 the Deno authors. MIT license. + +[package] +name = "deno_lib" +version = "0.1.1" +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +repository.workspace = true +description = "Shared code between the Deno CLI and denort" + +[lib] +path = "lib.rs" + +[dependencies] +deno_cache_dir.workspace = true +deno_error.workspace = true +deno_fs = { workspace = true, features = ["sync_fs"] } +deno_node = { workspace = true, features = ["sync_fs"] } +deno_path_util.workspace = true +deno_resolver = { workspace = true, features = ["sync"] } +deno_runtime.workspace = true +deno_terminal.workspace = true +faster-hex.workspace = true +log.workspace = true +node_resolver = { workspace = true, features = ["sync"] } +parking_lot.workspace = true +ring.workspace = true +serde = { workspace = true, features = ["derive"] } +sys_traits.workspace = true +thiserror.workspace = true +tokio.workspace = true +url.workspace = true + +[dev-dependencies] +test_util.workspace = true diff --git a/cli/lib/README.md b/cli/lib/README.md new file mode 100644 index 0000000000..bc6d7b57d0 --- /dev/null +++ b/cli/lib/README.md @@ -0,0 +1,4 @@ +# deno_lib + +This crate contains the shared code between the Deno CLI and denort. It is +highly unstable. diff --git a/cli/cache/deno_dir.rs b/cli/lib/cache/deno_dir.rs similarity index 90% rename from cli/cache/deno_dir.rs rename to cli/lib/cache/deno_dir.rs index 1b35f53071..00bc83ff9b 100644 --- a/cli/cache/deno_dir.rs +++ b/cli/lib/cache/deno_dir.rs @@ -4,21 +4,20 @@ use std::env; use std::path::PathBuf; use deno_cache_dir::DenoDirResolutionError; -use once_cell::sync::OnceCell; use super::DiskCache; -use crate::sys::CliSys; +use crate::sys::DenoLibSys; /// Lazily creates the deno dir which might be useful in scenarios /// where functionality wants to continue if the DENO_DIR can't be created. -pub struct DenoDirProvider { - sys: CliSys, +pub struct DenoDirProvider { + sys: TSys, maybe_custom_root: Option, - deno_dir: OnceCell>, + deno_dir: std::sync::OnceLock, DenoDirResolutionError>>, } -impl DenoDirProvider { - pub fn new(sys: CliSys, maybe_custom_root: Option) -> Self { +impl DenoDirProvider { + pub fn new(sys: TSys, maybe_custom_root: Option) -> Self { Self { sys, maybe_custom_root, @@ -26,7 +25,9 @@ impl DenoDirProvider { } } - pub fn get_or_create(&self) -> Result<&DenoDir, DenoDirResolutionError> { + pub fn get_or_create( + &self, + ) -> Result<&DenoDir, DenoDirResolutionError> { self .deno_dir .get_or_init(|| { @@ -49,16 +50,16 @@ impl DenoDirProvider { /// `DenoDir` serves as coordinator for multiple `DiskCache`s containing them /// in single directory that can be controlled with `$DENO_DIR` env variable. #[derive(Debug, Clone)] -pub struct DenoDir { +pub struct DenoDir { /// Example: /Users/rld/.deno/ pub root: PathBuf, /// Used by TsCompiler to cache compiler output. - pub gen_cache: DiskCache, + pub gen_cache: DiskCache, } -impl DenoDir { +impl DenoDir { pub fn new( - sys: CliSys, + sys: TSys, maybe_custom_root: Option, ) -> Result { let root = deno_cache_dir::resolve_deno_dir( diff --git a/cli/cache/disk_cache.rs b/cli/lib/cache/disk_cache.rs similarity index 92% rename from cli/cache/disk_cache.rs rename to cli/lib/cache/disk_cache.rs index f03b60854f..2c735a34b2 100644 --- a/cli/cache/disk_cache.rs +++ b/cli/lib/cache/disk_cache.rs @@ -9,22 +9,22 @@ use std::path::Prefix; use std::str; use deno_cache_dir::url_to_filename; -use deno_core::url::Host; -use deno_core::url::Url; +use deno_cache_dir::CACHE_PERM; use deno_path_util::fs::atomic_write_file_with_retries; +use url::Host; +use url::Url; -use super::CACHE_PERM; -use crate::sys::CliSys; +use crate::sys::DenoLibSys; #[derive(Debug, Clone)] -pub struct DiskCache { - sys: CliSys, +pub struct DiskCache { + sys: TSys, pub location: PathBuf, } -impl DiskCache { +impl DiskCache { /// `location` must be an absolute path. - pub fn new(sys: CliSys, location: &Path) -> Self { + pub fn new(sys: TSys, location: &Path) -> Self { assert!(location.is_absolute()); Self { sys, @@ -130,6 +130,9 @@ impl DiskCache { #[cfg(test)] mod tests { + // ok, testing + #[allow(clippy::disallowed_types)] + use sys_traits::impls::RealSys; use test_util::TempDir; use super::*; @@ -138,7 +141,7 @@ mod tests { fn test_set_get_cache_file() { let temp_dir = TempDir::new(); let sub_dir = temp_dir.path().join("sub_dir"); - let cache = DiskCache::new(CliSys::default(), &sub_dir.to_path_buf()); + let cache = DiskCache::new(RealSys, &sub_dir.to_path_buf()); let path = PathBuf::from("foo/bar.txt"); cache.set(&path, b"hello").unwrap(); assert_eq!(cache.get(&path).unwrap(), b"hello"); @@ -152,7 +155,7 @@ mod tests { PathBuf::from("/deno_dir/") }; - let cache = DiskCache::new(CliSys::default(), &cache_location); + let cache = DiskCache::new(RealSys, &cache_location); let mut test_cases = vec![ ( @@ -208,7 +211,7 @@ mod tests { } else { "/foo" }; - let cache = DiskCache::new(CliSys::default(), &PathBuf::from(p)); + let cache = DiskCache::new(RealSys, &PathBuf::from(p)); let mut test_cases = vec![ ( @@ -256,7 +259,7 @@ mod tests { PathBuf::from("/deno_dir/") }; - let cache = DiskCache::new(CliSys::default(), &cache_location); + let cache = DiskCache::new(RealSys, &cache_location); let mut test_cases = vec!["unknown://localhost/test.ts"]; diff --git a/cli/lib/cache/mod.rs b/cli/lib/cache/mod.rs new file mode 100644 index 0000000000..c4395df3e1 --- /dev/null +++ b/cli/lib/cache/mod.rs @@ -0,0 +1,8 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +pub use deno_dir::DenoDir; +pub use deno_dir::DenoDirProvider; +pub use disk_cache::DiskCache; + +mod deno_dir; +mod disk_cache; diff --git a/cli/lib/env.rs b/cli/lib/env.rs new file mode 100644 index 0000000000..9c6001478b --- /dev/null +++ b/cli/lib/env.rs @@ -0,0 +1,10 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +pub fn has_trace_permissions_enabled() -> bool { + has_flag_env_var("DENO_TRACE_PERMISSIONS") +} + +pub fn has_flag_env_var(name: &str) -> bool { + let value = std::env::var(name); + matches!(value.as_ref().map(|s| s.as_str()), Ok("1")) +} diff --git a/cli/lib/lib.rs b/cli/lib/lib.rs new file mode 100644 index 0000000000..5453bddaee --- /dev/null +++ b/cli/lib/lib.rs @@ -0,0 +1,9 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +pub mod cache; +pub mod env; +pub mod npm; +pub mod standalone; +pub mod sys; +pub mod util; +pub mod worker; diff --git a/cli/lib/npm/mod.rs b/cli/lib/npm/mod.rs new file mode 100644 index 0000000000..e7d4d8d9d1 --- /dev/null +++ b/cli/lib/npm/mod.rs @@ -0,0 +1,6 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +mod permission_checker; + +pub use permission_checker::NpmRegistryReadPermissionChecker; +pub use permission_checker::NpmRegistryReadPermissionCheckerMode; diff --git a/cli/npm/permission_checker.rs b/cli/lib/npm/permission_checker.rs similarity index 92% rename from cli/npm/permission_checker.rs rename to cli/lib/npm/permission_checker.rs index 53031b5bd4..ebed1270f3 100644 --- a/cli/npm/permission_checker.rs +++ b/cli/lib/npm/permission_checker.rs @@ -6,12 +6,11 @@ use std::io::ErrorKind; use std::path::Path; use std::path::PathBuf; -use deno_core::parking_lot::Mutex; use deno_error::JsErrorBox; use deno_runtime::deno_node::NodePermissions; -use sys_traits::FsCanonicalize; +use parking_lot::Mutex; -use crate::sys::CliSys; +use crate::sys::DenoLibSys; #[derive(Debug)] pub enum NpmRegistryReadPermissionCheckerMode { @@ -21,8 +20,8 @@ pub enum NpmRegistryReadPermissionCheckerMode { } #[derive(Debug)] -pub struct NpmRegistryReadPermissionChecker { - sys: CliSys, +pub struct NpmRegistryReadPermissionChecker { + sys: TSys, cache: Mutex>, mode: NpmRegistryReadPermissionCheckerMode, } @@ -37,8 +36,8 @@ struct EnsureRegistryReadPermissionError { source: std::io::Error, } -impl NpmRegistryReadPermissionChecker { - pub fn new(sys: CliSys, mode: NpmRegistryReadPermissionCheckerMode) -> Self { +impl NpmRegistryReadPermissionChecker { + pub fn new(sys: TSys, mode: NpmRegistryReadPermissionCheckerMode) -> Self { Self { sys, cache: Default::default(), diff --git a/cli/lib/standalone/mod.rs b/cli/lib/standalone/mod.rs new file mode 100644 index 0000000000..6e173a457a --- /dev/null +++ b/cli/lib/standalone/mod.rs @@ -0,0 +1,3 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +pub mod virtual_fs; diff --git a/cli/lib/standalone/virtual_fs.rs b/cli/lib/standalone/virtual_fs.rs new file mode 100644 index 0000000000..5fc17f27b7 --- /dev/null +++ b/cli/lib/standalone/virtual_fs.rs @@ -0,0 +1,296 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +use std::cmp::Ordering; +use std::path::Path; +use std::path::PathBuf; + +use serde::Deserialize; +use serde::Serialize; + +#[derive(Debug, Copy, Clone)] +pub enum VfsFileSubDataKind { + /// Raw bytes of the file. + Raw, + /// Bytes to use for module loading. For example, for TypeScript + /// files this will be the transpiled JavaScript source. + ModuleGraph, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum WindowsSystemRootablePath { + /// The root of the system above any drive letters. + WindowSystemRoot, + Path(PathBuf), +} + +impl WindowsSystemRootablePath { + pub fn join(&self, name_component: &str) -> PathBuf { + // this method doesn't handle multiple components + debug_assert!( + !name_component.contains('\\'), + "Invalid component: {}", + name_component + ); + debug_assert!( + !name_component.contains('/'), + "Invalid component: {}", + name_component + ); + + match self { + WindowsSystemRootablePath::WindowSystemRoot => { + // windows drive letter + PathBuf::from(&format!("{}\\", name_component)) + } + WindowsSystemRootablePath::Path(path) => path.join(name_component), + } + } +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum FileSystemCaseSensitivity { + #[serde(rename = "s")] + Sensitive, + #[serde(rename = "i")] + Insensitive, +} +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct VirtualDirectoryEntries(Vec); + +impl VirtualDirectoryEntries { + pub fn new(mut entries: Vec) -> Self { + // needs to be sorted by name + entries.sort_by(|a, b| a.name().cmp(b.name())); + Self(entries) + } + + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, VfsEntry> { + self.0.iter_mut() + } + + pub fn iter(&self) -> std::slice::Iter<'_, VfsEntry> { + self.0.iter() + } + + pub fn take_inner(&mut self) -> Vec { + std::mem::take(&mut self.0) + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get_by_name( + &self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Option<&VfsEntry> { + self + .binary_search(name, case_sensitivity) + .ok() + .map(|index| &self.0[index]) + } + + pub fn get_mut_by_name( + &mut self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Option<&mut VfsEntry> { + self + .binary_search(name, case_sensitivity) + .ok() + .map(|index| &mut self.0[index]) + } + + pub fn get_mut_by_index(&mut self, index: usize) -> Option<&mut VfsEntry> { + self.0.get_mut(index) + } + + pub fn binary_search( + &self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + ) -> Result { + match case_sensitivity { + FileSystemCaseSensitivity::Sensitive => { + self.0.binary_search_by(|e| e.name().cmp(name)) + } + FileSystemCaseSensitivity::Insensitive => self.0.binary_search_by(|e| { + e.name() + .chars() + .zip(name.chars()) + .map(|(a, b)| a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase())) + .find(|&ord| ord != Ordering::Equal) + .unwrap_or_else(|| e.name().len().cmp(&name.len())) + }), + } + } + + pub fn insert( + &mut self, + entry: VfsEntry, + case_sensitivity: FileSystemCaseSensitivity, + ) -> usize { + match self.binary_search(entry.name(), case_sensitivity) { + Ok(index) => { + self.0[index] = entry; + index + } + Err(insert_index) => { + self.0.insert(insert_index, entry); + insert_index + } + } + } + + pub fn insert_or_modify( + &mut self, + name: &str, + case_sensitivity: FileSystemCaseSensitivity, + on_insert: impl FnOnce() -> VfsEntry, + on_modify: impl FnOnce(&mut VfsEntry), + ) -> usize { + match self.binary_search(name, case_sensitivity) { + Ok(index) => { + on_modify(&mut self.0[index]); + index + } + Err(insert_index) => { + self.0.insert(insert_index, on_insert()); + insert_index + } + } + } + + pub fn remove(&mut self, index: usize) -> VfsEntry { + self.0.remove(index) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct VirtualDirectory { + #[serde(rename = "n")] + pub name: String, + // should be sorted by name + #[serde(rename = "e")] + pub entries: VirtualDirectoryEntries, +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub struct OffsetWithLength { + #[serde(rename = "o")] + pub offset: u64, + #[serde(rename = "l")] + pub len: u64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct VirtualFile { + #[serde(rename = "n")] + pub name: String, + #[serde(rename = "o")] + pub offset: OffsetWithLength, + /// Offset file to use for module loading when it differs from the + /// raw file. Often this will be the same offset as above for data + /// such as JavaScript files, but for TypeScript files the `offset` + /// will be the original raw bytes when included as an asset and this + /// offset will be to the transpiled JavaScript source. + #[serde(rename = "m")] + pub module_graph_offset: OffsetWithLength, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct VirtualSymlinkParts(Vec); + +impl VirtualSymlinkParts { + pub fn from_path(path: &Path) -> Self { + Self( + path + .components() + .filter(|c| !matches!(c, std::path::Component::RootDir)) + .map(|c| c.as_os_str().to_string_lossy().to_string()) + .collect(), + ) + } + + pub fn take_parts(&mut self) -> Vec { + std::mem::take(&mut self.0) + } + + pub fn parts(&self) -> &[String] { + &self.0 + } + + pub fn set_parts(&mut self, parts: Vec) { + self.0 = parts; + } + + pub fn display(&self) -> String { + self.0.join("/") + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct VirtualSymlink { + #[serde(rename = "n")] + pub name: String, + #[serde(rename = "p")] + pub dest_parts: VirtualSymlinkParts, +} + +impl VirtualSymlink { + pub fn resolve_dest_from_root(&self, root: &Path) -> PathBuf { + let mut dest = root.to_path_buf(); + for part in &self.dest_parts.0 { + dest.push(part); + } + dest + } +} + +#[derive(Debug, Copy, Clone)] +pub enum VfsEntryRef<'a> { + Dir(&'a VirtualDirectory), + File(&'a VirtualFile), + Symlink(&'a VirtualSymlink), +} + +impl VfsEntryRef<'_> { + pub fn name(&self) -> &str { + match self { + Self::Dir(dir) => &dir.name, + Self::File(file) => &file.name, + Self::Symlink(symlink) => &symlink.name, + } + } +} + +// todo(dsherret): we should store this more efficiently in the binary +#[derive(Debug, Serialize, Deserialize)] +pub enum VfsEntry { + Dir(VirtualDirectory), + File(VirtualFile), + Symlink(VirtualSymlink), +} + +impl VfsEntry { + pub fn name(&self) -> &str { + match self { + Self::Dir(dir) => &dir.name, + Self::File(file) => &file.name, + Self::Symlink(symlink) => &symlink.name, + } + } + + pub fn as_ref(&self) -> VfsEntryRef { + match self { + VfsEntry::Dir(dir) => VfsEntryRef::Dir(dir), + VfsEntry::File(file) => VfsEntryRef::File(file), + VfsEntry::Symlink(symlink) => VfsEntryRef::Symlink(symlink), + } + } +} diff --git a/cli/lib/sys.rs b/cli/lib/sys.rs new file mode 100644 index 0000000000..f5ca48b41c --- /dev/null +++ b/cli/lib/sys.rs @@ -0,0 +1,37 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +use deno_node::ExtNodeSys; +use sys_traits::FsCanonicalize; +use sys_traits::FsCreateDirAll; +use sys_traits::FsMetadata; +use sys_traits::FsOpen; +use sys_traits::FsRead; +use sys_traits::FsReadDir; +use sys_traits::FsRemoveFile; +use sys_traits::FsRename; +use sys_traits::SystemRandom; +use sys_traits::ThreadSleep; + +pub trait DenoLibSys: + FsCanonicalize + + FsCreateDirAll + + FsReadDir + + FsMetadata + + FsOpen + + FsRemoveFile + + FsRename + + FsRead + + ThreadSleep + + SystemRandom + + ExtNodeSys + + Clone + + Send + + Sync + + std::fmt::Debug + + 'static +{ +} + +// ok, implementation +#[allow(clippy::disallowed_types)] +impl DenoLibSys for sys_traits::impls::RealSys {} diff --git a/cli/util/checksum.rs b/cli/lib/util/checksum.rs similarity index 100% rename from cli/util/checksum.rs rename to cli/lib/util/checksum.rs diff --git a/cli/lib/util/mod.rs b/cli/lib/util/mod.rs new file mode 100644 index 0000000000..8371440750 --- /dev/null +++ b/cli/lib/util/mod.rs @@ -0,0 +1,3 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +pub mod checksum; diff --git a/cli/lib/worker.rs b/cli/lib/worker.rs new file mode 100644 index 0000000000..7c9071d0ba --- /dev/null +++ b/cli/lib/worker.rs @@ -0,0 +1,581 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +use std::path::PathBuf; +use std::rc::Rc; +use std::sync::Arc; + +use deno_core::error::JsError; +use deno_node::NodeRequireLoaderRc; +use deno_resolver::npm::DenoInNpmPackageChecker; +use deno_resolver::npm::NpmResolver; +use deno_runtime::colors; +use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; +use deno_runtime::deno_core; +use deno_runtime::deno_core::error::CoreError; +use deno_runtime::deno_core::v8; +use deno_runtime::deno_core::CompiledWasmModuleStore; +use deno_runtime::deno_core::Extension; +use deno_runtime::deno_core::FeatureChecker; +use deno_runtime::deno_core::JsRuntime; +use deno_runtime::deno_core::LocalInspectorSession; +use deno_runtime::deno_core::ModuleLoader; +use deno_runtime::deno_core::SharedArrayBufferStore; +use deno_runtime::deno_fs; +use deno_runtime::deno_node::NodeExtInitServices; +use deno_runtime::deno_node::NodeRequireLoader; +use deno_runtime::deno_node::NodeResolver; +use deno_runtime::deno_permissions::PermissionsContainer; +use deno_runtime::deno_telemetry::OtelConfig; +use deno_runtime::deno_tls::RootCertStoreProvider; +use deno_runtime::deno_web::BlobStore; +use deno_runtime::fmt_errors::format_js_error; +use deno_runtime::inspector_server::InspectorServer; +use deno_runtime::ops::process::NpmProcessStateProviderRc; +use deno_runtime::ops::worker_host::CreateWebWorkerCb; +use deno_runtime::web_worker::WebWorker; +use deno_runtime::web_worker::WebWorkerOptions; +use deno_runtime::web_worker::WebWorkerServiceOptions; +use deno_runtime::worker::MainWorker; +use deno_runtime::worker::WorkerOptions; +use deno_runtime::worker::WorkerServiceOptions; +use deno_runtime::BootstrapOptions; +use deno_runtime::WorkerExecutionMode; +use deno_runtime::WorkerLogLevel; +use deno_runtime::UNSTABLE_GRANULAR_FLAGS; +use url::Url; + +use crate::env::has_trace_permissions_enabled; +use crate::sys::DenoLibSys; +use crate::util::checksum; + +pub struct CreateModuleLoaderResult { + pub module_loader: Rc, + pub node_require_loader: Rc, +} + +pub trait ModuleLoaderFactory: Send + Sync { + fn create_for_main( + &self, + root_permissions: PermissionsContainer, + ) -> CreateModuleLoaderResult; + + fn create_for_worker( + &self, + parent_permissions: PermissionsContainer, + permissions: PermissionsContainer, + ) -> CreateModuleLoaderResult; +} + +enum StorageKeyResolverStrategy { + Specified(Option), + UseMainModule, +} + +pub struct StorageKeyResolver(StorageKeyResolverStrategy); + +impl StorageKeyResolver { + pub fn from_flag(location: &Url) -> Self { + // if a location is set, then the ascii serialization of the location is + // used, unless the origin is opaque, and then no storage origin is set, as + // we can't expect the origin to be reproducible + let storage_origin = location.origin(); + Self(StorageKeyResolverStrategy::Specified( + if storage_origin.is_tuple() { + Some(storage_origin.ascii_serialization()) + } else { + None + }, + )) + } + + pub fn from_config_file_url(url: &Url) -> Self { + Self(StorageKeyResolverStrategy::Specified(Some(url.to_string()))) + } + + pub fn new_use_main_module() -> Self { + Self(StorageKeyResolverStrategy::UseMainModule) + } + + /// Creates a storage key resolver that will always resolve to being empty. + pub fn empty() -> Self { + Self(StorageKeyResolverStrategy::Specified(None)) + } + + /// Resolves the storage key to use based on the current flags, config, or main module. + pub fn resolve_storage_key(&self, main_module: &Url) -> Option { + // use the stored value or fall back to using the path of the main module. + match &self.0 { + StorageKeyResolverStrategy::Specified(value) => value.clone(), + StorageKeyResolverStrategy::UseMainModule => { + Some(main_module.to_string()) + } + } + } +} + +// TODO(bartlomieju): this should be moved to some other place, added to avoid string +// duplication between worker setups and `deno info` output. +pub fn get_cache_storage_dir() -> PathBuf { + // Note: we currently use temp_dir() to avoid managing storage size. + std::env::temp_dir().join("deno_cache") +} + +/// By default V8 uses 1.4Gb heap limit which is meant for browser tabs. +/// Instead probe for the total memory on the system and use it instead +/// as a default. +pub fn create_isolate_create_params() -> Option { + let maybe_mem_info = deno_runtime::deno_os::sys_info::mem_info(); + maybe_mem_info.map(|mem_info| { + v8::CreateParams::default() + .heap_limits_from_system_memory(mem_info.total, 0) + }) +} + +pub struct LibMainWorkerOptions { + pub argv: Vec, + pub deno_version: &'static str, + pub deno_user_agent: &'static str, + pub log_level: WorkerLogLevel, + pub enable_op_summary_metrics: bool, + pub enable_testing_features: bool, + pub has_node_modules_dir: bool, + pub inspect_brk: bool, + pub inspect_wait: bool, + pub strace_ops: Option>, + pub is_inspecting: bool, + pub location: Option, + pub argv0: Option, + pub node_debug: Option, + pub otel_config: OtelConfig, + pub origin_data_folder_path: Option, + pub seed: Option, + pub unsafely_ignore_certificate_errors: Option>, + pub skip_op_registration: bool, + pub node_ipc: Option, + pub startup_snapshot: Option<&'static [u8]>, + pub serve_port: Option, + pub serve_host: Option, +} + +struct LibWorkerFactorySharedState { + blob_store: Arc, + broadcast_channel: InMemoryBroadcastChannel, + code_cache: Option>, + compiled_wasm_module_store: CompiledWasmModuleStore, + feature_checker: Arc, + fs: Arc, + maybe_inspector_server: Option>, + module_loader_factory: Box, + node_resolver: + Arc, TSys>>, + npm_process_state_provider: NpmProcessStateProviderRc, + pkg_json_resolver: Arc>, + root_cert_store_provider: Arc, + shared_array_buffer_store: SharedArrayBufferStore, + storage_key_resolver: StorageKeyResolver, + sys: TSys, + options: LibMainWorkerOptions, +} + +impl LibWorkerFactorySharedState { + fn resolve_unstable_features( + &self, + feature_checker: &FeatureChecker, + ) -> Vec { + let mut unstable_features = + Vec::with_capacity(UNSTABLE_GRANULAR_FLAGS.len()); + for granular_flag in UNSTABLE_GRANULAR_FLAGS { + if feature_checker.check(granular_flag.name) { + unstable_features.push(granular_flag.id); + } + } + unstable_features + } + + fn create_node_init_services( + &self, + node_require_loader: NodeRequireLoaderRc, + ) -> NodeExtInitServices, TSys> { + NodeExtInitServices { + node_require_loader, + node_resolver: self.node_resolver.clone(), + pkg_json_resolver: self.pkg_json_resolver.clone(), + sys: self.sys.clone(), + } + } + + fn create_web_worker_callback( + self: &Arc, + stdio: deno_runtime::deno_io::Stdio, + ) -> Arc { + let shared = self.clone(); + Arc::new(move |args| { + let maybe_inspector_server = shared.maybe_inspector_server.clone(); + + let CreateModuleLoaderResult { + module_loader, + node_require_loader, + } = shared.module_loader_factory.create_for_worker( + args.parent_permissions.clone(), + args.permissions.clone(), + ); + let create_web_worker_cb = + shared.create_web_worker_callback(stdio.clone()); + + let maybe_storage_key = shared + .storage_key_resolver + .resolve_storage_key(&args.main_module); + let cache_storage_dir = maybe_storage_key.map(|key| { + // TODO(@satyarohith): storage quota management + get_cache_storage_dir().join(checksum::gen(&[key.as_bytes()])) + }); + + // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out + // list of enabled features. + let feature_checker = shared.feature_checker.clone(); + let unstable_features = + shared.resolve_unstable_features(feature_checker.as_ref()); + + let services = WebWorkerServiceOptions { + root_cert_store_provider: Some(shared.root_cert_store_provider.clone()), + module_loader, + fs: shared.fs.clone(), + node_services: Some( + shared.create_node_init_services(node_require_loader), + ), + blob_store: shared.blob_store.clone(), + broadcast_channel: shared.broadcast_channel.clone(), + shared_array_buffer_store: Some( + shared.shared_array_buffer_store.clone(), + ), + compiled_wasm_module_store: Some( + shared.compiled_wasm_module_store.clone(), + ), + maybe_inspector_server, + feature_checker, + npm_process_state_provider: Some( + shared.npm_process_state_provider.clone(), + ), + permissions: args.permissions, + }; + let options = WebWorkerOptions { + name: args.name, + main_module: args.main_module.clone(), + worker_id: args.worker_id, + bootstrap: BootstrapOptions { + deno_version: shared.options.deno_version.to_string(), + args: shared.options.argv.clone(), + cpu_count: std::thread::available_parallelism() + .map(|p| p.get()) + .unwrap_or(1), + log_level: shared.options.log_level, + enable_op_summary_metrics: shared.options.enable_op_summary_metrics, + enable_testing_features: shared.options.enable_testing_features, + locale: deno_core::v8::icu::get_language_tag(), + location: Some(args.main_module), + no_color: !colors::use_color(), + color_level: colors::get_color_level(), + is_stdout_tty: deno_terminal::is_stdout_tty(), + is_stderr_tty: deno_terminal::is_stderr_tty(), + unstable_features, + user_agent: shared.options.deno_user_agent.to_string(), + inspect: shared.options.is_inspecting, + has_node_modules_dir: shared.options.has_node_modules_dir, + argv0: shared.options.argv0.clone(), + node_debug: shared.options.node_debug.clone(), + node_ipc_fd: None, + mode: WorkerExecutionMode::Worker, + serve_port: shared.options.serve_port, + serve_host: shared.options.serve_host.clone(), + otel_config: shared.options.otel_config.clone(), + close_on_idle: args.close_on_idle, + }, + extensions: vec![], + startup_snapshot: shared.options.startup_snapshot, + create_params: create_isolate_create_params(), + unsafely_ignore_certificate_errors: shared + .options + .unsafely_ignore_certificate_errors + .clone(), + seed: shared.options.seed, + create_web_worker_cb, + format_js_error_fn: Some(Arc::new(format_js_error)), + worker_type: args.worker_type, + stdio: stdio.clone(), + cache_storage_dir, + strace_ops: shared.options.strace_ops.clone(), + close_on_idle: args.close_on_idle, + maybe_worker_metadata: args.maybe_worker_metadata, + enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(), + }; + + WebWorker::bootstrap_from_options(services, options) + }) + } +} + +pub struct LibMainWorkerFactory { + shared: Arc>, +} + +impl LibMainWorkerFactory { + #[allow(clippy::too_many_arguments)] + pub fn new( + blob_store: Arc, + code_cache: Option>, + feature_checker: Arc, + fs: Arc, + maybe_inspector_server: Option>, + module_loader_factory: Box, + node_resolver: Arc< + NodeResolver, TSys>, + >, + npm_process_state_provider: NpmProcessStateProviderRc, + pkg_json_resolver: Arc>, + root_cert_store_provider: Arc, + storage_key_resolver: StorageKeyResolver, + sys: TSys, + options: LibMainWorkerOptions, + ) -> Self { + Self { + shared: Arc::new(LibWorkerFactorySharedState { + blob_store, + broadcast_channel: Default::default(), + code_cache, + compiled_wasm_module_store: Default::default(), + feature_checker, + fs, + maybe_inspector_server, + module_loader_factory, + node_resolver, + npm_process_state_provider, + pkg_json_resolver, + root_cert_store_provider, + shared_array_buffer_store: Default::default(), + storage_key_resolver, + sys, + options, + }), + } + } + + pub fn create_custom_worker( + &self, + mode: WorkerExecutionMode, + main_module: Url, + permissions: PermissionsContainer, + custom_extensions: Vec, + stdio: deno_runtime::deno_io::Stdio, + ) -> Result { + let shared = &self.shared; + let CreateModuleLoaderResult { + module_loader, + node_require_loader, + } = shared + .module_loader_factory + .create_for_main(permissions.clone()); + + // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out + // list of enabled features. + let feature_checker = shared.feature_checker.clone(); + let unstable_features = + shared.resolve_unstable_features(feature_checker.as_ref()); + let maybe_storage_key = shared + .storage_key_resolver + .resolve_storage_key(&main_module); + let origin_storage_dir = maybe_storage_key.as_ref().map(|key| { + shared + .options + .origin_data_folder_path + .as_ref() + .unwrap() // must be set if storage key resolver returns a value + .join(checksum::gen(&[key.as_bytes()])) + }); + let cache_storage_dir = maybe_storage_key.map(|key| { + // TODO(@satyarohith): storage quota management + get_cache_storage_dir().join(checksum::gen(&[key.as_bytes()])) + }); + + let services = WorkerServiceOptions { + root_cert_store_provider: Some(shared.root_cert_store_provider.clone()), + module_loader, + fs: shared.fs.clone(), + node_services: Some( + shared.create_node_init_services(node_require_loader), + ), + npm_process_state_provider: Some( + shared.npm_process_state_provider.clone(), + ), + blob_store: shared.blob_store.clone(), + broadcast_channel: shared.broadcast_channel.clone(), + fetch_dns_resolver: Default::default(), + shared_array_buffer_store: Some(shared.shared_array_buffer_store.clone()), + compiled_wasm_module_store: Some( + shared.compiled_wasm_module_store.clone(), + ), + feature_checker, + permissions, + v8_code_cache: shared.code_cache.clone(), + }; + + let options = WorkerOptions { + bootstrap: BootstrapOptions { + deno_version: shared.options.deno_version.to_string(), + args: shared.options.argv.clone(), + cpu_count: std::thread::available_parallelism() + .map(|p| p.get()) + .unwrap_or(1), + log_level: shared.options.log_level, + enable_op_summary_metrics: shared.options.enable_op_summary_metrics, + enable_testing_features: shared.options.enable_testing_features, + locale: deno_core::v8::icu::get_language_tag(), + location: shared.options.location.clone(), + no_color: !colors::use_color(), + is_stdout_tty: deno_terminal::is_stdout_tty(), + is_stderr_tty: deno_terminal::is_stderr_tty(), + color_level: colors::get_color_level(), + unstable_features, + user_agent: shared.options.deno_user_agent.to_string(), + inspect: shared.options.is_inspecting, + has_node_modules_dir: shared.options.has_node_modules_dir, + argv0: shared.options.argv0.clone(), + node_debug: shared.options.node_debug.clone(), + node_ipc_fd: shared.options.node_ipc, + mode, + serve_port: shared.options.serve_port, + serve_host: shared.options.serve_host.clone(), + otel_config: shared.options.otel_config.clone(), + close_on_idle: true, + }, + extensions: custom_extensions, + startup_snapshot: shared.options.startup_snapshot, + create_params: create_isolate_create_params(), + unsafely_ignore_certificate_errors: shared + .options + .unsafely_ignore_certificate_errors + .clone(), + seed: shared.options.seed, + format_js_error_fn: Some(Arc::new(format_js_error)), + create_web_worker_cb: shared.create_web_worker_callback(stdio.clone()), + maybe_inspector_server: shared.maybe_inspector_server.clone(), + should_break_on_first_statement: shared.options.inspect_brk, + should_wait_for_inspector_session: shared.options.inspect_wait, + strace_ops: shared.options.strace_ops.clone(), + cache_storage_dir, + origin_storage_dir, + stdio, + skip_op_registration: shared.options.skip_op_registration, + enable_stack_trace_arg_in_ops: has_trace_permissions_enabled(), + }; + + let worker = + MainWorker::bootstrap_from_options(&main_module, services, options); + + Ok(LibMainWorker { + main_module, + worker, + }) + } +} + +pub struct LibMainWorker { + main_module: Url, + worker: MainWorker, +} + +impl LibMainWorker { + pub fn into_main_worker(self) -> MainWorker { + self.worker + } + + pub fn main_module(&self) -> &Url { + &self.main_module + } + + pub fn js_runtime(&mut self) -> &mut JsRuntime { + &mut self.worker.js_runtime + } + + #[inline] + pub fn create_inspector_session(&mut self) -> LocalInspectorSession { + self.worker.create_inspector_session() + } + + #[inline] + pub fn dispatch_load_event(&mut self) -> Result<(), JsError> { + self.worker.dispatch_load_event() + } + + #[inline] + pub fn dispatch_beforeunload_event(&mut self) -> Result { + self.worker.dispatch_beforeunload_event() + } + + #[inline] + pub fn dispatch_process_beforeexit_event(&mut self) -> Result { + self.worker.dispatch_process_beforeexit_event() + } + + #[inline] + pub fn dispatch_unload_event(&mut self) -> Result<(), JsError> { + self.worker.dispatch_unload_event() + } + + #[inline] + pub fn dispatch_process_exit_event(&mut self) -> Result<(), JsError> { + self.worker.dispatch_process_exit_event() + } + + pub async fn execute_main_module(&mut self) -> Result<(), CoreError> { + let id = self.worker.preload_main_module(&self.main_module).await?; + self.worker.evaluate_module(id).await + } + + pub async fn execute_side_module(&mut self) -> Result<(), CoreError> { + let id = self.worker.preload_side_module(&self.main_module).await?; + self.worker.evaluate_module(id).await + } + + #[inline] + pub async fn run_event_loop( + &mut self, + wait_for_inspector: bool, + ) -> Result<(), CoreError> { + self.worker.run_event_loop(wait_for_inspector).await + } + + #[inline] + pub fn exit_code(&self) -> i32 { + self.worker.exit_code() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn storage_key_resolver_test() { + let resolver = + StorageKeyResolver(StorageKeyResolverStrategy::UseMainModule); + let specifier = Url::parse("file:///a.ts").unwrap(); + assert_eq!( + resolver.resolve_storage_key(&specifier), + Some(specifier.to_string()) + ); + let resolver = + StorageKeyResolver(StorageKeyResolverStrategy::Specified(None)); + assert_eq!(resolver.resolve_storage_key(&specifier), None); + let resolver = StorageKeyResolver(StorageKeyResolverStrategy::Specified( + Some("value".to_string()), + )); + assert_eq!( + resolver.resolve_storage_key(&specifier), + Some("value".to_string()) + ); + + // test empty + let resolver = StorageKeyResolver::empty(); + assert_eq!(resolver.resolve_storage_key(&specifier), None); + } +} diff --git a/cli/lsp/cache.rs b/cli/lsp/cache.rs index 97fbbaff14..a65bbd5efe 100644 --- a/cli/lsp/cache.rs +++ b/cli/lsp/cache.rs @@ -8,9 +8,9 @@ use std::time::SystemTime; use deno_core::url::Url; use deno_core::ModuleSpecifier; +use deno_lib::cache::DenoDir; use deno_path_util::url_to_file_path; -use crate::cache::DenoDir; use crate::cache::GlobalHttpCache; use crate::cache::HttpCache; use crate::cache::LocalLspHttpCache; @@ -70,7 +70,7 @@ fn calculate_fs_version_in_cache( #[derive(Debug, Clone)] pub struct LspCache { - deno_dir: DenoDir, + deno_dir: DenoDir, global: Arc, vendors_by_scope: BTreeMap>>, } @@ -121,7 +121,7 @@ impl LspCache { .collect(); } - pub fn deno_dir(&self) -> &DenoDir { + pub fn deno_dir(&self) -> &DenoDir { &self.deno_dir } diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index ba57502298..98c4498a1a 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -41,6 +41,7 @@ use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::url::Url; use deno_core::ModuleSpecifier; +use deno_lib::env::has_flag_env_var; use deno_lint::linter::LintConfig as DenoLintConfig; use deno_npm::npm_rc::ResolvedNpmRc; use deno_package_json::PackageJsonCache; @@ -55,7 +56,6 @@ use super::logging::lsp_log; use super::lsp_custom; use super::urls::url_to_uri; use crate::args::discover_npmrc_from_workspace; -use crate::args::has_flag_env_var; use crate::args::CliLockfile; use crate::args::CliLockfileReadFromPathOptions; use crate::args::ConfigFile; diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index fe8dc4c8d5..3e3e31de28 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -265,7 +265,7 @@ impl TsDiagnosticsStore { } pub fn should_send_diagnostic_batch_index_notifications() -> bool { - crate::args::has_flag_env_var( + deno_lib::env::has_flag_env_var( "DENO_DONT_USE_INTERNAL_LSP_DIAGNOSTIC_SYNC_FLAG", ) } diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index 0f3bfcdf59..c2fddc08bd 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -27,6 +27,7 @@ use deno_core::url::Url; use deno_core::ModuleSpecifier; use deno_graph::GraphKind; use deno_graph::Resolution; +use deno_lib::env::has_flag_env_var; use deno_path_util::url_to_file_path; use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::RootCertStoreProvider; @@ -95,7 +96,6 @@ use super::urls::uri_to_url; use super::urls::url_to_uri; use crate::args::create_default_npmrc; use crate::args::get_root_cert_store; -use crate::args::has_flag_env_var; use crate::args::CaData; use crate::args::CliOptions; use crate::args::Flags; diff --git a/cli/lsp/testing/definitions.rs b/cli/lsp/testing/definitions.rs index 8277dcbf00..d6630c1844 100644 --- a/cli/lsp/testing/definitions.rs +++ b/cli/lsp/testing/definitions.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; use deno_core::error::AnyError; use deno_core::ModuleSpecifier; +use deno_lib::util::checksum; use lsp::Range; use tower_lsp::lsp_types as lsp; @@ -15,7 +16,6 @@ use crate::lsp::logging::lsp_warn; use crate::lsp::urls::url_to_uri; use crate::tools::test::TestDescription; use crate::tools::test::TestStepDescription; -use crate::util::checksum; #[derive(Debug, Clone, PartialEq)] pub struct TestDefinition { diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index e2a0fc430d..0b53dc8506 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -39,6 +39,7 @@ use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_core::PollEventLoopOptions; use deno_core::RuntimeOptions; +use deno_lib::worker::create_isolate_create_params; use deno_path_util::url_to_file_path; use deno_runtime::deno_node::SUPPORTED_BUILTIN_NODE_MODULES; use deno_runtime::inspector_server::InspectorServer; @@ -96,7 +97,6 @@ use crate::util::path::relative_specifier; use crate::util::path::to_percent_decoded_str; use crate::util::result::InfallibleResultExt; use crate::util::v8::convert; -use crate::worker::create_isolate_create_params; static BRACKET_ACCESSOR_RE: Lazy = lazy_regex!(r#"^\[['"](.+)[\['"]\]$"#); diff --git a/cli/lsp/urls.rs b/cli/lsp/urls.rs index 2aadaf5352..068e4ad4d5 100644 --- a/cli/lsp/urls.rs +++ b/cli/lsp/urls.rs @@ -81,7 +81,7 @@ fn hash_data_specifier(specifier: &ModuleSpecifier) -> String { file_name_str.push('?'); file_name_str.push_str(query); } - crate::util::checksum::gen(&[file_name_str.as_bytes()]) + deno_lib::util::checksum::gen(&[file_name_str.as_bytes()]) } fn to_deno_uri(specifier: &Url) -> String { diff --git a/cli/module_loader.rs b/cli/module_loader.rs index daeb4dda37..2b0ebca986 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -39,6 +39,9 @@ use deno_graph::ModuleGraph; use deno_graph::ModuleGraphError; use deno_graph::Resolution; use deno_graph::WasmModule; +use deno_lib::npm::NpmRegistryReadPermissionChecker; +use deno_lib::worker::CreateModuleLoaderResult; +use deno_lib::worker::ModuleLoaderFactory; use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::code_cache; use deno_runtime::deno_node::create_host_defined_options; @@ -70,7 +73,6 @@ use crate::graph_util::ModuleGraphBuilder; use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::npm::CliNpmResolver; -use crate::npm::NpmRegistryReadPermissionChecker; use crate::resolver::CliCjsTracker; use crate::resolver::CliNpmReqResolver; use crate::resolver::CliResolver; @@ -84,8 +86,6 @@ use crate::tools::check::TypeChecker; use crate::util::progress_bar::ProgressBar; use crate::util::text_encoding::code_without_source_map; use crate::util::text_encoding::source_map_from_code; -use crate::worker::CreateModuleLoaderResult; -use crate::worker::ModuleLoaderFactory; #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum PrepareModuleLoadError { @@ -243,7 +243,8 @@ struct SharedCliModuleLoaderState { node_code_translator: Arc, node_resolver: Arc, npm_module_loader: NpmModuleLoader, - npm_registry_permission_checker: Arc, + npm_registry_permission_checker: + Arc>, npm_req_resolver: Arc, npm_resolver: CliNpmResolver, parsed_source_cache: Arc, @@ -304,7 +305,9 @@ impl CliModuleLoaderFactory { node_code_translator: Arc, node_resolver: Arc, npm_module_loader: NpmModuleLoader, - npm_registry_permission_checker: Arc, + npm_registry_permission_checker: Arc< + NpmRegistryReadPermissionChecker, + >, npm_req_resolver: Arc, npm_resolver: CliNpmResolver, parsed_source_cache: Arc, @@ -1145,7 +1148,8 @@ struct CliNodeRequireLoader { sys: CliSys, graph_container: TGraphContainer, in_npm_pkg_checker: DenoInNpmPackageChecker, - npm_registry_permission_checker: Arc, + npm_registry_permission_checker: + Arc>, } impl NodeRequireLoader diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index 1c12ce6c59..fc0916cc18 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -3,7 +3,6 @@ mod byonm; pub mod installer; mod managed; -mod permission_checker; use std::sync::Arc; @@ -24,8 +23,6 @@ pub use self::managed::CliManagedNpmResolverCreateOptions; pub use self::managed::CliNpmResolverManagedSnapshotOption; pub use self::managed::NpmResolutionInitializer; pub use self::managed::ResolveSnapshotError; -pub use self::permission_checker::NpmRegistryReadPermissionChecker; -pub use self::permission_checker::NpmRegistryReadPermissionCheckerMode; use crate::file_fetcher::CliFileFetcher; use crate::http_util::HttpClientProvider; use crate::sys::CliSys; diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index c9b57f3d6b..5334b4719d 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -38,6 +38,13 @@ use deno_core::futures::AsyncSeekExt; use deno_core::serde_json; use deno_core::url::Url; use deno_graph::ModuleGraph; +use deno_lib::cache::DenoDir; +use deno_lib::standalone::virtual_fs::FileSystemCaseSensitivity; +use deno_lib::standalone::virtual_fs::VfsEntry; +use deno_lib::standalone::virtual_fs::VfsFileSubDataKind; +use deno_lib::standalone::virtual_fs::VirtualDirectory; +use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries; +use deno_lib::standalone::virtual_fs::WindowsSystemRootablePath; use deno_npm::resolution::SerializedNpmResolutionSnapshot; use deno_npm::resolution::SerializedNpmResolutionSnapshotPackage; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; @@ -73,20 +80,14 @@ use super::serialization::SourceMapStore; use super::virtual_fs::output_vfs; use super::virtual_fs::BuiltVfs; use super::virtual_fs::FileBackedVfs; -use super::virtual_fs::FileSystemCaseSensitivity; use super::virtual_fs::VfsBuilder; -use super::virtual_fs::VfsFileSubDataKind; use super::virtual_fs::VfsRoot; -use super::virtual_fs::VirtualDirectory; -use super::virtual_fs::VirtualDirectoryEntries; -use super::virtual_fs::WindowsSystemRootablePath; use crate::args::CaData; use crate::args::CliOptions; use crate::args::CompileFlags; use crate::args::NpmInstallDepsProvider; use crate::args::PermissionFlags; use crate::args::UnstableConfig; -use crate::cache::DenoDir; use crate::cache::FastInsecureHasher; use crate::emit::Emitter; use crate::file_fetcher::CliFileFetcher; @@ -94,7 +95,7 @@ use crate::http_util::HttpClientProvider; use crate::npm::CliNpmResolver; use crate::resolver::CliCjsTracker; use crate::shared::ReleaseChannel; -use crate::standalone::virtual_fs::VfsEntry; +use crate::sys::CliSys; use crate::util::archive; use crate::util::fs::canonicalize_path; use crate::util::fs::canonicalize_path_maybe_not_exists; @@ -411,7 +412,7 @@ pub struct WriteBinOptions<'a> { pub struct DenoCompileBinaryWriter<'a> { cjs_tracker: &'a CliCjsTracker, cli_options: &'a CliOptions, - deno_dir: &'a DenoDir, + deno_dir: &'a DenoDir, emitter: &'a Emitter, file_fetcher: &'a CliFileFetcher, http_client_provider: &'a HttpClientProvider, @@ -425,7 +426,7 @@ impl<'a> DenoCompileBinaryWriter<'a> { pub fn new( cjs_tracker: &'a CliCjsTracker, cli_options: &'a CliOptions, - deno_dir: &'a DenoDir, + deno_dir: &'a DenoDir, emitter: &'a Emitter, file_fetcher: &'a CliFileFetcher, http_client_provider: &'a HttpClientProvider, diff --git a/cli/standalone/file_system.rs b/cli/standalone/file_system.rs index b04db88c90..c4b3ebe728 100644 --- a/cli/standalone/file_system.rs +++ b/cli/standalone/file_system.rs @@ -9,6 +9,7 @@ use std::sync::Arc; use std::time::Duration; use std::time::SystemTime; +use deno_lib::standalone::virtual_fs::VfsFileSubDataKind; use deno_runtime::deno_fs::AccessCheckCb; use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_fs::FsDirEntry; @@ -30,7 +31,6 @@ use super::virtual_fs::FileBackedVfs; use super::virtual_fs::FileBackedVfsDirEntry; use super::virtual_fs::FileBackedVfsFile; use super::virtual_fs::FileBackedVfsMetadata; -use super::virtual_fs::VfsFileSubDataKind; #[derive(Debug, Clone)] pub struct DenoCompileFileSystem(Arc); diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index 876c194ed1..f2a0859e8f 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -36,6 +36,15 @@ use deno_core::RequestedModuleType; use deno_core::ResolutionKind; use deno_core::SourceCodeCacheInfo; use deno_error::JsErrorBox; +use deno_lib::cache::DenoDirProvider; +use deno_lib::npm::NpmRegistryReadPermissionChecker; +use deno_lib::npm::NpmRegistryReadPermissionCheckerMode; +use deno_lib::standalone::virtual_fs::VfsFileSubDataKind; +use deno_lib::worker::CreateModuleLoaderResult; +use deno_lib::worker::LibMainWorkerFactory; +use deno_lib::worker::LibMainWorkerOptions; +use deno_lib::worker::ModuleLoaderFactory; +use deno_lib::worker::StorageKeyResolver; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::resolution::NpmResolutionSnapshot; use deno_package_json::PackageJsonDepValue; @@ -69,16 +78,13 @@ use node_resolver::ResolutionMode; use serialization::DenoCompileModuleSource; use serialization::SourceMapStore; use virtual_fs::FileBackedVfs; -use virtual_fs::VfsFileSubDataKind; use crate::args::create_default_npmrc; use crate::args::get_root_cert_store; use crate::args::npm_pkg_req_ref_to_binary_command; use crate::args::CaData; use crate::args::NpmInstallDepsProvider; -use crate::args::StorageKeyResolver; use crate::cache::Caches; -use crate::cache::DenoDirProvider; use crate::cache::FastInsecureHasher; use crate::cache::NodeAnalysisCache; use crate::http_util::HttpClientProvider; @@ -86,13 +92,12 @@ use crate::node::CliCjsCodeAnalyzer; use crate::node::CliNodeCodeTranslator; use crate::node::CliNodeResolver; use crate::node::CliPackageJsonResolver; +use crate::npm::create_npm_process_state_provider; use crate::npm::CliByonmNpmResolverCreateOptions; use crate::npm::CliManagedNpmResolverCreateOptions; use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolverCreateOptions; use crate::npm::CliNpmResolverManagedSnapshotOption; -use crate::npm::NpmRegistryReadPermissionChecker; -use crate::npm::NpmRegistryReadPermissionCheckerMode; use crate::npm::NpmResolutionInitializer; use crate::resolver::CliCjsTracker; use crate::resolver::CliNpmReqResolver; @@ -105,8 +110,6 @@ use crate::util::v8::construct_v8_flags; use crate::worker::CliCodeCache; use crate::worker::CliMainWorkerFactory; use crate::worker::CliMainWorkerOptions; -use crate::worker::CreateModuleLoaderResult; -use crate::worker::ModuleLoaderFactory; pub mod binary; mod code_cache; @@ -129,7 +132,7 @@ struct SharedModuleLoaderState { node_code_translator: Arc, node_resolver: Arc, npm_module_loader: Arc, - npm_registry_permission_checker: NpmRegistryReadPermissionChecker, + npm_registry_permission_checker: NpmRegistryReadPermissionChecker, npm_req_resolver: Arc, npm_resolver: CliNpmResolver, source_maps: SourceMapStore, @@ -962,54 +965,67 @@ pub async fn run( } checker }); - let worker_factory = CliMainWorkerFactory::new( + let lib_main_worker_options = LibMainWorkerOptions { + argv: metadata.argv, + log_level: WorkerLogLevel::Info, + enable_op_summary_metrics: false, + enable_testing_features: false, + has_node_modules_dir, + inspect_brk: false, + inspect_wait: false, + strace_ops: None, + is_inspecting: false, + skip_op_registration: true, + location: metadata.location, + argv0: NpmPackageReqReference::from_specifier(&main_module) + .ok() + .map(|req_ref| npm_pkg_req_ref_to_binary_command(&req_ref)) + .or(std::env::args().next()), + node_debug: std::env::var("NODE_DEBUG").ok(), + origin_data_folder_path: None, + seed: metadata.seed, + unsafely_ignore_certificate_errors: metadata + .unsafely_ignore_certificate_errors, + node_ipc: None, + serve_port: None, + serve_host: None, + deno_version: crate::version::DENO_VERSION_INFO.deno, + deno_user_agent: crate::version::DENO_VERSION_INFO.user_agent, + otel_config: metadata.otel_config, + startup_snapshot: crate::js::deno_isolate_init(), + }; + let lib_main_worker_factory = LibMainWorkerFactory::new( Arc::new(BlobStore::default()), - code_cache, + code_cache.map(|c| c.as_code_cache()), feature_checker, fs, None, - None, - None, Box::new(module_loader_factory), + node_resolver.clone(), + create_npm_process_state_provider(&npm_resolver), + pkg_json_resolver, + root_cert_store_provider, + StorageKeyResolver::empty(), + sys.clone(), + lib_main_worker_options, + ); + // todo(dsherret): use LibMainWorker directly here and don't use CliMainWorkerFactory + let cli_main_worker_options = CliMainWorkerOptions { + create_hmr_runner: None, + create_coverage_collector: None, + needs_test_modules: false, + default_npm_caching_strategy: crate::args::NpmCachingStrategy::Lazy, + }; + let worker_factory = CliMainWorkerFactory::new( + lib_main_worker_factory, + None, + None, node_resolver, None, npm_resolver, - pkg_json_resolver, - root_cert_store_provider, - permissions, - StorageKeyResolver::empty(), sys, - crate::args::DenoSubcommand::Run(Default::default()), - CliMainWorkerOptions { - argv: metadata.argv, - log_level: WorkerLogLevel::Info, - enable_op_summary_metrics: false, - enable_testing_features: false, - has_node_modules_dir, - hmr: false, - inspect_brk: false, - inspect_wait: false, - strace_ops: None, - is_inspecting: false, - skip_op_registration: true, - location: metadata.location, - argv0: NpmPackageReqReference::from_specifier(&main_module) - .ok() - .map(|req_ref| npm_pkg_req_ref_to_binary_command(&req_ref)) - .or(std::env::args().next()), - node_debug: std::env::var("NODE_DEBUG").ok(), - origin_data_folder_path: None, - seed: metadata.seed, - unsafely_ignore_certificate_errors: metadata - .unsafely_ignore_certificate_errors, - create_hmr_runner: None, - create_coverage_collector: None, - node_ipc: None, - serve_port: None, - serve_host: None, - }, - metadata.otel_config, - crate::args::NpmCachingStrategy::Lazy, + cli_main_worker_options, + permissions, ); // Initialize v8 once from the main thread. diff --git a/cli/standalone/serialization.rs b/cli/standalone/serialization.rs index ae2e411b5f..ab345917a3 100644 --- a/cli/standalone/serialization.rs +++ b/cli/standalone/serialization.rs @@ -17,6 +17,7 @@ use deno_core::url::Url; use deno_core::FastString; use deno_core::ModuleSourceCode; use deno_core::ModuleType; +use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries; use deno_npm::resolution::SerializedNpmResolutionSnapshot; use deno_npm::resolution::SerializedNpmResolutionSnapshotPackage; use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; @@ -27,10 +28,7 @@ use indexmap::IndexMap; use super::binary::Metadata; use super::virtual_fs::BuiltVfs; -use super::virtual_fs::FileSystemCaseSensitivity; use super::virtual_fs::VfsBuilder; -use super::virtual_fs::VirtualDirectoryEntries; -use crate::standalone::virtual_fs::VirtualDirectory; const MAGIC_BYTES: &[u8; 8] = b"d3n0l4nd"; diff --git a/cli/standalone/virtual_fs.rs b/cli/standalone/virtual_fs.rs index 0b1f33259d..4f761d0d15 100644 --- a/cli/standalone/virtual_fs.rs +++ b/cli/standalone/virtual_fs.rs @@ -23,6 +23,17 @@ use deno_core::parking_lot::Mutex; use deno_core::BufMutView; use deno_core::BufView; use deno_core::ResourceHandleFd; +use deno_lib::standalone::virtual_fs::FileSystemCaseSensitivity; +use deno_lib::standalone::virtual_fs::OffsetWithLength; +use deno_lib::standalone::virtual_fs::VfsEntry; +use deno_lib::standalone::virtual_fs::VfsEntryRef; +use deno_lib::standalone::virtual_fs::VfsFileSubDataKind; +use deno_lib::standalone::virtual_fs::VirtualDirectory; +use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries; +use deno_lib::standalone::virtual_fs::VirtualFile; +use deno_lib::standalone::virtual_fs::VirtualSymlink; +use deno_lib::standalone::virtual_fs::VirtualSymlinkParts; +use deno_lib::standalone::virtual_fs::WindowsSystemRootablePath; use deno_path_util::normalize_path; use deno_path_util::strip_unc_prefix; use deno_runtime::deno_fs::FsDirEntry; @@ -41,37 +52,6 @@ use crate::util::display::human_size; use crate::util::display::DisplayTreeNode; use crate::util::fs::canonicalize_path; -#[derive(Debug, PartialEq, Eq)] -pub enum WindowsSystemRootablePath { - /// The root of the system above any drive letters. - WindowSystemRoot, - Path(PathBuf), -} - -impl WindowsSystemRootablePath { - pub fn join(&self, name_component: &str) -> PathBuf { - // this method doesn't handle multiple components - debug_assert!( - !name_component.contains('\\'), - "Invalid component: {}", - name_component - ); - debug_assert!( - !name_component.contains('/'), - "Invalid component: {}", - name_component - ); - - match self { - WindowsSystemRootablePath::WindowSystemRoot => { - // windows drive letter - PathBuf::from(&format!("{}\\", name_component)) - } - WindowsSystemRootablePath::Path(path) => path.join(name_component), - } - } -} - #[derive(Debug)] pub struct BuiltVfs { pub root_path: WindowsSystemRootablePath, @@ -80,15 +60,6 @@ pub struct BuiltVfs { pub files: Vec>, } -#[derive(Debug, Copy, Clone)] -pub enum VfsFileSubDataKind { - /// Raw bytes of the file. - Raw, - /// Bytes to use for module loading. For example, for TypeScript - /// files this will be the transpiled JavaScript source. - ModuleGraph, -} - #[derive(Debug)] pub struct VfsBuilder { executable_root: VirtualDirectory, @@ -232,24 +203,21 @@ impl VfsBuilder { continue; } let name = component.as_os_str().to_string_lossy(); - let index = match current_dir - .entries - .binary_search(&name, self.case_sensitivity) - { - Ok(index) => index, - Err(insert_index) => { - current_dir.entries.0.insert( - insert_index, - VfsEntry::Dir(VirtualDirectory { - name: name.to_string(), - entries: Default::default(), - }), - ); - insert_index - } - }; - match &mut current_dir.entries.0[index] { - VfsEntry::Dir(dir) => { + let index = current_dir.entries.insert_or_modify( + &name, + self.case_sensitivity, + || { + VfsEntry::Dir(VirtualDirectory { + name: name.to_string(), + entries: Default::default(), + }) + }, + |_| { + // ignore + }, + ); + match current_dir.entries.get_mut_by_index(index) { + Some(VfsEntry::Dir(dir)) => { current_dir = dir; } _ => unreachable!(), @@ -325,7 +293,7 @@ impl VfsBuilder { sub_data_kind: VfsFileSubDataKind, ) -> Result<(), AnyError> { log::debug!("Adding file '{}'", path.display()); - let checksum = util::checksum::gen(&[&data]); + let checksum = deno_lib::util::checksum::gen(&[&data]); let case_sensitivity = self.case_sensitivity; let offset = if let Some(offset) = self.file_offsets.get(&checksum) { // duplicate file, reuse an old offset @@ -341,32 +309,28 @@ impl VfsBuilder { offset, len: data.len() as u64, }; - match dir.entries.binary_search(&name, case_sensitivity) { - Ok(index) => { - let entry = &mut dir.entries.0[index]; - match entry { - VfsEntry::File(virtual_file) => match sub_data_kind { - VfsFileSubDataKind::Raw => { - virtual_file.offset = offset_and_len; - } - VfsFileSubDataKind::ModuleGraph => { - virtual_file.module_graph_offset = offset_and_len; - } - }, - VfsEntry::Dir(_) | VfsEntry::Symlink(_) => unreachable!(), - } - } - Err(insert_index) => { - dir.entries.0.insert( - insert_index, - VfsEntry::File(VirtualFile { - name: name.to_string(), - offset: offset_and_len, - module_graph_offset: offset_and_len, - }), - ); - } - } + dir.entries.insert_or_modify( + &name, + case_sensitivity, + || { + VfsEntry::File(VirtualFile { + name: name.to_string(), + offset: offset_and_len, + module_graph_offset: offset_and_len, + }) + }, + |entry| match entry { + VfsEntry::File(virtual_file) => match sub_data_kind { + VfsFileSubDataKind::Raw => { + virtual_file.offset = offset_and_len; + } + VfsFileSubDataKind::ModuleGraph => { + virtual_file.module_graph_offset = offset_and_len; + } + }, + VfsEntry::Dir(_) | VfsEntry::Symlink(_) => unreachable!(), + }, + ); // new file, update the list of files if self.current_offset == offset { @@ -406,18 +370,19 @@ impl VfsBuilder { let target = normalize_path(path.parent().unwrap().join(&target)); let dir = self.add_dir_raw(path.parent().unwrap()); let name = path.file_name().unwrap().to_string_lossy(); - match dir.entries.binary_search(&name, case_sensitivity) { - Ok(_) => {} // previously inserted - Err(insert_index) => { - dir.entries.0.insert( - insert_index, - VfsEntry::Symlink(VirtualSymlink { - name: name.to_string(), - dest_parts: VirtualSymlinkParts::from_path(&target), - }), - ); - } - } + dir.entries.insert_or_modify( + &name, + case_sensitivity, + || { + VfsEntry::Symlink(VirtualSymlink { + name: name.to_string(), + dest_parts: VirtualSymlinkParts::from_path(&target), + }) + }, + |_| { + // ignore previously inserted + }, + ); let target_metadata = std::fs::symlink_metadata(&target).with_context(|| { format!("Reading symlink target '{}'", target.display()) @@ -448,16 +413,20 @@ impl VfsBuilder { dir: &mut VirtualDirectory, parts: &[String], ) { - for entry in &mut dir.entries.0 { + for entry in dir.entries.iter_mut() { match entry { VfsEntry::Dir(dir) => { strip_prefix_from_symlinks(dir, parts); } VfsEntry::File(_) => {} VfsEntry::Symlink(symlink) => { - let old_parts = std::mem::take(&mut symlink.dest_parts.0); - symlink.dest_parts.0 = - old_parts.into_iter().skip(parts.len()).collect(); + let parts = symlink + .dest_parts + .take_parts() + .into_iter() + .skip(parts.len()) + .collect(); + symlink.dest_parts.set_parts(parts); } } } @@ -476,13 +445,13 @@ impl VfsBuilder { if self.min_root_dir.as_ref() == Some(¤t_path) { break; } - match ¤t_dir.entries.0[0] { + match current_dir.entries.iter().next().unwrap() { VfsEntry::Dir(dir) => { if dir.name == DENO_COMPILE_GLOBAL_NODE_MODULES_DIR_NAME { // special directory we want to maintain break; } - match current_dir.entries.0.remove(0) { + match current_dir.entries.remove(0) { VfsEntry::Dir(dir) => { current_path = WindowsSystemRootablePath::Path(current_path.join(&dir.name)); @@ -497,7 +466,7 @@ impl VfsBuilder { if let WindowsSystemRootablePath::Path(path) = ¤t_path { strip_prefix_from_symlinks( &mut current_dir, - &VirtualSymlinkParts::from_path(path).0, + VirtualSymlinkParts::from_path(path).parts(), ); } BuiltVfs { @@ -577,7 +546,7 @@ fn vfs_as_display_tree( All(Size), Subset(Vec>), File(Size), - Symlink(&'a [String]), + Symlink(&'a VirtualSymlinkParts), } impl<'a> EntryOutput<'a> { @@ -626,7 +595,7 @@ fn vfs_as_display_tree( format!("{} ({})", name, format_size(*size)) } EntryOutput::Symlink(parts) => { - format!("{} --> {}", name, parts.join("/")) + format!("{} --> {}", name, parts.display()) } }, children: match self { @@ -769,7 +738,7 @@ fn vfs_as_display_tree( EntryOutput::File(file_size(file, seen_offsets)) } VfsEntry::Symlink(virtual_symlink) => { - EntryOutput::Symlink(&virtual_symlink.dest_parts.0) + EntryOutput::Symlink(&virtual_symlink.dest_parts) } }, }) @@ -806,7 +775,7 @@ fn vfs_as_display_tree( } VfsEntry::File(file) => EntryOutput::File(file_size(file, seen_offsets)), VfsEntry::Symlink(virtual_symlink) => { - EntryOutput::Symlink(&virtual_symlink.dest_parts.0) + EntryOutput::Symlink(&virtual_symlink.dest_parts) } } } @@ -872,226 +841,6 @@ fn vfs_as_display_tree( } } -#[derive(Debug)] -enum VfsEntryRef<'a> { - Dir(&'a VirtualDirectory), - File(&'a VirtualFile), - Symlink(&'a VirtualSymlink), -} - -impl VfsEntryRef<'_> { - pub fn as_metadata(&self) -> FileBackedVfsMetadata { - FileBackedVfsMetadata { - file_type: match self { - Self::Dir(_) => sys_traits::FileType::Dir, - Self::File(_) => sys_traits::FileType::File, - Self::Symlink(_) => sys_traits::FileType::Symlink, - }, - name: self.name().to_string(), - len: match self { - Self::Dir(_) => 0, - Self::File(file) => file.offset.len, - Self::Symlink(_) => 0, - }, - } - } - - pub fn name(&self) -> &str { - match self { - Self::Dir(dir) => &dir.name, - Self::File(file) => &file.name, - Self::Symlink(symlink) => &symlink.name, - } - } -} - -// todo(dsherret): we should store this more efficiently in the binary -#[derive(Debug, Serialize, Deserialize)] -pub enum VfsEntry { - Dir(VirtualDirectory), - File(VirtualFile), - Symlink(VirtualSymlink), -} - -impl VfsEntry { - pub fn name(&self) -> &str { - match self { - Self::Dir(dir) => &dir.name, - Self::File(file) => &file.name, - Self::Symlink(symlink) => &symlink.name, - } - } - - fn as_ref(&self) -> VfsEntryRef { - match self { - VfsEntry::Dir(dir) => VfsEntryRef::Dir(dir), - VfsEntry::File(file) => VfsEntryRef::File(file), - VfsEntry::Symlink(symlink) => VfsEntryRef::Symlink(symlink), - } - } -} - -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub enum FileSystemCaseSensitivity { - #[serde(rename = "s")] - Sensitive, - #[serde(rename = "i")] - Insensitive, -} - -#[derive(Debug, Default, Serialize, Deserialize)] -pub struct VirtualDirectoryEntries(Vec); - -impl VirtualDirectoryEntries { - pub fn new(mut entries: Vec) -> Self { - // needs to be sorted by name - entries.sort_by(|a, b| a.name().cmp(b.name())); - Self(entries) - } - - pub fn take_inner(&mut self) -> Vec { - std::mem::take(&mut self.0) - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn get_by_name( - &self, - name: &str, - case_sensitivity: FileSystemCaseSensitivity, - ) -> Option<&VfsEntry> { - self - .binary_search(name, case_sensitivity) - .ok() - .map(|index| &self.0[index]) - } - - pub fn get_mut_by_name( - &mut self, - name: &str, - case_sensitivity: FileSystemCaseSensitivity, - ) -> Option<&mut VfsEntry> { - self - .binary_search(name, case_sensitivity) - .ok() - .map(|index| &mut self.0[index]) - } - - pub fn binary_search( - &self, - name: &str, - case_sensitivity: FileSystemCaseSensitivity, - ) -> Result { - match case_sensitivity { - FileSystemCaseSensitivity::Sensitive => { - self.0.binary_search_by(|e| e.name().cmp(name)) - } - FileSystemCaseSensitivity::Insensitive => self.0.binary_search_by(|e| { - e.name() - .chars() - .zip(name.chars()) - .map(|(a, b)| a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase())) - .find(|&ord| ord != Ordering::Equal) - .unwrap_or_else(|| e.name().len().cmp(&name.len())) - }), - } - } - - pub fn insert( - &mut self, - entry: VfsEntry, - case_sensitivity: FileSystemCaseSensitivity, - ) { - match self.binary_search(entry.name(), case_sensitivity) { - Ok(index) => { - self.0[index] = entry; - } - Err(insert_index) => { - self.0.insert(insert_index, entry); - } - } - } - - pub fn remove(&mut self, index: usize) -> VfsEntry { - self.0.remove(index) - } - - pub fn iter(&self) -> std::slice::Iter<'_, VfsEntry> { - self.0.iter() - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct VirtualDirectory { - #[serde(rename = "n")] - pub name: String, - // should be sorted by name - #[serde(rename = "e")] - pub entries: VirtualDirectoryEntries, -} - -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct OffsetWithLength { - #[serde(rename = "o")] - pub offset: u64, - #[serde(rename = "l")] - pub len: u64, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct VirtualFile { - #[serde(rename = "n")] - pub name: String, - #[serde(rename = "o")] - pub offset: OffsetWithLength, - /// Offset file to use for module loading when it differs from the - /// raw file. Often this will be the same offset as above for data - /// such as JavaScript files, but for TypeScript files the `offset` - /// will be the original raw bytes when included as an asset and this - /// offset will be to the transpiled JavaScript source. - #[serde(rename = "m")] - pub module_graph_offset: OffsetWithLength, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct VirtualSymlinkParts(Vec); - -impl VirtualSymlinkParts { - pub fn from_path(path: &Path) -> Self { - Self( - path - .components() - .filter(|c| !matches!(c, std::path::Component::RootDir)) - .map(|c| c.as_os_str().to_string_lossy().to_string()) - .collect(), - ) - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct VirtualSymlink { - #[serde(rename = "n")] - pub name: String, - #[serde(rename = "p")] - pub dest_parts: VirtualSymlinkParts, -} - -impl VirtualSymlink { - pub fn resolve_dest_from_root(&self, root: &Path) -> PathBuf { - let mut dest = root.to_path_buf(); - for part in &self.dest_parts.0 { - dest.push(part); - } - dest - } -} - #[derive(Debug)] pub struct VfsRoot { pub dir: VirtualDirectory, @@ -1430,6 +1179,21 @@ pub struct FileBackedVfsMetadata { } impl FileBackedVfsMetadata { + pub fn from_vfs_entry_ref(vfs_entry: VfsEntryRef) -> Self { + FileBackedVfsMetadata { + file_type: match vfs_entry { + VfsEntryRef::Dir(_) => sys_traits::FileType::Dir, + VfsEntryRef::File(_) => sys_traits::FileType::File, + VfsEntryRef::Symlink(_) => sys_traits::FileType::Symlink, + }, + name: vfs_entry.name().to_string(), + len: match vfs_entry { + VfsEntryRef::Dir(_) => 0, + VfsEntryRef::File(file) => file.offset.len, + VfsEntryRef::Symlink(_) => 0, + }, + } + } pub fn as_fs_stat(&self) -> FsStat { FsStat { is_directory: self.file_type == sys_traits::FileType::Dir, @@ -1521,7 +1285,7 @@ impl FileBackedVfs { let path = path.to_path_buf(); Ok(dir.entries.iter().map(move |entry| FileBackedVfsDirEntry { parent_path: path.to_path_buf(), - metadata: entry.as_ref().as_metadata(), + metadata: FileBackedVfsMetadata::from_vfs_entry_ref(entry.as_ref()), })) } @@ -1544,12 +1308,12 @@ impl FileBackedVfs { let (_, entry) = self .fs_root .find_entry_no_follow(path, self.case_sensitivity)?; - Ok(entry.as_metadata()) + Ok(FileBackedVfsMetadata::from_vfs_entry_ref(entry)) } pub fn stat(&self, path: &Path) -> std::io::Result { let (_, entry) = self.fs_root.find_entry(path, self.case_sensitivity)?; - Ok(entry.as_metadata()) + Ok(FileBackedVfsMetadata::from_vfs_entry_ref(entry)) } pub fn canonicalize(&self, path: &Path) -> std::io::Result { diff --git a/cli/sys.rs b/cli/sys.rs index 718e9981e2..e551eab2e8 100644 --- a/cli/sys.rs +++ b/cli/sys.rs @@ -29,6 +29,8 @@ pub enum CliSys { DenoCompile(DenoCompileFileSystem), } +impl deno_lib::sys::DenoLibSys for CliSys {} + impl Default for CliSys { fn default() -> Self { Self::Real(sys_traits::impls::RealSys) diff --git a/cli/tools/clean.rs b/cli/tools/clean.rs index e6f8c1e52b..a550d2826a 100644 --- a/cli/tools/clean.rs +++ b/cli/tools/clean.rs @@ -4,8 +4,8 @@ use std::path::Path; use deno_core::anyhow::Context; use deno_core::error::AnyError; +use deno_lib::cache::DenoDir; -use crate::cache::DenoDir; use crate::colors; use crate::display; use crate::sys::CliSys; diff --git a/cli/tools/info.rs b/cli/tools/info.rs index 8c3b2665c5..1b2542d427 100644 --- a/cli/tools/info.rs +++ b/cli/tools/info.rs @@ -18,6 +18,7 @@ use deno_graph::Module; use deno_graph::ModuleError; use deno_graph::ModuleGraph; use deno_graph::Resolution; +use deno_lib::util::checksum; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::NpmPackageId; @@ -33,7 +34,6 @@ use crate::display; use crate::factory::CliFactory; use crate::graph_util::graph_exit_integrity_errors; use crate::npm::CliManagedNpmResolver; -use crate::util::checksum; use crate::util::display::DisplayTreeNode; const JSON_SCHEMA_VERSION: u8 = 1; @@ -191,7 +191,7 @@ fn print_cache_info( let registry_cache = dir.registries_folder_path(); let mut origin_dir = dir.origin_data_folder_path(); let deno_dir = dir.root_path_for_display().to_string(); - let web_cache_dir = crate::worker::get_cache_storage_dir(); + let web_cache_dir = deno_lib::worker::get_cache_storage_dir(); if let Some(location) = &location { origin_dir = diff --git a/cli/tools/serve.rs b/cli/tools/serve.rs index c2c53c1b69..2143eb33bb 100644 --- a/cli/tools/serve.rs +++ b/cli/tools/serve.rs @@ -43,7 +43,8 @@ pub async fn serve( maybe_npm_install(&factory).await?; - let worker_factory = factory.create_cli_main_worker_factory().await?; + let worker_factory = + Arc::new(factory.create_cli_main_worker_factory().await?); let hmr = serve_flags .watch .map(|watch_flags| watch_flags.hmr) @@ -58,7 +59,7 @@ pub async fn serve( } async fn do_serve( - worker_factory: CliMainWorkerFactory, + worker_factory: Arc, main_module: ModuleSpecifier, worker_count: Option, hmr: bool, @@ -116,7 +117,7 @@ async fn do_serve( async fn run_worker( worker_count: usize, - worker_factory: CliMainWorkerFactory, + worker_factory: Arc, main_module: ModuleSpecifier, hmr: bool, ) -> Result { @@ -164,7 +165,8 @@ async fn serve_with_watch( maybe_npm_install(&factory).await?; let _ = watcher_communicator.watch_paths(cli_options.watch_paths()); - let worker_factory = factory.create_cli_main_worker_factory().await?; + let worker_factory = + Arc::new(factory.create_cli_main_worker_factory().await?); do_serve(worker_factory, main_module.clone(), worker_count, hmr) .await?; diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 37d52c6cf2..1b76b640d3 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -28,6 +28,8 @@ use deno_graph::GraphKind; use deno_graph::Module; use deno_graph::ModuleGraph; use deno_graph::ResolutionResolved; +use deno_lib::util::checksum; +use deno_lib::worker::create_isolate_create_params; use deno_resolver::npm::managed::ResolvePkgFolderFromDenoModuleError; use deno_resolver::npm::ResolvePkgFolderFromDenoReqError; use deno_semver::npm::NpmPackageReqReference; @@ -48,9 +50,7 @@ use crate::node::CliNodeResolver; use crate::npm::CliNpmResolver; use crate::resolver::CliCjsTracker; use crate::sys::CliSys; -use crate::util::checksum; use crate::util::path::mapped_specifier_for_tsc; -use crate::worker::create_isolate_create_params; mod diagnostics; diff --git a/cli/util/file_watcher.rs b/cli/util/file_watcher.rs index 65963214b9..d3ff1bae77 100644 --- a/cli/util/file_watcher.rs +++ b/cli/util/file_watcher.rs @@ -25,6 +25,7 @@ use notify::Watcher; use tokio::select; use tokio::sync::broadcast::error::RecvError; use tokio::sync::mpsc; +use tokio::sync::mpsc::error::SendError; use tokio::sync::mpsc::UnboundedReceiver; use tokio::time::sleep; @@ -141,36 +142,60 @@ fn create_print_after_restart_fn(clear_screen: bool) -> impl Fn() { } } +#[derive(Debug)] +pub struct WatcherCommunicatorOptions { + /// Send a list of paths that should be watched for changes. + pub paths_to_watch_tx: tokio::sync::mpsc::UnboundedSender>, + /// Listen for a list of paths that were changed. + pub changed_paths_rx: tokio::sync::broadcast::Receiver>>, + pub changed_paths_tx: tokio::sync::broadcast::Sender>>, + /// Send a message to force a restart. + pub restart_tx: tokio::sync::mpsc::UnboundedSender<()>, + pub restart_mode: WatcherRestartMode, + pub banner: String, +} + /// An interface to interact with Deno's CLI file watcher. #[derive(Debug)] pub struct WatcherCommunicator { /// Send a list of paths that should be watched for changes. paths_to_watch_tx: tokio::sync::mpsc::UnboundedSender>, - /// Listen for a list of paths that were changed. changed_paths_rx: tokio::sync::broadcast::Receiver>>, - + changed_paths_tx: tokio::sync::broadcast::Sender>>, /// Send a message to force a restart. restart_tx: tokio::sync::mpsc::UnboundedSender<()>, - restart_mode: Mutex, - banner: String, } impl WatcherCommunicator { - pub fn watch_paths(&self, paths: Vec) -> Result<(), AnyError> { + pub fn new(options: WatcherCommunicatorOptions) -> Self { + Self { + paths_to_watch_tx: options.paths_to_watch_tx, + changed_paths_rx: options.changed_paths_rx, + changed_paths_tx: options.changed_paths_tx, + restart_tx: options.restart_tx, + restart_mode: Mutex::new(options.restart_mode), + banner: options.banner, + } + } + + pub fn watch_paths( + &self, + paths: Vec, + ) -> Result<(), SendError>> { if paths.is_empty() { return Ok(()); } - self.paths_to_watch_tx.send(paths).map_err(AnyError::from) + self.paths_to_watch_tx.send(paths) } - pub fn force_restart(&self) -> Result<(), AnyError> { + pub fn force_restart(&self) -> Result<(), SendError<()>> { // Change back to automatic mode, so that HMR can set up watching // from scratch. *self.restart_mode.lock() = WatcherRestartMode::Automatic; - self.restart_tx.send(()).map_err(AnyError::from) + self.restart_tx.send(()) } pub async fn watch_for_changed_paths( @@ -184,6 +209,22 @@ impl WatcherCommunicator { *self.restart_mode.lock() = restart_mode; } + pub fn send( + &self, + paths: Option>, + ) -> Result<(), SendError>>> { + match *self.restart_mode.lock() { + WatcherRestartMode::Automatic => { + self.restart_tx.send(()).map_err(|_| SendError(None)) + } + WatcherRestartMode::Manual => self + .changed_paths_tx + .send(paths) + .map(|_| ()) + .map_err(|e| SendError(e.0)), + } + } + pub fn print(&self, msg: String) { log::info!("{} {}", self.banner, colors::gray(msg)); } @@ -272,13 +313,15 @@ where } = print_config; let print_after_restart = create_print_after_restart_fn(clear_screen); - let watcher_communicator = Arc::new(WatcherCommunicator { - paths_to_watch_tx: paths_to_watch_tx.clone(), - changed_paths_rx: changed_paths_rx.resubscribe(), - restart_tx: restart_tx.clone(), - restart_mode: Mutex::new(restart_mode), - banner: colors::intense_blue(banner).to_string(), - }); + let watcher_communicator = + Arc::new(WatcherCommunicator::new(WatcherCommunicatorOptions { + paths_to_watch_tx: paths_to_watch_tx.clone(), + changed_paths_rx: changed_paths_rx.resubscribe(), + changed_paths_tx, + restart_tx: restart_tx.clone(), + restart_mode, + banner: colors::intense_blue(banner).to_string(), + })); info!("{} {} started.", colors::intense_blue(banner), job_name); let changed_paths = Rc::new(RefCell::new(None)); @@ -292,15 +335,8 @@ where .borrow_mut() .clone_from(&received_changed_paths); - match *watcher_.restart_mode.lock() { - WatcherRestartMode::Automatic => { - let _ = restart_tx.send(()); - } - WatcherRestartMode::Manual => { - // TODO(bartlomieju): should we fail on sending changed paths? - let _ = changed_paths_tx.send(received_changed_paths); - } - } + // TODO(bartlomieju): should we fail on sending changed paths? + let _ = watcher_.send(received_changed_paths); } }); diff --git a/cli/util/mod.rs b/cli/util/mod.rs index 0578ecb423..702e5673c9 100644 --- a/cli/util/mod.rs +++ b/cli/util/mod.rs @@ -2,7 +2,6 @@ // Note: Only add code in this folder that has no application specific logic pub mod archive; -pub mod checksum; pub mod console; pub mod diff; pub mod display; diff --git a/cli/worker.rs b/cli/worker.rs index d9cdbd3fb0..cf301de83e 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -1,8 +1,6 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::path::Path; -use std::path::PathBuf; -use std::rc::Rc; use std::sync::Arc; use deno_ast::ModuleSpecifier; @@ -10,77 +8,31 @@ use deno_core::anyhow::bail; use deno_core::error::AnyError; use deno_core::error::CoreError; use deno_core::futures::FutureExt; -use deno_core::url::Url; use deno_core::v8; -use deno_core::CompiledWasmModuleStore; use deno_core::Extension; -use deno_core::FeatureChecker; -use deno_core::ModuleLoader; use deno_core::PollEventLoopOptions; -use deno_core::SharedArrayBufferStore; use deno_error::JsErrorBox; -use deno_resolver::npm::DenoInNpmPackageChecker; +use deno_lib::worker::LibMainWorker; +use deno_lib::worker::LibMainWorkerFactory; use deno_runtime::code_cache; -use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; -use deno_runtime::deno_fs; -use deno_runtime::deno_node::NodeExtInitServices; -use deno_runtime::deno_node::NodeRequireLoader; -use deno_runtime::deno_node::NodeRequireLoaderRc; use deno_runtime::deno_permissions::PermissionsContainer; -use deno_runtime::deno_tls::RootCertStoreProvider; -use deno_runtime::deno_web::BlobStore; -use deno_runtime::fmt_errors::format_js_error; -use deno_runtime::inspector_server::InspectorServer; -use deno_runtime::ops::process::NpmProcessStateProviderRc; -use deno_runtime::ops::worker_host::CreateWebWorkerCb; -use deno_runtime::web_worker::WebWorker; -use deno_runtime::web_worker::WebWorkerOptions; -use deno_runtime::web_worker::WebWorkerServiceOptions; use deno_runtime::worker::MainWorker; -use deno_runtime::worker::WorkerOptions; -use deno_runtime::worker::WorkerServiceOptions; -use deno_runtime::BootstrapOptions; use deno_runtime::WorkerExecutionMode; -use deno_runtime::WorkerLogLevel; use deno_semver::npm::NpmPackageReqReference; -use deno_telemetry::OtelConfig; -use deno_terminal::colors; use node_resolver::NodeResolutionKind; use node_resolver::ResolutionMode; +use sys_traits::EnvCurrentDir; use tokio::select; use crate::args::CliLockfile; -use crate::args::DenoSubcommand; use crate::args::NpmCachingStrategy; -use crate::args::StorageKeyResolver; use crate::node::CliNodeResolver; -use crate::node::CliPackageJsonResolver; use crate::npm::installer::NpmInstaller; use crate::npm::installer::PackageCaching; use crate::npm::CliNpmResolver; use crate::sys::CliSys; -use crate::util::checksum; use crate::util::file_watcher::WatcherCommunicator; use crate::util::file_watcher::WatcherRestartMode; -use crate::version; - -pub struct CreateModuleLoaderResult { - pub module_loader: Rc, - pub node_require_loader: Rc, -} - -pub trait ModuleLoaderFactory: Send + Sync { - fn create_for_main( - &self, - root_permissions: PermissionsContainer, - ) -> CreateModuleLoaderResult; - - fn create_for_worker( - &self, - parent_permissions: PermissionsContainer, - permissions: PermissionsContainer, - ) -> CreateModuleLoaderResult; -} #[async_trait::async_trait(?Send)] pub trait HmrRunner: Send + Sync { @@ -115,83 +67,28 @@ pub type CreateCoverageCollectorCb = Box< >; pub struct CliMainWorkerOptions { - pub argv: Vec, - pub log_level: WorkerLogLevel, - pub enable_op_summary_metrics: bool, - pub enable_testing_features: bool, - pub has_node_modules_dir: bool, - pub hmr: bool, - pub inspect_brk: bool, - pub inspect_wait: bool, - pub strace_ops: Option>, - pub is_inspecting: bool, - pub location: Option, - pub argv0: Option, - pub node_debug: Option, - pub origin_data_folder_path: Option, - pub seed: Option, - pub unsafely_ignore_certificate_errors: Option>, - pub skip_op_registration: bool, pub create_hmr_runner: Option, pub create_coverage_collector: Option, - pub node_ipc: Option, - pub serve_port: Option, - pub serve_host: Option, + pub default_npm_caching_strategy: NpmCachingStrategy, + pub needs_test_modules: bool, } -struct SharedWorkerState { - blob_store: Arc, - broadcast_channel: InMemoryBroadcastChannel, - code_cache: Option>, - compiled_wasm_module_store: CompiledWasmModuleStore, - feature_checker: Arc, - fs: Arc, - maybe_file_watcher_communicator: Option>, - maybe_inspector_server: Option>, - maybe_lockfile: Option>, - module_loader_factory: Box, - node_resolver: Arc, - npm_installer: Option>, - npm_resolver: CliNpmResolver, - pkg_json_resolver: Arc, - root_cert_store_provider: Arc, - root_permissions: PermissionsContainer, - shared_array_buffer_store: SharedArrayBufferStore, - storage_key_resolver: StorageKeyResolver, - sys: CliSys, - options: CliMainWorkerOptions, - subcommand: DenoSubcommand, - otel_config: OtelConfig, - default_npm_caching_strategy: NpmCachingStrategy, -} - -impl SharedWorkerState { - pub fn create_node_init_services( - &self, - node_require_loader: NodeRequireLoaderRc, - ) -> NodeExtInitServices { - NodeExtInitServices { - node_require_loader, - node_resolver: self.node_resolver.clone(), - pkg_json_resolver: self.pkg_json_resolver.clone(), - sys: self.sys.clone(), - } - } - - pub fn npm_process_state_provider(&self) -> NpmProcessStateProviderRc { - crate::npm::create_npm_process_state_provider(&self.npm_resolver) - } +/// Data shared between the factory and workers. +struct SharedState { + pub create_hmr_runner: Option, + pub create_coverage_collector: Option, + pub maybe_file_watcher_communicator: Option>, } pub struct CliMainWorker { - main_module: ModuleSpecifier, - worker: MainWorker, - shared: Arc, + worker: LibMainWorker, + shared: Arc, } impl CliMainWorker { + #[inline] pub fn into_main_worker(self) -> MainWorker { - self.worker + self.worker.into_main_worker() } pub async fn setup_repl(&mut self) -> Result<(), AnyError> { @@ -204,16 +101,13 @@ impl CliMainWorker { self.maybe_setup_coverage_collector().await?; let mut maybe_hmr_runner = self.maybe_setup_hmr_runner().await?; - log::debug!("main_module {}", self.main_module); + log::debug!("main_module {}", self.worker.main_module()); self.execute_main_module().await?; self.worker.dispatch_load_event()?; loop { if let Some(hmr_runner) = maybe_hmr_runner.as_mut() { - let watcher_communicator = - self.shared.maybe_file_watcher_communicator.clone().unwrap(); - let hmr_future = hmr_runner.run().boxed_local(); let event_loop_future = self.worker.run_event_loop(false).boxed_local(); @@ -227,7 +121,11 @@ impl CliMainWorker { } } if let Err(e) = result { - watcher_communicator + self + .shared + .maybe_file_watcher_communicator + .as_ref() + .unwrap() .change_restart_mode(WatcherRestartMode::Automatic); return Err(e); } @@ -253,7 +151,7 @@ impl CliMainWorker { if let Some(coverage_collector) = maybe_coverage_collector.as_mut() { self .worker - .js_runtime + .js_runtime() .with_event_loop_future( coverage_collector.stop_collecting().boxed_local(), PollEventLoopOptions::default(), @@ -263,7 +161,7 @@ impl CliMainWorker { if let Some(hmr_runner) = maybe_hmr_runner.as_mut() { self .worker - .js_runtime + .js_runtime() .with_event_loop_future( hmr_runner.stop().boxed_local(), PollEventLoopOptions::default(), @@ -335,24 +233,20 @@ impl CliMainWorker { executor.execute().await } + #[inline] pub async fn execute_main_module(&mut self) -> Result<(), CoreError> { - let id = self.worker.preload_main_module(&self.main_module).await?; - self.worker.evaluate_module(id).await + self.worker.execute_main_module().await } + #[inline] pub async fn execute_side_module(&mut self) -> Result<(), CoreError> { - let id = self.worker.preload_side_module(&self.main_module).await?; - self.worker.evaluate_module(id).await + self.worker.execute_side_module().await } pub async fn maybe_setup_hmr_runner( &mut self, ) -> Result>, AnyError> { - if !self.shared.options.hmr { - return Ok(None); - } - let Some(setup_hmr_runner) = self.shared.options.create_hmr_runner.as_ref() - else { + let Some(setup_hmr_runner) = self.shared.create_hmr_runner.as_ref() else { return Ok(None); }; @@ -362,7 +256,7 @@ impl CliMainWorker { self .worker - .js_runtime + .js_runtime() .with_event_loop_future( hmr_runner.start().boxed_local(), PollEventLoopOptions::default(), @@ -375,7 +269,7 @@ impl CliMainWorker { &mut self, ) -> Result>, AnyError> { let Some(create_coverage_collector) = - self.shared.options.create_coverage_collector.as_ref() + self.shared.create_coverage_collector.as_ref() else { return Ok(None); }; @@ -384,7 +278,7 @@ impl CliMainWorker { let mut coverage_collector = create_coverage_collector(session); self .worker - .js_runtime + .js_runtime() .with_event_loop_future( coverage_collector.start_collecting().boxed_local(), PollEventLoopOptions::default(), @@ -398,72 +292,51 @@ impl CliMainWorker { name: &'static str, source_code: &'static str, ) -> Result, CoreError> { - self.worker.js_runtime.execute_script(name, source_code) + self.worker.js_runtime().execute_script(name, source_code) } } -// TODO(bartlomieju): this should be moved to some other place, added to avoid string -// duplication between worker setups and `deno info` output. -pub fn get_cache_storage_dir() -> PathBuf { - // Note: we currently use temp_dir() to avoid managing storage size. - std::env::temp_dir().join("deno_cache") -} - -#[derive(Clone)] pub struct CliMainWorkerFactory { - shared: Arc, + lib_main_worker_factory: LibMainWorkerFactory, + maybe_lockfile: Option>, + node_resolver: Arc, + npm_installer: Option>, + npm_resolver: CliNpmResolver, + root_permissions: PermissionsContainer, + shared: Arc, + sys: CliSys, + default_npm_caching_strategy: NpmCachingStrategy, + needs_test_modules: bool, } impl CliMainWorkerFactory { #[allow(clippy::too_many_arguments)] pub fn new( - blob_store: Arc, - code_cache: Option>, - feature_checker: Arc, - fs: Arc, + lib_main_worker_factory: LibMainWorkerFactory, maybe_file_watcher_communicator: Option>, - maybe_inspector_server: Option>, maybe_lockfile: Option>, - module_loader_factory: Box, node_resolver: Arc, npm_installer: Option>, npm_resolver: CliNpmResolver, - pkg_json_resolver: Arc, - root_cert_store_provider: Arc, - root_permissions: PermissionsContainer, - storage_key_resolver: StorageKeyResolver, sys: CliSys, - subcommand: DenoSubcommand, options: CliMainWorkerOptions, - otel_config: OtelConfig, - default_npm_caching_strategy: NpmCachingStrategy, + root_permissions: PermissionsContainer, ) -> Self { Self { - shared: Arc::new(SharedWorkerState { - blob_store, - broadcast_channel: Default::default(), - code_cache, - compiled_wasm_module_store: Default::default(), - feature_checker, - fs, + lib_main_worker_factory, + maybe_lockfile, + node_resolver, + npm_installer, + npm_resolver, + root_permissions, + sys, + shared: Arc::new(SharedState { + create_hmr_runner: options.create_hmr_runner, + create_coverage_collector: options.create_coverage_collector, maybe_file_watcher_communicator, - maybe_inspector_server, - maybe_lockfile, - module_loader_factory, - node_resolver, - npm_installer, - npm_resolver, - pkg_json_resolver, - root_cert_store_provider, - root_permissions, - shared_array_buffer_store: Default::default(), - storage_key_resolver, - sys, - options, - subcommand, - otel_config, - default_npm_caching_strategy, }), + default_npm_caching_strategy: options.default_npm_caching_strategy, + needs_test_modules: options.needs_test_modules, } } @@ -476,7 +349,7 @@ impl CliMainWorkerFactory { .create_custom_worker( mode, main_module, - self.shared.root_permissions.clone(), + self.root_permissions.clone(), vec![], Default::default(), ) @@ -491,23 +364,16 @@ impl CliMainWorkerFactory { custom_extensions: Vec, stdio: deno_runtime::deno_io::Stdio, ) -> Result { - let shared = &self.shared; - let CreateModuleLoaderResult { - module_loader, - node_require_loader, - } = shared - .module_loader_factory - .create_for_main(permissions.clone()); let main_module = if let Ok(package_ref) = NpmPackageReqReference::from_specifier(&main_module) { - if let Some(npm_installer) = &shared.npm_installer { + if let Some(npm_installer) = &self.npm_installer { let reqs = &[package_ref.req().clone()]; npm_installer .add_package_reqs( reqs, if matches!( - shared.default_npm_caching_strategy, + self.default_npm_caching_strategy, NpmCachingStrategy::Lazy ) { PackageCaching::Only(reqs.into()) @@ -520,18 +386,18 @@ impl CliMainWorkerFactory { // use a fake referrer that can be used to discover the package.json if necessary let referrer = ModuleSpecifier::from_directory_path( - self.shared.fs.cwd().map_err(JsErrorBox::from_err)?, + self.sys.env_current_dir().map_err(JsErrorBox::from_err)?, ) .unwrap() .join("package.json")?; - let package_folder = shared + let package_folder = self .npm_resolver .resolve_pkg_folder_from_deno_module_req(package_ref.req(), &referrer) .map_err(JsErrorBox::from_err)?; let main_module = self .resolve_binary_entrypoint(&package_folder, package_ref.sub_path())?; - if let Some(lockfile) = &shared.maybe_lockfile { + if let Some(lockfile) = &self.maybe_lockfile { // For npm binary commands, ensure that the lockfile gets updated // so that we can re-use the npm resolution the next time it runs // for better performance @@ -543,119 +409,18 @@ impl CliMainWorkerFactory { main_module }; - let maybe_inspector_server = shared.maybe_inspector_server.clone(); - - let create_web_worker_cb = - create_web_worker_callback(shared.clone(), stdio.clone()); - - let maybe_storage_key = shared - .storage_key_resolver - .resolve_storage_key(&main_module); - let origin_storage_dir = maybe_storage_key.as_ref().map(|key| { - shared - .options - .origin_data_folder_path - .as_ref() - .unwrap() // must be set if storage key resolver returns a value - .join(checksum::gen(&[key.as_bytes()])) - }); - let cache_storage_dir = maybe_storage_key.map(|key| { - // TODO(@satyarohith): storage quota management - get_cache_storage_dir().join(checksum::gen(&[key.as_bytes()])) - }); - - // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out - // list of enabled features. - let feature_checker = shared.feature_checker.clone(); - let mut unstable_features = - Vec::with_capacity(crate::UNSTABLE_GRANULAR_FLAGS.len()); - for granular_flag in crate::UNSTABLE_GRANULAR_FLAGS { - if feature_checker.check(granular_flag.name) { - unstable_features.push(granular_flag.id); - } - } - - let services = WorkerServiceOptions { - root_cert_store_provider: Some(shared.root_cert_store_provider.clone()), - module_loader, - fs: shared.fs.clone(), - node_services: Some( - shared.create_node_init_services(node_require_loader), - ), - npm_process_state_provider: Some(shared.npm_process_state_provider()), - blob_store: shared.blob_store.clone(), - broadcast_channel: shared.broadcast_channel.clone(), - fetch_dns_resolver: Default::default(), - shared_array_buffer_store: Some(shared.shared_array_buffer_store.clone()), - compiled_wasm_module_store: Some( - shared.compiled_wasm_module_store.clone(), - ), - feature_checker, + let mut worker = self.lib_main_worker_factory.create_custom_worker( + mode, + main_module, permissions, - v8_code_cache: shared.code_cache.clone().map(|c| c.as_code_cache()), - }; - - let options = WorkerOptions { - bootstrap: BootstrapOptions { - deno_version: crate::version::DENO_VERSION_INFO.deno.to_string(), - args: shared.options.argv.clone(), - cpu_count: std::thread::available_parallelism() - .map(|p| p.get()) - .unwrap_or(1), - log_level: shared.options.log_level, - enable_op_summary_metrics: shared.options.enable_op_summary_metrics, - enable_testing_features: shared.options.enable_testing_features, - locale: deno_core::v8::icu::get_language_tag(), - location: shared.options.location.clone(), - no_color: !colors::use_color(), - is_stdout_tty: deno_terminal::is_stdout_tty(), - is_stderr_tty: deno_terminal::is_stderr_tty(), - color_level: colors::get_color_level(), - unstable_features, - user_agent: version::DENO_VERSION_INFO.user_agent.to_string(), - inspect: shared.options.is_inspecting, - has_node_modules_dir: shared.options.has_node_modules_dir, - argv0: shared.options.argv0.clone(), - node_debug: shared.options.node_debug.clone(), - node_ipc_fd: shared.options.node_ipc, - mode, - serve_port: shared.options.serve_port, - serve_host: shared.options.serve_host.clone(), - otel_config: shared.otel_config.clone(), - close_on_idle: true, - }, - extensions: custom_extensions, - startup_snapshot: crate::js::deno_isolate_init(), - create_params: create_isolate_create_params(), - unsafely_ignore_certificate_errors: shared - .options - .unsafely_ignore_certificate_errors - .clone(), - seed: shared.options.seed, - format_js_error_fn: Some(Arc::new(format_js_error)), - create_web_worker_cb, - maybe_inspector_server, - should_break_on_first_statement: shared.options.inspect_brk, - should_wait_for_inspector_session: shared.options.inspect_wait, - strace_ops: shared.options.strace_ops.clone(), - cache_storage_dir, - origin_storage_dir, + custom_extensions, stdio, - skip_op_registration: shared.options.skip_op_registration, - enable_stack_trace_arg_in_ops: crate::args::has_trace_permissions_enabled( - ), - }; + )?; - let mut worker = MainWorker::bootstrap_from_options( - main_module.clone(), - services, - options, - ); - - if self.shared.subcommand.needs_test() { + if self.needs_test_modules { macro_rules! test_file { ($($file:literal),*) => { - $(worker.js_runtime.lazy_load_es_module_with_code( + $(worker.js_runtime().lazy_load_es_module_with_code( concat!("ext:cli/", $file), deno_core::ascii_str_include!(concat!("js/", $file)), )?;)* @@ -673,9 +438,8 @@ impl CliMainWorkerFactory { } Ok(CliMainWorker { - main_module, worker, - shared: shared.clone(), + shared: self.shared.clone(), }) } @@ -685,7 +449,6 @@ impl CliMainWorkerFactory { sub_path: Option<&str>, ) -> Result { match self - .shared .node_resolver .resolve_binary_export(package_folder, sub_path) { @@ -720,7 +483,6 @@ impl CliMainWorkerFactory { } let specifier = self - .shared .node_resolver .resolve_package_subpath_from_deno_module( package_folder, @@ -741,136 +503,20 @@ impl CliMainWorkerFactory { } } -fn create_web_worker_callback( - shared: Arc, - stdio: deno_runtime::deno_io::Stdio, -) -> Arc { - Arc::new(move |args| { - let maybe_inspector_server = shared.maybe_inspector_server.clone(); - - let CreateModuleLoaderResult { - module_loader, - node_require_loader, - } = shared.module_loader_factory.create_for_worker( - args.parent_permissions.clone(), - args.permissions.clone(), - ); - let create_web_worker_cb = - create_web_worker_callback(shared.clone(), stdio.clone()); - - let maybe_storage_key = shared - .storage_key_resolver - .resolve_storage_key(&args.main_module); - let cache_storage_dir = maybe_storage_key.map(|key| { - // TODO(@satyarohith): storage quota management - get_cache_storage_dir().join(checksum::gen(&[key.as_bytes()])) - }); - - // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out - // list of enabled features. - let feature_checker = shared.feature_checker.clone(); - let mut unstable_features = - Vec::with_capacity(crate::UNSTABLE_GRANULAR_FLAGS.len()); - for granular_flag in crate::UNSTABLE_GRANULAR_FLAGS { - if feature_checker.check(granular_flag.name) { - unstable_features.push(granular_flag.id); - } - } - - let services = WebWorkerServiceOptions { - root_cert_store_provider: Some(shared.root_cert_store_provider.clone()), - module_loader, - fs: shared.fs.clone(), - node_services: Some( - shared.create_node_init_services(node_require_loader), - ), - blob_store: shared.blob_store.clone(), - broadcast_channel: shared.broadcast_channel.clone(), - shared_array_buffer_store: Some(shared.shared_array_buffer_store.clone()), - compiled_wasm_module_store: Some( - shared.compiled_wasm_module_store.clone(), - ), - maybe_inspector_server, - feature_checker, - npm_process_state_provider: Some(shared.npm_process_state_provider()), - permissions: args.permissions, - }; - let options = WebWorkerOptions { - name: args.name, - main_module: args.main_module.clone(), - worker_id: args.worker_id, - bootstrap: BootstrapOptions { - deno_version: crate::version::DENO_VERSION_INFO.deno.to_string(), - args: shared.options.argv.clone(), - cpu_count: std::thread::available_parallelism() - .map(|p| p.get()) - .unwrap_or(1), - log_level: shared.options.log_level, - enable_op_summary_metrics: shared.options.enable_op_summary_metrics, - enable_testing_features: shared.options.enable_testing_features, - locale: deno_core::v8::icu::get_language_tag(), - location: Some(args.main_module), - no_color: !colors::use_color(), - color_level: colors::get_color_level(), - is_stdout_tty: deno_terminal::is_stdout_tty(), - is_stderr_tty: deno_terminal::is_stderr_tty(), - unstable_features, - user_agent: version::DENO_VERSION_INFO.user_agent.to_string(), - inspect: shared.options.is_inspecting, - has_node_modules_dir: shared.options.has_node_modules_dir, - argv0: shared.options.argv0.clone(), - node_debug: shared.options.node_debug.clone(), - node_ipc_fd: None, - mode: WorkerExecutionMode::Worker, - serve_port: shared.options.serve_port, - serve_host: shared.options.serve_host.clone(), - otel_config: shared.otel_config.clone(), - close_on_idle: args.close_on_idle, - }, - extensions: vec![], - startup_snapshot: crate::js::deno_isolate_init(), - create_params: create_isolate_create_params(), - unsafely_ignore_certificate_errors: shared - .options - .unsafely_ignore_certificate_errors - .clone(), - seed: shared.options.seed, - create_web_worker_cb, - format_js_error_fn: Some(Arc::new(format_js_error)), - worker_type: args.worker_type, - stdio: stdio.clone(), - cache_storage_dir, - strace_ops: shared.options.strace_ops.clone(), - close_on_idle: args.close_on_idle, - maybe_worker_metadata: args.maybe_worker_metadata, - enable_stack_trace_arg_in_ops: crate::args::has_trace_permissions_enabled( - ), - }; - - WebWorker::bootstrap_from_options(services, options) - }) -} - -/// By default V8 uses 1.4Gb heap limit which is meant for browser tabs. -/// Instead probe for the total memory on the system and use it instead -/// as a default. -pub fn create_isolate_create_params() -> Option { - let maybe_mem_info = deno_runtime::deno_os::sys_info::mem_info(); - maybe_mem_info.map(|mem_info| { - v8::CreateParams::default() - .heap_limits_from_system_memory(mem_info.total, 0) - }) -} - #[allow(clippy::print_stdout)] #[allow(clippy::print_stderr)] #[cfg(test)] mod tests { + use std::rc::Rc; + use deno_core::resolve_path; use deno_core::FsModuleLoader; - use deno_fs::RealFs; + use deno_resolver::npm::DenoInNpmPackageChecker; + use deno_runtime::deno_fs::RealFs; use deno_runtime::deno_permissions::Permissions; use deno_runtime::permissions::RuntimePermissionDescriptorParser; + use deno_runtime::worker::WorkerOptions; + use deno_runtime::worker::WorkerServiceOptions; use super::*; @@ -891,7 +537,7 @@ mod tests { CliNpmResolver, CliSys, >( - main_module, + &main_module, WorkerServiceOptions { module_loader: Rc::new(FsModuleLoader), permissions: PermissionsContainer::new( diff --git a/runtime/examples/extension/main.rs b/runtime/examples/extension/main.rs index e1538b8b75..a1c24f30e4 100644 --- a/runtime/examples/extension/main.rs +++ b/runtime/examples/extension/main.rs @@ -43,7 +43,7 @@ async fn main() -> Result<(), AnyError> { RuntimePermissionDescriptorParser::new(sys_traits::impls::RealSys), ); let mut worker = MainWorker::bootstrap_from_options( - main_module.clone(), + &main_module, WorkerServiceOptions::< DenoInNpmPackageChecker, NpmResolver, diff --git a/runtime/lib.rs b/runtime/lib.rs index c104f5cd61..65d3e88bae 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -18,6 +18,7 @@ pub use deno_net; pub use deno_node; pub use deno_os; pub use deno_permissions; +pub use deno_telemetry; pub use deno_terminal::colors; pub use deno_tls; pub use deno_url; diff --git a/runtime/worker.rs b/runtime/worker.rs index cfcadccc46..426383a19e 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -303,7 +303,7 @@ impl MainWorker { TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TExtNodeSys: ExtNodeSys + 'static, >( - main_module: ModuleSpecifier, + main_module: &ModuleSpecifier, services: WorkerServiceOptions< TInNpmPackageChecker, TNpmPackageFolderResolver, @@ -322,7 +322,7 @@ impl MainWorker { TNpmPackageFolderResolver: NpmPackageFolderResolver + 'static, TExtNodeSys: ExtNodeSys + 'static, >( - main_module: ModuleSpecifier, + main_module: &ModuleSpecifier, services: WorkerServiceOptions< TInNpmPackageChecker, TNpmPackageFolderResolver, From a02ee7adf9097ffeaf3b34f8d00946fdcd0a76b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 15 Jan 2025 18:09:08 +0000 Subject: [PATCH 23/38] ci: try to fix caching on Mac ARM (#27685) --- .github/workflows/ci.generate.ts | 10 ++++++++-- .github/workflows/ci.yml | 10 +++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.generate.ts b/.github/workflows/ci.generate.ts index 55c88fbe85..d0924f79ac 100755 --- a/.github/workflows/ci.generate.ts +++ b/.github/workflows/ci.generate.ts @@ -5,7 +5,7 @@ import { stringify } from "jsr:@std/yaml@^0.221/stringify"; // Bump this number when you want to purge the cache. // Note: the tools/release/01_bump_crate_versions.ts script will update this version // automatically via regex, so ensure that this line maintains this format. -const cacheVersion = 34; +const cacheVersion = 35; const ubuntuX86Runner = "ubuntu-24.04"; const ubuntuX86XlRunner = "ubuntu-24.04-xl"; @@ -41,6 +41,12 @@ const Runners = { macosArm: { os: "macos", arch: "aarch64", + runner: macosArmRunner, + }, + macosArmSelfHosted: { + os: "macos", + arch: "aarch64", + // Actually use self-hosted runner only in denoland/deno on `main` branch. runner: `\${{ github.repository == 'denoland/deno' && github.ref == 'refs/heads/main' && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`, }, @@ -384,7 +390,7 @@ const ci = { job: "test", profile: "debug", }, { - ...Runners.macosArm, + ...Runners.macosArmSelfHosted, job: "test", profile: "release", skip_pr: true, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f217d85032..75ded6fe53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,7 +68,7 @@ jobs: skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}' - os: macos arch: aarch64 - runner: '${{ github.repository == ''denoland/deno'' && github.ref == ''refs/heads/main'' && ''ghcr.io/cirruslabs/macos-runner:sonoma'' || ''macos-14'' }}' + runner: macos-14 job: test profile: debug - os: macos @@ -184,8 +184,8 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: '34-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' - restore-keys: '34-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-' + key: '35-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' + restore-keys: '35-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-' if: '!(matrix.skip)' - uses: dsherret/rust-toolchain-file@v1 if: '!(matrix.skip)' @@ -379,7 +379,7 @@ jobs: !./target/*/*.zip !./target/*/*.tar.gz key: never_saved - restore-keys: '34-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' + restore-keys: '35-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' - name: Apply and update mtime cache if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))' uses: ./.github/mtime_cache @@ -689,7 +689,7 @@ jobs: !./target/*/gn_root !./target/*/*.zip !./target/*/*.tar.gz - key: '34-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' + key: '35-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' publish-canary: name: publish canary runs-on: ubuntu-24.04 From 32708213d5c8ce21765297f37bdf3a86248d530b Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:48:10 -0800 Subject: [PATCH 24/38] fix(check/lsp): correctly resolve compilerOptions.types (#27686) Fixes https://github.com/denoland/deno/issues/27062 In the LSP we were passing `npm` specifiers to TSC as roots, but TSC needs fully resolved specifiers (like the actual file path). In `deno check` we were often excluding the specifiers entirely from the roots. In both cases, we need to resolve the specifiers fully and then pass them to tsc --- cli/lsp/tsc.rs | 20 +++++- cli/tools/check.rs | 64 ++++++++++++++++--- tests/integration/lsp_tests.rs | 49 ++++++++++++++ .../augments-global/1.0.0/index.d.ts | 1 + .../augments-global/1.0.0/other.d.ts | 6 ++ .../augments-global/1.0.0/package.json | 5 ++ .../compiler_options_types/__test__.jsonc | 53 +++++++++++++++ .../check/compiler_options_types/deno.json | 6 ++ .../check/compiler_options_types/main.ts | 2 + .../set_node_modules_dir.ts | 8 +++ tests/util/server/src/lsp.rs | 14 ++++ 11 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 tests/registry/npm/@denotest/augments-global/1.0.0/index.d.ts create mode 100644 tests/registry/npm/@denotest/augments-global/1.0.0/other.d.ts create mode 100644 tests/registry/npm/@denotest/augments-global/1.0.0/package.json create mode 100644 tests/specs/check/compiler_options_types/__test__.jsonc create mode 100644 tests/specs/check/compiler_options_types/deno.json create mode 100644 tests/specs/check/compiler_options_types/main.ts create mode 100644 tests/specs/check/compiler_options_types/set_node_modules_dir.ts diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 0b53dc8506..482d3d6cf7 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -73,6 +73,7 @@ use super::documents::Document; use super::documents::DocumentsFilter; use super::language_server; use super::language_server::StateSnapshot; +use super::logging::lsp_log; use super::performance::Performance; use super::performance::PerformanceMark; use super::refactor::RefactorCodeActionData; @@ -4695,7 +4696,24 @@ fn op_script_names(state: &mut OpState) -> ScriptNames { .graph_imports_by_referrer(scope) { for specifier in specifiers { - script_names.insert(specifier.to_string()); + if let Ok(req_ref) = + deno_semver::npm::NpmPackageReqReference::from_specifier(specifier) + { + let Some((resolved, _)) = + state.state_snapshot.resolver.npm_to_file_url( + &req_ref, + scope, + ResolutionMode::Import, + Some(scope), + ) + else { + lsp_log!("failed to resolve {req_ref} to file URL"); + continue; + }; + script_names.insert(resolved.to_string()); + } else { + script_names.insert(specifier.to_string()); + } } } } diff --git a/cli/tools/check.rs b/cli/tools/check.rs index 8c584113cb..e850b1900f 100644 --- a/cli/tools/check.rs +++ b/cli/tools/check.rs @@ -13,6 +13,7 @@ use deno_graph::Module; use deno_graph::ModuleError; use deno_graph::ModuleGraph; use deno_graph::ModuleLoadError; +use deno_semver::npm::NpmPackageNvReference; use deno_terminal::colors; use once_cell::sync::Lazy; use regex::Regex; @@ -261,6 +262,8 @@ impl TypeChecker { maybe_check_hash, } = get_tsc_roots( &self.sys, + &self.npm_resolver, + &self.node_resolver, &graph, check_js, check_state_hash(&self.npm_resolver), @@ -373,8 +376,11 @@ struct TscRoots { /// redirects resolved. We need to include all the emittable files in /// the roots, so they get type checked and optionally emitted, /// otherwise they would be ignored if only imported into JavaScript. +#[allow(clippy::too_many_arguments)] fn get_tsc_roots( sys: &CliSys, + npm_resolver: &CliNpmResolver, + node_resolver: &CliNodeResolver, graph: &ModuleGraph, check_js: bool, npm_cache_state_hash: Option, @@ -457,6 +463,7 @@ fn get_tsc_roots( if let Some(hasher) = hasher { hasher.write_str(module.specifier.as_str()); } + None } } @@ -493,17 +500,33 @@ fn get_tsc_roots( let mut pending = VecDeque::new(); // put in the global types first so that they're resolved before anything else - let get_import_specifiers = || { - graph - .imports + for (referrer, import) in graph.imports.iter() { + for specifier in import + .dependencies .values() - .flat_map(|i| i.dependencies.values()) .filter_map(|dep| dep.get_type().or_else(|| dep.get_code())) - }; - for specifier in get_import_specifiers() { - let specifier = graph.resolve(specifier); - if seen.insert(specifier) { - pending.push_back((specifier, false)); + { + let specifier = graph.resolve(specifier); + if seen.insert(specifier) { + if let Ok(nv_ref) = NpmPackageNvReference::from_specifier(specifier) { + let Some(resolved) = + resolve_npm_nv_ref(npm_resolver, node_resolver, &nv_ref, referrer) + else { + result.missing_diagnostics.push( + tsc::Diagnostic::from_missing_error( + specifier, + None, + maybe_additional_sloppy_imports_message(sys, specifier), + ), + ); + continue; + }; + let mt = MediaType::from_specifier(&resolved); + result.roots.push((resolved, mt)); + } else { + pending.push_back((specifier, false)); + } + } } } @@ -624,6 +647,29 @@ fn get_tsc_roots( result } +fn resolve_npm_nv_ref( + npm_resolver: &CliNpmResolver, + node_resolver: &CliNodeResolver, + nv_ref: &NpmPackageNvReference, + referrer: &ModuleSpecifier, +) -> Option { + let pkg_dir = npm_resolver + .as_managed() + .unwrap() + .resolve_pkg_folder_from_deno_module(nv_ref.nv()) + .ok()?; + let resolved = node_resolver + .resolve_package_subpath_from_deno_module( + &pkg_dir, + nv_ref.sub_path(), + Some(referrer), + node_resolver::ResolutionMode::Import, + node_resolver::NodeResolutionKind::Types, + ) + .ok()?; + Some(resolved) +} + /// Matches the `@ts-check` pragma. static TS_CHECK_RE: Lazy = lazy_regex::lazy_regex!(r#"(?i)^\s*@ts-check(?:\s+|$)"#); diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index bbeb6e7c13..3c1aa1c4ad 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -17296,3 +17296,52 @@ fn wildcard_augment() { let diagnostics = client.did_open_file(&source); assert_eq!(diagnostics.all().len(), 0); } + +#[test] +fn compiler_options_types() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + let temp = context.temp_dir(); + let temp_dir = temp.path(); + let source = source_file( + temp_dir.join("index.ts"), + r#" + const foo = [1]; + foo.augmented(); + "#, + ); + + let deno_json = json!({ + "imports": { + "@denotest/augments-global": "npm:@denotest/augments-global@1" + }, + "compilerOptions": { "types": ["@denotest/augments-global"] }, + }); + + temp.write("deno.json", deno_json.to_string()); + + client.initialize_default(); + + for node_modules_dir in ["none", "auto", "manual"] { + let mut deno_json = deno_json.clone(); + deno_json["nodeModulesDir"] = json!(node_modules_dir); + temp.write("deno.json", deno_json.to_string()); + context + .new_command() + .args("install") + .run() + .skip_output_check() + .assert_exit_code(0); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp.url().join("deno.json").unwrap(), + "type": 2, + }], + })); + + let diagnostics = client.did_open_file(&source); + eprintln!("{:#?}", diagnostics.all()); + assert_eq!(diagnostics.all().len(), 0); + client.did_close_file(&source); + } +} diff --git a/tests/registry/npm/@denotest/augments-global/1.0.0/index.d.ts b/tests/registry/npm/@denotest/augments-global/1.0.0/index.d.ts new file mode 100644 index 0000000000..f4e31e06dd --- /dev/null +++ b/tests/registry/npm/@denotest/augments-global/1.0.0/index.d.ts @@ -0,0 +1 @@ +import "./other.d.ts"; \ No newline at end of file diff --git a/tests/registry/npm/@denotest/augments-global/1.0.0/other.d.ts b/tests/registry/npm/@denotest/augments-global/1.0.0/other.d.ts new file mode 100644 index 0000000000..91dd7fa2d2 --- /dev/null +++ b/tests/registry/npm/@denotest/augments-global/1.0.0/other.d.ts @@ -0,0 +1,6 @@ +export {} +declare global { + interface Array { + augmented(): void + } +} \ No newline at end of file diff --git a/tests/registry/npm/@denotest/augments-global/1.0.0/package.json b/tests/registry/npm/@denotest/augments-global/1.0.0/package.json new file mode 100644 index 0000000000..33f20414ab --- /dev/null +++ b/tests/registry/npm/@denotest/augments-global/1.0.0/package.json @@ -0,0 +1,5 @@ +{ + "name": "@denotest/augments-global", + "version": "1.0.0", + "types": "./index.d.ts" +} \ No newline at end of file diff --git a/tests/specs/check/compiler_options_types/__test__.jsonc b/tests/specs/check/compiler_options_types/__test__.jsonc new file mode 100644 index 0000000000..f23081fef4 --- /dev/null +++ b/tests/specs/check/compiler_options_types/__test__.jsonc @@ -0,0 +1,53 @@ +{ + "tempDir": true, + "tests": { + "node_modules_dir_none": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts none", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + }, + "node_modules_dir_auto": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts auto", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + }, + "node_modules_dir_manual": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts auto", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + } + } +} diff --git a/tests/specs/check/compiler_options_types/deno.json b/tests/specs/check/compiler_options_types/deno.json new file mode 100644 index 0000000000..9a27ef33a8 --- /dev/null +++ b/tests/specs/check/compiler_options_types/deno.json @@ -0,0 +1,6 @@ +{ + "imports": { + "@denotest/augments-global": "npm:@denotest/augments-global@1" + }, + "compilerOptions": { "types": ["@denotest/augments-global"] } +} diff --git a/tests/specs/check/compiler_options_types/main.ts b/tests/specs/check/compiler_options_types/main.ts new file mode 100644 index 0000000000..ae30721279 --- /dev/null +++ b/tests/specs/check/compiler_options_types/main.ts @@ -0,0 +1,2 @@ +const foo = [1]; +foo.augmented(); diff --git a/tests/specs/check/compiler_options_types/set_node_modules_dir.ts b/tests/specs/check/compiler_options_types/set_node_modules_dir.ts new file mode 100644 index 0000000000..656f215890 --- /dev/null +++ b/tests/specs/check/compiler_options_types/set_node_modules_dir.ts @@ -0,0 +1,8 @@ +if (Deno.args.length !== 1) { + console.error("Usage: set_node_modules_dir.ts "); + Deno.exit(1); +} +const setting = Deno.args[0].trim(); +const denoJson = JSON.parse(Deno.readTextFileSync("./deno.json")); +denoJson["nodeModulesDir"] = setting; +Deno.writeTextFileSync("./deno.json", JSON.stringify(denoJson, null, 2)); diff --git a/tests/util/server/src/lsp.rs b/tests/util/server/src/lsp.rs index 12593578c3..3a7321db62 100644 --- a/tests/util/server/src/lsp.rs +++ b/tests/util/server/src/lsp.rs @@ -900,6 +900,20 @@ impl LspClient { self.read_diagnostics() } + pub fn did_close_file(&mut self, file: &SourceFile) { + self.did_close(json!({ + "textDocument": file.identifier(), + })) + } + + pub fn did_close(&mut self, params: Value) { + self.did_close_raw(params); + } + + pub fn did_close_raw(&mut self, params: Value) { + self.write_notification("textDocument/didClose", params); + } + pub fn did_open_raw(&mut self, params: Value) { self.write_notification("textDocument/didOpen", params); } From e49d6f2d45654a38531f0fc62d1d4802399468f6 Mon Sep 17 00:00:00 2001 From: Muthuraj Ramalingakumar Date: Wed, 15 Jan 2025 20:38:43 -0800 Subject: [PATCH 25/38] chore: add missing internal `core_import_map` file paths (#27691) Noted this when working locally, will help with vscode intellisense. fixes: https://github.com/denoland/deno/issues/27689 --- tools/core_import_map.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/core_import_map.json b/tools/core_import_map.json index 4843884015..0176f47e23 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -81,6 +81,7 @@ "node:https": "../ext/node/polyfills/https.ts", "node:inspector": "../ext/node/polyfills/inspector.ts", "ext:deno_node/inspector.ts": "../ext/node/polyfills/inspector.ts", + "ext:deno_node/internal/idna.ts": "../ext/node/polyfills/internal/idna.ts", "ext:deno_node/internal_binding/_libuv_winerror.ts": "../ext/node/polyfills/internal_binding/_libuv_winerror.ts", "ext:deno_node/internal_binding/_listen.ts": "../ext/node/polyfills/internal_binding/_listen.ts", "ext:deno_node/internal_binding/_node.ts": "../ext/node/polyfills/internal_binding/_node.ts", @@ -95,6 +96,8 @@ "ext:deno_node/internal_binding/crypto.ts": "../ext/node/polyfills/internal_binding/crypto.ts", "ext:deno_node/internal_binding/handle_wrap.ts": "../ext/node/polyfills/internal_binding/handle_wrap.ts", "ext:deno_node/internal_binding/mod.ts": "../ext/node/polyfills/internal_binding/mod.ts", + "ext:deno_node/internal_binding/node_file.ts": "../ext/node/polyfills/internal_binding/node_file.ts", + "ext:deno_node/internal_binding/node_options.ts": "../ext/node/polyfills/internal_binding/node_options.ts", "ext:deno_node/internal_binding/pipe_wrap.ts": "../ext/node/polyfills/internal_binding/pipe_wrap.ts", "ext:deno_node/internal_binding/stream_wrap.ts": "../ext/node/polyfills/internal_binding/stream_wrap.ts", "ext:deno_node/internal_binding/string_decoder.ts": "../ext/node/polyfills/internal_binding/string_decoder.ts", From e54d4678127a2d4124c359af73e3bfe76c71d234 Mon Sep 17 00:00:00 2001 From: Phil Hawksworth Date: Thu, 16 Jan 2025 04:33:08 -0800 Subject: [PATCH 26/38] docs:Adds examples in JSDocs for localStorage and sessionStorage (#27668) Improves docs for: - http://docs.deno.com/api/web/~/localStorage - http://docs.deno.com/api/web/~/sessionStorage --- cli/tsc/dts/lib.deno.window.d.ts | 81 +++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/cli/tsc/dts/lib.deno.window.d.ts b/cli/tsc/dts/lib.deno.window.d.ts index 251f338be6..6fc37ca08d 100644 --- a/cli/tsc/dts/lib.deno.window.d.ts +++ b/cli/tsc/dts/lib.deno.window.d.ts @@ -119,9 +119,86 @@ declare var onunload: ((this: Window, ev: Event) => any) | null; declare var onunhandledrejection: | ((this: Window, ev: PromiseRejectionEvent) => any) | null; -/** @category Storage */ +/** + * Deno's `localStorage` API provides a way to store key-value pairs in a + * web-like environment, similar to the Web Storage API found in browsers. + * It allows developers to persist data across sessions in a Deno application. + * This API is particularly useful for applications that require a simple + * and effective way to store data locally. + * + * - Key-Value Storage: Stores data as key-value pairs. + * - Persistent: Data is retained even after the application is closed. + * - Synchronous API: Operations are performed synchronously. + * + * `localStorage` is similar to {@linkcode sessionStorage}, and shares the same + * API methods, visible in the {@linkcode Storage} type. + * + * When using the `--location` flag, the origin for the location is used to + * uniquely store the data. That means a location of http://example.com/a.ts + * and http://example.com/b.ts and http://example.com:80/ would all share the + * same storage, but https://example.com/ would be different. + * + * For more information, see the reference guide for + * [Web Storage](https://docs.deno.com/runtime/reference/web_platform_apis/#web-storage) + * and using + * [the `--location` flag](https://docs.deno.com/runtime/reference/web_platform_apis/#location-flag). + * + * @example + * ```ts + * // Set a value in localStorage + * localStorage.setItem("key", "value"); + * + * // Get a value from localStorage + * const value = localStorage.getItem("key"); + * console.log(value); // Output: "value" + * + * // Remove a value from localStorage + * localStorage.removeItem("key"); + * + * // Clear all values from localStorage + * localStorage.clear(); + * ``` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage + * @category Storage */ declare var localStorage: Storage; -/** @category Storage */ + +/** + * Deno's `sessionStorage` API operates similarly to the {@linkcode localStorage} API, + * but it is intended for storing data temporarily for the duration of a session. + * Data stored in sessionStorage is cleared when the application session or + * process ends. This makes it suitable for temporary data that you do not need + * to persist across user sessions. + * + * - Key-Value Storage: Stores data as key-value pairs. + * - Session-Based: Data is only available for the duration of the page session. + * - Synchronous API: Operations are performed synchronously. + * + * `sessionStorage` is similar to {@linkcode localStorage}, and shares the same API + * methods, visible in the {@linkcode Storage} type. + * + * For more information, see the reference guide for + * [Web Storage](https://docs.deno.com/runtime/reference/web_platform_apis/#web-storage) + * + * @example + * ```ts + * // Set a value in sessionStorage + * sessionStorage.setItem("key", "value"); + * + * // Get a value from sessionStorage + * const value = sessionStorage.getItem("key"); + * console.log(value); // Output: "value" + * + * // Remove a value from sessionStorage + * sessionStorage.removeItem("key"); + * + * // Clear all the values from sessionStorage + * sessionStorage.clear(); + * ``` + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage + * @category Storage + */ declare var sessionStorage: Storage; /** @category Cache */ declare var caches: CacheStorage; From 8d2f76ae363b8d6f2ae39594c5c08552e76d37f7 Mon Sep 17 00:00:00 2001 From: Phil Hawksworth Date: Thu, 16 Jan 2025 06:20:45 -0800 Subject: [PATCH 27/38] docs: JSDocs examples for prompt, confirm, and alert (#27695) Adds examples --- cli/tsc/dts/lib.deno.window.d.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cli/tsc/dts/lib.deno.window.d.ts b/cli/tsc/dts/lib.deno.window.d.ts index 6fc37ca08d..698b39c5df 100644 --- a/cli/tsc/dts/lib.deno.window.d.ts +++ b/cli/tsc/dts/lib.deno.window.d.ts @@ -226,6 +226,12 @@ declare var navigator: Navigator; * * If the stdin is not interactive, it does nothing. * + * @example + * ```ts + * // Displays the message "Acknowledge me! [Enter]" and waits for the enter key to be pressed before continuing. + * alert("Acknowledge me!"); + * ``` + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/alert * @category Platform * * @param message @@ -239,6 +245,15 @@ declare function alert(message?: string): void; * * If the stdin is not interactive, it returns false. * + * @example + * ```ts + * const shouldProceed = confirm("Do you want to proceed?"); + * + * // If the user presses 'y' or 'Y', the result will be true + * // If the user presses 'n' or 'N', the result will be false + * console.log("Should proceed?", shouldProceed); + * ``` + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm * @category Platform * * @param message @@ -256,6 +271,15 @@ declare function confirm(message?: string): boolean; * * If the stdin is not interactive, it returns null. * + * @example + * ```ts + * const pet = prompt("Cats or dogs?", "It's fine to love both!"); + * + * // Displays the user's input or the default value of "It's fine to love both!" + * console.log("Best pet:", pet); + * ``` + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt + * * @category Platform * * @param message From 17d6e66ee336057954ab22544f30ea2761991a25 Mon Sep 17 00:00:00 2001 From: Jo Franchetti Date: Thu, 16 Jan 2025 14:48:13 +0000 Subject: [PATCH 28/38] docs: adding jsdocs info for console interface (#27666) Signed-off-by: Jo Franchetti Co-authored-by: Marvin Hagemeister --- cli/lsp/tsc.rs | 35 ++++- ext/console/lib.deno_console.d.ts | 224 +++++++++++++++++++++++++++++- 2 files changed, 255 insertions(+), 4 deletions(-) diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 482d3d6cf7..09e11380ac 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -6263,7 +6263,40 @@ mod tests { "kind": "keyword" } ], - "documentation": [] + "documentation": [ + { + "text": "Outputs a message to the console", + "kind": "text", + }, + ], + "tags": [ + { + "name": "param", + "text": [ + { + "text": "data", + "kind": "parameterName", + }, + { + "text": " ", + "kind": "space", + }, + { + "text": "Values to be printed to the console", + "kind": "text", + }, + ], + }, + { + "name": "example", + "text": [ + { + "text": "```ts\nconsole.log('Hello', 'World', 123);\n```", + "kind": "text", + }, + ], + }, + ] }) ); } diff --git a/ext/console/lib.deno_console.d.ts b/ext/console/lib.deno_console.d.ts index 54bbcab892..1f6c3fe682 100644 --- a/ext/console/lib.deno_console.d.ts +++ b/ext/console/lib.deno_console.d.ts @@ -6,33 +6,251 @@ /// /** @category I/O */ +/** + * The Console interface provides methods for logging information to the console, + * as well as other utility methods for debugging and inspecting code. + * @see https://developer.mozilla.org/en-US/docs/Web/API/console + */ +/** Interface representing the console object that provides methods for logging, debugging, and timing */ interface Console { + /** + * Tests that an expression is true. If not, logs an error message + * @param condition The expression to test for truthiness + * @param data Additional arguments to be printed if the assertion fails + * @example + * ```ts + * console.assert(1 === 1, "This won't show"); + * console.assert(1 === 2, "This will show an error"); + * ``` + */ assert(condition?: boolean, ...data: any[]): void; + + /** + * Clears the console if the environment allows it + * @example + * ```ts + * console.clear(); + * ``` + */ clear(): void; + + /** + * Maintains an internal counter for a given label, incrementing it each time the method is called + * @param label The label to count. Defaults to 'default' + * @example + * ```ts + * console.count('myCounter'); + * console.count('myCounter'); // Will show: myCounter: 2 + * ``` + */ count(label?: string): void; + + /** + * Resets the counter for a given label + * @param label The label to reset. Defaults to 'default' + * @example + * ```ts + * console.count('myCounter'); + * console.countReset('myCounter'); // Resets to 0 + * ``` + */ countReset(label?: string): void; + + /** + * Outputs a debugging message to the console + * @param data Values to be printed to the console + * @example + * ```ts + * console.debug('Debug message', { detail: 'some data' }); + * ``` + */ debug(...data: any[]): void; + + /** + * Displays a list of the properties of a specified object + * @param item Object to display + * @param options Formatting options + * @example + * ```ts + * console.dir({ name: 'object', value: 42 }, { depth: 1 }); + * ``` + */ dir(item?: any, options?: any): void; + + /** + * @ignore + */ dirxml(...data: any[]): void; + + /** + * Outputs an error message to the console. + * This method routes the output to stderr, + * unlike other console methods that route to stdout. + * @param data Values to be printed to the console + * @example + * ```ts + * console.error('Error occurred:', new Error('Something went wrong')); + * ``` + */ error(...data: any[]): void; + + /** + * Creates a new inline group in the console, indenting subsequent console messages + * @param data Labels for the group + * @example + * ```ts + * console.group('Group 1'); + * console.log('Inside group 1'); + * console.groupEnd(); + * ``` + */ group(...data: any[]): void; + + /** + * Creates a new inline group in the console that is initially collapsed + * @param data Labels for the group + * @example + * ```ts + * console.groupCollapsed('Details'); + * console.log('Hidden until expanded'); + * console.groupEnd(); + * ``` + */ groupCollapsed(...data: any[]): void; + + /** + * Exits the current inline group in the console + * @example + * ```ts + * console.group('Group'); + * console.log('Grouped message'); + * console.groupEnd(); + * ``` + */ groupEnd(): void; + + /** + * Outputs an informational message to the console + * @param data Values to be printed to the console + * @example + * ```ts + * console.info('Application started', { version: '1.0.0' }); + * ``` + */ info(...data: any[]): void; + + /** + * Outputs a message to the console + * @param data Values to be printed to the console + * @example + * ```ts + * console.log('Hello', 'World', 123); + * ``` + */ log(...data: any[]): void; + + /** + * Displays tabular data as a table + * @param tabularData Data to be displayed in table format + * @param properties Array of property names to be displayed + * @example + * ```ts + * console.table([ + * { name: 'John', age: 30 }, + * { name: 'Jane', age: 25 } + * ]); + * ``` + */ table(tabularData?: any, properties?: string[]): void; + + /** + * Starts a timer you can use to track how long an operation takes + * @param label Timer label. Defaults to 'default' + * @example + * ```ts + * console.time('operation'); + * // ... some code + * console.timeEnd('operation'); + * ``` + */ time(label?: string): void; + + /** + * Stops a timer that was previously started + * @param label Timer label to stop. Defaults to 'default' + * @example + * ```ts + * console.time('operation'); + * // ... some code + * console.timeEnd('operation'); // Prints: operation: 1234ms + * ``` + */ timeEnd(label?: string): void; + + /** + * Logs the current value of a timer that was previously started + * @param label Timer label + * @param data Additional data to log + * @example + * ```ts + * console.time('process'); + * // ... some code + * console.timeLog('process', 'Checkpoint A'); + * ``` + */ timeLog(label?: string, ...data: any[]): void; + + /** + * Outputs a stack trace to the console + * @param data Values to be printed to the console + * @example + * ```ts + * console.trace('Trace message'); + * ``` + */ trace(...data: any[]): void; + + /** + * Outputs a warning message to the console + * @param data Values to be printed to the console + * @example + * ```ts + * console.warn('Deprecated feature used'); + * ``` + */ warn(...data: any[]): void; - /** This method is a noop, unless used in inspector */ + /** + * Adds a marker to the DevTools Performance panel + * @param label Label for the timestamp + * @example + * ```ts + * console.timeStamp('Navigation Start'); + * ``` + */ timeStamp(label?: string): void; - /** This method is a noop, unless used in inspector */ + /** + * Starts recording a performance profile + * @param label Profile label + * @example + * ```ts + * console.profile('Performance Profile'); + * // ... code to profile + * console.profileEnd('Performance Profile'); + * ``` + */ profile(label?: string): void; - /** This method is a noop, unless used in inspector */ + /** + * Stops recording a performance profile + * @param label Profile label to stop + * @example + * ```ts + * console.profile('Performance Profile'); + * // ... code to profile + * console.profileEnd('Performance Profile'); + * ``` + */ profileEnd(label?: string): void; } From 2debe9c8dd06ec287034852dc41293cf851e8be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 16 Jan 2025 18:27:54 +0000 Subject: [PATCH 29/38] fix(ext/console): change Temporal color (#27684) This commit changes output color of `Temporal` instances from "magenta" to "cyan" to discriminate them from `Date` instances. Closes https://github.com/denoland/deno/issues/27585 --- ext/console/01_console.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/console/01_console.js b/ext/console/01_console.js index a85faaccf1..09441a56a3 100644 --- a/ext/console/01_console.js +++ b/ext/console/01_console.js @@ -216,7 +216,7 @@ const styles = { regexp: "red", module: "underline", internalError: "red", - temporal: "magenta", + temporal: "cyan", }; const defaultFG = 39; From 464ee9155e9e3938ab460beb5c240f1d5492e67b Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Thu, 16 Jan 2025 11:20:04 -0800 Subject: [PATCH 30/38] fix(check/lsp): fix bugs with tsc type resolution, allow npm packages to augment `ImportMeta` (#27690) Fixes #26224. Fixes #27042. There were three bugs here: - we were only resolving `/// ` directive in most of the vite templates) - the `$node_modules` workaround caused us to fail to read files for tsc. For instance tsc would construct new paths based on specifiers containing `$node_modules`, and since we hadn't created those we weren't mapping them back to the original (this broke some type resolution within `vite/client`) - our separation of `ImportMeta` across node and deno globals in tsc meant that npm packages couldn't augment `ImportMeta` (this broke `vite/client`'s augmentation to add `import.meta.env` and others) After this, the only remaining issue in the vanilla vite template is our error on `/vite.svg` (which is an ambient module), and I'll look into that next. --- cli/lsp/tsc.rs | 4 +- cli/tsc/99_main_compiler.js | 116 +++++++++++------- tests/integration/lsp_tests.rs | 79 +++++++++++- .../augments-global/1.0.0/import-meta.d.ts | 3 + .../augments-global/1.0.0/package.json | 10 +- .../1.0.0/real-import-meta.d.ts | 8 ++ .../import_meta_no_errors/__test__.jsonc | 53 ++++++++ .../check/import_meta_no_errors/deno.json | 5 + .../specs/check/import_meta_no_errors/main.ts | 3 + .../set_node_modules_dir.ts | 8 ++ .../type_reference_import_meta/__test__.jsonc | 53 ++++++++ .../type_reference_import_meta/deno.json | 6 + .../check/type_reference_import_meta/main.ts | 3 + .../set_node_modules_dir.ts | 8 ++ .../type_reference_import_meta/types.d.ts | 1 + 15 files changed, 311 insertions(+), 49 deletions(-) create mode 100644 tests/registry/npm/@denotest/augments-global/1.0.0/import-meta.d.ts create mode 100644 tests/registry/npm/@denotest/augments-global/1.0.0/real-import-meta.d.ts create mode 100644 tests/specs/check/import_meta_no_errors/__test__.jsonc create mode 100644 tests/specs/check/import_meta_no_errors/deno.json create mode 100644 tests/specs/check/import_meta_no_errors/main.ts create mode 100644 tests/specs/check/import_meta_no_errors/set_node_modules_dir.ts create mode 100644 tests/specs/check/type_reference_import_meta/__test__.jsonc create mode 100644 tests/specs/check/type_reference_import_meta/deno.json create mode 100644 tests/specs/check/type_reference_import_meta/main.ts create mode 100644 tests/specs/check/type_reference_import_meta/set_node_modules_dir.ts create mode 100644 tests/specs/check/type_reference_import_meta/types.d.ts diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 09e11380ac..32352d9f26 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -4341,7 +4341,9 @@ impl TscSpecifierMap { if let Some(specifier) = self.normalized_specifiers.get(original) { return Ok(specifier.clone()); } - let specifier_str = original.replace(".d.ts.d.ts", ".d.ts"); + let specifier_str = original + .replace(".d.ts.d.ts", ".d.ts") + .replace("$node_modules", "node_modules"); let specifier = match ModuleSpecifier::parse(&specifier_str) { Ok(s) => s, Err(err) => return Err(err), diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js index b3279f54ac..65319211fb 100644 --- a/cli/tsc/99_main_compiler.js +++ b/cli/tsc/99_main_compiler.js @@ -500,6 +500,8 @@ delete Object.prototype.__proto__; // Microsoft/TypeScript#26825 but that doesn't seem to be working here, // so we will ignore complaints about this compiler setting. 5070, + // TS6053: File '{0}' not found. + 6053, // TS7016: Could not find a declaration file for module '...'. '...' // implicitly has an 'any' type. This is due to `allowJs` being off by // default but importing of a JavaScript module. @@ -705,15 +707,14 @@ delete Object.prototype.__proto__; resolveTypeReferenceDirectiveReferences( typeDirectiveReferences, containingFilePath, - redirectedReference, + _redirectedReference, options, containingSourceFile, _reusedNames, ) { const isCjs = containingSourceFile?.impliedNodeFormat === ts.ModuleKind.CommonJS; - /** @type {Array} */ - const result = typeDirectiveReferences.map((arg) => { + const toResolve = typeDirectiveReferences.map((arg) => { /** @type {ts.FileReference} */ const fileReference = typeof arg === "string" ? { @@ -722,46 +723,50 @@ delete Object.prototype.__proto__; fileName: arg, } : arg; - if (fileReference.fileName.startsWith("npm:")) { - /** @type {[string, ts.Extension | null] | undefined} */ - const resolved = ops.op_resolve( - containingFilePath, - [ - [ - fileReference.resolutionMode == null - ? isCjs - : fileReference.resolutionMode === ts.ModuleKind.CommonJS, - fileReference.fileName, - ], - ], - )?.[0]; - if (resolved && resolved[1]) { - return { - resolvedTypeReferenceDirective: { - primary: true, - resolvedFileName: resolved[0], - // todo(dsherret): we should probably be setting this - isExternalLibraryImport: undefined, - }, - }; - } else { - return { - resolvedTypeReferenceDirective: undefined, - }; - } + return [ + fileReference.resolutionMode == null + ? isCjs + : fileReference.resolutionMode === ts.ModuleKind.CommonJS, + fileReference.fileName, + ]; + }); + + /** @type {Array<[string, ts.Extension | null] | undefined>} */ + const resolved = ops.op_resolve( + containingFilePath, + toResolve, + ); + + /** @type {Array} */ + const result = resolved.map((item) => { + if (item && item[1]) { + const [resolvedFileName, extension] = item; + return { + resolvedTypeReferenceDirective: { + primary: true, + resolvedFileName, + extension, + isExternalLibraryImport: false, + }, + }; } else { - return ts.resolveTypeReferenceDirective( - fileReference.fileName, - containingFilePath, - options, - host, - redirectedReference, - undefined, - containingSourceFile?.impliedNodeFormat ?? - fileReference.resolutionMode, - ); + return { + resolvedTypeReferenceDirective: undefined, + }; } }); + + if (logDebug) { + debug( + "resolveTypeReferenceDirectiveReferences ", + typeDirectiveReferences, + containingFilePath, + options, + containingSourceFile?.fileName, + " => ", + result, + ); + } return result; }, resolveModuleNameLiterals( @@ -1116,6 +1121,36 @@ delete Object.prototype.__proto__; if (IGNORED_DIAGNOSTICS.includes(diagnostic.code)) { return false; } + + // ignore diagnostics resulting from the `ImportMeta` declaration in deno merging with + // the one in @types/node. the types of the filename and dirname properties are different, + // which causes tsc to error. + const importMetaFilenameDirnameModifiersRe = + /^All declarations of '(filename|dirname)'/; + const importMetaFilenameDirnameTypesRe = + /^Subsequent property declarations must have the same type.\s+Property '(filename|dirname)'/; + // Declarations of X must have identical modifiers. + if (diagnostic.code === 2687) { + if ( + typeof diagnostic.messageText === "string" && + (importMetaFilenameDirnameModifiersRe.test(diagnostic.messageText)) && + (diagnostic.file?.fileName.startsWith("asset:///") || + diagnostic.file?.fileName?.includes("@types/node")) + ) { + return false; + } + } + // Subsequent property declarations must have the same type. + if (diagnostic.code === 2717) { + if ( + typeof diagnostic.messageText === "string" && + (importMetaFilenameDirnameTypesRe.test(diagnostic.messageText)) && + (diagnostic.file?.fileName.startsWith("asset:///") || + diagnostic.file?.fileName?.includes("@types/node")) + ) { + return false; + } + } // make the diagnostic for using an `export =` in an es module a warning if (diagnostic.code === 1203) { diagnostic.category = ts.DiagnosticCategory.Warning; @@ -1410,7 +1445,6 @@ delete Object.prototype.__proto__; "ErrorConstructor", "gc", "Global", - "ImportMeta", "localStorage", "queueMicrotask", "RequestInit", diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 3c1aa1c4ad..9607207163 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -17326,12 +17326,7 @@ fn compiler_options_types() { let mut deno_json = deno_json.clone(); deno_json["nodeModulesDir"] = json!(node_modules_dir); temp.write("deno.json", deno_json.to_string()); - context - .new_command() - .args("install") - .run() - .skip_output_check() - .assert_exit_code(0); + context.run_deno("install"); client.did_change_watched_files(json!({ "changes": [{ "uri": temp.url().join("deno.json").unwrap(), @@ -17345,3 +17340,75 @@ fn compiler_options_types() { client.did_close_file(&source); } } + +#[test] +fn type_reference_import_meta() { + let context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let mut client = context.new_lsp_command().build(); + let temp = context.temp_dir(); + let temp_dir = temp.path(); + let source = source_file( + temp_dir.join("index.ts"), + r#" + const test = import.meta.env.TEST; + const bar = import.meta.bar; + console.log(test, bar); + "#, + ); + /* + tests type reference w/ bare specifier, type reference in an npm package, + and augmentation of `ImportMeta` (this combination modeled after the vanilla vite template, + which uses `vite/client`) + + @denotest/augments-global/import-meta: + ```dts + /// + + export type Foo = number; + ``` + + real-import-meta.d.ts: + ```dts + interface ImportMetaEnv { + TEST: string; + } + + interface ImportMeta { + env: ImportMetaEnv; + bar: number; + } + ``` + */ + temp.write( + "types.d.ts", + r#" + /// + "#, + ); + + let deno_json = json!({ + "imports": { + "@denotest/augments-global": "npm:@denotest/augments-global@1" + } + }); + temp.write("deno.json", deno_json.to_string()); + + client.initialize_default(); + + for node_modules_dir in ["none", "auto", "manual"] { + let mut deno_json = deno_json.clone(); + deno_json["nodeModulesDir"] = json!(node_modules_dir); + temp.write("deno.json", deno_json.to_string()); + context.run_deno("install"); + client.did_change_watched_files(json!({ + "changes": [{ + "uri": temp.url().join("deno.json").unwrap(), + "type": 2, + }], + })); + + let diagnostics = client.did_open_file(&source); + assert_eq!(diagnostics.all().len(), 0); + client.did_close_file(&source); + } +} diff --git a/tests/registry/npm/@denotest/augments-global/1.0.0/import-meta.d.ts b/tests/registry/npm/@denotest/augments-global/1.0.0/import-meta.d.ts new file mode 100644 index 0000000000..9dbe976c2f --- /dev/null +++ b/tests/registry/npm/@denotest/augments-global/1.0.0/import-meta.d.ts @@ -0,0 +1,3 @@ +/// + +export type Foo = number; \ No newline at end of file diff --git a/tests/registry/npm/@denotest/augments-global/1.0.0/package.json b/tests/registry/npm/@denotest/augments-global/1.0.0/package.json index 33f20414ab..a63e420d68 100644 --- a/tests/registry/npm/@denotest/augments-global/1.0.0/package.json +++ b/tests/registry/npm/@denotest/augments-global/1.0.0/package.json @@ -1,5 +1,13 @@ { "name": "@denotest/augments-global", "version": "1.0.0", - "types": "./index.d.ts" + "types": "./index.d.ts", + "exports": { + ".": { + "types": "./index.d.ts" + }, + "./import-meta": { + "types": "./import-meta.d.ts" + } + } } \ No newline at end of file diff --git a/tests/registry/npm/@denotest/augments-global/1.0.0/real-import-meta.d.ts b/tests/registry/npm/@denotest/augments-global/1.0.0/real-import-meta.d.ts new file mode 100644 index 0000000000..06875eeef3 --- /dev/null +++ b/tests/registry/npm/@denotest/augments-global/1.0.0/real-import-meta.d.ts @@ -0,0 +1,8 @@ +interface ImportMetaEnv { + TEST: string; +} + +interface ImportMeta { + env: ImportMetaEnv; + bar: number; +} \ No newline at end of file diff --git a/tests/specs/check/import_meta_no_errors/__test__.jsonc b/tests/specs/check/import_meta_no_errors/__test__.jsonc new file mode 100644 index 0000000000..e03edb297f --- /dev/null +++ b/tests/specs/check/import_meta_no_errors/__test__.jsonc @@ -0,0 +1,53 @@ +{ + "tempDir": true, + "tests": { + "node_modules_dir_none": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts none", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check --all ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + }, + "node_modules_dir_auto": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts auto", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check --all ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + }, + "node_modules_dir_manual": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts auto", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check --all ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + } + } +} diff --git a/tests/specs/check/import_meta_no_errors/deno.json b/tests/specs/check/import_meta_no_errors/deno.json new file mode 100644 index 0000000000..4cc5c30d3a --- /dev/null +++ b/tests/specs/check/import_meta_no_errors/deno.json @@ -0,0 +1,5 @@ +{ + "imports": { + "@types/node": "npm:@types/node@*" + } +} diff --git a/tests/specs/check/import_meta_no_errors/main.ts b/tests/specs/check/import_meta_no_errors/main.ts new file mode 100644 index 0000000000..ff1b8e3629 --- /dev/null +++ b/tests/specs/check/import_meta_no_errors/main.ts @@ -0,0 +1,3 @@ +/// + +const _foo = import.meta.dirname; diff --git a/tests/specs/check/import_meta_no_errors/set_node_modules_dir.ts b/tests/specs/check/import_meta_no_errors/set_node_modules_dir.ts new file mode 100644 index 0000000000..656f215890 --- /dev/null +++ b/tests/specs/check/import_meta_no_errors/set_node_modules_dir.ts @@ -0,0 +1,8 @@ +if (Deno.args.length !== 1) { + console.error("Usage: set_node_modules_dir.ts "); + Deno.exit(1); +} +const setting = Deno.args[0].trim(); +const denoJson = JSON.parse(Deno.readTextFileSync("./deno.json")); +denoJson["nodeModulesDir"] = setting; +Deno.writeTextFileSync("./deno.json", JSON.stringify(denoJson, null, 2)); diff --git a/tests/specs/check/type_reference_import_meta/__test__.jsonc b/tests/specs/check/type_reference_import_meta/__test__.jsonc new file mode 100644 index 0000000000..f23081fef4 --- /dev/null +++ b/tests/specs/check/type_reference_import_meta/__test__.jsonc @@ -0,0 +1,53 @@ +{ + "tempDir": true, + "tests": { + "node_modules_dir_none": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts none", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + }, + "node_modules_dir_auto": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts auto", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + }, + "node_modules_dir_manual": { + "steps": [ + { + "args": "run -A ./set_node_modules_dir.ts auto", + "output": "" + }, + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "check ./main.ts", + "output": "Check [WILDCARD]main.ts\n" + } + ] + } + } +} diff --git a/tests/specs/check/type_reference_import_meta/deno.json b/tests/specs/check/type_reference_import_meta/deno.json new file mode 100644 index 0000000000..bea3f5b73d --- /dev/null +++ b/tests/specs/check/type_reference_import_meta/deno.json @@ -0,0 +1,6 @@ +{ + "imports": { + "@denotest/augments-global": "npm:@denotest/augments-global@1" + }, + "compilerOptions": { "types": ["./types.d.ts"] } +} diff --git a/tests/specs/check/type_reference_import_meta/main.ts b/tests/specs/check/type_reference_import_meta/main.ts new file mode 100644 index 0000000000..c0924e35ef --- /dev/null +++ b/tests/specs/check/type_reference_import_meta/main.ts @@ -0,0 +1,3 @@ +const test = import.meta.env.TEST; +const bar = import.meta.bar; +console.log(test, bar); diff --git a/tests/specs/check/type_reference_import_meta/set_node_modules_dir.ts b/tests/specs/check/type_reference_import_meta/set_node_modules_dir.ts new file mode 100644 index 0000000000..656f215890 --- /dev/null +++ b/tests/specs/check/type_reference_import_meta/set_node_modules_dir.ts @@ -0,0 +1,8 @@ +if (Deno.args.length !== 1) { + console.error("Usage: set_node_modules_dir.ts "); + Deno.exit(1); +} +const setting = Deno.args[0].trim(); +const denoJson = JSON.parse(Deno.readTextFileSync("./deno.json")); +denoJson["nodeModulesDir"] = setting; +Deno.writeTextFileSync("./deno.json", JSON.stringify(denoJson, null, 2)); diff --git a/tests/specs/check/type_reference_import_meta/types.d.ts b/tests/specs/check/type_reference_import_meta/types.d.ts new file mode 100644 index 0000000000..2df7d5371b --- /dev/null +++ b/tests/specs/check/type_reference_import_meta/types.d.ts @@ -0,0 +1 @@ +/// From 256950ddb6ff7029944f9da14147211d8cc20b7c Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Thu, 16 Jan 2025 11:33:38 -0800 Subject: [PATCH 31/38] fix(outdated): retain strict semver specifier when updating (#27701) Fixes https://github.com/denoland/deno/issues/27697 If it's a strict bound (e.g. `1.0.0` as opposed to `^1.0.0` or other), retain the strictness when we update --- cli/tools/registry/pm/outdated.rs | 8 +++++++- tests/specs/update/deno_json/filtered/deno.json.out | 2 +- .../update/deno_json/update_latest/deno.json.out | 8 ++++---- .../update/deno_json/update_latest/deno.lock.out | 12 ++++++------ .../update/external_import_map/import_map.json.out | 2 +- .../filtered/member_b_package.json.out | 2 +- .../update_latest/subdir/member_a_deno.json.out | 4 ++-- .../update_latest/subdir/member_b_package.json.out | 4 ++-- .../update/package_json/update_latest/deno.lock.out | 4 ++-- .../package_json/update_latest/package.json.out | 2 +- 10 files changed, 27 insertions(+), 21 deletions(-) diff --git a/cli/tools/registry/pm/outdated.rs b/cli/tools/registry/pm/outdated.rs index 939c30b5c1..610ad48c1d 100644 --- a/cli/tools/registry/pm/outdated.rs +++ b/cli/tools/registry/pm/outdated.rs @@ -280,9 +280,15 @@ fn choose_new_version_req( if preferred.version <= resolved?.version { return None; } + let exact = if let Some(range) = dep.req.version_req.range() { + range.0[0].start == range.0[0].end + } else { + false + }; Some( VersionReq::parse_from_specifier( - format!("^{}", preferred.version).as_str(), + format!("{}{}", if exact { "" } else { "^" }, preferred.version) + .as_str(), ) .unwrap(), ) diff --git a/tests/specs/update/deno_json/filtered/deno.json.out b/tests/specs/update/deno_json/filtered/deno.json.out index 4458e2d037..2ad36ca1ec 100644 --- a/tests/specs/update/deno_json/filtered/deno.json.out +++ b/tests/specs/update/deno_json/filtered/deno.json.out @@ -5,7 +5,7 @@ "@denotest/subtract": "jsr:@denotest/subtract@^0.2.0", "@denotest/with-subpath": "jsr:@denotest/multiple-exports@0.5.0/data-json", "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@1.0.0", - "@denotest/bin": "npm:@denotest/bin@^1.0.0", + "@denotest/bin": "npm:@denotest/bin@1.0.0", "@denotest/has-patch-versions": "npm:@denotest/has-patch-versions@^0.1.0" }, "scopes": { diff --git a/tests/specs/update/deno_json/update_latest/deno.json.out b/tests/specs/update/deno_json/update_latest/deno.json.out index 5e4e99bd66..2b5d1f95d7 100644 --- a/tests/specs/update/deno_json/update_latest/deno.json.out +++ b/tests/specs/update/deno_json/update_latest/deno.json.out @@ -3,9 +3,9 @@ "@denotest/add": "jsr:@denotest/add@^1.0.0", "@denotest/add/": "jsr:/@denotest/add@^1.0.0/", "@denotest/subtract": "jsr:@denotest/subtract@^1.0.0", - "@denotest/with-subpath": "jsr:@denotest/multiple-exports@^1.0.0/data-json", - "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@^2.0.0", - "@denotest/bin": "npm:@denotest/bin@^1.0.0", + "@denotest/with-subpath": "jsr:@denotest/multiple-exports@1.0.0/data-json", + "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@2.0.0", + "@denotest/bin": "npm:@denotest/bin@1.0.0", "@denotest/has-patch-versions": "npm:@denotest/has-patch-versions@^0.2.0" }, "scopes": { @@ -13,7 +13,7 @@ "@denotest/add": "jsr:@denotest/add@^1.0.0", "@denotest/add/": "jsr:/@denotest/add@^1.0.0/", "@denotest/subtract": "jsr:@denotest/subtract@^1.0.0", - "@denotest/with-subpath": "jsr:@denotest/multiple-exports@^1.0.0/data-json" + "@denotest/with-subpath": "jsr:@denotest/multiple-exports@1.0.0/data-json" } } } diff --git a/tests/specs/update/deno_json/update_latest/deno.lock.out b/tests/specs/update/deno_json/update_latest/deno.lock.out index ad83546ab1..88403fc77e 100644 --- a/tests/specs/update/deno_json/update_latest/deno.lock.out +++ b/tests/specs/update/deno_json/update_latest/deno.lock.out @@ -2,10 +2,10 @@ "version": "4", "specifiers": { "jsr:@denotest/add@1": "1.0.0", - "jsr:@denotest/multiple-exports@1": "1.0.0", + "jsr:@denotest/multiple-exports@1.0.0": "1.0.0", "jsr:@denotest/subtract@1": "1.0.0", - "npm:@denotest/bin@1": "1.0.0", - "npm:@denotest/breaking-change-between-versions@2": "2.0.0", + "npm:@denotest/bin@1.0.0": "1.0.0", + "npm:@denotest/breaking-change-between-versions@2.0.0": "2.0.0", "npm:@denotest/has-patch-versions@0.2": "0.2.0" }, "jsr": { @@ -33,10 +33,10 @@ "workspace": { "dependencies": [ "jsr:@denotest/add@1", - "jsr:@denotest/multiple-exports@1", + "jsr:@denotest/multiple-exports@1.0.0", "jsr:@denotest/subtract@1", - "npm:@denotest/bin@1", - "npm:@denotest/breaking-change-between-versions@2", + "npm:@denotest/bin@1.0.0", + "npm:@denotest/breaking-change-between-versions@2.0.0", "npm:@denotest/has-patch-versions@0.2" ] } diff --git a/tests/specs/update/external_import_map/import_map.json.out b/tests/specs/update/external_import_map/import_map.json.out index b4e24decbc..998f49eec7 100644 --- a/tests/specs/update/external_import_map/import_map.json.out +++ b/tests/specs/update/external_import_map/import_map.json.out @@ -2,7 +2,7 @@ "imports": { "@denotest/add": "jsr:@denotest/add@^1.0.0", "@denotest/subtract": "jsr:@denotest/subtract@^1.0.0", - "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@^2.0.0", + "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@2.0.0", "@denotest/has-patch-versions": "npm:@denotest/has-patch-versions@^0.2.0" } } diff --git a/tests/specs/update/mixed_workspace/filtered/member_b_package.json.out b/tests/specs/update/mixed_workspace/filtered/member_b_package.json.out index 7e582feeab..ee3c0a8548 100644 --- a/tests/specs/update/mixed_workspace/filtered/member_b_package.json.out +++ b/tests/specs/update/mixed_workspace/filtered/member_b_package.json.out @@ -3,6 +3,6 @@ "version": "0.1.0", "dependencies": { "@denotest/has-patch-versions": "0.1.0", - "aliased": "npm:@denotest/bin@^1.0.0" + "aliased": "npm:@denotest/bin@1.0.0" } } diff --git a/tests/specs/update/mixed_workspace/update_latest/subdir/member_a_deno.json.out b/tests/specs/update/mixed_workspace/update_latest/subdir/member_a_deno.json.out index 9210123b82..bda55c6ec5 100644 --- a/tests/specs/update/mixed_workspace/update_latest/subdir/member_a_deno.json.out +++ b/tests/specs/update/mixed_workspace/update_latest/subdir/member_a_deno.json.out @@ -4,7 +4,7 @@ "imports": { "@denotest/add": "jsr:@denotest/add@^1.0.0", "@denotest/add/": "jsr:/@denotest/add@^1.0.0/", - "@denotest/with-subpath": "jsr:@denotest/multiple-exports@^1.0.0/data-json", - "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@^2.0.0" + "@denotest/with-subpath": "jsr:@denotest/multiple-exports@1.0.0/data-json", + "@denotest/breaking-change-between-versions": "npm:@denotest/breaking-change-between-versions@2.0.0" } } diff --git a/tests/specs/update/mixed_workspace/update_latest/subdir/member_b_package.json.out b/tests/specs/update/mixed_workspace/update_latest/subdir/member_b_package.json.out index 1426fcd7f8..9118e94654 100644 --- a/tests/specs/update/mixed_workspace/update_latest/subdir/member_b_package.json.out +++ b/tests/specs/update/mixed_workspace/update_latest/subdir/member_b_package.json.out @@ -2,7 +2,7 @@ "name": "@denotest/member-b", "version": "0.1.0", "dependencies": { - "@denotest/has-patch-versions": "^0.2.0", - "aliased": "npm:@denotest/bin@^1.0.0" + "@denotest/has-patch-versions": "0.2.0", + "aliased": "npm:@denotest/bin@1.0.0" } } diff --git a/tests/specs/update/package_json/update_latest/deno.lock.out b/tests/specs/update/package_json/update_latest/deno.lock.out index 9a9b1bad5e..6723c8d475 100644 --- a/tests/specs/update/package_json/update_latest/deno.lock.out +++ b/tests/specs/update/package_json/update_latest/deno.lock.out @@ -2,7 +2,7 @@ "version": "4", "specifiers": { "npm:@denotest/bin@1": "1.0.0", - "npm:@denotest/breaking-change-between-versions@2": "2.0.0", + "npm:@denotest/breaking-change-between-versions@2.0.0": "2.0.0", "npm:@denotest/has-patch-versions@0.2": "0.2.0" }, "npm": { @@ -20,7 +20,7 @@ "packageJson": { "dependencies": [ "npm:@denotest/bin@1", - "npm:@denotest/breaking-change-between-versions@2", + "npm:@denotest/breaking-change-between-versions@2.0.0", "npm:@denotest/has-patch-versions@0.2" ] } diff --git a/tests/specs/update/package_json/update_latest/package.json.out b/tests/specs/update/package_json/update_latest/package.json.out index fb483d78bd..ac3c3ff460 100644 --- a/tests/specs/update/package_json/update_latest/package.json.out +++ b/tests/specs/update/package_json/update_latest/package.json.out @@ -1,7 +1,7 @@ { "dependencies": { "@denotest/has-patch-versions": "^0.2.0", - "@denotest/breaking-change-between-versions": "^2.0.0" + "@denotest/breaking-change-between-versions": "2.0.0" }, "devDependencies": { "aliased": "npm:@denotest/bin@^1.0.0" From a5ba198b9aa189da58b015a6e4585aaf33208a46 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Thu, 16 Jan 2025 12:03:25 -0800 Subject: [PATCH 32/38] fix(outdated): Use `latest` tag even when it's the same as the current version (#27699) Fixes https://github.com/denoland/deno/issues/27696. Just a `>` that should've been a `>=`. Also made sure to filter out deprecated versions. --- cli/tools/registry/pm/deps.rs | 15 +++++++++++++-- .../update/latest_not_pre_release/__test__.jsonc | 13 +++++++++++++ .../update/latest_not_pre_release/package.json | 5 +++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/specs/update/latest_not_pre_release/__test__.jsonc create mode 100644 tests/specs/update/latest_not_pre_release/package.json diff --git a/cli/tools/registry/pm/deps.rs b/cli/tools/registry/pm/deps.rs index 3d152490e8..621dd4693d 100644 --- a/cli/tools/registry/pm/deps.rs +++ b/cli/tools/registry/pm/deps.rs @@ -683,10 +683,21 @@ impl DepManager { .and_then(|info| { let latest_tag = info.dist_tags.get("latest")?; let lower_bound = &semver_compatible.as_ref()?.version; - if latest_tag > lower_bound { + if latest_tag >= lower_bound { Some(latest_tag.clone()) } else { - latest_version(Some(latest_tag), info.versions.keys()) + latest_version( + Some(latest_tag), + info.versions.iter().filter_map( + |(version, version_info)| { + if version_info.deprecated.is_none() { + Some(version) + } else { + None + } + }, + ), + ) } }) .map(|version| PackageNv { diff --git a/tests/specs/update/latest_not_pre_release/__test__.jsonc b/tests/specs/update/latest_not_pre_release/__test__.jsonc new file mode 100644 index 0000000000..2bfb7a3aa5 --- /dev/null +++ b/tests/specs/update/latest_not_pre_release/__test__.jsonc @@ -0,0 +1,13 @@ +{ + "tempDir": true, + "steps": [ + { + "args": "install", + "output": "[WILDCARD]" + }, + { + "args": "outdated", + "output": "" + } + ] +} diff --git a/tests/specs/update/latest_not_pre_release/package.json b/tests/specs/update/latest_not_pre_release/package.json new file mode 100644 index 0000000000..581e10cce7 --- /dev/null +++ b/tests/specs/update/latest_not_pre_release/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@denotest/has-pre-release": "1.0.0" + } +} From 94dc5b16f5c5ef28e4293d6edc0dd1b6338b41ec Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Thu, 16 Jan 2025 20:09:13 -0500 Subject: [PATCH 33/38] chore: forward v2.1.6 release commit to main (#27705) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the release commit being forwarded back to main for 2.1.6 Co-authored-by: bartlomieju Co-authored-by: Bartek Iwańczuk --- .github/workflows/ci.generate.ts | 2 +- .github/workflows/ci.yml | 8 ++-- Cargo.lock | 66 ++++++++++++++++---------------- Cargo.toml | 64 +++++++++++++++---------------- Releases.md | 26 +++++++++++++ bench_util/Cargo.toml | 2 +- cli/Cargo.toml | 2 +- cli/lib/Cargo.toml | 4 +- ext/broadcast_channel/Cargo.toml | 2 +- ext/cache/Cargo.toml | 2 +- ext/canvas/Cargo.toml | 2 +- ext/console/Cargo.toml | 2 +- ext/cron/Cargo.toml | 2 +- ext/crypto/Cargo.toml | 2 +- ext/fetch/Cargo.toml | 2 +- ext/ffi/Cargo.toml | 2 +- ext/fs/Cargo.toml | 2 +- ext/http/Cargo.toml | 2 +- ext/io/Cargo.toml | 2 +- ext/kv/Cargo.toml | 2 +- ext/napi/Cargo.toml | 2 +- ext/napi/sym/Cargo.toml | 2 +- ext/net/Cargo.toml | 2 +- ext/node/Cargo.toml | 2 +- ext/os/Cargo.toml | 2 +- ext/telemetry/Cargo.toml | 2 +- ext/tls/Cargo.toml | 2 +- ext/url/Cargo.toml | 2 +- ext/web/Cargo.toml | 2 +- ext/webgpu/Cargo.toml | 2 +- ext/webidl/Cargo.toml | 2 +- ext/websocket/Cargo.toml | 2 +- ext/webstorage/Cargo.toml | 2 +- resolvers/deno/Cargo.toml | 2 +- resolvers/node/Cargo.toml | 2 +- resolvers/npm_cache/Cargo.toml | 2 +- runtime/Cargo.toml | 2 +- runtime/permissions/Cargo.toml | 2 +- 38 files changed, 130 insertions(+), 104 deletions(-) diff --git a/.github/workflows/ci.generate.ts b/.github/workflows/ci.generate.ts index d0924f79ac..d302f92c98 100755 --- a/.github/workflows/ci.generate.ts +++ b/.github/workflows/ci.generate.ts @@ -5,7 +5,7 @@ import { stringify } from "jsr:@std/yaml@^0.221/stringify"; // Bump this number when you want to purge the cache. // Note: the tools/release/01_bump_crate_versions.ts script will update this version // automatically via regex, so ensure that this line maintains this format. -const cacheVersion = 35; +const cacheVersion = 36; const ubuntuX86Runner = "ubuntu-24.04"; const ubuntuX86XlRunner = "ubuntu-24.04-xl"; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75ded6fe53..501c23212a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -184,8 +184,8 @@ jobs: ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db - key: '35-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' - restore-keys: '35-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-' + key: '36-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles(''Cargo.lock'') }}' + restore-keys: '36-cargo-home-${{ matrix.os }}-${{ matrix.arch }}-' if: '!(matrix.skip)' - uses: dsherret/rust-toolchain-file@v1 if: '!(matrix.skip)' @@ -379,7 +379,7 @@ jobs: !./target/*/*.zip !./target/*/*.tar.gz key: never_saved - restore-keys: '35-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' + restore-keys: '36-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-' - name: Apply and update mtime cache if: '!(matrix.skip) && (!startsWith(github.ref, ''refs/tags/''))' uses: ./.github/mtime_cache @@ -689,7 +689,7 @@ jobs: !./target/*/gn_root !./target/*/*.zip !./target/*/*.tar.gz - key: '35-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' + key: '36-cargo-target-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.profile }}-${{ matrix.job }}-${{ github.sha }}' publish-canary: name: publish canary runs-on: ubuntu-24.04 diff --git a/Cargo.lock b/Cargo.lock index 7ec72aa3cd..3e571a2c2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1244,7 +1244,7 @@ dependencies = [ [[package]] name = "deno" -version = "2.1.5" +version = "2.1.6" dependencies = [ "anstream", "async-trait", @@ -1422,7 +1422,7 @@ dependencies = [ [[package]] name = "deno_bench_util" -version = "0.179.0" +version = "0.180.0" dependencies = [ "bencher", "deno_core", @@ -1431,7 +1431,7 @@ dependencies = [ [[package]] name = "deno_broadcast_channel" -version = "0.179.0" +version = "0.180.0" dependencies = [ "async-trait", "deno_core", @@ -1443,7 +1443,7 @@ dependencies = [ [[package]] name = "deno_cache" -version = "0.117.0" +version = "0.118.0" dependencies = [ "async-trait", "deno_core", @@ -1486,7 +1486,7 @@ dependencies = [ [[package]] name = "deno_canvas" -version = "0.54.0" +version = "0.55.0" dependencies = [ "deno_core", "deno_error", @@ -1525,7 +1525,7 @@ dependencies = [ [[package]] name = "deno_console" -version = "0.185.0" +version = "0.186.0" dependencies = [ "deno_core", ] @@ -1576,7 +1576,7 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" [[package]] name = "deno_cron" -version = "0.65.0" +version = "0.66.0" dependencies = [ "anyhow", "async-trait", @@ -1590,7 +1590,7 @@ dependencies = [ [[package]] name = "deno_crypto" -version = "0.199.0" +version = "0.200.0" dependencies = [ "aes", "aes-gcm", @@ -1683,7 +1683,7 @@ dependencies = [ [[package]] name = "deno_fetch" -version = "0.209.0" +version = "0.210.0" dependencies = [ "base64 0.21.7", "bytes", @@ -1720,7 +1720,7 @@ dependencies = [ [[package]] name = "deno_ffi" -version = "0.172.0" +version = "0.173.0" dependencies = [ "deno_core", "deno_error", @@ -1741,7 +1741,7 @@ dependencies = [ [[package]] name = "deno_fs" -version = "0.95.0" +version = "0.96.0" dependencies = [ "async-trait", "base32", @@ -1799,7 +1799,7 @@ dependencies = [ [[package]] name = "deno_http" -version = "0.183.0" +version = "0.184.0" dependencies = [ "async-compression", "async-trait", @@ -1839,7 +1839,7 @@ dependencies = [ [[package]] name = "deno_io" -version = "0.95.0" +version = "0.96.0" dependencies = [ "async-trait", "deno_core", @@ -1861,7 +1861,7 @@ dependencies = [ [[package]] name = "deno_kv" -version = "0.93.0" +version = "0.94.0" dependencies = [ "anyhow", "async-trait", @@ -1894,7 +1894,7 @@ dependencies = [ [[package]] name = "deno_lib" -version = "0.1.1" +version = "0.2.0" dependencies = [ "deno_cache_dir", "deno_error", @@ -1960,7 +1960,7 @@ dependencies = [ [[package]] name = "deno_napi" -version = "0.116.0" +version = "0.117.0" dependencies = [ "deno_core", "deno_error", @@ -1989,7 +1989,7 @@ dependencies = [ [[package]] name = "deno_net" -version = "0.177.0" +version = "0.178.0" dependencies = [ "deno_core", "deno_error", @@ -2008,7 +2008,7 @@ dependencies = [ [[package]] name = "deno_node" -version = "0.123.0" +version = "0.124.0" dependencies = [ "aead-gcm-stream", "aes", @@ -2121,7 +2121,7 @@ dependencies = [ [[package]] name = "deno_npm_cache" -version = "0.4.0" +version = "0.5.0" dependencies = [ "async-trait", "base64 0.21.7", @@ -2168,7 +2168,7 @@ dependencies = [ [[package]] name = "deno_os" -version = "0.1.0" +version = "0.3.0" dependencies = [ "deno_core", "deno_error", @@ -2220,7 +2220,7 @@ dependencies = [ [[package]] name = "deno_permissions" -version = "0.44.0" +version = "0.45.0" dependencies = [ "capacity_builder 0.5.0", "deno_core", @@ -2240,7 +2240,7 @@ dependencies = [ [[package]] name = "deno_resolver" -version = "0.16.0" +version = "0.17.0" dependencies = [ "anyhow", "async-trait", @@ -2266,7 +2266,7 @@ dependencies = [ [[package]] name = "deno_runtime" -version = "0.193.0" +version = "0.194.0" dependencies = [ "color-print", "deno_ast", @@ -2371,7 +2371,7 @@ dependencies = [ [[package]] name = "deno_telemetry" -version = "0.7.0" +version = "0.8.0" dependencies = [ "async-trait", "deno_core", @@ -2414,7 +2414,7 @@ dependencies = [ [[package]] name = "deno_tls" -version = "0.172.0" +version = "0.173.0" dependencies = [ "deno_core", "deno_error", @@ -2465,7 +2465,7 @@ dependencies = [ [[package]] name = "deno_url" -version = "0.185.0" +version = "0.186.0" dependencies = [ "deno_bench_util", "deno_console", @@ -2478,7 +2478,7 @@ dependencies = [ [[package]] name = "deno_web" -version = "0.216.0" +version = "0.217.0" dependencies = [ "async-trait", "base64-simd 0.8.0", @@ -2501,7 +2501,7 @@ dependencies = [ [[package]] name = "deno_webgpu" -version = "0.152.0" +version = "0.153.0" dependencies = [ "deno_core", "deno_error", @@ -2515,7 +2515,7 @@ dependencies = [ [[package]] name = "deno_webidl" -version = "0.185.0" +version = "0.186.0" dependencies = [ "deno_bench_util", "deno_core", @@ -2523,7 +2523,7 @@ dependencies = [ [[package]] name = "deno_websocket" -version = "0.190.0" +version = "0.191.0" dependencies = [ "bytes", "deno_core", @@ -2546,7 +2546,7 @@ dependencies = [ [[package]] name = "deno_webstorage" -version = "0.180.0" +version = "0.181.0" dependencies = [ "deno_core", "deno_error", @@ -5118,7 +5118,7 @@ dependencies = [ [[package]] name = "napi_sym" -version = "0.115.0" +version = "0.116.0" dependencies = [ "quote", "serde", @@ -5173,7 +5173,7 @@ dependencies = [ [[package]] name = "node_resolver" -version = "0.23.0" +version = "0.24.0" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 0c11ff9a69..46318bb828 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,17 +51,17 @@ repository = "https://github.com/denoland/deno" deno_ast = { version = "=0.44.0", features = ["transpiling"] } deno_core = { version = "0.330.0" } -deno_bench_util = { version = "0.179.0", path = "./bench_util" } +deno_bench_util = { version = "0.180.0", path = "./bench_util" } deno_config = { version = "=0.45.0", features = ["workspace", "sync"] } deno_lockfile = "=0.24.0" deno_media_type = { version = "0.2.3", features = ["module_specifier"] } deno_npm = "=0.27.2" deno_path_util = "=0.3.0" -deno_permissions = { version = "0.44.0", path = "./runtime/permissions" } -deno_runtime = { version = "0.193.0", path = "./runtime" } +deno_permissions = { version = "0.45.0", path = "./runtime/permissions" } +deno_runtime = { version = "0.194.0", path = "./runtime" } deno_semver = "=0.7.1" deno_terminal = "0.2.0" -napi_sym = { version = "0.115.0", path = "./ext/napi/sym" } +napi_sym = { version = "0.116.0", path = "./ext/napi/sym" } test_util = { package = "test_server", path = "./tests/util/server" } denokv_proto = "0.9.0" @@ -70,36 +70,36 @@ denokv_remote = "0.9.0" denokv_sqlite = { default-features = false, version = "0.9.0" } # exts -deno_broadcast_channel = { version = "0.179.0", path = "./ext/broadcast_channel" } -deno_cache = { version = "0.117.0", path = "./ext/cache" } -deno_canvas = { version = "0.54.0", path = "./ext/canvas" } -deno_console = { version = "0.185.0", path = "./ext/console" } -deno_cron = { version = "0.65.0", path = "./ext/cron" } -deno_crypto = { version = "0.199.0", path = "./ext/crypto" } -deno_fetch = { version = "0.209.0", path = "./ext/fetch" } -deno_ffi = { version = "0.172.0", path = "./ext/ffi" } -deno_fs = { version = "0.95.0", path = "./ext/fs" } -deno_http = { version = "0.183.0", path = "./ext/http" } -deno_io = { version = "0.95.0", path = "./ext/io" } -deno_kv = { version = "0.93.0", path = "./ext/kv" } -deno_napi = { version = "0.116.0", path = "./ext/napi" } -deno_net = { version = "0.177.0", path = "./ext/net" } -deno_node = { version = "0.123.0", path = "./ext/node" } -deno_os = { version = "0.1.0", path = "./ext/os" } -deno_telemetry = { version = "0.7.0", path = "./ext/telemetry" } -deno_tls = { version = "0.172.0", path = "./ext/tls" } -deno_url = { version = "0.185.0", path = "./ext/url" } -deno_web = { version = "0.216.0", path = "./ext/web" } -deno_webgpu = { version = "0.152.0", path = "./ext/webgpu" } -deno_webidl = { version = "0.185.0", path = "./ext/webidl" } -deno_websocket = { version = "0.190.0", path = "./ext/websocket" } -deno_webstorage = { version = "0.180.0", path = "./ext/webstorage" } +deno_broadcast_channel = { version = "0.180.0", path = "./ext/broadcast_channel" } +deno_cache = { version = "0.118.0", path = "./ext/cache" } +deno_canvas = { version = "0.55.0", path = "./ext/canvas" } +deno_console = { version = "0.186.0", path = "./ext/console" } +deno_cron = { version = "0.66.0", path = "./ext/cron" } +deno_crypto = { version = "0.200.0", path = "./ext/crypto" } +deno_fetch = { version = "0.210.0", path = "./ext/fetch" } +deno_ffi = { version = "0.173.0", path = "./ext/ffi" } +deno_fs = { version = "0.96.0", path = "./ext/fs" } +deno_http = { version = "0.184.0", path = "./ext/http" } +deno_io = { version = "0.96.0", path = "./ext/io" } +deno_kv = { version = "0.94.0", path = "./ext/kv" } +deno_napi = { version = "0.117.0", path = "./ext/napi" } +deno_net = { version = "0.178.0", path = "./ext/net" } +deno_node = { version = "0.124.0", path = "./ext/node" } +deno_os = { version = "0.3.0", path = "./ext/os" } +deno_telemetry = { version = "0.8.0", path = "./ext/telemetry" } +deno_tls = { version = "0.173.0", path = "./ext/tls" } +deno_url = { version = "0.186.0", path = "./ext/url" } +deno_web = { version = "0.217.0", path = "./ext/web" } +deno_webgpu = { version = "0.153.0", path = "./ext/webgpu" } +deno_webidl = { version = "0.186.0", path = "./ext/webidl" } +deno_websocket = { version = "0.191.0", path = "./ext/websocket" } +deno_webstorage = { version = "0.181.0", path = "./ext/webstorage" } # workspace libraries -deno_lib = { version = "=0.1.1", path = "./cli/lib" } -deno_npm_cache = { version = "0.4.0", path = "./resolvers/npm_cache" } -deno_resolver = { version = "0.16.0", path = "./resolvers/deno" } -node_resolver = { version = "0.23.0", path = "./resolvers/node" } +deno_lib = { version = "0.2.0", path = "./cli/lib" } +deno_npm_cache = { version = "0.5.0", path = "./resolvers/npm_cache" } +deno_resolver = { version = "0.17.0", path = "./resolvers/deno" } +node_resolver = { version = "0.24.0", path = "./resolvers/node" } aes = "=0.8.3" anyhow = "1.0.57" diff --git a/Releases.md b/Releases.md index 71cf524ca2..1fc6ebd1df 100644 --- a/Releases.md +++ b/Releases.md @@ -6,6 +6,32 @@ https://github.com/denoland/deno/releases We also have one-line install commands at: https://github.com/denoland/deno_install +### 2.1.6 / 2025.01.16 + +- fix(check/lsp): correctly resolve compilerOptions.types (#27686) +- fix(check/lsp): fix bugs with tsc type resolution, allow npm packages to + augment `ImportMeta` (#27690) +- fix(compile): store embedded fs case sensitivity (#27653) +- fix(compile/windows): better handling of deno_dir on different drive letter + than code (#27654) +- fix(ext/console): change Temporal color (#27684) +- fix(ext/node): add `writev` method to `FileHandle` (#27563) +- fix(ext/node): add chown method to FileHandle class (#27638) +- fix(ext/node): apply `@npmcli/agent` workaround to `npm-check-updates` + (#27639) +- fix(ext/node): fix playwright http client (#27662) +- fix(ext/node): show bare-node-builtin hint when using an import map (#27632) +- fix(ext/node): use primordials in `ext/node/polyfills/_fs_common.ts` (#27589) +- fix(lsp): handle pathless untitled URIs (#27637) +- fix(lsp/check): don't resolve unknown media types to a `.js` extension + (#27631) +- fix(node): Prevent node:child_process from always inheriting the parent + environment (#27343) (#27340) +- fix(node/fs): add utimes method to the FileHandle class (#27582) +- fix(outdated): Use `latest` tag even when it's the same as the current version + (#27699) +- fix(outdated): retain strict semver specifier when updating (#27701) + ### 2.1.5 / 2025.01.09 - feat(unstable): implement QUIC (#21942) diff --git a/bench_util/Cargo.toml b/bench_util/Cargo.toml index 30a88e931e..e2f1204eb2 100644 --- a/bench_util/Cargo.toml +++ b/bench_util/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_bench_util" -version = "0.179.0" +version = "0.180.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 4525a1bab4..d71047cc63 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno" -version = "2.1.5" +version = "2.1.6" authors.workspace = true default-run = "deno" edition.workspace = true diff --git a/cli/lib/Cargo.toml b/cli/lib/Cargo.toml index 6a74b22c2b..67caf6e944 100644 --- a/cli/lib/Cargo.toml +++ b/cli/lib/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_lib" -version = "0.1.1" +version = "0.2.0" authors.workspace = true edition.workspace = true license.workspace = true @@ -28,7 +28,7 @@ node_resolver = { workspace = true, features = ["sync"] } parking_lot.workspace = true ring.workspace = true serde = { workspace = true, features = ["derive"] } -sys_traits.workspace = true +sys_traits = { workspace = true, features = ["getrandom"] } thiserror.workspace = true tokio.workspace = true url.workspace = true diff --git a/ext/broadcast_channel/Cargo.toml b/ext/broadcast_channel/Cargo.toml index 0e1e0c3fbd..ff0034f0a8 100644 --- a/ext/broadcast_channel/Cargo.toml +++ b/ext/broadcast_channel/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_broadcast_channel" -version = "0.179.0" +version = "0.180.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/cache/Cargo.toml b/ext/cache/Cargo.toml index 18fbe23a23..4d15c8861b 100644 --- a/ext/cache/Cargo.toml +++ b/ext/cache/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_cache" -version = "0.117.0" +version = "0.118.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/canvas/Cargo.toml b/ext/canvas/Cargo.toml index e5c70b0054..0b89842f09 100644 --- a/ext/canvas/Cargo.toml +++ b/ext/canvas/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_canvas" -version = "0.54.0" +version = "0.55.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/console/Cargo.toml b/ext/console/Cargo.toml index 24cdb040a7..87ab697e36 100644 --- a/ext/console/Cargo.toml +++ b/ext/console/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_console" -version = "0.185.0" +version = "0.186.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/cron/Cargo.toml b/ext/cron/Cargo.toml index 7b41593841..7a5af4fc02 100644 --- a/ext/cron/Cargo.toml +++ b/ext/cron/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_cron" -version = "0.65.0" +version = "0.66.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml index c9876105e5..b1c0e8a24b 100644 --- a/ext/crypto/Cargo.toml +++ b/ext/crypto/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_crypto" -version = "0.199.0" +version = "0.200.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/fetch/Cargo.toml b/ext/fetch/Cargo.toml index a0d29291b0..0b98358104 100644 --- a/ext/fetch/Cargo.toml +++ b/ext/fetch/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_fetch" -version = "0.209.0" +version = "0.210.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/ffi/Cargo.toml b/ext/ffi/Cargo.toml index d71c04f9ff..f41ee2d644 100644 --- a/ext/ffi/Cargo.toml +++ b/ext/ffi/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_ffi" -version = "0.172.0" +version = "0.173.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index df9d140ac3..349c0a3be4 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_fs" -version = "0.95.0" +version = "0.96.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/http/Cargo.toml b/ext/http/Cargo.toml index 01198cb8e6..103af9a27b 100644 --- a/ext/http/Cargo.toml +++ b/ext/http/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_http" -version = "0.183.0" +version = "0.184.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/io/Cargo.toml b/ext/io/Cargo.toml index 0de9dfca84..35f138376d 100644 --- a/ext/io/Cargo.toml +++ b/ext/io/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_io" -version = "0.95.0" +version = "0.96.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/kv/Cargo.toml b/ext/kv/Cargo.toml index 726dccdfba..6f7fcf8f54 100644 --- a/ext/kv/Cargo.toml +++ b/ext/kv/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_kv" -version = "0.93.0" +version = "0.94.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/napi/Cargo.toml b/ext/napi/Cargo.toml index ff69d6a47e..916f0c4da5 100644 --- a/ext/napi/Cargo.toml +++ b/ext/napi/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_napi" -version = "0.116.0" +version = "0.117.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/napi/sym/Cargo.toml b/ext/napi/sym/Cargo.toml index f845b639ba..198e52474b 100644 --- a/ext/napi/sym/Cargo.toml +++ b/ext/napi/sym/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "napi_sym" -version = "0.115.0" +version = "0.116.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/net/Cargo.toml b/ext/net/Cargo.toml index ba02fe8708..348d8682ae 100644 --- a/ext/net/Cargo.toml +++ b/ext/net/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_net" -version = "0.177.0" +version = "0.178.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 6cd2b32866..e9226163d6 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_node" -version = "0.123.0" +version = "0.124.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/os/Cargo.toml b/ext/os/Cargo.toml index fb553d1532..bc809f3485 100644 --- a/ext/os/Cargo.toml +++ b/ext/os/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_os" -version = "0.1.0" +version = "0.3.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/telemetry/Cargo.toml b/ext/telemetry/Cargo.toml index a83a08c3fe..4d00b82909 100644 --- a/ext/telemetry/Cargo.toml +++ b/ext/telemetry/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_telemetry" -version = "0.7.0" +version = "0.8.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/tls/Cargo.toml b/ext/tls/Cargo.toml index 39b3d17c86..8a9fdb00c0 100644 --- a/ext/tls/Cargo.toml +++ b/ext/tls/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_tls" -version = "0.172.0" +version = "0.173.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/url/Cargo.toml b/ext/url/Cargo.toml index 2078571e39..b4500aad3c 100644 --- a/ext/url/Cargo.toml +++ b/ext/url/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_url" -version = "0.185.0" +version = "0.186.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/web/Cargo.toml b/ext/web/Cargo.toml index 065f1a12b1..dda1e98b4b 100644 --- a/ext/web/Cargo.toml +++ b/ext/web/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_web" -version = "0.216.0" +version = "0.217.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/webgpu/Cargo.toml b/ext/webgpu/Cargo.toml index 369fdb02e6..7e8973cadd 100644 --- a/ext/webgpu/Cargo.toml +++ b/ext/webgpu/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_webgpu" -version = "0.152.0" +version = "0.153.0" authors = ["the Deno authors"] edition.workspace = true license = "MIT" diff --git a/ext/webidl/Cargo.toml b/ext/webidl/Cargo.toml index adb072ff45..07ceb492b5 100644 --- a/ext/webidl/Cargo.toml +++ b/ext/webidl/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_webidl" -version = "0.185.0" +version = "0.186.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/websocket/Cargo.toml b/ext/websocket/Cargo.toml index a94da90484..39b400a7ac 100644 --- a/ext/websocket/Cargo.toml +++ b/ext/websocket/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_websocket" -version = "0.190.0" +version = "0.191.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/ext/webstorage/Cargo.toml b/ext/webstorage/Cargo.toml index 8a900f662b..04e6381b00 100644 --- a/ext/webstorage/Cargo.toml +++ b/ext/webstorage/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_webstorage" -version = "0.180.0" +version = "0.181.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/resolvers/deno/Cargo.toml b/resolvers/deno/Cargo.toml index 534a07ccf2..bf4d68fa91 100644 --- a/resolvers/deno/Cargo.toml +++ b/resolvers/deno/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_resolver" -version = "0.16.0" +version = "0.17.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/resolvers/node/Cargo.toml b/resolvers/node/Cargo.toml index 1c2a342a9f..ee3a783860 100644 --- a/resolvers/node/Cargo.toml +++ b/resolvers/node/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "node_resolver" -version = "0.23.0" +version = "0.24.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/resolvers/npm_cache/Cargo.toml b/resolvers/npm_cache/Cargo.toml index d73cee9cd6..4c6cca2416 100644 --- a/resolvers/npm_cache/Cargo.toml +++ b/resolvers/npm_cache/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_npm_cache" -version = "0.4.0" +version = "0.5.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 808f79ab7b..b56b4a2b50 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_runtime" -version = "0.193.0" +version = "0.194.0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/runtime/permissions/Cargo.toml b/runtime/permissions/Cargo.toml index 52501ee197..bdca6b379c 100644 --- a/runtime/permissions/Cargo.toml +++ b/runtime/permissions/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_permissions" -version = "0.44.0" +version = "0.45.0" authors.workspace = true edition.workspace = true license.workspace = true From 339bc44c58635f5a4b8b7410ae9fd256c13fe134 Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Fri, 17 Jan 2025 12:30:00 +0900 Subject: [PATCH 34/38] fix(ext/node): propagate socket error to client request object (#27678) Co-authored-by: Satya Rohith --- ext/node/polyfills/http.ts | 15 +++++++++++++-- tests/unit_node/http_test.ts | 11 +++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts index f698ca01b3..ff85a61531 100644 --- a/ext/node/polyfills/http.ts +++ b/ext/node/polyfills/http.ts @@ -455,8 +455,13 @@ class ClientRequest extends OutgoingMessage { (async () => { try { const parsedUrl = new URL(url); - let baseConnRid = - this.socket._handle[kStreamBaseField][internalRidSymbol]; + const handle = this.socket._handle; + if (!handle) { + // Using non-standard socket. There's no way to handle this type of socket. + // This should be only happening in artificial test cases + return; + } + let baseConnRid = handle[kStreamBaseField][internalRidSymbol]; if (this._encrypted) { [baseConnRid] = op_tls_start({ rid: baseConnRid, @@ -637,6 +642,12 @@ class ClientRequest extends OutgoingMessage { }; this.socket = socket; this.emit("socket", socket); + socket.once("error", (err) => { + // This callback loosely follow `socketErrorListener` in Node.js + // https://github.com/nodejs/node/blob/f16cd10946ca9ad272f42b94f00cf960571c9181/lib/_http_client.js#L509 + emitErrorEvent(this, err); + socket.destroy(err); + }); if (socket.readyState === "opening") { socket.on("connect", onConnect); } else { diff --git a/tests/unit_node/http_test.ts b/tests/unit_node/http_test.ts index 7478546617..b4f0d260aa 100644 --- a/tests/unit_node/http_test.ts +++ b/tests/unit_node/http_test.ts @@ -1881,3 +1881,14 @@ Deno.test("[node/http] decompress brotli response", { "localhost:3000", ], ["user-agent", "Deno/2.1.1"]]); }); + +Deno.test("[node/http] an error with DNS propagates to request object", async () => { + const { resolve, promise } = Promise.withResolvers(); + const req = http.request("http://invalid-hostname.test", () => {}); + req.on("error", (err) => { + assertEquals(err.name, "Error"); + assertEquals(err.message, "getaddrinfo ENOTFOUND invalid-hostname.test"); + resolve(); + }); + await promise; +}); From 0050857f511e886e4af0a811fef16a43eaeb6e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 17 Jan 2025 12:30:14 +0000 Subject: [PATCH 35/38] refactor: add 'deno_process' crate (#27680) Untangled the whole `runtime/ops/process.rs` from `ext/node/` and moved to a separate `ext/process` crate. --- Cargo.lock | 30 +- Cargo.toml | 1 + cli/args/mod.rs | 2 +- cli/lib/worker.rs | 2 +- cli/npm/byonm.rs | 2 +- cli/npm/installer/common/lifecycle_scripts.rs | 4 +- cli/npm/managed.rs | 2 +- cli/npm/mod.rs | 2 +- ext/node/Cargo.toml | 2 +- ext/node/lib.rs | 2 - ext/node/ops/ipc.rs | 544 +---------------- ext/node/polyfills/child_process.ts | 2 +- ext/node/polyfills/internal/child_process.ts | 2 +- {runtime/js => ext/process}/40_process.js | 0 ext/process/Cargo.toml | 41 ++ ext/process/README.md | 3 + ext/process/ipc.rs | 558 ++++++++++++++++++ runtime/ops/process.rs => ext/process/lib.rs | 25 +- runtime/Cargo.toml | 2 + runtime/js/90_deno_ns.js | 2 +- runtime/lib.rs | 3 +- runtime/ops/mod.rs | 1 - runtime/ops/tty.rs | 5 +- runtime/shared.rs | 1 - runtime/snapshot.rs | 2 +- runtime/web_worker.rs | 8 +- runtime/worker.rs | 8 +- tools/core_import_map.json | 2 +- 28 files changed, 676 insertions(+), 582 deletions(-) rename {runtime/js => ext/process}/40_process.js (100%) create mode 100644 ext/process/Cargo.toml create mode 100644 ext/process/README.md create mode 100644 ext/process/ipc.rs rename runtime/ops/process.rs => ext/process/lib.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 3e571a2c2a..392ff5ef46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2031,6 +2031,7 @@ dependencies = [ "deno_package_json", "deno_path_util", "deno_permissions", + "deno_process", "deno_whoami", "der", "digest", @@ -2068,7 +2069,6 @@ dependencies = [ "p384", "path-clean", "pbkdf2", - "pin-project-lite", "pkcs8", "rand", "regex", @@ -2238,6 +2238,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "deno_process" +version = "0.1.0" +dependencies = [ + "deno_core", + "deno_error", + "deno_fs", + "deno_io", + "deno_os", + "deno_path_util", + "deno_permissions", + "libc", + "log", + "memchr", + "nix", + "pin-project-lite", + "rand", + "serde", + "simd-json", + "tempfile", + "thiserror 2.0.3", + "tokio", + "which", + "winapi", + "windows-sys 0.59.0", +] + [[package]] name = "deno_resolver" version = "0.17.0" @@ -2290,6 +2317,7 @@ dependencies = [ "deno_os", "deno_path_util", "deno_permissions", + "deno_process", "deno_resolver", "deno_telemetry", "deno_terminal 0.2.0", diff --git a/Cargo.toml b/Cargo.toml index 46318bb828..42c2970e05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,6 +86,7 @@ deno_napi = { version = "0.117.0", path = "./ext/napi" } deno_net = { version = "0.178.0", path = "./ext/net" } deno_node = { version = "0.124.0", path = "./ext/node" } deno_os = { version = "0.3.0", path = "./ext/os" } +deno_process = { version = "0.1.0", path = "./ext/process" } deno_telemetry = { version = "0.8.0", path = "./ext/telemetry" } deno_tls = { version = "0.173.0", path = "./ext/tls" } deno_url = { version = "0.186.0", path = "./ext/url" } diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 29b493046f..f77eedc594 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -719,7 +719,7 @@ pub enum NpmProcessStateKind { } static NPM_PROCESS_STATE: Lazy> = Lazy::new(|| { - use deno_runtime::ops::process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME; + use deno_runtime::deno_process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME; let fd = std::env::var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME).ok()?; std::env::remove_var(NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME); let fd = fd.parse::().ok()?; diff --git a/cli/lib/worker.rs b/cli/lib/worker.rs index 7c9071d0ba..180d3eef8c 100644 --- a/cli/lib/worker.rs +++ b/cli/lib/worker.rs @@ -25,12 +25,12 @@ use deno_runtime::deno_node::NodeExtInitServices; use deno_runtime::deno_node::NodeRequireLoader; use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_permissions::PermissionsContainer; +use deno_runtime::deno_process::NpmProcessStateProviderRc; use deno_runtime::deno_telemetry::OtelConfig; use deno_runtime::deno_tls::RootCertStoreProvider; use deno_runtime::deno_web::BlobStore; use deno_runtime::fmt_errors::format_js_error; use deno_runtime::inspector_server::InspectorServer; -use deno_runtime::ops::process::NpmProcessStateProviderRc; use deno_runtime::ops::worker_host::CreateWebWorkerCb; use deno_runtime::web_worker::WebWorker; use deno_runtime::web_worker::WebWorkerOptions; diff --git a/cli/npm/byonm.rs b/cli/npm/byonm.rs index 8dc498bb04..d52b222074 100644 --- a/cli/npm/byonm.rs +++ b/cli/npm/byonm.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use deno_core::serde_json; use deno_resolver::npm::ByonmNpmResolver; use deno_resolver::npm::ByonmNpmResolverCreateOptions; -use deno_runtime::ops::process::NpmProcessStateProvider; +use deno_runtime::deno_process::NpmProcessStateProvider; use crate::args::NpmProcessState; use crate::args::NpmProcessStateKind; diff --git a/cli/npm/installer/common/lifecycle_scripts.rs b/cli/npm/installer/common/lifecycle_scripts.rs index a0d821cdfc..3238b8d023 100644 --- a/cli/npm/installer/common/lifecycle_scripts.rs +++ b/cli/npm/installer/common/lifecycle_scripts.rs @@ -240,7 +240,7 @@ impl<'a> LifecycleScripts<'a> { // However, if we concurrently run scripts in the future we will // have to have multiple temp files. let temp_file_fd = - deno_runtime::ops::process::npm_process_state_tempfile( + deno_runtime::deno_process::npm_process_state_tempfile( process_state.as_bytes(), ) .map_err(LifecycleScriptsError::CreateNpmProcessState)?; @@ -248,7 +248,7 @@ impl<'a> LifecycleScripts<'a> { let _temp_file = unsafe { std::fs::File::from_raw_io_handle(temp_file_fd) }; // make sure the file gets closed env_vars.insert( - deno_runtime::ops::process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME + deno_runtime::deno_process::NPM_RESOLUTION_STATE_FD_ENV_VAR_NAME .to_string(), (temp_file_fd as usize).to_string(), ); diff --git a/cli/npm/managed.rs b/cli/npm/managed.rs index 4122c881f1..049e3541db 100644 --- a/cli/npm/managed.rs +++ b/cli/npm/managed.rs @@ -14,7 +14,7 @@ use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_resolver::npm::managed::ManagedNpmResolverCreateOptions; use deno_resolver::npm::managed::NpmResolutionCell; use deno_resolver::npm::ManagedNpmResolverRc; -use deno_runtime::ops::process::NpmProcessStateProvider; +use deno_runtime::deno_process::NpmProcessStateProvider; use thiserror::Error; use super::CliNpmRegistryInfoProvider; diff --git a/cli/npm/mod.rs b/cli/npm/mod.rs index fc0916cc18..a2cbd81d5b 100644 --- a/cli/npm/mod.rs +++ b/cli/npm/mod.rs @@ -12,7 +12,7 @@ use deno_core::url::Url; use deno_error::JsErrorBox; use deno_npm::npm_rc::ResolvedNpmRc; use deno_npm::registry::NpmPackageInfo; -use deno_runtime::ops::process::NpmProcessStateProviderRc; +use deno_runtime::deno_process::NpmProcessStateProviderRc; use deno_semver::package::PackageNv; use deno_semver::package::PackageReq; use http::HeaderName; diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index e9226163d6..d4152ce58c 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -38,6 +38,7 @@ deno_net.workspace = true deno_package_json.workspace = true deno_path_util.workspace = true deno_permissions.workspace = true +deno_process.workspace = true deno_whoami = "0.1.0" der = { version = "0.7.9", features = ["derive"] } digest = { version = "0.10.5", features = ["core-api", "std"] } @@ -75,7 +76,6 @@ p256.workspace = true p384.workspace = true path-clean = "=0.1.0" pbkdf2 = "0.12.1" -pin-project-lite = "0.2.13" pkcs8 = { version = "0.10.2", features = ["std", "pkcs5", "encryption"] } rand.workspace = true regex.workspace = true diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 325cec6f5b..702a01e447 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -31,8 +31,6 @@ pub use deno_package_json::PackageJson; use deno_permissions::PermissionCheckError; pub use node_resolver::PathClean; pub use ops::ipc::ChildPipeFd; -pub use ops::ipc::IpcJsonStreamResource; -pub use ops::ipc::IpcRefTracker; use ops::vm; pub use ops::vm::create_v8_context; pub use ops::vm::init_global_template; diff --git a/ext/node/ops/ipc.rs b/ext/node/ops/ipc.rs index cf5e1e97ef..0213295c5a 100644 --- a/ext/node/ops/ipc.rs +++ b/ext/node/ops/ipc.rs @@ -8,38 +8,24 @@ mod impl_ { use std::cell::RefCell; use std::future::Future; use std::io; - use std::mem; - use std::pin::Pin; use std::rc::Rc; - use std::sync::atomic::AtomicBool; - use std::sync::atomic::AtomicUsize; - use std::task::ready; - use std::task::Context; - use std::task::Poll; use deno_core::op2; use deno_core::serde; use deno_core::serde::Serializer; use deno_core::serde_json; use deno_core::v8; - use deno_core::AsyncRefCell; use deno_core::CancelFuture; - use deno_core::CancelHandle; - use deno_core::ExternalOpsTracker; use deno_core::OpState; use deno_core::RcRef; use deno_core::ResourceId; use deno_core::ToV8; use deno_error::JsErrorBox; - use deno_io::BiPipe; - use deno_io::BiPipeRead; - use deno_io::BiPipeWrite; - use memchr::memchr; - use pin_project_lite::pin_project; + use deno_process::ipc::IpcJsonStreamError; + pub use deno_process::ipc::IpcJsonStreamResource; + pub use deno_process::ipc::IpcRefTracker; + pub use deno_process::ipc::INITIAL_CAPACITY; use serde::Serialize; - use tokio::io::AsyncRead; - use tokio::io::AsyncWriteExt; - use tokio::io::ReadBuf; /// Wrapper around v8 value that implements Serialize. struct SerializeWrapper<'a, 'b>( @@ -289,534 +275,12 @@ mod impl_ { stream.ref_tracker.unref(); } - /// Tracks whether the IPC resources is currently - /// refed, and allows refing/unrefing it. - pub struct IpcRefTracker { - refed: AtomicBool, - tracker: OpsTracker, - } - - /// A little wrapper so we don't have to get an - /// `ExternalOpsTracker` for tests. When we aren't - /// cfg(test), this will get optimized out. - enum OpsTracker { - External(ExternalOpsTracker), - #[cfg(test)] - Test, - } - - impl OpsTracker { - fn ref_(&self) { - match self { - Self::External(tracker) => tracker.ref_op(), - #[cfg(test)] - Self::Test => {} - } - } - - fn unref(&self) { - match self { - Self::External(tracker) => tracker.unref_op(), - #[cfg(test)] - Self::Test => {} - } - } - } - - impl IpcRefTracker { - pub fn new(tracker: ExternalOpsTracker) -> Self { - Self { - refed: AtomicBool::new(false), - tracker: OpsTracker::External(tracker), - } - } - - #[cfg(test)] - fn new_test() -> Self { - Self { - refed: AtomicBool::new(false), - tracker: OpsTracker::Test, - } - } - - fn ref_(&self) { - if !self.refed.swap(true, std::sync::atomic::Ordering::AcqRel) { - self.tracker.ref_(); - } - } - - fn unref(&self) { - if self.refed.swap(false, std::sync::atomic::Ordering::AcqRel) { - self.tracker.unref(); - } - } - } - - pub struct IpcJsonStreamResource { - read_half: AsyncRefCell, - write_half: AsyncRefCell, - cancel: Rc, - queued_bytes: AtomicUsize, - ref_tracker: IpcRefTracker, - } - - impl deno_core::Resource for IpcJsonStreamResource { - fn close(self: Rc) { - self.cancel.cancel(); - } - } - - impl IpcJsonStreamResource { - pub fn new( - stream: i64, - ref_tracker: IpcRefTracker, - ) -> Result { - let (read_half, write_half) = BiPipe::from_raw(stream as _)?.split(); - Ok(Self { - read_half: AsyncRefCell::new(IpcJsonStream::new(read_half)), - write_half: AsyncRefCell::new(write_half), - cancel: Default::default(), - queued_bytes: Default::default(), - ref_tracker, - }) - } - - #[cfg(all(unix, test))] - fn from_stream( - stream: tokio::net::UnixStream, - ref_tracker: IpcRefTracker, - ) -> Self { - let (read_half, write_half) = stream.into_split(); - Self { - read_half: AsyncRefCell::new(IpcJsonStream::new(read_half.into())), - write_half: AsyncRefCell::new(write_half.into()), - cancel: Default::default(), - queued_bytes: Default::default(), - ref_tracker, - } - } - - #[cfg(all(windows, test))] - fn from_stream( - pipe: tokio::net::windows::named_pipe::NamedPipeClient, - ref_tracker: IpcRefTracker, - ) -> Self { - let (read_half, write_half) = tokio::io::split(pipe); - Self { - read_half: AsyncRefCell::new(IpcJsonStream::new(read_half.into())), - write_half: AsyncRefCell::new(write_half.into()), - cancel: Default::default(), - queued_bytes: Default::default(), - ref_tracker, - } - } - - /// writes _newline terminated_ JSON message to the IPC pipe. - async fn write_msg_bytes( - self: Rc, - msg: &[u8], - ) -> Result<(), io::Error> { - let mut write_half = - RcRef::map(self, |r| &r.write_half).borrow_mut().await; - write_half.write_all(msg).await?; - Ok(()) - } - } - - // Initial capacity of the buffered reader and the JSON backing buffer. - // - // This is a tradeoff between memory usage and performance on large messages. - // - // 64kb has been chosen after benchmarking 64 to 66536 << 6 - 1 bytes per message. - const INITIAL_CAPACITY: usize = 1024 * 64; - - /// A buffer for reading from the IPC pipe. - /// Similar to the internal buffer of `tokio::io::BufReader`. - /// - /// This exists to provide buffered reading while granting mutable access - /// to the internal buffer (which isn't exposed through `tokio::io::BufReader` - /// or the `AsyncBufRead` trait). `simd_json` requires mutable access to an input - /// buffer for parsing, so this allows us to use the read buffer directly as the - /// input buffer without a copy (provided the message fits). - struct ReadBuffer { - buffer: Box<[u8]>, - pos: usize, - cap: usize, - } - - impl ReadBuffer { - fn new() -> Self { - Self { - buffer: vec![0; INITIAL_CAPACITY].into_boxed_slice(), - pos: 0, - cap: 0, - } - } - - fn get_mut(&mut self) -> &mut [u8] { - &mut self.buffer - } - - fn available_mut(&mut self) -> &mut [u8] { - &mut self.buffer[self.pos..self.cap] - } - - fn consume(&mut self, n: usize) { - self.pos = std::cmp::min(self.pos + n, self.cap); - } - - fn needs_fill(&self) -> bool { - self.pos >= self.cap - } - } - - #[derive(Debug, thiserror::Error, deno_error::JsError)] - pub enum IpcJsonStreamError { - #[class(inherit)] - #[error("{0}")] - Io(#[source] std::io::Error), - #[class(generic)] - #[error("{0}")] - SimdJson(#[source] simd_json::Error), - } - - // JSON serialization stream over IPC pipe. - // - // `\n` is used as a delimiter between messages. - struct IpcJsonStream { - pipe: BiPipeRead, - buffer: Vec, - read_buffer: ReadBuffer, - } - - impl IpcJsonStream { - fn new(pipe: BiPipeRead) -> Self { - Self { - pipe, - buffer: Vec::with_capacity(INITIAL_CAPACITY), - read_buffer: ReadBuffer::new(), - } - } - - async fn read_msg( - &mut self, - ) -> Result, IpcJsonStreamError> { - let mut json = None; - let nread = read_msg_inner( - &mut self.pipe, - &mut self.buffer, - &mut json, - &mut self.read_buffer, - ) - .await - .map_err(IpcJsonStreamError::Io)?; - if nread == 0 { - // EOF. - return Ok(None); - } - - let json = match json { - Some(v) => v, - None => { - // Took more than a single read and some buffering. - simd_json::from_slice(&mut self.buffer[..nread]) - .map_err(IpcJsonStreamError::SimdJson)? - } - }; - - // Safety: Same as `Vec::clear` but without the `drop_in_place` for - // each element (nop for u8). Capacity remains the same. - unsafe { - self.buffer.set_len(0); - } - - Ok(Some(json)) - } - } - - pin_project! { - #[must_use = "futures do nothing unless you `.await` or poll them"] - struct ReadMsgInner<'a, R: ?Sized> { - reader: &'a mut R, - buf: &'a mut Vec, - json: &'a mut Option, - // The number of bytes appended to buf. This can be less than buf.len() if - // the buffer was not empty when the operation was started. - read: usize, - read_buffer: &'a mut ReadBuffer, - } - } - - fn read_msg_inner<'a, R>( - reader: &'a mut R, - buf: &'a mut Vec, - json: &'a mut Option, - read_buffer: &'a mut ReadBuffer, - ) -> ReadMsgInner<'a, R> - where - R: AsyncRead + ?Sized + Unpin, - { - ReadMsgInner { - reader, - buf, - json, - read: 0, - read_buffer, - } - } - - fn read_msg_internal( - mut reader: Pin<&mut R>, - cx: &mut Context<'_>, - buf: &mut Vec, - read_buffer: &mut ReadBuffer, - json: &mut Option, - read: &mut usize, - ) -> Poll> { - loop { - let (done, used) = { - // effectively a tiny `poll_fill_buf`, but allows us to get a mutable reference to the buffer. - if read_buffer.needs_fill() { - let mut read_buf = ReadBuf::new(read_buffer.get_mut()); - ready!(reader.as_mut().poll_read(cx, &mut read_buf))?; - read_buffer.cap = read_buf.filled().len(); - read_buffer.pos = 0; - } - let available = read_buffer.available_mut(); - if let Some(i) = memchr(b'\n', available) { - if *read == 0 { - // Fast path: parse and put into the json slot directly. - json.replace( - simd_json::from_slice(&mut available[..i + 1]) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?, - ); - } else { - // This is not the first read, so we have to copy the data - // to make it contiguous. - buf.extend_from_slice(&available[..=i]); - } - (true, i + 1) - } else { - buf.extend_from_slice(available); - (false, available.len()) - } - }; - - read_buffer.consume(used); - *read += used; - if done || used == 0 { - return Poll::Ready(Ok(mem::replace(read, 0))); - } - } - } - - impl Future for ReadMsgInner<'_, R> { - type Output = io::Result; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let me = self.project(); - read_msg_internal( - Pin::new(*me.reader), - cx, - me.buf, - me.read_buffer, - me.json, - me.read, - ) - } - } - #[cfg(test)] mod tests { - use std::rc::Rc; - - use deno_core::serde_json::json; use deno_core::v8; use deno_core::JsRuntime; - use deno_core::RcRef; use deno_core::RuntimeOptions; - use super::IpcJsonStreamResource; - - #[allow(clippy::unused_async)] - #[cfg(unix)] - pub async fn pair() -> (Rc, tokio::net::UnixStream) { - let (a, b) = tokio::net::UnixStream::pair().unwrap(); - - /* Similar to how ops would use the resource */ - let a = Rc::new(IpcJsonStreamResource::from_stream( - a, - super::IpcRefTracker::new_test(), - )); - (a, b) - } - - #[cfg(windows)] - pub async fn pair() -> ( - Rc, - tokio::net::windows::named_pipe::NamedPipeServer, - ) { - use tokio::net::windows::named_pipe::ClientOptions; - use tokio::net::windows::named_pipe::ServerOptions; - - let name = - format!(r"\\.\pipe\deno-named-pipe-test-{}", rand::random::()); - - let server = ServerOptions::new().create(name.clone()).unwrap(); - let client = ClientOptions::new().open(name).unwrap(); - - server.connect().await.unwrap(); - /* Similar to how ops would use the resource */ - let client = Rc::new(IpcJsonStreamResource::from_stream( - client, - super::IpcRefTracker::new_test(), - )); - (client, server) - } - - #[allow(clippy::print_stdout)] - #[tokio::test] - async fn bench_ipc() -> Result<(), Box> { - // A simple round trip benchmark for quick dev feedback. - // - // Only ran when the env var is set. - if std::env::var_os("BENCH_IPC_DENO").is_none() { - return Ok(()); - } - - let (ipc, mut fd2) = pair().await; - let child = tokio::spawn(async move { - use tokio::io::AsyncWriteExt; - - let size = 1024 * 1024; - - let stri = "x".repeat(size); - let data = format!("\"{}\"\n", stri); - for _ in 0..100 { - fd2.write_all(data.as_bytes()).await?; - } - Ok::<_, std::io::Error>(()) - }); - - let start = std::time::Instant::now(); - let mut bytes = 0; - - let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; - loop { - let Some(msgs) = ipc.read_msg().await? else { - break; - }; - bytes += msgs.as_str().unwrap().len(); - if start.elapsed().as_secs() > 5 { - break; - } - } - let elapsed = start.elapsed(); - let mb = bytes as f64 / 1024.0 / 1024.0; - println!("{} mb/s", mb / elapsed.as_secs_f64()); - - child.await??; - - Ok(()) - } - - #[tokio::test] - async fn unix_ipc_json() -> Result<(), Box> { - let (ipc, mut fd2) = pair().await; - let child = tokio::spawn(async move { - use tokio::io::AsyncReadExt; - use tokio::io::AsyncWriteExt; - - const EXPECTED: &[u8] = b"\"hello\"\n"; - let mut buf = [0u8; EXPECTED.len()]; - let n = fd2.read_exact(&mut buf).await?; - assert_eq!(&buf[..n], EXPECTED); - fd2.write_all(b"\"world\"\n").await?; - - Ok::<_, std::io::Error>(()) - }); - - ipc - .clone() - .write_msg_bytes(&json_to_bytes(json!("hello"))) - .await?; - - let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; - let msgs = ipc.read_msg().await?.unwrap(); - assert_eq!(msgs, json!("world")); - - child.await??; - - Ok(()) - } - - fn json_to_bytes(v: deno_core::serde_json::Value) -> Vec { - let mut buf = deno_core::serde_json::to_vec(&v).unwrap(); - buf.push(b'\n'); - buf - } - - #[tokio::test] - async fn unix_ipc_json_multi() -> Result<(), Box> { - let (ipc, mut fd2) = pair().await; - let child = tokio::spawn(async move { - use tokio::io::AsyncReadExt; - use tokio::io::AsyncWriteExt; - - const EXPECTED: &[u8] = b"\"hello\"\n\"world\"\n"; - let mut buf = [0u8; EXPECTED.len()]; - let n = fd2.read_exact(&mut buf).await?; - assert_eq!(&buf[..n], EXPECTED); - fd2.write_all(b"\"foo\"\n\"bar\"\n").await?; - Ok::<_, std::io::Error>(()) - }); - - ipc - .clone() - .write_msg_bytes(&json_to_bytes(json!("hello"))) - .await?; - ipc - .clone() - .write_msg_bytes(&json_to_bytes(json!("world"))) - .await?; - - let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; - let msgs = ipc.read_msg().await?.unwrap(); - assert_eq!(msgs, json!("foo")); - - child.await??; - - Ok(()) - } - - #[tokio::test] - async fn unix_ipc_json_invalid() -> Result<(), Box> { - let (ipc, mut fd2) = pair().await; - let child = tokio::spawn(async move { - tokio::io::AsyncWriteExt::write_all(&mut fd2, b"\n\n").await?; - Ok::<_, std::io::Error>(()) - }); - - let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; - let _err = ipc.read_msg().await.unwrap_err(); - - child.await??; - - Ok(()) - } - - #[test] - fn memchr() { - let str = b"hello world"; - assert_eq!(super::memchr(b'h', str), Some(0)); - assert_eq!(super::memchr(b'w', str), Some(6)); - assert_eq!(super::memchr(b'd', str), Some(10)); - assert_eq!(super::memchr(b'x', str), None); - - let empty = b""; - assert_eq!(super::memchr(b'\n', empty), None); - } - fn wrap_expr(s: &str) -> String { format!("(function () {{ return {s}; }})()") } diff --git a/ext/node/polyfills/child_process.ts b/ext/node/polyfills/child_process.ts index 184b29bd2b..2bd8614275 100644 --- a/ext/node/polyfills/child_process.ts +++ b/ext/node/polyfills/child_process.ts @@ -53,7 +53,7 @@ import { convertToValidSignal, kEmptyObject, } from "ext:deno_node/internal/util.mjs"; -import { kNeedsNpmProcessState } from "ext:runtime/40_process.js"; +import { kNeedsNpmProcessState } from "ext:deno_process/40_process.js"; const MAX_BUFFER = 1024 * 1024; diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index 569ee7d328..9c9e084787 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -61,7 +61,7 @@ import { kExtraStdio, kIpc, kNeedsNpmProcessState, -} from "ext:runtime/40_process.js"; +} from "ext:deno_process/40_process.js"; export function mapValues( record: Readonly>, diff --git a/runtime/js/40_process.js b/ext/process/40_process.js similarity index 100% rename from runtime/js/40_process.js rename to ext/process/40_process.js diff --git a/ext/process/Cargo.toml b/ext/process/Cargo.toml new file mode 100644 index 0000000000..26f7a41a5e --- /dev/null +++ b/ext/process/Cargo.toml @@ -0,0 +1,41 @@ +# Copyright 2018-2025 the Deno authors. MIT license. + +[package] +name = "deno_process" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +repository.workspace = true +description = "Subprocess APIs for Deno" + +[lib] +path = "lib.rs" + +[dependencies] +deno_core.workspace = true +deno_error.workspace = true +deno_fs.workspace = true +deno_io.workspace = true +deno_os.workspace = true +deno_path_util.workspace = true +deno_permissions.workspace = true +libc.workspace = true +log.workspace = true +memchr = "2.7.4" +pin-project-lite = "0.2.13" +rand.workspace = true +serde.workspace = true +simd-json = "0.14.0" +tempfile.workspace = true +thiserror.workspace = true +tokio.workspace = true +which.workspace = true + +[target.'cfg(unix)'.dependencies] +nix = { workspace = true, features = ["signal", "process"] } + +[target.'cfg(windows)'.dependencies] +winapi = { workspace = true, features = [] } +windows-sys.workspace = true diff --git a/ext/process/README.md b/ext/process/README.md new file mode 100644 index 0000000000..ac39ab83d6 --- /dev/null +++ b/ext/process/README.md @@ -0,0 +1,3 @@ +# deno_process + +This crate implements subprocess APIs for Deno diff --git a/ext/process/ipc.rs b/ext/process/ipc.rs new file mode 100644 index 0000000000..3728943457 --- /dev/null +++ b/ext/process/ipc.rs @@ -0,0 +1,558 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +#![allow(unused)] + +use std::cell::RefCell; +use std::future::Future; +use std::io; +use std::mem; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::atomic::AtomicBool; +use std::sync::atomic::AtomicUsize; +use std::task::ready; +use std::task::Context; +use std::task::Poll; + +use deno_core::serde; +use deno_core::serde_json; +use deno_core::AsyncRefCell; +use deno_core::CancelHandle; +use deno_core::ExternalOpsTracker; +use deno_core::RcRef; +use deno_io::BiPipe; +use deno_io::BiPipeRead; +use deno_io::BiPipeWrite; +use memchr::memchr; +use pin_project_lite::pin_project; +use tokio::io::AsyncRead; +use tokio::io::AsyncWriteExt; +use tokio::io::ReadBuf; + +/// Tracks whether the IPC resources is currently +/// refed, and allows refing/unrefing it. +pub struct IpcRefTracker { + refed: AtomicBool, + tracker: OpsTracker, +} + +/// A little wrapper so we don't have to get an +/// `ExternalOpsTracker` for tests. When we aren't +/// cfg(test), this will get optimized out. +enum OpsTracker { + External(ExternalOpsTracker), + #[cfg(test)] + Test, +} + +impl OpsTracker { + fn ref_(&self) { + match self { + Self::External(tracker) => tracker.ref_op(), + #[cfg(test)] + Self::Test => {} + } + } + + fn unref(&self) { + match self { + Self::External(tracker) => tracker.unref_op(), + #[cfg(test)] + Self::Test => {} + } + } +} + +impl IpcRefTracker { + pub fn new(tracker: ExternalOpsTracker) -> Self { + Self { + refed: AtomicBool::new(false), + tracker: OpsTracker::External(tracker), + } + } + + #[cfg(test)] + fn new_test() -> Self { + Self { + refed: AtomicBool::new(false), + tracker: OpsTracker::Test, + } + } + + pub fn ref_(&self) { + if !self.refed.swap(true, std::sync::atomic::Ordering::AcqRel) { + self.tracker.ref_(); + } + } + + pub fn unref(&self) { + if self.refed.swap(false, std::sync::atomic::Ordering::AcqRel) { + self.tracker.unref(); + } + } +} + +pub struct IpcJsonStreamResource { + pub read_half: AsyncRefCell, + pub write_half: AsyncRefCell, + pub cancel: Rc, + pub queued_bytes: AtomicUsize, + pub ref_tracker: IpcRefTracker, +} + +impl deno_core::Resource for IpcJsonStreamResource { + fn close(self: Rc) { + self.cancel.cancel(); + } +} + +impl IpcJsonStreamResource { + pub fn new( + stream: i64, + ref_tracker: IpcRefTracker, + ) -> Result { + let (read_half, write_half) = BiPipe::from_raw(stream as _)?.split(); + Ok(Self { + read_half: AsyncRefCell::new(IpcJsonStream::new(read_half)), + write_half: AsyncRefCell::new(write_half), + cancel: Default::default(), + queued_bytes: Default::default(), + ref_tracker, + }) + } + + #[cfg(all(unix, test))] + pub fn from_stream( + stream: tokio::net::UnixStream, + ref_tracker: IpcRefTracker, + ) -> Self { + let (read_half, write_half) = stream.into_split(); + Self { + read_half: AsyncRefCell::new(IpcJsonStream::new(read_half.into())), + write_half: AsyncRefCell::new(write_half.into()), + cancel: Default::default(), + queued_bytes: Default::default(), + ref_tracker, + } + } + + #[cfg(all(windows, test))] + pub fn from_stream( + pipe: tokio::net::windows::named_pipe::NamedPipeClient, + ref_tracker: IpcRefTracker, + ) -> Self { + let (read_half, write_half) = tokio::io::split(pipe); + Self { + read_half: AsyncRefCell::new(IpcJsonStream::new(read_half.into())), + write_half: AsyncRefCell::new(write_half.into()), + cancel: Default::default(), + queued_bytes: Default::default(), + ref_tracker, + } + } + + /// writes _newline terminated_ JSON message to the IPC pipe. + pub async fn write_msg_bytes( + self: Rc, + msg: &[u8], + ) -> Result<(), io::Error> { + let mut write_half = RcRef::map(self, |r| &r.write_half).borrow_mut().await; + write_half.write_all(msg).await?; + Ok(()) + } +} + +// Initial capacity of the buffered reader and the JSON backing buffer. +// +// This is a tradeoff between memory usage and performance on large messages. +// +// 64kb has been chosen after benchmarking 64 to 66536 << 6 - 1 bytes per message. +pub const INITIAL_CAPACITY: usize = 1024 * 64; + +/// A buffer for reading from the IPC pipe. +/// Similar to the internal buffer of `tokio::io::BufReader`. +/// +/// This exists to provide buffered reading while granting mutable access +/// to the internal buffer (which isn't exposed through `tokio::io::BufReader` +/// or the `AsyncBufRead` trait). `simd_json` requires mutable access to an input +/// buffer for parsing, so this allows us to use the read buffer directly as the +/// input buffer without a copy (provided the message fits). +struct ReadBuffer { + buffer: Box<[u8]>, + pos: usize, + cap: usize, +} + +impl ReadBuffer { + fn new() -> Self { + Self { + buffer: vec![0; INITIAL_CAPACITY].into_boxed_slice(), + pos: 0, + cap: 0, + } + } + + fn get_mut(&mut self) -> &mut [u8] { + &mut self.buffer + } + + fn available_mut(&mut self) -> &mut [u8] { + &mut self.buffer[self.pos..self.cap] + } + + fn consume(&mut self, n: usize) { + self.pos = std::cmp::min(self.pos + n, self.cap); + } + + fn needs_fill(&self) -> bool { + self.pos >= self.cap + } +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum IpcJsonStreamError { + #[class(inherit)] + #[error("{0}")] + Io(#[source] std::io::Error), + #[class(generic)] + #[error("{0}")] + SimdJson(#[source] simd_json::Error), +} + +// JSON serialization stream over IPC pipe. +// +// `\n` is used as a delimiter between messages. +pub struct IpcJsonStream { + pipe: BiPipeRead, + buffer: Vec, + read_buffer: ReadBuffer, +} + +impl IpcJsonStream { + fn new(pipe: BiPipeRead) -> Self { + Self { + pipe, + buffer: Vec::with_capacity(INITIAL_CAPACITY), + read_buffer: ReadBuffer::new(), + } + } + + pub async fn read_msg( + &mut self, + ) -> Result, IpcJsonStreamError> { + let mut json = None; + let nread = read_msg_inner( + &mut self.pipe, + &mut self.buffer, + &mut json, + &mut self.read_buffer, + ) + .await + .map_err(IpcJsonStreamError::Io)?; + if nread == 0 { + // EOF. + return Ok(None); + } + + let json = match json { + Some(v) => v, + None => { + // Took more than a single read and some buffering. + simd_json::from_slice(&mut self.buffer[..nread]) + .map_err(IpcJsonStreamError::SimdJson)? + } + }; + + // Safety: Same as `Vec::clear` but without the `drop_in_place` for + // each element (nop for u8). Capacity remains the same. + unsafe { + self.buffer.set_len(0); + } + + Ok(Some(json)) + } +} + +pin_project! { + #[must_use = "futures do nothing unless you `.await` or poll them"] + struct ReadMsgInner<'a, R: ?Sized> { + reader: &'a mut R, + buf: &'a mut Vec, + json: &'a mut Option, + // The number of bytes appended to buf. This can be less than buf.len() if + // the buffer was not empty when the operation was started. + read: usize, + read_buffer: &'a mut ReadBuffer, + } +} + +fn read_msg_inner<'a, R>( + reader: &'a mut R, + buf: &'a mut Vec, + json: &'a mut Option, + read_buffer: &'a mut ReadBuffer, +) -> ReadMsgInner<'a, R> +where + R: AsyncRead + ?Sized + Unpin, +{ + ReadMsgInner { + reader, + buf, + json, + read: 0, + read_buffer, + } +} + +fn read_msg_internal( + mut reader: Pin<&mut R>, + cx: &mut Context<'_>, + buf: &mut Vec, + read_buffer: &mut ReadBuffer, + json: &mut Option, + read: &mut usize, +) -> Poll> { + loop { + let (done, used) = { + // effectively a tiny `poll_fill_buf`, but allows us to get a mutable reference to the buffer. + if read_buffer.needs_fill() { + let mut read_buf = ReadBuf::new(read_buffer.get_mut()); + ready!(reader.as_mut().poll_read(cx, &mut read_buf))?; + read_buffer.cap = read_buf.filled().len(); + read_buffer.pos = 0; + } + let available = read_buffer.available_mut(); + if let Some(i) = memchr(b'\n', available) { + if *read == 0 { + // Fast path: parse and put into the json slot directly. + json.replace( + simd_json::from_slice(&mut available[..i + 1]) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?, + ); + } else { + // This is not the first read, so we have to copy the data + // to make it contiguous. + buf.extend_from_slice(&available[..=i]); + } + (true, i + 1) + } else { + buf.extend_from_slice(available); + (false, available.len()) + } + }; + + read_buffer.consume(used); + *read += used; + if done || used == 0 { + return Poll::Ready(Ok(mem::replace(read, 0))); + } + } +} + +impl Future for ReadMsgInner<'_, R> { + type Output = io::Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let me = self.project(); + read_msg_internal( + Pin::new(*me.reader), + cx, + me.buf, + me.read_buffer, + me.json, + me.read, + ) + } +} + +#[cfg(test)] +mod tests { + use std::rc::Rc; + + use deno_core::serde_json::json; + use deno_core::v8; + use deno_core::JsRuntime; + use deno_core::RcRef; + use deno_core::RuntimeOptions; + + use super::IpcJsonStreamResource; + + #[allow(clippy::unused_async)] + #[cfg(unix)] + pub async fn pair() -> (Rc, tokio::net::UnixStream) { + let (a, b) = tokio::net::UnixStream::pair().unwrap(); + + /* Similar to how ops would use the resource */ + let a = Rc::new(IpcJsonStreamResource::from_stream( + a, + super::IpcRefTracker::new_test(), + )); + (a, b) + } + + #[cfg(windows)] + pub async fn pair() -> ( + Rc, + tokio::net::windows::named_pipe::NamedPipeServer, + ) { + use tokio::net::windows::named_pipe::ClientOptions; + use tokio::net::windows::named_pipe::ServerOptions; + + let name = + format!(r"\\.\pipe\deno-named-pipe-test-{}", rand::random::()); + + let server = ServerOptions::new().create(name.clone()).unwrap(); + let client = ClientOptions::new().open(name).unwrap(); + + server.connect().await.unwrap(); + /* Similar to how ops would use the resource */ + let client = Rc::new(IpcJsonStreamResource::from_stream( + client, + super::IpcRefTracker::new_test(), + )); + (client, server) + } + + #[allow(clippy::print_stdout)] + #[tokio::test] + async fn bench_ipc() -> Result<(), Box> { + // A simple round trip benchmark for quick dev feedback. + // + // Only ran when the env var is set. + if std::env::var_os("BENCH_IPC_DENO").is_none() { + return Ok(()); + } + + let (ipc, mut fd2) = pair().await; + let child = tokio::spawn(async move { + use tokio::io::AsyncWriteExt; + + let size = 1024 * 1024; + + let stri = "x".repeat(size); + let data = format!("\"{}\"\n", stri); + for _ in 0..100 { + fd2.write_all(data.as_bytes()).await?; + } + Ok::<_, std::io::Error>(()) + }); + + let start = std::time::Instant::now(); + let mut bytes = 0; + + let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; + loop { + let Some(msgs) = ipc.read_msg().await? else { + break; + }; + bytes += msgs.as_str().unwrap().len(); + if start.elapsed().as_secs() > 5 { + break; + } + } + let elapsed = start.elapsed(); + let mb = bytes as f64 / 1024.0 / 1024.0; + println!("{} mb/s", mb / elapsed.as_secs_f64()); + + child.await??; + + Ok(()) + } + + #[tokio::test] + async fn unix_ipc_json() -> Result<(), Box> { + let (ipc, mut fd2) = pair().await; + let child = tokio::spawn(async move { + use tokio::io::AsyncReadExt; + use tokio::io::AsyncWriteExt; + + const EXPECTED: &[u8] = b"\"hello\"\n"; + let mut buf = [0u8; EXPECTED.len()]; + let n = fd2.read_exact(&mut buf).await?; + assert_eq!(&buf[..n], EXPECTED); + fd2.write_all(b"\"world\"\n").await?; + + Ok::<_, std::io::Error>(()) + }); + + ipc + .clone() + .write_msg_bytes(&json_to_bytes(json!("hello"))) + .await?; + + let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; + let msgs = ipc.read_msg().await?.unwrap(); + assert_eq!(msgs, json!("world")); + + child.await??; + + Ok(()) + } + + fn json_to_bytes(v: deno_core::serde_json::Value) -> Vec { + let mut buf = deno_core::serde_json::to_vec(&v).unwrap(); + buf.push(b'\n'); + buf + } + + #[tokio::test] + async fn unix_ipc_json_multi() -> Result<(), Box> { + let (ipc, mut fd2) = pair().await; + let child = tokio::spawn(async move { + use tokio::io::AsyncReadExt; + use tokio::io::AsyncWriteExt; + + const EXPECTED: &[u8] = b"\"hello\"\n\"world\"\n"; + let mut buf = [0u8; EXPECTED.len()]; + let n = fd2.read_exact(&mut buf).await?; + assert_eq!(&buf[..n], EXPECTED); + fd2.write_all(b"\"foo\"\n\"bar\"\n").await?; + Ok::<_, std::io::Error>(()) + }); + + ipc + .clone() + .write_msg_bytes(&json_to_bytes(json!("hello"))) + .await?; + ipc + .clone() + .write_msg_bytes(&json_to_bytes(json!("world"))) + .await?; + + let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; + let msgs = ipc.read_msg().await?.unwrap(); + assert_eq!(msgs, json!("foo")); + + child.await??; + + Ok(()) + } + + #[tokio::test] + async fn unix_ipc_json_invalid() -> Result<(), Box> { + let (ipc, mut fd2) = pair().await; + let child = tokio::spawn(async move { + tokio::io::AsyncWriteExt::write_all(&mut fd2, b"\n\n").await?; + Ok::<_, std::io::Error>(()) + }); + + let mut ipc = RcRef::map(ipc, |r| &r.read_half).borrow_mut().await; + let _err = ipc.read_msg().await.unwrap_err(); + + child.await??; + + Ok(()) + } + + #[test] + fn memchr() { + let str = b"hello world"; + assert_eq!(super::memchr(b'h', str), Some(0)); + assert_eq!(super::memchr(b'w', str), Some(6)); + assert_eq!(super::memchr(b'd', str), Some(10)); + assert_eq!(super::memchr(b'x', str), None); + + let empty = b""; + assert_eq!(super::memchr(b'\n', empty), None); + } +} diff --git a/runtime/ops/process.rs b/ext/process/lib.rs similarity index 98% rename from runtime/ops/process.rs rename to ext/process/lib.rs index fc32f7e066..24985a8048 100644 --- a/runtime/ops/process.rs +++ b/ext/process/lib.rs @@ -38,6 +38,10 @@ use serde::Deserialize; use serde::Serialize; use tokio::process::Command; +pub mod ipc; +use ipc::IpcJsonStreamResource; +use ipc::IpcRefTracker; + pub const UNSTABLE_FEATURE_NAME: &str = "process"; #[derive(Copy, Clone, Eq, PartialEq, Deserialize)] @@ -153,6 +157,7 @@ deno_core::extension!( deprecated::op_run_status, deprecated::op_kill, ], + esm = ["40_process.js"], options = { get_npm_process_state: Option }, state = |state, options| { state.put::(options.get_npm_process_state.unwrap_or(deno_fs::sync::MaybeArc::new(EmptyNpmProcessStateProvider))); @@ -462,13 +467,10 @@ fn create_command( fds_to_dup.push((ipc_fd2, ipc)); fds_to_close.push(ipc_fd2); /* One end returned to parent process (this) */ - let pipe_rid = - state - .resource_table - .add(deno_node::IpcJsonStreamResource::new( - ipc_fd1 as _, - deno_node::IpcRefTracker::new(state.external_ops_tracker.clone()), - )?); + let pipe_rid = state.resource_table.add(IpcJsonStreamResource::new( + ipc_fd1 as _, + IpcRefTracker::new(state.external_ops_tracker.clone()), + )?); /* The other end passed to child process via NODE_CHANNEL_FD */ command.env("NODE_CHANNEL_FD", format!("{}", ipc)); ipc_rid = Some(pipe_rid); @@ -532,12 +534,11 @@ fn create_command( let (hd1, hd2) = deno_io::bi_pipe_pair_raw()?; /* One end returned to parent process (this) */ - let pipe_rid = Some(state.resource_table.add( - deno_node::IpcJsonStreamResource::new( + let pipe_rid = + Some(state.resource_table.add(IpcJsonStreamResource::new( hd1 as i64, - deno_node::IpcRefTracker::new(state.external_ops_tracker.clone()), - )?, - )); + IpcRefTracker::new(state.external_ops_tracker.clone()), + )?)); /* The other end passed to child process via NODE_CHANNEL_FD */ command.env("NODE_CHANNEL_FD", format!("{}", hd2 as i64)); diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index b56b4a2b50..b87d4cfbdf 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -60,6 +60,7 @@ deno_kv.workspace = true deno_tls.workspace = true deno_url.workspace = true deno_web.workspace = true +deno_process.workspace = true deno_webgpu.workspace = true deno_webidl.workspace = true deno_websocket.workspace = true @@ -93,6 +94,7 @@ deno_node.workspace = true deno_os.workspace = true deno_path_util.workspace = true deno_permissions.workspace = true +deno_process.workspace = true deno_resolver.workspace = true deno_telemetry.workspace = true deno_terminal.workspace = true diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index b241028077..5aaf0614dc 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -23,7 +23,7 @@ import * as io from "ext:deno_io/12_io.js"; import * as fs from "ext:deno_fs/30_fs.js"; import * as os from "ext:deno_os/30_os.js"; import * as fsEvents from "ext:runtime/40_fs_events.js"; -import * as process from "ext:runtime/40_process.js"; +import * as process from "ext:deno_process/40_process.js"; import * as signals from "ext:deno_os/40_signals.js"; import * as tty from "ext:runtime/40_tty.js"; import * as kv from "ext:deno_kv/01_db.ts"; diff --git a/runtime/lib.rs b/runtime/lib.rs index 65d3e88bae..c83fe5d60b 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -18,6 +18,7 @@ pub use deno_net; pub use deno_node; pub use deno_os; pub use deno_permissions; +pub use deno_process; pub use deno_telemetry; pub use deno_terminal::colors; pub use deno_tls; @@ -115,7 +116,7 @@ pub static UNSTABLE_GRANULAR_FLAGS: &[UnstableGranularFlag] = &[ }, // TODO(bartlomieju): consider removing it UnstableGranularFlag { - name: ops::process::UNSTABLE_FEATURE_NAME, + name: deno_process::UNSTABLE_FEATURE_NAME, help_text: "Enable unstable process APIs", show_in_help: false, id: 10, diff --git a/runtime/ops/mod.rs b/runtime/ops/mod.rs index d131e9aab5..04065ff2f8 100644 --- a/runtime/ops/mod.rs +++ b/runtime/ops/mod.rs @@ -4,7 +4,6 @@ pub mod bootstrap; pub mod fs_events; pub mod http; pub mod permissions; -pub mod process; pub mod runtime; pub mod tty; pub mod web_worker; diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs index d9912839b8..a929b7d18a 100644 --- a/runtime/ops/tty.rs +++ b/runtime/ops/tty.rs @@ -50,14 +50,13 @@ impl TtyModeStore { } } +#[cfg(unix)] +use deno_process::JsNixError; #[cfg(windows)] use winapi::shared::minwindef::DWORD; #[cfg(windows)] use winapi::um::wincon; -#[cfg(unix)] -use crate::ops::process::JsNixError; - deno_core::extension!( deno_tty, ops = [op_set_raw, op_console_size, op_read_line_prompt], diff --git a/runtime/shared.rs b/runtime/shared.rs index 0e747b0565..ecf2088fe1 100644 --- a/runtime/shared.rs +++ b/runtime/shared.rs @@ -43,7 +43,6 @@ extension!(runtime, "10_permissions.js", "11_workers.js", "40_fs_events.js", - "40_process.js", "40_tty.js", "41_prompt.js", "90_deno_ns.js", diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 08ea17a986..eec8579e59 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -311,6 +311,7 @@ pub fn create_runtime_snapshot( deno_io::deno_io::init_ops_and_esm(Default::default()), deno_fs::deno_fs::init_ops_and_esm::(fs.clone()), deno_os::deno_os::init_ops_and_esm(Default::default()), + deno_process::deno_process::init_ops_and_esm(Default::default()), deno_node::deno_node::init_ops_and_esm::< Permissions, DenoInNpmPackageChecker, @@ -325,7 +326,6 @@ pub fn create_runtime_snapshot( ), ops::fs_events::deno_fs_events::init_ops(), ops::permissions::deno_permissions::init_ops(), - ops::process::deno_process::init_ops(None), ops::tty::deno_tty::init_ops(), ops::http::deno_http_runtime::init_ops(), ops::bootstrap::deno_bootstrap::init_ops(Some(snapshot_options)), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index e4ea42a2f7..bb769c46a9 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -44,6 +44,7 @@ use deno_kv::dynamic::MultiBackendDbHandler; use deno_node::ExtNodeSys; use deno_node::NodeExtInitServices; use deno_permissions::PermissionsContainer; +use deno_process::NpmProcessStateProviderRc; use deno_terminal::colors; use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; @@ -59,7 +60,6 @@ use node_resolver::NpmPackageFolderResolver; use crate::inspector_server::InspectorServer; use crate::ops; -use crate::ops::process::NpmProcessStateProviderRc; use crate::shared::maybe_transpile_source; use crate::shared::runtime; use crate::tokio_util::create_and_run_current_thread; @@ -529,6 +529,9 @@ impl WebWorker { services.fs.clone(), ), deno_os::deno_os_worker::init_ops_and_esm(), + deno_process::deno_process::init_ops_and_esm( + services.npm_process_state_provider, + ), deno_node::deno_node::init_ops_and_esm::< PermissionsContainer, TInNpmPackageChecker, @@ -543,9 +546,6 @@ impl WebWorker { ), ops::fs_events::deno_fs_events::init_ops_and_esm(), ops::permissions::deno_permissions::init_ops_and_esm(), - ops::process::deno_process::init_ops_and_esm( - services.npm_process_state_provider, - ), ops::tty::deno_tty::init_ops_and_esm(), ops::http::deno_http_runtime::init_ops_and_esm(), ops::bootstrap::deno_bootstrap::init_ops_and_esm( diff --git a/runtime/worker.rs b/runtime/worker.rs index 426383a19e..72eb54ec47 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -40,6 +40,7 @@ use deno_node::ExtNodeSys; use deno_node::NodeExtInitServices; use deno_os::ExitCode; use deno_permissions::PermissionsContainer; +use deno_process::NpmProcessStateProviderRc; use deno_tls::RootCertStoreProvider; use deno_tls::TlsKeys; use deno_web::BlobStore; @@ -51,7 +52,6 @@ use crate::code_cache::CodeCache; use crate::code_cache::CodeCacheType; use crate::inspector_server::InspectorServer; use crate::ops; -use crate::ops::process::NpmProcessStateProviderRc; use crate::shared::maybe_transpile_source; use crate::shared::runtime; use crate::BootstrapOptions; @@ -428,6 +428,9 @@ impl MainWorker { services.fs.clone(), ), deno_os::deno_os::init_ops_and_esm(exit_code.clone()), + deno_process::deno_process::init_ops_and_esm( + services.npm_process_state_provider, + ), deno_node::deno_node::init_ops_and_esm::< PermissionsContainer, TInNpmPackageChecker, @@ -442,9 +445,6 @@ impl MainWorker { ), ops::fs_events::deno_fs_events::init_ops_and_esm(), ops::permissions::deno_permissions::init_ops_and_esm(), - ops::process::deno_process::init_ops_and_esm( - services.npm_process_state_provider, - ), ops::tty::deno_tty::init_ops_and_esm(), ops::http::deno_http_runtime::init_ops_and_esm(), ops::bootstrap::deno_bootstrap::init_ops_and_esm( diff --git a/tools/core_import_map.json b/tools/core_import_map.json index 0176f47e23..935c7179a1 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -244,7 +244,7 @@ "ext:runtime/11_workers.js": "../runtime/js/11_workers.js", "ext:deno_os/30_os.js": "../ext/os/30_os.js", "ext:runtime/40_fs_events.js": "../runtime/js/40_fs_events.js", - "ext:runtime/40_process.js": "../runtime/js/40_process.js", + "ext:deno_process/40_process.js": "../ext/process/40_process.js", "ext:deno_os/40_signals.js": "../ext/os/40_signals.js", "ext:runtime/40_tty.js": "../runtime/js/40_tty.js", "ext:runtime/41_prompt.js": "../runtime/js/41_prompt.js", From 342ccbb99d4bc5c7ed9d21b46de48412c8997b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 17 Jan 2025 13:31:58 +0000 Subject: [PATCH 36/38] ci: use self-hosted mac arm runner on tags (#27708) --- .github/workflows/ci.generate.ts | 4 ++-- .github/workflows/ci.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.generate.ts b/.github/workflows/ci.generate.ts index d302f92c98..cd0f3a382b 100755 --- a/.github/workflows/ci.generate.ts +++ b/.github/workflows/ci.generate.ts @@ -46,9 +46,9 @@ const Runners = { macosArmSelfHosted: { os: "macos", arch: "aarch64", - // Actually use self-hosted runner only in denoland/deno on `main` branch. + // Actually use self-hosted runner only in denoland/deno on `main` branch and for tags (release) builds. runner: - `\${{ github.repository == 'denoland/deno' && github.ref == 'refs/heads/main' && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`, + `\${{ github.repository == 'denoland/deno' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && '${selfHostedMacosArmRunner}' || '${macosArmRunner}' }}`, }, windowsX86: { os: "windows", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 501c23212a..fd9aaaf741 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,7 @@ jobs: profile: debug - os: macos arch: aarch64 - runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && github.ref == ''refs/heads/main'' && ''ghcr.io/cirruslabs/macos-runner:sonoma'' || ''macos-14'' }}' + runner: '${{ (!contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'')) && ''ubuntu-24.04'' || github.repository == ''denoland/deno'' && (github.ref == ''refs/heads/main'' || startsWith(github.ref, ''refs/tags/'')) && ''ghcr.io/cirruslabs/macos-runner:sonoma'' || ''macos-14'' }}' job: test profile: release skip: '${{ !contains(github.event.pull_request.labels.*.name, ''ci-full'') && (github.event_name == ''pull_request'') }}' From b55451b178b941dcd15a7139e208e38b176b9452 Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Sat, 18 Jan 2025 00:10:26 +0900 Subject: [PATCH 37/38] fix(ext/node): tls.connect regression (#27707) The TLS start sequence has been broken since #26661 because of the way how we wrap TCP handle to create TLS handle. #26661 introduced happy-eyeballs algorithm and some connection could be dropped because of happy-eyeball attempt timeout. The current implementation doesn't consider that case and it could start TLS handshake with timed out TCP connection. That caused #27652 . This PR fixes it by changing the initialization steps. Now `wrapHandle` of TLSSocket set up `afterConnectTls` callback in TCP handle, and `afterConnect` of TCP handle calls it at `connect` event timing if it exists. This avoids starting TLS session with timed out connection. closes #27652 --- ext/node/polyfills/_tls_wrap.ts | 9 +++------ ext/node/polyfills/net.ts | 6 ++++++ tests/unit_node/tls_test.ts | 13 +++++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ext/node/polyfills/_tls_wrap.ts b/ext/node/polyfills/_tls_wrap.ts index dc7dac77ac..6697bc97ac 100644 --- a/ext/node/polyfills/_tls_wrap.ts +++ b/ext/node/polyfills/_tls_wrap.ts @@ -79,7 +79,7 @@ export class TLSSocket extends net.Socket { ssl: any; _start() { - this[kHandle].afterConnect(); + this[kHandle].afterConnectTls(); } constructor(socket: any, opts: any = kEmptyObject) { @@ -150,16 +150,14 @@ export class TLSSocket extends net.Socket { const { promise, resolve } = Promise.withResolvers(); - // Patches `afterConnect` hook to replace TCP conn with TLS conn - const afterConnect = handle.afterConnect; - handle.afterConnect = async (req: any, status: number) => { + // Set `afterConnectTls` hook. This is called in the `afterConnect` method of net.Socket + handle.afterConnectTls = async () => { options.hostname ??= undefined; // coerce to undefined if null, startTls expects hostname to be undefined if (tlssock._needsSockInitWorkaround) { // skips the TLS handshake for @npmcli/agent as it's handled by // onSocket handler of ClientRequest object. tlssock.emit("secure"); tlssock.removeListener("end", onConnectEnd); - return afterConnect.call(handle, req, status); } try { @@ -190,7 +188,6 @@ export class TLSSocket extends net.Socket { } catch { // TODO(kt3k): Handle this } - return afterConnect.call(handle, req, status); }; handle.upgrading = promise; diff --git a/ext/node/polyfills/net.ts b/ext/node/polyfills/net.ts index 2d57507c1b..8fde8eac1e 100644 --- a/ext/node/polyfills/net.ts +++ b/ext/node/polyfills/net.ts @@ -378,6 +378,12 @@ function _afterConnect( socket.emit("connect"); socket.emit("ready"); + // Deno specific: run tls handshake if it's from a tls socket + // This swaps the handle[kStreamBaseField] from TcpConn to TlsConn + if (typeof handle.afterConnectTls === "function") { + handle.afterConnectTls(); + } + // Start the first read, or get an immediate EOF. // this doesn't actually consume any bytes, because len=0. if (readable && !socket.isPaused()) { diff --git a/tests/unit_node/tls_test.ts b/tests/unit_node/tls_test.ts index f34d9efb5b..97d753e4f8 100644 --- a/tests/unit_node/tls_test.ts +++ b/tests/unit_node/tls_test.ts @@ -12,6 +12,7 @@ import { fromFileUrl, join } from "@std/path"; import * as tls from "node:tls"; import * as net from "node:net"; import * as stream from "node:stream"; +import { text } from "node:stream/consumers"; import { execCode } from "../unit/test_util.ts"; const tlsTestdataDir = fromFileUrl( @@ -97,6 +98,18 @@ Connection: close assertEquals(bodyText, "hello"); }); +// Regression at https://github.com/denoland/deno/issues/27652 +Deno.test("tls.connect makes tls connection to example.com", async () => { + const socket = tls.connect(443, "example.com"); + await new Promise((resolve) => { + socket.on("secureConnect", resolve); + }); + socket.write( + "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n", + ); + assertStringIncludes(await text(socket), "Example Domain"); +}); + // https://github.com/denoland/deno/pull/20120 Deno.test("tls.connect mid-read tcp->tls upgrade", async () => { const { promise, resolve } = Promise.withResolvers(); From 054075730c074d03b22c20615da477c4501622d3 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Fri, 17 Jan 2025 18:41:52 +0100 Subject: [PATCH 38/38] refactor: update deno_core and use more concrete errors (#27620) waiting for https://github.com/denoland/deno_core/pull/1043 Fixes #27672 --- Cargo.lock | 20 +++--- Cargo.toml | 4 +- cli/args/lockfile.rs | 24 ++++--- cli/args/mod.rs | 1 + cli/emit.rs | 4 +- cli/main.rs | 2 +- cli/module_loader.rs | 93 ++++++++++++++++++++----- cli/node.rs | 17 +++-- cli/resolver.rs | 105 +++++++++++++++++++---------- cli/standalone/binary.rs | 3 +- cli/standalone/mod.rs | 6 +- cli/standalone/serialization.rs | 8 ++- cli/tools/bench/mod.rs | 33 ++++++--- cli/tools/coverage/mod.rs | 27 +++++--- cli/tools/test/mod.rs | 49 +++++++++++--- cli/util/result.rs | 2 +- cli/worker.rs | 116 ++++++++++++++++++++++++-------- ext/net/quic.rs | 3 - ext/node/ops/require.rs | 11 ++- resolvers/node/analyze.rs | 115 +++++++++++++++++++++---------- runtime/fs_util.rs | 5 +- runtime/inspector_server.rs | 28 ++++++-- 22 files changed, 474 insertions(+), 202 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 392ff5ef46..cd16ac1b7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1532,9 +1532,9 @@ dependencies = [ [[package]] name = "deno_core" -version = "0.330.0" +version = "0.331.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd38bbbd68ed873165ccb630322704b44140d3a8c8d50f898beac4d1a8a3358c" +checksum = "ce2d1779358cad2bc56d71176298767be628d707bb75585f6f8a4be2da8ccda1" dependencies = [ "anyhow", "az", @@ -1658,9 +1658,9 @@ dependencies = [ [[package]] name = "deno_error" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da6a58de6932a96f84e133c072fd3b525966ee122a71f3efd48bbff2eed5ac" +checksum = "9c23dbc46d5804814b08b4675838f9884e3a52916987ec5105af36d42f9911b5" dependencies = [ "deno_error_macro", "libc", @@ -1672,9 +1672,9 @@ dependencies = [ [[package]] name = "deno_error_macro" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46351dff93aed2039407c91e2ded2a5591e42d2795ab3d111288625bb710d3d2" +checksum = "babccedee31ce7e57c3e6dff2cb3ab8d68c49d0df8222fe0d11d628e65192790" dependencies = [ "proc-macro2", "quote", @@ -2151,9 +2151,9 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.206.0" +version = "0.207.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c25ffa9d088ea00748dbef870bba110ac22ebf8cf7b2e9eb288409c5d852af3" +checksum = "96f000a21f6969b4c945bc8e9e785aa439f11ca4fd3fbddcd5bebc102167eb37" dependencies = [ "indexmap 2.3.0", "proc-macro-rules", @@ -6947,9 +6947,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3caa6d882827148e5d9052d9d8d6d1c9d6ad426ed00cab46cafb8c07a0e7126a" +checksum = "cd0494d74c40ab94f53a19485de359ea6a55f05341b817b93440b673c1ce8ec6" dependencies = [ "deno_error", "num-bigint", diff --git a/Cargo.toml b/Cargo.toml index 42c2970e05..83d4a8398a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ repository = "https://github.com/denoland/deno" [workspace.dependencies] deno_ast = { version = "=0.44.0", features = ["transpiling"] } -deno_core = { version = "0.330.0" } +deno_core = { version = "0.331.0" } deno_bench_util = { version = "0.180.0", path = "./bench_util" } deno_config = { version = "=0.45.0", features = ["workspace", "sync"] } @@ -123,7 +123,7 @@ dashmap = "5.5.3" data-encoding = "2.3.3" data-url = "=0.3.1" deno_cache_dir = "=0.16.0" -deno_error = "=0.5.3" +deno_error = "=0.5.5" deno_package_json = { version = "0.4.0", default-features = false } deno_unsync = "0.4.2" dlopen2 = "0.6.1" diff --git a/cli/args/lockfile.rs b/cli/args/lockfile.rs index 976992aac8..5fa6a49c43 100644 --- a/cli/args/lockfile.rs +++ b/cli/args/lockfile.rs @@ -61,11 +61,13 @@ impl<'a, T> std::ops::DerefMut for Guard<'a, T> { } #[derive(Debug, thiserror::Error, deno_error::JsError)] -#[error("Failed writing lockfile")] -#[class(inherit)] -struct AtomicWriteFileWithRetriesError { - #[source] - source: std::io::Error, +pub enum AtomicWriteFileWithRetriesError { + #[class(inherit)] + #[error(transparent)] + Changed(JsErrorBox), + #[class(inherit)] + #[error("Failed writing lockfile")] + Io(#[source] std::io::Error), } impl CliLockfile { @@ -87,12 +89,16 @@ impl CliLockfile { self.lockfile.lock().overwrite } - pub fn write_if_changed(&self) -> Result<(), JsErrorBox> { + pub fn write_if_changed( + &self, + ) -> Result<(), AtomicWriteFileWithRetriesError> { if self.skip_write { return Ok(()); } - self.error_if_changed()?; + self + .error_if_changed() + .map_err(AtomicWriteFileWithRetriesError::Changed)?; let mut lockfile = self.lockfile.lock(); let Some(bytes) = lockfile.resolve_write_bytes() else { return Ok(()); // nothing to do @@ -105,9 +111,7 @@ impl CliLockfile { &bytes, cache::CACHE_PERM, ) - .map_err(|source| { - JsErrorBox::from_err(AtomicWriteFileWithRetriesError { source }) - })?; + .map_err(AtomicWriteFileWithRetriesError::Io)?; lockfile.has_content_changed = false; Ok(()) } diff --git a/cli/args/mod.rs b/cli/args/mod.rs index f77eedc594..46ada5440f 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -82,6 +82,7 @@ use deno_terminal::colors; use dotenvy::from_filename; pub use flags::*; use import_map::resolve_import_map_value_from_specifier; +pub use lockfile::AtomicWriteFileWithRetriesError; pub use lockfile::CliLockfile; pub use lockfile::CliLockfileReadFromPathOptions; use once_cell::sync::Lazy; diff --git a/cli/emit.rs b/cli/emit.rs index 69ac8323bb..f928591eaf 100644 --- a/cli/emit.rs +++ b/cli/emit.rs @@ -112,9 +112,9 @@ impl Emitter { &self, specifier: &ModuleSpecifier, media_type: MediaType, - module_kind: deno_ast::ModuleKind, + module_kind: ModuleKind, source: &Arc, - ) -> Result { + ) -> Result { // Note: keep this in sync with the sync version below let helper = EmitParsedSourceHelper(self); match helper.pre_emit_parsed_source(specifier, module_kind, source) { diff --git a/cli/main.rs b/cli/main.rs index f97ea81e5d..a6b552c636 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -201,7 +201,7 @@ async fn run_subcommand(flags: Arc) -> Result { match result { Ok(v) => Ok(v), Err(script_err) => { - if let Some(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_))) = util::result::any_and_jserrorbox_downcast_ref::(&script_err) { + if let Some(worker::CreateCustomWorkerError::ResolvePkgFolderFromDenoReq(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_)))) = util::result::any_and_jserrorbox_downcast_ref::(&script_err) { if flags.node_modules_dir.is_none() { let mut flags = flags.deref().clone(); let watch = match &flags.subcommand { diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 2b0ebca986..7acb947491 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -13,8 +13,6 @@ use std::sync::Arc; use deno_ast::MediaType; use deno_ast::ModuleKind; -use deno_core::anyhow::anyhow; -use deno_core::anyhow::Context; use deno_core::error::AnyError; use deno_core::error::ModuleLoaderError; use deno_core::futures::future::FutureExt; @@ -45,6 +43,7 @@ use deno_lib::worker::ModuleLoaderFactory; use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::code_cache; use deno_runtime::deno_node::create_host_defined_options; +use deno_runtime::deno_node::ops::require::UnableToGetCwdError; use deno_runtime::deno_node::NodeRequireLoader; use deno_runtime::deno_permissions::PermissionsContainer; use deno_semver::npm::NpmPackageReqReference; @@ -99,6 +98,11 @@ pub enum PrepareModuleLoadError { Check(#[from] CheckError), #[class(inherit)] #[error(transparent)] + AtomicWriteFileWithRetries( + #[from] crate::args::AtomicWriteFileWithRetriesError, + ), + #[class(inherit)] + #[error(transparent)] Other(#[from] JsErrorBox), } @@ -419,6 +423,55 @@ impl ModuleLoaderFactory for CliModuleLoaderFactory { } } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum LoadCodeSourceError { + #[class(inherit)] + #[error(transparent)] + NpmModuleLoad(crate::resolver::NpmModuleLoadError), + #[class(inherit)] + #[error(transparent)] + LoadPreparedModule(#[from] LoadPreparedModuleError), + #[class(generic)] + #[error("Loading unprepared module: {}{}", .specifier, .maybe_referrer.as_ref().map(|r| format!(", imported from: {}", r)).unwrap_or_default())] + LoadUnpreparedModule { + specifier: ModuleSpecifier, + maybe_referrer: Option, + }, +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum LoadPreparedModuleError { + #[class(inherit)] + #[error(transparent)] + NpmModuleLoad(#[from] crate::emit::EmitParsedSourceHelperError), + #[class(inherit)] + #[error(transparent)] + LoadMaybeCjs(#[from] LoadMaybeCjsError), + #[class(inherit)] + #[error(transparent)] + Other(#[from] JsErrorBox), +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum LoadMaybeCjsError { + #[class(inherit)] + #[error(transparent)] + NpmModuleLoad(#[from] crate::emit::EmitParsedSourceHelperError), + #[class(inherit)] + #[error(transparent)] + TranslateCjsToEsm(#[from] node_resolver::analyze::TranslateCjsToEsmError), +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[class(inherit)] +#[error("Could not resolve '{reference}'")] +pub struct CouldNotResolveError { + reference: deno_semver::npm::NpmPackageNvReference, + #[source] + #[inherit] + source: node_resolver::errors::PackageSubpathResolveError, +} + struct CliModuleLoaderInner { lib: TsTypeLib, is_worker: bool, @@ -443,7 +496,10 @@ impl maybe_referrer: Option<&ModuleSpecifier>, requested_module_type: RequestedModuleType, ) -> Result { - let code_source = self.load_code_source(specifier, maybe_referrer).await?; + let code_source = self + .load_code_source(specifier, maybe_referrer) + .await + .map_err(JsErrorBox::from_err)?; let code = if self.shared.is_inspecting || code_source.media_type == MediaType::Wasm { @@ -504,7 +560,7 @@ impl &self, specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - ) -> Result { + ) -> Result { if let Some(code_source) = self.load_prepared_module(specifier).await? { return Ok(code_source); } @@ -513,14 +569,14 @@ impl .shared .npm_module_loader .load(specifier, maybe_referrer) - .await; + .await + .map_err(LoadCodeSourceError::NpmModuleLoad); } - let mut msg = format!("Loading unprepared module: {specifier}"); - if let Some(referrer) = maybe_referrer { - msg = format!("{}, imported from: {}", msg, referrer.as_str()); - } - Err(anyhow!(msg)) + Err(LoadCodeSourceError::LoadUnpreparedModule { + specifier: specifier.clone(), + maybe_referrer: maybe_referrer.cloned(), + }) } fn resolve_referrer( @@ -543,7 +599,8 @@ impl .map_err(|e| e.into()) } else { // this cwd check is slow, so try to avoid it - let cwd = std::env::current_dir().context("Unable to get CWD")?; + let cwd = std::env::current_dir() + .map_err(|e| JsErrorBox::from_err(UnableToGetCwdError(e)))?; deno_core::resolve_path(referrer, &cwd).map_err(|e| e.into()) } } @@ -622,8 +679,11 @@ impl ResolutionMode::Import, NodeResolutionKind::Execution, ) - .with_context(|| { - format!("Could not resolve '{}'.", module.nv_reference) + .map_err(|source| { + JsErrorBox::from_err(CouldNotResolveError { + reference: module.nv_reference.clone(), + source, + }) })? } Some(Module::Node(module)) => module.specifier.clone(), @@ -644,7 +704,7 @@ impl async fn load_prepared_module( &self, specifier: &ModuleSpecifier, - ) -> Result, AnyError> { + ) -> Result, LoadPreparedModuleError> { // Note: keep this in sync with the sync version below let graph = self.graph_container.graph(); match self.load_prepared_module_or_defer_emit(&graph, specifier)? { @@ -676,7 +736,8 @@ impl }) => self .load_maybe_cjs(specifier, media_type, source) .await - .map(Some), + .map(Some) + .map_err(LoadPreparedModuleError::LoadMaybeCjs), None => Ok(None), } } @@ -837,7 +898,7 @@ impl specifier: &ModuleSpecifier, media_type: MediaType, original_source: &Arc, - ) -> Result { + ) -> Result { let js_source = if media_type.is_emittable() { Cow::Owned( self diff --git a/cli/node.rs b/cli/node.rs index 892e25914a..f6411f5e53 100644 --- a/cli/node.rs +++ b/cli/node.rs @@ -5,13 +5,14 @@ use std::sync::Arc; use deno_ast::MediaType; use deno_ast::ModuleSpecifier; -use deno_core::error::AnyError; +use deno_error::JsErrorBox; use deno_graph::ParsedSourceStore; use deno_resolver::npm::DenoInNpmPackageChecker; use deno_runtime::deno_fs; use deno_runtime::deno_node::RealIsBuiltInNodeModuleChecker; use node_resolver::analyze::CjsAnalysis as ExtNodeCjsAnalysis; use node_resolver::analyze::CjsAnalysisExports; +use node_resolver::analyze::CjsCodeAnalysisError; use node_resolver::analyze::CjsCodeAnalyzer; use node_resolver::analyze::NodeCodeTranslator; use serde::Deserialize; @@ -75,7 +76,7 @@ impl CliCjsCodeAnalyzer { &self, specifier: &ModuleSpecifier, source: &str, - ) -> Result { + ) -> Result { let source_hash = CacheDBHash::from_hashable(source); if let Some(analysis) = self.cache.get_cjs_analysis(specifier.as_str(), source_hash) @@ -102,9 +103,10 @@ impl CliCjsCodeAnalyzer { deno_core::unsync::spawn_blocking({ let specifier = specifier.clone(); let source: Arc = source.into(); - move || -> Result<_, AnyError> { - let parsed_source = - maybe_parsed_source.map(Ok).unwrap_or_else(|| { + move || -> Result<_, CjsCodeAnalysisError> { + let parsed_source = maybe_parsed_source + .map(Ok) + .unwrap_or_else(|| { deno_ast::parse_program(deno_ast::ParseParams { specifier, text: source, @@ -113,7 +115,8 @@ impl CliCjsCodeAnalyzer { scope_analysis: false, maybe_syntax: None, }) - })?; + }) + .map_err(JsErrorBox::from_err)?; let is_script = parsed_source.compute_is_script(); let is_cjs = cjs_tracker.is_cjs_with_known_is_script( parsed_source.specifier(), @@ -151,7 +154,7 @@ impl CjsCodeAnalyzer for CliCjsCodeAnalyzer { &self, specifier: &ModuleSpecifier, source: Option>, - ) -> Result, AnyError> { + ) -> Result, CjsCodeAnalysisError> { let source = match source { Some(source) => source, None => { diff --git a/cli/resolver.rs b/cli/resolver.rs index 5677767fdd..b837ba51b1 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -1,6 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. use std::borrow::Cow; +use std::path::PathBuf; use std::sync::Arc; use async_trait::async_trait; @@ -8,8 +9,6 @@ use dashmap::DashSet; use deno_ast::MediaType; use deno_config::workspace::MappedResolutionDiagnostic; use deno_config::workspace::MappedResolutionError; -use deno_core::anyhow::Context; -use deno_core::error::AnyError; use deno_core::url::Url; use deno_core::ModuleSourceCode; use deno_core::ModuleSpecifier; @@ -84,6 +83,62 @@ pub struct NpmModuleLoader { node_code_translator: Arc, } +#[derive(Debug, Error, deno_error::JsError)] +pub enum NpmModuleLoadError { + #[class(inherit)] + #[error(transparent)] + NotSupportedKindInNpm(#[from] NotSupportedKindInNpmError), + #[class(inherit)] + #[error(transparent)] + ClosestPkgJson(#[from] node_resolver::errors::ClosestPkgJsonError), + #[class(inherit)] + #[error(transparent)] + TranslateCjsToEsm(#[from] node_resolver::analyze::TranslateCjsToEsmError), + #[class(inherit)] + #[error("{}", format_message(file_path, maybe_referrer))] + Fs { + file_path: PathBuf, + maybe_referrer: Option, + #[source] + #[inherit] + source: deno_runtime::deno_io::fs::FsError, + }, +} + +fn format_message( + file_path: &std::path::Path, + maybe_referrer: &Option, +) -> String { + if file_path.is_dir() { + // directory imports are not allowed when importing from an + // ES module, so provide the user with a helpful error message + let dir_path = file_path; + let mut msg = "Directory import ".to_string(); + msg.push_str(&dir_path.to_string_lossy()); + if let Some(referrer) = maybe_referrer { + msg.push_str(" is not supported resolving import from "); + msg.push_str(referrer.as_str()); + let entrypoint_name = ["index.mjs", "index.js", "index.cjs"] + .iter() + .find(|e| dir_path.join(e).is_file()); + if let Some(entrypoint_name) = entrypoint_name { + msg.push_str("\nDid you mean to import "); + msg.push_str(entrypoint_name); + msg.push_str(" within the directory?"); + } + } + msg + } else { + let mut msg = "Unable to load ".to_string(); + msg.push_str(&file_path.to_string_lossy()); + if let Some(referrer) = maybe_referrer { + msg.push_str(" imported from "); + msg.push_str(referrer.as_str()); + } + msg + } +} + impl NpmModuleLoader { pub fn new( cjs_tracker: Arc, @@ -101,50 +156,26 @@ impl NpmModuleLoader { &self, specifier: &ModuleSpecifier, maybe_referrer: Option<&ModuleSpecifier>, - ) -> Result { + ) -> Result { let file_path = specifier.to_file_path().unwrap(); let code = self .fs .read_file_async(file_path.clone(), None) .await - .map_err(AnyError::from) - .with_context(|| { - if file_path.is_dir() { - // directory imports are not allowed when importing from an - // ES module, so provide the user with a helpful error message - let dir_path = file_path; - let mut msg = "Directory import ".to_string(); - msg.push_str(&dir_path.to_string_lossy()); - if let Some(referrer) = &maybe_referrer { - msg.push_str(" is not supported resolving import from "); - msg.push_str(referrer.as_str()); - let entrypoint_name = ["index.mjs", "index.js", "index.cjs"] - .iter() - .find(|e| dir_path.join(e).is_file()); - if let Some(entrypoint_name) = entrypoint_name { - msg.push_str("\nDid you mean to import "); - msg.push_str(entrypoint_name); - msg.push_str(" within the directory?"); - } - } - msg - } else { - let mut msg = "Unable to load ".to_string(); - msg.push_str(&file_path.to_string_lossy()); - if let Some(referrer) = &maybe_referrer { - msg.push_str(" imported from "); - msg.push_str(referrer.as_str()); - } - msg - } + .map_err(|source| NpmModuleLoadError::Fs { + file_path, + maybe_referrer: maybe_referrer.cloned(), + source, })?; let media_type = MediaType::from_specifier(specifier); if media_type.is_emittable() { - return Err(AnyError::from(NotSupportedKindInNpmError { - media_type, - specifier: specifier.clone(), - })); + return Err(NpmModuleLoadError::NotSupportedKindInNpm( + NotSupportedKindInNpmError { + media_type, + specifier: specifier.clone(), + }, + )); } let code = if self.cjs_tracker.is_maybe_cjs(specifier, media_type)? { diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs index 5334b4719d..54c82d17a3 100644 --- a/cli/standalone/binary.rs +++ b/cli/standalone/binary.rs @@ -37,6 +37,7 @@ use deno_core::futures::AsyncReadExt; use deno_core::futures::AsyncSeekExt; use deno_core::serde_json; use deno_core::url::Url; +use deno_error::JsErrorBox; use deno_graph::ModuleGraph; use deno_lib::cache::DenoDir; use deno_lib::standalone::virtual_fs::FileSystemCaseSensitivity; @@ -278,7 +279,7 @@ impl StandaloneModules { pub fn resolve_specifier<'a>( &'a self, specifier: &'a ModuleSpecifier, - ) -> Result, AnyError> { + ) -> Result, JsErrorBox> { if specifier.scheme() == "file" { Ok(Some(specifier)) } else { diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index f2a0859e8f..1ab77a5a4c 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -414,7 +414,8 @@ impl ModuleLoader for EmbeddedModuleLoader { let code_source = shared .npm_module_loader .load(&original_specifier, maybe_referrer.as_ref()) - .await?; + .await + .map_err(JsErrorBox::from_err)?; let code_cache_entry = shared.get_code_cache( &code_source.found_url, code_source.code.as_bytes(), @@ -477,7 +478,8 @@ impl ModuleLoader for EmbeddedModuleLoader { let source = shared .node_code_translator .translate_cjs_to_esm(&module_specifier, Some(source)) - .await?; + .await + .map_err(JsErrorBox::from_err)?; let module_source = match source { Cow::Owned(source) => ModuleSourceCode::String(source.into()), Cow::Borrowed(source) => { diff --git a/cli/standalone/serialization.rs b/cli/standalone/serialization.rs index ab345917a3..00a0a04997 100644 --- a/cli/standalone/serialization.rs +++ b/cli/standalone/serialization.rs @@ -17,6 +17,7 @@ use deno_core::url::Url; use deno_core::FastString; use deno_core::ModuleSourceCode; use deno_core::ModuleType; +use deno_error::JsErrorBox; use deno_lib::standalone::virtual_fs::VirtualDirectoryEntries; use deno_npm::resolution::SerializedNpmResolutionSnapshot; use deno_npm::resolution::SerializedNpmResolutionSnapshotPackage; @@ -441,12 +442,15 @@ impl RemoteModulesStore { pub fn resolve_specifier<'a>( &'a self, specifier: &'a Url, - ) -> Result, AnyError> { + ) -> Result, JsErrorBox> { let mut count = 0; let mut current = specifier; loop { if count > 10 { - bail!("Too many redirects resolving '{}'", specifier); + return Err(JsErrorBox::generic(format!( + "Too many redirects resolving '{}'", + specifier + ))); } match self.specifiers.get(current) { Some(RemoteModulesStoreSpecifierValue::Redirect(to)) => { diff --git a/cli/tools/bench/mod.rs b/cli/tools/bench/mod.rs index 6a57c4ce6c..a316e60b52 100644 --- a/cli/tools/bench/mod.rs +++ b/cli/tools/bench/mod.rs @@ -48,6 +48,7 @@ use crate::util::fs::collect_specifiers; use crate::util::path::is_script_ext; use crate::util::path::matches_pattern_or_exact_path; use crate::worker::CliMainWorkerFactory; +use crate::worker::CreateCustomWorkerError; mod mitata; mod reporters; @@ -164,7 +165,7 @@ async fn bench_specifier( .await { Ok(()) => Ok(()), - Err(CoreError::Js(error)) => { + Err(CreateCustomWorkerError::Core(CoreError::Js(error))) => { sender.send(BenchEvent::UncaughtError( specifier.to_string(), Box::new(error), @@ -182,7 +183,7 @@ async fn bench_specifier_inner( specifier: ModuleSpecifier, sender: &UnboundedSender, filter: TestFilter, -) -> Result<(), CoreError> { +) -> Result<(), CreateCustomWorkerError> { let mut worker = worker_factory .create_custom_worker( WorkerExecutionMode::Bench, @@ -201,7 +202,7 @@ async fn bench_specifier_inner( // Ensure that there are no pending exceptions before we start running tests worker.run_up_to_duration(Duration::from_millis(0)).await?; - worker.dispatch_load_event()?; + worker.dispatch_load_event().map_err(CoreError::Js)?; let benchmarks = { let state_rc = worker.js_runtime.op_state(); @@ -236,11 +237,13 @@ async fn bench_specifier_inner( used_only, names: benchmarks.iter().map(|(d, _)| d.name.clone()).collect(), })) - .map_err(JsErrorBox::from_err)?; + .map_err(JsErrorBox::from_err) + .map_err(CoreError::JsBox)?; for (desc, function) in benchmarks { sender .send(BenchEvent::Wait(desc.id)) - .map_err(JsErrorBox::from_err)?; + .map_err(JsErrorBox::from_err) + .map_err(CoreError::JsBox)?; let call = worker.js_runtime.call(&function); let result = worker .js_runtime @@ -249,18 +252,26 @@ async fn bench_specifier_inner( let scope = &mut worker.js_runtime.handle_scope(); let result = v8::Local::new(scope, result); let result = serde_v8::from_v8::(scope, result) - .map_err(JsErrorBox::from_err)?; + .map_err(JsErrorBox::from_err) + .map_err(CoreError::JsBox)?; sender .send(BenchEvent::Result(desc.id, result)) - .map_err(JsErrorBox::from_err)?; + .map_err(JsErrorBox::from_err) + .map_err(CoreError::JsBox)?; } // Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the // event loop to continue beyond what's needed to await results. - worker.dispatch_beforeunload_event()?; - worker.dispatch_process_beforeexit_event()?; - worker.dispatch_unload_event()?; - worker.dispatch_process_exit_event()?; + worker + .dispatch_beforeunload_event() + .map_err(CoreError::Js)?; + worker + .dispatch_process_beforeexit_event() + .map_err(CoreError::Js)?; + worker.dispatch_unload_event().map_err(CoreError::Js)?; + worker + .dispatch_process_exit_event() + .map_err(CoreError::Js)?; // Ensure the worker has settled so we can catch any remaining unhandled rejections. We don't // want to wait forever here. diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs index 9b6ef81ea3..53c08191f7 100644 --- a/cli/tools/coverage/mod.rs +++ b/cli/tools/coverage/mod.rs @@ -18,10 +18,12 @@ use deno_config::glob::PathOrPatternSet; use deno_core::anyhow::anyhow; use deno_core::anyhow::Context; use deno_core::error::AnyError; +use deno_core::error::CoreError; use deno_core::serde_json; use deno_core::sourcemap::SourceMap; use deno_core::url::Url; use deno_core::LocalInspectorSession; +use deno_error::JsErrorBox; use deno_resolver::npm::DenoInNpmPackageChecker; use node_resolver::InNpmPackageChecker; use regex::Regex; @@ -53,7 +55,7 @@ pub struct CoverageCollector { #[async_trait::async_trait(?Send)] impl crate::worker::CoverageCollector for CoverageCollector { - async fn start_collecting(&mut self) -> Result<(), AnyError> { + async fn start_collecting(&mut self) -> Result<(), CoreError> { self.enable_debugger().await?; self.enable_profiler().await?; self @@ -67,7 +69,7 @@ impl crate::worker::CoverageCollector for CoverageCollector { Ok(()) } - async fn stop_collecting(&mut self) -> Result<(), AnyError> { + async fn stop_collecting(&mut self) -> Result<(), CoreError> { fs::create_dir_all(&self.dir)?; let script_coverages = self.take_precise_coverage().await?.result; @@ -88,7 +90,8 @@ impl crate::worker::CoverageCollector for CoverageCollector { let filepath = self.dir.join(filename); let mut out = BufWriter::new(File::create(&filepath)?); - let coverage = serde_json::to_string(&script_coverage)?; + let coverage = serde_json::to_string(&script_coverage) + .map_err(JsErrorBox::from_err)?; let formatted_coverage = format_json(&filepath, &coverage, &Default::default()) .ok() @@ -111,7 +114,7 @@ impl CoverageCollector { Self { dir, session } } - async fn enable_debugger(&mut self) -> Result<(), AnyError> { + async fn enable_debugger(&mut self) -> Result<(), CoreError> { self .session .post_message::<()>("Debugger.enable", None) @@ -119,7 +122,7 @@ impl CoverageCollector { Ok(()) } - async fn enable_profiler(&mut self) -> Result<(), AnyError> { + async fn enable_profiler(&mut self) -> Result<(), CoreError> { self .session .post_message::<()>("Profiler.enable", None) @@ -127,7 +130,7 @@ impl CoverageCollector { Ok(()) } - async fn disable_debugger(&mut self) -> Result<(), AnyError> { + async fn disable_debugger(&mut self) -> Result<(), CoreError> { self .session .post_message::<()>("Debugger.disable", None) @@ -135,7 +138,7 @@ impl CoverageCollector { Ok(()) } - async fn disable_profiler(&mut self) -> Result<(), AnyError> { + async fn disable_profiler(&mut self) -> Result<(), CoreError> { self .session .post_message::<()>("Profiler.disable", None) @@ -146,26 +149,28 @@ impl CoverageCollector { async fn start_precise_coverage( &mut self, parameters: cdp::StartPreciseCoverageArgs, - ) -> Result { + ) -> Result { let return_value = self .session .post_message("Profiler.startPreciseCoverage", Some(parameters)) .await?; - let return_object = serde_json::from_value(return_value)?; + let return_object = + serde_json::from_value(return_value).map_err(JsErrorBox::from_err)?; Ok(return_object) } async fn take_precise_coverage( &mut self, - ) -> Result { + ) -> Result { let return_value = self .session .post_message::<()>("Profiler.takePreciseCoverage", None) .await?; - let return_object = serde_json::from_value(return_value)?; + let return_object = + serde_json::from_value(return_value).map_err(JsErrorBox::from_err)?; Ok(return_object) } diff --git a/cli/tools/test/mod.rs b/cli/tools/test/mod.rs index 21ee7e152d..cb49a9de95 100644 --- a/cli/tools/test/mod.rs +++ b/cli/tools/test/mod.rs @@ -87,6 +87,7 @@ use crate::util::path::is_script_ext; use crate::util::path::matches_pattern_or_exact_path; use crate::worker::CliMainWorkerFactory; use crate::worker::CoverageCollector; +use crate::worker::CreateCustomWorkerError; mod channel; pub mod fmt; @@ -614,7 +615,10 @@ async fn configure_main_worker( permissions_container: PermissionsContainer, worker_sender: TestEventWorkerSender, options: &TestSpecifierOptions, -) -> Result<(Option>, MainWorker), CoreError> { +) -> Result< + (Option>, MainWorker), + CreateCustomWorkerError, +> { let mut worker = worker_factory .create_custom_worker( WorkerExecutionMode::Test, @@ -647,7 +651,7 @@ async fn configure_main_worker( &worker.js_runtime.op_state(), TestEvent::UncaughtError(specifier.to_string(), Box::new(err)), ) - .map_err(JsErrorBox::from_err)?; + .map_err(|e| CoreError::JsBox(JsErrorBox::from_err(e)))?; Ok(()) } Err(err) => Err(err), @@ -687,7 +691,7 @@ pub async fn test_specifier( .await { Ok(()) => Ok(()), - Err(CoreError::Js(err)) => { + Err(TestSpecifierError::Core(CoreError::Js(err))) => { send_test_event( &worker.js_runtime.op_state(), TestEvent::UncaughtError(specifier.to_string(), Box::new(err)), @@ -698,6 +702,16 @@ pub async fn test_specifier( } } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum TestSpecifierError { + #[class(inherit)] + #[error(transparent)] + Core(#[from] CoreError), + #[class(inherit)] + #[error(transparent)] + RunTestsForWorker(#[from] RunTestsForWorkerErr), +} + /// Test a single specifier as documentation containing test programs, an executable test module or /// both. #[allow(clippy::too_many_arguments)] @@ -707,19 +721,21 @@ async fn test_specifier_inner( specifier: ModuleSpecifier, fail_fast_tracker: FailFastTracker, options: TestSpecifierOptions, -) -> Result<(), CoreError> { +) -> Result<(), TestSpecifierError> { // Ensure that there are no pending exceptions before we start running tests worker.run_up_to_duration(Duration::from_millis(0)).await?; - worker.dispatch_load_event()?; + worker.dispatch_load_event().map_err(CoreError::Js)?; run_tests_for_worker(worker, &specifier, &options, &fail_fast_tracker) .await?; // Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the // event loop to continue beyond what's needed to await results. - worker.dispatch_beforeunload_event()?; - worker.dispatch_unload_event()?; + worker + .dispatch_beforeunload_event() + .map_err(CoreError::Js)?; + worker.dispatch_unload_event().map_err(CoreError::Js)?; // Ensure all output has been flushed _ = worker @@ -780,12 +796,25 @@ pub fn send_test_event( .send(event) } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum RunTestsForWorkerErr { + #[class(inherit)] + #[error(transparent)] + ChannelClosed(#[from] ChannelClosedError), + #[class(inherit)] + #[error(transparent)] + Core(#[from] CoreError), + #[class(inherit)] + #[error(transparent)] + SerdeV8(#[from] serde_v8::Error), +} + pub async fn run_tests_for_worker( worker: &mut MainWorker, specifier: &ModuleSpecifier, options: &TestSpecifierOptions, fail_fast_tracker: &FailFastTracker, -) -> Result<(), AnyError> { +) -> Result<(), RunTestsForWorkerErr> { let state_rc = worker.js_runtime.op_state(); // Take whatever tests have been registered let TestContainer(tests, test_functions) = @@ -814,7 +843,7 @@ async fn run_tests_for_worker_inner( test_functions: Vec>, options: &TestSpecifierOptions, fail_fast_tracker: &FailFastTracker, -) -> Result<(), AnyError> { +) -> Result<(), RunTestsForWorkerErr> { let unfiltered = tests.len(); let state_rc = worker.js_runtime.op_state(); @@ -1109,7 +1138,7 @@ async fn wait_for_activity_to_stabilize( before: RuntimeActivityStats, sanitize_ops: bool, sanitize_resources: bool, -) -> Result, AnyError> { +) -> Result, CoreError> { // First, check to see if there's any diff at all. If not, just continue. let after = stats.clone().capture(filter); let mut diff = RuntimeActivityStats::diff(&before, &after); diff --git a/cli/util/result.rs b/cli/util/result.rs index 0c1a75b1ce..e6d45be470 100644 --- a/cli/util/result.rs +++ b/cli/util/result.rs @@ -36,7 +36,7 @@ pub fn any_and_jserrorbox_downcast_ref< }) .or_else(|| { err.downcast_ref::().and_then(|e| match e { - CoreError::JsNative(e) => e.as_any().downcast_ref::(), + CoreError::JsBox(e) => e.as_any().downcast_ref::(), _ => None, }) }) diff --git a/cli/worker.rs b/cli/worker.rs index cf301de83e..3a11f56c71 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -4,8 +4,6 @@ use std::path::Path; use std::sync::Arc; use deno_ast::ModuleSpecifier; -use deno_core::anyhow::bail; -use deno_core::error::AnyError; use deno_core::error::CoreError; use deno_core::futures::FutureExt; use deno_core::v8; @@ -19,6 +17,7 @@ use deno_runtime::deno_permissions::PermissionsContainer; use deno_runtime::worker::MainWorker; use deno_runtime::WorkerExecutionMode; use deno_semver::npm::NpmPackageReqReference; +use node_resolver::errors::ResolvePkgJsonBinExportError; use node_resolver::NodeResolutionKind; use node_resolver::ResolutionMode; use sys_traits::EnvCurrentDir; @@ -52,8 +51,8 @@ pub trait CliCodeCache: code_cache::CodeCache { #[async_trait::async_trait(?Send)] pub trait CoverageCollector: Send + Sync { - async fn start_collecting(&mut self) -> Result<(), AnyError>; - async fn stop_collecting(&mut self) -> Result<(), AnyError>; + async fn start_collecting(&mut self) -> Result<(), CoreError>; + async fn stop_collecting(&mut self) -> Result<(), CoreError>; } pub type CreateHmrRunnerCb = Box< @@ -91,7 +90,7 @@ impl CliMainWorker { self.worker.into_main_worker() } - pub async fn setup_repl(&mut self) -> Result<(), AnyError> { + pub async fn setup_repl(&mut self) -> Result<(), CoreError> { self.worker.run_event_loop(false).await?; Ok(()) } @@ -172,7 +171,7 @@ impl CliMainWorker { Ok(self.worker.exit_code()) } - pub async fn run_for_watcher(self) -> Result<(), AnyError> { + pub async fn run_for_watcher(self) -> Result<(), CoreError> { /// The FileWatcherModuleExecutor provides module execution with safe dispatching of life-cycle events by tracking the /// state of any pending events and emitting accordingly on drop in the case of a future /// cancellation. @@ -191,7 +190,7 @@ impl CliMainWorker { /// Execute the given main module emitting load and unload events before and after execution /// respectively. - pub async fn execute(&mut self) -> Result<(), AnyError> { + pub async fn execute(&mut self) -> Result<(), CoreError> { self.inner.execute_main_module().await?; self.inner.worker.dispatch_load_event()?; self.pending_unload = true; @@ -245,7 +244,7 @@ impl CliMainWorker { pub async fn maybe_setup_hmr_runner( &mut self, - ) -> Result>, AnyError> { + ) -> Result>, CoreError> { let Some(setup_hmr_runner) = self.shared.create_hmr_runner.as_ref() else { return Ok(None); }; @@ -267,7 +266,7 @@ impl CliMainWorker { pub async fn maybe_setup_coverage_collector( &mut self, - ) -> Result>, AnyError> { + ) -> Result>, CoreError> { let Some(create_coverage_collector) = self.shared.create_coverage_collector.as_ref() else { @@ -296,6 +295,58 @@ impl CliMainWorker { } } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum ResolveBinaryEntrypointError { + #[class(inherit)] + #[error(transparent)] + ResolvePkgJsonBinExport(ResolvePkgJsonBinExportError), + #[class(generic)] + #[error("{original:#}\n\nFallback failed: {fallback:#}")] + Fallback { + fallback: ResolveBinaryEntrypointFallbackError, + original: ResolvePkgJsonBinExportError, + }, +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum ResolveBinaryEntrypointFallbackError { + #[class(inherit)] + #[error(transparent)] + PackageSubpathResolve(node_resolver::errors::PackageSubpathResolveError), + #[class(generic)] + #[error("Cannot find module '{0}'")] + ModuleNotFound(ModuleSpecifier), +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum CreateCustomWorkerError { + #[class(inherit)] + #[error(transparent)] + Io(#[from] std::io::Error), + #[class(inherit)] + #[error(transparent)] + Core(#[from] CoreError), + #[class(inherit)] + #[error(transparent)] + ResolvePkgFolderFromDenoReq( + #[from] deno_resolver::npm::ResolvePkgFolderFromDenoReqError, + ), + #[class(inherit)] + #[error(transparent)] + UrlParse(#[from] deno_core::url::ParseError), + #[class(inherit)] + #[error(transparent)] + ResolveBinaryEntrypoint(#[from] ResolveBinaryEntrypointError), + #[class(inherit)] + #[error(transparent)] + NpmPackageReq(JsErrorBox), + #[class(inherit)] + #[error(transparent)] + AtomicWriteFileWithRetries( + #[from] crate::args::AtomicWriteFileWithRetriesError, + ), +} + pub struct CliMainWorkerFactory { lib_main_worker_factory: LibMainWorkerFactory, maybe_lockfile: Option>, @@ -344,7 +395,7 @@ impl CliMainWorkerFactory { &self, mode: WorkerExecutionMode, main_module: ModuleSpecifier, - ) -> Result { + ) -> Result { self .create_custom_worker( mode, @@ -363,7 +414,7 @@ impl CliMainWorkerFactory { permissions: PermissionsContainer, custom_extensions: Vec, stdio: deno_runtime::deno_io::Stdio, - ) -> Result { + ) -> Result { let main_module = if let Ok(package_ref) = NpmPackageReqReference::from_specifier(&main_module) { @@ -381,19 +432,20 @@ impl CliMainWorkerFactory { PackageCaching::All }, ) - .await?; + .await + .map_err(CreateCustomWorkerError::NpmPackageReq)?; } // use a fake referrer that can be used to discover the package.json if necessary - let referrer = ModuleSpecifier::from_directory_path( - self.sys.env_current_dir().map_err(JsErrorBox::from_err)?, - ) - .unwrap() - .join("package.json")?; - let package_folder = self - .npm_resolver - .resolve_pkg_folder_from_deno_module_req(package_ref.req(), &referrer) - .map_err(JsErrorBox::from_err)?; + let referrer = + ModuleSpecifier::from_directory_path(self.sys.env_current_dir()?) + .unwrap() + .join("package.json")?; + let package_folder = + self.npm_resolver.resolve_pkg_folder_from_deno_module_req( + package_ref.req(), + &referrer, + )?; let main_module = self .resolve_binary_entrypoint(&package_folder, package_ref.sub_path())?; @@ -447,7 +499,7 @@ impl CliMainWorkerFactory { &self, package_folder: &Path, sub_path: Option<&str>, - ) -> Result { + ) -> Result { match self .node_resolver .resolve_binary_export(package_folder, sub_path) @@ -459,10 +511,13 @@ impl CliMainWorkerFactory { self.resolve_binary_entrypoint_fallback(package_folder, sub_path); match result { Ok(Some(specifier)) => Ok(specifier), - Ok(None) => Err(original_err.into()), - Err(fallback_err) => { - bail!("{:#}\n\nFallback failed: {:#}", original_err, fallback_err) - } + Ok(None) => Err( + ResolveBinaryEntrypointError::ResolvePkgJsonBinExport(original_err), + ), + Err(fallback_err) => Err(ResolveBinaryEntrypointError::Fallback { + original: original_err, + fallback: fallback_err, + }), } } } @@ -473,7 +528,7 @@ impl CliMainWorkerFactory { &self, package_folder: &Path, sub_path: Option<&str>, - ) -> Result, AnyError> { + ) -> Result, ResolveBinaryEntrypointFallbackError> { // only fallback if the user specified a sub path if sub_path.is_none() { // it's confusing to users if the package doesn't have any binary @@ -490,7 +545,8 @@ impl CliMainWorkerFactory { /* referrer */ None, ResolutionMode::Import, NodeResolutionKind::Execution, - )?; + ) + .map_err(ResolveBinaryEntrypointFallbackError::PackageSubpathResolve)?; if specifier .to_file_path() .map(|p| p.exists()) @@ -498,7 +554,9 @@ impl CliMainWorkerFactory { { Ok(Some(specifier)) } else { - bail!("Cannot find module '{}'", specifier) + Err(ResolveBinaryEntrypointFallbackError::ModuleNotFound( + specifier, + )) } } } diff --git a/ext/net/quic.rs b/ext/net/quic.rs index e075745495..af13a3f009 100644 --- a/ext/net/quic.rs +++ b/ext/net/quic.rs @@ -99,9 +99,6 @@ pub enum QuicError { #[class(range)] #[error("Connection has reached the maximum number of concurrent outgoing {0} streams")] MaxStreams(&'static str), - #[class(generic)] - #[error("{0}")] - Core(#[from] deno_core::error::AnyError), #[class(inherit)] #[error(transparent)] Other(#[from] JsErrorBox), diff --git a/ext/node/ops/require.rs b/ext/node/ops/require.rs index bff0cd79ed..c0e54993ae 100644 --- a/ext/node/ops/require.rs +++ b/ext/node/ops/require.rs @@ -106,10 +106,15 @@ pub enum RequireErrorKind { JsErrorBox, ), #[class(inherit)] - #[error("Unable to get CWD: {0}")] - UnableToGetCwd(#[inherit] std::io::Error), + #[error(transparent)] + UnableToGetCwd(UnableToGetCwdError), } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[error("Unable to get CWD")] +#[class(inherit)] +pub struct UnableToGetCwdError(#[source] pub std::io::Error); + #[op2] #[serde] pub fn op_require_init_paths() -> Vec { @@ -177,7 +182,7 @@ pub fn op_require_node_module_paths< } else { let current_dir = &sys .env_current_dir() - .map_err(RequireErrorKind::UnableToGetCwd)?; + .map_err(|e| RequireErrorKind::UnableToGetCwd(UnableToGetCwdError(e)))?; normalize_path(current_dir.join(from)) }; diff --git a/resolvers/node/analyze.rs b/resolvers/node/analyze.rs index e144e2b8fb..a67023d1e1 100644 --- a/resolvers/node/analyze.rs +++ b/resolvers/node/analyze.rs @@ -6,8 +6,7 @@ use std::collections::HashSet; use std::path::Path; use std::path::PathBuf; -use anyhow::Context; -use anyhow::Error as AnyError; +use deno_error::JsErrorBox; use deno_path_util::url_from_file_path; use deno_path_util::url_to_file_path; use futures::future::LocalBoxFuture; @@ -43,6 +42,16 @@ pub struct CjsAnalysisExports { pub reexports: Vec, } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum CjsCodeAnalysisError { + #[class(inherit)] + #[error(transparent)] + ClosestPkgJson(#[from] crate::errors::ClosestPkgJsonError), + #[class(inherit)] + #[error(transparent)] + Other(#[from] JsErrorBox), +} + /// Code analyzer for CJS and ESM files. #[async_trait::async_trait(?Send)] pub trait CjsCodeAnalyzer { @@ -57,7 +66,28 @@ pub trait CjsCodeAnalyzer { &self, specifier: &Url, maybe_source: Option>, - ) -> Result, AnyError>; + ) -> Result, CjsCodeAnalysisError>; +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum TranslateCjsToEsmError { + #[class(inherit)] + #[error(transparent)] + CjsCodeAnalysis(#[from] CjsCodeAnalysisError), + #[class(inherit)] + #[error(transparent)] + ExportAnalysis(#[from] JsErrorBox), +} + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +#[class(generic)] +#[error("Could not load '{reexport}' ({reexport_specifier}) referenced from {referrer}")] +pub struct CjsAnalysisCouldNotLoadError { + reexport: String, + reexport_specifier: Url, + referrer: Url, + #[source] + source: CjsCodeAnalysisError, } pub struct NodeCodeTranslator< @@ -128,7 +158,7 @@ impl< &self, entry_specifier: &Url, source: Option>, - ) -> Result, AnyError> { + ) -> Result, TranslateCjsToEsmError> { let mut temp_var_count = 0; let analysis = self @@ -164,7 +194,7 @@ impl< // surface errors afterwards in a deterministic way if !errors.is_empty() { errors.sort_by_cached_key(|e| e.to_string()); - return Err(errors.remove(0)); + return Err(TranslateCjsToEsmError::ExportAnalysis(errors.remove(0))); } } @@ -208,7 +238,7 @@ impl< all_exports: &mut BTreeSet, // this goes through the modules concurrently, so collect // the errors in order to be deterministic - errors: &mut Vec, + errors: &mut Vec, ) { struct Analysis { reexport_specifier: url::Url, @@ -216,7 +246,7 @@ impl< analysis: CjsAnalysis<'static>, } - type AnalysisFuture<'a> = LocalBoxFuture<'a, Result>; + type AnalysisFuture<'a> = LocalBoxFuture<'a, Result>; let mut handled_reexports: HashSet = HashSet::default(); handled_reexports.insert(entry_specifier.clone()); @@ -227,7 +257,7 @@ impl< |referrer: url::Url, reexports: Vec, analyze_futures: &mut FuturesUnordered>, - errors: &mut Vec| { + errors: &mut Vec| { // 1. Resolve the re-exports and start a future to analyze each one for reexport in reexports { let result = self.resolve( @@ -256,11 +286,13 @@ impl< let analysis = cjs_code_analyzer .analyze_cjs(&reexport_specifier, None) .await - .with_context(|| { - format!( - "Could not load '{}' ({}) referenced from {}", - reexport, reexport_specifier, referrer - ) + .map_err(|source| { + JsErrorBox::from_err(CjsAnalysisCouldNotLoadError { + reexport, + reexport_specifier: reexport_specifier.clone(), + referrer: referrer.clone(), + source, + }) })?; Ok(Analysis { @@ -297,11 +329,10 @@ impl< match analysis { CjsAnalysis::Esm(_) => { // todo(dsherret): support this once supporting requiring ES modules - errors.push(anyhow::anyhow!( + errors.push(JsErrorBox::generic(format!( "Cannot require ES module '{}' from '{}'", - reexport_specifier, - referrer, - )); + reexport_specifier, referrer, + ))); } CjsAnalysis::Cjs(analysis) => { if !analysis.reexports.is_empty() { @@ -331,7 +362,7 @@ impl< referrer: &Url, conditions: &[&str], resolution_kind: NodeResolutionKind, - ) -> Result, AnyError> { + ) -> Result, JsErrorBox> { if specifier.starts_with('/') { todo!(); } @@ -341,7 +372,7 @@ impl< if let Some(parent) = referrer_path.parent() { return self .file_extension_probe(parent.join(specifier), &referrer_path) - .and_then(|p| url_from_file_path(&p).map_err(AnyError::from)) + .and_then(|p| url_from_file_path(&p).map_err(JsErrorBox::from_err)) .map(Some); } else { todo!(); @@ -364,13 +395,14 @@ impl< { return Ok(None); } - other => other, - }?; + other => other.map_err(JsErrorBox::from_err)?, + }; let package_json_path = module_dir.join("package.json"); let maybe_package_json = self .pkg_json_resolver - .load_package_json(&package_json_path)?; + .load_package_json(&package_json_path) + .map_err(JsErrorBox::from_err)?; if let Some(package_json) = maybe_package_json { if let Some(exports) = &package_json.exports { return Some( @@ -385,7 +417,7 @@ impl< conditions, resolution_kind, ) - .map_err(AnyError::from), + .map_err(JsErrorBox::from_err), ) .transpose(); } @@ -398,29 +430,40 @@ impl< let package_json_path = d.join("package.json"); let maybe_package_json = self .pkg_json_resolver - .load_package_json(&package_json_path)?; + .load_package_json(&package_json_path) + .map_err(JsErrorBox::from_err)?; if let Some(package_json) = maybe_package_json { if let Some(main) = package_json.main(deno_package_json::NodeModuleKind::Cjs) { - return Ok(Some(url_from_file_path(&d.join(main).clean())?)); + return Ok(Some( + url_from_file_path(&d.join(main).clean()) + .map_err(JsErrorBox::from_err)?, + )); } } - return Ok(Some(url_from_file_path(&d.join("index.js").clean())?)); + return Ok(Some( + url_from_file_path(&d.join("index.js").clean()) + .map_err(JsErrorBox::from_err)?, + )); } return self .file_extension_probe(d, &referrer_path) - .and_then(|p| url_from_file_path(&p).map_err(AnyError::from)) + .and_then(|p| url_from_file_path(&p).map_err(JsErrorBox::from_err)) .map(Some); } else if let Some(main) = package_json.main(deno_package_json::NodeModuleKind::Cjs) { - return Ok(Some(url_from_file_path(&module_dir.join(main).clean())?)); + return Ok(Some( + url_from_file_path(&module_dir.join(main).clean()) + .map_err(JsErrorBox::from_err)?, + )); } else { - return Ok(Some(url_from_file_path( - &module_dir.join("index.js").clean(), - )?)); + return Ok(Some( + url_from_file_path(&module_dir.join("index.js").clean()) + .map_err(JsErrorBox::from_err)?, + )); } } @@ -436,7 +479,9 @@ impl< parent.join("node_modules").join(specifier) }; if let Ok(path) = self.file_extension_probe(path, &referrer_path) { - return Ok(Some(url_from_file_path(&path)?)); + return Ok(Some( + url_from_file_path(&path).map_err(JsErrorBox::from_err)?, + )); } last = parent; } @@ -448,7 +493,7 @@ impl< &self, p: PathBuf, referrer: &Path, - ) -> Result { + ) -> Result { let p = p.clean(); if self.sys.fs_exists_no_err(&p) { let file_name = p.file_name().unwrap(); @@ -638,13 +683,13 @@ fn parse_specifier(specifier: &str) -> Option<(String, String)> { Some((package_name, package_subpath)) } -fn not_found(path: &str, referrer: &Path) -> AnyError { +fn not_found(path: &str, referrer: &Path) -> JsErrorBox { let msg = format!( "[ERR_MODULE_NOT_FOUND] Cannot find module \"{}\" imported from \"{}\"", path, referrer.to_string_lossy() ); - std::io::Error::new(std::io::ErrorKind::NotFound, msg).into() + JsErrorBox::from_err(std::io::Error::new(std::io::ErrorKind::NotFound, msg)) } fn to_double_quote_string(text: &str) -> String { diff --git a/runtime/fs_util.rs b/runtime/fs_util.rs index 7788a97170..5dca3a55ee 100644 --- a/runtime/fs_util.rs +++ b/runtime/fs_util.rs @@ -4,11 +4,12 @@ use std::path::Path; use std::path::PathBuf; use deno_core::anyhow::Context; -use deno_core::error::AnyError; use deno_path_util::normalize_path; #[inline] -pub fn resolve_from_cwd(path: &Path) -> Result { +pub fn resolve_from_cwd( + path: &Path, +) -> Result { if path.is_absolute() { Ok(normalize_path(path)) } else { diff --git a/runtime/inspector_server.rs b/runtime/inspector_server.rs index 75e9668db4..cf043c97ac 100644 --- a/runtime/inspector_server.rs +++ b/runtime/inspector_server.rs @@ -10,8 +10,6 @@ use std::process; use std::rc::Rc; use std::thread; -use deno_core::anyhow::Context; -use deno_core::error::AnyError; use deno_core::futures::channel::mpsc; use deno_core::futures::channel::mpsc::UnboundedReceiver; use deno_core::futures::channel::mpsc::UnboundedSender; @@ -49,17 +47,33 @@ pub struct InspectorServer { thread_handle: Option>, } +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum InspectorServerError { + #[class(inherit)] + #[error(transparent)] + Io(#[from] std::io::Error), + #[class(inherit)] + #[error("Failed to start inspector server at \"{host}\"")] + Connect { + host: SocketAddr, + #[source] + #[inherit] + source: std::io::Error, + }, +} + impl InspectorServer { - pub fn new(host: SocketAddr, name: &'static str) -> Result { + pub fn new( + host: SocketAddr, + name: &'static str, + ) -> Result { let (register_inspector_tx, register_inspector_rx) = mpsc::unbounded::(); let (shutdown_server_tx, shutdown_server_rx) = broadcast::channel(1); - let tcp_listener = - std::net::TcpListener::bind(host).with_context(|| { - format!("Failed to start inspector server at \"{}\"", host) - })?; + let tcp_listener = std::net::TcpListener::bind(host) + .map_err(|source| InspectorServerError::Connect { host, source })?; tcp_listener.set_nonblocking(true)?; let thread_handle = thread::spawn(move || {

OEfUU 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