diff --git a/crates/napi/Cargo.toml b/crates/napi/Cargo.toml index 9cbb043d..05c53efc 100644 --- a/crates/napi/Cargo.toml +++ b/crates/napi/Cargo.toml @@ -20,15 +20,15 @@ all-features = true independent = true [features] -noop = [] async = ["tokio_rt"] +chrono_date = ["chrono", "napi5"] compat-mode = [] default = ["napi3", "compat-mode"] # for most Node.js users +deferred_trace = ["napi4"] +error_anyhow = ["anyhow"] experimental = ["napi-sys/experimental"] -chrono_date = ["chrono", "napi5"] full = ["latin1", "napi9", "async", "serde-json", "experimental", "chrono_date"] latin1 = ["encoding_rs"] -error_anyhow = ["anyhow"] napi1 = [] napi2 = ["napi1", "napi-sys/napi2"] napi3 = ["napi2", "napi-sys/napi3"] @@ -37,7 +37,8 @@ napi5 = ["napi4", "napi-sys/napi5"] napi6 = ["napi5", "napi-sys/napi6"] napi7 = ["napi6", "napi-sys/napi7"] napi8 = ["napi7", "napi-sys/napi8"] -napi9 = ["napi8", "napi-sys/napi9"] +napi9 = ["napi8", "napi-sys/napi9", "byteorder"] +noop = [] serde-json = ["serde", "serde_json"] tokio_fs = ["tokio/fs"] tokio_full = ["tokio/full"] @@ -52,20 +53,19 @@ tokio_stats = ["tokio/stats"] tokio_sync = ["tokio/sync"] tokio_test_util = ["tokio/test-util"] tokio_time = ["tokio/time"] -deferred_trace = ["napi4"] [dependencies] +bitflags = "2" ctor = "0.2" once_cell = "1.16" -bitflags = "2" [dependencies.anyhow] -version = "1" optional = true +version = "1" [dependencies.napi-sys] -version = "2.2.3" path = "../sys" +version = "2.2.3" [dependencies.encoding_rs] optional = true @@ -75,9 +75,13 @@ version = "0.8" optional = true version = "0.4" +[dependencies.byteorder] +optional = true +version = "1.5" + [target.'cfg(target_os = "wasi")'.dependencies] -tokio = { version = "1", optional = true, features = ["rt", "sync"] } napi-derive = { path = "../macro", version = "2.10.1", default-features = false } +tokio = { version = "1", optional = true, features = ["rt", "sync"] } [target.'cfg(not(target_os = "wasi"))'.dependencies] tokio = { version = "1", optional = true, features = [ diff --git a/crates/napi/src/env.rs b/crates/napi/src/env.rs index 4994393f..1954885c 100644 --- a/crates/napi/src/env.rs +++ b/crates/napi/src/env.rs @@ -1269,6 +1269,36 @@ impl Env { Ok(unsafe { JsSymbol::from_raw_unchecked(self.0, result) }) } + #[cfg(feature = "napi9")] + /// This API retrieves the file path of the currently running JS module as a URL. For a file on + /// the local file system it will start with `file://`. + /// + /// # Errors + /// + /// The retrieved string may be empty if the add-on loading process fails to establish the + /// add-on's file name. + pub fn get_module_file_name(&self) -> Result { + let mut char_ptr = ptr::null(); + check_status!( + unsafe { sys::node_api_get_module_file_name(self.0, &mut char_ptr) }, + "call node_api_get_module_file_name failed" + )?; + // SAFETY: This is safe because `char_ptr` is guaranteed to not be `null`, and point to + // null-terminated string data. + let module_filename = unsafe { std::ffi::CStr::from_ptr(char_ptr) }; + #[cfg(windows)] + { + let byte_len = module_filename.to_bytes().len(); + let mut utf16_buf = vec![0u16; byte_len / 2]; + byteorder::LittleEndian::read_u16_into(module_filename.to_bytes(), &mut utf16_buf); + Ok(String::from_utf16_lossy(utf16_buf)) + } + #[cfg(not(windows))] + { + Ok(module_filename.to_string_lossy().into_owned()) + } + } + /// ### Serialize `Rust Struct` into `JavaScript Value` /// /// ```