2021-01-11 12:13:41 -05:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
2020-09-05 20:34:02 -04:00
|
|
|
|
2020-11-02 14:41:20 -05:00
|
|
|
use crate::module_graph::BundleType;
|
|
|
|
use crate::module_graph::EmitOptions;
|
|
|
|
use crate::module_graph::GraphBuilder;
|
2021-09-24 11:10:42 -04:00
|
|
|
use crate::proc_state::ProcState;
|
2020-11-01 21:51:56 -05:00
|
|
|
use crate::specifier_handler::FetchHandler;
|
|
|
|
use crate::specifier_handler::MemoryHandler;
|
|
|
|
use crate::specifier_handler::SpecifierHandler;
|
|
|
|
|
2020-12-31 16:43:54 -05:00
|
|
|
use deno_core::error::generic_error;
|
2021-01-28 20:33:58 -05:00
|
|
|
use deno_core::error::type_error;
|
2020-09-14 12:48:57 -04:00
|
|
|
use deno_core::error::AnyError;
|
2020-11-01 21:51:56 -05:00
|
|
|
use deno_core::error::Context;
|
2021-07-06 23:48:01 -04:00
|
|
|
use deno_core::parking_lot::Mutex;
|
2021-02-17 13:47:18 -05:00
|
|
|
use deno_core::resolve_url_or_path;
|
2020-09-21 12:36:37 -04:00
|
|
|
use deno_core::serde_json::Value;
|
2020-09-10 09:57:45 -04:00
|
|
|
use deno_core::OpState;
|
2020-12-29 23:17:17 -05:00
|
|
|
use deno_runtime::permissions::Permissions;
|
2021-09-10 21:38:24 -04:00
|
|
|
use import_map::ImportMap;
|
2020-09-16 12:43:08 -04:00
|
|
|
use serde::Deserialize;
|
2021-10-05 16:38:27 -04:00
|
|
|
use serde::Serialize;
|
2020-09-10 09:57:45 -04:00
|
|
|
use std::cell::RefCell;
|
2020-01-21 11:50:06 -05:00
|
|
|
use std::collections::HashMap;
|
2020-08-18 12:30:13 -04:00
|
|
|
use std::rc::Rc;
|
2020-12-29 23:17:17 -05:00
|
|
|
use std::sync::Arc;
|
2020-01-21 11:50:06 -05:00
|
|
|
|
2020-09-10 09:57:45 -04:00
|
|
|
pub fn init(rt: &mut deno_core::JsRuntime) {
|
2021-04-12 15:55:05 -04:00
|
|
|
super::reg_async(rt, "op_emit", op_emit);
|
2020-01-21 11:50:06 -05:00
|
|
|
}
|
|
|
|
|
2020-12-31 16:43:54 -05:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
enum RuntimeBundleType {
|
2021-04-25 16:54:57 -04:00
|
|
|
#[serde(rename = "module")]
|
|
|
|
Module,
|
|
|
|
#[serde(rename = "classic")]
|
|
|
|
Classic,
|
2020-12-31 16:43:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
2020-01-21 11:50:06 -05:00
|
|
|
#[serde(rename_all = "camelCase")]
|
2020-12-31 16:43:54 -05:00
|
|
|
struct EmitArgs {
|
|
|
|
bundle: Option<RuntimeBundleType>,
|
|
|
|
check: Option<bool>,
|
|
|
|
compiler_options: Option<HashMap<String, Value>>,
|
|
|
|
import_map: Option<Value>,
|
|
|
|
import_map_path: Option<String>,
|
|
|
|
root_specifier: String,
|
2021-09-07 10:39:32 -04:00
|
|
|
sources: Option<HashMap<String, Arc<String>>>,
|
2020-01-21 11:50:06 -05:00
|
|
|
}
|
|
|
|
|
2021-10-05 16:38:27 -04:00
|
|
|
#[derive(Serialize)]
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
struct EmitResult {
|
|
|
|
diagnostics: crate::diagnostics::Diagnostics,
|
|
|
|
files: HashMap<String, String>,
|
|
|
|
ignored_options: Option<crate::config_file::IgnoredCompilerOptions>,
|
|
|
|
stats: crate::module_graph::Stats,
|
|
|
|
}
|
|
|
|
|
2020-12-31 16:43:54 -05:00
|
|
|
async fn op_emit(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: Rc<RefCell<OpState>>,
|
2021-10-05 16:38:27 -04:00
|
|
|
args: EmitArgs,
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-10-05 16:38:27 -04:00
|
|
|
) -> Result<EmitResult, AnyError> {
|
2020-12-31 16:43:54 -05:00
|
|
|
deno_runtime::ops::check_unstable2(&state, "Deno.emit");
|
2021-01-28 20:33:58 -05:00
|
|
|
let root_specifier = args.root_specifier;
|
2021-09-24 11:10:42 -04:00
|
|
|
let ps = state.borrow().borrow::<ProcState>().clone();
|
2021-04-11 22:15:43 -04:00
|
|
|
let mut runtime_permissions = {
|
2020-09-19 19:17:35 -04:00
|
|
|
let state = state.borrow();
|
|
|
|
state.borrow::<Permissions>().clone()
|
|
|
|
};
|
2020-12-31 16:43:54 -05:00
|
|
|
// when we are actually resolving modules without provided sources, we should
|
|
|
|
// treat the root module as a dynamic import so that runtime permissions are
|
|
|
|
// applied.
|
2020-12-29 23:17:17 -05:00
|
|
|
let handler: Arc<Mutex<dyn SpecifierHandler>> =
|
2020-11-01 21:51:56 -05:00
|
|
|
if let Some(sources) = args.sources {
|
2020-12-29 23:17:17 -05:00
|
|
|
Arc::new(Mutex::new(MemoryHandler::new(sources)))
|
2020-11-01 21:51:56 -05:00
|
|
|
} else {
|
2020-12-29 23:17:17 -05:00
|
|
|
Arc::new(Mutex::new(FetchHandler::new(
|
2021-09-24 11:10:42 -04:00
|
|
|
&ps,
|
2021-02-17 08:32:57 -05:00
|
|
|
runtime_permissions.clone(),
|
2021-05-17 03:44:38 -04:00
|
|
|
runtime_permissions.clone(),
|
2020-11-01 21:51:56 -05:00
|
|
|
)?))
|
|
|
|
};
|
2020-12-31 16:43:54 -05:00
|
|
|
let maybe_import_map = if let Some(import_map_str) = args.import_map_path {
|
2021-02-17 13:47:18 -05:00
|
|
|
let import_map_specifier = resolve_url_or_path(&import_map_str)
|
|
|
|
.context(format!("Bad URL (\"{}\") for import map.", import_map_str))?;
|
2020-12-31 16:43:54 -05:00
|
|
|
let import_map = if let Some(value) = args.import_map {
|
2021-02-17 13:47:18 -05:00
|
|
|
ImportMap::from_json(import_map_specifier.as_str(), &value.to_string())?
|
2020-12-31 16:43:54 -05:00
|
|
|
} else {
|
2021-09-24 11:10:42 -04:00
|
|
|
let file = ps
|
2021-02-17 08:32:57 -05:00
|
|
|
.file_fetcher
|
2021-04-11 22:15:43 -04:00
|
|
|
.fetch(&import_map_specifier, &mut runtime_permissions)
|
2021-05-04 08:27:20 -04:00
|
|
|
.await
|
|
|
|
.map_err(|e| {
|
|
|
|
generic_error(format!(
|
|
|
|
"Unable to load '{}' import map: {}",
|
|
|
|
import_map_specifier, e
|
|
|
|
))
|
|
|
|
})?;
|
2021-02-17 08:32:57 -05:00
|
|
|
ImportMap::from_json(import_map_specifier.as_str(), &file.source)?
|
2020-12-31 16:43:54 -05:00
|
|
|
};
|
|
|
|
Some(import_map)
|
|
|
|
} else if args.import_map.is_some() {
|
|
|
|
return Err(generic_error("An importMap was specified, but no importMapPath was provided, which is required."));
|
2020-08-28 11:08:24 -04:00
|
|
|
} else {
|
2020-12-31 16:43:54 -05:00
|
|
|
None
|
|
|
|
};
|
|
|
|
let mut builder = GraphBuilder::new(handler, maybe_import_map, None);
|
2021-02-17 13:47:18 -05:00
|
|
|
let root_specifier = resolve_url_or_path(&root_specifier)?;
|
2021-05-17 03:44:38 -04:00
|
|
|
builder.add(&root_specifier, false).await.map_err(|_| {
|
|
|
|
type_error(format!(
|
|
|
|
"Unable to handle the given specifier: {}",
|
|
|
|
&root_specifier
|
|
|
|
))
|
|
|
|
})?;
|
2021-06-21 17:18:32 -04:00
|
|
|
builder
|
|
|
|
.analyze_compiler_options(&args.compiler_options)
|
|
|
|
.await?;
|
2020-12-31 16:43:54 -05:00
|
|
|
let bundle_type = match args.bundle {
|
2021-04-25 16:54:57 -04:00
|
|
|
Some(RuntimeBundleType::Module) => BundleType::Module,
|
|
|
|
Some(RuntimeBundleType::Classic) => BundleType::Classic,
|
2021-02-15 20:02:00 -05:00
|
|
|
None => BundleType::None,
|
2020-08-28 11:08:24 -04:00
|
|
|
};
|
2020-12-31 16:43:54 -05:00
|
|
|
let graph = builder.get_graph();
|
2021-09-24 11:10:42 -04:00
|
|
|
let debug = ps.flags.log_level == Some(log::Level::Debug);
|
2021-06-21 17:27:32 -04:00
|
|
|
let graph_errors = graph.get_errors();
|
|
|
|
let (files, mut result_info) = graph.emit(EmitOptions {
|
2020-11-01 21:51:56 -05:00
|
|
|
bundle_type,
|
2020-12-31 16:43:54 -05:00
|
|
|
check: args.check.unwrap_or(true),
|
2020-11-01 21:51:56 -05:00
|
|
|
debug,
|
2020-12-31 16:43:54 -05:00
|
|
|
maybe_user_config: args.compiler_options,
|
2020-11-01 21:51:56 -05:00
|
|
|
})?;
|
2021-06-21 17:27:32 -04:00
|
|
|
result_info.diagnostics.extend_graph_errors(graph_errors);
|
2020-11-01 21:51:56 -05:00
|
|
|
|
2021-10-05 16:38:27 -04:00
|
|
|
Ok(EmitResult {
|
|
|
|
diagnostics: result_info.diagnostics,
|
|
|
|
files,
|
|
|
|
ignored_options: result_info.maybe_ignored_options,
|
|
|
|
stats: result_info.stats,
|
|
|
|
})
|
2020-01-21 11:50:06 -05:00
|
|
|
}
|