mirror of
https://github.com/denoland/deno.git
synced 2024-12-26 17:19:06 -05:00
fadda6a8fb
We should track dependencies in `jsxImportSource`, `jsxImportSourceTypes`, and `types`. That way, for example, if someone removes or changes the `jsxImportSource` then we can remove those items from the lockfile.
165 lines
4.5 KiB
Rust
165 lines
4.5 KiB
Rust
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
|
|
use std::collections::HashSet;
|
|
|
|
use deno_config::deno_json::TsConfigForEmit;
|
|
use deno_core::serde_json;
|
|
use deno_semver::jsr::JsrDepPackageReq;
|
|
use deno_semver::jsr::JsrPackageReqReference;
|
|
use deno_semver::npm::NpmPackageReqReference;
|
|
|
|
#[cfg(test)] // happens to only be used by the tests at the moment
|
|
pub struct DenoConfigFsAdapter<'a>(
|
|
pub &'a dyn deno_runtime::deno_fs::FileSystem,
|
|
);
|
|
|
|
#[cfg(test)]
|
|
impl<'a> deno_config::fs::DenoConfigFs for DenoConfigFsAdapter<'a> {
|
|
fn read_to_string_lossy(
|
|
&self,
|
|
path: &std::path::Path,
|
|
) -> Result<String, std::io::Error> {
|
|
self
|
|
.0
|
|
.read_text_file_lossy_sync(path, None)
|
|
.map_err(|err| err.into_io_error())
|
|
}
|
|
|
|
fn stat_sync(
|
|
&self,
|
|
path: &std::path::Path,
|
|
) -> Result<deno_config::fs::FsMetadata, std::io::Error> {
|
|
self
|
|
.0
|
|
.stat_sync(path)
|
|
.map(|stat| deno_config::fs::FsMetadata {
|
|
is_file: stat.is_file,
|
|
is_directory: stat.is_directory,
|
|
is_symlink: stat.is_symlink,
|
|
})
|
|
.map_err(|err| err.into_io_error())
|
|
}
|
|
|
|
fn read_dir(
|
|
&self,
|
|
path: &std::path::Path,
|
|
) -> Result<Vec<deno_config::fs::FsDirEntry>, std::io::Error> {
|
|
self
|
|
.0
|
|
.read_dir_sync(path)
|
|
.map_err(|err| err.into_io_error())
|
|
.map(|entries| {
|
|
entries
|
|
.into_iter()
|
|
.map(|e| deno_config::fs::FsDirEntry {
|
|
path: path.join(e.name),
|
|
metadata: deno_config::fs::FsMetadata {
|
|
is_file: e.is_file,
|
|
is_directory: e.is_directory,
|
|
is_symlink: e.is_symlink,
|
|
},
|
|
})
|
|
.collect()
|
|
})
|
|
}
|
|
}
|
|
|
|
pub fn deno_json_deps(
|
|
config: &deno_config::deno_json::ConfigFile,
|
|
) -> HashSet<JsrDepPackageReq> {
|
|
let values = imports_values(config.json.imports.as_ref())
|
|
.into_iter()
|
|
.chain(scope_values(config.json.scopes.as_ref()));
|
|
let mut set = values_to_set(values);
|
|
|
|
if let Some(serde_json::Value::Object(compiler_options)) =
|
|
&config.json.compiler_options
|
|
{
|
|
// add jsxImportSource
|
|
if let Some(serde_json::Value::String(value)) =
|
|
compiler_options.get("jsxImportSource")
|
|
{
|
|
if let Some(dep_req) = value_to_dep_req(value) {
|
|
set.insert(dep_req);
|
|
}
|
|
}
|
|
// add jsxImportSourceTypes
|
|
if let Some(serde_json::Value::String(value)) =
|
|
compiler_options.get("jsxImportSourceTypes")
|
|
{
|
|
if let Some(dep_req) = value_to_dep_req(value) {
|
|
set.insert(dep_req);
|
|
}
|
|
}
|
|
// add the dependencies in the types array
|
|
if let Some(serde_json::Value::Array(types)) = compiler_options.get("types")
|
|
{
|
|
for value in types {
|
|
if let serde_json::Value::String(value) = value {
|
|
if let Some(dep_req) = value_to_dep_req(value) {
|
|
set.insert(dep_req);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
set
|
|
}
|
|
|
|
fn imports_values(value: Option<&serde_json::Value>) -> Vec<&String> {
|
|
let Some(obj) = value.and_then(|v| v.as_object()) else {
|
|
return Vec::new();
|
|
};
|
|
let mut items = Vec::with_capacity(obj.len());
|
|
for value in obj.values() {
|
|
if let serde_json::Value::String(value) = value {
|
|
items.push(value);
|
|
}
|
|
}
|
|
items
|
|
}
|
|
|
|
fn scope_values(value: Option<&serde_json::Value>) -> Vec<&String> {
|
|
let Some(obj) = value.and_then(|v| v.as_object()) else {
|
|
return Vec::new();
|
|
};
|
|
obj.values().flat_map(|v| imports_values(Some(v))).collect()
|
|
}
|
|
|
|
fn values_to_set<'a>(
|
|
values: impl Iterator<Item = &'a String>,
|
|
) -> HashSet<JsrDepPackageReq> {
|
|
let mut entries = HashSet::new();
|
|
for value in values {
|
|
if let Some(dep_req) = value_to_dep_req(value) {
|
|
entries.insert(dep_req);
|
|
}
|
|
}
|
|
entries
|
|
}
|
|
|
|
fn value_to_dep_req(value: &str) -> Option<JsrDepPackageReq> {
|
|
if let Ok(req_ref) = JsrPackageReqReference::from_str(value) {
|
|
Some(JsrDepPackageReq::jsr(req_ref.into_inner().req))
|
|
} else if let Ok(req_ref) = NpmPackageReqReference::from_str(value) {
|
|
Some(JsrDepPackageReq::npm(req_ref.into_inner().req))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn check_warn_tsconfig(ts_config: &TsConfigForEmit) {
|
|
if let Some(ignored_options) = &ts_config.maybe_ignored_options {
|
|
log::warn!("{}", ignored_options);
|
|
}
|
|
let serde_json::Value::Object(obj) = &ts_config.ts_config.0 else {
|
|
return;
|
|
};
|
|
if obj.get("experimentalDecorators") == Some(&serde_json::Value::Bool(true)) {
|
|
log::warn!(
|
|
"{} experimentalDecorators compiler option is deprecated and may be removed at any time",
|
|
deno_runtime::colors::yellow("Warning"),
|
|
);
|
|
}
|
|
}
|