1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat(unstable): initial support for npm specifiers (#15484)

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
David Sherret 2022-08-20 11:31:33 -04:00 committed by GitHub
parent 1ffbd56164
commit 87f80ff6be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
92 changed files with 65674 additions and 352 deletions

4
Cargo.lock generated
View file

@ -834,6 +834,7 @@ dependencies = [
"notify",
"once_cell",
"os_pipe",
"path-clean",
"percent-encoding 2.1.0",
"pin-project",
"pretty_assertions",
@ -1140,6 +1141,8 @@ name = "deno_node"
version = "0.2.0"
dependencies = [
"deno_core",
"regex",
"serde",
]
[[package]]
@ -4601,6 +4604,7 @@ dependencies = [
"pretty_assertions",
"pty",
"regex",
"reqwest",
"rustls-pemfile 1.0.0",
"serde",
"serde_json",

View file

@ -83,6 +83,7 @@ node_resolver = "=0.1.1"
notify = "=5.0.0-pre.15"
once_cell = "=1.12.0"
os_pipe = "=1.0.1"
path-clean = "=0.1.0"
percent-encoding = "=2.1.0"
pin-project = "1.0.11" # don't pin because they yank crates from cargo
rand = { version = "=0.8.5", features = ["small_rng"] }

17
cli/cache/mod.rs vendored
View file

@ -2,7 +2,9 @@
use crate::errors::get_error_class_name;
use crate::file_fetcher::FileFetcher;
use crate::npm;
use deno_core::futures;
use deno_core::futures::FutureExt;
use deno_core::ModuleSpecifier;
use deno_graph::source::CacheInfo;
@ -53,6 +55,10 @@ impl FetchCacher {
impl Loader for FetchCacher {
fn get_cache_info(&self, specifier: &ModuleSpecifier) -> Option<CacheInfo> {
if specifier.scheme() == "npm" {
return None;
}
let local = self.file_fetcher.get_local_path(specifier)?;
if local.is_file() {
let emit = self
@ -74,6 +80,17 @@ impl Loader for FetchCacher {
specifier: &ModuleSpecifier,
is_dynamic: bool,
) -> LoadFuture {
if specifier.scheme() == "npm" {
return Box::pin(futures::future::ready(
match npm::NpmPackageReference::from_specifier(specifier) {
Ok(_) => Ok(Some(deno_graph::source::LoadResponse::External {
specifier: specifier.clone(),
})),
Err(err) => Err(err),
},
));
}
let specifier = specifier.clone();
let mut permissions = if is_dynamic {
self.dynamic_permissions.clone()

View file

@ -11,6 +11,7 @@ use deno_core::url::Url;
use deno_core::ModuleSpecifier;
use deno_graph::source::ResolveResponse;
use deno_graph::source::Resolver;
use deno_runtime::deno_node::DEFAULT_CONDITIONS;
use regex::Regex;
use std::path::PathBuf;
@ -74,8 +75,6 @@ impl Resolver for NodeEsmResolver {
}
}
static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"];
/// This function is an implementation of `defaultResolve` in
/// `lib/internal/modules/esm/resolve.js` from Node.
fn node_resolve(

View file

@ -1,6 +1,6 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
mod errors;
pub mod errors;
mod esm_resolver;
use crate::file_fetcher::FileFetcher;
@ -75,15 +75,15 @@ static NODE_COMPAT_URL: Lazy<String> = Lazy::new(|| {
static GLOBAL_URL_STR: Lazy<String> =
Lazy::new(|| format!("{}node/global.ts", NODE_COMPAT_URL.as_str()));
static PROCESS_URL_STR: Lazy<String> =
Lazy::new(|| format!("{}node/process.ts", NODE_COMPAT_URL.as_str()));
pub static GLOBAL_URL: Lazy<Url> =
Lazy::new(|| Url::parse(&GLOBAL_URL_STR).unwrap());
static MODULE_URL_STR: Lazy<String> =
Lazy::new(|| format!("{}node/module.ts", NODE_COMPAT_URL.as_str()));
pub static MODULE_ALL_URL: Lazy<Url> =
Lazy::new(|| Url::parse(&MODULE_ALL_URL_STR).unwrap());
static MODULE_ALL_URL_STR: Lazy<String> =
Lazy::new(|| format!("{}node/module_all.ts", NODE_COMPAT_URL.as_str()));
@ -98,7 +98,7 @@ pub fn get_node_imports() -> Vec<(Url, Vec<String>)> {
vec![(COMPAT_IMPORT_URL.clone(), vec![GLOBAL_URL_STR.clone()])]
}
fn try_resolve_builtin_module(specifier: &str) -> Option<Url> {
pub fn try_resolve_builtin_module(specifier: &str) -> Option<Url> {
if SUPPORTED_MODULES.contains(&specifier) {
let ext = match specifier {
"stream/promises" => "mjs",
@ -112,28 +112,6 @@ fn try_resolve_builtin_module(specifier: &str) -> Option<Url> {
}
}
#[allow(unused)]
pub async fn load_builtin_node_modules(
js_runtime: &mut JsRuntime,
) -> Result<(), AnyError> {
let source_code = &format!(
r#"(async function loadBuiltinNodeModules(moduleAllUrl, processUrl) {{
const [moduleAll, processModule] = await Promise.all([
import(moduleAllUrl),
import(processUrl)
]);
Deno[Deno.internal].require.initializeCommonJs(moduleAll.default, processModule.default);
}})('{}', '{}');"#,
MODULE_ALL_URL_STR.as_str(),
PROCESS_URL_STR.as_str(),
);
let value =
js_runtime.execute_script(&located_script_name!(), source_code)?;
js_runtime.resolve_value(value).await?;
Ok(())
}
#[allow(unused)]
pub fn load_cjs_module_from_ext_node(
js_runtime: &mut JsRuntime,
@ -214,7 +192,7 @@ pub fn setup_builtin_modules(
/// For all discovered reexports the analysis will be performed recursively.
///
/// If successful a source code for equivalent ES module is returned.
pub async fn translate_cjs_to_esm(
pub fn translate_cjs_to_esm(
file_fetcher: &FileFetcher,
specifier: &ModuleSpecifier,
code: String,
@ -271,7 +249,7 @@ pub async fn translate_cjs_to_esm(
// TODO(bartlomieju): Node actually checks if a given export exists in `exports` object,
// but it might not be necessary here since our analysis is more detailed?
source.push(format!(
"export const {} = reexport{}.{};",
"export const {0} = Deno[Deno.internal].require.bindExport(reexport{1}.{2}, reexport{1});",
export, idx, export
));
}
@ -294,7 +272,10 @@ pub async fn translate_cjs_to_esm(
for export in analysis.exports.iter().filter(|e| e.as_str() != "default") {
// TODO(bartlomieju): Node actually checks if a given export exists in `exports` object,
// but it might not be necessary here since our analysis is more detailed?
source.push(format!("export const {} = mod.{};", export, export));
source.push(format!(
"export const {} = Deno[Deno.internal].require.bindExport(mod.{}, mod);",
export, export
));
}
let translated_source = source.join("\n");

View file

@ -3,6 +3,8 @@
use crate::colors;
use crate::emit::TsTypeLib;
use crate::errors::get_error_class_name;
use crate::npm::NpmPackageReference;
use crate::npm::NpmPackageReq;
use deno_ast::ParsedSource;
use deno_core::error::custom_error;
@ -58,6 +60,7 @@ pub enum ModuleEntry {
#[derive(Debug, Default)]
pub struct GraphData {
modules: HashMap<ModuleSpecifier, ModuleEntry>,
npm_packages: HashSet<NpmPackageReq>,
/// Map of first known referrer locations for each module. Used to enhance
/// error messages.
referrer_map: HashMap<ModuleSpecifier, Range>,
@ -91,6 +94,13 @@ impl GraphData {
if !reload && self.modules.contains_key(&specifier) {
continue;
}
if specifier.scheme() == "npm" {
// the loader enforces npm specifiers are valid, so it's ok to unwrap here
let reference =
NpmPackageReference::from_specifier(&specifier).unwrap();
self.npm_packages.insert(reference.req);
continue;
}
if let Some(found) = graph.redirects.get(&specifier) {
let module_entry = ModuleEntry::Redirect(found.clone());
self.modules.insert(specifier.clone(), module_entry);
@ -167,6 +177,11 @@ impl GraphData {
self.modules.iter()
}
/// Gets the unique npm package requirements from all the encountered graphs.
pub fn npm_package_reqs(&self) -> Vec<NpmPackageReq> {
self.npm_packages.iter().cloned().collect()
}
/// Walk dependencies from `roots` and return every encountered specifier.
/// Return `None` if any modules are not known.
pub fn walk<'a>(
@ -199,6 +214,10 @@ impl GraphData {
}
}
while let Some(specifier) = visiting.pop_front() {
if NpmPackageReference::from_specifier(specifier).is_ok() {
continue; // skip analyzing npm specifiers
}
let (specifier, entry) = match self.modules.get_key_value(specifier) {
Some(pair) => pair,
None => return None,
@ -228,7 +247,13 @@ impl GraphData {
}
}
}
for (_, dep) in dependencies.iter().rev() {
for (dep_specifier, dep) in dependencies.iter().rev() {
// todo(dsherret): ideally there would be a way to skip external dependencies
// in the graph here rather than specifically npm package references
if NpmPackageReference::from_str(dep_specifier).is_ok() {
continue;
}
if !dep.is_dynamic || follow_dynamic {
let mut resolutions = vec![&dep.maybe_code];
if check_types {
@ -278,6 +303,7 @@ impl GraphData {
}
Some(Self {
modules,
npm_packages: self.npm_packages.clone(),
referrer_map,
// TODO(nayeemrmn): Implement `Clone` on `GraphImport`.
graph_imports: self

View file

@ -67,7 +67,7 @@ impl CacheMetadata {
&self,
specifier: &ModuleSpecifier,
) -> Option<Arc<HashMap<MetadataKey, String>>> {
if specifier.scheme() == "file" {
if specifier.scheme() == "file" || specifier.scheme() == "npm" {
return None;
}
let version = self
@ -83,7 +83,7 @@ impl CacheMetadata {
}
fn refresh(&self, specifier: &ModuleSpecifier) -> Option<Metadata> {
if specifier.scheme() == "file" {
if specifier.scheme() == "file" || specifier.scheme() == "npm" {
return None;
}
let cache_filename = self.cache.get_cache_filename(specifier)?;

View file

@ -14,6 +14,7 @@ use super::tsc::TsServer;
use crate::args::LintConfig;
use crate::diagnostics;
use crate::npm::NpmPackageReference;
use deno_ast::MediaType;
use deno_core::anyhow::anyhow;
@ -846,6 +847,8 @@ fn diagnose_resolved(
.push(DenoDiagnostic::NoAssertType.to_lsp_diagnostic(&range)),
}
}
} else if NpmPackageReference::from_specifier(specifier).is_ok() {
// ignore npm specifiers for now
} else {
// When the document is not available, it means that it cannot be found
// in the cache or locally on the disk, so we want to issue a diagnostic

View file

@ -23,7 +23,7 @@ mod lockfile;
mod logger;
mod lsp;
mod module_loader;
#[allow(unused)]
mod node;
mod npm;
mod ops;
mod proc_state;

View file

@ -3,6 +3,8 @@
use crate::emit::emit_parsed_source;
use crate::emit::TsTypeLib;
use crate::graph_util::ModuleEntry;
use crate::node;
use crate::npm::NpmPackageResolver;
use crate::proc_state::ProcState;
use crate::text_encoding::code_without_source_map;
use crate::text_encoding::source_map_from_code;
@ -115,6 +117,57 @@ impl CliModuleLoader {
)),
}
}
fn load_sync(
&self,
specifier: &ModuleSpecifier,
) -> Result<ModuleSource, AnyError> {
let code_source = if self.ps.npm_resolver.in_npm_package(specifier) {
let file_path = specifier.to_file_path().unwrap();
let code = std::fs::read_to_string(file_path)?;
let is_cjs = self.ps.cjs_resolutions.lock().contains(specifier);
let code = if is_cjs {
// translate cjs to esm if it's cjs and inject node globals
node::translate_cjs_to_esm(
&self.ps.file_fetcher,
specifier,
code,
MediaType::Cjs,
&self.ps.npm_resolver,
)?
} else {
// only inject node globals for esm
node::esm_code_with_node_globals(specifier, code)?
};
ModuleCodeSource {
code,
found_url: specifier.clone(),
media_type: MediaType::from(specifier),
}
} else {
self.load_prepared_module(specifier)?
};
let code = if self.ps.options.is_inspecting() {
// we need the code with the source map in order for
// it to work with --inspect or --inspect-brk
code_source.code
} else {
// reduce memory and throw away the source map
// because we don't need it
code_without_source_map(code_source.code)
};
Ok(ModuleSource {
code: code.into_bytes().into_boxed_slice(),
module_url_specified: specifier.to_string(),
module_url_found: code_source.found_url.to_string(),
module_type: match code_source.media_type {
MediaType::Json => ModuleType::Json,
_ => ModuleType::JavaScript,
},
})
}
}
impl ModuleLoader for CliModuleLoader {
@ -136,28 +189,7 @@ impl ModuleLoader for CliModuleLoader {
// NOTE: this block is async only because of `deno_core` interface
// requirements; module was already loaded when constructing module graph
// during call to `prepare_load` so we can load it synchronously.
let result = self.load_prepared_module(specifier).map(|code_source| {
let code = if self.ps.options.is_inspecting() {
// we need the code with the source map in order for
// it to work with --inspect or --inspect-brk
code_source.code
} else {
// reduce memory and throw away the source map
// because we don't need it
code_without_source_map(code_source.code)
};
ModuleSource {
code: code.into_bytes().into_boxed_slice(),
module_url_specified: specifier.to_string(),
module_url_found: code_source.found_url.to_string(),
module_type: match code_source.media_type {
MediaType::Json => ModuleType::Json,
_ => ModuleType::JavaScript,
},
}
});
Box::pin(deno_core::futures::future::ready(result))
Box::pin(deno_core::futures::future::ready(self.load_sync(specifier)))
}
fn prepare_load(
@ -167,6 +199,11 @@ impl ModuleLoader for CliModuleLoader {
_maybe_referrer: Option<String>,
is_dynamic: bool,
) -> Pin<Box<dyn Future<Output = Result<(), AnyError>>>> {
if self.ps.npm_resolver.in_npm_package(specifier) {
// nothing to prepare
return Box::pin(deno_core::futures::future::ready(Ok(())));
}
let specifier = specifier.clone();
let ps = self.ps.clone();
let state = op_state.borrow();
@ -198,21 +235,15 @@ impl ModuleLoader for CliModuleLoader {
impl SourceMapGetter for CliModuleLoader {
fn get_source_map(&self, file_name: &str) -> Option<Vec<u8>> {
if let Ok(specifier) = resolve_url(file_name) {
match specifier.scheme() {
// we should only be looking for emits for schemes that denote external
// modules, which the disk_cache supports
"wasm" | "file" | "http" | "https" | "data" | "blob" => (),
_ => return None,
}
if let Ok(source) = self.load_prepared_module(&specifier) {
source_map_from_code(&source.code)
} else {
None
}
} else {
None
let specifier = resolve_url(file_name).ok()?;
match specifier.scheme() {
// we should only be looking for emits for schemes that denote external
// modules, which the disk_cache supports
"wasm" | "file" | "http" | "https" | "data" | "blob" => (),
_ => return None,
}
let source = self.load_prepared_module(&specifier).ok()?;
source_map_from_code(&source.code)
}
fn get_source_line(

161
cli/node/analyze.rs Normal file
View file

@ -0,0 +1,161 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use std::collections::HashSet;
use deno_ast::swc::common::SyntaxContext;
use deno_ast::view::Node;
use deno_ast::view::NodeTrait;
use deno_ast::ModuleSpecifier;
use deno_ast::ParsedSource;
use deno_ast::SourceRanged;
use deno_core::error::AnyError;
use std::fmt::Write;
static NODE_GLOBALS: &[&str] = &[
"Buffer",
"clearImmediate",
"clearInterval",
"clearTimeout",
"global",
"process",
"setImmediate",
"setInterval",
"setTimeout",
];
// TODO(dsherret): this code is way more inefficient than it needs to be.
//
// In the future, we should disable capturing tokens & scope analysis
// and instead only use swc's APIs to go through the portions of the tree
// that we know will affect the global scope while still ensuring that
// `var` decls are taken into consideration.
pub fn esm_code_with_node_globals(
specifier: &ModuleSpecifier,
code: String,
) -> Result<String, AnyError> {
let parsed_source = deno_ast::parse_program(deno_ast::ParseParams {
specifier: specifier.to_string(),
text_info: deno_ast::SourceTextInfo::from_string(code),
media_type: deno_ast::MediaType::from(specifier),
capture_tokens: true,
scope_analysis: true,
maybe_syntax: None,
})?;
let top_level_decls = analyze_top_level_decls(&parsed_source)?;
let mut globals = Vec::with_capacity(NODE_GLOBALS.len());
let has_global_this = top_level_decls.contains("globalThis");
for global in NODE_GLOBALS.iter() {
if !top_level_decls.contains(&global.to_string()) {
globals.push(*global);
}
}
let mut result = String::new();
let has_deno_decl = top_level_decls.contains("Deno");
let global_this_expr = if has_deno_decl {
if top_level_decls.contains("window") {
// Will probably never happen, but if it does then we should consider
// creating an obscure global name to get this from.
panic!("The node esm module had a local `Deno` declaration and `window` declaration.");
}
// fallback to using `window.Deno`
"window.Deno[Deno.internal].node.globalThis"
} else {
"Deno[Deno.internal].node.globalThis"
};
let global_this_expr = if has_global_this {
global_this_expr
} else {
write!(result, "var globalThis = {};", global_this_expr).unwrap();
"globalThis"
};
for global in globals {
write!(result, "var {0} = {1}.{0};", global, global_this_expr).unwrap();
}
result.push_str(parsed_source.text_info().text_str());
Ok(result)
}
fn analyze_top_level_decls(
parsed_source: &ParsedSource,
) -> Result<HashSet<String>, AnyError> {
let top_level_context = parsed_source.top_level_context();
parsed_source.with_view(|program| {
let mut results = HashSet::new();
visit_children(program.into(), top_level_context, &mut results);
Ok(results)
})
}
fn visit_children(
node: Node,
top_level_context: SyntaxContext,
results: &mut HashSet<String>,
) {
if let Node::Ident(ident) = node {
if ident.ctxt() == top_level_context && is_local_declaration_ident(node) {
results.insert(ident.sym().to_string());
}
}
for child in node.children() {
visit_children(child, top_level_context, results);
}
}
fn is_local_declaration_ident(node: Node) -> bool {
if let Some(parent) = node.parent() {
match parent {
Node::BindingIdent(decl) => decl.id.range().contains(&node.range()),
Node::ClassDecl(decl) => decl.ident.range().contains(&node.range()),
Node::ClassExpr(decl) => decl
.ident
.as_ref()
.map(|i| i.range().contains(&node.range()))
.unwrap_or(false),
Node::TsInterfaceDecl(decl) => decl.id.range().contains(&node.range()),
Node::FnDecl(decl) => decl.ident.range().contains(&node.range()),
Node::FnExpr(decl) => decl
.ident
.as_ref()
.map(|i| i.range().contains(&node.range()))
.unwrap_or(false),
Node::TsModuleDecl(decl) => decl.id.range().contains(&node.range()),
Node::TsNamespaceDecl(decl) => decl.id.range().contains(&node.range()),
Node::VarDeclarator(decl) => decl.name.range().contains(&node.range()),
Node::ImportNamedSpecifier(decl) => {
decl.local.range().contains(&node.range())
}
Node::ImportDefaultSpecifier(decl) => {
decl.local.range().contains(&node.range())
}
Node::ImportStarAsSpecifier(decl) => decl.range().contains(&node.range()),
Node::KeyValuePatProp(decl) => decl.key.range().contains(&node.range()),
Node::AssignPatProp(decl) => decl.key.range().contains(&node.range()),
_ => false,
}
} else {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_esm_code_with_node_globals() {
let r = esm_code_with_node_globals(
&ModuleSpecifier::parse("https://example.com/foo/bar.js").unwrap(),
"export const x = 1;".to_string(),
)
.unwrap();
assert!(r.contains("var globalThis = Deno[Deno.internal].node.globalThis;"));
assert!(r.contains("var process = globalThis.process;"));
assert!(r.contains("export const x = 1;"));
}
}

730
cli/node/mod.rs Normal file
View file

@ -0,0 +1,730 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use std::collections::HashSet;
use std::path::Path;
use std::path::PathBuf;
use deno_ast::MediaType;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::Context;
use deno_core::error::generic_error;
use deno_core::error::AnyError;
use deno_core::located_script_name;
use deno_core::serde_json::Map;
use deno_core::serde_json::Value;
use deno_core::url::Url;
use deno_core::JsRuntime;
use deno_graph::source::ResolveResponse;
use deno_runtime::deno_node::get_package_scope_config;
use deno_runtime::deno_node::legacy_main_resolve;
use deno_runtime::deno_node::package_exports_resolve;
use deno_runtime::deno_node::package_imports_resolve;
use deno_runtime::deno_node::package_resolve;
use deno_runtime::deno_node::DenoDirNpmResolver;
use deno_runtime::deno_node::PackageJson;
use deno_runtime::deno_node::DEFAULT_CONDITIONS;
use once_cell::sync::Lazy;
use path_clean::PathClean;
use regex::Regex;
use crate::compat;
use crate::file_fetcher::FileFetcher;
use crate::npm::GlobalNpmPackageResolver;
use crate::npm::NpmPackageReference;
use crate::npm::NpmPackageResolver;
mod analyze;
pub use analyze::esm_code_with_node_globals;
static RESERVED_WORDS: Lazy<HashSet<&str>> = Lazy::new(|| {
HashSet::from([
"break",
"case",
"catch",
"class",
"const",
"continue",
"debugger",
"default",
"delete",
"do",
"else",
"export",
"extends",
"false",
"finally",
"for",
"function",
"if",
"import",
"in",
"instanceof",
"new",
"null",
"return",
"super",
"switch",
"this",
"throw",
"true",
"try",
"typeof",
"var",
"void",
"while",
"with",
"yield",
"let",
"enum",
"implements",
"interface",
"package",
"private",
"protected",
"public",
"static",
])
});
pub async fn initialize_runtime(
js_runtime: &mut JsRuntime,
) -> Result<(), AnyError> {
let source_code = &format!(
r#"(async function loadBuiltinNodeModules(moduleAllUrl) {{
const moduleAll = await import(moduleAllUrl);
Deno[Deno.internal].node.initialize(moduleAll.default);
}})('{}');"#,
compat::MODULE_ALL_URL.as_str(),
);
let value =
js_runtime.execute_script(&located_script_name!(), source_code)?;
js_runtime.resolve_value(value).await?;
Ok(())
}
/// This function is an implementation of `defaultResolve` in
/// `lib/internal/modules/esm/resolve.js` from Node.
pub fn node_resolve(
specifier: &str,
referrer: &ModuleSpecifier,
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<Option<ResolveResponse>, AnyError> {
// TODO(bartlomieju): skipped "policy" part as we don't plan to support it
if let Some(resolved) = compat::try_resolve_builtin_module(specifier) {
return Ok(Some(ResolveResponse::Esm(resolved)));
}
if let Ok(url) = Url::parse(specifier) {
if url.scheme() == "data" {
return Ok(Some(ResolveResponse::Specifier(url)));
}
let protocol = url.scheme();
if protocol == "node" {
let split_specifier = url.as_str().split(':');
let specifier = split_specifier.skip(1).collect::<String>();
if let Some(resolved) = compat::try_resolve_builtin_module(&specifier) {
return Ok(Some(ResolveResponse::Esm(resolved)));
} else {
return Err(generic_error(format!("Unknown module {}", specifier)));
}
}
if protocol != "file" && protocol != "data" {
return Err(compat::errors::err_unsupported_esm_url_scheme(&url));
}
// todo(THIS PR): I think this is handled upstream so can be removed?
if referrer.scheme() == "data" {
let url = referrer.join(specifier).map_err(AnyError::from)?;
return Ok(Some(ResolveResponse::Specifier(url)));
}
}
let conditions = DEFAULT_CONDITIONS;
let url = module_resolve(specifier, referrer, conditions, npm_resolver)?;
let url = match url {
Some(url) => url,
None => return Ok(None),
};
let resolve_response = url_to_resolve_response(url, npm_resolver)?;
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
// "preserveSymlinksMain"/"preserveSymlinks" options.
Ok(Some(resolve_response))
}
pub fn node_resolve_npm_reference(
reference: &NpmPackageReference,
npm_resolver: &GlobalNpmPackageResolver,
) -> Result<Option<ResolveResponse>, AnyError> {
let package_folder = npm_resolver
.resolve_package_from_deno_module(&reference.req)?
.folder_path;
let maybe_url = package_config_resolve(
reference.sub_path.as_deref().unwrap_or("."),
&package_folder,
npm_resolver,
)
.map(Some)
.with_context(|| {
format!("Error resolving package config for '{}'.", reference)
})?;
let url = match maybe_url {
Some(url) => url,
None => return Ok(None),
};
let resolve_response = url_to_resolve_response(url, npm_resolver)?;
// TODO(bartlomieju): skipped checking errors for commonJS resolution and
// "preserveSymlinksMain"/"preserveSymlinks" options.
Ok(Some(resolve_response))
}
fn package_config_resolve(
package_subpath: &str,
package_dir: &Path,
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<ModuleSpecifier, AnyError> {
let package_json_path = package_dir.join("package.json");
// todo(dsherret): remove base from this code
let base =
ModuleSpecifier::from_directory_path(package_json_path.parent().unwrap())
.unwrap();
let package_config =
PackageJson::load(npm_resolver, package_json_path.clone())?;
let package_json_url =
ModuleSpecifier::from_file_path(&package_json_path).unwrap();
if let Some(exports) = &package_config.exports {
return package_exports_resolve(
package_json_url,
package_subpath.to_string(),
exports,
&base,
DEFAULT_CONDITIONS,
npm_resolver,
);
}
if package_subpath == "." {
return legacy_main_resolve(&package_json_url, &package_config, &base);
}
package_json_url
.join(package_subpath)
.map_err(AnyError::from)
}
fn url_to_resolve_response(
url: ModuleSpecifier,
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<ResolveResponse, AnyError> {
Ok(if url.as_str().starts_with("http") {
ResolveResponse::Esm(url)
} else if url.as_str().ends_with(".js") {
let package_config = get_package_scope_config(&url, npm_resolver)?;
if package_config.typ == "module" {
ResolveResponse::Esm(url)
} else {
ResolveResponse::CommonJs(url)
}
} else if url.as_str().ends_with(".cjs") {
ResolveResponse::CommonJs(url)
} else {
ResolveResponse::Esm(url)
})
}
fn finalize_resolution(
resolved: ModuleSpecifier,
base: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> {
// TODO(bartlomieju): this is not part of Node resolution algorithm
// (as it doesn't support http/https); but I had to short circuit here
// for remote modules because they are mainly used to polyfill `node` built
// in modules. Another option would be to leave the resolved URLs
// as `node:<module_name>` and do the actual remapping to std's polyfill
// in module loader. I'm not sure which approach is better.
if resolved.scheme().starts_with("http") {
return Ok(resolved);
}
// todo(dsherret): cache
let encoded_sep_re = Regex::new(r"%2F|%2C").unwrap();
if encoded_sep_re.is_match(resolved.path()) {
return Err(compat::errors::err_invalid_module_specifier(
resolved.path(),
"must not include encoded \"/\" or \"\\\\\" characters",
Some(to_file_path_string(base)),
));
}
let path = to_file_path(&resolved);
// TODO(bartlomieju): currently not supported
// if (getOptionValue('--experimental-specifier-resolution') === 'node') {
// ...
// }
let p_str = path.to_str().unwrap();
let p = if p_str.ends_with('/') {
p_str[p_str.len() - 1..].to_string()
} else {
p_str.to_string()
};
let (is_dir, is_file) = if let Ok(stats) = std::fs::metadata(&p) {
(stats.is_dir(), stats.is_file())
} else {
(false, false)
};
if is_dir {
return Err(compat::errors::err_unsupported_dir_import(
resolved.as_str(),
base.as_str(),
));
} else if !is_file {
return Err(compat::errors::err_module_not_found(
resolved.as_str(),
base.as_str(),
"module",
));
}
Ok(resolved)
}
fn module_resolve(
specifier: &str,
referrer: &ModuleSpecifier,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<Option<ModuleSpecifier>, AnyError> {
let url = if should_be_treated_as_relative_or_absolute_path(specifier) {
let resolved_specifier = referrer.join(specifier)?;
Some(resolved_specifier)
} else if specifier.starts_with('#') {
Some(package_imports_resolve(
specifier,
referrer,
conditions,
npm_resolver,
)?)
} else if let Ok(resolved) = Url::parse(specifier) {
Some(resolved)
} else {
Some(package_resolve(
specifier,
referrer,
conditions,
npm_resolver,
)?)
};
Ok(match url {
Some(url) => Some(finalize_resolution(url, referrer)?),
None => None,
})
}
fn add_export(source: &mut Vec<String>, name: &str, initializer: &str) {
// TODO(bartlomieju): Node actually checks if a given export exists in `exports` object,
// but it might not be necessary here since our analysis is more detailed?
if RESERVED_WORDS.contains(name) {
// we can't create an identifier with a reserved word, so assign it to a temporary
// variable that won't have a conflict, then re-export it as a string
source.push(format!(
"const __deno_reexport_temp__{} = {};",
name, initializer
));
source.push(format!(
"export {{ __deno_reexport_temp__{0} as \"{0}\" }};",
name
));
} else {
source.push(format!("export const {} = {};", name, initializer));
}
}
/// Translates given CJS module into ESM. This function will perform static
/// analysis on the file to find defined exports and reexports.
///
/// For all discovered reexports the analysis will be performed recursively.
///
/// If successful a source code for equivalent ES module is returned.
pub fn translate_cjs_to_esm(
file_fetcher: &FileFetcher,
specifier: &ModuleSpecifier,
code: String,
media_type: MediaType,
npm_resolver: &GlobalNpmPackageResolver,
) -> Result<String, AnyError> {
let parsed_source = deno_ast::parse_script(deno_ast::ParseParams {
specifier: specifier.to_string(),
text_info: deno_ast::SourceTextInfo::new(code.into()),
media_type,
capture_tokens: true,
scope_analysis: false,
maybe_syntax: None,
})?;
let analysis = parsed_source.analyze_cjs();
let mut source = vec![
r#"const require = Deno[Deno.internal].require.Module.createRequire(import.meta.url);"#.to_string(),
];
// if there are reexports, handle them first
for (idx, reexport) in analysis.reexports.iter().enumerate() {
// Firstly, resolve relate reexport specifier
// todo(dsherret): call module_resolve instead?
let resolved_reexport = resolve(
reexport,
specifier,
// FIXME(bartlomieju): check if these conditions are okay, probably
// should be `deno-require`, because `deno` is already used in `esm_resolver.rs`
&["deno", "require", "default"],
npm_resolver,
)?;
let reexport_specifier =
ModuleSpecifier::from_file_path(&resolved_reexport).unwrap();
// Secondly, read the source code from disk
let reexport_file = file_fetcher.get_source(&reexport_specifier).unwrap();
// Now perform analysis again
{
let parsed_source = deno_ast::parse_script(deno_ast::ParseParams {
specifier: reexport_specifier.to_string(),
text_info: deno_ast::SourceTextInfo::new(reexport_file.source),
media_type: reexport_file.media_type,
capture_tokens: true,
scope_analysis: false,
maybe_syntax: None,
})?;
let analysis = parsed_source.analyze_cjs();
source.push(format!(
"const reexport{} = require(\"{}\");",
idx, reexport
));
for export in analysis.exports.iter().filter(|e| e.as_str() != "default")
{
add_export(&mut source, export, &format!("Deno[Deno.internal].require.bindExport(reexport{0}.{1}, reexport{0})", idx, export));
}
}
}
source.push(format!(
"const mod = require(\"{}\");",
specifier
.to_file_path()
.unwrap()
.to_str()
.unwrap()
.replace('\\', "\\\\")
.replace('\'', "\\\'")
.replace('\"', "\\\"")
));
let mut had_default = false;
for export in analysis.exports.iter() {
if export.as_str() == "default" {
// todo(dsherret): we should only do this if there was a `_esModule: true` instead
source.push(format!(
"export default Deno[Deno.internal].require.bindExport(mod.{}, mod);",
export,
));
had_default = true;
} else {
add_export(
&mut source,
export,
&format!(
"Deno[Deno.internal].require.bindExport(mod.{}, mod)",
export
),
);
}
}
if !had_default {
source.push("export default mod;".to_string());
}
let translated_source = source.join("\n");
Ok(translated_source)
}
fn resolve_package_target_string(
target: &str,
subpath: Option<String>,
) -> String {
if let Some(subpath) = subpath {
target.replace('*', &subpath)
} else {
target.to_string()
}
}
fn resolve(
specifier: &str,
referrer: &ModuleSpecifier,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<PathBuf, AnyError> {
if specifier.starts_with('/') {
todo!();
}
let referrer_path = referrer.to_file_path().unwrap();
if specifier.starts_with("./") || specifier.starts_with("../") {
if let Some(parent) = referrer_path.parent() {
return file_extension_probe(parent.join(specifier), &referrer_path);
} else {
todo!();
}
}
// We've got a bare specifier or maybe bare_specifier/blah.js"
let (_, package_subpath) = parse_specifier(specifier).unwrap();
// todo(dsherret): use not_found error on not found here
let module_dir =
npm_resolver.resolve_package_folder_from_path(&referrer_path)?;
let package_json_path = module_dir.join("package.json");
if package_json_path.exists() {
let package_json = PackageJson::load(npm_resolver, package_json_path)?;
if let Some(map) = package_json.exports {
if let Some((key, subpath)) = exports_resolve(&map, &package_subpath) {
let value = map.get(&key).unwrap();
let s = conditions_resolve(value, conditions);
let t = resolve_package_target_string(&s, subpath);
return Ok(module_dir.join(t).clean());
} else {
todo!()
}
}
// old school
if package_subpath != "." {
let d = module_dir.join(package_subpath);
if let Ok(m) = d.metadata() {
if m.is_dir() {
return Ok(d.join("index.js").clean());
}
}
return file_extension_probe(d, &referrer_path);
} else if let Some(main) = package_json.main {
return Ok(module_dir.join(main).clean());
} else {
return Ok(module_dir.join("index.js").clean());
}
}
Err(not_found(specifier, &referrer_path))
}
fn conditions_resolve(value: &Value, conditions: &[&str]) -> String {
match value {
Value::String(s) => s.to_string(),
Value::Object(map) => {
for condition in conditions {
if let Some(x) = map.get(&condition.to_string()) {
if let Value::String(s) = x {
return s.to_string();
} else {
todo!()
}
}
}
todo!()
}
_ => todo!(),
}
}
fn parse_specifier(specifier: &str) -> Option<(String, String)> {
let mut separator_index = specifier.find('/');
let mut valid_package_name = true;
// let mut is_scoped = false;
if specifier.is_empty() {
valid_package_name = false;
} else if specifier.starts_with('@') {
// is_scoped = true;
if let Some(index) = separator_index {
separator_index = specifier[index + 1..].find('/');
} else {
valid_package_name = false;
}
}
let package_name = if let Some(index) = separator_index {
specifier[0..index].to_string()
} else {
specifier.to_string()
};
// Package name cannot have leading . and cannot have percent-encoding or separators.
for ch in package_name.chars() {
if ch == '%' || ch == '\\' {
valid_package_name = false;
break;
}
}
if !valid_package_name {
return None;
}
let package_subpath = if let Some(index) = separator_index {
format!(".{}", specifier.chars().skip(index).collect::<String>())
} else {
".".to_string()
};
Some((package_name, package_subpath))
}
fn exports_resolve(
map: &Map<String, Value>,
subpath: &str,
) -> Option<(String, Option<String>)> {
if map.contains_key(subpath) {
return Some((subpath.to_string(), None));
}
// best match
let mut best_match = None;
for key in map.keys() {
if let Some(pattern_index) = key.find('*') {
let key_sub = &key[0..pattern_index];
if subpath.starts_with(key_sub) {
if subpath.ends_with('/') {
todo!()
}
let pattern_trailer = &key[pattern_index + 1..];
if subpath.len() > key.len()
&& subpath.ends_with(pattern_trailer)
// && pattern_key_compare(best_match, key) == 1
&& key.rfind('*') == Some(pattern_index)
{
let rest = subpath
[pattern_index..(subpath.len() - pattern_trailer.len())]
.to_string();
best_match = Some((key, rest));
}
}
}
}
if let Some((key, subpath_)) = best_match {
return Some((key.to_string(), Some(subpath_)));
}
None
}
fn to_file_path(url: &ModuleSpecifier) -> PathBuf {
url
.to_file_path()
.unwrap_or_else(|_| panic!("Provided URL was not file:// URL: {}", url))
}
fn to_file_path_string(url: &ModuleSpecifier) -> String {
to_file_path(url).display().to_string()
}
fn should_be_treated_as_relative_or_absolute_path(specifier: &str) -> bool {
if specifier.is_empty() {
return false;
}
if specifier.starts_with('/') {
return true;
}
is_relative_specifier(specifier)
}
// TODO(ry) We very likely have this utility function elsewhere in Deno.
fn is_relative_specifier(specifier: &str) -> bool {
let specifier_len = specifier.len();
let specifier_chars: Vec<_> = specifier.chars().collect();
if !specifier_chars.is_empty() && specifier_chars[0] == '.' {
if specifier_len == 1 || specifier_chars[1] == '/' {
return true;
}
if specifier_chars[1] == '.'
&& (specifier_len == 2 || specifier_chars[2] == '/')
{
return true;
}
}
false
}
fn file_extension_probe(
mut p: PathBuf,
referrer: &Path,
) -> Result<PathBuf, AnyError> {
if p.exists() && !p.is_dir() {
Ok(p.clean())
} else {
p.set_extension("js");
if p.exists() && !p.is_dir() {
Ok(p)
} else {
Err(not_found(&p.clean().to_string_lossy(), referrer))
}
}
}
fn not_found(path: &str, referrer: &Path) -> AnyError {
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()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add_export() {
let mut source = vec![];
let exports = vec!["static", "server", "app"];
for export in exports {
add_export(&mut source, export, "init");
}
assert_eq!(
source,
vec![
"const __deno_reexport_temp__static = init;".to_string(),
"export { __deno_reexport_temp__static as \"static\" };".to_string(),
"export const server = init;".to_string(),
"export const app = init;".to_string(),
]
)
}
#[test]
fn test_resolve_package_target_string() {
assert_eq!(resolve_package_target_string("foo", None), "foo");
assert_eq!(
resolve_package_target_string("*foo", Some("bar".to_string())),
"barfoo"
);
}
}

View file

@ -6,6 +6,7 @@ use std::path::PathBuf;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::url::Url;
use deno_runtime::colors;
@ -37,20 +38,23 @@ impl Default for ReadonlyNpmCache {
// This only gets used when creating the tsc runtime and for testing, and so
// it shouldn't ever actually access the DenoDir, so it doesn't support a
// custom root.
Self::from_deno_dir(&crate::deno_dir::DenoDir::new(None).unwrap())
Self::from_deno_dir(&crate::deno_dir::DenoDir::new(None).unwrap()).unwrap()
}
}
impl ReadonlyNpmCache {
pub fn new(root_dir: PathBuf) -> Self {
pub fn new(root_dir: PathBuf) -> Result<Self, AnyError> {
std::fs::create_dir_all(&root_dir)
.with_context(|| format!("Error creating {}", root_dir.display()))?;
let root_dir = crate::fs_util::canonicalize_path(&root_dir)?;
let root_dir_url = Url::from_directory_path(&root_dir).unwrap();
Self {
Ok(Self {
root_dir,
root_dir_url,
}
})
}
pub fn from_deno_dir(dir: &DenoDir) -> Self {
pub fn from_deno_dir(dir: &DenoDir) -> Result<Self, AnyError> {
Self::new(dir.root.join("npm"))
}
@ -65,16 +69,14 @@ impl ReadonlyNpmCache {
}
pub fn package_name_folder(&self, name: &str, registry_url: &Url) -> PathBuf {
let mut dir = self
.root_dir
.join(fs_util::root_url_to_safe_local_dirname(registry_url));
let mut dir = self.registry_folder(registry_url);
let mut parts = name.split('/').map(Cow::Borrowed).collect::<Vec<_>>();
// package names were not always enforced to be lowercase and so we need
// to ensure package names, which are therefore case sensitive, are stored
// on a case insensitive file system to not have conflicts. We do this by
// first putting it in a "_" folder then hashing the package name.
if name.to_lowercase() != name {
let mut last_part = parts.last_mut().unwrap();
let last_part = parts.last_mut().unwrap();
*last_part = Cow::Owned(crate::checksum::gen(&[last_part.as_bytes()]));
// We can't just use the hash as part of the directory because it may
// have a collision with an actual package name in case someone wanted
@ -90,6 +92,12 @@ impl ReadonlyNpmCache {
dir
}
pub fn registry_folder(&self, registry_url: &Url) -> PathBuf {
self
.root_dir
.join(fs_util::root_url_to_safe_local_dirname(registry_url))
}
pub fn resolve_package_id_from_specifier(
&self,
specifier: &ModuleSpecifier,
@ -147,12 +155,8 @@ impl ReadonlyNpmCache {
pub struct NpmCache(ReadonlyNpmCache);
impl NpmCache {
pub fn new(root_dir: PathBuf) -> Self {
Self(ReadonlyNpmCache::new(root_dir))
}
pub fn from_deno_dir(dir: &DenoDir) -> Self {
Self(ReadonlyNpmCache::from_deno_dir(dir))
pub fn from_deno_dir(dir: &DenoDir) -> Result<Self, AnyError> {
Ok(Self(ReadonlyNpmCache::from_deno_dir(dir)?))
}
pub fn as_readonly(&self) -> ReadonlyNpmCache {
@ -228,6 +232,10 @@ impl NpmCache {
self.0.package_name_folder(name, registry_url)
}
pub fn registry_folder(&self, registry_url: &Url) -> PathBuf {
self.0.registry_folder(registry_url)
}
pub fn resolve_package_id_from_specifier(
&self,
specifier: &ModuleSpecifier,
@ -242,7 +250,6 @@ impl NpmCache {
#[cfg(test)]
mod test {
use deno_core::url::Url;
use std::path::PathBuf;
use super::ReadonlyNpmCache;
use crate::npm::NpmPackageId;
@ -250,7 +257,7 @@ mod test {
#[test]
fn should_get_lowercase_package_folder() {
let root_dir = crate::deno_dir::DenoDir::new(None).unwrap().root;
let cache = ReadonlyNpmCache::new(root_dir.clone());
let cache = ReadonlyNpmCache::new(root_dir.clone()).unwrap();
let registry_url = Url::parse("https://registry.npmjs.org/").unwrap();
// all lowercase should be as-is
@ -273,7 +280,7 @@ mod test {
fn should_handle_non_all_lowercase_package_names() {
// it was possible at one point for npm packages to not just be lowercase
let root_dir = crate::deno_dir::DenoDir::new(None).unwrap().root;
let cache = ReadonlyNpmCache::new(root_dir.clone());
let cache = ReadonlyNpmCache::new(root_dir.clone()).unwrap();
let registry_url = Url::parse("https://registry.npmjs.org/").unwrap();
let json_uppercase_hash =
"db1a21a0bc2ef8fbe13ac4cf044e8c9116d29137d5ed8b916ab63dcb2d4290df";

View file

@ -5,15 +5,19 @@ mod registry;
mod resolution;
mod tarball;
use std::io::ErrorKind;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::futures;
use deno_core::url::Url;
use deno_runtime::deno_node::DenoDirNpmResolver;
pub use resolution::NpmPackageId;
pub use resolution::NpmPackageReference;
pub use resolution::NpmPackageReq;
@ -65,7 +69,7 @@ pub trait NpmPackageResolver {
}
}
#[derive(Clone, Debug)]
#[derive(Debug, Clone)]
pub struct GlobalNpmPackageResolver {
cache: NpmCache,
resolution: Arc<NpmResolution>,
@ -73,12 +77,8 @@ pub struct GlobalNpmPackageResolver {
}
impl GlobalNpmPackageResolver {
pub fn new(root_cache_dir: PathBuf, reload: bool) -> Self {
Self::from_cache(NpmCache::new(root_cache_dir), reload)
}
pub fn from_deno_dir(dir: &DenoDir, reload: bool) -> Self {
Self::from_cache(NpmCache::from_deno_dir(dir), reload)
pub fn from_deno_dir(dir: &DenoDir, reload: bool) -> Result<Self, AnyError> {
Ok(Self::from_cache(NpmCache::from_deno_dir(dir)?, reload))
}
fn from_cache(cache: NpmCache, reload: bool) -> Self {
@ -98,11 +98,6 @@ impl GlobalNpmPackageResolver {
self.resolution.has_packages()
}
/// Gets all the packages.
pub fn all_packages(&self) -> Vec<NpmResolutionPackage> {
self.resolution.all_packages()
}
/// Adds a package requirement to the resolver.
pub async fn add_package_reqs(
&self,
@ -113,22 +108,38 @@ impl GlobalNpmPackageResolver {
/// Caches all the packages in parallel.
pub async fn cache_packages(&self) -> Result<(), AnyError> {
let handles = self.resolution.all_packages().into_iter().map(|package| {
let cache = self.cache.clone();
let registry_url = self.registry_url.clone();
tokio::task::spawn(async move {
cache
.ensure_package(&package.id, &package.dist, &registry_url)
if std::env::var("DENO_UNSTABLE_NPM_SYNC_DOWNLOAD") == Ok("1".to_string()) {
// for some of the tests, we want downloading of packages
// to be deterministic so that the output is always the same
let mut packages = self.resolution.all_packages();
packages.sort_by(|a, b| a.id.cmp(&b.id));
for package in packages {
self
.cache
.ensure_package(&package.id, &package.dist, &self.registry_url)
.await
.with_context(|| {
format!("Failed caching npm package '{}'.", package.id)
})
})
});
let results = futures::future::join_all(handles).await;
for result in results {
// surface the first error
result??;
})?;
}
} else {
let handles = self.resolution.all_packages().into_iter().map(|package| {
let cache = self.cache.clone();
let registry_url = self.registry_url.clone();
tokio::task::spawn(async move {
cache
.ensure_package(&package.id, &package.dist, &registry_url)
.await
.with_context(|| {
format!("Failed caching npm package '{}'.", package.id)
})
})
});
let results = futures::future::join_all(handles).await;
for result in results {
// surface the first error
result??;
}
}
Ok(())
}
@ -141,6 +152,7 @@ impl GlobalNpmPackageResolver {
}
/// Creates an inner clone.
#[allow(unused)]
pub fn snapshot(&self) -> NpmPackageResolverSnapshot {
NpmPackageResolverSnapshot {
cache: self.cache.as_readonly(),
@ -246,3 +258,112 @@ impl NpmPackageResolver for NpmPackageResolverSnapshot {
Ok(self.local_package_info(&pkg_id))
}
}
impl DenoDirNpmResolver for GlobalNpmPackageResolver {
fn resolve_package_folder_from_package(
&self,
specifier: &str,
referrer: &std::path::Path,
) -> Result<PathBuf, AnyError> {
let referrer = specifier_to_path(referrer)?;
self
.resolve_package_from_package(specifier, &referrer)
.map(|p| p.folder_path)
}
fn resolve_package_folder_from_path(
&self,
path: &Path,
) -> Result<PathBuf, AnyError> {
let specifier = specifier_to_path(path)?;
self
.resolve_package_from_specifier(&specifier)
.map(|p| p.folder_path)
}
fn in_npm_package(&self, path: &Path) -> bool {
let specifier = match ModuleSpecifier::from_file_path(path) {
Ok(p) => p,
Err(_) => return false,
};
self.resolve_package_from_specifier(&specifier).is_ok()
}
fn ensure_read_permission(&self, path: &Path) -> Result<(), AnyError> {
let registry_path = self.cache.registry_folder(&self.registry_url);
ensure_read_permission(&registry_path, path)
}
}
impl DenoDirNpmResolver for NpmPackageResolverSnapshot {
fn resolve_package_folder_from_package(
&self,
specifier: &str,
referrer: &std::path::Path,
) -> Result<PathBuf, AnyError> {
let referrer = specifier_to_path(referrer)?;
self
.resolve_package_from_package(specifier, &referrer)
.map(|p| p.folder_path)
}
fn resolve_package_folder_from_path(
&self,
path: &Path,
) -> Result<PathBuf, AnyError> {
let specifier = specifier_to_path(path)?;
self
.resolve_package_from_specifier(&specifier)
.map(|p| p.folder_path)
}
fn in_npm_package(&self, path: &Path) -> bool {
let specifier = match ModuleSpecifier::from_file_path(path) {
Ok(p) => p,
Err(_) => return false,
};
self.resolve_package_from_specifier(&specifier).is_ok()
}
fn ensure_read_permission(&self, path: &Path) -> Result<(), AnyError> {
let registry_path = self.cache.registry_folder(&self.registry_url);
ensure_read_permission(&registry_path, path)
}
}
fn specifier_to_path(path: &Path) -> Result<ModuleSpecifier, AnyError> {
match ModuleSpecifier::from_file_path(&path) {
Ok(specifier) => Ok(specifier),
Err(()) => bail!("Could not convert '{}' to url.", path.display()),
}
}
fn ensure_read_permission(
registry_path: &Path,
path: &Path,
) -> Result<(), AnyError> {
// allow reading if it's in the deno_dir node modules
if path.starts_with(&registry_path)
&& path
.components()
.all(|c| !matches!(c, std::path::Component::ParentDir))
{
// todo(dsherret): cache this?
if let Ok(registry_path) = std::fs::canonicalize(registry_path) {
match std::fs::canonicalize(path) {
Ok(path) if path.starts_with(registry_path) => {
return Ok(());
}
Err(e) if e.kind() == ErrorKind::NotFound => {
return Ok(());
}
_ => {} // ignore
}
}
}
Err(deno_core::error::custom_error(
"PermissionDenied",
format!("Reading {} is not allowed", path.display()),
))
}

View file

@ -12,6 +12,7 @@ use deno_core::parking_lot::Mutex;
use deno_core::serde::Deserialize;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_runtime::colors;
use deno_runtime::deno_fetch::reqwest;
use serde::Serialize;
@ -63,8 +64,13 @@ impl NpmPackageVersionInfo {
} else {
(entry.0.clone(), entry.1.clone())
};
let version_req = NpmVersionReq::parse(&version_req)
.with_context(|| format!("Dependency: {}", bare_specifier))?;
let version_req =
NpmVersionReq::parse(&version_req).with_context(|| {
format!(
"error parsing version requirement for dependency: {}@{}",
bare_specifier, version_req
)
})?;
Ok(NpmDependencyEntry {
bare_specifier,
name,
@ -98,7 +104,22 @@ pub struct NpmRegistryApi {
impl NpmRegistryApi {
pub fn default_url() -> Url {
Url::parse("https://registry.npmjs.org").unwrap()
let env_var_name = "DENO_NPM_REGISTRY";
if let Ok(registry_url) = std::env::var(env_var_name) {
// ensure there is a trailing slash for the directory
let registry_url = format!("{}/", registry_url.trim_end_matches('/'));
match Url::parse(&registry_url) {
Ok(url) => url,
Err(err) => {
eprintln!("{}: Invalid {} environment variable. Please provide a valid url.\n\n{:#}",
colors::red_bold("error"),
env_var_name, err);
std::process::exit(1);
}
}
} else {
Url::parse("https://registry.npmjs.org").unwrap()
}
}
pub fn new(cache: NpmCache, reload: bool) -> Self {
@ -125,7 +146,7 @@ impl NpmRegistryApi {
let maybe_package_info = self.maybe_package_info(name).await?;
match maybe_package_info {
Some(package_info) => Ok(package_info),
None => bail!("package '{}' does not exist", name),
None => bail!("npm package '{}' does not exist", name),
}
}
@ -271,6 +292,7 @@ fn npm_version_req_parse_part(
text: &str,
) -> Result<semver::VersionReq, AnyError> {
let text = text.trim();
let text = text.strip_prefix('v').unwrap_or(text);
let mut chars = text.chars().enumerate().peekable();
let mut final_text = String::new();
while chars.peek().is_some() {
@ -307,6 +329,11 @@ mod test {
}
}
#[test]
pub fn npm_version_req_with_v() {
assert!(NpmVersionReq::parse("v1.0.0").is_ok());
}
#[test]
pub fn npm_version_req_ranges() {
let tester = NpmVersionReqTester(

View file

@ -105,13 +105,14 @@ impl std::fmt::Display for NpmPackageReference {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct NpmPackageId {
pub name: String,
pub version: semver::Version,
}
impl NpmPackageId {
#[allow(unused)]
pub fn scope(&self) -> Option<&str> {
if self.name.starts_with('@') && self.name.contains('/') {
self.name.split('/').next()
@ -169,17 +170,19 @@ impl NpmResolutionSnapshot {
referrer: &NpmPackageId,
) -> Result<&NpmResolutionPackage, AnyError> {
match self.packages.get(referrer) {
Some(referrer_package) => match referrer_package.dependencies.get(name) {
Some(id) => Ok(self.packages.get(id).unwrap()),
None => {
bail!(
"could not find package '{}' referenced by '{}'",
name,
referrer
)
Some(referrer_package) => {
match referrer_package.dependencies.get(name_without_path(name)) {
Some(id) => Ok(self.packages.get(id).unwrap()),
None => {
bail!(
"could not find npm package '{}' referenced by '{}'",
name,
referrer
)
}
}
},
None => bail!("could not find referrer package '{}'", referrer),
}
None => bail!("could not find referrer npm package '{}'", referrer),
}
}
@ -276,7 +279,7 @@ impl NpmResolution {
let dependencies = version_and_info
.info
.dependencies_as_entries()
.with_context(|| format!("Package: {}", id))?;
.with_context(|| format!("npm package: {}", id))?;
pending_dependencies.push_back((id.clone(), dependencies));
snapshot.packages.insert(
@ -334,7 +337,7 @@ impl NpmResolution {
.info
.dependencies_as_entries()
.with_context(|| {
format!("Package: {}@{}", dep.name, version_and_info.version)
format!("npm package: {}@{}", dep.name, version_and_info.version)
})?;
let id = NpmPackageId {
@ -452,7 +455,7 @@ fn get_resolved_package_version_and_info(
// version, but next time to a different version because it has new information.
None => bail!(
concat!(
"Could not find package '{}' matching {}{}. ",
"Could not find npm package '{}' matching {}{}. ",
"Try retreiving the latest npm package information by running with --reload",
),
pkg_name,
@ -464,3 +467,31 @@ fn get_resolved_package_version_and_info(
),
}
}
fn name_without_path(name: &str) -> &str {
let mut search_start_index = 0;
if name.starts_with('@') {
if let Some(slash_index) = name.find('/') {
search_start_index = slash_index + 1;
}
}
if let Some(slash_index) = &name[search_start_index..].find('/') {
// get the name up until the path slash
&name[0..search_start_index + slash_index]
} else {
name
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_name_without_path() {
assert_eq!(name_without_path("foo"), "foo");
assert_eq!(name_without_path("@foo/bar"), "@foo/bar");
assert_eq!(name_without_path("@foo/bar/baz"), "@foo/bar");
assert_eq!(name_without_path("@hello"), "@hello");
}
}

View file

@ -22,10 +22,15 @@ use crate::graph_util::ModuleEntry;
use crate::http_cache;
use crate::lockfile::as_maybe_locker;
use crate::lockfile::Lockfile;
use crate::node;
use crate::npm::GlobalNpmPackageResolver;
use crate::npm::NpmPackageReference;
use crate::npm::NpmPackageResolver;
use crate::resolver::ImportMapResolver;
use crate::resolver::JsxResolver;
use deno_core::anyhow::anyhow;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
@ -79,6 +84,8 @@ pub struct Inner {
pub compiled_wasm_module_store: CompiledWasmModuleStore,
maybe_resolver: Option<Arc<dyn deno_graph::source::Resolver + Send + Sync>>,
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
pub npm_resolver: GlobalNpmPackageResolver,
pub cjs_resolutions: Mutex<HashSet<ModuleSpecifier>>,
}
impl Deref for ProcState {
@ -210,6 +217,8 @@ impl ProcState {
warn!("{}", ignored_options);
}
let emit_cache = EmitCache::new(dir.gen_cache.clone());
let npm_resolver =
GlobalNpmPackageResolver::from_deno_dir(&dir, cli_options.reload_flag())?;
Ok(ProcState(Arc::new(Inner {
dir,
@ -232,6 +241,8 @@ impl ProcState {
compiled_wasm_module_store,
maybe_resolver,
maybe_file_watcher_reporter,
npm_resolver,
cjs_resolutions: Default::default(),
})))
}
@ -383,8 +394,7 @@ impl ProcState {
&module.specifier,
module.maybe_source.as_ref().unwrap().to_string(),
module.media_type,
)
.await?;
)?;
let mut graph_data = self.graph_data.write();
graph_data
.add_cjs_esm_translation(&module.specifier, translated_source);
@ -403,7 +413,7 @@ impl ProcState {
graph_data.entries().map(|(s, _)| s).cloned().collect()
};
{
let npm_package_references = {
let mut graph_data = self.graph_data.write();
graph_data.add_graph(&graph, reload_on_watch);
let check_js = self.options.check_js();
@ -414,6 +424,21 @@ impl ProcState {
check_js,
)
.unwrap()?;
graph_data.npm_package_reqs()
};
if !npm_package_references.is_empty() {
self
.npm_resolver
.add_package_reqs(npm_package_references)
.await?;
self.npm_resolver.cache_packages().await?;
// add the builtin node modules to the graph data
let node_std_graph = self
.create_graph(vec![(compat::MODULE_ALL_URL.clone(), ModuleKind::Esm)])
.await?;
self.graph_data.write().add_graph(&node_std_graph, false);
}
// type check if necessary
@ -457,12 +482,48 @@ impl ProcState {
Ok(())
}
fn handle_node_resolve_result(
&self,
result: Result<Option<ResolveResponse>, AnyError>,
) -> Result<ModuleSpecifier, AnyError> {
let response = match result? {
Some(response) => response,
None => bail!("Not found."),
};
if let ResolveResponse::CommonJs(specifier) = &response {
// remember that this was a common js resolution
self.cjs_resolutions.lock().insert(specifier.clone());
}
response.to_result()
}
pub fn resolve(
&self,
specifier: &str,
referrer: &str,
) -> Result<ModuleSpecifier, AnyError> {
if let Ok(referrer) = deno_core::resolve_url_or_path(referrer) {
if self.npm_resolver.in_npm_package(&referrer) {
// we're in an npm package, so use node resolution
return self
.handle_node_resolve_result(node::node_resolve(
specifier,
&referrer,
&self.npm_resolver,
))
.with_context(|| {
format!(
"Could not resolve '{}' from '{}'.",
specifier,
self
.npm_resolver
.resolve_package_from_specifier(&referrer)
.unwrap()
.id
)
});
}
let graph_data = self.graph_data.read();
let found_referrer = graph_data.follow_redirect(&referrer);
let maybe_resolved = match graph_data.get(&found_referrer) {
@ -473,7 +534,19 @@ impl ProcState {
};
match maybe_resolved {
Some(Resolved::Ok { specifier, .. }) => return Ok(specifier.clone()),
Some(Resolved::Ok { specifier, .. }) => {
if let Ok(reference) = NpmPackageReference::from_specifier(specifier)
{
return self
.handle_node_resolve_result(node::node_resolve_npm_reference(
&reference,
&self.npm_resolver,
))
.with_context(|| format!("Could not resolve '{}'.", reference));
} else {
return Ok(specifier.clone());
}
}
Some(Resolved::Err(err)) => {
return Err(custom_error(
"TypeError",
@ -555,19 +628,31 @@ impl ProcState {
.map(|im| im.as_resolver())
};
Ok(
create_graph(
roots,
false,
maybe_imports,
&mut cache,
maybe_resolver,
maybe_locker,
None,
None,
)
.await,
let graph = create_graph(
roots,
false,
maybe_imports,
&mut cache,
maybe_resolver,
maybe_locker,
None,
None,
)
.await;
// add the found npm package references to the npm resolver and cache them
let mut package_reqs = Vec::new();
for (specifier, _) in graph.specifiers() {
if let Ok(reference) = NpmPackageReference::from_specifier(&specifier) {
package_reqs.push(reference.req);
}
}
if !package_reqs.is_empty() {
self.npm_resolver.add_package_reqs(package_reqs).await?;
self.npm_resolver.cache_packages().await?;
}
Ok(graph)
}
}

View file

@ -297,6 +297,7 @@ pub async fn run(
maybe_inspector_server: None,
should_break_on_first_statement: false,
module_loader,
npm_resolver: None, // not currently supported
get_error_class_fn: Some(&get_error_class_name),
origin_storage_dir: None,
blob_store,

View file

@ -84,6 +84,8 @@ mod install;
mod lint;
#[path = "lsp_tests.rs"]
mod lsp;
#[path = "npm_tests.rs"]
mod npm;
#[path = "repl_tests.rs"]
mod repl;
#[path = "run_tests.rs"]

View file

@ -0,0 +1,123 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use deno_core::url::Url;
use test_util as util;
// NOTE: It's possible to automatically update the npm registry data in the test server
// by setting the DENO_TEST_UTIL_UPDATE_NPM=1 environment variable.
itest!(esm_module {
args: "run --allow-read npm/esm/main.js",
output: "npm/esm/main.out",
envs: env_vars(),
http_server: true,
});
itest!(esm_module_eval {
args_vec: vec![
"eval",
"import chalk from 'npm:chalk@5'; console.log(chalk.green('chalk esm loads'));",
],
output: "npm/esm/main.out",
envs: env_vars(),
http_server: true,
});
itest!(esm_module_deno_test {
args: "test --allow-read npm/esm/test.js",
output: "npm/esm/test.out",
envs: env_vars(),
http_server: true,
});
itest!(cjs_with_deps {
args: "run --allow-read --unstable npm/cjs_with_deps/main.js",
output: "npm/cjs_with_deps/main.out",
envs: env_vars(),
http_server: true,
});
itest!(cjs_sub_path {
args: "run --allow-read --unstable npm/cjs_sub_path/main.js",
output: "npm/cjs_sub_path/main.out",
envs: env_vars(),
http_server: true,
});
itest!(dynamic_import {
args: "run --allow-read --unstable npm/dynamic_import/main.ts",
output: "npm/dynamic_import/main.out",
envs: env_vars(),
http_server: true,
});
itest!(import_map {
args: "run --allow-read --unstable --import-map npm/import_map/import_map.json npm/import_map/main.js",
output: "npm/import_map/main.out",
envs: env_vars(),
http_server: true,
});
#[test]
fn parallel_downloading() {
let (out, _err) = util::run_and_collect_output_with_args(
true,
vec![
"run",
"--allow-read",
"--unstable",
"npm/cjs_with_deps/main.js",
],
None,
// don't use the sync env var
Some(env_vars_no_sync_download()),
true,
);
assert!(out.contains("chalk cjs loads"));
}
#[test]
fn ensure_registry_files_local() {
// ensures the registry files all point at local tarballs
let registry_dir_path = util::testdata_path().join("npm").join("registry");
for entry in std::fs::read_dir(&registry_dir_path).unwrap() {
let entry = entry.unwrap();
if entry.metadata().unwrap().is_dir() {
let registry_json_path = registry_dir_path
.join(entry.file_name())
.join("registry.json");
let file_text = std::fs::read_to_string(&registry_json_path).unwrap();
if file_text.contains("https://registry.npmjs.org/") {
panic!(
"file {} contained a reference to the npm registry",
registry_json_path.display(),
);
}
}
}
}
fn std_file_url() -> String {
let u = Url::from_directory_path(util::std_path()).unwrap();
u.to_string()
}
fn env_vars_no_sync_download() -> Vec<(String, String)> {
vec![
("DENO_NODE_COMPAT_URL".to_string(), std_file_url()),
(
"DENO_NPM_REGISTRY".to_string(),
"http://localhost:4545/npm/registry/".to_string(),
),
]
}
fn env_vars() -> Vec<(String, String)> {
let mut env_vars = env_vars_no_sync_download();
env_vars.push((
// make downloads determinstic
"DENO_UNSTABLE_NPM_SYNC_DOWNLOAD".to_string(),
"1".to_string(),
));
env_vars
}

View file

@ -2,16 +2,9 @@ import { fromFileUrl } from "../../../../test_util/std/path/mod.ts";
const DENO_NODE_COMPAT_URL = Deno.env.get("DENO_NODE_COMPAT_URL");
const moduleAllUrl = `${DENO_NODE_COMPAT_URL}node/module_all.ts`;
const processUrl = `${DENO_NODE_COMPAT_URL}node/process.ts`;
let moduleName = import.meta.resolve(Deno.args[0]);
moduleName = fromFileUrl(moduleName);
const [moduleAll, processModule] = await Promise.all([
import(moduleAllUrl),
import(processUrl),
]);
Deno[Deno.internal].require.initializeCommonJs(
moduleAll.default,
processModule.default,
);
const moduleAll = await import(moduleAllUrl);
Deno[Deno.internal].node.initialize(moduleAll.default);
Deno[Deno.internal].require.Module._load(moduleName, null, true);

View file

@ -0,0 +1,21 @@
// this package will require a subpath like "ajv/dist/compile/codegen"
// and also get the parent directory index.js file using require("..")
import Ajv from "npm:ajv@~8.11";
import addFormats from "npm:ajv-formats@2.1.1";
import { expect } from "npm:chai@4.2";
const ajv = new Ajv();
addFormats(ajv);
const schema = {
type: "string",
format: "date",
formatMinimum: "2016-02-06",
formatExclusiveMaximum: "2016-12-27",
};
const validate = ajv.compile(schema);
expect(validate("2016-02-06")).to.be.true;
expect(validate("2016-02-05")).to.be.false;
console.log("Fini");

View file

@ -0,0 +1,16 @@
Download http://localhost:4545/npm/registry/ajv/ajv-8.11.0.tgz
Download http://localhost:4545/npm/registry/ajv-formats/ajv-formats-2.1.1.tgz
Download http://localhost:4545/npm/registry/assertion-error/assertion-error-1.1.0.tgz
Download http://localhost:4545/npm/registry/chai/chai-4.3.6.tgz
Download http://localhost:4545/npm/registry/check-error/check-error-1.0.2.tgz
Download http://localhost:4545/npm/registry/deep-eql/deep-eql-3.0.1.tgz
Download http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.1.3.tgz
Download http://localhost:4545/npm/registry/get-func-name/get-func-name-2.0.0.tgz
Download http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-1.0.0.tgz
Download http://localhost:4545/npm/registry/loupe/loupe-2.3.4.tgz
Download http://localhost:4545/npm/registry/pathval/pathval-1.1.1.tgz
Download http://localhost:4545/npm/registry/punycode/punycode-2.1.1.tgz
Download http://localhost:4545/npm/registry/require-from-string/require-from-string-2.0.2.tgz
Download http://localhost:4545/npm/registry/type-detect/type-detect-4.0.8.tgz
Download http://localhost:4545/npm/registry/uri-js/uri-js-4.4.1.tgz
Fini

View file

@ -0,0 +1,12 @@
import chalk from "npm:chalk@4";
import { expect } from "npm:chai@4.2";
console.log(chalk.green("chalk cjs loads"));
const timeout = setTimeout(() => {}, 0);
expect(timeout).to.be.a("number");
clearTimeout(timeout);
const interval = setInterval(() => {}, 100);
expect(interval).to.be.a("number");
clearInterval(interval);

View file

@ -0,0 +1,15 @@
Download http://localhost:4545/npm/registry/ansi-styles/ansi-styles-4.3.0.tgz
Download http://localhost:4545/npm/registry/assertion-error/assertion-error-1.1.0.tgz
Download http://localhost:4545/npm/registry/chai/chai-4.3.6.tgz
Download http://localhost:4545/npm/registry/chalk/chalk-4.1.2.tgz
Download http://localhost:4545/npm/registry/check-error/check-error-1.0.2.tgz
Download http://localhost:4545/npm/registry/color-convert/color-convert-2.0.1.tgz
Download http://localhost:4545/npm/registry/color-name/color-name-1.1.4.tgz
Download http://localhost:4545/npm/registry/deep-eql/deep-eql-3.0.1.tgz
Download http://localhost:4545/npm/registry/get-func-name/get-func-name-2.0.0.tgz
Download http://localhost:4545/npm/registry/has-flag/has-flag-4.0.0.tgz
Download http://localhost:4545/npm/registry/loupe/loupe-2.3.4.tgz
Download http://localhost:4545/npm/registry/pathval/pathval-1.1.1.tgz
Download http://localhost:4545/npm/registry/supports-color/supports-color-7.2.0.tgz
Download http://localhost:4545/npm/registry/type-detect/type-detect-4.0.8.tgz
chalk cjs loads

View file

@ -0,0 +1,4 @@
A
Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
B
C

View file

@ -0,0 +1,3 @@
const importName = "./other.ts";
console.log("A");
await import(importName);

View file

@ -0,0 +1,4 @@
console.log("B");
const chalk = (await import("npm:chalk@5")).default;
console.log(chalk.green("C"));

7
cli/tests/testdata/npm/esm/main.js vendored Normal file
View file

@ -0,0 +1,7 @@
import chalk from "npm:chalk@5";
console.log(chalk.green("chalk esm loads"));
export function test(value) {
return chalk.red(value);
}

2
cli/tests/testdata/npm/esm/main.out vendored Normal file
View file

@ -0,0 +1,2 @@
Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
chalk esm loads

5
cli/tests/testdata/npm/esm/test.js vendored Normal file
View file

@ -0,0 +1,5 @@
import { test } from "./main.js";
Deno.test("test", () => {
console.log(test("test"));
});

12
cli/tests/testdata/npm/esm/test.out vendored Normal file
View file

@ -0,0 +1,12 @@
Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
Check [WILDCARD]/std/node/module_all.ts
chalk esm loads
running 1 test from ./npm/esm/test.js
test ...
------- output -------
test
----- output end -----
test ... ok ([WILDCARD]ms)
ok | 1 passed | 0 failed ([WILDCARD]s)

View file

@ -0,0 +1,5 @@
{
"imports": {
"chalk": "npm:chalk@5"
}
}

View file

@ -0,0 +1,7 @@
import chalk from "chalk";
console.log(chalk.green("chalk import map loads"));
export function test(value) {
return chalk.red(value);
}

View file

@ -0,0 +1,2 @@
Download http://localhost:4545/npm/registry/chalk/chalk-5.0.1.tgz
chalk import map loads

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,318 @@
{
"_id": "assertion-error",
"_rev": "17-95a34e275de6ed2a7809e331289d8a38",
"name": "assertion-error",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"dist-tags": { "latest": "2.0.0" },
"versions": {
"0.1.0": {
"name": "assertion-error",
"version": "0.1.0",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"license": "MIT",
"keywords": [],
"repository": {
"type": "git",
"url": "git@github.com:qualiancy/assertion-error.git"
},
"engines": { "node": "*" },
"main": "./index",
"scripts": { "test": "make test" },
"dependencies": {},
"devDependencies": { "component": "*" },
"_id": "assertion-error@0.1.0",
"dist": {
"shasum": "555cb007e89be44ba73e7b9600c3907dc381ce2b",
"tarball": "http://localhost:4545/npm/registry/assertion-error/assertion-error-0.1.0.tgz",
"integrity": "sha512-5GDYNFgUTLRv4GignYXrUUHcxAzLafgfWYWzWXTeBiimgLrxSW7HTNNAXnHyypP0mS34OOrQ6xpOwe5iePe48w==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDSOgg+BYn+W1TNWZFSVXnGIW5/6LO+LwqfQJ048hUxcgIgfQxa0B3fNmKfc2QeVPGMRm9IldEcwByMoh+GNLsTog0="
}
]
},
"_from": ".",
"_npmVersion": "1.2.14",
"_npmUser": { "name": "jakeluer", "email": "jake@alogicalparadox.com" },
"maintainers": [
{ "name": "jakeluer", "email": "jake@alogicalparadox.com" }
],
"directories": {}
},
"1.0.0": {
"name": "assertion-error",
"version": "1.0.0",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"license": "MIT",
"keywords": ["test", "assertion", "assertion-error"],
"repository": {
"type": "git",
"url": "git@github.com:chaijs/assertion-error.git"
},
"engines": { "node": "*" },
"main": "./index",
"scripts": { "test": "make test" },
"dependencies": {},
"devDependencies": { "component": "*" },
"bugs": { "url": "https://github.com/chaijs/assertion-error/issues" },
"_id": "assertion-error@1.0.0",
"dist": {
"shasum": "c7f85438fdd466bc7ca16ab90c81513797a5d23b",
"tarball": "http://localhost:4545/npm/registry/assertion-error/assertion-error-1.0.0.tgz",
"integrity": "sha512-g/gZV+G476cnmtYI+Ko9d5khxSoCSoom/EaNmmCfwpOvBXEJ18qwFrxfP1/CsIqk2no1sAKKwxndV0tP7ROOFQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDnmhFogTTZa4E1MfbbZn2eDsEN2qxGw6nImAN7NjImFgIhAMbkTUU91blDDpuAzdP6jBBIGHukoDrHhkjD8RtJHQME"
}
]
},
"_from": ".",
"_npmVersion": "1.2.23",
"_npmUser": { "name": "jakeluer", "email": "jake@alogicalparadox.com" },
"maintainers": [
{ "name": "jakeluer", "email": "jake@alogicalparadox.com" }
],
"directories": {}
},
"1.0.1": {
"name": "assertion-error",
"version": "1.0.1",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"license": "MIT",
"keywords": ["test", "assertion", "assertion-error"],
"repository": {
"type": "git",
"url": "git@github.com:chaijs/assertion-error.git"
},
"engines": { "node": "*" },
"main": "./index",
"scripts": { "test": "make test" },
"dependencies": {},
"devDependencies": { "component": "*" },
"gitHead": "db10d2fc753f00b3dad24956921056eaf1e03708",
"bugs": { "url": "https://github.com/chaijs/assertion-error/issues" },
"homepage": "https://github.com/chaijs/assertion-error",
"_id": "assertion-error@1.0.1",
"_shasum": "35aaeec33097f11f42399ecadf33faccd27f5c4c",
"_from": ".",
"_npmVersion": "1.4.28",
"_npmUser": { "name": "jakeluer", "email": "jake@alogicalparadox.com" },
"maintainers": [
{ "name": "jakeluer", "email": "jake@alogicalparadox.com" }
],
"dist": {
"shasum": "35aaeec33097f11f42399ecadf33faccd27f5c4c",
"tarball": "http://localhost:4545/npm/registry/assertion-error/assertion-error-1.0.1.tgz",
"integrity": "sha512-vSfN0UZYL0hwYkKhFq48vEI7CUJkgELo+xtcdjM/X9o5NRY4GW8PLQUDxQ1KYaugkPpnws9LCxEGzMfYWzL/Ww==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQD/H+TZ2RE5BBywaNop0yBuFVklnwE5RXhO0eARDgB4LwIgeTtsnwuVXY+wqeknKvvsN9xBvIzeeAA1gw18VVEvqMw="
}
]
},
"directories": {}
},
"1.0.2": {
"name": "assertion-error",
"version": "1.0.2",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"license": "MIT",
"keywords": ["test", "assertion", "assertion-error"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/assertion-error.git"
},
"engines": { "node": "*" },
"main": "./index",
"scripts": { "test": "make test" },
"dependencies": {},
"devDependencies": { "component": "*" },
"gitHead": "b36f593951c1487fa33747c9911025734923f28c",
"bugs": { "url": "https://github.com/chaijs/assertion-error/issues" },
"homepage": "https://github.com/chaijs/assertion-error#readme",
"_id": "assertion-error@1.0.2",
"_shasum": "13ca515d86206da0bac66e834dd397d87581094c",
"_from": ".",
"_npmVersion": "3.8.9",
"_nodeVersion": "5.7.0",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "13ca515d86206da0bac66e834dd397d87581094c",
"tarball": "http://localhost:4545/npm/registry/assertion-error/assertion-error-1.0.2.tgz",
"integrity": "sha512-wzQs0MF+xNG9ji/rooK2bLg8XVqP+dn/IYX6qgejMtmDNB8JRLL+BoBrd4furQNgPaWhJaQRXyMXGa48lzsGtQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCLcWfk28lkeQX/e39Gdc+vmgfvlluLHY0EUV215S9VfwIgWG+WCGpIZrvbJHJjx6GsOxS63ISwDqJjagoxWwPqATc="
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/assertion-error-1.0.2.tgz_1465237527264_0.8082898685242981"
},
"directories": {}
},
"1.1.0": {
"name": "assertion-error",
"version": "1.1.0",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"license": "MIT",
"types": "./index.d.ts",
"keywords": ["test", "assertion", "assertion-error"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/assertion-error.git"
},
"engines": { "node": "*" },
"main": "./index",
"scripts": { "test": "make test" },
"dependencies": {},
"devDependencies": { "component": "*", "typescript": "^2.6.1" },
"gitHead": "faa3f8cbbdba74d2760f9d2e95c008ba9ce4812e",
"bugs": { "url": "https://github.com/chaijs/assertion-error/issues" },
"homepage": "https://github.com/chaijs/assertion-error#readme",
"_id": "assertion-error@1.1.0",
"_npmVersion": "5.6.0",
"_nodeVersion": "8.8.0",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"shasum": "e60b6b0e8f301bd97e5375215bda406c85118c0b",
"tarball": "http://localhost:4545/npm/registry/assertion-error/assertion-error-1.1.0.tgz",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIBLKjetp37+0lhhi9deyZvXmBZcF/3rW0uJJtY/162bGAiA/3giMIaJv7sRAruur386mr5e9OzyX7FBDJo6ugT1cxQ=="
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/assertion-error-1.1.0.tgz_1515337170361_0.5846316555980593"
},
"directories": {}
},
"2.0.0": {
"name": "assertion-error",
"version": "2.0.0",
"description": "Error constructor for test and validation frameworks that implements standardized AssertionError specification.",
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"license": "MIT",
"types": "./dist/mod.d.ts",
"keywords": ["test", "assertion", "assertion-error"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/assertion-error.git"
},
"engines": { "node": ">=12" },
"type": "module",
"module": "./dist/mod.js",
"main": "./dist/mod.js",
"scripts": {
"build": "tsc",
"pretest": "npm run build",
"test": "NODE_ENV=test node ./test/index.js"
},
"devDependencies": { "typescript": "^4.4.3" },
"gitHead": "06761d175ab7d188c18c1c7ed1ea5ae4a6a4d52c",
"bugs": { "url": "https://github.com/chaijs/assertion-error/issues" },
"homepage": "https://github.com/chaijs/assertion-error#readme",
"_id": "assertion-error@2.0.0",
"_nodeVersion": "16.8.0",
"_npmVersion": "7.21.0",
"dist": {
"integrity": "sha512-Q0en67fcMTcBp1xn4DTYasTSKD4KAo86UhA6lr+c6neaz2gelKi5ILIqLcYl9JGWkGGbooYLs2iGQv7v1e83AA==",
"shasum": "791a05c4b3c3f70652b51dcda070b9ef89da662c",
"tarball": "http://localhost:4545/npm/registry/assertion-error/assertion-error-2.0.0.tgz",
"fileCount": 5,
"unpackedSize": 5776,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2j2mCRA9TVsSAnZWagAAj3MP/jHlgRzlMC4+uXz+3raT\ntp7ow0G53y7WkQXSou8+deifgO/AKPbgX5osfckjobDllMBRd8KqMvMn6I4X\nIdywrmDkXn2nutVGTwFi616leeXUlnyht7Jst6zhIEjDukPQ/RBZ+qT8V8H3\nvbzrmpjXj1EZdEMHnKQMdPriFe8ueZBE/bzpDS5AW/seaI/BkEAfx97HesVd\nicHcoOvlLgt7SWGfBArUlZC6ufB8eOl/LFpBaFh7fXHjh/kBmDGGEz3eGXU9\nOhgMgpg5k9/shMb3kIf8hJ/31eWHf9vcU7QPv5U1+z3FaKt/hdCaWfrjpkAz\ne1UE0j+qwYOKWYYyrjFmIS4ZSUf4tzP+y1Rz91kZHKZqipvVARhELGRclrSh\nxINCWcqGmOiuqnh4y3F4gC/K1IGN7rth4Ha67u+yXTFOLwMY0eTVpvu/1OrN\n+sEbccNw+uWO7T+itkc4/DuwFdpCa+LRcOterYmxgSyVoCrwsD1/oeYh6tUN\nMhZXXEoN1+Gkc3rsDc3q53rz6mNSmW+otUUhOjrfLOE6fzl6m9pBLCFTFT6V\ndT60KPLlN4Kv7tEBol/AS4bDu320NpXo2IB/QtKLFHlmxXrKEYXvhVHOUpzh\nWDa2bNhBFKkFoiBG6Z8GTGRup4rQvVtbOwHOP0ygHvWuKOujFP5sZMqPP3kS\nbxPQ\r\n=vExu\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCb5vGpzCFi2x+1kbn4dHWMTFIn60/LpTEVxMDoTLNFOAIgO/CAtZzdsNwg94EdSSQlwPA2nyk+rmmGBz09JVL3dIA="
}
]
},
"_npmUser": { "name": "chai", "email": "chaijs@keithcirkel.co.uk" },
"directories": {},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
{ "name": "chai", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/assertion-error_2.0.0_1633447251025_0.35381096573804993"
},
"_hasShrinkwrap": false
}
},
"readme": "<p align=center>\n AssertionError and AssertionResult classes.\n</p>\n\n<p align=center>\n <a href=\"https://github.com/chaijs/assertion-error/actions\">\n <img\n alt=\"build:?\"\n src=\"https://github.com/chaijs/assertion-error/actions/workflows/nodejs.yml/badge.svg\"\n />\n </a><a href=\"https://www.npmjs.com/package/assertion-error\">\n <img\n alt=\"downloads:?\"\n src=\"https://img.shields.io/npm/dm/assertion-error.svg\"\n />\n </a><a href=\"\">\n <img\n alt=\"devDependencies:none\"\n src=\"https://img.shields.io/badge/dependencies-none-brightgreen\"\n />\n </a>\n</p>\n\n## What is AssertionError?\n\nAssertion Error is a module that contains two classes: `AssertionError`, which\nis an instance of an `Error`, and `AssertionResult` which is not an instance of\nError.\n\nThese can be useful for returning from a function - if the function \"succeeds\"\nreturn an `AssertionResult` and if the function fails return (or throw) an\n`AssertionError`.\n\nBoth `AssertionError` and `AssertionResult` implement the `Result` interface:\n\n```typescript\ninterface Result {\n name: 'AssertionError' | 'AssertionResult'\n ok: boolean\n toJSON(...args: unknown[]): Record<string, unknown>\n}\n```\n\nSo if a function returns `AssertionResult | AssertionError` it is easy to check\n_which_ one is returned by checking either `.name` or `.ok`, or check `instanceof Error`.\n\n## Installation\n\n### Node.js\n\n`assertion-error` is available on [npm](http://npmjs.org).\n\n```\n$ npm install --save assertion-error\n```\n\n### Deno\n\n`assertion_error` is available on [Deno.land](https://deno.land/x/assertion_error)\n\n```typescript\nimport {AssertionError, AssertionResult} from 'https://deno.land/x/assertion_error@2.0.0/mod.ts'\n```\n",
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
{ "name": "chai", "email": "chaijs@keithcirkel.co.uk" }
],
"time": {
"modified": "2022-06-13T03:33:52.316Z",
"created": "2013-04-07T22:59:41.018Z",
"0.1.0": "2013-04-07T22:59:42.826Z",
"1.0.0": "2013-06-08T20:41:17.202Z",
"1.0.1": "2015-03-05T23:45:54.576Z",
"1.0.2": "2016-06-06T18:25:29.009Z",
"1.1.0": "2018-01-07T14:59:31.257Z",
"2.0.0": "2021-10-05T15:20:51.185Z"
},
"author": {
"name": "Jake Luer",
"email": "jake@qualiancy.com",
"url": "http://qualiancy.com"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/assertion-error.git"
},
"homepage": "https://github.com/chaijs/assertion-error#readme",
"keywords": ["test", "assertion", "assertion-error"],
"bugs": { "url": "https://github.com/chaijs/assertion-error/issues" },
"license": "MIT",
"readmeFilename": "README.md"
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,384 @@
{
"_id": "color-name",
"_rev": "16-0b775155abb6444519e5f1c7655731ca",
"name": "color-name",
"description": "A list of color names and its values",
"dist-tags": { "latest": "1.1.4" },
"versions": {
"0.0.1": {
"name": "color-name",
"version": "0.0.1",
"description": "A list of color names and its values",
"main": "index.json",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git@github.com:dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "Dyma Ywanov" },
"license": "unlicensed",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"_id": "color-name@0.0.1",
"dist": {
"shasum": "c824e087906bc0683062ab47272df7be6ec94659",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-0.0.1.tgz",
"integrity": "sha512-h+3SQlhFZPTPTyLnkh24T8iwDqQ+dTeGkxxsf/bKypCiEGsw185T35HfiKVunj24vphahSdLWbTVvG9PFHVaxQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCuC02YIefm9IH7n1Z4xUhJuf5bPQ6s7Lyh9LV2risHoAIgfuyKQVuHuyiWk1psrQJcJBs8jFqbiWkMnktRNfq8J00="
}
]
},
"_from": ".",
"_npmVersion": "1.3.24",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"directories": {}
},
"0.0.2": {
"name": "color-name",
"version": "0.0.2",
"description": "A list of color names and its values",
"main": "index.json",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git@github.com:dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "Dyma Ywanov" },
"license": "unlicensed",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"_id": "color-name@0.0.2",
"dist": {
"shasum": "767c4389d07d4bec162f5fb0b87a8c9b81a3c0af",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-0.0.2.tgz",
"integrity": "sha512-ubJSEdDiEKySKubTMBG03Ulo4zDLculwX6xgkYYA5H6HEiMniEWqty0LUwyrKxz8v6s1+r0202HSsJsU7D+Gng==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDBsIX70G5+ywhz+3t744W+tqfTxhvSffFLy5MEd1XO4QIhAN9ZmOJCZMdSok032PD5xM8vIYWPC53K6XLHMGbFCAVy"
}
]
},
"_from": ".",
"_npmVersion": "1.3.24",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"directories": {}
},
"1.0.0": {
"name": "color-name",
"version": "1.0.0",
"description": "A list of color names and its values",
"main": "index.json",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git@github.com:dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "Dyma Ywanov" },
"license": "unlicensed",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"_id": "color-name@1.0.0",
"dist": {
"shasum": "ce3579a4ef43b672bee4f37e8876332b5a36e6b5",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.0.0.tgz",
"integrity": "sha512-EGBM2T7+LfAKfv+ovjidZ+KPgItQSdjMdzNsvecNLLEjwKOG2XAfJKhJo5hUuX1+i/ofedvabKZwt+S46u3v7g==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIGAC0Z6T+uOZw8eSou0CEOt84uKcsyXSSi/W+OxRGOCdAiA9rBcIS3hTTaMEznF7lUMVBR+wVv3u1x4qD1+jCnXzOw=="
}
]
},
"_from": ".",
"_npmVersion": "1.3.24",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"directories": {}
},
"1.0.1": {
"name": "color-name",
"version": "1.0.1",
"description": "A list of color names and its values",
"main": "index.json",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git@github.com:dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "Dyma Ywanov" },
"license": "Unlicense",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"gitHead": "6d51c7376a86c96c9a645f7226e2cba1ffcf8c05",
"_id": "color-name@1.0.1",
"_shasum": "6b34b2b29b7716013972b0b9d5bedcfbb6718df8",
"_from": ".",
"_npmVersion": "2.5.1",
"_nodeVersion": "0.12.0",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"dist": {
"shasum": "6b34b2b29b7716013972b0b9d5bedcfbb6718df8",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.0.1.tgz",
"integrity": "sha512-ipj55CYipJcmYpiDwpDRZ91iMJOnsTW9wICiE1efyPWadY2FapkgfTvB8IJLxf5muHHrpKVVxhEnv03UIshOJQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIGjavfffqx2iZoyd8GzL2R+Bi2KsXIAK7vvd4BCZ2Sn4AiBkOV+UYLoJDofDkuITBSMq61ZzRQ85JG9NsNYezdazPQ=="
}
]
},
"directories": {}
},
"1.1.0": {
"name": "color-name",
"version": "1.1.0",
"description": "A list of color names and its values",
"main": "index.js",
"scripts": { "test": "node test.js" },
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "DY", "email": "dfcreative@gmail.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"gitHead": "0ccc911ab063f15b8d89f137bacef3955b99e838",
"_id": "color-name@1.1.0",
"_shasum": "a5481420307855e5bdbdbc26bc4b39d864828fcd",
"_from": ".",
"_npmVersion": "3.3.12",
"_nodeVersion": "5.3.0",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"dist": {
"shasum": "a5481420307855e5bdbdbc26bc4b39d864828fcd",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.1.0.tgz",
"integrity": "sha512-+cCpbUmNJ/7SCcD6RKVuIwXvd3oeSYTLDR8lJlk7ofhchGHp7EMit4q5AjCHLTc1Cyin4TIrWmhaukp0EORPkg==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIAdK4Wc5m4JSRNIHyphLoIzKIbBhcQxYk7VuNoPhlpmnAiEAkDsR+EBvNbGN/T2iNtyaXpS4Jmc0BpAuxtqtW3AsM6g="
}
]
},
"directories": {}
},
"1.1.1": {
"name": "color-name",
"version": "1.1.1",
"description": "A list of color names and its values",
"main": "index.js",
"scripts": { "test": "node test.js" },
"files": ["index.js"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "DY", "email": "dfcreative@gmail.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"gitHead": "b47de1bf75da523d6d6061a41f7f0c9bb7c213bf",
"_id": "color-name@1.1.1",
"_shasum": "4b1415304cf50028ea81643643bd82ea05803689",
"_from": ".",
"_npmVersion": "3.3.12",
"_nodeVersion": "5.3.0",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"dist": {
"shasum": "4b1415304cf50028ea81643643bd82ea05803689",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.1.1.tgz",
"integrity": "sha512-KueG6e1jnj4enh6KzhXxA51awXK/yB4z1gUNPuH81hLDdmvmiQU4EDL1mZPB4m9rxEJkZ+kqmd51Ml9rSz2B3g==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIHPAypeXYwmXNlnPj/dE4AERIXSEJHoIEGxC0/JXmisBAiAObNO9Co2OZ8v8289fhsy7lrG7p8HYaapJqX8jOJeO9g=="
}
]
},
"directories": {}
},
"1.1.2": {
"name": "color-name",
"version": "1.1.2",
"description": "A list of color names and its values",
"main": "index.js",
"scripts": { "test": "node test.js" },
"files": ["index.js"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "DY", "email": "dfcreative@gmail.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"gitHead": "db3f3979970c30380f30ae3209a144c855578ae1",
"_id": "color-name@1.1.2",
"_shasum": "5c8ab72b64bd2215d617ae9559ebb148475cf98d",
"_from": ".",
"_npmVersion": "3.7.2",
"_nodeVersion": "6.2.0",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"dist": {
"shasum": "5c8ab72b64bd2215d617ae9559ebb148475cf98d",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.1.2.tgz",
"integrity": "sha512-UzOVwiu1XqofxLGE8CyCtJySssb2YtmDn/PoNJgvOrqGrH0w6h3MlfRAo1qHIZHzX/Ov1kXHKv/7OwsIX0Ot+Q==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQC0GwOwCSjpYtwk21Qlufv7KwdT6ZfAzWhQ3cY8zfen5QIhAK2tNeZy0zlDCKRU8HEKs5PC+vFGRLn7P8FLDap5PjFY"
}
]
},
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/color-name-1.1.2.tgz_1489460073624_0.09481105045415461"
},
"directories": {}
},
"1.1.3": {
"name": "color-name",
"version": "1.1.3",
"description": "A list of color names and its values",
"main": "index.js",
"scripts": { "test": "node test.js" },
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/dfcreative/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "DY", "email": "dfcreative@gmail.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/dfcreative/color-name/issues" },
"homepage": "https://github.com/dfcreative/color-name",
"gitHead": "cb7d4629b00fe38564f741a0779f6ad84d8007a2",
"_id": "color-name@1.1.3",
"_shasum": "a7d0558bd89c42f795dd42328f740831ca53bc25",
"_from": ".",
"_npmVersion": "4.6.1",
"_nodeVersion": "8.1.2",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"dist": {
"shasum": "a7d0558bd89c42f795dd42328f740831ca53bc25",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDzKQts2FJq//siNTEblzss3pfSXqBCbyYqpigBXVzO3AIhAKgONJYDUfAClb2tknEu48xoMUPwhUUWdnWDz0UCtNzM"
}
]
},
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/color-name-1.1.3.tgz_1500157027207_0.5641644957941025"
},
"directories": {}
},
"1.1.4": {
"name": "color-name",
"version": "1.1.4",
"description": "A list of color names and its values",
"main": "index.js",
"scripts": { "test": "node test.js" },
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/colorjs/color-name.git"
},
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"author": { "name": "DY", "email": "dfcreative@gmail.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/colorjs/color-name/issues" },
"homepage": "https://github.com/colorjs/color-name",
"gitHead": "4536ce5944f56659a2dfb2198eaf81b5ad5f2ad9",
"_id": "color-name@1.1.4",
"_npmVersion": "6.4.1",
"_nodeVersion": "8.11.1",
"_npmUser": { "name": "dfcreative", "email": "df.creative@gmail.com" },
"dist": {
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"shasum": "c2a09a87acbde69543de6f63fa3995c826c536a2",
"tarball": "http://localhost:4545/npm/registry/color-name/color-name-1.1.4.tgz",
"fileCount": 4,
"unpackedSize": 6693,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbpMyZCRA9TVsSAnZWagAA8GsP/0AsmYCiGphh3CFKIPep\nvNTX/KZgee4XYpqtD9GtlSg2t7vq3RzzMqe0ZVaVtI6lHu6xbx1sjCSKveN2\nhhzpchB4yDFadju+d180Blrawa+JAuJW+mG5k346Iqt6d8zuPPrHhraR6fEY\ntHCVxhQiHpgyzoyMATZnII8fNc236SCgvDwV0vJsJS3xbJp21peIVgZAOZg+\nKNzcM6dH1yxgZb99THhHYI4za/+xkIm2oy8o9AKIJz8HcogqOG5MHaklc5R+\niZlIE5A9KpbUbLerhUatXUKu6CeosCbQcPcYsOfifXw5ifQunM86ySU6OgQF\nSADAeVO6k5ZBFvzaSjc7La7+MisZ2KPAKiegCLMxcqc5xVBCcjZb0F7vS59m\nHTAa/uHLgmv76wiNMz2zHR+1qYWt3/mQq5OItunccFZQ5jxw3JWzygY9C/Zs\ndUakmc6+pCScPuDzs6OruKqHPk4S0fv8HfH8wBGFzd0GvHtT8xKUmit5p6G7\nTIPJV+dVaz5iO8uhhtUpVUogs8Y9DyoRDBaz3Btq19B8sYBwacMlRZCHiwBQ\nYdpTe9Go7NBPUNYEUsiSiZxCT6GuIdCit6P6Dwx6AZ3+DdeTEB1DcF9UVycE\nwbc1jz10q0pTbW5REgtFZ5eDTVXUkepA3+P6sLwubq7yu8lsqO34tYp3rOop\nshOJ\r\n=Rq6j\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIA/cRJF1USbKE8OvNZK7EOTIg9+Bg+KvqGyAcFM83/7VAiB4QKj7PJ06UPRuqXUutmL6e+n5XgOGZlpNzYmkOyPUSQ=="
}
]
},
"maintainers": [
{ "name": "dfcreative", "email": "df.creative@gmail.com" }
],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/color-name_1.1.4_1537526936346_0.08590528311695667"
},
"_hasShrinkwrap": false
}
},
"readme": "A JSON with color names and its values. Based on http://dev.w3.org/csswg/css-color/#named-colors.\r\n\r\n[![NPM](https://nodei.co/npm/color-name.png?mini=true)](https://nodei.co/npm/color-name/)\r\n\r\n\r\n```js\r\nvar colors = require('color-name');\r\ncolors.red //[255,0,0]\r\n```\r\n\r\n<a href=\"LICENSE\"><img src=\"https://upload.wikimedia.org/wikipedia/commons/0/0c/MIT_logo.svg\" width=\"120\"/></a>\r\n",
"maintainers": [{ "name": "dfcreative", "email": "df.creative@gmail.com" }],
"time": {
"modified": "2022-06-13T06:31:20.486Z",
"created": "2014-11-23T16:18:30.217Z",
"0.0.1": "2014-11-23T16:18:30.217Z",
"0.0.2": "2014-11-23T16:21:53.606Z",
"1.0.0": "2014-12-15T19:08:24.911Z",
"1.0.1": "2015-09-21T02:51:08.141Z",
"1.1.0": "2015-12-24T02:03:18.586Z",
"1.1.1": "2015-12-24T02:05:36.986Z",
"1.1.2": "2017-03-14T02:54:35.452Z",
"1.1.3": "2017-07-15T22:17:08.140Z",
"1.1.4": "2018-09-21T10:48:56.546Z"
},
"homepage": "https://github.com/colorjs/color-name",
"keywords": ["color-name", "color", "color-keyword", "keyword"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/colorjs/color-name.git"
},
"author": { "name": "DY", "email": "dfcreative@gmail.com" },
"bugs": { "url": "https://github.com/colorjs/color-name/issues" },
"license": "MIT",
"readmeFilename": "README.md",
"users": { "tg-z": true }
}

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,996 @@
{
"_id": "fast-deep-equal",
"_rev": "24-a2aa17e20fc6209a262d41bf02733c2a",
"name": "fast-deep-equal",
"description": "Fast deep equal",
"dist-tags": { "latest": "3.1.3", "beta": "3.0.0-beta.2" },
"versions": {
"0.0.1": {
"name": "fast-deep-equal",
"version": "0.0.1",
"description": "Fast deep equal",
"main": "index.js",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"gitHead": "3d6d9ef5717f3fe1666e64d2d31271825cdba406",
"_id": "fast-deep-equal@0.0.1",
"_shasum": "18a9a0a1eb9f64308696c451e758e0dd593455cb",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "6.9.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "18a9a0a1eb9f64308696c451e758e0dd593455cb",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-0.0.1.tgz",
"integrity": "sha512-BoSRog3gyM/Op9zNY4D8baPC54Qbbim86mf8ac8zdCqZVtO7xXbwPxnmi8q+dR/ntN1Hqv4eQ9LisTB43yms6g==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCeTW/wRgjxWpwbiUOVNi0btb9i4u2RljKC1uwmqWTQKgIgayEMJ1J6iFqwUbEfpk5qDWnJBORVyosZ9dBCaUBbB6g="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal-0.0.1.tgz_1497565588844_0.36595384287647903"
},
"directories": {}
},
"0.1.0": {
"name": "fast-deep-equal",
"version": "0.1.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js spec",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test": "npm run eslint && npm run test-cov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "7a8f904fcefb081adb45f3b293dccb4945e2e85c",
"_id": "fast-deep-equal@0.1.0",
"_shasum": "5c6f4599aba6b333ee3342e2ed978672f1001f8d",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "6.9.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "5c6f4599aba6b333ee3342e2ed978672f1001f8d",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-0.1.0.tgz",
"integrity": "sha512-hPWh1g6qiKvTahrwdMaLXVQ3LEIJVfaE4rlfjjR/3p+Yzhfelr0RPGTnBmRwxJ2ffhekJ1iqYPEgpNTvLe2jUg==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIEKl8M/ey60TIpKvnboCbB5DIFVBaUMIq4KxQKCy0cXzAiEA7eJ5BWZ1RqTyCZ4/kTXUfI/UIW87f7Snwn7ZZUIxzAI="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal-0.1.0.tgz_1497650347241_0.6521883145906031"
},
"directories": {}
},
"1.0.0": {
"name": "fast-deep-equal",
"version": "1.0.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test": "npm run eslint && npm run test-cov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"benchmark": "^2.1.4",
"coveralls": "^2.13.1",
"deep-eql": "^2.0.2",
"deep-equal": "^1.0.1",
"eslint": "^4.0.0",
"lodash": "^4.17.4",
"mocha": "^3.4.2",
"nano-equal": "^1.0.1",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"shallow-equal-fuzzy": "0.0.2",
"underscore": "^1.8.3"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "b876854e5e56eb5baf79eb434d4bcb81f4c30b9a",
"_id": "fast-deep-equal@1.0.0",
"_shasum": "96256a3bc975595eb36d82e9929d060d893439ff",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "6.9.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "96256a3bc975595eb36d82e9929d060d893439ff",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-1.0.0.tgz",
"integrity": "sha512-46+Jxk9Yj/nQY+3a1KTnpbBTemcAbPySTKya8iM9D7EsiONpSWbvzesalcCJ6tmJrCUITT2fmAQfNHFG+OHM6Q==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIDCx4qLZzsGfwB0A9s2I3sA2oZmZykDwMXVd/bIwikG9AiBSnBjDi+XjGZpfo7tDcDYJ5/4mE8/mhBuDrc4owv6CcA=="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal-1.0.0.tgz_1497730970672_0.7519061632920057"
},
"directories": {}
},
"1.1.0": {
"name": "fast-deep-equal",
"version": "1.1.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run eslint && npm run test-ts && npm run test-cov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"benchmark": "^2.1.4",
"coveralls": "^2.13.1",
"deep-eql": "^2.0.2",
"deep-equal": "^1.0.1",
"eslint": "^4.0.0",
"lodash": "^4.17.4",
"mocha": "^3.4.2",
"nano-equal": "^1.0.1",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"shallow-equal-fuzzy": "0.0.2",
"typescript": "^2.6.1",
"underscore": "^1.8.3"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"files": ["index.js", "index.d.ts"],
"types": "index.d.ts",
"gitHead": "4b879ceed561ad14665f50b1073f7107245ead1e",
"_id": "fast-deep-equal@1.1.0",
"_shasum": "c053477817c86b51daa853c81e059b733d023614",
"_from": ".",
"_npmVersion": "3.10.10",
"_nodeVersion": "6.13.0",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"dist": {
"shasum": "c053477817c86b51daa853c81e059b733d023614",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-1.1.0.tgz",
"fileCount": 5,
"unpackedSize": 5254,
"integrity": "sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDAvfRPgC7Af9p3+BcVhpYXo+MX3GfYzhyVlOq1F6Rn1gIgQizMrL0sPViaiv3PJy/E3gJoFRLIGz4W4FA07UClQEg="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_1.1.0_1519591549336_0.5661688195911738"
},
"_hasShrinkwrap": false
},
"2.0.0": {
"name": "fast-deep-equal",
"version": "2.0.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run eslint && npm run test-ts && npm run test-cov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"benchmark": "^2.1.4",
"coveralls": "^2.13.1",
"deep-eql": "latest",
"deep-equal": "latest",
"eslint": "^4.0.0",
"lodash": "latest",
"mocha": "^3.4.2",
"nano-equal": "latest",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"ramda": "latest",
"shallow-equal-fuzzy": "latest",
"typescript": "^2.6.1",
"underscore": "latest"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"files": ["index.js", "index.d.ts"],
"types": "index.d.ts",
"gitHead": "5a472bc5bde46f446d21138c5234cd101ce6d5e0",
"_id": "fast-deep-equal@2.0.0",
"_npmVersion": "5.6.0",
"_nodeVersion": "9.11.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"dist": {
"integrity": "sha512-nS7DU+NOwYHqiTuF5yHkS9DAdDOMZkqfu2+4QEmqWGBFEJjCemy1gfHF7g1vNdB/9hL5HpdDCkU1enn2sQ9xAg==",
"shasum": "eaa6d36ab9bf2ffb5fe3aa55c7ed1223e9cbd8b0",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-2.0.0.tgz",
"fileCount": 5,
"unpackedSize": 5410,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa5DnFCRA9TVsSAnZWagAAfoAP/jsUlFvBzx4gvLiAUq+h\nCv4KWU/D4F8An3Jsso3VTwUPmTH4TdjSHM3p9Hp66FycbCzQdU8YR1yjEFuQ\n9e1u5OnZwuQBIWp3ZVTYwn/sQuxHEbDWfCDMMiIXHsrsgd6GdVw4G4v2GBqG\nHWOWY2s6upZjHZrb4xWGGcYumWnf284T5yMZOR+N3tf4SQMJ9oDSBYCyh6IR\ngjeTkfU3pYvcVMdgfN+tLWnwp1mFcdI9GJLxgVmC2RF4f5n4tZGlu6e7EutX\nj0vrHZLyC6iyykTOShg5qxg0tnUq899yeaTbo2ZFt/80DjXWUhvHoyRIXPGn\ndJPmyTtAO+/SQlPAMSkDKXoubqSSTGJWDYZhzWVlqyarwN8HUd5eTsUn8unR\nUqeIkm3djDJt4y54yPEbj7g20XMbwiGcJvRsSrJ6rZ+8M044pa6oMzntH6CN\n20MyaX6fffz1HhmfCSlfXiNdnQNwvzXBIvCBSo5baQdkGLnRDE5VBjAxEolS\n1JnhtGKMPXLk15e7MBJCrx6/Hj7vn2JyVnOjYxEMCrm3v3W5hJCS/mDBFzPt\n0Dsgj4rRqzqqeeDxORIxeHBARcmHT4OoFG0rp4WpO//mQ6gdwXn7eZbssiXq\njRl2GGHeuak+WlntWb48cZ2ztMFFpabd7SAfZJDeN5zDJDvtFE7tyGlGt89z\n2dnO\r\n=r5zY\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIB1ROrL0qeuVj+zL3D3RcBjTIbC//f0pfySHslZXHhzZAiEA4+KJEZBXUZevc7HHKmIaNQowRkhclzS4M3jKOShzfNU="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_2.0.0_1524906436392_0.9757226693566117"
},
"_hasShrinkwrap": false
},
"2.0.1": {
"name": "fast-deep-equal",
"version": "2.0.1",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run eslint && npm run test-ts && npm run test-cov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"benchmark": "^2.1.4",
"coveralls": "^2.13.1",
"deep-eql": "latest",
"deep-equal": "latest",
"eslint": "^4.0.0",
"lodash": "latest",
"mocha": "^3.4.2",
"nano-equal": "latest",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"ramda": "latest",
"shallow-equal-fuzzy": "latest",
"typescript": "^2.6.1",
"underscore": "latest"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"files": ["index.js", "index.d.ts"],
"types": "index.d.ts",
"gitHead": "8a9c22e36a18a0b6a006d180572016c91e9f23e1",
"_id": "fast-deep-equal@2.0.1",
"_shasum": "7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49",
"_from": ".",
"_npmVersion": "4.2.0",
"_nodeVersion": "7.10.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"dist": {
"shasum": "7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-2.0.1.tgz",
"fileCount": 5,
"unpackedSize": 5420,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa5EcHCRA9TVsSAnZWagAATBcP+QATaW7yrJRQQz3cs6En\nm0Io9k9vGuptXBcCTp0FHZlx40MvfQLWxZY99tpm7RsOcIjiwj08B7M41ytM\n6JjgHsoHKzouGuTOEqwUo2FsOu2OO4af4eb2C6BFbEz3ipbGYUNc1eXZanFo\nn4HoFKZOqqMI83NoC36lHEA2w1IdIQvcMtk4Drqf/wg+/jAFFswtEQMs4Roi\nGYd4WpEUcZKuK7TzH70Q3U9kAsHcAH9Ro/aHpph1EpDGeAZKZ5s9KfvYh2ot\nJXWmmOOeg/vhtbhQ6tGoFfsxIQ8ZHc3p7rlZ4CfPIw68caQ6HweOs42TIdk6\nySO7te3zo9LtUgBMxOLTmAFKX/hGnhRYWx5rfX2IIQD8QC5795FfY2+8qfxo\n3pWXTyHm08J4kEP45vF65xf0Pk57BTKPO2b4cUayztWmELaVl+efmaYWf2jg\nHpybN7BMPWIqXpLLDXwRf7AcppiGvNN0kKozVJVv81H0mxbb4X4fW/GIBhrM\nytKcoMGLQiRbeCMak1ZE2+ckP042QOrKZrRm3LuILCeaW1zdiLKkZ/F2zZ0+\nrfXrQCltWobOYgEDzgF1e1aXgJfAYdPsgKPs/l+aZjv4BaZl2F9ltz0Kl4BS\nZ9ZYpucHldI23nNi9w+EETPxfFHvbLWKqru823aowwD7N2R2kWyAA89VLueU\nQ6+W\r\n=3lMs\r\n-----END PGP SIGNATURE-----\r\n",
"integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIFVFig/tJujGZfFzBYM5kUofgMlQ35INoLJ5erkp18qBAiEApHZxy6f1b0+fn/P0sCEl7r/51X2ZCsUJ2AAMkkQXBh4="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_2.0.1_1524909830041_0.13261732364737422"
},
"_hasShrinkwrap": false
},
"3.0.0-beta.0": {
"name": "fast-deep-equal",
"version": "3.0.0-beta.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"build": "node build",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"benchmark": "^2.1.4",
"coveralls": "^2.13.1",
"deep-eql": "latest",
"deep-equal": "latest",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"lodash": "latest",
"mocha": "^3.4.2",
"nano-equal": "latest",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"ramda": "latest",
"shallow-equal-fuzzy": "latest",
"typescript": "^2.6.1",
"underscore": "latest"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"readme": "# fast-deep-equal\nThe fastest deep equal\n\n[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal)\n[![npm version](https://badge.fury.io/js/fast-deep-equal.svg)](http://badge.fury.io/js/fast-deep-equal)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master)\n\n\nThis readme is for pre-release v3 with ES6 Map, Set and Typed arrays support.\n\nSee branch [v2](https://github.com/epoberezkin/fast-deep-equal/tree/v2) for the main version.\n\n\n## Install\n\n```bash\nnpm install fast-deep-equal\n```\n\n\n## Features\n\n- ES5 compatible\n- works in node.js (8+) and browsers (IE9+)\n- checks equality of Date and RegExp objects by value.\n\nES6 equal (`require('fast-deep-equal/es6')`) also supports:\n- Maps\n- Sets\n- Typed arrays\n\n\n## Usage\n\n```javascript\nvar equal = require('fast-deep-equal');\nconsole.log(equal({foo: 'bar'}, {foo: 'bar'})); // true\n```\n\nTo support ES6 Maps, Sets and Typed arrays equality use:\n\n```javascript\nvar equal = require('fast-deep-equal/es6');\nconsole.log(equal(Int16Array([1, 2]), Int16Array([1, 2]))); // true\n```\n\n\n## Performance benchmark\n\nNode.js v12.6.0:\n\n```\nfast-deep-equal x 325,485 ops/sec ±0.57% (86 runs sampled)\nfast-deep-equal/es6 x 261,338 ops/sec ±0.45% (89 runs sampled)\nnano-equal x 231,064 ops/sec ±0.62% (88 runs sampled)\nshallow-equal-fuzzy x 164,828 ops/sec ±0.87% (88 runs sampled)\nunderscore.isEqual x 91,247 ops/sec ±0.56% (88 runs sampled)\nlodash.isEqual x 48,000 ops/sec ±0.48% (86 runs sampled)\ndeep-equal x 73,699 ops/sec ±0.55% (86 runs sampled)\ndeep-eql x 42,804 ops/sec ±0.45% (87 runs sampled)\nramda.equals x 15,119 ops/sec ±0.49% (87 runs sampled)\nutil.isDeepStrictEqual x 58,458 ops/sec ±0.56% (89 runs sampled)\nassert.deepStrictEqual x 583 ops/sec ±0.47% (87 runs sampled)\n\nThe fastest is fast-deep-equal\n```\n\nTo run benchmark (requires node.js 6+):\n\n```bash\nnpm install\nnpm run build\nnode benchmark\n```\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE)\n",
"readmeFilename": "README.md",
"gitHead": "e61a878a94a819f3b407927a7b4b549d4596d701",
"_id": "fast-deep-equal@3.0.0-beta.0",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-VB9eg7F17nVCQ9WcHIcJMnyrX/xxGlxB3VvfTp2FE0vtRFT92Te9B2tXwTx+MzR+ofBXvtDF4qLzptiri0TrsQ==",
"shasum": "6168fba8e375247040d34c551414b50ac5aa4612",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.0.0-beta.0.tgz",
"fileCount": 5,
"unpackedSize": 6006,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdIfYuCRA9TVsSAnZWagAApjUP/RXYYl+Hlt124qpfyw65\nDVMJ6v0ly8ExIcLTepJcH75KjJ7icP51vJi5LzRjLP+jn18/jIGETZ1MtyLy\neHSyv/+fwcBpnLNJ9IFYcKqNc/gId7SfmBUrootbmhx5rtT9tbuV3NVnREtL\n+/B6bSYqsnkWb5J5L2Fh/00fQMSnqTUt/PAuyvc0+86x+ynnBM1Riqri0BCt\nPP7eWxPPQnnV2bE1fXMrL8/vNtaUxn8WrjpQCSdP3PcOR3lnQdyRNhPllTNN\ntsuB1m15B3kB/h0AoV1wbWZXq4gV/FSfzci19jMXOfj96Kaj4/yDJK4A7mbw\nhQXZil3JsJecnAF7B4/tv8p92cTdL2JbuXqVD6YiYK3ztRFlm7iCExilV2Ne\nI+4UjS7Nr+37OmED8ih8EBmfGxpYEQKygar6NHpde9/x9Di6lMhkg/4Mj+uq\n59SCyIbD0lrln7i4EHyFr42+lUpQ92MoR6X2ZOstkY+lGyJgywysqi/i7Wal\nFD2K4upTCGDgJxD5+Jz0EL62XgDv3VZPdbbsibQxYQn8Kw8IeYQsoah9rl1Z\nV14n0nV3SN5l/kMX3BtzeWnfxiHmf7U6JTqCbpETm5TxRnCY1u2j4zs81mJz\nfb6H7q2WnUY+ckVa0k1IWcuoPwX8jicqIShwy3UoIcXdFVAaxKUDjZVTJWno\nFzZ9\r\n=nmOL\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIFampEBYKCjL48SM/DBa4NdClRSs9xMJ4HmRBqBa6ydcAiASMuY15CVIw9wgx/W0nH/dE1m9oqB107vQ/t+Xmd2fGg=="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.0.0-beta.0_1562506797886_0.3308294011939501"
},
"_hasShrinkwrap": false
},
"3.0.0-beta.1": {
"name": "fast-deep-equal",
"version": "3.0.0-beta.1",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"build": "node build",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"benchmark": "^2.1.4",
"coveralls": "^2.13.1",
"deep-eql": "latest",
"deep-equal": "latest",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"lodash": "latest",
"mocha": "^3.4.2",
"nano-equal": "latest",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"ramda": "latest",
"shallow-equal-fuzzy": "latest",
"typescript": "^2.6.1",
"underscore": "latest"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"readme": "# fast-deep-equal\nThe fastest deep equal\n\n[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal)\n[![npm](https://img.shields.io/npm/v/fast-deep-equal.svg)](https://www.npmjs.com/package/fast-deep-equal)\n[![npm](https://img.shields.io/npm/v/fast-deep-equal/beta.svg)](https://www.npmjs.com/package/fast-deep-equal)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master)\n\n\nThis readme is for pre-release v3 with ES6 Map, Set and Typed arrays support.\n\nSee branch [v2](https://github.com/epoberezkin/fast-deep-equal/tree/v2) for the main version.\n\n\n## Install\n\nTo install v3 pre-release with ES6 Map, Set and Typed arrays support\n\n```bash\nnpm install fast-deep-equal@beta\n```\n\nTo install [v2](https://github.com/epoberezkin/fast-deep-equal/tree/v2)\n\n```bash\nnpm install fast-deep-equal\n```\n\n\n## Features\n\n- ES5 compatible\n- works in node.js (8+) and browsers (IE9+)\n- checks equality of Date and RegExp objects by value.\n\nES6 equal (`require('fast-deep-equal/es6')`) also supports:\n- Maps\n- Sets\n- Typed arrays\n\n\n## Usage\n\n```javascript\nvar equal = require('fast-deep-equal');\nconsole.log(equal({foo: 'bar'}, {foo: 'bar'})); // true\n```\n\nTo support ES6 Maps, Sets and Typed arrays equality use:\n\n```javascript\nvar equal = require('fast-deep-equal/es6');\nconsole.log(equal(Int16Array([1, 2]), Int16Array([1, 2]))); // true\n```\n\n\n## Performance benchmark\n\nNode.js v12.6.0:\n\n```\nfast-deep-equal x 325,485 ops/sec ±0.57% (86 runs sampled)\nfast-deep-equal/es6 x 261,338 ops/sec ±0.45% (89 runs sampled)\nnano-equal x 231,064 ops/sec ±0.62% (88 runs sampled)\nshallow-equal-fuzzy x 164,828 ops/sec ±0.87% (88 runs sampled)\nunderscore.isEqual x 91,247 ops/sec ±0.56% (88 runs sampled)\nlodash.isEqual x 48,000 ops/sec ±0.48% (86 runs sampled)\ndeep-equal x 73,699 ops/sec ±0.55% (86 runs sampled)\ndeep-eql x 42,804 ops/sec ±0.45% (87 runs sampled)\nramda.equals x 15,119 ops/sec ±0.49% (87 runs sampled)\nutil.isDeepStrictEqual x 58,458 ops/sec ±0.56% (89 runs sampled)\nassert.deepStrictEqual x 583 ops/sec ±0.47% (87 runs sampled)\n\nThe fastest is fast-deep-equal\n```\n\nTo run benchmark (requires node.js 6+):\n\n```bash\nnpm install\nnpm run build\nnode benchmark\n```\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE)\n",
"readmeFilename": "README.md",
"gitHead": "a7bf530713a16217625069091e7abb1a8beb58e5",
"_id": "fast-deep-equal@3.0.0-beta.1",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-jCbIq8DtBhGWV8P9bKUtFcZShlQ8miECXN30SLkmjPXI0REN56XVDFd+8TH5VFjocqjEuK9OQVN8MedJL0lQdA==",
"shasum": "6d3ffe12cd9f26a6e64501248fc6e0a60d99e0ab",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.0.0-beta.1.tgz",
"fileCount": 6,
"unpackedSize": 8738,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdIiGSCRA9TVsSAnZWagAAuKcP/0q4YwruHc8nLhjkUYTZ\nMRwcmEqiiNYy7v8Wz9ezYztDyHl+M0vl/OnuzwEQkwKo/n8Dym3T0oyUlWzR\ndoroUJotPOLJnuo90GWSKbWHv6vO4bxXSQEt8LnSn3UFEnfX0UYHZX4FY8sl\nEI9SSYPUfxm9llu6GZhQUToVtPXMmyT2dOp+syhSttIaHbRrZO2/Prhb3qN1\n7S7xiT4SEulRSMwyZC8h1VtZHZW6nd1BYsei1jtHJJsFU3jLvI+M4xUdz/8X\ndUHwsGkfhNF7IAKS2/OZ34EA/mhqK4HCSa7LqfC8SsKYLqElp0THDzpFhFxR\nEdDF/NFEZAKa4x9gE6Qze5GQTSGsggzYxopiGTlyRof6YnGr8cYFejJkI3zm\nSUvwohcJKunXB5x2+byShlaPIsmwTMjedDJFrJOxE81a0is3oJPYOjlYmcT4\nDYONQgomgSVb9vB4jWp7kUXCEmIlYah9As38YKEa1HsifixmhTpWA4H7q0Td\nlBc/aKUGwbwVIZ8kd32NCZF1y/LpZDJN8+kow9uLIDMwTTyg5pyS0ggTtRkW\nRPspUYdMDOkOX0oZBD4UNg2wMub9zXn+5pw+tp5Iyd/5L5w8pNLFQgXdUrXP\nRVzXSmqeQ7I+7WTbh6Hrb9q/33H5ctWGP7ClQrk81hjURPzI5ikb/RLe4hmY\n+b2X\r\n=lFrK\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIGwiLmuWrZhKwKunZByzmA1IuBM+/9VUTyPdmSh6itUSAiBsmlVKmc8gCI3w9/QG4xZbJURKGkUmCK4n+0ZZxEigVQ=="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.0.0-beta.1_1562517905353_0.1702218812796703"
},
"_hasShrinkwrap": false
},
"3.0.0-beta.2": {
"name": "fast-deep-equal",
"version": "3.0.0-beta.2",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark spec",
"build": "node build",
"benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"typescript": "^2.6.1"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"readme": "# fast-deep-equal\nThe fastest deep equal\n\n[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal)\n[![npm](https://img.shields.io/npm/v/fast-deep-equal.svg)](https://www.npmjs.com/package/fast-deep-equal)\n[![npm](https://img.shields.io/npm/v/fast-deep-equal/beta.svg)](https://www.npmjs.com/package/fast-deep-equal)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master)\n\n\nThis readme is for pre-release v3 with ES6 Map, Set and Typed arrays support.\n\nSee branch [v2](https://github.com/epoberezkin/fast-deep-equal/tree/v2) for the main version.\n\n\n## Install\n\nTo install v3 pre-release with ES6 Map, Set and Typed arrays support\n\n```bash\nnpm install fast-deep-equal@beta\n```\n\nTo install [v2](https://github.com/epoberezkin/fast-deep-equal/tree/v2)\n\n```bash\nnpm install fast-deep-equal\n```\n\n\n## Features\n\n- ES5 compatible\n- works in node.js (8+) and browsers (IE9+)\n- checks equality of Date and RegExp objects by value.\n\nES6 equal (`require('fast-deep-equal/es6')`) also supports:\n- Maps\n- Sets\n- Typed arrays\n\n\n## Usage\n\n```javascript\nvar equal = require('fast-deep-equal');\nconsole.log(equal({foo: 'bar'}, {foo: 'bar'})); // true\n```\n\nTo support ES6 Maps, Sets and Typed arrays equality use:\n\n```javascript\nvar equal = require('fast-deep-equal/es6');\nconsole.log(equal(Int16Array([1, 2]), Int16Array([1, 2]))); // true\n```\n\n\n## Performance benchmark\n\nNode.js v12.6.0:\n\n```\nfast-deep-equal x 325,485 ops/sec ±0.57% (86 runs sampled)\nfast-deep-equal/es6 x 261,338 ops/sec ±0.45% (89 runs sampled)\nnano-equal x 231,064 ops/sec ±0.62% (88 runs sampled)\nshallow-equal-fuzzy x 164,828 ops/sec ±0.87% (88 runs sampled)\nunderscore.isEqual x 91,247 ops/sec ±0.56% (88 runs sampled)\nlodash.isEqual x 48,000 ops/sec ±0.48% (86 runs sampled)\ndeep-equal x 73,699 ops/sec ±0.55% (86 runs sampled)\ndeep-eql x 42,804 ops/sec ±0.45% (87 runs sampled)\nramda.equals x 15,119 ops/sec ±0.49% (87 runs sampled)\nutil.isDeepStrictEqual x 58,458 ops/sec ±0.56% (89 runs sampled)\nassert.deepStrictEqual x 583 ops/sec ±0.47% (87 runs sampled)\n\nThe fastest is fast-deep-equal\n```\n\nTo run benchmark (requires node.js 6+):\n\n```bash\nnpm run benchmark\n```\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE)\n",
"readmeFilename": "README.md",
"gitHead": "fbfd12e4ed280673062a576c97c08251cf1437b5",
"_id": "fast-deep-equal@3.0.0-beta.2",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-/1ttQLbtYMjR0n+pR0dIuYELUJ4QMhT7sqatQBY+ux4snfkGS9gG/bDQq7i94IeNn3XUO2sVw5/EuxKzFEHWGw==",
"shasum": "a479f3ff9c18e08c5a13b9ac42f53c021bdda9fd",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.0.0-beta.2.tgz",
"fileCount": 6,
"unpackedSize": 8438,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdcMg0CRA9TVsSAnZWagAAiu8P/1qIcEN2nb8v8Mcww4zM\n/nbJtnJKf0EcRj4sKnRh3griax6DThslcxLG+61+IXleilQysjq6JMF+x8K2\nXBBpkZwxYID7QbvAKbetFBQ8LtrhfL78D6p1cObL1OJX2A+s0U5UmYnqi5UL\nN6UGKXzq/9nYsqSChsHTdf9Jhtun1LIw/6P3FqW9p7N+FBZWNaR4lyAnLXL4\nJ1AqM4e4ou9taSL9/w8fqpDBYVqbrMwys4ltu502vBhYXI1kN7VRC6RzmMhR\nzefqfI4KpsFlyLUmCisPrMlo/PsdDuIWg/igX+H2pg2Wd0i1TZUVyKoRjeVz\nDWu5+zeIYqffZ2ivIq4kTE/gQcyjymzTXVMY/iXhgqrQR6yvU97for+aQbUb\n7E5l37lViH3Aac7M/118UtlYFKHIqEhjGxNDAWaGEg3jrZMtrr/+Ize9rIu8\nzgwR+SEzrk2o071VrNeo7wFecPaG4GdbP01SjaTUHiN5HHaymQSQQebtQEFZ\n2BQUco+HQuMsKv97ws0zhBACEZc3ICOj4IuvA+j4zY6kyWa1sQ7GC+cQ1A/p\np3m+OrkXar3Gv9+ETgkzMRYT12GZsn/swVJXOB25fIx4Sytk9pNorhprOfLj\nhGai7FjsMeykVnz2aFmyUGv6u+PfBvwCW6BxJ6ni6zsIhXLJAFjGl/spHI9r\n+EA0\r\n=gcXK\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCoE0bM6pKJESdpJUGvth7gLslpdlhmNhGT9BtusSD+PgIgJcJnuAz0G4XyRzcoGOBqoCjQ/EJxl9Cpxgs9RbjBYO8="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.0.0-beta.2_1567672371907_0.4785130425637518"
},
"_hasShrinkwrap": false
},
"3.0.0": {
"name": "fast-deep-equal",
"version": "3.0.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark/*.js spec/*.js",
"build": "node build",
"benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"typescript": "^2.6.1"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"gitHead": "5ad617e945055b8c31cad6c2fa72d15824d106c6",
"_id": "fast-deep-equal@3.0.0",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-fXvSXoWb8v2XMz0oKK+8KgOFO3w3kmv5zvXS4KKtMWy7LMWAgE8U4SVTPDlBwYIT7ZznmnkqYEo3kpfTY5HJ9Q==",
"shasum": "8949979fa5eaf98ecfeafa9d72a8a943cfd2fbda",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.0.0.tgz",
"fileCount": 6,
"unpackedSize": 9050,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd4jzECRA9TVsSAnZWagAAxxUP/iL8vQBaLNYa74yO1kei\nOp7fcThRfGa3Pc7l8HFi17BrOOo/1LIz6K1RSi75qJMevh/vvrCFlStWTdTp\nUK2jyVnM6tF0PUvMLydpG4gLoFJUiYCykHI7BmNAfFfq/CGyq0qB8IRxTfWs\nJxmaIERjbVbgKa8iW3sUWZug0J9MS73j1ULxpbWVvm4pFamRQUkrDkyFMNfP\nGM7mnB6HmJIF5OeJiB3/8XrYXLAlYACqAHwPDJmmMDe1Ssc4s5evbfur8tg9\nXnsacF79p23ECxfGoXmle7A3mdM4X4jg9z2fjhe0hYv+fUrQhEPivJgLBmj3\nmTQZ0TFXxCNUE7qPH2kwNqMKfiPc2CkRyWxC6gWVFCqRVHyp1rDcNgh/VnnY\nUmYd+InyuQ8R6U16FsnRKH2PS3lA6VDpUoZLb4fcv9g5LQoqMhqRr6/9Ftl6\nUWiJPq4y8xKAEa1KV6e9ZgzVQ57s/IbGLiVIb3zZjxYZ4f7+dUwFi3rT9p9d\n4Oj6nBt9INqupcj6hmj5toYA1NU/jGhanR2im9xZmVa7A4P8UJwSmdN++pEE\nPO8SHzQ8i3FZE62pcghjqNUEUb4ypF7+MN1RpUhc1cecXN9o5VR+t8jjH7x9\nQjSAMkVfwt7kMvjofc1evrci/wiAg4dWtvsQzAREc+XXwdN2ytrakiAc0686\n0yMZ\r\n=0rZu\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQD9RjABhf6spMek1URwr+JnwHTC9SLqF0eijQ1FJyCWEwIhAIupkjw8IdJJa7+R8U05g4JCrZXbqIhrd7wIDTS/bTJD"
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.0.0_1575107780444_0.0012007568166698679"
},
"_hasShrinkwrap": false
},
"3.0.1": {
"name": "fast-deep-equal",
"version": "3.0.1",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark/*.js spec/*.js",
"build": "node build",
"benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"typescript": "^2.6.1"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"gitHead": "b791fac6965de0f5f08a3a7f94096cbcc1cffc48",
"_id": "fast-deep-equal@3.0.1",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-eV4KJB1HpEcckLU+u/i+FFZnvbeu34rQ514kL8m4uw7FyGWa7ltvz45vfDVFPZD+Z+h8WQL86+co5P3OWZrScw==",
"shasum": "05a7fb9c3c34e594562b73c2b6e7ddaa92e5e79b",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.0.1.tgz",
"fileCount": 6,
"unpackedSize": 8620,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd4j/tCRA9TVsSAnZWagAAzwIP/1oN4GkNeoAhHDwHqyHx\nI9DGHN6TmsZfTvtli+EpOEcB98SPo0VSCddysF6fx+7kQk0nbwspIUBNbeKu\nTqSv0XGvaYIeN3OwenuUxbHaqoAgyQD0mth9wGyf2T9Bl5QEQ9jtQCAnQeAy\nPO9oaDUjR+pMuMynshw4julKa0UcfFS5en88+JIep6S02NxmOmAEcvNTXaIa\npd+D2EJYYu856Xe6oNp5B1dG+/VcNb7X4CFhDYU/3bvcYb65ebVHql3IvSUr\n+VBOlTeLYLb/ZvpLEDc8YLPIdGDeEtsmdCMZNJqsgvHViEllk8cPCYnNHuvK\nCOacW5xoJhh8OKO1/G/BMF/4znATMYOU3DiYEjjSKpTeFCdVeZ1nClngYWh7\nGkC/auWX0r4LfFqFw/63Y/cLlIEp7t2l9vGVxItHu0FX9Mu68G/zpyy+dYZp\noHfHmcXO1LoMDHDdp1Nj2BH62uoywuBnO0ugBTC5HtsWaH0wYNX/u54zEdd4\nRMvCvZaGVdPndq6MHaV3D3el0PrXIDSi8+RShurVXzehdu0DmCCRM4xaUmsv\nTNNsRVi5FccVIB5HciRSQC00sNWEMK92eRfNPo1apnotsTFsdsrCqKZjAU67\nQ6JqSXlC4t7iJuIQcqklymaKS1/X+kZ5dGINUDutelPkiWZ4FtbfBw+2vhp3\ni5VU\r\n=wEHn\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQCrShX+rRqPeNEf5SrFQIVDB+krjRigL1rXNjdc9YmdUgIhALdxzgX8qDP6DQ5ExjLc6CNMn7uJ2Ybem1UcCXflYHVN"
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.0.1_1575108588917_0.5419538340501044"
},
"_hasShrinkwrap": false
},
"3.1.0": {
"name": "fast-deep-equal",
"version": "3.1.0",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark/*.js spec/*.js",
"build": "node build",
"benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"react": "^16.12.0",
"react-test-renderer": "^16.12.0",
"sinon": "^7.5.0",
"typescript": "^2.6.1"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"gitHead": "09f9b429d89a5953073edd753654d259aaadf32a",
"_id": "fast-deep-equal@3.1.0",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-Tv4ewzk1IJYQHXqSDUFwpTRMcD6JdeEEf+zS+9hdBNIJWM7pPDYwDvKmS/9Ul0h8LOhY3UisVr9MolJCBPiaNA==",
"shasum": "62b2f73b6b16ef2d53cb2a17c3e563422e80d32d",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.1.0.tgz",
"fileCount": 9,
"unpackedSize": 11400,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd5QoLCRA9TVsSAnZWagAAXQUQAJyyfWRbnMmyALKu1ko5\nSotuZ6OihKvz+NnJPh/XR+Y4j2lRXei0YaNdVVXOkhCrOfwE2krb2269SrMz\nQv8dR4ar45G40UZDT3Qtyuj8IAnujk27k9uWNdJ7CPGCsZIQ73P13IuXkets\nOp/v2olZLcrmxTbBYPRkH2sF7AUcuJEUkfqvSNKlMUbSu5hoknOimw6vZwZe\n+SPVuEeK+nGry25Z/L7XdYXSfXHxuW2tsvO9N1wJ0aKTDKm2ezEY7ioiFph9\nSVk8/naNNioqGuPjHpX15KjqFdDrl6Id0TVsq68KSVzf8cTN+qCd3WpgaVSZ\nHe53PYJuLYgVZ3Ce961VAfUM/YYB+WReJTxew3oU2ttjweHZej07+Mbp4A2M\nQCIEdwCWN4iQ0F2IXTnhQWgNwFHck1v2k7STbS19B33Q7AWQcLzxwQIjWIvu\nFH4lHqDaFd/jDHpHN8jc0tGdQct6y5Hu9LJT1p9Ef/Ar+Nm+9pz+e4iZVwFo\nmWV4tXTKfg7iq8nBTHXewlPj1os7x/34ttD7ExQJ2i3tHWC/vX3mdfqQXIuQ\nh9nBwunNjGgBUgNk5CZkSCK7YLjlPMVohjFPSzwJDs60ERYH0iEJaJXJI6QC\n/ydAj/+sVRFxwsJnFjbXc0uTaarfAkWuqgSLWiFGEPNdzQvSPq8FtfRr9DNl\nRR/7\r\n=DX3i\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIHg4Yl3Qb3U+TuzA+ysicfSdAM3T5Yt4Qx4GOANcY8hlAiEAg/uEZQA50EDvWjfsHrzbvA6IMiLMJ5tB3h5257MONGg="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.1.0_1575291402987_0.027436250886170965"
},
"_hasShrinkwrap": false
},
"3.1.1": {
"name": "fast-deep-equal",
"version": "3.1.1",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark/*.js spec/*.js",
"build": "node build",
"benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"dot": "^1.1.2",
"eslint": "^4.0.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2",
"react": "^16.12.0",
"react-test-renderer": "^16.12.0",
"sinon": "^7.5.0",
"typescript": "^2.6.1"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"gitHead": "32f8e288c2ed5b7f71aa47d5f9b980da5c9951aa",
"_id": "fast-deep-equal@3.1.1",
"_nodeVersion": "12.6.0",
"_npmVersion": "6.9.0",
"dist": {
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
"shasum": "545145077c501491e33b15ec408c294376e94ae4",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.1.1.tgz",
"fileCount": 11,
"unpackedSize": 12943,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd5nF5CRA9TVsSAnZWagAAKoEP+gJ9E6MD1MP8F6qitV1M\nAw+0FsW5XIkFHLQR4zsf+PNDuEM4rjlz8vAslIMbD43XGzpE4tvfuMpISHUS\nkKvEStpWLpO3Iy5JD4FcWCLZdlPjHMI69/p7JNOPqovMGNLXPA3b/dzWpPgj\nq8muatLMmNq4uc8XIuTA9hQlXiuJXzuZc5fIfRqL0QMbfGs5u9yfXDyPpCPt\nFK+LVpZiVu6a/ILMyUNK61ueqce2FYqRs9GFwD8NvzpDxAfzRAGAMEKj3u+6\no9ToSgjbfzVpE3XX4/mA6sqX3JHWBwaKBgWz2qkMKwrdIKrqk+ZUTCrWcdOF\n2KiVvQAksmm20IxeHbsgNAW2wbFiGAC792UyQFtgDUCzoQcaB5AxZZ3Q6sn+\nOQmMzTghZPZwB2ZS45QPtWqDvjsgfF5rXgMbBXjuAVnp1b+BvMBNcczyxkZd\n2uCwWYp+Y4DObUdLxvUUszjosyxWZmAGD2RoEpi2tOrB8sgsGGR7zVxHudBy\nRPFgijEXDBPhBFg6avnBlltrH7kF28iapYffpYlURGwftILoCJjXBLtHC/6C\nrTIECFndV3USo+ct4vvKLqYWUkxfKu45M42XL8gsFf/COOByCEg/OuCGwhA7\n8Eg7vdxHfxlTIG/FBpnd5jND4cLKIiYoDrrqlm6qUaRv9uhhxD6aBRKLbFx7\nPNzd\r\n=Fsqp\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQC374S8GXkh8y3bETOyOc+EHDAdaG5Kem7aLBCTeLMt0QIgL1bsheU26kW0j1wO6EBSxzNMfXacOBALwvuoR6lhnjU="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.1.1_1575383416611_0.8717651608206709"
},
"_hasShrinkwrap": false
},
"3.1.3": {
"name": "fast-deep-equal",
"version": "3.1.3",
"description": "Fast deep equal",
"main": "index.js",
"scripts": {
"eslint": "eslint *.js benchmark/*.js spec/*.js",
"build": "node build",
"benchmark": "npm i && npm run build && cd ./benchmark && npm i && node ./",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test-ts": "tsc --target ES5 --noImplicitAny index.d.ts",
"test": "npm run build && npm run eslint && npm run test-ts && npm run test-cov",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"keywords": ["fast", "equal", "deep-equal"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/fast-deep-equal/issues"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"devDependencies": {
"coveralls": "^3.1.0",
"dot": "^1.1.2",
"eslint": "^7.2.0",
"mocha": "^7.2.0",
"nyc": "^15.1.0",
"pre-commit": "^1.2.2",
"react": "^16.12.0",
"react-test-renderer": "^16.12.0",
"sinon": "^9.0.2",
"typescript": "^3.9.5"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"types": "index.d.ts",
"gitHead": "d807ffc5013e710deb1c63d463a03f729bcd144d",
"_id": "fast-deep-equal@3.1.3",
"_nodeVersion": "14.0.0",
"_npmVersion": "6.14.4",
"dist": {
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"shasum": "3a7d56b559d6cbc3eb512325244e619a65c6c525",
"tarball": "http://localhost:4545/npm/registry/fast-deep-equal/fast-deep-equal-3.1.3.tgz",
"fileCount": 11,
"unpackedSize": 12966,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe3ehgCRA9TVsSAnZWagAAXoEP/AmAr6hbgGqa2L7/95pm\nB+wX1GaxB/Ynk4kSU4xeP3TGu9L72sqNhCf8Vj/WLl1XYPyJ0xA9betwXSIa\n+eE+Bd07xJAmaCM4Se583zgv4lifprYoKSCaSgGcXZ0Ay4yDxAeHLmrvELah\nNBnVM0eAJ/YxeVpwEemrh28mT5XDdq1HrXcbRq5ZnjTfth1oPvmEvfEoEtCc\nx/6NrH0tfyhPlbCt7XqpmJPJIYi4KPaDuaLbAhE+yKVzXtCfKsjf/eJVwfi/\n79sIhtQn8lINhbwbk0gs5PmFsxVIFllV6RPROa+iLLSV+MupLCoTWrmzzpx3\nJimUwaSKt4iPxsM3a/jvn73mODmqL2w4NNmyOJYmNj4Jx/ps+QjDnWJ8Vtqz\n0HEC/RnvP0M7HpObaOMeb12+xJY1PGnJqSDygMxVg9xT6WMEIoE4D55V8HSL\nyEQB9gNWpKjX2NAjolidqAYBc3XFplQrVPsXm5eg+Uvd+sbwolho8mMv3J4B\n0BVwcCcrxLgFOBxt+ZALNkcAb8MxkgU7Ptbcg+BZtqJV7FxSIXgRZW94kLXn\nMg+OorbUoGHPyGpRc8L3RGkfdXztpGdyjXHC5VDbkZHlw+1lyAQzQq7g090S\nkbQNT9BvcHpKIPaNvZsY1VjenDW5hupOCdyTfjP0HidwJkMN7OPPTWRNBfaW\nWqbw\r\n=uuzF\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIDaDosp9IxEQRt2XkZPq/dpNlm0nhS0lCPdWBSWBZHcDAiEApfm2QlsgGUYm5sFGQYPVb97kIorp3Voeb7/UQRiSmKc="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/fast-deep-equal_3.1.3_1591601248371_0.8712300502707653"
},
"_hasShrinkwrap": false
}
},
"readme": "# fast-deep-equal\nThe fastest deep equal with ES6 Map, Set and Typed arrays support.\n\n[![Build Status](https://travis-ci.org/epoberezkin/fast-deep-equal.svg?branch=master)](https://travis-ci.org/epoberezkin/fast-deep-equal)\n[![npm](https://img.shields.io/npm/v/fast-deep-equal.svg)](https://www.npmjs.com/package/fast-deep-equal)\n[![Coverage Status](https://coveralls.io/repos/github/epoberezkin/fast-deep-equal/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/fast-deep-equal?branch=master)\n\n\n## Install\n\n```bash\nnpm install fast-deep-equal\n```\n\n\n## Features\n\n- ES5 compatible\n- works in node.js (8+) and browsers (IE9+)\n- checks equality of Date and RegExp objects by value.\n\nES6 equal (`require('fast-deep-equal/es6')`) also supports:\n- Maps\n- Sets\n- Typed arrays\n\n\n## Usage\n\n```javascript\nvar equal = require('fast-deep-equal');\nconsole.log(equal({foo: 'bar'}, {foo: 'bar'})); // true\n```\n\nTo support ES6 Maps, Sets and Typed arrays equality use:\n\n```javascript\nvar equal = require('fast-deep-equal/es6');\nconsole.log(equal(Int16Array([1, 2]), Int16Array([1, 2]))); // true\n```\n\nTo use with React (avoiding the traversal of React elements' _owner\nproperty that contains circular references and is not needed when\ncomparing the elements - borrowed from [react-fast-compare](https://github.com/FormidableLabs/react-fast-compare)):\n\n```javascript\nvar equal = require('fast-deep-equal/react');\nvar equal = require('fast-deep-equal/es6/react');\n```\n\n\n## Performance benchmark\n\nNode.js v12.6.0:\n\n```\nfast-deep-equal x 261,950 ops/sec ±0.52% (89 runs sampled)\nfast-deep-equal/es6 x 212,991 ops/sec ±0.34% (92 runs sampled)\nfast-equals x 230,957 ops/sec ±0.83% (85 runs sampled)\nnano-equal x 187,995 ops/sec ±0.53% (88 runs sampled)\nshallow-equal-fuzzy x 138,302 ops/sec ±0.49% (90 runs sampled)\nunderscore.isEqual x 74,423 ops/sec ±0.38% (89 runs sampled)\nlodash.isEqual x 36,637 ops/sec ±0.72% (90 runs sampled)\ndeep-equal x 2,310 ops/sec ±0.37% (90 runs sampled)\ndeep-eql x 35,312 ops/sec ±0.67% (91 runs sampled)\nramda.equals x 12,054 ops/sec ±0.40% (91 runs sampled)\nutil.isDeepStrictEqual x 46,440 ops/sec ±0.43% (90 runs sampled)\nassert.deepStrictEqual x 456 ops/sec ±0.71% (88 runs sampled)\n\nThe fastest is fast-deep-equal\n```\n\nTo run benchmark (requires node.js 6+):\n\n```bash\nnpm run benchmark\n```\n\n__Please note__: this benchmark runs against the available test cases. To choose the most performant library for your application, it is recommended to benchmark against your data and to NOT expect this benchmark to reflect the performance difference in your application.\n\n\n## Enterprise support\n\nfast-deep-equal package is a part of [Tidelift enterprise subscription](https://tidelift.com/subscription/pkg/npm-fast-deep-equal?utm_source=npm-fast-deep-equal&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers.\n\n\n## Security contact\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://tidelift.com/security).\nTidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues.\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/fast-deep-equal/blob/master/LICENSE)\n",
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"time": {
"modified": "2022-06-17T23:35:19.987Z",
"created": "2017-06-15T22:26:29.798Z",
"0.0.1": "2017-06-15T22:26:29.798Z",
"0.1.0": "2017-06-16T21:59:08.238Z",
"1.0.0": "2017-06-17T20:22:51.722Z",
"1.1.0": "2018-02-25T20:45:49.397Z",
"2.0.0": "2018-04-28T09:07:16.594Z",
"2.0.1": "2018-04-28T10:03:50.090Z",
"3.0.0-beta.0": "2019-07-07T13:39:58.009Z",
"3.0.0-beta.1": "2019-07-07T16:45:05.499Z",
"3.0.0-beta.2": "2019-09-05T08:32:52.010Z",
"3.0.0": "2019-11-30T09:56:20.567Z",
"3.0.1": "2019-11-30T10:09:49.179Z",
"3.1.0": "2019-12-02T12:56:43.132Z",
"3.1.1": "2019-12-03T14:30:16.748Z",
"3.1.3": "2020-06-08T07:27:28.474Z"
},
"homepage": "https://github.com/epoberezkin/fast-deep-equal#readme",
"keywords": ["fast", "equal", "deep-equal"],
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/fast-deep-equal.git"
},
"author": { "name": "Evgeny Poberezkin" },
"bugs": { "url": "https://github.com/epoberezkin/fast-deep-equal/issues" },
"license": "MIT",
"readmeFilename": "README.md",
"users": {
"colshacol": true,
"sxhyxnchxng": true,
"ganeshkbhat": true,
"chaoliu": true,
"ksyrytczyk": true,
"jalik": true,
"daizch": true
}
}

View file

@ -0,0 +1,238 @@
{
"_id": "get-func-name",
"_rev": "5-9f6e0ab6bcd7810e50d6032d165fb59b",
"name": "get-func-name",
"description": "Utility for getting a function's name for node and the browser",
"dist-tags": { "latest": "2.0.0" },
"versions": {
"1.0.0": {
"name": "get-func-name",
"description": "Utility for getting a function's name for node and the browser",
"keywords": ["get-func-name", "chai util"],
"license": "MIT",
"author": {
"name": "Jake Luer",
"email": "jake@alogicalparadox.com",
"url": "http://alogicalparadox.com"
},
"contributors": [
{ "name": "Keith Cirkel", "url": "https://github.com/keithamus" },
{
"name": "Lucas Fernandes da Costa",
"url": "https://github.com/lucasfcosta"
},
{ "name": "Grant Snodgrass", "url": "https://github.com/meeber" },
{ "name": "Lucas Vieira", "url": "https://github.com/vieiralucas" },
{ "name": "Aleksey Shvayka", "url": "https://github.com/shvaikalesh" }
],
"files": ["index.js", "get-func-name.js"],
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/get-func-name.git"
},
"scripts": {
"build": "browserify --bare $npm_package_main --standalone getFuncName -o get-func-name.js",
"lint": "eslint --ignore-path .gitignore .",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "istanbul cover _mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"dependencies": {},
"devDependencies": {
"browserify": "^13.0.0",
"browserify-istanbul": "^1.0.0",
"coveralls": "2.11.9",
"eslint": "^2.4.0",
"eslint-config-strict": "^8.5.0",
"eslint-plugin-filenames": "^0.2.0",
"ghooks": "^1.0.1",
"istanbul": "^0.4.2",
"karma": "^0.13.22",
"karma-browserify": "^5.0.2",
"karma-coverage": "^0.5.5",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^0.3.1",
"lcov-result-merger": "^1.0.2",
"mocha": "^2.4.5",
"phantomjs-prebuilt": "^2.1.5",
"semantic-release": "^4.3.5",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.4",
"validate-commit-msg": "^2.3.1"
},
"engines": { "node": "*" },
"version": "1.0.0",
"gitHead": "70bdc1268a76940053b1d90c8ced089a283f00c3",
"bugs": { "url": "https://github.com/chaijs/get-func-name/issues" },
"homepage": "https://github.com/chaijs/get-func-name#readme",
"_id": "get-func-name@1.0.0",
"_shasum": "d64e38da8e45acb746726049f36bef89ebfa91c2",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "0.10.47",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "d64e38da8e45acb746726049f36bef89ebfa91c2",
"tarball": "http://localhost:4545/npm/registry/get-func-name/get-func-name-1.0.0.tgz",
"integrity": "sha512-UB5pzOr1hCCutr/JkVy7txtz53LaKQ4LR3sUXh4dYajE06pGddjKuwUASd+maoUsxt6M8lAaHTPwkZtQmFaH5A==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIAL7YEf9X+8M3bPENg68qhdrGXY280h7moqznZj9yWPaAiAdRkR4J3zXH2ACJJXVdqpBKRHvRP4ywLJJ2Lv5z0WgVw=="
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/get-func-name-1.0.0.tgz_1476229336262_0.2564441079739481"
}
},
"2.0.0": {
"name": "get-func-name",
"description": "Utility for getting a function's name for node and the browser",
"keywords": ["get-func-name", "chai util"],
"license": "MIT",
"author": {
"name": "Jake Luer",
"email": "jake@alogicalparadox.com",
"url": "http://alogicalparadox.com"
},
"contributors": [
{ "name": "Keith Cirkel", "url": "https://github.com/keithamus" },
{
"name": "Lucas Fernandes da Costa",
"url": "https://github.com/lucasfcosta"
},
{ "name": "Grant Snodgrass", "url": "https://github.com/meeber" },
{ "name": "Lucas Vieira", "url": "https://github.com/vieiralucas" },
{ "name": "Aleksey Shvayka", "url": "https://github.com/shvaikalesh" }
],
"files": ["index.js", "get-func-name.js"],
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/get-func-name.git"
},
"scripts": {
"build": "browserify --bare $npm_package_main --standalone getFuncName -o get-func-name.js",
"lint": "eslint --ignore-path .gitignore .",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "istanbul cover _mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"dependencies": {},
"devDependencies": {
"browserify": "^13.0.0",
"browserify-istanbul": "^2.0.0",
"coveralls": "2.11.14",
"eslint": "^2.4.0",
"eslint-config-strict": "^9.1.0",
"eslint-plugin-filenames": "^1.1.0",
"ghooks": "^1.0.1",
"istanbul": "^0.4.2",
"karma": "^1.3.0",
"karma-browserify": "^5.0.2",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.2.0",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^1.0.0",
"lcov-result-merger": "^1.0.2",
"mocha": "^3.1.2",
"phantomjs-prebuilt": "^2.1.5",
"semantic-release": "^4.3.5",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.4",
"validate-commit-msg": "^2.3.1"
},
"engines": { "node": "*" },
"version": "2.0.0",
"gitHead": "fbd5eb57742d6e7669a857de85925559b9a830bb",
"bugs": { "url": "https://github.com/chaijs/get-func-name/issues" },
"homepage": "https://github.com/chaijs/get-func-name#readme",
"_id": "get-func-name@2.0.0",
"_shasum": "ead774abee72e20409433a066366023dd6887a41",
"_from": ".",
"_npmVersion": "4.1.1",
"_nodeVersion": "0.10.48",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "ead774abee72e20409433a066366023dd6887a41",
"tarball": "http://localhost:4545/npm/registry/get-func-name/get-func-name-2.0.0.tgz",
"integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCICp7WV/4PxPCjSMc8LgR+WY3ZOyLdI5KXu2RVK8pQ47QAiBl8cB0Xa33Lh4CCx8VkCznbXVimvN6r4zv3UGsqbVorw=="
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/get-func-name-2.0.0.tgz_1485286464499_0.020393710350617766"
}
}
},
"readme": "<h1 align=center>\n <a href=\"http://chaijs.com\" title=\"Chai Documentation\">\n <img alt=\"ChaiJS\" src=\"http://chaijs.com/img/chai-logo.png\"/>\n <br>\n get-func-name\n </a>\n</h1>\n\n<p align=center>\n Utility for getting a function's name for <a href=\"http://nodejs.org\">node</a> and the browser.\n</p>\n\n<p align=center>\n <a href=\"./LICENSE\">\n <img\n alt=\"license:mit\"\n src=\"https://img.shields.io/badge/license-mit-green.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://github.com/chaijs/get-func-name/releases\">\n <img\n alt=\"tag:?\"\n src=\"https://img.shields.io/github/tag/chaijs/get-func-name.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://travis-ci.org/chaijs/get-func-name\">\n <img\n alt=\"build:?\"\n src=\"https://img.shields.io/travis/chaijs/get-func-name/master.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://coveralls.io/r/chaijs/get-func-name\">\n <img\n alt=\"coverage:?\"\n src=\"https://img.shields.io/coveralls/chaijs/get-func-name/master.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://www.npmjs.com/packages/get-func-name\">\n <img\n alt=\"npm:?\"\n src=\"https://img.shields.io/npm/v/get-func-name.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://www.npmjs.com/packages/get-func-name\">\n <img\n alt=\"dependencies:?\"\n src=\"https://img.shields.io/npm/dm/get-func-name.svg?style=flat-square\"\n />\n </a>\n <a href=\"\">\n <img\n alt=\"devDependencies:?\"\n src=\"https://img.shields.io/david/chaijs/get-func-name.svg?style=flat-square\"\n />\n </a>\n <br/>\n <a href=\"https://saucelabs.com/u/chaijs-get-func-name\">\n <img\n alt=\"Selenium Test Status\"\n src=\"https://saucelabs.com/browser-matrix/chaijs-get-func-name.svg\"\n />\n </a>\n <br>\n <a href=\"https://chai-slack.herokuapp.com/\">\n <img\n alt=\"Join the Slack chat\"\n src=\"https://img.shields.io/badge/slack-join%20chat-E2206F.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://gitter.im/chaijs/chai\">\n <img\n alt=\"Join the Gitter chat\"\n src=\"https://img.shields.io/badge/gitter-join%20chat-D0104D.svg?style=flat-square\"\n />\n </a>\n</p>\n\n## What is get-func-name?\n\nThis is a module to retrieve a function's name securely and consistently both in NodeJS and the browser.\n\n## Installation\n\n### Node.js\n\n`get-func-name` is available on [npm](http://npmjs.org). To install it, type:\n\n $ npm install get-func-name\n\n### Browsers\n\nYou can also use it within the browser; install via npm and use the `get-func-name.js` file found within the download. For example:\n\n```html\n<script src=\"./node_modules/get-func-name/get-func-name.js\"></script>\n```\n\n## Usage\n\nThe module `get-func-name` exports the following method:\n\n* `getFuncName(fn)` - Returns the name of a function.\n\n```js\nvar getFuncName = require('get-func-name');\n```\n\n#### .getFuncName(fun)\n\n```js\nvar getFuncName = require('get-func-name');\n\nvar unknownFunction = function myCoolFunction(word) {\n return word + 'is cool'; \n};\n\nvar anonymousFunction = (function () {\n return function () {};\n}());\n\ngetFuncName(unknownFunction) // 'myCoolFunction'\ngetFuncName(anonymousFunction) // ''\n```\n",
"maintainers": [{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }],
"time": {
"modified": "2022-06-18T07:48:21.817Z",
"created": "2016-10-11T23:42:17.896Z",
"1.0.0": "2016-10-11T23:42:17.896Z",
"2.0.0": "2017-01-24T19:34:26.383Z"
},
"homepage": "https://github.com/chaijs/get-func-name#readme",
"keywords": ["get-func-name", "chai util"],
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/get-func-name.git"
},
"contributors": [
{ "name": "Keith Cirkel", "url": "https://github.com/keithamus" },
{
"name": "Lucas Fernandes da Costa",
"url": "https://github.com/lucasfcosta"
},
{ "name": "Grant Snodgrass", "url": "https://github.com/meeber" },
{ "name": "Lucas Vieira", "url": "https://github.com/vieiralucas" },
{ "name": "Aleksey Shvayka", "url": "https://github.com/shvaikalesh" }
],
"author": {
"name": "Jake Luer",
"email": "jake@alogicalparadox.com",
"url": "http://alogicalparadox.com"
},
"bugs": { "url": "https://github.com/chaijs/get-func-name/issues" },
"license": "MIT",
"readmeFilename": "README.md",
"users": { "justjavac": true }
}

Binary file not shown.

View file

@ -0,0 +1,487 @@
{
"_id": "has-flag",
"_rev": "16-c315872d5b8ffee8fecd0e69c571f1aa",
"name": "has-flag",
"description": "Check if argv has a specific flag",
"dist-tags": { "latest": "5.0.1" },
"versions": {
"1.0.0": {
"name": "has-flag",
"version": "1.0.0",
"description": "Check if argv has a specific flag",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"maintainers": [
{
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
{
"name": "Joshua Appelman",
"email": "jappelman@xebia.com",
"url": "jbnicolai.com"
},
{
"name": "JD Ballard",
"email": "i.am.qix@gmail.com",
"url": "github.com/qix-"
}
],
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "node test.js" },
"files": ["index.js"],
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"devDependencies": { "ava": "0.0.4" },
"gitHead": "621de2782d538f28f99f0bb85b158799cb3ae5cf",
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"_id": "has-flag@1.0.0",
"_shasum": "9d9e793165ce017a00f00418c43f942a7b1d11fa",
"_from": ".",
"_npmVersion": "2.11.2",
"_nodeVersion": "0.12.5",
"_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
"dist": {
"shasum": "9d9e793165ce017a00f00418c43f942a7b1d11fa",
"tarball": "http://localhost:4545/npm/registry/has-flag/has-flag-1.0.0.tgz",
"integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIGJPhJVs8d0OfRuxcVvpsx8/GlyCDY76+T7lmUWEAiYbAiEA2FMa55+Q2P/9xW4CO98gnJER9U0G98XTLOt1Fb5LZQQ="
}
]
},
"directories": {}
},
"2.0.0": {
"name": "has-flag",
"version": "2.0.0",
"description": "Check if argv has a specific flag",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"maintainers": [
{ "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
{ "name": "jbnicolai", "email": "jappelman@xebia.com" }
],
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "xo && ava" },
"files": ["index.js"],
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"devDependencies": { "ava": "*", "xo": "*" },
"gitHead": "601137409f2617c75838d8f3febed5c6e6e8ee2c",
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"_id": "has-flag@2.0.0",
"_shasum": "e8207af1cc7b30d446cc70b734b5e8be18f88d51",
"_from": ".",
"_npmVersion": "3.8.6",
"_nodeVersion": "4.4.2",
"_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
"dist": {
"shasum": "e8207af1cc7b30d446cc70b734b5e8be18f88d51",
"tarball": "http://localhost:4545/npm/registry/has-flag/has-flag-2.0.0.tgz",
"integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIGAVqTFFTaeMGmOLp7C8GcVliAujwOiJBlkgnH1vJ67PAiAzfhhRC3Qfcl2Xcy2ecWV5xyaxQu70coaS5895eDJYzA=="
}
]
},
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/has-flag-2.0.0.tgz_1460389675597_0.3113734829239547"
},
"directories": {}
},
"3.0.0": {
"name": "has-flag",
"version": "3.0.0",
"description": "Check if argv has a specific flag",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": { "node": ">=4" },
"scripts": { "test": "xo && ava" },
"files": ["index.js"],
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"devDependencies": { "ava": "*", "xo": "*" },
"gitHead": "8b2ca7e693b2c742b29f2399194077b64b9ff781",
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"_id": "has-flag@3.0.0",
"_shasum": "b5d454dc2199ae225699f3467e5a07f3b955bafd",
"_from": ".",
"_npmVersion": "2.15.11",
"_nodeVersion": "4.8.4",
"_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
"dist": {
"shasum": "b5d454dc2199ae225699f3467e5a07f3b955bafd",
"tarball": "http://localhost:4545/npm/registry/has-flag/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDYPznbV4hRZzxmumAMzd7EHPhJS1CSCRg/h8+BV/oW6QIhAPJ6qohX1iPmbo4ATN+qBxI8hj86PILSMCets72aK/oa"
}
]
},
"maintainers": [
{ "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
{ "name": "jbnicolai", "email": "jappelman@xebia.com" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/has-flag-3.0.0.tgz_1514920915118_0.33958922349847853"
},
"directories": {}
},
"4.0.0": {
"name": "has-flag",
"version": "4.0.0",
"description": "Check if argv has a specific flag",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": { "node": ">=8" },
"scripts": { "test": "xo && ava && tsd" },
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"devDependencies": { "ava": "^1.4.1", "tsd": "^0.7.2", "xo": "^0.24.0" },
"gitHead": "474aa39afca7333d356c022fc5be4d31732bbba3",
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"_id": "has-flag@4.0.0",
"_npmVersion": "6.4.1",
"_nodeVersion": "10.15.1",
"_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
"dist": {
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"shasum": "944771fd9c81c81265c4d6941860da06bb59479b",
"tarball": "http://localhost:4545/npm/registry/has-flag/has-flag-4.0.0.tgz",
"fileCount": 5,
"unpackedSize": 4419,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcqMqCCRA9TVsSAnZWagAATrIP/22VegVJi5IYjjhsWhNL\nllQoPP8zRlEq/AG6a36bAVuF2lEGtPvtausr/IUbsWZj83n4orGFECflp7Qb\nAsJ3u6zFZLtnp5ug+AhjcqloCM57A05T2RT1YtMpIStapRGsIVc5xudQJtQI\nC+i8ePGQH42iYtLweN7xEw6UKa1ke8UG9hn8FvNP3EkGJOhS59TL8KfsxD8v\nQaNYjOr15UsRsL8K44afDQyhlO4njhr/e+INBDBQhR9vbjTysSxjf/edhzqu\n0CT+WdecdjAMk5egAjIIIbFTQmJtzITfVGJy/UnDmHF3Dyn68QPCOGVbInzy\ncyR858RhE2DAthInEOTYoM5ZfzH2YVSboXcsVZCn2/qcwmKVEyMcGzb0Mzeb\na2jyCMKacWlFO4LbdlXelLaiAfax5auAGiCtDyVfxV1QzBfGbOPoHpmN3drr\nRGxKBoQnlvXrrofmnnpP6sTHQVJJEo86y+F3WzlTwXqp50sC1gq05JC/TNxp\nOIsT5A8RPYmJBvZZKArMo3dHtlvOPPCN9GNERqrKr6ITq55d6h2dylmi46pJ\n920HPH55IKZlB3w73e3ylfAqEmG1KlM3auk/bHqRZJpdPRxUtHP+9pxweDbV\nNYAxJI6hZ3yMhAU8CwbLGBDYZTXSEJt2QxfJj8Yw4lQbQfUScjiML+MmJipS\nM5jU\r\n=+VZG\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIFIW6CbIUufytlg7z6IWHf4WQ5H0IgTew2Vydxc86Y04AiBa0VEMmjPBw7a40g+RZ1HkEW18uRdGxBR72XhW67yDew=="
}
]
},
"maintainers": [
{ "email": "sindresorhus@gmail.com", "name": "sindresorhus" }
],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/has-flag_4.0.0_1554565761745_0.3213063984648754"
},
"_hasShrinkwrap": false
},
"5.0.0": {
"name": "has-flag",
"version": "5.0.0",
"description": "Check if argv has a specific flag",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": { "node": ">=12" },
"scripts": { "test": "xo && ava && tsd" },
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"devDependencies": {
"ava": "^3.15.0",
"tsd": "^0.14.0",
"xo": "^0.38.2"
},
"gitHead": "49240fe75374a5e8f90c9a32827a0faf9f001ad1",
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"_id": "has-flag@5.0.0",
"_nodeVersion": "14.16.1",
"_npmVersion": "6.14.10",
"_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
"dist": {
"integrity": "sha512-dmhh9fPE7WRat4yiFvyhXh7LytudXDcE89VEdR3sxfWQKtFPr7jpXip5H402aeFfA36ucqSKecGEapc7N44k+g==",
"shasum": "36e12f0b14052d6ffc8007c6f768a87623f6f692",
"tarball": "http://localhost:4545/npm/registry/has-flag/has-flag-5.0.0.tgz",
"fileCount": 5,
"unpackedSize": 4210,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgeUG1CRA9TVsSAnZWagAAYFAP/RZHf8wA6lQ6YmX3zWOu\n0PEvFdah/uqRIaJgXSsmxStHkADFAY6Z95lc0SGjCkEowEQopai328zfJRse\nFr0V2XoLObhL9ZP9XU5qNbtm0TPAUI1xq3EVeDyQomEX8JSp1RU7JB1iWbaX\nVcuDnreA3Lxff+eOgR0j11n/VWDAh7YJme+3F3l8LeH72ErDha27QhW8rBf6\nF+ceVrtQ7IV6B6/NlvgAz5fvOML27KDmbntFMQLJdyQ+nWDbrD5r7pJ4bZ27\n/IdQ1nS07RXUDAx103ThEf+Vr+23bdv59eR7CxnX0QENTw3Tm0rq+kvEKZ2L\n+aGw+aFca3L/q7zPv5XY8Mr58R4MCAEpl4HlPbukBsOeuLN+9uvjn4EUMQoo\nqv2GjaGqUWqtrQyCLFB+EKmTT1/9rWapwDwLEW5cjB+nTZDJTSUqwNgWyjps\n5dWQVQn5jaCNeLpEZk95OWkNFxgtp69uWIhvCImEEiE1uPq4iPhfPd4yrmIr\ny2hBo/B62DeVOfzL2HXrUf5hM6oRh+c+38vghJkIGV/bV7fi8VZPbNIK3rBG\nOzIw4qVrGhaopLRg53G9rGLJiSU4pgTwMY93/5zrxq0IIdU0iN9VDQmq2M/p\n6mRF9tIjrG8hUa29BPOl07XSKjSprUQNpOKi2F0T1gmmpVe1ie9+0/TZ3Qq/\naR67\r\n=N7jb\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCHlp1IPWIzPvt5C9fvUu6o7NJyuAaXENeYjli2FJtmRQIgHgpln/kHbKB8znY6IoOTqgu1dYvn2qpBmVKCpmMCGtk="
}
]
},
"directories": {},
"maintainers": [
{ "name": "sindresorhus", "email": "sindresorhus@gmail.com" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/has-flag_5.0.0_1618559413186_0.44645416684559414"
},
"_hasShrinkwrap": false
},
"5.0.1": {
"name": "has-flag",
"version": "5.0.1",
"description": "Check if argv has a specific flag",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": { "node": ">=12" },
"scripts": { "test": "xo && ava && tsd" },
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"devDependencies": {
"ava": "^3.15.0",
"tsd": "^0.14.0",
"xo": "^0.38.2"
},
"gitHead": "0c7d032214c51d14b458364c9f6575ea9afa08b1",
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"_id": "has-flag@5.0.1",
"_nodeVersion": "14.16.1",
"_npmVersion": "7.10.0",
"dist": {
"integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==",
"shasum": "5483db2ae02a472d1d0691462fc587d1843cd940",
"tarball": "http://localhost:4545/npm/registry/has-flag/has-flag-5.0.1.tgz",
"fileCount": 5,
"unpackedSize": 4292,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9bbOCRA9TVsSAnZWagAA7FgQAIi/uPnwjILtQMmTqCIY\nWcD7Chz2q6Lf72iyfQje+50nmpmSrf16BcbBsNeR2T3NC9lFpTJKnDSpVMpM\nBye41Qwlw18c2hMLtXSpCdzMcuH1B0U+4cXuotoZaovThCA+p40y903bMox9\nG9xJRQrpy4XGjHe8o/4W6poR0QiQQrUJRWYhNgnRLvK87fSSk0PIAx9C4HSw\nsMOQdjCaSeSPby67AiF+qlIDfwwKBZqjsEZmUssxhpbxIqeBELHU+1KGJGGc\nKTqsl8Lez+Q5GYVmJo/84lcDLGxHCUolGoWhJqf54JTanEV+40x3QNmUtNTA\nGhbsi9ISZ1KIvu0NgxmkieLn14m0xM3sTcQ5IA+9kPrGj3b5Miqc0DlahtL6\ngRmrAegEmYUjeXdVLkH1XUJLuAbORfil1QzCZwxurJ0MatnKZtgxuIR1DU54\n9gbiDEpNJdhYs5sVLO7qaV5b1sHbJrEgqUw67eeOLb3WlTzW6mJyXAfqmUhS\nKspMFnXqkw+pOXdNL1TEDrTHb5x9TBoZjgugzcCDc45NpgMpATrgqp8v87x8\nux5C4bnVr6OGmB7rkwdKH7wF1vtIT8hiRR/CKkj+zoSqEJjZiE0hPLNZGmse\nms9671k04MVadIG+/M0MIVuuNd5OfoNmnA3oIn7JCyGotE3ggQXQlVYS+L2+\nTtXm\r\n=nheO\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCID0U3iZuF4ngw6yI5Q1DMIzgGZOC+FjSkP1cUVWWPxX+AiEArAIRr7tR7h9kIVk4EB0OIr5q442GpY4swyNJsRVrI/I="
}
]
},
"_npmUser": { "name": "sindresorhus", "email": "sindresorhus@gmail.com" },
"directories": {},
"maintainers": [
{ "name": "sindresorhus", "email": "sindresorhus@gmail.com" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/has-flag_5.0.1_1626715853988_0.3138751642264608"
},
"_hasShrinkwrap": false
}
},
"readme": "# has-flag\n\n> Check if [`argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv) has a specific flag\n\n## Install\n\n```\n$ npm install has-flag\n```\n\n## Usage\n\n```js\n// foo.js\nimport hasFlag from 'has-flag';\n\nhasFlag('unicorn');\n//=> true\n\nhasFlag('--unicorn');\n//=> true\n\nhasFlag('f');\n//=> true\n\nhasFlag('-f');\n//=> true\n\nhasFlag('foo=bar');\n//=> true\n\nhasFlag('foo');\n//=> false\n\nhasFlag('rainbow');\n//=> false\n```\n\n```\n$ node foo.js -f --unicorn --foo=bar -- --rainbow\n```\n\n## API\n\n### hasFlag(flag, argv?)\n\nReturns a boolean for whether the flag exists.\n\nIt correctly stops looking after an `--` argument terminator.\n\n#### flag\n\nType: `string`\n\nCLI flag to look for. The `--` prefix is optional.\n\n#### argv\n\nType: `string[]`\\\nDefault: `process.argv`\n\nCLI arguments.\n\n---\n\n<div align=\"center\">\n\t<b>\n\t\t<a href=\"https://tidelift.com/subscription/pkg/npm-has-flag?utm_source=npm-has-flag&utm_medium=referral&utm_campaign=readme\">Get professional support for this package with a Tidelift subscription</a>\n\t</b>\n\t<br>\n\t<sub>\n\t\tTidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.\n\t</sub>\n</div>\n",
"maintainers": [
{ "name": "sindresorhus", "email": "sindresorhus@gmail.com" }
],
"time": {
"modified": "2022-06-18T19:25:24.129Z",
"created": "2015-07-07T22:43:54.339Z",
"1.0.0": "2015-07-07T22:43:54.339Z",
"2.0.0": "2016-04-11T15:47:58.270Z",
"3.0.0": "2018-01-02T19:21:56.098Z",
"4.0.0": "2019-04-06T15:49:21.907Z",
"5.0.0": "2021-04-16T07:50:13.326Z",
"5.0.1": "2021-07-19T17:30:54.122Z"
},
"homepage": "https://github.com/sindresorhus/has-flag#readme",
"keywords": [
"has",
"check",
"detect",
"contains",
"find",
"flag",
"cli",
"command-line",
"argv",
"process",
"arg",
"args",
"argument",
"arguments",
"getopt",
"minimist",
"optimist"
],
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/has-flag.git"
},
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"bugs": { "url": "https://github.com/sindresorhus/has-flag/issues" },
"license": "MIT",
"readmeFilename": "readme.md",
"users": {
"michalskuza": true,
"webzuu": true,
"aleclarson": true,
"rubiadias": true,
"drewigg": true
}
}

View file

@ -0,0 +1,541 @@
{
"_id": "json-schema-traverse",
"_rev": "11-d5036db48a0e112a81d191b7808d1607",
"name": "json-schema-traverse",
"description": "Traverse JSON Schema passing each schema object to callback",
"dist-tags": { "latest": "1.0.0" },
"versions": {
"0.0.1": {
"name": "json-schema-traverse",
"version": "0.0.1",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"gitHead": "c0a0d74b106d56a61e953f5571ff42739b4ca3dd",
"_id": "json-schema-traverse@0.0.1",
"_shasum": "d241e25481ad2fe8a1fdef61240d727fdee61283",
"_from": ".",
"_npmVersion": "2.15.9",
"_nodeVersion": "4.6.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "d241e25481ad2fe8a1fdef61240d727fdee61283",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.0.1.tgz",
"integrity": "sha512-P3xS/mSXzflYybh30MoI1fF1nFJuyVnNKlluipufn3Jeg0V2bMxsQ4GzF+L7DYud3OSH0QLR7wxgETrF+i2L3A==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCICcHoqEB2KrJcOWJjZB3/3+1KUeg9DRhkXoLv3rrj4W8AiEAv51Bi28kYL/xuhv38ir35R2q3cY4aLNIi8EBQPUjUS8="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse-0.0.1.tgz_1496601736961_0.5534928701817989"
},
"directories": {}
},
"0.1.0": {
"name": "json-schema-traverse",
"version": "0.1.0",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "0d928d60085ef32d11cec52fd2adbb1a9cef80e9",
"_id": "json-schema-traverse@0.1.0",
"_npmVersion": "5.0.0",
"_nodeVersion": "8.0.0",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"integrity": "sha512-1MtXJHDOlTbfMgXZ2mL1DvViXyph6ISlzKIk5On6KJbcMrmdOmwTsWkFDhy+9CJsstbuKlQHohAM3UIDNzQQQA==",
"shasum": "d88e207b83fd8b71f09f5b0c11734de5a0a2d203",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.1.0.tgz",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDYvoTSzjq4AXufqip4HqomwT98HXIEZIHep8LTM/MlcAIgFiTIx13nnu8bxYpt9SbfWJeW5I80ag9VkIsXMNt/U3w="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse-0.1.0.tgz_1496693959875_0.9615707800257951"
},
"directories": {}
},
"0.2.0": {
"name": "json-schema-traverse",
"version": "0.2.0",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "70465d279ff702ae915106cb5bfbd851712d37d0",
"_id": "json-schema-traverse@0.2.0",
"_shasum": "486926926c876f74dd0f7d696ad072118c75d03c",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "6.9.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "486926926c876f74dd0f7d696ad072118c75d03c",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.2.0.tgz",
"integrity": "sha512-W8OfVxI/WDsrJXsDzCRfcH4UXFaxC+W/MuWB38urdbLZAkgxV/Qi+YeC6tTmx6+n9sbFXp36oe95Fn3FFNyMRw==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIGDTJg4X0USb8FZj84XtVy+05viKTY1xkEW1zuBrydrrAiB1v6ydur38P+xh+R3eeWji2yU5p0ogZZX3Di8qNoP+Pg=="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse-0.2.0.tgz_1497475368098_0.03620475740171969"
},
"directories": {}
},
"0.3.0": {
"name": "json-schema-traverse",
"version": "0.3.0",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "0c2808d402f8d57b6360f24ad8cc0fb0662e17c7",
"_id": "json-schema-traverse@0.3.0",
"_shasum": "0016c0b1ca1efe46d44d37541bcdfc19dcfae0db",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "6.9.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "0016c0b1ca1efe46d44d37541bcdfc19dcfae0db",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.3.0.tgz",
"integrity": "sha512-rAzOwA4cQfuDsZtnNbop0anQyosa+EzNt6bafT8lDMQA+xFmlVnhG+Uc6Eri/pOI6nFtA5Nak9ORyvbCZ4KFNQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCPhCdw3Nvs9Gid+yGpm4jif6WGagbu0JZPOWzJ9bgvvwIgK4fIwQ6MVtrJQor+dCvZ0NxCXe9/xL2BBlDxgU+wWn8="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse-0.3.0.tgz_1497558177644_0.5944948405958712"
},
"directories": {}
},
"0.3.1": {
"name": "json-schema-traverse",
"version": "0.3.1",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "f0a6627655525debea519dc8ebb4cf35f3c8e85f",
"_id": "json-schema-traverse@0.3.1",
"_shasum": "349a6d44c53a51de89b40805c5d5e59b417d3340",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "6.9.1",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"dist": {
"shasum": "349a6d44c53a51de89b40805c5d5e59b417d3340",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.3.1.tgz",
"integrity": "sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIEEUvq6T+SmKN/KLhRDONA5sJia05n3oYTphNkVZZl+UAiEA7ITFoYFGXSzOvfcziBq7b/81vfczQk8HS+n0k+rgWzo="
}
]
},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse-0.3.1.tgz_1498261856588_0.601617609616369"
},
"directories": {}
},
"0.4.0": {
"name": "json-schema-traverse",
"version": "0.4.0",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "c1fd5208eb7fce760867477aa119c8bb16972df3",
"_id": "json-schema-traverse@0.4.0",
"_npmVersion": "5.6.0",
"_nodeVersion": "10.0.0",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"dist": {
"integrity": "sha512-1YoNcmKmUIOyoF4DdbjA4qeZz9sxGJ3O0OAZI7J0b6K9A7jiE/24azJPEE/4ZDZbXsDU6biRoNcC8QWwCKegkA==",
"shasum": "e8467bf83020ba9d2a47b2e6b82e1ac056b0ad86",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.4.0.tgz",
"fileCount": 9,
"unpackedSize": 19547,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa8fygCRA9TVsSAnZWagAAdn8P/09M6Zwu8Q608VPdBomC\n34JdJK+UNPU/k0NCO0aC84D31U4M/fsT2zVAWF8XcQ4X+9qFYJyKwRyvA+b0\ni2hxPdlBife/3aJKxFugOGlHQv0QE46H9BI1Yzr/auKlc/XtBPbK5NgBxQua\ngpOZKY92+jRE42eZaQ5AL1K+W6pzkE5/zOfDCeI5CHJos7/EAdQdsS/5Ferm\nJV/i+A2Z1VbdFtZYAiqgvdldqt4gP6TA77uoep1aLPtf/Zvm3T7qXk7hencf\noo6AilfwwTUOWvIsy2ph4qaq1zwtM1PQ8/27/YQx0notvsegRfEJvh/8rtQD\nuOk/6nWtiG9Ls/Tbh/ZqwQBikcuFsU5EA+Zn/ZSnl33EhXSahSHP7l2BQA/Q\nx7jDqts1ATpwQvX9Zz09h3s7RsHtTNftIrahUGqJ5owBw8vi48RAO2pcgxqr\neLdCJkzUf/ECyQvoroxV7Ek57V2It61QlNankKGEB3rHlH2O1aCldTjtSsqB\njv9F9dCCufHMp7LwWibaiZseLqdOn00NSY2GvOnmrjM8sU3OBIq/bwNt4CyI\nX1SI866T56JMBCT6B9KCDMdysfEKtqtho2vXqtjWbRY7LVXiycHn+HR9x5v8\nj+2+c4lYY1t5vMjOdh6Om0+eUGK1C04cERu5yIvKNbaOtrxOxNo/wzamly5a\nkEpm\r\n=ZBqZ\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIFIhICbuOP7yZkZHWsL7vBkiNhAHTUZE0fTGPF8yYtrtAiA3VEMyl+zpOLpWbvLHqA2ZnkOHRCSCFTAq8OitS+MRGg=="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse_0.4.0_1525808286399_0.5813937245567184"
},
"_hasShrinkwrap": false
},
"0.4.1": {
"name": "json-schema-traverse",
"version": "0.4.1",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"mocha": "^3.4.2",
"nyc": "^11.0.2",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "bc898eeee723833fc9d604523e00014350bcc4e1",
"_id": "json-schema-traverse@0.4.1",
"_npmVersion": "5.6.0",
"_nodeVersion": "10.0.0",
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"dist": {
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"shasum": "69f6a87d9513ab8bb8fe63bdb0979c448e684660",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.4.1.tgz",
"fileCount": 9,
"unpackedSize": 19564,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbHOReCRA9TVsSAnZWagAAVWUP/0MJPYc1bhxL+UjZWR+N\n0w1lIESRrtuAzcNFPDBfPvd8bBr3gxJlaLHMkpvzyEZGN69bgQP2hsp6I+Mg\nxvZz/mSOnK5Yj9/VTytxEjlwqW0GDK24x08GXNAZenNidRht1iZvBjugZbJa\n0hxF0z2Xjkn9VXgtOI0QiBLj9t4mutLrte3kFFDNpLTzoRx5r08JeA3L4k4I\na/Svzav/z4c8AsUFaeY/eAtGPm9KqwLzX0eLWQ7ueYPR7YgtY7WUWuSSh8+f\nuk9UJrG0OVS4GPl8YvwMvjf3Di9nUDwoQem9QnsIJCaXJ+Gbknv8B/Lit/9a\nzmjaNJDDNOF8t2iUfwUZWarFBGxYsZBcoECDPrU/tGMj/8IfHXMNHVWraqAp\nfZ9pvYbJ7s8DTlpJ8pkuGUDPrZIX4POWYcsuYVjUUpRwV73HnCIIAJibctmm\nOf1HzG0WaF5OE0ZU06UcGD6SUiZTgtyqaA0jU9vExTYhYSobaWqGKxA1PspG\nMATdwowCSsHWrUx+jXpzuJnEAyDBLW0iVh+rjBmWWvZHS+fub3rE/yT5FOPI\nk1y4qSwsF2I8T8R+Moo1OewFQzUBbaCjdpnOsBluUWmSvkRiwr/lcwZznt51\nBCTVCgPAGPQhcHbHtM/cK8tqpGEXeFTKtHZ5fHCGsL49sLtGPTj3b948t4z/\n1BiZ\r\n=77vn\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIBDbOwAHkjLehseSNqU5TdSlk74ifhLpOlyMdfnCn3piAiEA0+22VOsxdSfplXb4J6DDiQvQd4rDYLqynJknCRcTsBE="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse_0.4.1_1528620124976_0.4290201343994062"
},
"_hasShrinkwrap": false
},
"0.5.0": {
"name": "json-schema-traverse",
"version": "0.5.0",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"coveralls": "^3.0.1",
"eslint": "^7.3.1",
"mocha": "^8.0.1",
"nyc": "^15.0.0",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "666a85fe56ccc27a07f4d40ba52cc172406f8f17",
"_id": "json-schema-traverse@0.5.0",
"_nodeVersion": "12.12.0",
"_npmVersion": "6.11.3",
"dist": {
"integrity": "sha512-x+TRJIQFskrNnFKE2Viz9FCSjK1vIh+H/uaBiOYszh/IcZmAFneQ35H4osWDJp1NPXccuV2I0RMXmi2ZS6Kqcg==",
"shasum": "1069a6097f9e9a567bfc6cc215e85f606ebf6480",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-0.5.0.tgz",
"fileCount": 11,
"unpackedSize": 21098,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfU+ywCRA9TVsSAnZWagAAo4MQAJhqEwwNhHZFLPcknIez\n/fD01Vms7E0C65XAiKct2X2Pkiqpv9LqMk3cBBaPXDnVUMZeebjIjXacuN6z\nuuyIAQTjxDPZez3j2qd91lFPMSW5QXuWDK0xpnUqCINkZfrAH0g2ctZY81vW\nGVY5lutIYk6uQStlsSet/iVDWdJX4C81lmDZzew7EnNcTUi0O3TQtghOSuVG\nslnT7qpdweY+z+mNzrBwkFeMg6il5YygkHmmYz18HssNncV6+PoVdFn+XJK+\nZZ/QGXjS9IcBh+/iCgz0+2Az4bGr6UVcf2HleKBMIfjOQduLQ0zMiBy+lDMx\nhxyLmtevrqefSdkeVX7Y8tAIAhHr8Se7WMeNHjMbGQe2T+dB7PUh18zLSO8+\nQZqtOsNprGm23n5avkLORrxA7PnqGVq8BBPY3pisPv19P8ljJYbRtSrsH2Vz\nMoMUupSVaLNWeFwiUA/64WkXPVMFcxNjTQK6XDUL30JwGuE6PN/p1FGIYPXv\nByCLsZ+sumBDYF8V0jIb1AfERA143Nvgl2Pz6Ye27yAKw1hdR+d+5MTMxUWu\nmPSkSNAni33H9VMybozn3nulLHIwb+YyGJieR/iLQvoyemduoMAhwtCjK0fA\nnfRehA0Qp2hefE0AfyUb6IcPV3ROZddrDGvMgpJ5CbMNeaDoXy2T09vG/a/7\ntDlM\r\n=6n/B\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIHaYYtSpbSyhEv3zHtQ/JRHfNMkXDufaaoXD4+ivt36BAiEAnCnCZR8CFN2gs5RehRrsmfjwXkBtC0cA6XgRhWgvMmA="
}
]
},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse_0.5.0_1599335600219_0.22633217841346598"
},
"_hasShrinkwrap": false
},
"1.0.0": {
"name": "json-schema-traverse",
"version": "1.0.0",
"description": "Traverse JSON Schema passing each schema object to callback",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"eslint": "eslint index.js spec",
"test-spec": "mocha spec -R spec",
"test": "npm run eslint && nyc npm run test-spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"keywords": ["JSON-Schema", "traverse", "iterate"],
"author": { "name": "Evgeny Poberezkin" },
"license": "MIT",
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"devDependencies": {
"eslint": "^7.3.1",
"mocha": "^8.0.1",
"nyc": "^15.0.0",
"pre-commit": "^1.2.2"
},
"nyc": {
"exclude": ["**/spec/**", "node_modules"],
"reporter": ["lcov", "text-summary"]
},
"gitHead": "6b45983cd76270042cc79527da5c8972f13599ec",
"_id": "json-schema-traverse@1.0.0",
"_nodeVersion": "14.15.1",
"_npmVersion": "6.14.8",
"dist": {
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"shasum": "ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2",
"tarball": "http://localhost:4545/npm/registry/json-schema-traverse/json-schema-traverse-1.0.0.tgz",
"fileCount": 12,
"unpackedSize": 22220,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf1fN3CRA9TVsSAnZWagAAOvgP/RW4IyNaG+9p/oIa6WhS\nu0try6lP7Hym+dFd2utH5S19/K2IPoFXP7CFvq1blPVc1adUBBRdfdz7SJ9J\nVJr0Hdzpvrzhkzfod9SyGcjmwOIZDGmI7mhwxTuqYCN1kOWpAY0gnzfV+n5p\nZxDGKLieCqCzmKc1TsSb/aUtWndUmcs8UsUZI5mjqSTajcqRSX11Fillmor8\nZVFzyKWhwEmDFRQlFRR3cTEbytvs55sqTdpWxaZDh7g8UrxdhUQIoI0SnQFO\n3pWaMCf+fM9SGY2JUlMLhr6n3ui5OBqkgjfw5AUtld405fyNbPQlJu7QxATo\nMU7npmYHcoinMOpciVD/tLNxD+OQKyOZ/NlL+XXBdCWQhLIuF+Rnb+raUiSC\nw8q8W5Vba/JN9/pHs8x+3P1eZFIM+cxMQk9RYFuEqtHkGhDiVthpyMsK5h0K\n2Nu7nLBVsnEEid9UggwPep2ua1JO5YETsAtwwo0RFuhRhs3I37eKloiI+NmJ\nCBASUczFiT2vE5ySGPHWMteTjL/5uUU+a+IZhqA/o2Wsmnw4Kxln5npF0kjg\njAQnn/t7QQcWhNGqsFnKEg2rv6cUgj9MoZdxHsyyyCnZ4qEBLByv83zOpigR\nfyxhFwV8uGKg1IZmeNQn+Kj/pBpifoUSbR4LGr54MVSuUrkjIdBv/sCLVC3c\n3vaz\r\n=T5IW\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCNOIFNJRe2jcKCXH4ICrcSvZnowa7w+vu8ftVn1ma0LAIgVov161AURGFLhlj5B6eSkke5RxOlmvY3avjHP8IvUTo="
}
]
},
"_npmUser": { "name": "esp", "email": "e.poberezkin@me.com" },
"directories": {},
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/json-schema-traverse_1.0.0_1607857014508_0.11357423963069646"
},
"_hasShrinkwrap": false
}
},
"readme": "# json-schema-traverse\nTraverse JSON Schema passing each schema object to callback\n\n[![build](https://github.com/epoberezkin/json-schema-traverse/workflows/build/badge.svg)](https://github.com/epoberezkin/json-schema-traverse/actions?query=workflow%3Abuild)\n[![npm](https://img.shields.io/npm/v/json-schema-traverse)](https://www.npmjs.com/package/json-schema-traverse)\n[![coverage](https://coveralls.io/repos/github/epoberezkin/json-schema-traverse/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/json-schema-traverse?branch=master)\n\n\n## Install\n\n```\nnpm install json-schema-traverse\n```\n\n\n## Usage\n\n```javascript\nconst traverse = require('json-schema-traverse');\nconst schema = {\n properties: {\n foo: {type: 'string'},\n bar: {type: 'integer'}\n }\n};\n\ntraverse(schema, {cb});\n// cb is called 3 times with:\n// 1. root schema\n// 2. {type: 'string'}\n// 3. {type: 'integer'}\n\n// Or:\n\ntraverse(schema, {cb: {pre, post}});\n// pre is called 3 times with:\n// 1. root schema\n// 2. {type: 'string'}\n// 3. {type: 'integer'}\n//\n// post is called 3 times with:\n// 1. {type: 'string'}\n// 2. {type: 'integer'}\n// 3. root schema\n\n```\n\nCallback function `cb` is called for each schema object (not including draft-06 boolean schemas), including the root schema, in pre-order traversal. Schema references ($ref) are not resolved, they are passed as is. Alternatively, you can pass a `{pre, post}` object as `cb`, and then `pre` will be called before traversing child elements, and `post` will be called after all child elements have been traversed.\n\nCallback is passed these parameters:\n\n- _schema_: the current schema object\n- _JSON pointer_: from the root schema to the current schema object\n- _root schema_: the schema passed to `traverse` object\n- _parent JSON pointer_: from the root schema to the parent schema object (see below)\n- _parent keyword_: the keyword inside which this schema appears (e.g. `properties`, `anyOf`, etc.)\n- _parent schema_: not necessarily parent object/array; in the example above the parent schema for `{type: 'string'}` is the root schema\n- _index/property_: index or property name in the array/object containing multiple schemas; in the example above for `{type: 'string'}` the property name is `'foo'`\n\n\n## Traverse objects in all unknown keywords\n\n```javascript\nconst traverse = require('json-schema-traverse');\nconst schema = {\n mySchema: {\n minimum: 1,\n maximum: 2\n }\n};\n\ntraverse(schema, {allKeys: true, cb});\n// cb is called 2 times with:\n// 1. root schema\n// 2. mySchema\n```\n\nWithout option `allKeys: true` callback will be called only with root schema.\n\n\n## Enterprise support\n\njson-schema-traverse package is a part of [Tidelift enterprise subscription](https://tidelift.com/subscription/pkg/npm-json-schema-traverse?utm_source=npm-json-schema-traverse&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - it provides a centralised commercial support to open-source software users, in addition to the support provided by software maintainers.\n\n\n## Security contact\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://tidelift.com/security).\nTidelift will coordinate the fix and disclosure. Please do NOT report security vulnerability via GitHub issues.\n\n\n## License\n\n[MIT](https://github.com/epoberezkin/json-schema-traverse/blob/master/LICENSE)\n",
"maintainers": [{ "name": "esp", "email": "e.poberezkin@me.com" }],
"time": {
"modified": "2022-06-19T06:25:13.230Z",
"created": "2017-06-04T18:42:17.844Z",
"0.0.1": "2017-06-04T18:42:17.844Z",
"0.1.0": "2017-06-05T20:19:20.802Z",
"0.2.0": "2017-06-14T21:22:49.143Z",
"0.3.0": "2017-06-15T20:22:58.966Z",
"0.3.1": "2017-06-23T23:50:57.513Z",
"0.4.0": "2018-05-08T19:38:06.477Z",
"0.4.1": "2018-06-10T08:42:05.056Z",
"0.5.0": "2020-09-05T19:53:20.342Z",
"1.0.0": "2020-12-13T10:56:54.719Z"
},
"homepage": "https://github.com/epoberezkin/json-schema-traverse#readme",
"keywords": ["JSON-Schema", "traverse", "iterate"],
"repository": {
"type": "git",
"url": "git+https://github.com/epoberezkin/json-schema-traverse.git"
},
"author": { "name": "Evgeny Poberezkin" },
"bugs": {
"url": "https://github.com/epoberezkin/json-schema-traverse/issues"
},
"license": "MIT",
"readmeFilename": "README.md"
}

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -0,0 +1,605 @@
{
"_id": "pathval",
"_rev": "21-2c490ca7f605dac95e8fee78fa5c545e",
"name": "pathval",
"description": "Object value retrieval given a string path",
"dist-tags": { "latest": "1.1.1" },
"versions": {
"0.0.1": {
"name": "pathval",
"version": "0.0.1",
"description": "Object value retrieval given a string path",
"main": "./lib/pathval.js",
"homepage": "https://github.com/chaijs/pathval",
"scripts": {
"test": "mocha test/*.test.js",
"coverage": "istanbul cover ./node_modules/.bin/_mocha test/*.test.js",
"coveralls": "istanbul cover ./node_modules/.bin/_mocha test/*.test.js --report lcovonly && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"test-readme": "jsmd README.md"
},
"repository": {
"type": "git",
"url": "https://github.com/chaijs/pathval"
},
"devDependencies": {
"mocha": "~1.13.0",
"chai": "~1.8.1",
"coveralls": "~2.3.0",
"istanbul": "~0.1.44",
"jsmd": "~0.2.0"
},
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@0.0.1",
"dist": {
"shasum": "130054c3874153be50fc3fdb4c5b9a1c68036d08",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-0.0.1.tgz",
"integrity": "sha512-yXID7tg2VqiMHVsJF7aXo5KUE6A4bmGYsWulnMGNyM6pfQujjOBXmCPZHQ3Mndx5amQ0nOWnwaG/RLaOGMib4Q==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCmrl3XuKZF435pd685aQA4Sc4MDb3plPnNezwqGjJldAIgCmu43u+TCsEQ3cx18kHQ9tUGVi2+bYyUGLyqzOnIsQQ="
}
]
},
"_from": ".",
"_npmVersion": "1.3.8",
"_npmUser": { "name": "vesln", "email": "hi@vesln.com" },
"maintainers": [{ "name": "vesln", "email": "hi@vesln.com" }],
"directories": {}
},
"0.1.0": {
"name": "pathval",
"version": "0.1.0",
"description": "Object value retrieval given a string path",
"main": "./lib/pathval.js",
"homepage": "https://github.com/chaijs/pathval",
"scripts": {
"test": "hydro",
"coverage": "istanbul cover _hydro",
"coveralls": "istanbul cover _hydro --report lcovonly && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"test-readme": "jsmd README.md"
},
"repository": {
"type": "git",
"url": "https://github.com/chaijs/pathval"
},
"devDependencies": {
"coveralls": "~2.3.0",
"istanbul": "~0.1.44",
"jsmd": "~0.2.0",
"simple-assert": "~1.0.0",
"hydro": "~0.8.7",
"hydro-file-suite": "0.0.1",
"hydro-doc": "0.0.2",
"hydro-bdd": "0.0.3"
},
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@0.1.0",
"dist": {
"shasum": "a4b33d8c231784bb3c88bbf1802f8b59b883d5cd",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-0.1.0.tgz",
"integrity": "sha512-IsbM3R/xiW40mcyFHb5wAqjCiT8vUMSsAWgXS3ysYVLHXS91x2XT9IGmVKhMJeyU5ORjc/b7JvemcEkjA1nEGQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDMQ8F/vfTCVo0JrJwekG+mUi2ZWlrf4D+Fx8f4o9TXJwIhANhebK8YzkkiyAgBvJvnnpmlnSoVd+g3HwxbgBHjHlln"
}
]
},
"_from": ".",
"_npmVersion": "1.3.8",
"_npmUser": { "name": "vesln", "email": "hi@vesln.com" },
"maintainers": [
{ "name": "vesln", "email": "hi@vesln.com" },
{ "name": "jakeluer", "email": "jake@alogicalparadox.com" }
],
"directories": {}
},
"0.1.1": {
"name": "pathval",
"version": "0.1.1",
"description": "Object value retrieval given a string path",
"main": "./index.js",
"homepage": "https://github.com/chaijs/pathval",
"scripts": {
"test": "hydro",
"coverage": "istanbul cover _hydro",
"coveralls": "istanbul cover _hydro --report lcovonly && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"test-readme": "jsmd README.md"
},
"repository": {
"type": "git",
"url": "https://github.com/chaijs/pathval"
},
"devDependencies": {
"coveralls": "~2.3.0",
"istanbul": "~0.1.44",
"jsmd": "~0.2.0",
"simple-assert": "~1.0.0",
"hydro": "~0.8.7",
"hydro-file-suite": "0.0.1",
"hydro-doc": "0.0.2",
"hydro-bdd": "0.0.3"
},
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"license": "MIT",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@0.1.1",
"dist": {
"shasum": "08f911cdca9cce5942880da7817bc0b723b66d82",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-0.1.1.tgz",
"integrity": "sha512-2AJyCGXy4VsZ2wa0TmMoL93KtWshxWQAMuuAG+7/Q3kth9uRDV38cMZTaSCsrTDJEwV8QbIHad+3E673s1ZY0A==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIHnANtUzPBfWCQOD8WwOCSVbloYchYo1DDoO6Vat7Z8YAiACo1AkJzXU1BQfpX6aLuo+VXB0u3elqUi8FSAXMVfgFQ=="
}
]
},
"_from": ".",
"_npmVersion": "1.3.15",
"_npmUser": { "name": "jakeluer", "email": "jake@alogicalparadox.com" },
"maintainers": [
{ "name": "vesln", "email": "hi@vesln.com" },
{ "name": "jakeluer", "email": "jake@alogicalparadox.com" }
],
"directories": {}
},
"0.2.0": {
"name": "pathval",
"description": "Object value retrieval given a string path",
"homepage": "https://github.com/chaijs/pathval",
"keywords": ["pathval", "value retrieval", "chai util"],
"license": "MIT",
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"files": ["index.js", "pathval.js"],
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/pathval.git"
},
"scripts": {
"build": "browserify --bare $npm_package_main --standalone pathval -o pathval.js",
"lint": "eslint --ignore-path .gitignore .",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "istanbul cover _mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"dependencies": { "type-detect": "^2.0.1" },
"devDependencies": {
"browserify": "^13.0.0",
"browserify-istanbul": "^1.0.0",
"coveralls": "2.11.9",
"eslint": "^2.4.0",
"eslint-config-strict": "^8.5.0",
"eslint-plugin-filenames": "^0.2.0",
"ghooks": "^1.0.1",
"istanbul": "^0.4.2",
"karma": "^0.13.22",
"karma-browserify": "^5.0.2",
"karma-coverage": "^0.5.5",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^0.3.1",
"lcov-result-merger": "^1.0.2",
"mocha": "^2.4.5",
"phantomjs-prebuilt": "^2.1.5",
"semantic-release": "^4.3.5",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.4",
"validate-commit-msg": "^2.3.1"
},
"engines": { "node": "*" },
"version": "0.2.0",
"gitHead": "979fa9d501484be5a48f9bcaaf00d726b8190a6a",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@0.2.0",
"_shasum": "cf87ac1ced492cadcbcbb482d2e72012a5237ade",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "0.10.47",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "cf87ac1ced492cadcbcbb482d2e72012a5237ade",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-0.2.0.tgz",
"integrity": "sha512-RqQUI9eBpASf+T/+CvwwO/BBtw7tXWTHAdIac+RdksgHqnsbNcDePIIhuVThvHX6MaTqC4/8B7k1eyU4/4AoDA==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQCppMVkec5tFAbFh1JQmM5/KBBe4yAHRdhaTHQUZCvJzQIhAKwpnP4EW1ZzgNUBDjr4Zk8HJoH/nWaF5C2zmiy2V2t8"
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/pathval-0.2.0.tgz_1475626779711_0.6217861396726221"
},
"directories": {}
},
"0.2.1": {
"name": "pathval",
"description": "Object value retrieval given a string path",
"homepage": "https://github.com/chaijs/pathval",
"keywords": ["pathval", "value retrieval", "chai util"],
"license": "MIT",
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"files": ["index.js", "pathval.js"],
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/pathval.git"
},
"scripts": {
"build": "browserify --bare $npm_package_main --standalone pathval -o pathval.js",
"lint": "eslint --ignore-path .gitignore .",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "istanbul cover _mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"devDependencies": {
"browserify": "^13.0.0",
"browserify-istanbul": "^1.0.0",
"coveralls": "2.11.9",
"eslint": "^2.4.0",
"eslint-config-strict": "^8.5.0",
"eslint-plugin-filenames": "^0.2.0",
"ghooks": "^1.0.1",
"istanbul": "^0.4.2",
"karma": "^0.13.22",
"karma-browserify": "^5.0.2",
"karma-coverage": "^0.5.5",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^0.3.1",
"lcov-result-merger": "^1.0.2",
"mocha": "^2.4.5",
"phantomjs-prebuilt": "^2.1.5",
"semantic-release": "^4.3.5",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.4",
"validate-commit-msg": "^2.3.1"
},
"engines": { "node": "*" },
"version": "0.2.1",
"gitHead": "6d2f6d4db2fc62f0c74d89d0575cfd433afdd2a7",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@0.2.1",
"_shasum": "47ead80a77bbe6192b59326e1b71635e6962563c",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "0.10.47",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "47ead80a77bbe6192b59326e1b71635e6962563c",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-0.2.1.tgz",
"integrity": "sha512-yjoZNnKIKwdEwYqCWqgbplqEyh19S2SZwnKgdJtcuQ7HLgXoSVmszN1mArYouhwpLp6etkCX70NpmLknXyJ4VQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQD0LF0Ud2NgSQ53eztERakKGlSwuXgyA2izKVDSkbG3SgIgDLq5JAqQHAXARcrqVswnVkJfg++ZpG/0mlbWfmWsm6E="
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/pathval-0.2.1.tgz_1475703461600_0.5263914761599153"
},
"directories": {}
},
"1.0.0": {
"name": "pathval",
"description": "Object value retrieval given a string path",
"homepage": "https://github.com/chaijs/pathval",
"keywords": ["pathval", "value retrieval", "chai util"],
"license": "MIT",
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"files": ["index.js", "pathval.js"],
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/pathval.git"
},
"scripts": {
"build": "browserify --bare $npm_package_main --standalone pathval -o pathval.js",
"lint": "eslint --ignore-path .gitignore .",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "istanbul cover _mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"devDependencies": {
"browserify": "^13.0.0",
"browserify-istanbul": "^1.0.0",
"coveralls": "2.11.9",
"eslint": "^2.4.0",
"eslint-config-strict": "^8.5.0",
"eslint-plugin-filenames": "^0.2.0",
"ghooks": "^1.0.1",
"istanbul": "^0.4.2",
"karma": "^0.13.22",
"karma-browserify": "^5.0.2",
"karma-coverage": "^0.5.5",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^0.3.1",
"lcov-result-merger": "^1.0.2",
"mocha": "^2.4.5",
"phantomjs-prebuilt": "^2.1.5",
"semantic-release": "^4.3.5",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.4",
"validate-commit-msg": "^2.3.1"
},
"engines": { "node": "*" },
"version": "1.0.0",
"gitHead": "37f1dc9f0c41b815598e62c92bbe89b83fca1089",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@1.0.0",
"_shasum": "dd843dd66e7666d3193376f4479e6ee6e1d29d28",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "0.10.47",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "dd843dd66e7666d3193376f4479e6ee6e1d29d28",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-1.0.0.tgz",
"integrity": "sha512-VIsZrz7ZymQhnimx/iNm0rp+tK2SO60k4PQ2gKvtldy40/3MT8gbaKOrjV4xDQ3wF54QjU/Ucu0o2HJe61oxjg==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQCEIu8dTztXUUCEmWzABtCXZDBt1vqx5BDA+68nPr+UFgIhAMcZUqZb+LDLV1JN5s008torQ4rWhTJ/+eFsu7wQP3VU"
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/pathval-1.0.0.tgz_1475963991947_0.6970440507866442"
},
"directories": {}
},
"1.1.0": {
"name": "pathval",
"description": "Object value retrieval given a string path",
"homepage": "https://github.com/chaijs/pathval",
"keywords": ["pathval", "value retrieval", "chai util"],
"license": "MIT",
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"files": ["index.js", "pathval.js"],
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/pathval.git"
},
"scripts": {
"build": "browserify --bare $npm_package_main --standalone pathval -o pathval.js",
"lint": "eslint --ignore-path .gitignore .",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "istanbul cover _mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"devDependencies": {
"browserify": "^13.0.0",
"browserify-istanbul": "^1.0.0",
"coveralls": "2.11.9",
"eslint": "^2.4.0",
"eslint-config-strict": "^8.5.0",
"eslint-plugin-filenames": "^0.2.0",
"ghooks": "^1.0.1",
"istanbul": "^0.4.2",
"karma": "^0.13.22",
"karma-browserify": "^5.0.2",
"karma-coverage": "^0.5.5",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^0.3.1",
"lcov-result-merger": "^1.0.2",
"mocha": "^3.1.2",
"phantomjs-prebuilt": "^2.1.5",
"semantic-release": "^4.3.5",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.4",
"validate-commit-msg": "^2.3.1"
},
"engines": { "node": "*" },
"version": "1.1.0",
"gitHead": "fd11b26a39c2d948ef6785feac1edf8c01e4a055",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@1.1.0",
"_shasum": "b942e6d4bde653005ef6b71361def8727d0645e0",
"_from": ".",
"_npmVersion": "3.10.8",
"_nodeVersion": "0.10.47",
"_npmUser": { "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
"dist": {
"shasum": "b942e6d4bde653005ef6b71361def8727d0645e0",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-1.1.0.tgz",
"integrity": "sha512-qZ181q3ICkag/+lv1X6frDUF84pqCm30qild3LGbD84n0AC75CYwnWsQRDlpz7zDkU5NVcmhHh4LjXK0goLYZA==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIHQe9Hc6MGAGtARY10udH/aL5O/58z3hsoL7B1mGShwdAiASBywB9qBLzuwiTJUuGLg3QUtLWHCfqlz0pyOb1s+UUg=="
}
]
},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/pathval-1.1.0.tgz_1476222299732_0.22869419353082776"
},
"directories": {}
},
"1.1.1": {
"name": "pathval",
"description": "Object value retrieval given a string path",
"homepage": "https://github.com/chaijs/pathval",
"version": "1.1.1",
"keywords": ["pathval", "value retrieval", "chai util"],
"license": "MIT",
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"main": "./index.js",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/pathval.git"
},
"scripts": {
"build": "browserify --standalone pathval -o pathval.js",
"lint": "eslint --ignore-path .gitignore .",
"lint:fix": "npm run lint -- --fix",
"prepublish": "npm run build",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"pretest": "npm run lint",
"test": "npm run test:node && npm run test:browser && npm run upload-coverage",
"test:browser": "karma start --singleRun=true",
"test:node": "nyc mocha",
"upload-coverage": "lcov-result-merger 'coverage/**/lcov.info' | coveralls; exit 0"
},
"config": { "ghooks": { "commit-msg": "validate-commit-msg" } },
"eslintConfig": {
"extends": ["strict/es5"],
"env": { "es6": true },
"globals": { "HTMLElement": false },
"rules": { "complexity": 0, "max-statements": 0 }
},
"devDependencies": {
"browserify": "^17.0.0",
"browserify-istanbul": "^3.0.1",
"coveralls": "^3.1.0",
"eslint": "^7.13.0",
"eslint-config-strict": "^14.0.1",
"eslint-plugin-filenames": "^1.3.2",
"ghooks": "^2.0.4",
"karma": "^5.2.3",
"karma-browserify": "^7.0.0",
"karma-coverage": "^2.0.3",
"karma-mocha": "^2.0.1",
"karma-phantomjs-launcher": "^1.0.4",
"karma-sauce-launcher": "^4.3.3",
"lcov-result-merger": "^3.1.0",
"mocha": "^8.2.1",
"nyc": "^15.1.0",
"phantomjs-prebuilt": "^2.1.16",
"semantic-release": "^17.2.2",
"simple-assert": "^1.0.0",
"travis-after-all": "^1.4.5",
"validate-commit-msg": "^2.14.0"
},
"engines": { "node": "*" },
"gitHead": "db6c3e39c39859564704b7f37149082689f1b172",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"_id": "pathval@1.1.1",
"_nodeVersion": "14.9.0",
"_npmVersion": "6.14.8",
"dist": {
"integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
"shasum": "8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d",
"tarball": "http://localhost:4545/npm/registry/pathval/pathval-1.1.1.tgz",
"fileCount": 6,
"unpackedSize": 15830,
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgD+x9CRA9TVsSAnZWagAARd4P+wdHojovTrxc91hH6k/c\n3Godh5zA1jYAwNlwjcHWxS88ahx4eOff0OiBeNx+nVhILsAKxrXyCySC0yFc\nf16UdXO6u3IX4O8dzlVFwKYdT7icgioUDzrxsNXioE/sdZMXlEyNFxm6QHN8\nBUz0fI+h5FyTUuHIjt6vd5ZbDL5nsL58+S3JiqWl76KBxNyzUh53j+2AVLW4\n+bTUyNQMkgFUXwY0O3IxNQqBLuDUOrAoiCowF/WsgzESdkvwFbVTu6JY4Hnb\niMw4RSIbV78iEVESSli1Tug3bBFLshjzIzZUNqzdu9En1iy12sPvmqctXDZy\ntimD/2vV7ei5zievT/FjwcXj/V5k2if7mNxwbdBPPEb36UeXnCYzYOyUAmY8\noSZbAav6rVTVJkkBYl+2XXz4eypZ6CNBc07y8M/1y8tQ0vgQYTd43fHvrZ1K\nglH/YtSLj+abkPtW65wCZS1Ahx8Okvg4bsogwkovPL0SUiNbQzBvoUeJz3bz\nPIE2t7H7ZIniuTYEF/l6y+MKWOdVBt1ucq8rsBRiGMov5PQK08/8OzrBOl/K\n3dZY61MkvmcTeBMlw7Ti2pZ8A0+W6Tw4naO31KfmuVh4404Fqp79G3TEu0Xl\ngjoSFM/TdS/3QeuCMCl9v4ol8Cs1aMybSsAjdGe1UOWTetLX5cNd239CXy9o\n1gti\r\n=fphS\r\n-----END PGP SIGNATURE-----\r\n",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDCq1EFJ5gpdj/gAtuMvlWrx/gGxxt2sXf3r02rgfLyuQIgN3fLLXsIoODW1d6v4ajwQ6/MikOWcxFFSj9cBcVQTdY="
}
]
},
"_npmUser": { "name": "chai", "email": "chaijs@keithcirkel.co.uk" },
"directories": {},
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
{ "name": "chai", "email": "chaijs@keithcirkel.co.uk" }
],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/pathval_1.1.1_1611656316931_0.13667452195133456"
},
"_hasShrinkwrap": false
}
},
"readme": "<h1 align=center>\n <a href=\"http://chaijs.com\" title=\"Chai Documentation\">\n <img alt=\"ChaiJS\" src=\"http://chaijs.com/img/chai-logo.png\">\n </a>\n <br>\n pathval\n</h1>\n\n<p align=center>\n Tool for Object value retrieval given a string path for <a href=\"http://nodejs.org\">node</a> and the browser.\n</p>\n\n<p align=center>\n <a href=\"./LICENSE\">\n <img\n alt=\"license:mit\"\n src=\"https://img.shields.io/badge/license-mit-green.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://github.com/chaijs/pathval/releases\">\n <img\n alt=\"tag:?\"\n src=\"https://img.shields.io/github/tag/chaijs/pathval.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://travis-ci.org/chaijs/pathval\">\n <img\n alt=\"build:?\"\n src=\"https://img.shields.io/travis/chaijs/pathval/master.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://coveralls.io/r/chaijs/pathval\">\n <img\n alt=\"coverage:?\"\n src=\"https://img.shields.io/coveralls/chaijs/pathval/master.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://www.npmjs.com/packages/pathval\">\n <img\n alt=\"npm:?\"\n src=\"https://img.shields.io/npm/v/pathval.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://www.npmjs.com/packages/pathval\">\n <img\n alt=\"dependencies:?\"\n src=\"https://img.shields.io/npm/dm/pathval.svg?style=flat-square\"\n />\n </a>\n <a href=\"\">\n <img\n alt=\"devDependencies:?\"\n src=\"https://img.shields.io/david/chaijs/pathval.svg?style=flat-square\"\n />\n </a>\n <br/>\n <a href=\"https://saucelabs.com/u/chaijs-pathval\">\n <img\n alt=\"Selenium Test Status\"\n src=\"https://saucelabs.com/browser-matrix/chaijs-pathval.svg\"\n />\n </a>\n <br>\n <a href=\"https://chai-slack.herokuapp.com/\">\n <img\n alt=\"Join the Slack chat\"\n src=\"https://img.shields.io/badge/slack-join%20chat-E2206F.svg?style=flat-square\"\n />\n </a>\n <a href=\"https://gitter.im/chaijs/chai\">\n <img\n alt=\"Join the Gitter chat\"\n src=\"https://img.shields.io/badge/gitter-join%20chat-D0104D.svg?style=flat-square\"\n />\n </a>\n</p>\n\n## What is pathval?\n\nPathval is a module which you can use to retrieve or set an Object's property for a given `String` path.\n\n## Installation\n\n### Node.js\n\n`pathval` is available on [npm](http://npmjs.org). To install it, type:\n\n $ npm install pathval\n\n### Browsers\n\nYou can also use it within the browser; install via npm and use the `pathval.js` file found within the download. For example:\n\n```html\n<script src=\"./node_modules/pathval/pathval.js\"></script>\n```\n\n## Usage\n\nThe primary export of `pathval` is an object which has the following methods:\n\n* `hasProperty(object, name)` - Checks whether an `object` has `name`d property or numeric array index.\n* `getPathInfo(object, path)` - Returns an object with info indicating the value of the `parent` of that path, the `name ` of the property we're retrieving and its `value`.\n* `getPathValue(object, path)` - Retrieves the value of a property at a given `path` inside an `object`'.\n* `setPathValue(object, path, value)` - Sets the `value` of a property at a given `path` inside an `object` and returns the object in which the property has been set.\n\n```js\nvar pathval = require('pathval');\n```\n\n#### .hasProperty(object, name)\n\n```js\nvar pathval = require('pathval');\n\nvar obj = { prop: 'a value' };\npathval.hasProperty(obj, 'prop'); // true\n```\n\n#### .getPathInfo(object, path)\n\n```js\nvar pathval = require('pathval');\n\nvar obj = { earth: { country: 'Brazil' } };\npathval.getPathInfo(obj, 'earth.country'); // { parent: { country: 'Brazil' }, name: 'country', value: 'Brazil', exists: true }\n```\n\n#### .getPathValue(object, path)\n\n```js\nvar pathval = require('pathval');\n\nvar obj = { earth: { country: 'Brazil' } };\npathval.getPathValue(obj, 'earth.country'); // 'Brazil'\n```\n\n#### .setPathValue(object, path, value)\n\n```js\nvar pathval = require('pathval');\n\nvar obj = { earth: { country: 'Brazil' } };\npathval.setPathValue(obj, 'earth.country', 'USA');\n\nobj.earth.country; // 'USA'\n```\n",
"maintainers": [
{ "name": "chaijs", "email": "chaijs@keithcirkel.co.uk" },
{ "name": "chai", "email": "chaijs@keithcirkel.co.uk" }
],
"time": {
"modified": "2022-06-23T14:56:08.461Z",
"created": "2013-11-24T18:10:05.614Z",
"0.0.1": "2013-11-24T18:10:08.847Z",
"0.1.0": "2013-12-28T10:40:59.775Z",
"0.1.1": "2013-12-30T23:14:27.044Z",
"0.2.0": "2016-10-05T00:19:41.579Z",
"0.2.1": "2016-10-05T21:37:43.749Z",
"1.0.0": "2016-10-08T21:59:52.585Z",
"1.1.0": "2016-10-11T21:45:01.397Z",
"1.1.1": "2021-01-26T10:18:37.054Z"
},
"author": { "name": "Veselin Todorov", "email": "hi@vesln.com" },
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/chaijs/pathval.git"
},
"users": { "focusaurus": true, "justjavac": true },
"homepage": "https://github.com/chaijs/pathval",
"bugs": { "url": "https://github.com/chaijs/pathval/issues" },
"license": "MIT",
"readmeFilename": "README.md",
"keywords": ["pathval", "value retrieval", "chai util"]
}

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,463 @@
{
"_id": "require-from-string",
"_rev": "24-c2cdc326408bbec716917c1afa732f95",
"name": "require-from-string",
"description": "Require module from string",
"dist-tags": { "latest": "2.0.2" },
"versions": {
"1.0.0": {
"name": "require-from-string",
"version": "1.0.0",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/floatdrop/require-from-string"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "247ebd2cccc5aabde8876312dfed1dc1e8e6bedd",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string",
"_id": "require-from-string@1.0.0",
"_shasum": "05f10696e6ff228172c4e313a8bdebd95534548a",
"_from": ".",
"_npmVersion": "1.4.28",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"dist": {
"shasum": "05f10696e6ff228172c4e313a8bdebd95534548a",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-1.0.0.tgz",
"integrity": "sha512-NPk19C5PqAFl1JOHwyOvtiB7QHiMpbzdiq/n8VeKOE75L0wMCKAoQRLfVE/HqnFrwmMyl5bVFfFLlr0M81QOjQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDzYLnqduLTbVYBqrrY/xErtb+YTp8Etmnxqz1NqN8N+QIgNLWP1aBHxO14iiqbmC4XYeiYvsFw/8fpbzXPoWT23sw="
}
]
},
"directories": {}
},
"1.0.1": {
"name": "require-from-string",
"version": "1.0.1",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/floatdrop/require-from-string"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "b869afb66be27941b362c44381f93bb3baf2422f",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string",
"_id": "require-from-string@1.0.1",
"_shasum": "b5d140f894b70feacb8f9a7209588b51d0c7f629",
"_from": ".",
"_npmVersion": "2.14.7",
"_nodeVersion": "4.2.0",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"shasum": "b5d140f894b70feacb8f9a7209588b51d0c7f629",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-1.0.1.tgz",
"integrity": "sha512-wKgFU9RE/yK9AHv9JTlpKtqF0prdiIPa4PIBL95Z7CjW8INyTsBGn3cFt3G0Dw4hMbxvwVe9+1ZnYYoGPJqX6g==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIGRvTq1OGMH0bpQTWKSSXoIykEBshVsVY2T3siW811wkAiEAhEfiDcJTKgX6jpM56ZaumPxSk+6hPBG/sWOT1lGMdGg="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"directories": {}
},
"1.0.2": {
"name": "require-from-string",
"version": "1.0.2",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/floatdrop/require-from-string"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "0ce4cc5c5eb0487eddd6463ceafff7fcf0d3d459",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string",
"_id": "require-from-string@1.0.2",
"_shasum": "83ce7d5b4671d89afb2ee0287a51a2a5b997acfd",
"_from": ".",
"_npmVersion": "1.4.28",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"dist": {
"shasum": "83ce7d5b4671d89afb2ee0287a51a2a5b997acfd",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-1.0.2.tgz",
"integrity": "sha512-zceVE5W40yFQ7cNFgSkOKMgE00tXoF58RFe8NqhTVWEI9azOieuvaO8IPDvUG9Ziq3UOh5Vku3+RHfD6M/AaGQ==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCS5LeiZ8cVP01bX2gjHT5pB1Mfrm3H/AOjESrhgLGhwwIgMNNL32NWrC9DnXlrk0Ei0o0T64JPUWV0ENpCb+oJXjs="
}
]
},
"directories": {}
},
"1.1.0": {
"name": "require-from-string",
"version": "1.1.0",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/floatdrop/require-from-string"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "42b400d921efa55874cc301e59282a2d2a442715",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string",
"_id": "require-from-string@1.1.0",
"_shasum": "91610638dfe986818c591f585d1085b386503289",
"_from": ".",
"_npmVersion": "2.14.7",
"_nodeVersion": "4.2.0",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"shasum": "91610638dfe986818c591f585d1085b386503289",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-1.1.0.tgz",
"integrity": "sha512-KIOCdVHbUyDA3aDuoIHcuLsCsO00m/rwnOm1kFN2NNTnMpI7lkVnkzo4utM4jVm7BCdb4D+7++xCdgx7hpA6ag==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIDxgrH/lsoVWpHAc1NI21atxAB1tdp00/4qaH/MhaRB4AiEA4Ej5LtMD1KsKlabY9oAl9MaTqxs9JhmtTFU31sr61SA="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"directories": {}
},
"1.2.0": {
"name": "require-from-string",
"version": "1.2.0",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/require-from-string.git"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "8610539617336b3f60376c040a090a9797645bfe",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string#readme",
"_id": "require-from-string@1.2.0",
"_shasum": "12a23f7e69c9d6d16a4517650f8b59629777e3a0",
"_from": ".",
"_npmVersion": "2.15.1",
"_nodeVersion": "4.4.3",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"shasum": "12a23f7e69c9d6d16a4517650f8b59629777e3a0",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-1.2.0.tgz",
"integrity": "sha512-7swt+9ZwilLV4efl9ZuYsG1CtT98eusv8j9hfzSoD7ZvIGBzl8xZQn8RWsvxavst41WQqVbWSfM9Mrgf5lp5tA==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCIAXM5yQT268yhzaecdkBK4lHhzD4dv1tGeRuAbvfF5jrAiA42kgmMNKwVL07eLionZofGeHokIaBIF9X3U1Xdds0FQ=="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/require-from-string-1.2.0.tgz_1462260731186_0.739558148663491"
},
"directories": {}
},
"1.2.1": {
"name": "require-from-string",
"version": "1.2.1",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/require-from-string.git"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "b81e995c6ff82fbf71d9ee7a9990b10794fecb98",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string#readme",
"_id": "require-from-string@1.2.1",
"_shasum": "529c9ccef27380adfec9a2f965b649bbee636418",
"_from": ".",
"_npmVersion": "3.10.3",
"_nodeVersion": "6.6.0",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"shasum": "529c9ccef27380adfec9a2f965b649bbee636418",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-1.2.1.tgz",
"integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDpd7vHXOYuo8RA/lL8DvBGqc2nFvUpmf0Rj4WHXevtkgIgGSbXabOE7T7ktq/vf+hG6CgNWqjw7fMJI/uo4fBSNs0="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/require-from-string-1.2.1.tgz_1475350323439_0.3740670408587903"
},
"directories": {}
},
"2.0.0": {
"name": "require-from-string",
"version": "2.0.0",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/require-from-string.git"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "ce8ae318921a649ede77fd13c1b1851889923786",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string#readme",
"_id": "require-from-string@2.0.0",
"_shasum": "620588727e5941acbf467db17728b9cab5176211",
"_from": ".",
"_npmVersion": "4.1.2",
"_nodeVersion": "7.7.1",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"shasum": "620588727e5941acbf467db17728b9cab5176211",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-2.0.0.tgz",
"integrity": "sha512-VX8ZAJPwCYe0KVhHyRfY8xLjqfwbvoqssql5vq6JPBF9dOrRkdalCdDQxQ/pwvff7l0Ft3GpeFIqzvrI4qQxmw==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIGQ2q4Lqrtxs9fB+lYElKC5x49SdZyGUiy07A2gUfxoCAiEA/BFPfHEOPts8mQdoEaQgi5HE8kJq/92PuuqBtr/Anwk="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/require-from-string-2.0.0.tgz_1505545473212_0.1633690781891346"
},
"directories": {}
},
"2.0.1": {
"name": "require-from-string",
"version": "2.0.1",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/require-from-string.git"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "cbe9197bfb08e7354b2e84cd060ba36fc476e1d3",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string#readme",
"_id": "require-from-string@2.0.1",
"_shasum": "c545233e9d7da6616e9d59adfb39fc9f588676ff",
"_from": ".",
"_npmVersion": "4.1.2",
"_nodeVersion": "7.7.1",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"shasum": "c545233e9d7da6616e9d59adfb39fc9f588676ff",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-2.0.1.tgz",
"integrity": "sha512-McvI+pnbFkdwzAcXx2b8WKmSo9ucq6mlVcLd2ZgxuwOknFtj5dz9PTleVfMVTgcp5ucJ8CMDqYkJ3jDZImvcxg==",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQDYDVuCZAdTg4i4CkF9ALbEwb1epiOGL7/8rCkwRGwfiAIgEJTKgxOB1rOsfMf46tMJGvwSkcYrFbEL7n5Ute5iVMA="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/require-from-string-2.0.1.tgz_1505631156427_0.9107523618731648"
},
"directories": {}
},
"2.0.2": {
"name": "require-from-string",
"version": "2.0.2",
"description": "Require module from string",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/require-from-string.git"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"engines": { "node": ">=0.10.0" },
"scripts": { "test": "mocha" },
"files": ["index.js"],
"keywords": [],
"dependencies": {},
"devDependencies": { "mocha": "*" },
"gitHead": "d1575a49065eb7a49b86b4de963f04f1a14dfd60",
"bugs": {
"url": "https://github.com/floatdrop/require-from-string/issues"
},
"homepage": "https://github.com/floatdrop/require-from-string#readme",
"_id": "require-from-string@2.0.2",
"_npmVersion": "5.6.0",
"_nodeVersion": "9.5.0",
"_npmUser": { "name": "floatdrop", "email": "floatdrop@gmail.com" },
"dist": {
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"shasum": "89a7fdd938261267318eafe14f9c32e598c36909",
"tarball": "http://localhost:4545/npm/registry/require-from-string/require-from-string-2.0.2.tgz",
"fileCount": 4,
"unpackedSize": 3422,
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIE2jrMs9LEA5YwPbB+k86fiEWbTiZrILb/xQp2cSIEePAiEApTYU69t0eG1qFeeVayYDlVRtYxsT4vFi9gJB5pqvtXE="
}
]
},
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"directories": {},
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/require-from-string_2.0.2_1523267387201_0.3738099631330949"
},
"_hasShrinkwrap": false
}
},
"readme": "# require-from-string [![Build Status](https://travis-ci.org/floatdrop/require-from-string.svg?branch=master)](https://travis-ci.org/floatdrop/require-from-string)\n\nLoad module from string in Node.\n\n## Install\n\n```\n$ npm install --save require-from-string\n```\n\n\n## Usage\n\n```js\nvar requireFromString = require('require-from-string');\n\nrequireFromString('module.exports = 1');\n//=> 1\n```\n\n\n## API\n\n### requireFromString(code, [filename], [options])\n\n#### code\n\n*Required* \nType: `string`\n\nModule code.\n\n#### filename\nType: `string` \nDefault: `''`\n\nOptional filename.\n\n\n#### options\nType: `object`\n\n##### appendPaths\nType: `Array`\n\nList of `paths`, that will be appended to module `paths`. Useful, when you want\nto be able require modules from these paths.\n\n##### prependPaths\nType: `Array`\n\nSame as `appendPaths`, but paths will be prepended.\n\n## License\n\nMIT © [Vsevolod Strukchinsky](http://github.com/floatdrop)\n",
"maintainers": [{ "name": "floatdrop", "email": "floatdrop@gmail.com" }],
"time": {
"modified": "2022-06-26T11:37:26.323Z",
"created": "2015-07-18T15:08:53.362Z",
"1.0.0": "2015-07-18T15:08:53.362Z",
"1.0.1": "2015-11-03T08:09:49.990Z",
"1.0.2": "2015-11-06T19:08:43.545Z",
"1.1.0": "2015-11-07T11:43:15.008Z",
"1.2.0": "2016-05-03T07:32:12.394Z",
"1.2.1": "2016-10-01T19:32:05.278Z",
"2.0.0": "2017-09-16T07:04:34.217Z",
"2.0.1": "2017-09-17T06:52:37.555Z",
"2.0.2": "2018-04-09T09:49:47.301Z"
},
"homepage": "https://github.com/floatdrop/require-from-string#readme",
"keywords": [],
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/require-from-string.git"
},
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"bugs": { "url": "https://github.com/floatdrop/require-from-string/issues" },
"license": "MIT",
"readmeFilename": "readme.md",
"users": { "nichoth": true, "morewry": true, "eshinn": true }
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -1,4 +1,5 @@
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;
use deno_ast::ModuleSpecifier;
@ -24,6 +25,7 @@ use crate::compat;
use crate::errors;
use crate::fmt_errors::format_js_error;
use crate::module_loader::CliModuleLoader;
use crate::node;
use crate::ops;
use crate::proc_state::ProcState;
use crate::tools;
@ -99,7 +101,7 @@ impl CliMainWorker {
}
} else {
// Regular ES module execution
self.worker.execute_main_module(&self.main_module).await?;
self.execute_main_module_possibly_with_npm().await?;
}
self.worker.dispatch_load_event(&located_script_name!())?;
@ -134,39 +136,39 @@ impl CliMainWorker {
/// state of any pending events and emitting accordingly on drop in the case of a future
/// cancellation.
struct FileWatcherModuleExecutor {
worker: MainWorker,
inner: CliMainWorker,
pending_unload: bool,
ps: ProcState,
}
impl FileWatcherModuleExecutor {
pub fn new(
worker: MainWorker,
ps: ProcState,
) -> FileWatcherModuleExecutor {
pub fn new(worker: CliMainWorker) -> FileWatcherModuleExecutor {
FileWatcherModuleExecutor {
worker,
inner: worker,
pending_unload: false,
ps,
}
}
/// Execute the given main module emitting load and unload events before and after execution
/// respectively.
pub async fn execute(
&mut self,
main_module: &ModuleSpecifier,
) -> Result<(), AnyError> {
if self.ps.options.compat() {
self.worker.execute_side_module(&compat::GLOBAL_URL).await?;
pub async fn execute(&mut self) -> Result<(), AnyError> {
if self.inner.ps.options.compat() {
self
.inner
.worker
.execute_side_module(&compat::GLOBAL_URL)
.await?;
}
self.worker.execute_main_module(main_module).await?;
self.worker.dispatch_load_event(&located_script_name!())?;
self.inner.execute_main_module_possibly_with_npm().await?;
self
.inner
.worker
.dispatch_load_event(&located_script_name!())?;
self.pending_unload = true;
let result = loop {
let result = self.worker.run_event_loop(false).await;
let result = self.inner.worker.run_event_loop(false).await;
if !self
.inner
.worker
.dispatch_beforeunload_event(&located_script_name!())?
{
@ -179,7 +181,10 @@ impl CliMainWorker {
return Err(err);
}
self.worker.dispatch_unload_event(&located_script_name!())?;
self
.inner
.worker
.dispatch_unload_event(&located_script_name!())?;
Ok(())
}
@ -189,6 +194,7 @@ impl CliMainWorker {
fn drop(&mut self) {
if self.pending_unload {
self
.inner
.worker
.dispatch_unload_event(&located_script_name!())
.unwrap();
@ -196,8 +202,8 @@ impl CliMainWorker {
}
}
let mut executor = FileWatcherModuleExecutor::new(self.worker, self.ps);
executor.execute(&self.main_module).await
let mut executor = FileWatcherModuleExecutor::new(self);
executor.execute().await
}
pub async fn run_test_specifier(
@ -252,7 +258,7 @@ impl CliMainWorker {
}
} else {
// We execute the module module as a side module so that import.meta.main is not set.
self.worker.execute_side_module(&self.main_module).await?;
self.execute_side_module_possibly_with_npm().await?;
}
}
@ -307,7 +313,8 @@ impl CliMainWorker {
.unwrap();
if mode != TestMode::Documentation {
self.worker.execute_side_module(&self.main_module).await?;
// We execute the module module as a side module so that import.meta.main is not set.
self.execute_side_module_possibly_with_npm().await?;
}
self.worker.dispatch_load_event(&located_script_name!())?;
@ -362,7 +369,7 @@ impl CliMainWorker {
}
} else {
// We execute the module module as a side module so that import.meta.main is not set.
self.worker.execute_side_module(&self.main_module).await?;
self.execute_side_module_possibly_with_npm().await?;
}
self.worker.dispatch_load_event(&located_script_name!())?;
@ -387,6 +394,30 @@ impl CliMainWorker {
Ok(())
}
async fn execute_main_module_possibly_with_npm(
&mut self,
) -> Result<(), AnyError> {
let id = self.worker.preload_main_module(&self.main_module).await?;
self.evaluate_module_possibly_with_npm(id).await
}
async fn execute_side_module_possibly_with_npm(
&mut self,
) -> Result<(), AnyError> {
let id = self.worker.preload_side_module(&self.main_module).await?;
self.evaluate_module_possibly_with_npm(id).await
}
async fn evaluate_module_possibly_with_npm(
&mut self,
id: ModuleId,
) -> Result<(), AnyError> {
if self.ps.npm_resolver.has_packages() {
node::initialize_runtime(&mut self.worker.js_runtime).await?;
}
self.worker.evaluate_module(id).await
}
async fn maybe_setup_coverage_collector(
&mut self,
) -> Result<Option<CoverageCollector>, AnyError> {
@ -423,6 +454,8 @@ pub fn create_main_worker(
create_web_worker_callback(ps.clone(), stdio.clone());
let web_worker_preload_module_cb =
create_web_worker_preload_module_callback(ps.clone());
let web_worker_pre_execute_module_cb =
create_web_worker_pre_execute_module_callback(ps.clone());
let maybe_storage_key = ps.options.resolve_storage_key(&main_module);
let origin_storage_dir = maybe_storage_key.map(|key| {
@ -466,14 +499,11 @@ pub fn create_main_worker(
format_js_error_fn: Some(Arc::new(format_js_error)),
create_web_worker_cb,
web_worker_preload_module_cb,
web_worker_pre_execute_module_cb: Arc::new(|worker| {
LocalFutureObj::new(Box::new(deno_core::futures::future::ready(Ok(
worker,
))))
}),
web_worker_pre_execute_module_cb,
maybe_inspector_server,
should_break_on_first_statement,
module_loader,
npm_resolver: Some(Rc::new(ps.npm_resolver.clone())),
get_error_class_fn: Some(&errors::get_error_class_name),
origin_storage_dir,
blob_store: ps.blob_store.clone(),
@ -513,6 +543,23 @@ fn create_web_worker_preload_module_callback(
})
}
fn create_web_worker_pre_execute_module_callback(
ps: ProcState,
) -> Arc<WorkerEventCb> {
Arc::new(move |mut worker| {
let ps = ps.clone();
let fut = async move {
// this will be up to date after pre-load
if ps.npm_resolver.has_packages() {
node::initialize_runtime(&mut worker.js_runtime).await?;
}
Ok(worker)
};
LocalFutureObj::new(Box::new(fut))
})
}
fn create_web_worker_callback(
ps: ProcState,
stdio: deno_runtime::ops::io::Stdio,
@ -528,6 +575,8 @@ fn create_web_worker_callback(
create_web_worker_callback(ps.clone(), stdio.clone());
let preload_module_cb =
create_web_worker_preload_module_callback(ps.clone());
let pre_execute_module_cb =
create_web_worker_pre_execute_module_callback(ps.clone());
let extensions = ops::cli_exts(ps.clone());
@ -559,14 +608,11 @@ fn create_web_worker_callback(
seed: ps.options.seed(),
create_web_worker_cb,
preload_module_cb,
pre_execute_module_cb: Arc::new(|worker| {
LocalFutureObj::new(Box::new(deno_core::futures::future::ready(Ok(
worker,
))))
}),
pre_execute_module_cb,
format_js_error_fn: Some(Arc::new(format_js_error)),
source_map_getter: Some(Box::new(module_loader.clone())),
module_loader,
npm_resolver: Some(Rc::new(ps.npm_resolver.clone())),
worker_type: args.worker_type,
maybe_inspector_server,
get_error_class_fn: Some(&errors::get_error_class_name),

111
ext/node/01_node.js Normal file
View file

@ -0,0 +1,111 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file
"use strict";
((window) => {
const {
ArrayPrototypePush,
ObjectEntries,
ObjectCreate,
} = window.__bootstrap.primordials;
function assert(cond) {
if (!cond) {
throw Error("assert");
}
}
let initialized = false;
const nodeGlobals = {};
const nodeGlobalThis = new Proxy(globalThis, {
get(_target, prop, _receiver) {
if (prop in nodeGlobals) {
return nodeGlobals[prop];
} else {
return globalThis[prop];
}
},
set(_target, prop, value) {
if (prop in nodeGlobals) {
nodeGlobals[prop] = value;
} else {
globalThis[prop] = value;
}
return true;
},
deleteProperty(_target, prop) {
let success = false;
if (prop in nodeGlobals) {
delete nodeGlobals[prop];
success = true;
}
if (prop in globalThis) {
delete globalThis[prop];
success = true;
}
return success;
},
ownKeys(_target) {
const globalThisKeys = Reflect.ownKeys(globalThis);
const nodeGlobalsKeys = Reflect.ownKeys(nodeGlobals);
const nodeGlobalsKeySet = new Set(nodeGlobalsKeys);
return [
...ArrayPrototypeFilter(
globalThisKeys,
(k) => !nodeGlobalsKeySet.has(k),
),
...nodeGlobalsKeys,
];
},
defineProperty(_target, prop, desc) {
if (prop in nodeGlobals) {
return Reflect.defineProperty(nodeGlobals, prop, desc);
} else {
return Reflect.defineProperty(globalThis, prop, desc);
}
},
getOwnPropertyDescriptor(_target, prop) {
if (prop in nodeGlobals) {
return Reflect.getOwnPropertyDescriptor(nodeGlobals, prop);
} else {
return Reflect.getOwnPropertyDescriptor(globalThis, prop);
}
},
has(_target, prop) {
return prop in nodeGlobals || prop in globalThis;
},
});
const nativeModuleExports = ObjectCreate(null);
const builtinModules = [];
function initialize(nodeModules) {
assert(!initialized);
initialized = true;
for (const [name, exports] of ObjectEntries(nodeModules)) {
nativeModuleExports[name] = exports;
ArrayPrototypePush(builtinModules, name);
}
nodeGlobals.Buffer = nativeModuleExports["buffer"].Buffer;
nodeGlobals.clearImmediate = nativeModuleExports["timers"].clearImmediate;
nodeGlobals.clearInterval = nativeModuleExports["timers"].clearInterval;
nodeGlobals.clearTimeout = nativeModuleExports["timers"].clearTimeout;
nodeGlobals.global = nodeGlobals;
nodeGlobals.process = nativeModuleExports["process"];
nodeGlobals.setImmediate = nativeModuleExports["timers"].setImmediate;
nodeGlobals.setInterval = nativeModuleExports["timers"].setInterval;
nodeGlobals.setTimeout = nativeModuleExports["timers"].setTimeout;
}
window.__bootstrap.internals = {
...window.__bootstrap.internals ?? {},
node: {
globalThis: nodeGlobalThis,
initialize,
nativeModuleExports,
builtinModules,
},
};
})(globalThis);

View file

@ -13,9 +13,9 @@
ArrayPrototypePush,
ArrayPrototypeSlice,
ArrayPrototypeSplice,
FunctionPrototypeBind,
ObjectGetOwnPropertyDescriptor,
ObjectGetPrototypeOf,
ObjectEntries,
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
ObjectKeys,
@ -26,6 +26,7 @@
JSONParse,
StringPrototypeEndsWith,
StringPrototypeIndexOf,
StringPrototypeMatch,
StringPrototypeSlice,
StringPrototypeStartsWith,
StringPrototypeCharCodeAt,
@ -33,6 +34,7 @@
} = window.__bootstrap.primordials;
const core = window.Deno.core;
const ops = core.ops;
const { node } = window.__bootstrap.internals;
// Map used to store CJS parsing data.
const cjsParseCache = new SafeWeakMap();
@ -51,12 +53,7 @@
}
}
// TODO(bartlomieju): verify in other parts of this file that
// we have initialized the system before making APIs work
let cjsInitialized = false;
let processGlobal = null;
const nativeModulePolyfill = new SafeMap();
const nativeModuleExports = ObjectCreate(null);
const relativeResolveCache = ObjectCreate(null);
let requireDepth = 0;
@ -99,9 +96,7 @@
}
function tryPackage(requestPath, exts, isMain, originalPath) {
// const pkg = readPackage(requestPath)?.main;
let pkg = false;
const pkg = core.ops.op_require_read_package_scope(requestPath).main;
if (!pkg) {
return tryExtensions(
pathResolve(requestPath, "index"),
@ -110,7 +105,7 @@
);
}
const filename = path.resolve(requestPath, pkg);
const filename = pathResolve(requestPath, pkg);
let actual = tryFile(filename, isMain) ||
tryExtensions(filename, exts, isMain) ||
tryExtensions(
@ -142,7 +137,7 @@
requestPath,
"package.json",
);
process.emitWarning(
node.globalThis.process.emitWarning(
`Invalid 'main' field in '${jsonPath}' of '${pkg}'. ` +
"Please either fix that or report it to the module author",
"DeprecationWarning",
@ -214,7 +209,7 @@
}
function emitCircularRequireWarning(prop) {
processGlobal.emitWarning(
node.globalThis.process.emitWarning(
`Accessing non-existent property '${String(prop)}' of module exports ` +
"inside circular dependency",
);
@ -255,8 +250,7 @@
this.children = [];
}
const builtinModules = [];
Module.builtinModules = builtinModules;
Module.builtinModules = node.builtinModules;
Module._extensions = Object.create(null);
Module._cache = Object.create(null);
@ -266,7 +260,54 @@
const CHAR_FORWARD_SLASH = 47;
const TRAILING_SLASH_REGEX = /(?:^|\/)\.?\.$/;
Module._findPath = function (request, paths, isMain) {
const encodedSepRegEx = /%2F|%2C/i;
function finalizeEsmResolution(
resolved,
parentPath,
pkgPath,
) {
if (RegExpPrototypeTest(encodedSepRegEx, resolved)) {
throw new ERR_INVALID_MODULE_SPECIFIER(
resolved,
'must not include encoded "/" or "\\" characters',
parentPath,
);
}
// const filename = fileURLToPath(resolved);
const filename = resolved;
const actual = tryFile(filename, false);
if (actual) {
return actual;
}
throw new ERR_MODULE_NOT_FOUND(
filename,
path.resolve(pkgPath, "package.json"),
);
}
// This only applies to requests of a specific form:
// 1. name/.*
// 2. @scope/name/.*
const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/;
function resolveExports(modulesPath, request, parentPath) {
// The implementation's behavior is meant to mirror resolution in ESM.
const [, name, expansion = ""] =
StringPrototypeMatch(request, EXPORTS_PATTERN) || [];
if (!name) {
return;
}
return core.ops.op_require_resolve_exports(
modulesPath,
request,
name,
expansion,
parentPath,
) ?? false;
}
Module._findPath = function (request, paths, isMain, parentPath) {
const absoluteRequest = ops.op_require_path_is_absolute(request);
if (absoluteRequest) {
paths = [""];
@ -295,23 +336,29 @@
if (curPath && stat(curPath) < 1) continue;
if (!absoluteRequest) {
const exportsResolved = resolveExports(curPath, request);
const exportsResolved = resolveExports(curPath, request, parentPath);
if (exportsResolved) {
return exportsResolved;
}
}
const basePath = pathResolve(curPath, request);
const isDenoDirPackage = Deno.core.opSync(
"op_require_is_deno_dir_package",
curPath,
);
const isRelative = ops.op_require_is_request_relative(
request,
);
// TODO(bartlomieju): could be a single op
const basePath = (isDenoDirPackage && !isRelative)
? pathResolve(curPath, packageSpecifierSubPath(request))
: pathResolve(curPath, request);
let filename;
const rc = stat(basePath);
if (!trailingSlash) {
if (rc === 0) { // File.
if (!isMain) {
filename = toRealPath(basePath);
} else {
filename = toRealPath(basePath);
}
filename = toRealPath(basePath);
}
if (!filename) {
@ -345,11 +392,23 @@
};
Module._resolveLookupPaths = function (request, parent) {
return ops.op_require_resolve_lookup_paths(
const paths = [];
if (parent?.filename && parent.filename.length > 0) {
const denoDirPath = core.opSync(
"op_require_resolve_deno_dir",
request,
parent.filename,
);
if (denoDirPath) {
paths.push(denoDirPath);
}
}
paths.push(...ops.op_require_resolve_lookup_paths(
request,
parent?.paths,
parent?.filename ?? "",
);
));
return paths;
};
Module._load = function (request, parent, isMain) {
@ -392,14 +451,9 @@
if (cachedModule !== undefined) {
updateChildren(parent, cachedModule, true);
if (!cachedModule.loaded) {
const parseCachedModule = cjsParseCache.get(cachedModule);
if (!parseCachedModule || parseCachedModule.loaded) {
return getExportsForCircularRequire(cachedModule);
}
parseCachedModule.loaded = true;
} else {
return cachedModule.exports;
return getExportsForCircularRequire(cachedModule);
}
return cachedModule.exports;
}
const mod = loadNativeModule(filename, request);
@ -408,12 +462,11 @@
) {
return mod.exports;
}
// Don't call updateChildren(), Module constructor already does.
const module = cachedModule || new Module(filename, parent);
if (isMain) {
processGlobal.mainModule = module;
node.globalThis.process.mainModule = module;
module.id = ".";
}
@ -504,38 +557,23 @@
if (parent?.filename) {
if (request[0] === "#") {
console.log("TODO: Module._resolveFilename with #specifier");
// const pkg = readPackageScope(parent.filename) || {};
// if (pkg.data?.imports != null) {
// try {
// return finalizeEsmResolution(
// packageImportsResolve(
// request,
// pathToFileURL(parent.filename),
// cjsConditions,
// ),
// parent.filename,
// pkg.path,
// );
// } catch (e) {
// if (e.code === "ERR_MODULE_NOT_FOUND") {
// throw createEsmNotFoundErr(request);
// }
// throw e;
// }
// }
const maybeResolved = core.ops.op_require_package_imports_resolve(
parent.filename,
request,
);
if (maybeResolved) {
return maybeResolved;
}
}
}
// Try module self resolution first
// TODO(bartlomieju): make into a single op
const parentPath = ops.op_require_try_self_parent_path(
!!parent,
parent?.filename,
parent?.id,
);
// const selfResolved = ops.op_require_try_self(parentPath, request);
const selfResolved = false;
const selfResolved = ops.op_require_try_self(parentPath, request);
if (selfResolved) {
const cacheKey = request + "\x00" +
(paths.length === 1 ? paths[0] : ArrayPrototypeJoin(paths, "\x00"));
@ -544,7 +582,12 @@
}
// Look up the filename first, since that's the cache key.
const filename = Module._findPath(request, paths, isMain, false);
const filename = Module._findPath(
request,
paths,
isMain,
parentPath,
);
if (filename) return filename;
const requireStack = [];
for (let cursor = parent; cursor; cursor = moduleParentCache.get(cursor)) {
@ -609,8 +652,8 @@
// TODO:
// We provide non standard timer APIs in the CommonJS wrapper
// to avoid exposing them in global namespace.
"(function (exports, require, module, __filename, __dirname, setTimeout, clearTimeout, setInterval, clearInterval) { (function (exports, require, module, __filename, __dirname) {",
"\n}).call(this, exports, require, module, __filename, __dirname); })",
"(function (exports, require, module, __filename, __dirname, globalThis) { (function (exports, require, module, __filename, __dirname, globalThis, Buffer, clearImmediate, clearInterval, clearTimeout, global, process, setImmediate, setInterval, setTimeout) {",
"\n}).call(this, exports, require, module, __filename, __dirname, globalThis, globalThis.Buffer, globalThis.clearImmediate, globalThis.clearInterval, globalThis.clearTimeout, globalThis.global, globalThis.process, globalThis.setImmediate, globalThis.setInterval, globalThis.setTimeout); })",
];
Module.wrap = function (script) {
script = script.replace(/^#!.*?\n/, "");
@ -641,7 +684,7 @@
const wrapper = Module.wrap(content);
const [f, err] = core.evalContext(wrapper, filename);
if (err) {
if (processGlobal.mainModule === cjsModuleInstance) {
if (node.globalThis.process.mainModule === cjsModuleInstance) {
enrichCJSError(err.thrown);
}
throw err.thrown;
@ -667,6 +710,7 @@
this,
filename,
dirname,
node.globalThis,
);
if (requireDepth === 0) {
statCache = null;
@ -677,7 +721,14 @@
Module._extensions[".js"] = function (module, filename) {
const content = ops.op_require_read_file(filename);
console.log(`TODO: Module._extensions[".js"] is ESM`);
if (StringPrototypeEndsWith(filename, ".js")) {
const pkg = core.ops.op_require_read_package_scope(filename);
if (pkg && pkg.exists && pkg.typ == "module") {
throw new Error(
`Import ESM module: ${filename} from ${module.parent.filename}`,
);
}
}
module._compile(content, filename);
};
@ -738,8 +789,9 @@
return require;
}
function createRequire(filename) {
function createRequire(filenameOrUrl) {
// FIXME: handle URLs and validation
const filename = core.opSync("op_require_as_file_path", filenameOrUrl);
return createRequireFromPath(filename);
}
@ -775,13 +827,13 @@
wrap: Module.wrap,
};
nativeModuleExports.module = m;
node.nativeModuleExports.module = m;
function loadNativeModule(_id, request) {
if (nativeModulePolyfill.has(request)) {
return nativeModulePolyfill.get(request);
}
const modExports = nativeModuleExports[request];
const modExports = node.nativeModuleExports[request];
if (modExports) {
const nodeMod = new Module(request);
nodeMod.exports = modExports;
@ -793,23 +845,33 @@
}
function nativeModuleCanBeRequiredByUsers(request) {
return !!nativeModuleExports[request];
}
function initializeCommonJs(nodeModules, process) {
assert(!cjsInitialized);
cjsInitialized = true;
for (const [name, exports] of ObjectEntries(nodeModules)) {
nativeModuleExports[name] = exports;
ArrayPrototypePush(Module.builtinModules, name);
}
processGlobal = process;
return !!node.nativeModuleExports[request];
}
function readPackageScope() {
throw new Error("not implemented");
}
function bindExport(value, mod) {
// ensure exported functions are bound to their module object
if (typeof value === "function") {
return FunctionPrototypeBind(value, mod);
} else {
return value;
}
}
/** @param specifier {string} */
function packageSpecifierSubPath(specifier) {
let parts = specifier.split("/");
if (parts[0].startsWith("@")) {
parts = parts.slice(2);
} else {
parts = parts.slice(1);
}
return parts.join("/");
}
window.__bootstrap.internals = {
...window.__bootstrap.internals ?? {},
require: {
@ -818,7 +880,7 @@
toRealPath,
cjsParseCache,
readPackageScope,
initializeCommonJs,
bindExport,
},
};
})(globalThis);

View file

@ -15,3 +15,5 @@ path = "lib.rs"
[dependencies]
deno_core = { version = "0.147.0", path = "../../core" }
regex = "1"
serde = "1.0.136"

122
ext/node/errors.rs Normal file
View file

@ -0,0 +1,122 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use deno_core::error::generic_error;
use deno_core::error::type_error;
use deno_core::error::AnyError;
pub fn err_invalid_module_specifier(
request: &str,
reason: &str,
maybe_base: Option<String>,
) -> AnyError {
let mut msg = format!(
"[ERR_INVALID_MODULE_SPECIFIER] Invalid module \"{}\" {}",
request, reason
);
if let Some(base) = maybe_base {
msg = format!("{} imported from {}", msg, base);
}
type_error(msg)
}
#[allow(unused)]
pub fn err_invalid_package_config(
path: &str,
maybe_base: Option<String>,
maybe_message: Option<String>,
) -> AnyError {
let mut msg = format!(
"[ERR_INVALID_PACKAGE_CONFIG] Invalid package config {}",
path
);
if let Some(base) = maybe_base {
msg = format!("{} while importing {}", msg, base);
}
if let Some(message) = maybe_message {
msg = format!("{}. {}", msg, message);
}
generic_error(msg)
}
#[allow(unused)]
pub fn err_module_not_found(path: &str, base: &str, typ: &str) -> AnyError {
generic_error(format!(
"[ERR_MODULE_NOT_FOUND] Cannot find {} \"{}\" imported from \"{}\"",
typ, path, base
))
}
pub fn err_invalid_package_target(
pkg_path: String,
key: String,
target: String,
is_import: bool,
maybe_base: Option<String>,
) -> AnyError {
let rel_error = !is_import && !target.is_empty() && !target.starts_with("./");
let mut msg = "[ERR_INVALID_PACKAGE_TARGET]".to_string();
if key == "." {
assert!(!is_import);
msg = format!("{} Invalid \"exports\" main target {} defined in the package config {}package.json", msg, target, pkg_path)
} else {
let ie = if is_import { "imports" } else { "exports" };
msg = format!("{} Invalid \"{}\" target {} defined for '{}' in the package config {}package.json", msg, ie, target, key, pkg_path)
};
if let Some(base) = maybe_base {
msg = format!("{} imported from {}", msg, base);
};
if rel_error {
msg = format!("{}; target must start with \"./\"", msg);
}
generic_error(msg)
}
pub fn err_package_path_not_exported(
pkg_path: String,
subpath: String,
maybe_base: Option<String>,
) -> AnyError {
let mut msg = "[ERR_PACKAGE_PATH_NOT_EXPORTED]".to_string();
if subpath == "." {
msg = format!(
"{} No \"exports\" main defined in {}package.json",
msg, pkg_path
);
} else {
msg = format!("{} Package subpath \'{}\' is not defined by \"exports\" in {}package.json", msg, subpath, pkg_path);
};
if let Some(base) = maybe_base {
msg = format!("{} imported from {}", msg, base);
}
generic_error(msg)
}
pub fn err_package_import_not_defined(
specifier: &str,
package_path: Option<String>,
base: &str,
) -> AnyError {
let mut msg = format!(
"[ERR_PACKAGE_IMPORT_NOT_DEFINED] Package import specifier \"{}\" is not defined in",
specifier
);
if let Some(package_path) = package_path {
msg = format!("{} in package {}package.json", msg, package_path);
}
msg = format!("{} imported from {}", msg, base);
type_error(msg)
}

View file

@ -4,22 +4,60 @@ use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::normalize_path;
use deno_core::op;
use deno_core::url::Url;
use deno_core::Extension;
use deno_core::OpState;
use std::path::Path;
use std::path::PathBuf;
use std::rc::Rc;
pub struct Unstable(pub bool);
pub use package_json::PackageJson;
pub use resolution::get_package_scope_config;
pub use resolution::legacy_main_resolve;
pub use resolution::package_exports_resolve;
pub use resolution::package_imports_resolve;
pub use resolution::package_resolve;
pub use resolution::DEFAULT_CONDITIONS;
pub fn init(unstable: bool) -> Extension {
pub trait DenoDirNpmResolver {
fn resolve_package_folder_from_package(
&self,
specifier: &str,
referrer: &Path,
) -> Result<PathBuf, AnyError>;
fn resolve_package_folder_from_path(
&self,
path: &Path,
) -> Result<PathBuf, AnyError>;
fn in_npm_package(&self, path: &Path) -> bool;
fn ensure_read_permission(&self, path: &Path) -> Result<(), AnyError>;
}
mod errors;
mod package_json;
mod resolution;
struct Unstable(pub bool);
pub fn init(
unstable: bool,
maybe_npm_resolver: Option<Rc<dyn DenoDirNpmResolver>>,
) -> Extension {
Extension::builder()
.js(include_js_files!(
prefix "deno:ext/node",
"01_require.js",
"01_node.js",
"02_require.js",
))
.ops(vec![
op_require_init_paths::decl(),
op_require_node_module_paths::decl(),
op_require_proxy_path::decl(),
op_require_is_deno_dir_package::decl(),
op_require_resolve_deno_dir::decl(),
op_require_is_request_relative::decl(),
op_require_resolve_lookup_paths::decl(),
op_require_try_self_parent_path::decl(),
@ -31,9 +69,16 @@ pub fn init(unstable: bool) -> Extension {
op_require_path_resolve::decl(),
op_require_path_basename::decl(),
op_require_read_file::decl(),
op_require_as_file_path::decl(),
op_require_resolve_exports::decl(),
op_require_read_package_scope::decl(),
op_require_package_imports_resolve::decl(),
])
.state(move |state| {
state.put(Unstable(unstable));
if let Some(npm_resolver) = maybe_npm_resolver.clone() {
state.put(npm_resolver);
}
Ok(())
})
.build()
@ -48,60 +93,74 @@ fn check_unstable(state: &OpState) {
}
}
fn ensure_read_permission(
state: &mut OpState,
file_path: &Path,
) -> Result<(), AnyError> {
let resolver = {
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>();
resolver.clone()
};
resolver.ensure_read_permission(file_path)
}
#[op]
pub fn op_require_init_paths(state: &mut OpState) -> Vec<String> {
check_unstable(state);
let (home_dir, node_path) = if cfg!(windows) {
(
std::env::var("USERPROFILE").unwrap_or_else(|_| "".into()),
std::env::var("NODE_PATH").unwrap_or_else(|_| "".into()),
)
} else {
(
std::env::var("HOME").unwrap_or_else(|_| "".into()),
std::env::var("NODE_PATH").unwrap_or_else(|_| "".into()),
)
};
// todo(dsherret): this code is node compat mode specific and
// we probably don't want it for small mammal, so ignore it for now
let mut prefix_dir = std::env::current_exe().unwrap();
if cfg!(windows) {
prefix_dir = prefix_dir.join("..").join("..")
} else {
prefix_dir = prefix_dir.join("..")
}
// let (home_dir, node_path) = if cfg!(windows) {
// (
// std::env::var("USERPROFILE").unwrap_or_else(|_| "".into()),
// std::env::var("NODE_PATH").unwrap_or_else(|_| "".into()),
// )
// } else {
// (
// std::env::var("HOME").unwrap_or_else(|_| "".into()),
// std::env::var("NODE_PATH").unwrap_or_else(|_| "".into()),
// )
// };
let mut paths = vec![prefix_dir.join("lib").join("node")];
// let mut prefix_dir = std::env::current_exe().unwrap();
// if cfg!(windows) {
// prefix_dir = prefix_dir.join("..").join("..")
// } else {
// prefix_dir = prefix_dir.join("..")
// }
if !home_dir.is_empty() {
paths.insert(0, PathBuf::from(&home_dir).join(".node_libraries"));
paths.insert(0, PathBuf::from(&home_dir).join(".nod_modules"));
}
// let mut paths = vec![prefix_dir.join("lib").join("node")];
let mut paths = paths
.into_iter()
.map(|p| p.to_string_lossy().to_string())
.collect();
// if !home_dir.is_empty() {
// paths.insert(0, PathBuf::from(&home_dir).join(".node_libraries"));
// paths.insert(0, PathBuf::from(&home_dir).join(".nod_modules"));
// }
if !node_path.is_empty() {
let delimiter = if cfg!(windows) { ";" } else { ":" };
let mut node_paths: Vec<String> = node_path
.split(delimiter)
.filter(|e| !e.is_empty())
.map(|s| s.to_string())
.collect();
node_paths.append(&mut paths);
paths = node_paths;
}
// let mut paths = paths
// .into_iter()
// .map(|p| p.to_string_lossy().to_string())
// .collect();
paths
// if !node_path.is_empty() {
// let delimiter = if cfg!(windows) { ";" } else { ":" };
// let mut node_paths: Vec<String> = node_path
// .split(delimiter)
// .filter(|e| !e.is_empty())
// .map(|s| s.to_string())
// .collect();
// node_paths.append(&mut paths);
// paths = node_paths;
// }
vec![]
}
#[op]
pub fn op_require_node_module_paths(
state: &mut OpState,
from: String,
) -> Vec<String> {
) -> Result<Vec<String>, AnyError> {
check_unstable(state);
// Guarantee that "from" is absolute.
let from = deno_core::resolve_path(&from)
@ -109,6 +168,8 @@ pub fn op_require_node_module_paths(
.to_file_path()
.unwrap();
ensure_read_permission(state, &from)?;
if cfg!(windows) {
// return root node_modules when path is 'D:\\'.
let from_str = from.to_str().unwrap();
@ -117,14 +178,14 @@ pub fn op_require_node_module_paths(
if bytes[from_str.len() - 1] == b'\\' && bytes[from_str.len() - 2] == b':'
{
let p = from_str.to_owned() + "node_modules";
return vec![p];
return Ok(vec![p]);
}
}
} else {
// Return early not only to avoid unnecessary work, but to *avoid* returning
// an array of two items for a root: [ '//node_modules', '/node_modules' ]
if from.to_string_lossy() == "/" {
return vec!["/node_modules".to_string()];
return Ok(vec!["/node_modules".to_string()]);
}
}
@ -144,7 +205,7 @@ pub fn op_require_node_module_paths(
paths.push("/node_modules".to_string());
}
paths
Ok(paths)
}
#[op]
@ -171,11 +232,8 @@ fn op_require_is_request_relative(
request: String,
) -> bool {
check_unstable(state);
if request.starts_with("./") {
return true;
}
if request.starts_with("../") {
if request.starts_with("./") || request.starts_with("../") || request == ".."
{
return true;
}
@ -192,6 +250,30 @@ fn op_require_is_request_relative(
false
}
#[op]
fn op_require_resolve_deno_dir(
state: &mut OpState,
request: String,
parent_filename: String,
) -> Option<String> {
check_unstable(state);
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>();
resolver
.resolve_package_folder_from_package(
&request,
&PathBuf::from(parent_filename),
)
.ok()
.map(|p| p.to_string_lossy().to_string())
}
#[op]
fn op_require_is_deno_dir_package(state: &mut OpState, path: String) -> bool {
check_unstable(state);
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>();
resolver.in_npm_package(&PathBuf::from(path))
}
#[op]
fn op_require_resolve_lookup_paths(
state: &mut OpState,
@ -242,17 +324,19 @@ fn op_require_path_is_absolute(state: &mut OpState, p: String) -> bool {
}
#[op]
fn op_require_stat(state: &mut OpState, filename: String) -> i32 {
fn op_require_stat(state: &mut OpState, path: String) -> Result<i32, AnyError> {
check_unstable(state);
if let Ok(metadata) = std::fs::metadata(&filename) {
let path = PathBuf::from(path);
ensure_read_permission(state, &path)?;
if let Ok(metadata) = std::fs::metadata(&path) {
if metadata.is_file() {
return 0;
return Ok(0);
} else {
return 1;
return Ok(1);
}
}
-1
Ok(-1)
}
#[op]
@ -261,7 +345,9 @@ fn op_require_real_path(
request: String,
) -> Result<String, AnyError> {
check_unstable(state);
let mut canonicalized_path = PathBuf::from(request).canonicalize()?;
let path = PathBuf::from(request);
ensure_read_permission(state, &path)?;
let mut canonicalized_path = path.canonicalize()?;
if cfg!(windows) {
canonicalized_path = PathBuf::from(
canonicalized_path
@ -273,9 +359,7 @@ fn op_require_real_path(
Ok(canonicalized_path.to_string_lossy().to_string())
}
#[op]
fn op_require_path_resolve(state: &mut OpState, parts: Vec<String>) -> String {
check_unstable(state);
fn path_resolve(parts: Vec<String>) -> String {
assert!(!parts.is_empty());
let mut p = PathBuf::from(&parts[0]);
if parts.len() > 1 {
@ -286,6 +370,12 @@ fn op_require_path_resolve(state: &mut OpState, parts: Vec<String>) -> String {
normalize_path(p).to_string_lossy().to_string()
}
#[op]
fn op_require_path_resolve(state: &mut OpState, parts: Vec<String>) -> String {
check_unstable(state);
path_resolve(parts)
}
#[op]
fn op_require_path_dirname(state: &mut OpState, request: String) -> String {
check_unstable(state);
@ -306,57 +396,183 @@ fn op_require_try_self_parent_path(
has_parent: bool,
maybe_parent_filename: Option<String>,
maybe_parent_id: Option<String>,
) -> Option<String> {
) -> Result<Option<String>, AnyError> {
check_unstable(state);
if !has_parent {
return None;
return Ok(None);
}
if let Some(parent_filename) = maybe_parent_filename {
return Some(parent_filename);
return Ok(Some(parent_filename));
}
if let Some(parent_id) = maybe_parent_id {
if parent_id == "<repl>" || parent_id == "internal/preload" {
if let Ok(cwd) = std::env::current_dir() {
return Some(cwd.to_string_lossy().to_string());
ensure_read_permission(state, &cwd)?;
return Ok(Some(cwd.to_string_lossy().to_string()));
}
}
}
None
Ok(None)
}
#[op]
fn op_require_try_self(
state: &mut OpState,
has_parent: bool,
maybe_parent_filename: Option<String>,
maybe_parent_id: Option<String>,
) -> Option<String> {
parent_path: Option<String>,
request: String,
) -> Result<Option<String>, AnyError> {
check_unstable(state);
if !has_parent {
return None;
if parent_path.is_none() {
return Ok(None);
}
if let Some(parent_filename) = maybe_parent_filename {
return Some(parent_filename);
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>().clone();
let pkg = resolution::get_package_scope_config(
&Url::from_file_path(parent_path.unwrap()).unwrap(),
&*resolver,
)
.ok();
if pkg.is_none() {
return Ok(None);
}
if let Some(parent_id) = maybe_parent_id {
if parent_id == "<repl>" || parent_id == "internal/preload" {
if let Ok(cwd) = std::env::current_dir() {
return Some(cwd.to_string_lossy().to_string());
}
}
let pkg = pkg.unwrap();
if pkg.exports.is_none() {
return Ok(None);
}
if pkg.name.is_none() {
return Ok(None);
}
let pkg_name = pkg.name.as_ref().unwrap().to_string();
let mut expansion = ".".to_string();
if request == pkg_name {
// pass
} else if request.starts_with(&format!("{}/", pkg_name)) {
expansion += &request[pkg_name.len()..];
} else {
return Ok(None);
}
let base = deno_core::url::Url::from_file_path(PathBuf::from("/")).unwrap();
if let Some(exports) = &pkg.exports {
resolution::package_exports_resolve(
deno_core::url::Url::from_file_path(&pkg.path).unwrap(),
expansion,
exports,
&base,
resolution::REQUIRE_CONDITIONS,
&*resolver,
)
.map(|r| Some(r.as_str().to_string()))
} else {
Ok(None)
}
None
}
#[op]
fn op_require_read_file(
state: &mut OpState,
_filename: String,
file_path: String,
) -> Result<String, AnyError> {
check_unstable(state);
todo!("not implemented");
let file_path = PathBuf::from(file_path);
ensure_read_permission(state, &file_path)?;
Ok(std::fs::read_to_string(file_path)?)
}
#[op]
pub fn op_require_as_file_path(
state: &mut OpState,
file_or_url: String,
) -> String {
check_unstable(state);
match Url::parse(&file_or_url) {
Ok(url) => url.to_file_path().unwrap().to_string_lossy().to_string(),
Err(_) => file_or_url,
}
}
#[op]
fn op_require_resolve_exports(
state: &mut OpState,
modules_path: String,
_request: String,
name: String,
expansion: String,
parent_path: String,
) -> Result<Option<String>, AnyError> {
check_unstable(state);
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>().clone();
let pkg_path = if resolver.in_npm_package(&PathBuf::from(&modules_path)) {
modules_path
} else {
path_resolve(vec![modules_path, name])
};
let pkg = PackageJson::load(
&*resolver,
PathBuf::from(&pkg_path).join("package.json"),
)?;
if let Some(exports) = &pkg.exports {
let base = Url::from_file_path(parent_path).unwrap();
resolution::package_exports_resolve(
deno_core::url::Url::from_directory_path(pkg_path).unwrap(),
format!(".{}", expansion),
exports,
&base,
resolution::REQUIRE_CONDITIONS,
&*resolver,
)
.map(|r| Some(r.to_file_path().unwrap().to_string_lossy().to_string()))
} else {
Ok(None)
}
}
#[op]
fn op_require_read_package_scope(
state: &mut OpState,
filename: String,
) -> Option<PackageJson> {
check_unstable(state);
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>().clone();
resolution::get_package_scope_config(
&Url::from_file_path(filename).unwrap(),
&*resolver,
)
.ok()
}
#[op]
fn op_require_package_imports_resolve(
state: &mut OpState,
parent_filename: String,
request: String,
) -> Result<Option<String>, AnyError> {
check_unstable(state);
let parent_path = PathBuf::from(&parent_filename);
ensure_read_permission(state, &parent_path)?;
let resolver = state.borrow::<Rc<dyn DenoDirNpmResolver>>().clone();
let pkg = PackageJson::load(&*resolver, parent_path.join("package.json"))?;
if pkg.imports.is_some() {
let referrer =
deno_core::url::Url::from_file_path(&parent_filename).unwrap();
let r = resolution::package_imports_resolve(
&request,
&referrer,
resolution::REQUIRE_CONDITIONS,
&*resolver,
)
.map(|r| Some(r.as_str().to_string()));
state.put(resolver);
r
} else {
Ok(None)
}
}

159
ext/node/package_json.rs Normal file
View file

@ -0,0 +1,159 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use super::DenoDirNpmResolver;
use deno_core::anyhow;
use deno_core::anyhow::bail;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::serde_json::Map;
use deno_core::serde_json::Value;
use serde::Serialize;
use std::io::ErrorKind;
use std::path::PathBuf;
// TODO(bartlomieju): deduplicate with cli/compat/esm_resolver.rs
#[derive(Clone, Debug, Serialize)]
pub struct PackageJson {
pub exists: bool,
pub exports: Option<Map<String, Value>>,
pub imports: Option<Map<String, Value>>,
pub bin: Option<Value>,
pub main: Option<String>,
pub name: Option<String>,
pub path: PathBuf,
pub typ: String,
pub types: Option<String>,
}
impl PackageJson {
pub fn empty(path: PathBuf) -> PackageJson {
PackageJson {
exists: false,
exports: None,
imports: None,
bin: None,
main: None,
name: None,
path,
typ: "none".to_string(),
types: None,
}
}
pub fn load(
resolver: &dyn DenoDirNpmResolver,
path: PathBuf,
) -> Result<PackageJson, AnyError> {
resolver.ensure_read_permission(&path)?;
let source = match std::fs::read_to_string(&path) {
Ok(source) => source,
Err(err) if err.kind() == ErrorKind::NotFound => {
return Ok(PackageJson::empty(path));
}
Err(err) => bail!(
"Error loading package.json at {}. {:#}",
path.display(),
err
),
};
if source.trim().is_empty() {
return Ok(PackageJson::empty(path));
}
let package_json: Value = serde_json::from_str(&source)
.map_err(|err| anyhow::anyhow!("malformed package.json {}", err))?;
let imports_val = package_json.get("imports");
let main_val = package_json.get("main");
let name_val = package_json.get("name");
let type_val = package_json.get("type");
let bin = package_json.get("bin").map(ToOwned::to_owned);
let exports = package_json.get("exports").map(|exports| {
if is_conditional_exports_main_sugar(exports) {
let mut map = Map::new();
map.insert(".".to_string(), exports.to_owned());
map
} else {
exports.as_object().unwrap().to_owned()
}
});
let imports = if let Some(imp) = imports_val {
imp.as_object().map(|imp| imp.to_owned())
} else {
None
};
let main = if let Some(m) = main_val {
m.as_str().map(|m| m.to_string())
} else {
None
};
let name = if let Some(n) = name_val {
n.as_str().map(|n| n.to_string())
} else {
None
};
// Ignore unknown types for forwards compatibility
let typ = if let Some(t) = type_val {
if let Some(t) = t.as_str() {
if t != "module" && t != "commonjs" {
"none".to_string()
} else {
t.to_string()
}
} else {
"none".to_string()
}
} else {
"none".to_string()
};
// for typescript, it looks for "typings" first, then "types"
let types = package_json
.get("typings")
.or_else(|| package_json.get("types"))
.and_then(|t| t.as_str().map(|s| s.to_string()));
let package_json = PackageJson {
exists: true,
path,
main,
name,
typ,
types,
exports,
imports,
bin,
};
Ok(package_json)
}
}
fn is_conditional_exports_main_sugar(exports: &Value) -> bool {
if exports.is_string() || exports.is_array() {
return true;
}
if exports.is_null() || !exports.is_object() {
return false;
}
let exports_obj = exports.as_object().unwrap();
let mut is_conditional_sugar = false;
let mut i = 0;
for key in exports_obj.keys() {
let cur_is_conditional_sugar = key.is_empty() || !key.starts_with('.');
if i == 0 {
is_conditional_sugar = cur_is_conditional_sugar;
i += 1;
} else if is_conditional_sugar != cur_is_conditional_sugar {
panic!("\"exports\" cannot contains some keys starting with \'.\' and some not.
The exports object must either be an object of package subpath keys
or an object of main entry condition name keys only.")
}
}
is_conditional_sugar
}

696
ext/node/resolution.rs Normal file
View file

@ -0,0 +1,696 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
use std::path::PathBuf;
use deno_core::error::generic_error;
use deno_core::error::AnyError;
use deno_core::serde_json::Map;
use deno_core::serde_json::Value;
use deno_core::url::Url;
use deno_core::ModuleSpecifier;
use regex::Regex;
use crate::errors;
use crate::package_json::PackageJson;
use crate::DenoDirNpmResolver;
pub static DEFAULT_CONDITIONS: &[&str] = &["deno", "node", "import"];
pub static REQUIRE_CONDITIONS: &[&str] = &["require", "node"];
fn to_file_path(url: &ModuleSpecifier) -> PathBuf {
url
.to_file_path()
.unwrap_or_else(|_| panic!("Provided URL was not file:// URL: {}", url))
}
fn to_file_path_string(url: &ModuleSpecifier) -> String {
to_file_path(url).display().to_string()
}
fn throw_import_not_defined(
specifier: &str,
package_json_url: Option<ModuleSpecifier>,
base: &ModuleSpecifier,
) -> AnyError {
errors::err_package_import_not_defined(
specifier,
package_json_url.map(|u| to_file_path_string(&u.join(".").unwrap())),
&to_file_path_string(base),
)
}
fn pattern_key_compare(a: &str, b: &str) -> i32 {
let a_pattern_index = a.find('*');
let b_pattern_index = b.find('*');
let base_len_a = if let Some(index) = a_pattern_index {
index + 1
} else {
a.len()
};
let base_len_b = if let Some(index) = b_pattern_index {
index + 1
} else {
b.len()
};
if base_len_a > base_len_b {
return -1;
}
if base_len_b > base_len_a {
return 1;
}
if a_pattern_index.is_none() {
return 1;
}
if b_pattern_index.is_none() {
return -1;
}
if a.len() > b.len() {
return -1;
}
if b.len() > a.len() {
return 1;
}
0
}
pub fn package_imports_resolve(
name: &str,
referrer: &ModuleSpecifier,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<ModuleSpecifier, AnyError> {
if name == "#" || name.starts_with("#/") || name.ends_with('/') {
let reason = "is not a valid internal imports specifier name";
return Err(errors::err_invalid_module_specifier(
name,
reason,
Some(to_file_path_string(referrer)),
));
}
let package_config = get_package_scope_config(referrer, npm_resolver)?;
let mut package_json_url = None;
if package_config.exists {
package_json_url = Some(Url::from_file_path(package_config.path).unwrap());
if let Some(imports) = &package_config.imports {
if imports.contains_key(name) && !name.contains('*') {
let maybe_resolved = resolve_package_target(
package_json_url.clone().unwrap(),
imports.get(name).unwrap().to_owned(),
"".to_string(),
name.to_string(),
referrer,
false,
true,
conditions,
npm_resolver,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
}
} else {
let mut best_match = "";
let mut best_match_subpath = None;
for key in imports.keys() {
let pattern_index = key.find('*');
if let Some(pattern_index) = pattern_index {
let key_sub = &key[0..=pattern_index];
if name.starts_with(key_sub) {
let pattern_trailer = &key[pattern_index + 1..];
if name.len() > key.len()
&& name.ends_with(&pattern_trailer)
&& pattern_key_compare(best_match, key) == 1
&& key.rfind('*') == Some(pattern_index)
{
best_match = key;
best_match_subpath = Some(
name[pattern_index..=(name.len() - pattern_trailer.len())]
.to_string(),
);
}
}
}
}
if !best_match.is_empty() {
let target = imports.get(best_match).unwrap().to_owned();
let maybe_resolved = resolve_package_target(
package_json_url.clone().unwrap(),
target,
best_match_subpath.unwrap(),
best_match.to_string(),
referrer,
true,
true,
conditions,
npm_resolver,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
}
}
}
}
}
Err(throw_import_not_defined(name, package_json_url, referrer))
}
fn throw_invalid_package_target(
subpath: String,
target: String,
package_json_url: &ModuleSpecifier,
internal: bool,
base: &ModuleSpecifier,
) -> AnyError {
errors::err_invalid_package_target(
to_file_path_string(&package_json_url.join(".").unwrap()),
subpath,
target,
internal,
Some(base.as_str().to_string()),
)
}
fn throw_invalid_subpath(
subpath: String,
package_json_url: &ModuleSpecifier,
internal: bool,
base: &ModuleSpecifier,
) -> AnyError {
let ie = if internal { "imports" } else { "exports" };
let reason = format!(
"request is not a valid subpath for the \"{}\" resolution of {}",
ie,
to_file_path_string(package_json_url)
);
errors::err_invalid_module_specifier(
&subpath,
&reason,
Some(to_file_path_string(base)),
)
}
#[allow(clippy::too_many_arguments)]
fn resolve_package_target_string(
target: String,
subpath: String,
match_: String,
package_json_url: ModuleSpecifier,
base: &ModuleSpecifier,
pattern: bool,
internal: bool,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<ModuleSpecifier, AnyError> {
if !subpath.is_empty() && !pattern && !target.ends_with('/') {
return Err(throw_invalid_package_target(
match_,
target,
&package_json_url,
internal,
base,
));
}
let invalid_segment_re =
Regex::new(r"(^|\|/)(..?|node_modules)(\|/|$)").expect("bad regex");
let pattern_re = Regex::new(r"\*").expect("bad regex");
if !target.starts_with("./") {
if internal && !target.starts_with("../") && !target.starts_with('/') {
let is_url = Url::parse(&target).is_ok();
if !is_url {
let export_target = if pattern {
pattern_re
.replace(&target, |_caps: &regex::Captures| subpath.clone())
.to_string()
} else {
format!("{}{}", target, subpath)
};
return package_resolve(
&export_target,
&package_json_url,
conditions,
npm_resolver,
);
}
}
return Err(throw_invalid_package_target(
match_,
target,
&package_json_url,
internal,
base,
));
}
if invalid_segment_re.is_match(&target[2..]) {
return Err(throw_invalid_package_target(
match_,
target,
&package_json_url,
internal,
base,
));
}
let resolved = package_json_url.join(&target)?;
let resolved_path = resolved.path();
let package_url = package_json_url.join(".").unwrap();
let package_path = package_url.path();
if !resolved_path.starts_with(package_path) {
return Err(throw_invalid_package_target(
match_,
target,
&package_json_url,
internal,
base,
));
}
if subpath.is_empty() {
return Ok(resolved);
}
if invalid_segment_re.is_match(&subpath) {
let request = if pattern {
match_.replace('*', &subpath)
} else {
format!("{}{}", match_, subpath)
};
return Err(throw_invalid_subpath(
request,
&package_json_url,
internal,
base,
));
}
if pattern {
let replaced = pattern_re
.replace(resolved.as_str(), |_caps: &regex::Captures| subpath.clone());
let url = Url::parse(&replaced)?;
return Ok(url);
}
Ok(resolved.join(&subpath)?)
}
#[allow(clippy::too_many_arguments)]
fn resolve_package_target(
package_json_url: ModuleSpecifier,
target: Value,
subpath: String,
package_subpath: String,
base: &ModuleSpecifier,
pattern: bool,
internal: bool,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<Option<ModuleSpecifier>, AnyError> {
if let Some(target) = target.as_str() {
return Ok(Some(resolve_package_target_string(
target.to_string(),
subpath,
package_subpath,
package_json_url,
base,
pattern,
internal,
conditions,
npm_resolver,
)?));
} else if let Some(target_arr) = target.as_array() {
if target_arr.is_empty() {
return Ok(None);
}
let mut last_error = None;
for target_item in target_arr {
let resolved_result = resolve_package_target(
package_json_url.clone(),
target_item.to_owned(),
subpath.clone(),
package_subpath.clone(),
base,
pattern,
internal,
conditions,
npm_resolver,
);
if let Err(e) = resolved_result {
let err_string = e.to_string();
last_error = Some(e);
if err_string.starts_with("[ERR_INVALID_PACKAGE_TARGET]") {
continue;
}
return Err(last_error.unwrap());
}
let resolved = resolved_result.unwrap();
if resolved.is_none() {
last_error = None;
continue;
}
return Ok(resolved);
}
if last_error.is_none() {
return Ok(None);
}
return Err(last_error.unwrap());
} else if let Some(target_obj) = target.as_object() {
for key in target_obj.keys() {
// TODO(bartlomieju): verify that keys are not numeric
// return Err(errors::err_invalid_package_config(
// to_file_path_string(package_json_url),
// Some(base.as_str().to_string()),
// Some("\"exports\" cannot contain numeric property keys.".to_string()),
// ));
if key == "default" || conditions.contains(&key.as_str()) {
let condition_target = target_obj.get(key).unwrap().to_owned();
let resolved = resolve_package_target(
package_json_url.clone(),
condition_target,
subpath.clone(),
package_subpath.clone(),
base,
pattern,
internal,
conditions,
npm_resolver,
)?;
if resolved.is_none() {
continue;
}
return Ok(resolved);
}
}
} else if target.is_null() {
return Ok(None);
}
Err(throw_invalid_package_target(
package_subpath,
target.to_string(),
&package_json_url,
internal,
base,
))
}
fn throw_exports_not_found(
subpath: String,
package_json_url: &ModuleSpecifier,
base: &ModuleSpecifier,
) -> AnyError {
errors::err_package_path_not_exported(
to_file_path_string(&package_json_url.join(".").unwrap()),
subpath,
Some(to_file_path_string(base)),
)
}
pub fn package_exports_resolve(
package_json_url: ModuleSpecifier,
package_subpath: String,
package_exports: &Map<String, Value>,
base: &ModuleSpecifier,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<ModuleSpecifier, AnyError> {
if package_exports.contains_key(&package_subpath)
&& package_subpath.find('*').is_none()
&& !package_subpath.ends_with('/')
{
let target = package_exports.get(&package_subpath).unwrap().to_owned();
let resolved = resolve_package_target(
package_json_url.clone(),
target,
"".to_string(),
package_subpath.to_string(),
base,
false,
false,
conditions,
npm_resolver,
)?;
if resolved.is_none() {
return Err(throw_exports_not_found(
package_subpath,
&package_json_url,
base,
));
}
return Ok(resolved.unwrap());
}
let mut best_match = "";
let mut best_match_subpath = None;
for key in package_exports.keys() {
let pattern_index = key.find('*');
if let Some(pattern_index) = pattern_index {
let key_sub = &key[0..=pattern_index];
if package_subpath.starts_with(key_sub) {
// When this reaches EOL, this can throw at the top of the whole function:
//
// if (StringPrototypeEndsWith(packageSubpath, '/'))
// throwInvalidSubpath(packageSubpath)
//
// To match "imports" and the spec.
if package_subpath.ends_with('/') {
// TODO(bartlomieju):
// emitTrailingSlashPatternDeprecation();
}
let pattern_trailer = &key[pattern_index + 1..];
if package_subpath.len() > key.len()
&& package_subpath.ends_with(&pattern_trailer)
&& pattern_key_compare(best_match, key) == 1
&& key.rfind('*') == Some(pattern_index)
{
best_match = key;
best_match_subpath = Some(
package_subpath
[pattern_index..=(package_subpath.len() - pattern_trailer.len())]
.to_string(),
);
}
}
}
}
if !best_match.is_empty() {
let target = package_exports.get(best_match).unwrap().to_owned();
let maybe_resolved = resolve_package_target(
package_json_url.clone(),
target,
best_match_subpath.unwrap(),
best_match.to_string(),
base,
true,
false,
conditions,
npm_resolver,
)?;
if let Some(resolved) = maybe_resolved {
return Ok(resolved);
} else {
return Err(throw_exports_not_found(
package_subpath,
&package_json_url,
base,
));
}
}
Err(throw_exports_not_found(
package_subpath,
&package_json_url,
base,
))
}
fn parse_package_name(
specifier: &str,
base: &ModuleSpecifier,
) -> Result<(String, String, bool), AnyError> {
let mut separator_index = specifier.find('/');
let mut valid_package_name = true;
let mut is_scoped = false;
if specifier.is_empty() {
valid_package_name = false;
} else if specifier.starts_with('@') {
is_scoped = true;
if let Some(index) = separator_index {
separator_index = specifier[index + 1..].find('/');
} else {
valid_package_name = false;
}
}
let package_name = if let Some(index) = separator_index {
specifier[0..index].to_string()
} else {
specifier.to_string()
};
// Package name cannot have leading . and cannot have percent-encoding or separators.
for ch in package_name.chars() {
if ch == '%' || ch == '\\' {
valid_package_name = false;
break;
}
}
if !valid_package_name {
return Err(errors::err_invalid_module_specifier(
specifier,
"is not a valid package name",
Some(to_file_path_string(base)),
));
}
let package_subpath = if let Some(index) = separator_index {
format!(".{}", specifier.chars().skip(index).collect::<String>())
} else {
".".to_string()
};
Ok((package_name, package_subpath, is_scoped))
}
pub fn package_resolve(
specifier: &str,
referrer: &ModuleSpecifier,
conditions: &[&str],
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<ModuleSpecifier, AnyError> {
let (package_name, package_subpath, _is_scoped) =
parse_package_name(specifier, referrer)?;
// ResolveSelf
let package_config = get_package_scope_config(referrer, npm_resolver)?;
if package_config.exists {
let package_json_url = Url::from_file_path(&package_config.path).unwrap();
if package_config.name.as_ref() == Some(&package_name) {
if let Some(exports) = &package_config.exports {
return package_exports_resolve(
package_json_url,
package_subpath,
exports,
referrer,
conditions,
npm_resolver,
);
}
}
}
let package_dir_path = npm_resolver
.resolve_package_folder_from_package(
&package_name,
&referrer.to_file_path().unwrap(),
)
.unwrap();
let package_json_path = package_dir_path.join("package.json");
let package_json_url =
ModuleSpecifier::from_file_path(&package_json_path).unwrap();
// todo: error with this instead when can't find package
// Err(errors::err_module_not_found(
// &package_json_url
// .join(".")
// .unwrap()
// .to_file_path()
// .unwrap()
// .display()
// .to_string(),
// &to_file_path_string(referrer),
// "package",
// ))
// Package match.
let package_json = PackageJson::load(npm_resolver, package_json_path)?;
if let Some(exports) = &package_json.exports {
return package_exports_resolve(
package_json_url,
package_subpath,
exports,
referrer,
conditions,
npm_resolver,
);
}
if package_subpath == "." {
return legacy_main_resolve(&package_json_url, &package_json, referrer);
}
package_json_url
.join(&package_subpath)
.map_err(AnyError::from)
}
pub fn get_package_scope_config(
referrer: &ModuleSpecifier,
npm_resolver: &dyn DenoDirNpmResolver,
) -> Result<PackageJson, AnyError> {
let root_folder = npm_resolver
.resolve_package_folder_from_path(&referrer.to_file_path().unwrap())?;
let package_json_path = root_folder.join("./package.json");
PackageJson::load(npm_resolver, package_json_path)
}
fn file_exists(path_url: &ModuleSpecifier) -> bool {
if let Ok(stats) = std::fs::metadata(to_file_path(path_url)) {
stats.is_file()
} else {
false
}
}
pub fn legacy_main_resolve(
package_json_url: &ModuleSpecifier,
package_json: &PackageJson,
_base: &ModuleSpecifier,
) -> Result<ModuleSpecifier, AnyError> {
let mut guess;
if let Some(main) = &package_json.main {
guess = package_json_url.join(&format!("./{}", main))?;
if file_exists(&guess) {
return Ok(guess);
}
let mut found = false;
for ext in [
".js",
".json",
".node",
"/index.js",
"/index.json",
"/index.node",
] {
guess = package_json_url.join(&format!("./{}{}", main, ext))?;
if file_exists(&guess) {
found = true;
break;
}
}
if found {
// TODO(bartlomieju): emitLegacyIndexDeprecation()
return Ok(guess);
}
}
for p in ["./index.js", "./index.json", "./index.node"] {
guess = package_json_url.join(p)?;
if file_exists(&guess) {
// TODO(bartlomieju): emitLegacyIndexDeprecation()
return Ok(guess);
}
}
Err(generic_error("not found"))
}

View file

@ -167,7 +167,7 @@ mod not_docs {
deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable.
),
// deno_node::init(), // todo(dsherret): re-enable
deno_node::init(false, None), // No --unstable.
deno_ffi::init::<Permissions>(false),
deno_net::init::<Permissions>(
None, false, // No --unstable.

View file

@ -52,6 +52,7 @@ async fn main() -> Result<(), AnyError> {
maybe_inspector_server: None,
should_break_on_first_statement: false,
module_loader,
npm_resolver: None,
get_error_class_fn: Some(&get_error_class_name),
origin_storage_dir: None,
blob_store: BlobStore::default(),

View file

@ -31,6 +31,7 @@ use deno_core::ModuleSpecifier;
use deno_core::RuntimeOptions;
use deno_core::SharedArrayBufferStore;
use deno_core::SourceMapGetter;
use deno_node::DenoDirNpmResolver;
use deno_tls::rustls::RootCertStore;
use deno_web::create_entangled_message_port;
use deno_web::BlobStore;
@ -323,6 +324,7 @@ pub struct WebWorkerOptions {
pub root_cert_store: Option<RootCertStore>,
pub seed: Option<u64>,
pub module_loader: Rc<dyn ModuleLoader>,
pub npm_resolver: Option<Rc<dyn DenoDirNpmResolver>>,
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
pub preload_module_cb: Arc<ops::worker_host::WorkerEventCb>,
pub pre_execute_module_cb: Arc<ops::worker_host::WorkerEventCb>,
@ -421,7 +423,7 @@ impl WebWorker {
unstable,
options.unsafely_ignore_certificate_errors.clone(),
),
// deno_node::init(), // todo(dsherret): re-enable
deno_node::init(unstable, options.npm_resolver),
ops::os::init_for_worker(),
ops::permissions::init(),
ops::process::init(),

View file

@ -22,6 +22,7 @@ use deno_core::ModuleSpecifier;
use deno_core::RuntimeOptions;
use deno_core::SharedArrayBufferStore;
use deno_core::SourceMapGetter;
use deno_node::DenoDirNpmResolver;
use deno_tls::rustls::RootCertStore;
use deno_web::BlobStore;
use log::debug;
@ -67,6 +68,7 @@ pub struct WorkerOptions {
pub root_cert_store: Option<RootCertStore>,
pub seed: Option<u64>,
pub module_loader: Rc<dyn ModuleLoader>,
pub npm_resolver: Option<Rc<dyn DenoDirNpmResolver>>,
// Callbacks invoked when creating new instance of WebWorker
pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
pub web_worker_preload_module_cb: Arc<ops::worker_host::WorkerEventCb>,
@ -163,7 +165,7 @@ impl MainWorker {
unstable,
options.unsafely_ignore_certificate_errors.clone(),
),
// deno_node::init() // todo(dsherret): re-enable,
deno_node::init(unstable, options.npm_resolver),
ops::os::init(exit_code.clone()),
ops::permissions::init(),
ops::process::init(),
@ -428,6 +430,7 @@ mod tests {
maybe_inspector_server: None,
should_break_on_first_statement: false,
module_loader: Rc::new(deno_core::FsModuleLoader),
npm_resolver: None,
get_error_class_fn: None,
origin_storage_dir: None,
blob_store: BlobStore::default(),

View file

@ -24,6 +24,7 @@ os_pipe = "1.0.1"
parking_lot = "0.12.0"
pretty_assertions = "=1.2.1"
regex = "1.6.0"
reqwest = { version = "0.11.11", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks"] }
rustls-pemfile = "1.0.0"
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"

View file

@ -947,11 +947,37 @@ async fn main_server(
_ => {
let mut file_path = testdata_path();
file_path.push(&req.uri().path()[1..]);
if let Ok(file) = tokio::fs::read(file_path).await {
if let Ok(file) = tokio::fs::read(&file_path).await {
let file_resp = custom_headers(req.uri().path(), file);
return Ok(file_resp);
}
// serve npm registry files
if req.uri().path().starts_with("/npm/registry/") {
let is_tarball = req.uri().path().ends_with(".tgz");
if !is_tarball {
file_path.push("registry.json");
}
if let Ok(file) = tokio::fs::read(&file_path).await {
let file_resp = custom_headers(req.uri().path(), file);
return Ok(file_resp);
} else if should_download_npm_packages() {
if let Err(err) =
download_npm_registry_file(&file_path, is_tarball).await
{
return Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(format!("{:#}", err).into());
};
// serve the file
if let Ok(file) = tokio::fs::read(&file_path).await {
let file_resp = custom_headers(req.uri().path(), file);
return Ok(file_resp);
}
}
}
Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::empty())
@ -959,6 +985,50 @@ async fn main_server(
};
}
fn should_download_npm_packages() -> bool {
// when this env var is set, it will download and save npm packages
// to the testdata/npm/registry directory
std::env::var("DENO_TEST_UTIL_UPDATE_NPM") == Ok("1".to_string())
}
async fn download_npm_registry_file(
file_path: &PathBuf,
is_tarball: bool,
) -> Result<(), anyhow::Error> {
let package_name = file_path
.parent()
.unwrap()
.file_name()
.unwrap()
.to_string_lossy();
let url = if is_tarball {
let file_name = file_path.file_name().unwrap().to_string_lossy();
format!(
"https://registry.npmjs.org/{}/-/{}",
package_name, file_name
)
} else {
format!("https://registry.npmjs.org/{}", package_name)
};
let client = reqwest::Client::new();
let response = client.get(url).send().await?;
let bytes = response.bytes().await?;
let bytes = if is_tarball {
bytes.to_vec()
} else {
String::from_utf8(bytes.to_vec())
.unwrap()
.replace(
&format!("https://registry.npmjs.org/{}/-/", package_name),
&format!("http://localhost:4545/npm/registry/{}/", package_name),
)
.into_bytes()
};
std::fs::create_dir_all(file_path.parent().unwrap())?;
std::fs::write(&file_path, bytes)?;
Ok(())
}
/// Taken from example in https://github.com/ctz/hyper-rustls/blob/a02ef72a227dcdf102f86e905baa7415c992e8b3/examples/server.rs
struct HyperAcceptor<'a> {
acceptor: Pin<