1#![allow(clippy::too_many_arguments)]
2
3mod napi1 {
4 use super::super::types::*;
5 use std::os::raw::{c_char, c_void};
6
7 generate!(
8 #[cfg_attr(docsrs, doc(cfg(feature = "napi-1")))]
9 extern "C" {
10 fn get_undefined(env: Env, result: *mut Value) -> Status;
11
12 fn get_null(env: Env, result: *mut Value) -> Status;
13
14 fn get_global(env: Env, result: *mut Value) -> Status;
15
16 fn get_boolean(env: Env, value: bool, result: *mut Value) -> Status;
17
18 fn create_double(env: Env, value: f64, result: *mut Value) -> Status;
19
20 fn create_object(env: Env, result: *mut Value) -> Status;
21
22 fn get_value_bool(env: Env, value: Value, result: *mut bool) -> Status;
23
24 fn get_value_double(env: Env, value: Value, result: *mut f64) -> Status;
25
26 fn get_value_uint32(env: Env, value: Value, result: *mut u32) -> Status;
27
28 fn get_value_int32(env: Env, value: Value, result: *mut i32) -> Status;
29
30 fn create_array_with_length(env: Env, length: usize, result: *mut Value) -> Status;
31
32 fn get_array_length(env: Env, value: Value, result: *mut u32) -> Status;
33
34 fn get_new_target(env: Env, cbinfo: CallbackInfo, result: *mut Value) -> Status;
35
36 fn coerce_to_string(env: Env, value: Value, result: *mut Value) -> Status;
37
38 fn throw(env: Env, error: Value) -> Status;
39
40 fn create_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
41
42 fn get_and_clear_last_exception(env: Env, result: *mut Value) -> Status;
43
44 fn is_exception_pending(env: Env, result: *mut bool) -> Status;
45
46 fn get_value_external(env: Env, value: Value, result: *mut *mut c_void) -> Status;
47
48 fn typeof_value(env: Env, value: Value, result: *mut ValueType) -> Status;
49
50 fn close_escapable_handle_scope(env: Env, scope: EscapableHandleScope) -> Status;
51
52 fn open_escapable_handle_scope(env: Env, result: *mut EscapableHandleScope) -> Status;
53
54 fn open_handle_scope(env: Env, result: *mut HandleScope) -> Status;
55
56 fn close_handle_scope(env: Env, scope: HandleScope) -> Status;
57
58 fn is_arraybuffer(env: Env, value: Value, result: *mut bool) -> Status;
59 fn is_typedarray(env: Env, value: Value, result: *mut bool) -> Status;
60 fn is_buffer(env: Env, value: Value, result: *mut bool) -> Status;
61 fn is_error(env: Env, value: Value, result: *mut bool) -> Status;
62 fn is_array(env: Env, value: Value, result: *mut bool) -> Status;
63 fn is_promise(env: Env, value: Value, result: *mut bool) -> Status;
64
65 fn get_value_string_utf8(
66 env: Env,
67 value: Value,
68 buf: *mut c_char,
69 bufsize: usize,
70 result: *mut usize,
71 ) -> Status;
72
73 fn get_value_string_utf16(
77 env: Env,
78 value: Value,
79 buf: *mut u16,
80 bufsize: usize,
81 result: *mut usize,
82 ) -> Status;
83
84 fn create_type_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
85
86 fn create_range_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
87
88 fn create_string_utf8(
89 env: Env,
90 str: *const c_char,
91 length: usize,
92 result: *mut Value,
93 ) -> Status;
94
95 fn create_arraybuffer(
96 env: Env,
97 byte_length: usize,
98 data: *mut *mut c_void,
99 result: *mut Value,
100 ) -> Status;
101
102 fn get_arraybuffer_info(
103 env: Env,
104 arraybuffer: Value,
105 data: *mut *mut c_void,
106 byte_length: *mut usize,
107 ) -> Status;
108
109 fn create_typedarray(
110 env: Env,
111 type_: TypedArrayType,
112 length: usize,
113 arraybuffer: Value,
114 byte_offset: usize,
115 result: *mut Value,
116 ) -> Status;
117
118 fn get_typedarray_info(
119 env: Env,
120 typedarray: Value,
121 typ: *mut TypedArrayType,
122 length: *mut usize,
123 data: *mut *mut c_void,
124 buf: *mut Value,
125 offset: *mut usize,
126 ) -> Status;
127
128 fn create_buffer(
129 env: Env,
130 length: usize,
131 data: *mut *mut c_void,
132 result: *mut Value,
133 ) -> Status;
134
135 fn get_buffer_info(
136 env: Env,
137 value: Value,
138 data: *mut *mut c_void,
139 length: *mut usize,
140 ) -> Status;
141
142 fn get_cb_info(
143 env: Env,
144 cbinfo: CallbackInfo,
145 argc: *mut usize,
146 argv: *mut Value,
147 this_arg: *mut Value,
148 data: *mut *mut c_void,
149 ) -> Status;
150
151 fn create_external(
152 env: Env,
153 data: *mut c_void,
154 finalize_cb: Finalize,
155 finalize_hint: *mut c_void,
156 result: *mut Value,
157 ) -> Status;
158
159 fn new_instance(
160 env: Env,
161 constructor: Value,
162 argc: usize,
163 argv: *const Value,
164 result: *mut Value,
165 ) -> Status;
166
167 fn call_function(
168 env: Env,
169 recv: Value,
170 func: Value,
171 argc: usize,
172 argv: *const Value,
173 result: *mut Value,
174 ) -> Status;
175
176 fn create_function(
177 env: Env,
178 utf8name: *const c_char,
179 length: usize,
180 cb: Callback,
181 data: *mut c_void,
182 result: *mut Value,
183 ) -> Status;
184
185 fn set_property(env: Env, object: Value, key: Value, value: Value) -> Status;
186
187 fn get_property(env: Env, object: Value, key: Value, result: *mut Value) -> Status;
188
189 fn set_element(env: Env, object: Value, index: u32, value: Value) -> Status;
190
191 fn get_element(env: Env, object: Value, index: u32, result: *mut Value) -> Status;
192
193 fn escape_handle(
194 env: Env,
195 scope: EscapableHandleScope,
196 escapee: Value,
197 result: *mut Value,
198 ) -> Status;
199
200 fn create_reference(
201 env: Env,
202 value: Value,
203 initial_ref_count: u32,
204 result: *mut Ref,
205 ) -> Status;
206
207 fn reference_ref(env: Env, reference: Ref, result: *mut u32) -> Status;
208
209 fn reference_unref(env: Env, reference: Ref, result: *mut u32) -> Status;
210
211 fn delete_reference(env: Env, reference: Ref) -> Status;
212
213 fn get_reference_value(env: Env, reference: Ref, result: *mut Value) -> Status;
214
215 fn strict_equals(env: Env, lhs: Value, rhs: Value, result: *mut bool) -> Status;
216
217 #[cfg(any(feature = "sys", feature = "external-buffers"))]
218 fn create_external_arraybuffer(
219 env: Env,
220 data: *mut c_void,
221 length: usize,
222 finalize_cb: Finalize,
223 finalize_hint: *mut c_void,
224 result: *mut Value,
225 ) -> Status;
226
227 #[cfg(any(feature = "sys", feature = "external-buffers"))]
228 fn create_external_buffer(
229 env: Env,
230 length: usize,
231 data: *mut c_void,
232 finalize_cb: Finalize,
233 finalize_hint: *mut c_void,
234 result: *mut Value,
235 ) -> Status;
236
237 fn run_script(env: Env, script: Value, result: *mut Value) -> Status;
238
239 fn create_async_work(
240 env: Env,
241 async_resource: Value,
242 async_resource_name: Value,
243 execute: AsyncExecuteCallback,
244 complete: AsyncCompleteCallback,
245 data: *mut c_void,
246 result: *mut AsyncWork,
247 ) -> Status;
248
249 fn delete_async_work(env: Env, work: AsyncWork) -> Status;
250 fn queue_async_work(env: Env, work: AsyncWork) -> Status;
251 fn create_promise(env: Env, deferred: *mut Deferred, promise: *mut Value) -> Status;
252 fn resolve_deferred(env: Env, deferred: Deferred, resolution: Value) -> Status;
253 fn reject_deferred(env: Env, deferred: Deferred, rejection: Value) -> Status;
254
255 fn fatal_error(
256 location: *const c_char,
257 location_len: usize,
258 message: *const c_char,
259 message_len: usize,
260 );
261
262 fn wrap(
263 env: Env,
264 js_object: Value,
265 native_object: *mut c_void,
266 finalize_cb: Finalize,
267 finalize_hint: *mut c_void,
268 result: *mut Ref,
269 ) -> Status;
270
271 fn unwrap(env: Env, js_object: Value, result: *mut *mut c_void) -> Status;
272
273 #[cfg(feature = "napi-8")]
274 fn remove_wrap(env: Env, js_object: Value, result: *mut *mut c_void) -> Status;
275 }
276 );
277}
278
279#[cfg(feature = "napi-4")]
280mod napi4 {
281 use super::super::types::*;
282 use std::os::raw::c_void;
283
284 generate!(
285 #[cfg_attr(docsrs, doc(cfg(feature = "napi-4")))]
286 extern "C" {
287 fn create_threadsafe_function(
288 env: Env,
289 func: Value,
290 async_resource: Value,
291 async_resource_name: Value,
292 max_queue_size: usize,
293 initial_thread_count: usize,
294 thread_finalize_data: *mut c_void,
295 thread_finalize_cb: Finalize,
296 context: *mut c_void,
297 call_js_cb: ThreadsafeFunctionCallJs,
298 result: *mut ThreadsafeFunction,
299 ) -> Status;
300
301 fn call_threadsafe_function(
302 func: ThreadsafeFunction,
303 data: *mut c_void,
304 is_blocking: ThreadsafeFunctionCallMode,
305 ) -> Status;
306
307 fn release_threadsafe_function(
308 func: ThreadsafeFunction,
309 mode: ThreadsafeFunctionReleaseMode,
310 ) -> Status;
311
312 fn ref_threadsafe_function(env: Env, func: ThreadsafeFunction) -> Status;
313
314 fn unref_threadsafe_function(env: Env, func: ThreadsafeFunction) -> Status;
315 }
316 );
317}
318
319#[cfg(feature = "napi-5")]
320mod napi5 {
321 use super::super::types::*;
322 use std::ffi::c_void;
323
324 generate!(
325 #[cfg_attr(docsrs, doc(cfg(feature = "napi-5")))]
326 extern "C" {
327 fn create_date(env: Env, value: f64, result: *mut Value) -> Status;
328
329 fn get_date_value(env: Env, value: Value, result: *mut f64) -> Status;
330
331 fn is_date(env: Env, value: Value, result: *mut bool) -> Status;
332
333 fn add_finalizer(
334 env: Env,
335 js_object: Value,
336 native_object: *mut c_void,
337 finalize_cb: Finalize,
338 finalize_hint: *mut c_void,
339 result: Ref,
340 ) -> Status;
341 }
342 );
343}
344
345#[cfg(feature = "napi-6")]
346mod napi6 {
347 use super::super::types::*;
348 use std::os::raw::c_void;
349
350 generate!(
351 #[cfg_attr(docsrs, doc(cfg(feature = "napi-6")))]
352 extern "C" {
353 fn get_all_property_names(
354 env: Env,
355 object: Value,
356 key_mode: KeyCollectionMode,
357 key_filter: KeyFilter,
358 key_conversion: KeyConversion,
359 result: *mut Value,
360 ) -> Status;
361
362 fn set_instance_data(
363 env: Env,
364 data: *mut c_void,
365 finalize_cb: Finalize,
366 finalize_hint: *mut c_void,
367 ) -> Status;
368
369 fn get_instance_data(env: Env, data: *mut *mut c_void) -> Status;
370
371 fn create_bigint_int64(env: Env, value: i64, result: *mut Value) -> Status;
372
373 fn create_bigint_uint64(env: Env, value: u64, result: *mut Value) -> Status;
374
375 fn create_bigint_words(
376 env: Env,
377 sign_bit: i32,
378 word_count: usize,
379 words: *const u64,
380 result: *mut Value,
381 ) -> Status;
382
383 fn get_value_bigint_int64(
384 env: Env,
385 value: Value,
386 result: *mut i64,
387 lossless: *mut bool,
388 ) -> Status;
389
390 fn get_value_bigint_uint64(
391 env: Env,
392 value: Value,
393 result: *mut u64,
394 lossless: *mut bool,
395 ) -> Status;
396
397 fn get_value_bigint_words(
398 env: Env,
399 value: Value,
400 sign_bit: *mut i64,
401 word_count: *mut usize,
402 words: *mut u64,
403 ) -> Status;
404 }
405 );
406}
407
408#[cfg(feature = "napi-8")]
409mod napi8 {
410 use super::super::types::*;
411
412 generate!(
413 #[cfg_attr(docsrs, doc(cfg(feature = "napi-8")))]
414 extern "C" {
415 fn object_freeze(env: Env, object: Value) -> Status;
416 fn object_seal(env: Env, object: Value) -> Status;
417 fn type_tag_object(env: Env, object: Value, tag: *const TypeTag) -> Status;
418 fn check_object_type_tag(
419 env: Env,
420 object: Value,
421 tag: *const TypeTag,
422 result: *mut bool,
423 ) -> Status;
424 }
425 );
426}
427
428pub use napi1::*;
429#[cfg(feature = "napi-4")]
430pub use napi4::*;
431#[cfg(feature = "napi-5")]
432pub use napi5::*;
433#[cfg(feature = "napi-6")]
434pub use napi6::*;
435#[cfg(feature = "napi-8")]
436pub use napi8::*;
437
438use super::{Env, Status};
439
440unsafe fn get_version(host: &libloading::Library, env: Env) -> Result<u32, libloading::Error> {
442 let get_version = host.get::<fn(Env, *mut u32) -> Status>(b"napi_get_version")?;
443 let mut version = 0;
444
445 assert_eq!(get_version(env, &mut version as *mut _), Status::Ok,);
446
447 Ok(version)
448}
449
450pub(crate) unsafe fn load(env: Env) -> Result<(), libloading::Error> {
451 #[cfg(not(windows))]
452 let host = libloading::os::unix::Library::this().into();
453 #[cfg(windows)]
454 let host = libloading::os::windows::Library::this()?.into();
455
456 let actual_version = get_version(&host, env).expect("Failed to find N-API version");
459
460 let expected_version = match () {
461 _ if cfg!(feature = "napi-8") => 8,
462 _ if cfg!(feature = "napi-7") => 7,
463 _ if cfg!(feature = "napi-6") => 6,
464 _ if cfg!(feature = "napi-5") => 5,
465 _ if cfg!(feature = "napi-4") => 4,
466 _ if cfg!(feature = "napi-3") => 3,
467 _ if cfg!(feature = "napi-2") => 2,
468 _ => 1,
469 };
470
471 if actual_version < expected_version {
472 eprintln!("Minimum required Node-API version {expected_version}, found {actual_version}.\n\nSee the Node-API support matrix for more details: https://nodejs.org/api/n-api.html#node-api-version-matrix");
473 }
474
475 napi1::load(&host);
476
477 #[cfg(feature = "napi-4")]
478 napi4::load(&host);
479
480 #[cfg(feature = "napi-5")]
481 napi5::load(&host);
482
483 #[cfg(feature = "napi-6")]
484 napi6::load(&host);
485
486 #[cfg(feature = "napi-8")]
487 napi8::load(&host);
488
489 Ok(())
490}