From 596dfaf2b4ecf1be954516202e1f3815f267a0ea Mon Sep 17 00:00:00 2001 From: richerfu Date: Thu, 28 May 2026 09:49:24 +0800 Subject: [PATCH] Add Env wrapper APIs --- src/napi.zig | 1 + src/napi/env.zig | 56 ++++++++++++++++++++++++++++++++++++++++++ src/napi/util/napi.zig | 6 +++-- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/napi.zig b/src/napi.zig index dd83795..0c18509 100644 --- a/src/napi.zig +++ b/src/napi.zig @@ -25,6 +25,7 @@ pub const NapiVersion = options.NapiVersion; pub const selectedNapiVersion = options.selectedNapiVersion; pub const experimentalEnabled = options.experimentalEnabled; pub const Env = env.Env; +pub const NapiValue = value.NapiValue; pub const Object = value.Object; pub const Number = value.Number; pub const String = value.String; diff --git a/src/napi/env.zig b/src/napi/env.zig index fa15f9a..8e61774 100644 --- a/src/napi/env.zig +++ b/src/napi/env.zig @@ -1,7 +1,12 @@ const napi = @import("napi-sys").napi_sys; const Undefined = @import("./value/undefined.zig").Undefined; const Null = @import("./value/null.zig").Null; +const Object = @import("./value/object.zig").Object; +const String = @import("./value/string.zig").String; +const NapiValue = @import("./value.zig").NapiValue; +const NapiError = @import("./wrapper/error.zig"); const native_wrap = @import("./wrapper/native_wrap.zig"); +const options = @import("./options.zig"); pub const Env = struct { raw: napi.napi_env, @@ -24,6 +29,57 @@ pub const Env = struct { return Null.from_raw(self.raw, result); } + pub fn getNapiVersion(self: Env) u32 { + var result: u32 = 0; + _ = napi.napi_get_version(self.raw, &result); + return result; + } + + pub fn getGlobal(self: Env) !Object { + var result: napi.napi_value = undefined; + const status = napi.napi_get_global(self.raw, &result); + if (status != napi.napi_ok) { + return NapiError.Error.fromStatus(NapiError.Status.New(status)); + } + return Object.from_raw(self.raw, result); + } + + pub fn createSymbol(self: Env, description: []const u8) !NapiValue { + const description_value = String.New(self, description); + var result: napi.napi_value = undefined; + const status = napi.napi_create_symbol(self.raw, description_value.raw, &result); + if (status != napi.napi_ok) { + return NapiError.Error.fromStatus(NapiError.Status.New(status)); + } + return NapiValue.from_raw(self.raw, result); + } + + pub fn createDate(self: Env, value: f64) !Object { + comptime options.requireNapiVersion(.v5); + + var result: napi.napi_value = undefined; + const status = napi.napi_create_date(self.raw, value, &result); + if (status != napi.napi_ok) { + return NapiError.Error.fromStatus(NapiError.Status.New(status)); + } + return Object.from_raw(self.raw, result); + } + + pub fn isExceptionPending(self: Env) bool { + var result = false; + _ = napi.napi_is_exception_pending(self.raw, &result); + return result; + } + + pub fn getAndClearLastException(self: Env) !NapiValue { + var result: napi.napi_value = undefined; + const status = napi.napi_get_and_clear_last_exception(self.raw, &result); + if (status != napi.napi_ok) { + return NapiError.Error.fromStatus(NapiError.Status.New(status)); + } + return NapiValue.from_raw(self.raw, result); + } + pub fn wrap(self: Env, js_object: anytype, payload: anytype) !void { return self.wrapWithSizeHint(js_object, payload, 0); } diff --git a/src/napi/util/napi.zig b/src/napi/util/napi.zig index 9aafb55..9d1f5dc 100644 --- a/src/napi/util/napi.zig +++ b/src/napi/util/napi.zig @@ -133,6 +133,7 @@ fn valueMatchesType(env: napi.napi_env, raw: napi.napi_value, comptime T: type) switch (T) { NapiValue.Number => return napiTypeOf(env, raw) == napi.napi_number, NapiValue.String => return napiTypeOf(env, raw) == napi.napi_string, + NapiValue.NapiValue => return true, NapiValue.BigInt => { comptime options.requireNapiVersion(.v6); return napiTypeOf(env, raw) == napi.napi_bigint; @@ -432,6 +433,7 @@ pub const Napi = struct { helper.isReference(T) or helper.isExternal(T) or helper.isAbortSignal(T) or + T == NapiValue.NapiValue or T == NapiValue.BigInt or T == NapiValue.Bool or T == NapiValue.Number or @@ -479,7 +481,7 @@ pub const Napi = struct { pub fn from_napi_value(env: napi.napi_env, raw: napi.napi_value, comptime T: type) T { const infos = @typeInfo(T); switch (T) { - NapiValue.BigInt, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer, DataView => { + NapiValue.NapiValue, NapiValue.BigInt, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer, DataView => { return T.from_raw(env, raw); }, else => { @@ -644,7 +646,7 @@ pub const Napi = struct { } switch (value_type) { - NapiValue.BigInt, NapiValue.Bool, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer, DataView => { + NapiValue.NapiValue, NapiValue.BigInt, NapiValue.Bool, NapiValue.Number, NapiValue.String, NapiValue.Object, NapiValue.Promise, NapiValue.Array, NapiValue.Undefined, NapiValue.Null, Buffer, ArrayBuffer, DataView => { return value.raw; }, // If value is already a napi_value, return it directly