diff --git a/cli/tests/unit_node/fs_test.ts b/cli/tests/unit_node/fs_test.ts index 310113233e..d9fe3af76e 100644 --- a/cli/tests/unit_node/fs_test.ts +++ b/cli/tests/unit_node/fs_test.ts @@ -3,7 +3,8 @@ import { assert, assertThrows } from "../../../test_util/std/assert/mod.ts"; import { join } from "node:path"; import { tmpdir } from "node:os"; -import { mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { pathToAbsoluteFileUrl } from "../unit/test_util.ts"; Deno.test( "[node/fs writeFileSync] write file without option", @@ -43,3 +44,39 @@ Deno.test( ); }, ); + +Deno.test( + "[node/fs existsSync] path", + { permissions: { read: true } }, + () => { + assert(existsSync("cli/tests/testdata/assets/fixture.json")); + }, +); + +Deno.test( + "[node/fs existsSync] url", + { permissions: { read: true } }, + () => { + assert(existsSync( + pathToAbsoluteFileUrl("cli/tests/testdata/assets/fixture.json"), + )); + }, +); + +Deno.test( + "[node/fs existsSync] no permission", + { permissions: { read: false } }, + () => { + assertThrows(() => { + existsSync("cli/tests/testdata/assets/fixture.json"); + }, Deno.errors.PermissionDenied); + }, +); + +Deno.test( + "[node/fs existsSync] not exists", + { permissions: { read: true } }, + () => { + assert(!existsSync("bad_filename")); + }, +); diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 7fa5b893b2..547f1d60a1 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -50,7 +50,15 @@ pub trait NodePermissions { url: &Url, api_name: &str, ) -> Result<(), AnyError>; - fn check_read(&self, path: &Path) -> Result<(), AnyError>; + #[inline(always)] + fn check_read(&self, path: &Path) -> Result<(), AnyError> { + self.check_read_with_api_name(path, None) + } + fn check_read_with_api_name( + &self, + path: &Path, + api_name: Option<&str>, + ) -> Result<(), AnyError>; fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError>; } @@ -64,7 +72,11 @@ impl NodePermissions for AllowAllNodePermissions { ) -> Result<(), AnyError> { Ok(()) } - fn check_read(&self, _path: &Path) -> Result<(), AnyError> { + fn check_read_with_api_name( + &self, + _path: &Path, + _api_name: Option<&str>, + ) -> Result<(), AnyError> { Ok(()) } fn check_sys(&self, _kind: &str, _api_name: &str) -> Result<(), AnyError> { @@ -227,6 +239,7 @@ deno_core::extension!(deno_node, ops::crypto::x509::op_node_x509_get_valid_to, ops::crypto::x509::op_node_x509_get_serial_number, ops::crypto::x509::op_node_x509_key_usage, + ops::fs::op_node_fs_exists_sync
, ops::winerror::op_node_sys_to_uv_error, ops::v8::op_v8_cached_data_version_tag, ops::v8::op_v8_get_heap_statistics, diff --git a/ext/node/ops/fs.rs b/ext/node/ops/fs.rs new file mode 100644 index 0000000000..b21652634d --- /dev/null +++ b/ext/node/ops/fs.rs @@ -0,0 +1,26 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +use std::path::PathBuf; + +use deno_core::error::AnyError; +use deno_core::op2; +use deno_core::OpState; +use deno_fs::FileSystemRc; + +use crate::NodePermissions; + +#[op2(fast)] +pub fn op_node_fs_exists_sync
(
+ state: &mut OpState,
+ #[string] path: String,
+) -> Result ()
+ .check_read_with_api_name(&path, Some("node:fs.existsSync()"))?;
+ let fs = state.borrow::