deno/cli/args/import_map.rs
Bartek Iwańczuk 9534e6e113
feat(unstable): Workspaces support (#20410)
This commit adds unstable workspace support. This is extremely
bare-bones and
minimal first-pass at this.

With this change `deno.json` supports specifying `workspaces` key, that
accepts a list of subdirectories. Each workspace can have its own import
map. It's required to specify a `"name"` and `"version"` properties in the
configuration file for the workspace:

```jsonc
// deno.json
{
  "workspaces": [
     "a",
     "b"
  },
  "imports": {
    "express": "npm:express@5"
   }
}
```
``` jsonc
// a/deno.json
{
  "name": "a",
  "version": "1.0.2",
  "imports": {
    "kleur": "npm:kleur"
  }
}
```
```jsonc
// b/deno.json
{
  "name": "b",
  "version": "0.51.0",
  "imports": {
    "chalk": "npm:chalk"
  }
}
```

`--unstable-workspaces` flag is required to use this feature:
```
$ deno run --unstable-workspaces mod.ts
```

---------

Co-authored-by: David Sherret <dsherret@gmail.com>
2023-11-17 01:28:38 +00:00

65 lines
1.8 KiB
Rust

// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_runtime::permissions::PermissionsContainer;
use import_map::ImportMap;
use import_map::ImportMapDiagnostic;
use log::warn;
use super::ConfigFile;
use crate::file_fetcher::get_source_from_data_url;
use crate::file_fetcher::FileFetcher;
pub async fn resolve_import_map_from_specifier(
specifier: &Url,
maybe_config_file: Option<&ConfigFile>,
file_fetcher: &FileFetcher,
) -> Result<ImportMap, AnyError> {
let value: serde_json::Value = if specifier.scheme() == "data" {
serde_json::from_str(&get_source_from_data_url(specifier)?.0)?
} else {
let import_map_config = maybe_config_file
.as_ref()
.filter(|c| c.specifier == *specifier);
match import_map_config {
Some(config) => config.to_import_map_value(),
None => {
let file = file_fetcher
.fetch(specifier, PermissionsContainer::allow_all())
.await?;
serde_json::from_str(&file.source)?
}
}
};
import_map_from_value(specifier, value)
}
pub fn import_map_from_value(
specifier: &Url,
json_value: serde_json::Value,
) -> Result<ImportMap, AnyError> {
debug_assert!(
!specifier.as_str().contains("../"),
"Import map specifier incorrectly contained ../: {}",
specifier.as_str()
);
let result = import_map::parse_from_value(specifier, json_value)?;
print_import_map_diagnostics(&result.diagnostics);
Ok(result.import_map)
}
fn print_import_map_diagnostics(diagnostics: &[ImportMapDiagnostic]) {
if !diagnostics.is_empty() {
warn!(
"Import map diagnostics:\n{}",
diagnostics
.iter()
.map(|d| format!(" - {d}"))
.collect::<Vec<_>>()
.join("\n")
);
}
}