• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / edge-runtime / 15218527727

23 May 2025 08:20PM UTC coverage: 49.447% (-2.0%) from 51.44%
15218527727

Pull #543

github

web-flow
Merge 36d428d17 into a1625a929
Pull Request #543: feat: add technical docs

17167 of 34718 relevant lines covered (49.45%)

1637.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.72
/ext/node/ops/require.rs
1
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2

3
use boxed_error::Boxed;
4
use deno_core::error::AnyError;
5
use deno_core::op2;
6
use deno_core::url::Url;
7
use deno_core::v8;
8
use deno_core::JsRuntimeInspector;
9
use deno_core::OpState;
10
use deno_fs::FileSystemRc;
11
use deno_fs::V8MaybeStaticStr;
12
use deno_package_json::PackageJsonRc;
13
use deno_path_util::normalize_path;
14
use deno_path_util::url_from_file_path;
15
use deno_path_util::url_to_file_path;
16
use node_resolver::errors::ClosestPkgJsonError;
17
use node_resolver::NodeResolutionKind;
18
use node_resolver::ResolutionMode;
19
use node_resolver::REQUIRE_CONDITIONS;
20
use std::borrow::Cow;
21
use std::cell::RefCell;
22
use std::path::Path;
23
use std::path::PathBuf;
24
use std::rc::Rc;
25

26
use crate::NodePermissions;
27
use crate::NodeRequireLoaderRc;
28
use crate::NodeResolverRc;
29
use crate::NpmPackageFolderResolverRc;
30
use crate::PackageJsonResolverRc;
31

32
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
33
fn ensure_read_permission<'a, P>(
10,676✔
34
  state: &mut OpState,
10,676✔
35
  file_path: &'a Path,
10,676✔
36
) -> Result<Cow<'a, Path>, deno_core::error::AnyError>
10,676✔
37
where
10,676✔
38
  P: NodePermissions + 'static,
10,676✔
39
{
10,676✔
40
  let loader = state.borrow::<NodeRequireLoaderRc>().clone();
10,676✔
41
  let permissions = state.borrow_mut::<P>();
10,676✔
42
  loader.ensure_read_permission(permissions, file_path)
10,676✔
43
}
10,676✔
44

45
#[derive(Debug, Boxed)]
×
46
pub struct RequireError(pub Box<RequireErrorKind>);
47

48
#[derive(Debug, thiserror::Error)]
49
pub enum RequireErrorKind {
50
  #[error(transparent)]
51
  UrlParse(#[from] url::ParseError),
52
  #[error(transparent)]
53
  Permission(deno_core::error::AnyError),
54
  #[error(transparent)]
55
  PackageExportsResolve(
56
    #[from] node_resolver::errors::PackageExportsResolveError,
57
  ),
58
  #[error(transparent)]
59
  PackageJsonLoad(#[from] node_resolver::errors::PackageJsonLoadError),
60
  #[error(transparent)]
61
  ClosestPkgJson(#[from] node_resolver::errors::ClosestPkgJsonError),
62
  #[error(transparent)]
63
  PackageImportsResolve(
64
    #[from] node_resolver::errors::PackageImportsResolveError,
65
  ),
66
  #[error(transparent)]
67
  FilePathConversion(#[from] deno_path_util::UrlToFilePathError),
68
  #[error(transparent)]
69
  UrlConversion(#[from] deno_path_util::PathToUrlError),
70
  #[error(transparent)]
71
  Fs(#[from] deno_io::fs::FsError),
72
  #[error(transparent)]
73
  ReadModule(deno_core::error::AnyError),
74
  #[error("Unable to get CWD: {0}")]
75
  UnableToGetCwd(deno_io::fs::FsError),
76
}
77

78
#[op2]
274✔
79
#[serde]
80
pub fn op_require_init_paths() -> Vec<String> {
×
81
  // todo(dsherret): this code is node compat mode specific and
×
82
  // we probably don't want it for small mammal, so ignore it for now
×
83

×
84
  // let (home_dir, node_path) = if cfg!(windows) {
×
85
  //   (
×
86
  //     std::env::var("USERPROFILE").unwrap_or_else(|_| "".into()),
×
87
  //     std::env::var("NODE_PATH").unwrap_or_else(|_| "".into()),
×
88
  //   )
×
89
  // } else {
×
90
  //   (
×
91
  //     std::env::var("HOME").unwrap_or_else(|_| "".into()),
×
92
  //     std::env::var("NODE_PATH").unwrap_or_else(|_| "".into()),
×
93
  //   )
×
94
  // };
×
95

×
96
  // let mut prefix_dir = std::env::current_exe().unwrap();
×
97
  // if cfg!(windows) {
×
98
  //   prefix_dir = prefix_dir.join("..").join("..")
×
99
  // } else {
×
100
  //   prefix_dir = prefix_dir.join("..")
×
101
  // }
×
102

×
103
  // let mut paths = vec![prefix_dir.join("lib").join("node")];
×
104

×
105
  // if !home_dir.is_empty() {
×
106
  //   paths.insert(0, PathBuf::from(&home_dir).join(".node_libraries"));
×
107
  //   paths.insert(0, PathBuf::from(&home_dir).join(".nod_modules"));
×
108
  // }
×
109

×
110
  // let mut paths = paths
×
111
  //   .into_iter()
×
112
  //   .map(|p| p.to_string_lossy().into_owned())
×
113
  //   .collect();
×
114

×
115
  // if !node_path.is_empty() {
×
116
  //   let delimiter = if cfg!(windows) { ";" } else { ":" };
×
117
  //   let mut node_paths: Vec<String> = node_path
×
118
  //     .split(delimiter)
×
119
  //     .filter(|e| !e.is_empty())
×
120
  //     .map(|s| s.to_string())
×
121
  //     .collect();
×
122
  //   node_paths.append(&mut paths);
×
123
  //   paths = node_paths;
×
124
  // }
×
125

×
126
  vec![]
×
127
}
×
128

129
#[op2(stack_trace)]
1,330✔
130
#[serde]
131
pub fn op_require_node_module_paths<P>(
1,057✔
132
  state: &mut OpState,
1,057✔
133
  #[string] from: String,
1,057✔
134
) -> Result<Vec<String>, RequireError>
1,057✔
135
where
1,057✔
136
  P: NodePermissions + 'static,
1,057✔
137
{
1,057✔
138
  let fs = state.borrow::<FileSystemRc>();
1,057✔
139
  // Guarantee that "from" is absolute.
140
  let from = if from.starts_with("file:///") {
1,057✔
141
    url_to_file_path(&Url::parse(&from)?)?
×
142
  } else {
143
    let current_dir = &fs.cwd().map_err(RequireErrorKind::UnableToGetCwd)?;
1,057✔
144
    normalize_path(current_dir.join(from))
1,057✔
145
  };
146

147
  if cfg!(windows) {
1,057✔
148
    // return root node_modules when path is 'D:\\'.
149
    let from_str = from.to_str().unwrap();
×
150
    if from_str.len() >= 3 {
×
151
      let bytes = from_str.as_bytes();
×
152
      if bytes[from_str.len() - 1] == b'\\' && bytes[from_str.len() - 2] == b':'
×
153
      {
154
        let p = format!("{}node_modules", from_str);
×
155
        return Ok(vec![p]);
×
156
      }
×
157
    }
×
158
  } else {
159
    // Return early not only to avoid unnecessary work, but to *avoid* returning
160
    // an array of two items for a root: [ '//node_modules', '/node_modules' ]
161
    if from.to_string_lossy() == "/" {
1,057✔
162
      return Ok(vec!["/node_modules".to_string()]);
×
163
    }
1,057✔
164
  }
165

166
  let mut paths = Vec::with_capacity(from.components().count());
1,057✔
167
  let mut current_path = from.as_path();
1,057✔
168
  let mut maybe_parent = Some(current_path);
1,057✔
169
  while let Some(parent) = maybe_parent {
10,465✔
170
    if !parent.ends_with("node_modules") {
9,408✔
171
      paths.push(parent.join("node_modules").to_string_lossy().into_owned());
8,366✔
172
    }
8,366✔
173
    current_path = parent;
9,408✔
174
    maybe_parent = current_path.parent();
9,408✔
175
  }
176

177
  Ok(paths)
1,057✔
178
}
1,057✔
179

180
#[op2]
321✔
181
#[string]
182
pub fn op_require_proxy_path(#[string] filename: String) -> String {
47✔
183
  // Allow a directory to be passed as the filename
184
  let trailing_slash = if cfg!(windows) {
47✔
185
    // Node also counts a trailing forward slash as a
186
    // directory for node on Windows, but not backslashes
187
    // on non-Windows platforms
188
    filename.ends_with('\\') || filename.ends_with('/')
×
189
  } else {
190
    filename.ends_with('/')
47✔
191
  };
192

193
  if trailing_slash {
47✔
194
    let p = PathBuf::from(filename);
×
195
    p.join("noop.js").to_string_lossy().into_owned()
×
196
  } else {
197
    filename
47✔
198
  }
199
}
47✔
200

201
#[op2(fast)]
274✔
202
pub fn op_require_is_request_relative(#[string] request: String) -> bool {
3,168✔
203
  if request.starts_with("./") || request.starts_with("../") || request == ".."
3,168✔
204
  {
205
    return true;
2,228✔
206
  }
940✔
207

940✔
208
  if cfg!(windows) {
940✔
209
    if request.starts_with(".\\") {
×
210
      return true;
×
211
    }
×
212

×
213
    if request.starts_with("..\\") {
×
214
      return true;
×
215
    }
×
216
  }
940✔
217

218
  false
940✔
219
}
3,168✔
220

221
#[op2]
805✔
222
#[string]
223
pub fn op_require_resolve_deno_dir(
531✔
224
  state: &mut OpState,
531✔
225
  #[string] request: String,
531✔
226
  #[string] parent_filename: String,
531✔
227
) -> Result<Option<String>, AnyError> {
531✔
228
  let resolver = state.borrow::<NpmPackageFolderResolverRc>();
531✔
229
  Ok(
531✔
230
    resolver
531✔
231
      .resolve_package_folder_from_package(
531✔
232
        &request,
531✔
233
        &url_from_file_path(&PathBuf::from(parent_filename))?,
531✔
234
      )
235
      .ok()
531✔
236
      .map(|p| p.to_string_lossy().into_owned()),
531✔
237
  )
531✔
238
}
531✔
239

240
#[op2(fast)]
274✔
241
pub fn op_require_is_deno_dir_package(
1,373✔
242
  state: &mut OpState,
1,373✔
243
  #[string] path: String,
1,373✔
244
) -> bool {
1,373✔
245
  let resolver = state.borrow::<NodeResolverRc>();
1,373✔
246
  match deno_path_util::url_from_file_path(&PathBuf::from(path)) {
1,373✔
247
    Ok(specifier) => resolver.in_npm_package(&specifier),
1,326✔
248
    Err(_) => false,
47✔
249
  }
250
}
1,373✔
251

252
#[op2]
813✔
253
#[serde]
254
pub fn op_require_resolve_lookup_paths(
539✔
255
  #[string] request: String,
539✔
256
  #[serde] maybe_parent_paths: Option<Vec<String>>,
539✔
257
  #[string] parent_filename: String,
539✔
258
) -> Option<Vec<String>> {
539✔
259
  if !request.starts_with('.')
539✔
260
    || (request.len() > 1
×
261
      && !request.starts_with("..")
×
262
      && !request.starts_with("./")
×
263
      && (!cfg!(windows) || !request.starts_with(".\\")))
×
264
  {
265
    let module_paths = vec![];
539✔
266
    let mut paths = module_paths;
539✔
267
    if let Some(mut parent_paths) = maybe_parent_paths {
539✔
268
      if !parent_paths.is_empty() {
531✔
269
        paths.append(&mut parent_paths);
531✔
270
      }
531✔
271
    }
8✔
272

273
    if !paths.is_empty() {
539✔
274
      return Some(paths);
531✔
275
    } else {
276
      return None;
8✔
277
    }
278
  }
×
279

×
280
  // In REPL, parent.filename is null.
×
281
  // if (!parent || !parent.id || !parent.filename) {
×
282
  //   // Make require('./path/to/foo') work - normally the path is taken
×
283
  //   // from realpath(__filename) but in REPL there is no filename
×
284
  //   const mainPaths = ['.'];
×
285

×
286
  //   debug('looking for %j in %j', request, mainPaths);
×
287
  //   return mainPaths;
×
288
  // }
×
289

×
290
  let p = PathBuf::from(parent_filename);
×
291
  Some(vec![p.parent().unwrap().to_string_lossy().into_owned()])
×
292
}
539✔
293

294
#[op2(fast)]
274✔
295
pub fn op_require_path_is_absolute(#[string] p: String) -> bool {
1,795✔
296
  PathBuf::from(p).is_absolute()
1,795✔
297
}
1,795✔
298

299
#[op2(fast, stack_trace)]
6,199✔
300
pub fn op_require_stat<P>(
5,926✔
301
  state: &mut OpState,
5,926✔
302
  #[string] path: String,
5,926✔
303
) -> Result<i32, deno_core::error::AnyError>
5,926✔
304
where
5,926✔
305
  P: NodePermissions + 'static,
5,926✔
306
{
5,926✔
307
  let path = PathBuf::from(path);
5,926✔
308
  let path = ensure_read_permission::<P>(state, &path)?;
5,926✔
309
  let fs = state.borrow::<FileSystemRc>();
5,926✔
310
  if let Ok(metadata) = fs.stat_sync(&path) {
5,926✔
311
    if metadata.is_file {
2,496✔
312
      return Ok(0);
1,230✔
313
    } else {
314
      return Ok(1);
1,266✔
315
    }
316
  }
3,430✔
317

3,430✔
318
  Ok(-1)
3,430✔
319
}
5,926✔
320

321
#[op2(stack_trace)]
4,013✔
322
#[string]
323
pub fn op_require_real_path<P>(
3,740✔
324
  state: &mut OpState,
3,740✔
325
  #[string] request: String,
3,740✔
326
) -> Result<String, RequireError>
3,740✔
327
where
3,740✔
328
  P: NodePermissions + 'static,
3,740✔
329
{
3,740✔
330
  let path = PathBuf::from(request);
3,740✔
331
  let path = ensure_read_permission::<P>(state, &path)
3,740✔
332
    .map_err(RequireErrorKind::Permission)?;
3,740✔
333
  let fs = state.borrow::<FileSystemRc>();
3,740✔
334
  let canonicalized_path =
3,740✔
335
    deno_path_util::strip_unc_prefix(fs.realpath_sync(&path)?);
3,740✔
336
  Ok(canonicalized_path.to_string_lossy().into_owned())
3,740✔
337
}
3,740✔
338

339
fn path_resolve<'a>(mut parts: impl Iterator<Item = &'a str>) -> PathBuf {
2,225✔
340
  let mut p = PathBuf::from(parts.next().unwrap());
2,225✔
341
  for part in parts {
4,450✔
342
    p = p.join(part);
2,225✔
343
  }
2,225✔
344
  normalize_path(p)
2,225✔
345
}
2,225✔
346

347
#[op2]
2,439✔
348
#[string]
349
pub fn op_require_path_resolve(#[serde] parts: Vec<String>) -> String {
2,165✔
350
  path_resolve(parts.iter().map(|s| s.as_str()))
4,330✔
351
    .to_string_lossy()
2,165✔
352
    .into_owned()
2,165✔
353
}
2,165✔
354

355
#[op2]
4,728✔
356
#[string]
357
pub fn op_require_path_dirname(
4,454✔
358
  #[string] request: String,
4,454✔
359
) -> Result<String, deno_core::error::AnyError> {
4,454✔
360
  let p = PathBuf::from(request);
4,454✔
361
  if let Some(parent) = p.parent() {
4,454✔
362
    Ok(parent.to_string_lossy().into_owned())
4,454✔
363
  } else {
364
    Err(deno_core::error::generic_error(
×
365
      "Path doesn't have a parent",
×
366
    ))
×
367
  }
368
}
4,454✔
369

370
#[op2]
1,284✔
371
#[string]
372
pub fn op_require_path_basename(
1,010✔
373
  #[string] request: String,
1,010✔
374
) -> Result<String, deno_core::error::AnyError> {
1,010✔
375
  let p = PathBuf::from(request);
1,010✔
376
  if let Some(path) = p.file_name() {
1,010✔
377
    Ok(path.to_string_lossy().into_owned())
1,010✔
378
  } else {
379
    Err(deno_core::error::generic_error(
×
380
      "Path doesn't have a file name",
×
381
    ))
×
382
  }
383
}
1,010✔
384

385
#[op2(stack_trace)]
2,068✔
386
#[string]
387
pub fn op_require_try_self_parent_path<P>(
1,795✔
388
  state: &mut OpState,
1,795✔
389
  has_parent: bool,
1,795✔
390
  #[string] maybe_parent_filename: Option<String>,
1,795✔
391
  #[string] maybe_parent_id: Option<String>,
1,795✔
392
) -> Result<Option<String>, deno_core::error::AnyError>
1,795✔
393
where
1,795✔
394
  P: NodePermissions + 'static,
1,795✔
395
{
1,795✔
396
  if !has_parent {
1,795✔
397
    return Ok(None);
8✔
398
  }
1,787✔
399

400
  if let Some(parent_filename) = maybe_parent_filename {
1,787✔
401
    return Ok(Some(parent_filename));
1,787✔
402
  }
×
403

404
  if let Some(parent_id) = maybe_parent_id {
×
405
    if parent_id == "<repl>" || parent_id == "internal/preload" {
×
406
      let fs = state.borrow::<FileSystemRc>();
×
407
      if let Ok(cwd) = fs.cwd() {
×
408
        let cwd = ensure_read_permission::<P>(state, &cwd)?;
×
409
        return Ok(Some(cwd.to_string_lossy().into_owned()));
×
410
      }
×
411
    }
×
412
  }
×
413
  Ok(None)
×
414
}
1,795✔
415

416
#[op2(stack_trace)]
2,068✔
417
#[string]
418
pub fn op_require_try_self<P>(
1,795✔
419
  state: &mut OpState,
1,795✔
420
  #[string] parent_path: Option<String>,
1,795✔
421
  #[string] request: String,
1,795✔
422
) -> Result<Option<String>, RequireError>
1,795✔
423
where
1,795✔
424
  P: NodePermissions + 'static,
1,795✔
425
{
1,795✔
426
  if parent_path.is_none() {
1,795✔
427
    return Ok(None);
8✔
428
  }
1,787✔
429

1,787✔
430
  let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>();
1,787✔
431
  let pkg = pkg_json_resolver
1,787✔
432
    .get_closest_package_json_from_file_path(&PathBuf::from(
1,787✔
433
      parent_path.unwrap(),
1,787✔
434
    ))
1,787✔
435
    .ok()
1,787✔
436
    .flatten();
1,787✔
437
  if pkg.is_none() {
1,787✔
438
    return Ok(None);
×
439
  }
1,787✔
440

1,787✔
441
  let pkg = pkg.unwrap();
1,787✔
442
  if pkg.exports.is_none() {
1,787✔
443
    return Ok(None);
1,566✔
444
  }
221✔
445
  if pkg.name.is_none() {
221✔
446
    return Ok(None);
×
447
  }
221✔
448

221✔
449
  let pkg_name = pkg.name.as_ref().unwrap().to_string();
221✔
450
  let mut expansion = ".".to_string();
221✔
451

221✔
452
  if request == pkg_name {
221✔
453
    // pass
×
454
  } else if request.starts_with(&format!("{pkg_name}/")) {
221✔
455
    expansion += &request[pkg_name.len()..];
×
456
  } else {
×
457
    return Ok(None);
221✔
458
  }
459

460
  let referrer = deno_core::url::Url::from_file_path(&pkg.path).unwrap();
×
461
  if let Some(exports) = &pkg.exports {
×
462
    let node_resolver = state.borrow::<NodeResolverRc>();
×
463
    let r = node_resolver.package_exports_resolve(
×
464
      &pkg.path,
×
465
      &expansion,
×
466
      exports,
×
467
      Some(&referrer),
×
468
      ResolutionMode::Require,
×
469
      REQUIRE_CONDITIONS,
×
470
      NodeResolutionKind::Execution,
×
471
    )?;
×
472
    Ok(Some(if r.scheme() == "file" {
×
473
      url_to_file_path_string(&r)?
×
474
    } else {
475
      r.to_string()
×
476
    }))
477
  } else {
478
    Ok(None)
×
479
  }
480
}
1,795✔
481

482
#[op2(stack_trace)]
1,283✔
483
#[to_v8]
484
pub fn op_require_read_file<P>(
1,010✔
485
  state: &mut OpState,
1,010✔
486
  #[string] file_path: String,
1,010✔
487
) -> Result<V8MaybeStaticStr, RequireError>
1,010✔
488
where
1,010✔
489
  P: NodePermissions + 'static,
1,010✔
490
{
1,010✔
491
  let file_path = PathBuf::from(file_path);
1,010✔
492
  // todo(dsherret): there's multiple borrows to NodeRequireLoaderRc here
493
  let file_path = ensure_read_permission::<P>(state, &file_path)
1,010✔
494
    .map_err(RequireErrorKind::Permission)?;
1,010✔
495
  let loader = state.borrow::<NodeRequireLoaderRc>();
1,010✔
496
  loader
1,010✔
497
    .load_text_file_lossy(&file_path)
1,010✔
498
    .map(V8MaybeStaticStr)
1,010✔
499
    .map_err(|e| RequireErrorKind::ReadModule(e).into_box())
1,010✔
500
}
1,010✔
501

502
#[op2]
321✔
503
#[string]
504
pub fn op_require_as_file_path(#[string] file_or_url: String) -> String {
47✔
505
  if let Ok(url) = Url::parse(&file_or_url) {
47✔
506
    if let Ok(p) = url.to_file_path() {
47✔
507
      return p.to_string_lossy().into_owned();
47✔
508
    }
×
509
  }
×
510

511
  file_or_url
×
512
}
47✔
513

514
#[op2(stack_trace)]
730✔
515
#[string]
516
pub fn op_require_resolve_exports<P>(
457✔
517
  state: &mut OpState,
457✔
518
  uses_local_node_modules_dir: bool,
457✔
519
  #[string] modules_path_str: String,
457✔
520
  #[string] _request: String,
457✔
521
  #[string] name: String,
457✔
522
  #[string] expansion: String,
457✔
523
  #[string] parent_path: String,
457✔
524
) -> Result<Option<String>, RequireError>
457✔
525
where
457✔
526
  P: NodePermissions + 'static,
457✔
527
{
457✔
528
  let fs = state.borrow::<FileSystemRc>();
457✔
529
  let node_resolver = state.borrow::<NodeResolverRc>();
457✔
530
  let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>();
457✔
531

457✔
532
  let modules_path = PathBuf::from(&modules_path_str);
457✔
533
  let modules_specifier = deno_path_util::url_from_file_path(&modules_path)?;
457✔
534
  let pkg_path = if node_resolver.in_npm_package(&modules_specifier)
457✔
535
    && !uses_local_node_modules_dir
397✔
536
  {
537
    modules_path
397✔
538
  } else {
539
    let mod_dir =
60✔
540
      path_resolve([modules_path_str.as_str(), name.as_str()].into_iter());
60✔
541
    if fs.is_dir_sync(&mod_dir) {
60✔
542
      mod_dir
49✔
543
    } else {
544
      modules_path
11✔
545
    }
546
  };
547
  let Some(pkg) =
449✔
548
    pkg_json_resolver.load_package_json(&pkg_path.join("package.json"))?
457✔
549
  else {
550
    return Ok(None);
8✔
551
  };
552
  let Some(exports) = &pkg.exports else {
449✔
553
    return Ok(None);
346✔
554
  };
555

556
  let referrer = if parent_path.is_empty() {
103✔
557
    None
×
558
  } else {
559
    Some(Url::from_file_path(parent_path).unwrap())
103✔
560
  };
561
  let r = node_resolver.package_exports_resolve(
103✔
562
    &pkg.path,
103✔
563
    &format!(".{expansion}"),
103✔
564
    exports,
103✔
565
    referrer.as_ref(),
103✔
566
    ResolutionMode::Require,
103✔
567
    REQUIRE_CONDITIONS,
103✔
568
    NodeResolutionKind::Execution,
103✔
569
  )?;
103✔
570
  Ok(Some(if r.scheme() == "file" {
103✔
571
    url_to_file_path_string(&r)?
103✔
572
  } else {
573
    r.to_string()
×
574
  }))
575
}
457✔
576

577
#[op2(fast)]
1,269✔
578
pub fn op_require_is_maybe_cjs(
995✔
579
  state: &mut OpState,
995✔
580
  #[string] filename: String,
995✔
581
) -> Result<bool, ClosestPkgJsonError> {
995✔
582
  let filename = PathBuf::from(filename);
995✔
583
  let Ok(url) = url_from_file_path(&filename) else {
995✔
584
    return Ok(false);
×
585
  };
586
  let loader = state.borrow::<NodeRequireLoaderRc>();
995✔
587
  loader.is_maybe_cjs(&url)
995✔
588
}
995✔
589

590
#[op2(stack_trace)]
669✔
591
#[serde]
592
pub fn op_require_read_package_scope<P>(
396✔
593
  state: &mut OpState,
396✔
594
  #[string] package_json_path: String,
396✔
595
) -> Option<PackageJsonRc>
396✔
596
where
396✔
597
  P: NodePermissions + 'static,
396✔
598
{
396✔
599
  let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>();
396✔
600
  let package_json_path = PathBuf::from(package_json_path);
396✔
601
  if package_json_path.file_name() != Some("package.json".as_ref()) {
396✔
602
    // permissions: do not allow reading a non-package.json file
603
    return None;
×
604
  }
396✔
605
  pkg_json_resolver
396✔
606
    .load_package_json(&package_json_path)
396✔
607
    .ok()
396✔
608
    .flatten()
396✔
609
}
396✔
610

611
#[op2(stack_trace)]
273✔
612
#[string]
613
pub fn op_require_package_imports_resolve<P>(
×
614
  state: &mut OpState,
×
615
  #[string] referrer_filename: String,
×
616
  #[string] request: String,
×
617
) -> Result<Option<String>, RequireError>
×
618
where
×
619
  P: NodePermissions + 'static,
×
620
{
×
621
  let referrer_path = PathBuf::from(&referrer_filename);
×
622
  let referrer_path = ensure_read_permission::<P>(state, &referrer_path)
×
623
    .map_err(RequireErrorKind::Permission)?;
×
624
  let pkg_json_resolver = state.borrow::<PackageJsonResolverRc>();
×
625
  let Some(pkg) = pkg_json_resolver
×
626
    .get_closest_package_json_from_file_path(&referrer_path)?
×
627
  else {
628
    return Ok(None);
×
629
  };
630

631
  if pkg.imports.is_some() {
×
632
    let node_resolver = state.borrow::<NodeResolverRc>();
×
633
    let referrer_url = Url::from_file_path(&referrer_filename).unwrap();
×
634
    let url = node_resolver.package_imports_resolve(
×
635
      &request,
×
636
      Some(&referrer_url),
×
637
      ResolutionMode::Require,
×
638
      Some(&pkg),
×
639
      REQUIRE_CONDITIONS,
×
640
      NodeResolutionKind::Execution,
×
641
    )?;
×
642
    Ok(Some(url_to_file_path_string(&url)?))
×
643
  } else {
644
    Ok(None)
×
645
  }
646
}
×
647

648
#[op2(fast, reentrant)]
274✔
649
pub fn op_require_break_on_next_statement(state: Rc<RefCell<OpState>>) {
×
650
  let inspector_rc = {
×
651
    let state = state.borrow();
×
652
    state.borrow::<Rc<RefCell<JsRuntimeInspector>>>().clone()
×
653
  };
×
654
  let mut inspector = inspector_rc.borrow_mut();
×
655
  inspector.wait_for_session_and_break_on_next_statement()
×
656
}
×
657

658
fn url_to_file_path_string(url: &Url) -> Result<String, RequireError> {
103✔
659
  let file_path = url_to_file_path(url)?;
103✔
660
  Ok(file_path.to_string_lossy().into_owned())
103✔
661
}
103✔
662

663
#[op2(fast)]
274✔
664
pub fn op_require_can_parse_as_esm(
×
665
  scope: &mut v8::HandleScope,
×
666
  #[string] source: &str,
×
667
) -> bool {
×
668
  let scope = &mut v8::TryCatch::new(scope);
×
669
  let Some(source) = v8::String::new(scope, source) else {
×
670
    return false;
×
671
  };
672
  let origin = v8::ScriptOrigin::new(
×
673
    scope,
×
674
    source.into(),
×
675
    0,
×
676
    0,
×
677
    false,
×
678
    0,
×
679
    None,
×
680
    true,
×
681
    false,
×
682
    true,
×
683
    None,
×
684
  );
×
685
  let mut source = v8::script_compiler::Source::new(source, Some(&origin));
×
686
  v8::script_compiler::compile_module(scope, &mut source).is_some()
×
687
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc