Skip to content

Commit 5758f3b

Browse files
authored
fix(base): checking more strictly whether source map inlining is possible (#458)
* chore(base): add a dependency * chore: update `Cargo.lock` * fix(base): checking more strictly whether source map inlining is possible * stamp: support specifying from the user context whether the source map is applied * chore: add an integration test for issue #456
1 parent 7172c87 commit 5758f3b

File tree

7 files changed

+75
-22
lines changed

7 files changed

+75
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/base/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ reqwest_v011.workspace = true
8080
tracing-subscriber = { workspace = true, optional = true, features = ["env-filter", "tracing-log"] }
8181
num-traits.workspace = true
8282
tempfile.workspace = true
83+
either.workspace = true
8384

8485
tls-listener = { version = "0.10", features = ["rustls"] }
8586
strum = { version = "0.25", features = ["derive"] }

crates/base/src/deno_runtime.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ where
377377
let is_user_worker = conf.is_user_worker();
378378
let is_some_entry_point = maybe_entrypoint.is_some();
379379

380+
let maybe_user_conf = conf.as_user_worker();
381+
let user_context = maybe_user_conf
382+
.and_then(|it| it.context.clone())
383+
.unwrap_or_default();
384+
380385
if is_some_entry_point {
381386
main_module_url = Url::parse(&maybe_entrypoint.unwrap())?;
382387
}
@@ -386,7 +391,7 @@ where
386391
let mut allow_remote_modules = true;
387392

388393
if is_user_worker {
389-
let user_conf = conf.as_user_worker().unwrap();
394+
let user_conf = maybe_user_conf.unwrap();
390395

391396
net_access_disabled = user_conf.net_access_disabled;
392397
allow_remote_modules = user_conf.allow_remote_modules;
@@ -514,12 +519,17 @@ where
514519
}
515520

516521
let has_inspector = maybe_inspector.is_some();
522+
let need_source_map = user_context
523+
.get("sourceMap")
524+
.and_then(serde_json::Value::as_bool)
525+
.unwrap_or_default();
526+
517527
let rt_provider = create_module_loader_for_standalone_from_eszip_kind(
518528
eszip,
519529
base_dir_path.clone(),
520530
maybe_import_map,
521531
import_map_path,
522-
has_inspector,
532+
has_inspector || need_source_map,
523533
)
524534
.await?;
525535

@@ -645,7 +655,7 @@ where
645655
let beforeunload_mem_threshold = ArcSwapOption::<u64>::from_pointee(None);
646656

647657
if conf.is_user_worker() {
648-
let conf = conf.as_user_worker().unwrap();
658+
let conf = maybe_user_conf.unwrap();
649659
let memory_limit_bytes = mib_to_bytes(conf.memory_limit_mb) as usize;
650660

651661
beforeunload_mem_threshold.store(
@@ -792,14 +802,7 @@ where
792802
let extra_context = {
793803
let mut context = serde_json::json!(RuntimeContext::get_extra_context());
794804

795-
json::merge_object(
796-
&mut context,
797-
&conf
798-
.as_user_worker()
799-
.and_then(|it| it.context.clone())
800-
.map(serde_json::Value::Object)
801-
.unwrap_or_else(|| serde_json::json!({})),
802-
);
805+
json::merge_object(&mut context, &serde_json::Value::Object(user_context));
803806

804807
context
805808
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { STATUS_CODE } from "jsr:@std/http";
2+
console.log(STATUS_CODE.Accepted);
3+
4+
export default {
5+
fetch() {
6+
return new Response("meow");
7+
}
8+
}

crates/base/test_cases/main/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ Deno.serve((req: Request) => {
4141
const importMapPath = null;
4242
const envVarsObj = Deno.env.toObject();
4343
const envVars = Object.keys(envVarsObj).map(k => [k, envVarsObj[k]]);
44+
const context = {
45+
sourceMap: req.headers.get("x-context-source-map") == "true"
46+
};
4447

4548
return await EdgeRuntime.userWorkers.create({
4649
servicePath,
@@ -50,7 +53,8 @@ Deno.serve((req: Request) => {
5053
cpuTimeHardLimitMs,
5154
noModuleCache,
5255
importMapPath,
53-
envVars
56+
envVars,
57+
context
5458
});
5559
}
5660

crates/base/tests/integration_tests.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,24 @@ async fn test_issue_420() {
23512351
);
23522352
}
23532353

2354+
#[tokio::test]
2355+
#[serial]
2356+
async fn test_issue_456() {
2357+
let tb = TestBedBuilder::new("./test_cases/main").build().await;
2358+
let resp = tb
2359+
.request(|b| {
2360+
b.uri("/issue-456")
2361+
.header("x-context-source-map", "true")
2362+
.body(Body::empty())
2363+
.context("can't make request")
2364+
})
2365+
.await
2366+
.unwrap();
2367+
2368+
assert_eq!(resp.status().as_u16(), StatusCode::OK);
2369+
tb.exit(Duration::from_secs(TESTBED_DEADLINE_SEC)).await;
2370+
}
2371+
23542372
#[tokio::test]
23552373
#[serial]
23562374
async fn test_should_render_detailed_failed_to_create_graph_error() {

crates/sb_module_loader/standalone/standalone_module_loader.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use deno_core::{ModuleSpecifier, RequestedModuleType};
1616
use deno_semver::npm::NpmPackageReqReference;
1717
use eszip::deno_graph;
1818
use eszip::EszipRelativeFileBaseUrl;
19+
use eszip::ModuleKind;
1920
use sb_eszip_shared::AsyncEszipDataRead;
2021
use sb_graph::resolver::CliNodeResolver;
2122
use sb_graph::resolver::NpmModuleLoader;
@@ -41,14 +42,17 @@ impl WorkspaceEszip {
4142
if specifier.scheme() == "file" {
4243
let specifier_key =
4344
EszipRelativeFileBaseUrl::new(&self.root_dir_url).specifier_key(specifier);
45+
4446
let module = self.eszip.ensure_module(&specifier_key)?;
4547
let specifier = self.root_dir_url.join(&module.specifier).unwrap();
48+
4649
Some(WorkspaceEszipModule {
4750
specifier,
4851
inner: module,
4952
})
5053
} else {
5154
let module = self.eszip.ensure_module(specifier.as_str())?;
55+
5256
Some(WorkspaceEszipModule {
5357
specifier: ModuleSpecifier::parse(&module.specifier).unwrap(),
5458
inner: module,
@@ -85,6 +89,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
8589
kind
8690
)));
8791
}
92+
8893
let current_dir = std::env::current_dir().unwrap();
8994
deno_core::resolve_path(".", &current_dir)?
9095
} else {
@@ -122,11 +127,13 @@ impl ModuleLoader for EmbeddedModuleLoader {
122127
NodeResolutionMode::Execution,
123128
)
124129
.map(|res| res.into_url()),
130+
125131
PackageJsonDepValue::Workspace(version_req) => {
126132
let pkg_folder = self
127133
.shared
128134
.workspace_resolver
129135
.resolve_workspace_pkg_json_folder_for_pkg_json_dep(alias, version_req)?;
136+
130137
Ok(self
131138
.shared
132139
.node_resolver
@@ -185,6 +192,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
185192
_requested_module_type: RequestedModuleType,
186193
) -> deno_core::ModuleLoadResponse {
187194
let include_source_map = self.include_source_map;
195+
188196
if original_specifier.scheme() == "data" {
189197
let data_url_text = match deno_graph::source::RawDataUrl::parse(original_specifier)
190198
.and_then(|url| url.decode())
@@ -197,6 +205,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
197205
))));
198206
}
199207
};
208+
200209
return deno_core::ModuleLoadResponse::Sync(Ok(deno_core::ModuleSource::new(
201210
deno_core::ModuleType::JavaScript,
202211
ModuleSourceCode::String(data_url_text.into()),
@@ -209,11 +218,13 @@ impl ModuleLoader for EmbeddedModuleLoader {
209218
let npm_module_loader = self.shared.npm_module_loader.clone();
210219
let original_specifier = original_specifier.clone();
211220
let maybe_referrer = maybe_referrer.cloned();
221+
212222
return deno_core::ModuleLoadResponse::Async(
213223
async move {
214224
let code_source = npm_module_loader
215225
.load(&original_specifier, maybe_referrer.as_ref())
216226
.await?;
227+
217228
Ok(deno_core::ModuleSource::new_with_redirect(
218229
match code_source.media_type {
219230
MediaType::Json => ModuleType::Json,
@@ -243,37 +254,44 @@ impl ModuleLoader for EmbeddedModuleLoader {
243254
let code = module.inner.source().await.ok_or_else(|| {
244255
type_error(format!("Module not found: {}", original_specifier))
245256
})?;
257+
246258
let code = arc_u8_to_arc_str(code)
247259
.map_err(|_| type_error("Module source is not utf-8"))?;
260+
248261
let source_map = module.inner.source_map().await;
249262
let maybe_code_with_source_map = 'scope: {
250-
if !include_source_map {
263+
if !include_source_map || !matches!(module.inner.kind, ModuleKind::JavaScript) {
251264
break 'scope code;
252265
}
253266

254267
let Some(source_map) = source_map else {
255268
break 'scope code;
256269
};
270+
if source_map.is_empty() {
271+
break 'scope code;
272+
}
257273

258274
let mut src = code.to_string();
259275

260-
if src.ends_with('\n') {
276+
if !src.ends_with('\n') {
261277
src.push('\n');
262278
}
263279

264-
src.push_str("//# sourceMappingURL=data:application/json;base64,");
265-
base64::prelude::BASE64_STANDARD.encode_string(source_map, &mut src);
280+
const SOURCE_MAP_PREFIX: &str =
281+
"//# sourceMappingURL=data:application/json;base64,";
266282

283+
src.push_str(SOURCE_MAP_PREFIX);
284+
285+
base64::prelude::BASE64_STANDARD.encode_string(source_map, &mut src);
267286
Arc::from(src)
268287
};
288+
269289
Ok(deno_core::ModuleSource::new_with_redirect(
270290
match module.inner.kind {
271-
eszip::ModuleKind::JavaScript => ModuleType::JavaScript,
272-
eszip::ModuleKind::Json => ModuleType::Json,
273-
eszip::ModuleKind::Jsonc => {
274-
return Err(type_error("jsonc modules not supported"))
275-
}
276-
eszip::ModuleKind::OpaqueData => {
291+
ModuleKind::JavaScript => ModuleType::JavaScript,
292+
ModuleKind::Json => ModuleType::Json,
293+
ModuleKind::Jsonc => return Err(type_error("jsonc modules not supported")),
294+
ModuleKind::OpaqueData => {
277295
unreachable!();
278296
}
279297
},

0 commit comments

Comments
 (0)