summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/integration/npm_tests.rs37
-rw-r--r--cli/tests/testdata/info/076_info_json_deps_order.out3
-rw-r--r--cli/tests/testdata/info/json_output/main.out3
-rw-r--r--cli/tests/testdata/npm/cjs_with_deps/main_info.out (renamed from cli/tests/testdata/npm/cjs_with_deps/main.info.out)0
-rw-r--r--cli/tests/testdata/npm/cjs_with_deps/main_info_json.out146
-rw-r--r--cli/tests/testdata/npm/info/chalk.out (renamed from cli/tests/testdata/npm/deno_info_chalk.out)0
-rw-r--r--cli/tests/testdata/npm/info/chalk_json.out54
-rw-r--r--cli/tools/info.rs96
8 files changed, 330 insertions, 9 deletions
diff --git a/cli/tests/integration/npm_tests.rs b/cli/tests/integration/npm_tests.rs
index 0ca1ae910..714fe25d4 100644
--- a/cli/tests/integration/npm_tests.rs
+++ b/cli/tests/integration/npm_tests.rs
@@ -733,26 +733,51 @@ itest!(compile_errors {
http_server: true,
});
-itest!(info_chalk {
+itest!(info_chalk_display {
args: "info --quiet --unstable npm/cjs_with_deps/main.js",
- output: "npm/cjs_with_deps/main.info.out",
+ output: "npm/cjs_with_deps/main_info.out",
exit_code: 0,
envs: env_vars(),
http_server: true,
});
-itest!(info_chalk_node_modules_dir {
+itest!(info_chalk_display_node_modules_dir {
args: "info --quiet --unstable --node-modules-dir $TESTDATA/npm/cjs_with_deps/main.js",
- output: "npm/cjs_with_deps/main.info.out",
+ output: "npm/cjs_with_deps/main_info.out",
exit_code: 0,
envs: env_vars(),
http_server: true,
temp_cwd: true,
});
-itest!(info_cli_chalk {
+itest!(info_chalk_json {
+ args: "info --quiet --unstable --json npm/cjs_with_deps/main.js",
+ output: "npm/cjs_with_deps/main_info_json.out",
+ exit_code: 0,
+ envs: env_vars(),
+ http_server: true,
+});
+
+itest!(info_chalk_json_node_modules_dir {
+ args: "info --quiet --unstable --node-modules-dir --json $TESTDATA/npm/cjs_with_deps/main.js",
+ output: "npm/cjs_with_deps/main_info_json.out",
+ exit_code: 0,
+ envs: env_vars(),
+ http_server: true,
+ temp_cwd: true,
+});
+
+itest!(info_cli_chalk_display {
args: "info --quiet --unstable npm:chalk@4",
- output: "npm/deno_info_chalk.out",
+ output: "npm/info/chalk.out",
+ exit_code: 0,
+ envs: env_vars(),
+ http_server: true,
+});
+
+itest!(info_cli_chalk_json {
+ args: "info --quiet --unstable --json npm:chalk@4",
+ output: "npm/info/chalk_json.out",
exit_code: 0,
envs: env_vars(),
http_server: true,
diff --git a/cli/tests/testdata/info/076_info_json_deps_order.out b/cli/tests/testdata/info/076_info_json_deps_order.out
index db890ef02..98b5d5d50 100644
--- a/cli/tests/testdata/info/076_info_json_deps_order.out
+++ b/cli/tests/testdata/info/076_info_json_deps_order.out
@@ -159,5 +159,6 @@
"specifier": "file://[WILDCARD]/recursive_imports/common.ts"
}
],
- "redirects": {}
+ "redirects": {},
+ "npmPackages": {}
}
diff --git a/cli/tests/testdata/info/json_output/main.out b/cli/tests/testdata/info/json_output/main.out
index 124fc7351..aaef028c0 100644
--- a/cli/tests/testdata/info/json_output/main.out
+++ b/cli/tests/testdata/info/json_output/main.out
@@ -86,5 +86,6 @@
"specifier": "file://[WILDCARD]/subdir/subdir2/mod2.ts"
}
],
- "redirects": {}
+ "redirects": {},
+ "npmPackages": {}
}
diff --git a/cli/tests/testdata/npm/cjs_with_deps/main.info.out b/cli/tests/testdata/npm/cjs_with_deps/main_info.out
index 345583a90..345583a90 100644
--- a/cli/tests/testdata/npm/cjs_with_deps/main.info.out
+++ b/cli/tests/testdata/npm/cjs_with_deps/main_info.out
diff --git a/cli/tests/testdata/npm/cjs_with_deps/main_info_json.out b/cli/tests/testdata/npm/cjs_with_deps/main_info_json.out
new file mode 100644
index 000000000..bc7b9e162
--- /dev/null
+++ b/cli/tests/testdata/npm/cjs_with_deps/main_info_json.out
@@ -0,0 +1,146 @@
+{
+ "roots": [
+ "file://[WILDCARD]/main.js"
+ ],
+ "modules": [
+ {
+ "dependencies": [
+ {
+ "specifier": "npm:chai@4.3",
+ "code": {
+ "specifier": "npm:chai@4.3",
+ "span": {
+ "start": {
+ "line": 1,
+ "character": 23
+ },
+ "end": {
+ "line": 1,
+ "character": 37
+ }
+ }
+ },
+ "npmPackage": "chai@4.3.6"
+ },
+ {
+ "specifier": "npm:chalk@4",
+ "code": {
+ "specifier": "npm:chalk@4",
+ "span": {
+ "start": {
+ "line": 0,
+ "character": 18
+ },
+ "end": {
+ "line": 0,
+ "character": 31
+ }
+ }
+ },
+ "npmPackage": "chalk@4.1.2"
+ }
+ ],
+ "kind": "esm",
+ "local": "[WILDCARD]main.js",
+ "emit": null,
+ "map": null,
+ "size": 325,
+ "mediaType": "JavaScript",
+ "specifier": "[WILDCARD]/main.js"
+ }
+ ],
+ "redirects": {},
+ "npmPackages": {
+ "ansi-styles@4.3.0": {
+ "name": "ansi-styles",
+ "version": "4.3.0",
+ "dependencies": [
+ "color-convert@2.0.1"
+ ]
+ },
+ "assertion-error@1.1.0": {
+ "name": "assertion-error",
+ "version": "1.1.0",
+ "dependencies": []
+ },
+ "chai@4.3.6": {
+ "name": "chai",
+ "version": "4.3.6",
+ "dependencies": [
+ "assertion-error@1.1.0",
+ "check-error@1.0.2",
+ "deep-eql@3.0.1",
+ "get-func-name@2.0.0",
+ "loupe@2.3.4",
+ "pathval@1.1.1",
+ "type-detect@4.0.8"
+ ]
+ },
+ "chalk@4.1.2": {
+ "name": "chalk",
+ "version": "4.1.2",
+ "dependencies": [
+ "ansi-styles@4.3.0",
+ "supports-color@7.2.0"
+ ]
+ },
+ "check-error@1.0.2": {
+ "name": "check-error",
+ "version": "1.0.2",
+ "dependencies": []
+ },
+ "color-convert@2.0.1": {
+ "name": "color-convert",
+ "version": "2.0.1",
+ "dependencies": [
+ "color-name@1.1.4"
+ ]
+ },
+ "color-name@1.1.4": {
+ "name": "color-name",
+ "version": "1.1.4",
+ "dependencies": []
+ },
+ "deep-eql@3.0.1": {
+ "name": "deep-eql",
+ "version": "3.0.1",
+ "dependencies": [
+ "type-detect@4.0.8"
+ ]
+ },
+ "get-func-name@2.0.0": {
+ "name": "get-func-name",
+ "version": "2.0.0",
+ "dependencies": []
+ },
+ "has-flag@4.0.0": {
+ "name": "has-flag",
+ "version": "4.0.0",
+ "dependencies": []
+ },
+ "loupe@2.3.4": {
+ "name": "loupe",
+ "version": "2.3.4",
+ "dependencies": [
+ "get-func-name@2.0.0"
+ ]
+ },
+ "pathval@1.1.1": {
+ "name": "pathval",
+ "version": "1.1.1",
+ "dependencies": []
+ },
+ "supports-color@7.2.0": {
+ "name": "supports-color",
+ "version": "7.2.0",
+ "dependencies": [
+ "has-flag@4.0.0"
+ ]
+ },
+ "type-detect@4.0.8": {
+ "name": "type-detect",
+ "version": "4.0.8",
+ "dependencies": []
+ }
+ }
+}
diff --git a/cli/tests/testdata/npm/deno_info_chalk.out b/cli/tests/testdata/npm/info/chalk.out
index 89ea05e71..89ea05e71 100644
--- a/cli/tests/testdata/npm/deno_info_chalk.out
+++ b/cli/tests/testdata/npm/info/chalk.out
diff --git a/cli/tests/testdata/npm/info/chalk_json.out b/cli/tests/testdata/npm/info/chalk_json.out
new file mode 100644
index 000000000..f6673d032
--- /dev/null
+++ b/cli/tests/testdata/npm/info/chalk_json.out
@@ -0,0 +1,54 @@
+{
+ "roots": [
+ "npm:chalk@4"
+ ],
+ "modules": [
+ {
+ "kind": "npm",
+ "specifier": "npm:chalk@4",
+ "npmPackage": "chalk@4.1.2"
+ }
+ ],
+ "redirects": {},
+ "npmPackages": {
+ "ansi-styles@4.3.0": {
+ "name": "ansi-styles",
+ "version": "4.3.0",
+ "dependencies": [
+ "color-convert@2.0.1"
+ ]
+ },
+ "chalk@4.1.2": {
+ "name": "chalk",
+ "version": "4.1.2",
+ "dependencies": [
+ "ansi-styles@4.3.0",
+ "supports-color@7.2.0"
+ ]
+ },
+ "color-convert@2.0.1": {
+ "name": "color-convert",
+ "version": "2.0.1",
+ "dependencies": [
+ "color-name@1.1.4"
+ ]
+ },
+ "color-name@1.1.4": {
+ "name": "color-name",
+ "version": "1.1.4",
+ "dependencies": []
+ },
+ "has-flag@4.0.0": {
+ "name": "has-flag",
+ "version": "4.0.0",
+ "dependencies": []
+ },
+ "supports-color@7.2.0": {
+ "name": "supports-color",
+ "version": "7.2.0",
+ "dependencies": [
+ "has-flag@4.0.0"
+ ]
+ }
+ }
+}
diff --git a/cli/tools/info.rs b/cli/tools/info.rs
index e45958b34..12b1ae4c3 100644
--- a/cli/tools/info.rs
+++ b/cli/tools/info.rs
@@ -38,7 +38,9 @@ pub async fn info(flags: Flags, info_flags: InfoFlags) -> Result<(), AnyError> {
let graph = ps.create_graph(vec![(specifier, ModuleKind::Esm)]).await?;
if info_flags.json {
- display::write_json_to_stdout(&json!(graph))?;
+ let mut json_graph = json!(graph);
+ add_npm_packages_to_json(&mut json_graph, &ps.npm_resolver);
+ display::write_json_to_stdout(&json_graph)?;
} else {
let mut output = String::new();
GraphDisplayContext::write(&graph, &ps.npm_resolver, &mut output)?;
@@ -128,6 +130,98 @@ fn print_cache_info(
}
}
+fn add_npm_packages_to_json(
+ json: &mut serde_json::Value,
+ npm_resolver: &NpmPackageResolver,
+) {
+ // ideally deno_graph could handle this, but for now we just modify the json here
+ let snapshot = npm_resolver.snapshot();
+ let json = json.as_object_mut().unwrap();
+ let modules = json.get_mut("modules").and_then(|m| m.as_array_mut());
+ if let Some(modules) = modules {
+ if modules.len() == 1
+ && modules[0].get("kind").and_then(|k| k.as_str()) == Some("external")
+ {
+ // If there is only one module and it's "external", then that means
+ // someone provided an npm specifier as a cli argument. In this case,
+ // we want to show which npm package the cli argument resolved to.
+ let module = &mut modules[0];
+ let maybe_package = module
+ .get("specifier")
+ .and_then(|k| k.as_str())
+ .and_then(|specifier| NpmPackageReference::from_str(specifier).ok())
+ .and_then(|package_ref| {
+ snapshot
+ .resolve_package_from_deno_module(&package_ref.req)
+ .ok()
+ });
+ if let Some(pkg) = maybe_package {
+ if let Some(module) = module.as_object_mut() {
+ module.insert("npmPackage".to_string(), format!("{}", pkg.id).into());
+ // change the "kind" to be "npm"
+ module.insert("kind".to_string(), "npm".into());
+ }
+ }
+ } else {
+ // Filter out npm package references from the modules and instead
+ // have them only listed as dependencies. This is done because various
+ // npm specifiers modules in the graph are really just unresolved
+ // references. So there could be listed multiple npm specifiers
+ // that would resolve to a single npm package.
+ for i in (0..modules.len()).rev() {
+ if modules[i].get("kind").and_then(|k| k.as_str()) == Some("external") {
+ modules.remove(i);
+ }
+ }
+ }
+
+ for module in modules.iter_mut() {
+ let dependencies = module
+ .get_mut("dependencies")
+ .and_then(|d| d.as_array_mut());
+ if let Some(dependencies) = dependencies {
+ for dep in dependencies.iter_mut() {
+ if let serde_json::Value::Object(dep) = dep {
+ let specifier = dep.get("specifier").and_then(|s| s.as_str());
+ if let Some(specifier) = specifier {
+ if let Ok(npm_ref) = NpmPackageReference::from_str(specifier) {
+ if let Ok(pkg) =
+ snapshot.resolve_package_from_deno_module(&npm_ref.req)
+ {
+ dep.insert(
+ "npmPackage".to_string(),
+ format!("{}", pkg.id).into(),
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ let mut sorted_packages = snapshot.all_packages();
+ sorted_packages.sort_by(|a, b| a.id.cmp(&b.id));
+ let mut json_packages = serde_json::Map::with_capacity(sorted_packages.len());
+ for pkg in sorted_packages {
+ let mut kv = serde_json::Map::new();
+ kv.insert("name".to_string(), pkg.id.name.to_string().into());
+ kv.insert("version".to_string(), pkg.id.version.to_string().into());
+ let mut deps = pkg.dependencies.values().collect::<Vec<_>>();
+ deps.sort();
+ let deps = deps
+ .into_iter()
+ .map(|id| serde_json::Value::String(format!("{}", id)))
+ .collect::<Vec<_>>();
+ kv.insert("dependencies".to_string(), deps.into());
+
+ json_packages.insert(format!("{}", &pkg.id), kv.into());
+ }
+
+ json.insert("npmPackages".to_string(), json_packages.into());
+}
+
struct TreeNode {
text: String,
children: Vec<TreeNode>,