summaryrefslogtreecommitdiff
path: root/cli/tsc
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tsc')
-rw-r--r--cli/tsc/99_main_compiler.js105
-rw-r--r--cli/tsc/diagnostics.rs2
-rw-r--r--cli/tsc/dts/lib.deno.ns.d.ts44
-rw-r--r--cli/tsc/dts/lib.deno.unstable.d.ts93
-rw-r--r--cli/tsc/mod.rs221
5 files changed, 335 insertions, 130 deletions
diff --git a/cli/tsc/99_main_compiler.js b/cli/tsc/99_main_compiler.js
index 719f2b982..68d099253 100644
--- a/cli/tsc/99_main_compiler.js
+++ b/cli/tsc/99_main_compiler.js
@@ -121,8 +121,8 @@ delete Object.prototype.__proto__;
/** @type {Map<string, ts.SourceFile>} */
const sourceFileCache = new Map();
- /** @type {Map<string, string>} */
- const sourceTextCache = new Map();
+ /** @type {Map<string, ts.IScriptSnapshot & { isCjs?: boolean; }>} */
+ const scriptSnapshotCache = new Map();
/** @type {Map<string, number>} */
const sourceRefCounts = new Map();
@@ -133,9 +133,6 @@ delete Object.prototype.__proto__;
/** @type {Map<string, boolean>} */
const isNodeSourceFileCache = new Map();
- /** @type {Map<string, boolean>} */
- const isCjsCache = new Map();
-
// Maps asset specifiers to the first scope that the asset was loaded into.
/** @type {Map<string, string | null>} */
const assetScopes = new Map();
@@ -210,12 +207,13 @@ delete Object.prototype.__proto__;
const mapKey = path + key;
let sourceFile = documentRegistrySourceFileCache.get(mapKey);
if (!sourceFile || sourceFile.version !== version) {
+ const isCjs = /** @type {any} */ (scriptSnapshot).isCjs;
sourceFile = ts.createLanguageServiceSourceFile(
fileName,
scriptSnapshot,
{
...getCreateSourceFileOptions(sourceFileOptions),
- impliedNodeFormat: (isCjsCache.get(fileName) ?? false)
+ impliedNodeFormat: isCjs
? ts.ModuleKind.CommonJS
: ts.ModuleKind.ESNext,
// in the lsp we want to be able to show documentation
@@ -320,7 +318,7 @@ delete Object.prototype.__proto__;
if (lastRequestMethod != "cleanupSemanticCache") {
const mapKey = path + key;
documentRegistrySourceFileCache.delete(mapKey);
- sourceTextCache.delete(path);
+ scriptSnapshotCache.delete(path);
ops.op_release(path);
}
} else {
@@ -516,7 +514,6 @@ delete Object.prototype.__proto__;
/** @typedef {{
* ls: ts.LanguageService & { [k:string]: any },
* compilerOptions: ts.CompilerOptions,
- * forceEnabledVerbatimModuleSyntax: boolean,
* }} LanguageServiceEntry */
/** @type {{ unscoped: LanguageServiceEntry, byScope: Map<string, LanguageServiceEntry> }} */
const languageServiceEntries = {
@@ -625,8 +622,6 @@ delete Object.prototype.__proto__;
`"data" is unexpectedly null for "${specifier}".`,
);
- isCjsCache.set(specifier, isCjs);
-
sourceFile = ts.createSourceFile(
specifier,
data,
@@ -700,7 +695,7 @@ delete Object.prototype.__proto__;
/** @type {[string, ts.Extension] | undefined} */
const resolved = ops.op_resolve(
containingFilePath,
- isCjsCache.get(containingFilePath) ?? false,
+ containingFileMode === ts.ModuleKind.CommonJS,
[fileReference.fileName],
)?.[0];
if (resolved) {
@@ -724,7 +719,14 @@ delete Object.prototype.__proto__;
}
});
},
- resolveModuleNames(specifiers, base) {
+ resolveModuleNames(
+ specifiers,
+ base,
+ _reusedNames,
+ _redirectedReference,
+ _options,
+ containingSourceFile,
+ ) {
if (logDebug) {
debug(`host.resolveModuleNames()`);
debug(` base: ${base}`);
@@ -733,7 +735,7 @@ delete Object.prototype.__proto__;
/** @type {Array<[string, ts.Extension] | undefined>} */
const resolved = ops.op_resolve(
base,
- isCjsCache.get(base) ?? false,
+ containingSourceFile?.impliedNodeFormat === ts.ModuleKind.CommonJS,
specifiers,
);
if (resolved) {
@@ -802,27 +804,32 @@ delete Object.prototype.__proto__;
if (logDebug) {
debug(`host.getScriptSnapshot("${specifier}")`);
}
- const sourceFile = sourceFileCache.get(specifier);
- if (sourceFile) {
- if (!assetScopes.has(specifier)) {
- assetScopes.set(specifier, lastRequestScope);
+ if (specifier.startsWith(ASSETS_URL_PREFIX)) {
+ const sourceFile = this.getSourceFile(
+ specifier,
+ ts.ScriptTarget.ESNext,
+ );
+ if (sourceFile) {
+ if (!assetScopes.has(specifier)) {
+ assetScopes.set(specifier, lastRequestScope);
+ }
+ // This case only occurs for assets.
+ return ts.ScriptSnapshot.fromString(sourceFile.text);
}
- // This case only occurs for assets.
- return ts.ScriptSnapshot.fromString(sourceFile.text);
}
- let sourceText = sourceTextCache.get(specifier);
- if (sourceText == undefined) {
+ let scriptSnapshot = scriptSnapshotCache.get(specifier);
+ if (scriptSnapshot == undefined) {
/** @type {{ data: string, version: string, isCjs: boolean }} */
const fileInfo = ops.op_load(specifier);
if (!fileInfo) {
return undefined;
}
- isCjsCache.set(specifier, fileInfo.isCjs);
- sourceTextCache.set(specifier, fileInfo.data);
+ scriptSnapshot = ts.ScriptSnapshot.fromString(fileInfo.data);
+ scriptSnapshot.isCjs = fileInfo.isCjs;
+ scriptSnapshotCache.set(specifier, scriptSnapshot);
scriptVersionCache.set(specifier, fileInfo.version);
- sourceText = fileInfo.data;
}
- return ts.ScriptSnapshot.fromString(sourceText);
+ return scriptSnapshot;
},
};
@@ -846,6 +853,8 @@ delete Object.prototype.__proto__;
jqueryMessage,
"Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592":
jqueryMessage,
+ "Module_0_was_resolved_to_1_but_allowArbitraryExtensions_is_not_set_6263":
+ "Module '{0}' was resolved to '{1}', but importing these modules is not supported.",
};
})());
@@ -1026,7 +1035,7 @@ delete Object.prototype.__proto__;
: ts.sortAndDeduplicateDiagnostics(
checkFiles.map((s) => program.getSemanticDiagnostics(s)).flat(),
)),
- ].filter(filterMapDiagnostic.bind(null, false));
+ ].filter(filterMapDiagnostic);
// emit the tsbuildinfo file
// @ts-ignore: emitBuildInfo is not exposed (https://github.com/microsoft/TypeScript/issues/49871)
@@ -1041,28 +1050,11 @@ delete Object.prototype.__proto__;
debug("<<< exec stop");
}
- /**
- * @param {boolean} isLsp
- * @param {ts.Diagnostic} diagnostic
- */
- function filterMapDiagnostic(isLsp, diagnostic) {
+ /** @param {ts.Diagnostic} diagnostic */
+ function filterMapDiagnostic(diagnostic) {
if (IGNORED_DIAGNOSTICS.includes(diagnostic.code)) {
return false;
}
- if (isLsp) {
- // TS1484: `...` is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled.
- // We force-enable `verbatimModuleSyntax` in the LSP so the `type`
- // modifier is used when auto-importing types. But we don't want this
- // diagnostic unless it was explicitly enabled by the user.
- if (diagnostic.code == 1484) {
- const entry = (lastRequestScope
- ? languageServiceEntries.byScope.get(lastRequestScope)
- : null) ?? languageServiceEntries.unscoped;
- if (entry.forceEnabledVerbatimModuleSyntax) {
- return false;
- }
- }
- }
// make the diagnostic for using an `export =` in an es module a warning
if (diagnostic.code === 1203) {
diagnostic.category = ts.DiagnosticCategory.Warning;
@@ -1159,12 +1151,10 @@ delete Object.prototype.__proto__;
"strict": true,
"target": "esnext",
"useDefineForClassFields": true,
- "verbatimModuleSyntax": true,
"jsx": "react",
"jsxFactory": "React.createElement",
"jsxFragmentFactory": "React.Fragment",
}),
- forceEnabledVerbatimModuleSyntax: true,
};
setLogDebug(enableDebugLogging, "TSLS");
debug("serverInit()");
@@ -1230,17 +1220,8 @@ delete Object.prototype.__proto__;
const ls = oldEntry
? oldEntry.ls
: ts.createLanguageService(host, documentRegistry);
- let forceEnabledVerbatimModuleSyntax = false;
- if (!config["verbatimModuleSyntax"]) {
- config["verbatimModuleSyntax"] = true;
- forceEnabledVerbatimModuleSyntax = true;
- }
const compilerOptions = lspTsConfigToCompilerOptions(config);
- newByScope.set(scope, {
- ls,
- compilerOptions,
- forceEnabledVerbatimModuleSyntax,
- });
+ newByScope.set(scope, { ls, compilerOptions });
languageServiceEntries.byScope.delete(scope);
}
for (const oldEntry of languageServiceEntries.byScope.values()) {
@@ -1260,7 +1241,7 @@ delete Object.prototype.__proto__;
closed = true;
}
scriptVersionCache.delete(script);
- sourceTextCache.delete(script);
+ scriptSnapshotCache.delete(script);
}
if (newConfigsByScope || opened || closed) {
@@ -1305,7 +1286,7 @@ delete Object.prototype.__proto__;
...ls.getSemanticDiagnostics(specifier),
...ls.getSuggestionDiagnostics(specifier),
...ls.getSyntacticDiagnostics(specifier),
- ].filter(filterMapDiagnostic.bind(null, true)));
+ ].filter(filterMapDiagnostic));
}
return respond(id, diagnosticMap);
} catch (e) {
@@ -1366,18 +1347,12 @@ delete Object.prototype.__proto__;
"console",
"Console",
"ErrorConstructor",
- "exports",
"gc",
"Global",
"ImportMeta",
"localStorage",
- "module",
- "NodeModule",
- "NodeRequire",
- "process",
"queueMicrotask",
"RequestInit",
- "require",
"ResponseInit",
"sessionStorage",
"setImmediate",
diff --git a/cli/tsc/diagnostics.rs b/cli/tsc/diagnostics.rs
index b0394ec17..d3795706e 100644
--- a/cli/tsc/diagnostics.rs
+++ b/cli/tsc/diagnostics.rs
@@ -323,7 +323,7 @@ impl Diagnostics {
// todo(dsherret): use a short lived cache to prevent parsing
// source maps so often
if let Ok(source_map) =
- SourceMap::from_slice(&fast_check_module.source_map)
+ SourceMap::from_slice(fast_check_module.source_map.as_bytes())
{
if let Some(start) = d.start.as_mut() {
let maybe_token = source_map
diff --git a/cli/tsc/dts/lib.deno.ns.d.ts b/cli/tsc/dts/lib.deno.ns.d.ts
index 36592e10d..8179e4223 100644
--- a/cli/tsc/dts/lib.deno.ns.d.ts
+++ b/cli/tsc/dts/lib.deno.ns.d.ts
@@ -556,14 +556,23 @@ declare namespace Deno {
*/
env?: "inherit" | boolean | string[];
- /** Specifies if the `sys` permission should be requested or revoked.
- * If set to `"inherit"`, the current `sys` permission will be inherited.
- * If set to `true`, the global `sys` permission will be requested.
- * If set to `false`, the global `sys` permission will be revoked.
+ /** Specifies if the `ffi` permission should be requested or revoked.
+ * If set to `"inherit"`, the current `ffi` permission will be inherited.
+ * If set to `true`, the global `ffi` permission will be requested.
+ * If set to `false`, the global `ffi` permission will be revoked.
*
* @default {false}
*/
- sys?: "inherit" | boolean | string[];
+ ffi?: "inherit" | boolean | Array<string | URL>;
+
+ /** Specifies if the `import` permission should be requested or revoked.
+ * If set to `"inherit"` the current `import` permission will be inherited.
+ * If set to `true`, the global `import` permission will be requested.
+ * If set to `false`, the global `import` permission will be revoked.
+ * If set to `Array<string>`, the `import` permissions will be requested with the
+ * specified domains.
+ */
+ import?: "inherit" | boolean | Array<string>;
/** Specifies if the `net` permission should be requested or revoked.
* if set to `"inherit"`, the current `net` permission will be inherited.
@@ -638,15 +647,6 @@ declare namespace Deno {
*/
net?: "inherit" | boolean | string[];
- /** Specifies if the `ffi` permission should be requested or revoked.
- * If set to `"inherit"`, the current `ffi` permission will be inherited.
- * If set to `true`, the global `ffi` permission will be requested.
- * If set to `false`, the global `ffi` permission will be revoked.
- *
- * @default {false}
- */
- ffi?: "inherit" | boolean | Array<string | URL>;
-
/** Specifies if the `read` permission should be requested or revoked.
* If set to `"inherit"`, the current `read` permission will be inherited.
* If set to `true`, the global `read` permission will be requested.
@@ -667,6 +667,15 @@ declare namespace Deno {
*/
run?: "inherit" | boolean | Array<string | URL>;
+ /** Specifies if the `sys` permission should be requested or revoked.
+ * If set to `"inherit"`, the current `sys` permission will be inherited.
+ * If set to `true`, the global `sys` permission will be requested.
+ * If set to `false`, the global `sys` permission will be revoked.
+ *
+ * @default {false}
+ */
+ sys?: "inherit" | boolean | string[];
+
/** Specifies if the `write` permission should be requested or revoked.
* If set to `"inherit"`, the current `write` permission will be inherited.
* If set to `true`, the global `write` permission will be requested.
@@ -2962,6 +2971,10 @@ declare namespace Deno {
* field from `stat` on Mac/BSD and `ftCreationTime` on Windows. This may
* not be available on all platforms. */
birthtime: Date | null;
+ /** The last change time of the file. This corresponds to the `ctime`
+ * field from `stat` on Mac/BSD and `ChangeTime` on Windows. This may
+ * not be available on all platforms. */
+ ctime: Date | null;
/** ID of the device containing the file. */
dev: number;
/** Inode number.
@@ -2970,8 +2983,7 @@ declare namespace Deno {
ino: number | null;
/** The underlying raw `st_mode` bits that contain the standard Unix
* permissions for this file/directory.
- *
- * _Linux/Mac OS only._ */
+ */
mode: number | null;
/** Number of hard links pointing to this file.
*
diff --git a/cli/tsc/dts/lib.deno.unstable.d.ts b/cli/tsc/dts/lib.deno.unstable.d.ts
index 973a09d92..6759856e6 100644
--- a/cli/tsc/dts/lib.deno.unstable.d.ts
+++ b/cli/tsc/dts/lib.deno.unstable.d.ts
@@ -1181,6 +1181,32 @@ declare namespace Deno {
): Displayable;
/**
+ * Display a JPG or PNG image.
+ *
+ * ```
+ * Deno.jupyter.image("./cat.jpg");
+ * Deno.jupyter.image("./dog.png");
+ * ```
+ *
+ * @category Jupyter
+ * @experimental
+ */
+ export function image(path: string): Displayable;
+
+ /**
+ * Display a JPG or PNG image.
+ *
+ * ```
+ * const img = Deno.readFileSync("./cat.jpg");
+ * Deno.jupyter.image(img);
+ * ```
+ *
+ * @category Jupyter
+ * @experimental
+ */
+ export function image(data: Uint8Array): Displayable;
+
+ /**
* Format an object for displaying in Deno
*
* @param obj - The object to be displayed
@@ -1225,6 +1251,73 @@ declare namespace Deno {
export {}; // only export exports
}
+ /**
+ * **UNSTABLE**: New API, yet to be vetted.
+ *
+ * APIs for working with the OpenTelemetry observability framework. Deno can
+ * export traces, metrics, and logs to OpenTelemetry compatible backends via
+ * the OTLP protocol.
+ *
+ * Deno automatically instruments the runtime with OpenTelemetry traces and
+ * metrics. This data is exported via OTLP to OpenTelemetry compatible
+ * backends. User logs from the `console` API are exported as OpenTelemetry
+ * logs via OTLP.
+ *
+ * User code can also create custom traces, metrics, and logs using the
+ * OpenTelemetry API. This is done using the official OpenTelemetry package
+ * for JavaScript:
+ * [`npm:@opentelemetry/api`](https://opentelemetry.io/docs/languages/js/).
+ * Deno integrates with this package to provide trace context propagation
+ * between native Deno APIs (like `Deno.serve` or `fetch`) and custom user
+ * code. Deno also provides APIs that allow exporting custom telemetry data
+ * via the same OTLP channel used by the Deno runtime. This is done using the
+ * [`jsr:@deno/otel`](https://jsr.io/@deno/otel) package.
+ *
+ * @example Using OpenTelemetry API to create custom traces
+ * ```ts,ignore
+ * import { trace } from "npm:@opentelemetry/api@1";
+ * import "jsr:@deno/otel@0.0.2/register";
+ *
+ * const tracer = trace.getTracer("example-tracer");
+ *
+ * async function doWork() {
+ * return tracer.startActiveSpan("doWork", async (span) => {
+ * span.setAttribute("key", "value");
+ * await new Promise((resolve) => setTimeout(resolve, 1000));
+ * span.end();
+ * });
+ * }
+ *
+ * Deno.serve(async (req) => {
+ * await doWork();
+ * const resp = await fetch("https://example.com");
+ * return resp;
+ * });
+ * ```
+ *
+ * @category Telemetry
+ * @experimental
+ */
+ export namespace telemetry {
+ /**
+ * A SpanExporter compatible with OpenTelemetry.js
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_sdk_trace_base.SpanExporter.html
+ * @category Telemetry
+ * @experimental
+ */
+ export class SpanExporter {}
+
+ /**
+ * A ContextManager compatible with OpenTelemetry.js
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api.ContextManager.html
+ * @category Telemetry
+ * @experimental
+ */
+ export class ContextManager {}
+
+ export {}; // only export exports
+ }
+
export {}; // only export exports
}
diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs
index 0e3387494..8f8bed20a 100644
--- a/cli/tsc/mod.rs
+++ b/cli/tsc/mod.rs
@@ -3,10 +3,13 @@
use crate::args::TsConfig;
use crate::args::TypeCheckMode;
use crate::cache::FastInsecureHasher;
+use crate::cache::ModuleInfoCache;
use crate::node;
use crate::npm::CliNpmResolver;
+use crate::resolver::CjsTracker;
use crate::util::checksum;
use crate::util::path::mapped_specifier_for_tsc;
+use crate::worker::create_isolate_create_params;
use deno_ast::MediaType;
use deno_core::anyhow::anyhow;
@@ -31,12 +34,14 @@ use deno_graph::GraphKind;
use deno_graph::Module;
use deno_graph::ModuleGraph;
use deno_graph::ResolutionResolved;
+use deno_resolver::npm::ResolvePkgFolderFromDenoReqError;
+use deno_runtime::deno_fs;
use deno_runtime::deno_node::NodeResolver;
use deno_semver::npm::NpmPackageReqReference;
use node_resolver::errors::NodeJsErrorCode;
use node_resolver::errors::NodeJsErrorCoded;
+use node_resolver::errors::PackageSubpathResolveError;
use node_resolver::NodeModuleKind;
-use node_resolver::NodeResolution;
use node_resolver::NodeResolutionMode;
use once_cell::sync::Lazy;
use std::borrow::Cow;
@@ -45,6 +50,7 @@ use std::fmt;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
+use thiserror::Error;
mod diagnostics;
@@ -299,8 +305,81 @@ pub struct EmittedFile {
pub media_type: MediaType,
}
+pub fn into_specifier_and_media_type(
+ specifier: Option<ModuleSpecifier>,
+) -> (ModuleSpecifier, MediaType) {
+ match specifier {
+ Some(specifier) => {
+ let media_type = MediaType::from_specifier(&specifier);
+
+ (specifier, media_type)
+ }
+ None => (
+ Url::parse("internal:///missing_dependency.d.ts").unwrap(),
+ MediaType::Dts,
+ ),
+ }
+}
+
+#[derive(Debug)]
+pub struct TypeCheckingCjsTracker {
+ cjs_tracker: Arc<CjsTracker>,
+ module_info_cache: Arc<ModuleInfoCache>,
+}
+
+impl TypeCheckingCjsTracker {
+ pub fn new(
+ cjs_tracker: Arc<CjsTracker>,
+ module_info_cache: Arc<ModuleInfoCache>,
+ ) -> Self {
+ Self {
+ cjs_tracker,
+ module_info_cache,
+ }
+ }
+
+ pub fn is_cjs(
+ &self,
+ specifier: &ModuleSpecifier,
+ media_type: MediaType,
+ code: &Arc<str>,
+ ) -> bool {
+ let maybe_is_script = self
+ .module_info_cache
+ .as_module_analyzer()
+ .analyze_sync(specifier, media_type, code)
+ .ok()
+ .map(|info| info.is_script);
+ maybe_is_script
+ .and_then(|is_script| {
+ self
+ .cjs_tracker
+ .is_cjs_with_known_is_script(specifier, media_type, is_script)
+ .ok()
+ })
+ .unwrap_or_else(|| {
+ self
+ .cjs_tracker
+ .is_maybe_cjs(specifier, media_type)
+ .unwrap_or(false)
+ })
+ }
+
+ pub fn is_cjs_with_known_is_script(
+ &self,
+ specifier: &ModuleSpecifier,
+ media_type: MediaType,
+ is_script: bool,
+ ) -> Result<bool, node_resolver::errors::ClosestPkgJsonError> {
+ self
+ .cjs_tracker
+ .is_cjs_with_known_is_script(specifier, media_type, is_script)
+ }
+}
+
#[derive(Debug)]
pub struct RequestNpmState {
+ pub cjs_tracker: Arc<TypeCheckingCjsTracker>,
pub node_resolver: Arc<NodeResolver>,
pub npm_resolver: Arc<dyn CliNpmResolver>,
}
@@ -453,7 +532,7 @@ pub fn as_ts_script_kind(media_type: MediaType) -> i32 {
MediaType::Tsx => 4,
MediaType::Json => 6,
MediaType::SourceMap
- | MediaType::TsBuildInfo
+ | MediaType::Css
| MediaType::Wasm
| MediaType::Unknown => 0,
}
@@ -486,25 +565,22 @@ fn op_load_inner(
) -> Result<Option<LoadResponse>, AnyError> {
fn load_from_node_modules(
specifier: &ModuleSpecifier,
- node_resolver: Option<&NodeResolver>,
+ npm_state: Option<&RequestNpmState>,
media_type: &mut MediaType,
is_cjs: &mut bool,
) -> Result<String, AnyError> {
*media_type = MediaType::from_specifier(specifier);
- *is_cjs = node_resolver
- .map(|node_resolver| {
- match node_resolver.url_to_node_resolution(specifier.clone()) {
- Ok(NodeResolution::CommonJs(_)) => true,
- Ok(NodeResolution::Esm(_))
- | Ok(NodeResolution::BuiltIn(_))
- | Err(_) => false,
- }
- })
- .unwrap_or(false);
let file_path = specifier.to_file_path().unwrap();
let code = std::fs::read_to_string(&file_path)
.with_context(|| format!("Unable to load {}", file_path.display()))?;
- Ok(code)
+ let code: Arc<str> = code.into();
+ *is_cjs = npm_state
+ .map(|npm_state| {
+ npm_state.cjs_tracker.is_cjs(specifier, *media_type, &code)
+ })
+ .unwrap_or(false);
+ // todo(dsherret): how to avoid cloning here?
+ Ok(code.to_string())
}
let state = state.borrow_mut::<State>();
@@ -557,6 +633,13 @@ fn op_load_inner(
match module {
Module::Js(module) => {
media_type = module.media_type;
+ if let Some(npm_state) = &state.maybe_npm {
+ is_cjs = npm_state.cjs_tracker.is_cjs_with_known_is_script(
+ specifier,
+ module.media_type,
+ module.is_script,
+ )?;
+ }
let source = module
.fast_check_module()
.map(|m| &*m.source)
@@ -570,11 +653,13 @@ fn op_load_inner(
Module::Npm(_) | Module::Node(_) => None,
Module::External(module) => {
// means it's Deno code importing an npm module
- let specifier =
- node::resolve_specifier_into_node_modules(&module.specifier);
+ let specifier = node::resolve_specifier_into_node_modules(
+ &module.specifier,
+ &deno_fs::RealFs,
+ );
Some(Cow::Owned(load_from_node_modules(
&specifier,
- state.maybe_npm.as_ref().map(|n| n.node_resolver.as_ref()),
+ state.maybe_npm.as_ref(),
&mut media_type,
&mut is_cjs,
)?))
@@ -587,7 +672,7 @@ fn op_load_inner(
{
Some(Cow::Owned(load_from_node_modules(
specifier,
- Some(npm.node_resolver.as_ref()),
+ Some(npm),
&mut media_type,
&mut is_cjs,
)?))
@@ -662,6 +747,7 @@ fn op_resolve_inner(
"Error converting a string module specifier for \"op_resolve\".",
)?
};
+ let referrer_module = state.graph.get(&referrer);
for specifier in args.specifiers {
if specifier.starts_with("node:") {
resolved.push((
@@ -677,23 +763,44 @@ fn op_resolve_inner(
continue;
}
- let graph = &state.graph;
- let resolved_dep = graph
- .get(&referrer)
+ let resolved_dep = referrer_module
.and_then(|m| m.js())
.and_then(|m| m.dependencies_prefer_fast_check().get(&specifier))
.and_then(|d| d.maybe_type.ok().or_else(|| d.maybe_code.ok()));
let maybe_result = match resolved_dep {
Some(ResolutionResolved { specifier, .. }) => {
- resolve_graph_specifier_types(specifier, &referrer, state)?
+ resolve_graph_specifier_types(
+ specifier,
+ &referrer,
+ referrer_kind,
+ state,
+ )?
+ }
+ _ => {
+ match resolve_non_graph_specifier_types(
+ &specifier,
+ &referrer,
+ referrer_kind,
+ state,
+ ) {
+ Ok(maybe_result) => maybe_result,
+ Err(
+ err @ ResolveNonGraphSpecifierTypesError::ResolvePkgFolderFromDenoReq(
+ ResolvePkgFolderFromDenoReqError::Managed(_),
+ ),
+ ) => {
+ // it's most likely requesting the jsxImportSource, which isn't loaded
+ // into the graph when not using jsx, so just ignore this error
+ if specifier.ends_with("/jsx-runtime") {
+ None
+ } else {
+ return Err(err.into());
+ }
+ }
+ Err(err) => return Err(err.into()),
+ }
}
- _ => resolve_non_graph_specifier_types(
- &specifier,
- &referrer,
- referrer_kind,
- state,
- )?,
};
let result = match maybe_result {
Some((specifier, media_type)) => {
@@ -718,7 +825,13 @@ fn op_resolve_inner(
}
}
};
- (specifier_str, media_type.as_ts_extension())
+ (
+ specifier_str,
+ match media_type {
+ MediaType::Css => ".js", // surface these as .js for typescript
+ media_type => media_type.as_ts_extension(),
+ },
+ )
}
None => (
MISSING_DEPENDENCY_SPECIFIER.to_string(),
@@ -735,6 +848,7 @@ fn op_resolve_inner(
fn resolve_graph_specifier_types(
specifier: &ModuleSpecifier,
referrer: &ModuleSpecifier,
+ referrer_kind: NodeModuleKind,
state: &State,
) -> Result<Option<(ModuleSpecifier, MediaType)>, AnyError> {
let graph = &state.graph;
@@ -787,43 +901,53 @@ fn resolve_graph_specifier_types(
&package_folder,
module.nv_reference.sub_path(),
Some(referrer),
+ referrer_kind,
NodeResolutionMode::Types,
);
- let maybe_resolution = match res_result {
- Ok(res) => Some(res),
+ let maybe_url = match res_result {
+ Ok(url) => Some(url),
Err(err) => match err.code() {
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
_ => return Err(err.into()),
},
};
- Ok(Some(NodeResolution::into_specifier_and_media_type(
- maybe_resolution,
- )))
+ Ok(Some(into_specifier_and_media_type(maybe_url)))
} else {
Ok(None)
}
}
Some(Module::External(module)) => {
// we currently only use "External" for when the module is in an npm package
- Ok(state.maybe_npm.as_ref().map(|npm| {
- let specifier =
- node::resolve_specifier_into_node_modules(&module.specifier);
- NodeResolution::into_specifier_and_media_type(
- npm.node_resolver.url_to_node_resolution(specifier).ok(),
- )
+ Ok(state.maybe_npm.as_ref().map(|_| {
+ let specifier = node::resolve_specifier_into_node_modules(
+ &module.specifier,
+ &deno_fs::RealFs,
+ );
+ into_specifier_and_media_type(Some(specifier))
}))
}
Some(Module::Node(_)) | None => Ok(None),
}
}
+#[derive(Debug, Error)]
+enum ResolveNonGraphSpecifierTypesError {
+ #[error(transparent)]
+ ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
+ #[error(transparent)]
+ PackageSubpathResolve(#[from] PackageSubpathResolveError),
+}
+
fn resolve_non_graph_specifier_types(
raw_specifier: &str,
referrer: &ModuleSpecifier,
referrer_kind: NodeModuleKind,
state: &State,
-) -> Result<Option<(ModuleSpecifier, MediaType)>, AnyError> {
+) -> Result<
+ Option<(ModuleSpecifier, MediaType)>,
+ ResolveNonGraphSpecifierTypesError,
+> {
let npm = match state.maybe_npm.as_ref() {
Some(npm) => npm,
None => return Ok(None), // we only support non-graph types for npm packages
@@ -831,7 +955,7 @@ fn resolve_non_graph_specifier_types(
let node_resolver = &npm.node_resolver;
if node_resolver.in_npm_package(referrer) {
// we're in an npm package, so use node resolution
- Ok(Some(NodeResolution::into_specifier_and_media_type(
+ Ok(Some(into_specifier_and_media_type(
node_resolver
.resolve(
raw_specifier,
@@ -839,7 +963,8 @@ fn resolve_non_graph_specifier_types(
referrer_kind,
NodeResolutionMode::Types,
)
- .ok(),
+ .ok()
+ .map(|res| res.into_url()),
)))
} else if let Ok(npm_req_ref) =
NpmPackageReqReference::from_str(raw_specifier)
@@ -856,19 +981,18 @@ fn resolve_non_graph_specifier_types(
&package_folder,
npm_req_ref.sub_path(),
Some(referrer),
+ referrer_kind,
NodeResolutionMode::Types,
);
- let maybe_resolution = match res_result {
- Ok(res) => Some(res),
+ let maybe_url = match res_result {
+ Ok(url) => Some(url),
Err(err) => match err.code() {
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
_ => return Err(err.into()),
},
};
- Ok(Some(NodeResolution::into_specifier_and_media_type(
- maybe_resolution,
- )))
+ Ok(Some(into_specifier_and_media_type(maybe_url)))
} else {
Ok(None)
}
@@ -981,6 +1105,7 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
root_map,
remapped_specifiers,
)],
+ create_params: create_isolate_create_params(),
..Default::default()
});