node-addon-api 8.0.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # **node-addon-api module**
2
2
 
3
+ [![codecov](https://codecov.io/gh/nodejs/node-addon-api/branch/main/graph/badge.svg)](https://app.codecov.io/gh/nodejs/node-addon-api/tree/main)
4
+
3
5
  [![NPM](https://nodei.co/npm/node-addon-api.png?downloads=true&downloadRank=true)](https://nodei.co/npm/node-addon-api/) [![NPM](https://nodei.co/npm-dl/node-addon-api.png?months=6&height=1)](https://nodei.co/npm/node-addon-api/)
4
6
 
5
7
  This module contains **header-only C++ wrapper classes** which simplify
@@ -16,7 +18,9 @@ and exception handling semantics with low overhead.
16
18
 
17
19
  API references are available in the [doc](doc/README.md) directory.
18
20
 
19
- ## Current version: 8.0.0
21
+ <!-- x-release-please-start-version -->
22
+ ## Current version: 8.1.0
23
+ <!-- x-release-please-end -->
20
24
 
21
25
  (See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
22
26
 
package/common.gypi CHANGED
@@ -5,6 +5,7 @@
5
5
  },
6
6
  'conditions': [
7
7
  ['NAPI_VERSION!=""', { 'defines': ['NAPI_VERSION=<@(NAPI_VERSION)'] } ],
8
+ ['NAPI_VERSION==2147483647', { 'defines': ['NAPI_EXPERIMENTAL'] } ],
8
9
  ['disable_deprecated=="true"', {
9
10
  'defines': ['NODE_ADDON_API_DISABLE_DEPRECATED']
10
11
  }],
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const path = require('path');
2
+ const { version } = require('./package.json');
2
3
 
3
4
  const includeDir = path.relative('.', __dirname);
4
5
 
@@ -7,6 +8,7 @@ module.exports = {
7
8
  include_dir: includeDir,
8
9
  gyp: path.join(includeDir, 'node_api.gyp:nothing'), // deprecated.
9
10
  targets: path.join(includeDir, 'node_addon_api.gyp'),
11
+ version,
10
12
  isNodeApiBuiltin: true,
11
13
  needsFlag: false
12
14
  };
package/napi-inl.h CHANGED
@@ -9,8 +9,11 @@
9
9
  ////////////////////////////////////////////////////////////////////////////////
10
10
 
11
11
  // Note: Do not include this file directly! Include "napi.h" instead.
12
+ // This should be a no-op and is intended for better IDE integration.
13
+ #include "napi.h"
12
14
 
13
15
  #include <algorithm>
16
+ #include <cstdarg>
14
17
  #include <cstring>
15
18
  #if NAPI_HAS_THREADS
16
19
  #include <mutex>
@@ -31,6 +34,23 @@ namespace details {
31
34
  // Node.js releases. Only necessary when they are used in napi.h and napi-inl.h.
32
35
  constexpr int napi_no_external_buffers_allowed = 22;
33
36
 
37
+ #if (defined(NAPI_EXPERIMENTAL) && \
38
+ defined(NODE_API_EXPERIMENTAL_HAS_POST_FINALIZER))
39
+ template <napi_finalize finalizer>
40
+ inline void PostFinalizerWrapper(node_api_nogc_env nogc_env,
41
+ void* data,
42
+ void* hint) {
43
+ napi_status status = node_api_post_finalizer(nogc_env, finalizer, data, hint);
44
+ NAPI_FATAL_IF_FAILED(
45
+ status, "PostFinalizerWrapper", "node_api_post_finalizer failed");
46
+ }
47
+ #else
48
+ template <napi_finalize finalizer>
49
+ inline void PostFinalizerWrapper(napi_env env, void* data, void* hint) {
50
+ finalizer(env, data, hint);
51
+ }
52
+ #endif
53
+
34
54
  template <typename FreeType>
35
55
  inline void default_finalizer(napi_env /*env*/, void* data, void* /*hint*/) {
36
56
  delete static_cast<FreeType*>(data);
@@ -65,7 +85,8 @@ inline napi_status AttachData(napi_env env,
65
85
  }
66
86
  }
67
87
  #else // NAPI_VERSION >= 5
68
- status = napi_add_finalizer(env, obj, data, finalizer, hint, nullptr);
88
+ status = napi_add_finalizer(
89
+ env, obj, data, details::PostFinalizerWrapper<finalizer>, hint, nullptr);
69
90
  #endif
70
91
  return status;
71
92
  }
@@ -154,7 +175,10 @@ napi_value TemplatedCallback(napi_env env,
154
175
  napi_callback_info info) NAPI_NOEXCEPT {
155
176
  return details::WrapCallback([&] {
156
177
  CallbackInfo cbInfo(env, info);
157
- return Callback(cbInfo);
178
+ // MSVC requires to copy 'Callback' function pointer to a local variable
179
+ // before invoking it.
180
+ auto callback = Callback;
181
+ return callback(cbInfo);
158
182
  });
159
183
  }
160
184
 
@@ -337,6 +361,18 @@ struct AccessorCallbackData {
337
361
  void* data;
338
362
  };
339
363
 
364
+ // Debugging-purpose C++-style variant of sprintf().
365
+ inline std::string StringFormat(const char* format, ...) {
366
+ std::string result;
367
+ va_list args;
368
+ va_start(args, format);
369
+ int len = vsnprintf(nullptr, 0, format, args);
370
+ result.resize(len);
371
+ vsnprintf(&result[0], len + 1, format, args);
372
+ va_end(args);
373
+ return result;
374
+ }
375
+
340
376
  } // namespace details
341
377
 
342
378
  #ifndef NODE_ADDON_API_DISABLE_DEPRECATED
@@ -805,8 +841,7 @@ inline void Boolean::CheckCast(napi_env env, napi_value value) {
805
841
  napi_valuetype type;
806
842
  napi_status status = napi_typeof(env, value, &type);
807
843
  NAPI_CHECK(status == napi_ok, "Boolean::CheckCast", "napi_typeof failed");
808
- NAPI_CHECK(
809
- type == napi_boolean, "Boolean::CheckCast", "value is not napi_boolean");
844
+ NAPI_INTERNAL_CHECK_EQ(type, napi_boolean, "%d", "Boolean::CheckCast");
810
845
  }
811
846
 
812
847
  inline Boolean::Boolean() : Napi::Value() {}
@@ -842,8 +877,7 @@ inline void Number::CheckCast(napi_env env, napi_value value) {
842
877
  napi_valuetype type;
843
878
  napi_status status = napi_typeof(env, value, &type);
844
879
  NAPI_CHECK(status == napi_ok, "Number::CheckCast", "napi_typeof failed");
845
- NAPI_CHECK(
846
- type == napi_number, "Number::CheckCast", "value is not napi_number");
880
+ NAPI_INTERNAL_CHECK_EQ(type, napi_number, "%d", "Number::CheckCast");
847
881
  }
848
882
 
849
883
  inline Number::Number() : Value() {}
@@ -938,8 +972,7 @@ inline void BigInt::CheckCast(napi_env env, napi_value value) {
938
972
  napi_valuetype type;
939
973
  napi_status status = napi_typeof(env, value, &type);
940
974
  NAPI_CHECK(status == napi_ok, "BigInt::CheckCast", "napi_typeof failed");
941
- NAPI_CHECK(
942
- type == napi_bigint, "BigInt::CheckCast", "value is not napi_bigint");
975
+ NAPI_INTERNAL_CHECK_EQ(type, napi_bigint, "%d", "BigInt::CheckCast");
943
976
  }
944
977
 
945
978
  inline BigInt::BigInt() : Value() {}
@@ -1025,9 +1058,10 @@ inline void Name::CheckCast(napi_env env, napi_value value) {
1025
1058
  napi_valuetype type;
1026
1059
  napi_status status = napi_typeof(env, value, &type);
1027
1060
  NAPI_CHECK(status == napi_ok, "Name::CheckCast", "napi_typeof failed");
1028
- NAPI_CHECK(type == napi_string || type == napi_symbol,
1029
- "Name::CheckCast",
1030
- "value is not napi_string or napi_symbol");
1061
+ NAPI_INTERNAL_CHECK(type == napi_string || type == napi_symbol,
1062
+ "Name::CheckCast",
1063
+ "value is not napi_string or napi_symbol, got %d.",
1064
+ type);
1031
1065
  }
1032
1066
 
1033
1067
  inline Name::Name() : Value() {}
@@ -1094,8 +1128,7 @@ inline void String::CheckCast(napi_env env, napi_value value) {
1094
1128
  napi_valuetype type;
1095
1129
  napi_status status = napi_typeof(env, value, &type);
1096
1130
  NAPI_CHECK(status == napi_ok, "String::CheckCast", "napi_typeof failed");
1097
- NAPI_CHECK(
1098
- type == napi_string, "String::CheckCast", "value is not napi_string");
1131
+ NAPI_INTERNAL_CHECK_EQ(type, napi_string, "%d", "String::CheckCast");
1099
1132
  }
1100
1133
 
1101
1134
  inline String::String() : Name() {}
@@ -1231,8 +1264,7 @@ inline void Symbol::CheckCast(napi_env env, napi_value value) {
1231
1264
  napi_valuetype type;
1232
1265
  napi_status status = napi_typeof(env, value, &type);
1233
1266
  NAPI_CHECK(status == napi_ok, "Symbol::CheckCast", "napi_typeof failed");
1234
- NAPI_CHECK(
1235
- type == napi_symbol, "Symbol::CheckCast", "value is not napi_symbol");
1267
+ NAPI_INTERNAL_CHECK_EQ(type, napi_symbol, "%d", "Symbol::CheckCast");
1236
1268
  }
1237
1269
 
1238
1270
  inline Symbol::Symbol() : Name() {}
@@ -1403,8 +1435,7 @@ inline void Object::CheckCast(napi_env env, napi_value value) {
1403
1435
  napi_valuetype type;
1404
1436
  napi_status status = napi_typeof(env, value, &type);
1405
1437
  NAPI_CHECK(status == napi_ok, "Object::CheckCast", "napi_typeof failed");
1406
- NAPI_CHECK(
1407
- type == napi_object, "Object::CheckCast", "value is not napi_object");
1438
+ NAPI_INTERNAL_CHECK_EQ(type, napi_object, "%d", "Object::CheckCast");
1408
1439
  }
1409
1440
 
1410
1441
  inline Object::Object() : TypeTaggable() {}
@@ -1774,7 +1805,8 @@ inline External<T> External<T>::New(napi_env env,
1774
1805
  napi_status status =
1775
1806
  napi_create_external(env,
1776
1807
  data,
1777
- details::FinalizeData<T, Finalizer>::Wrapper,
1808
+ details::PostFinalizerWrapper<
1809
+ details::FinalizeData<T, Finalizer>::Wrapper>,
1778
1810
  finalizeData,
1779
1811
  &value);
1780
1812
  if (status != napi_ok) {
@@ -1797,7 +1829,8 @@ inline External<T> External<T>::New(napi_env env,
1797
1829
  napi_status status = napi_create_external(
1798
1830
  env,
1799
1831
  data,
1800
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
1832
+ details::PostFinalizerWrapper<
1833
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
1801
1834
  finalizeData,
1802
1835
  &value);
1803
1836
  if (status != napi_ok) {
@@ -1814,9 +1847,7 @@ inline void External<T>::CheckCast(napi_env env, napi_value value) {
1814
1847
  napi_valuetype type;
1815
1848
  napi_status status = napi_typeof(env, value, &type);
1816
1849
  NAPI_CHECK(status == napi_ok, "External::CheckCast", "napi_typeof failed");
1817
- NAPI_CHECK(type == napi_external,
1818
- "External::CheckCast",
1819
- "value is not napi_external");
1850
+ NAPI_INTERNAL_CHECK_EQ(type, napi_external, "%d", "External::CheckCast");
1820
1851
  }
1821
1852
 
1822
1853
  template <typename T>
@@ -1910,7 +1941,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1910
1941
  env,
1911
1942
  externalData,
1912
1943
  byteLength,
1913
- details::FinalizeData<void, Finalizer>::Wrapper,
1944
+ details::PostFinalizerWrapper<
1945
+ details::FinalizeData<void, Finalizer>::Wrapper>,
1914
1946
  finalizeData,
1915
1947
  &value);
1916
1948
  if (status != napi_ok) {
@@ -1935,7 +1967,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1935
1967
  env,
1936
1968
  externalData,
1937
1969
  byteLength,
1938
- details::FinalizeData<void, Finalizer, Hint>::WrapperWithHint,
1970
+ details::PostFinalizerWrapper<
1971
+ details::FinalizeData<void, Finalizer, Hint>::WrapperWithHint>,
1939
1972
  finalizeData,
1940
1973
  &value);
1941
1974
  if (status != napi_ok) {
@@ -2270,12 +2303,13 @@ inline void TypedArrayOf<T>::CheckCast(napi_env env, napi_value value) {
2270
2303
  "TypedArrayOf::CheckCast",
2271
2304
  "napi_is_typedarray failed");
2272
2305
 
2273
- NAPI_CHECK(
2306
+ NAPI_INTERNAL_CHECK(
2274
2307
  (type == TypedArrayTypeForPrimitiveType<T>() ||
2275
2308
  (type == napi_uint8_clamped_array && std::is_same<T, uint8_t>::value)),
2276
2309
  "TypedArrayOf::CheckCast",
2277
- "Array type must match the template parameter. (Uint8 arrays may "
2278
- "optionally have the \"clamped\" array type.)");
2310
+ "Array type must match the template parameter, (Uint8 arrays may "
2311
+ "optionally have the \"clamped\" array type.), got %d.",
2312
+ type);
2279
2313
  }
2280
2314
 
2281
2315
  template <typename T>
@@ -2456,9 +2490,7 @@ inline void Function::CheckCast(napi_env env, napi_value value) {
2456
2490
  napi_valuetype type;
2457
2491
  napi_status status = napi_typeof(env, value, &type);
2458
2492
  NAPI_CHECK(status == napi_ok, "Function::CheckCast", "napi_typeof failed");
2459
- NAPI_CHECK(type == napi_function,
2460
- "Function::CheckCast",
2461
- "value is not napi_function");
2493
+ NAPI_INTERNAL_CHECK_EQ(type, napi_function, "%d", "Function::CheckCast");
2462
2494
  }
2463
2495
 
2464
2496
  inline Function::Function() : Object() {}
@@ -2652,13 +2684,14 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
2652
2684
  details::FinalizeData<T, Finalizer>* finalizeData =
2653
2685
  new details::FinalizeData<T, Finalizer>(
2654
2686
  {std::move(finalizeCallback), nullptr});
2655
- napi_status status =
2656
- napi_create_external_buffer(env,
2657
- length * sizeof(T),
2658
- data,
2659
- details::FinalizeData<T, Finalizer>::Wrapper,
2660
- finalizeData,
2661
- &value);
2687
+ napi_status status = napi_create_external_buffer(
2688
+ env,
2689
+ length * sizeof(T),
2690
+ data,
2691
+ details::PostFinalizerWrapper<
2692
+ details::FinalizeData<T, Finalizer>::Wrapper>,
2693
+ finalizeData,
2694
+ &value);
2662
2695
  if (status != napi_ok) {
2663
2696
  delete finalizeData;
2664
2697
  NAPI_THROW_IF_FAILED(env, status, Buffer());
@@ -2681,7 +2714,8 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
2681
2714
  env,
2682
2715
  length * sizeof(T),
2683
2716
  data,
2684
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2717
+ details::PostFinalizerWrapper<
2718
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
2685
2719
  finalizeData,
2686
2720
  &value);
2687
2721
  if (status != napi_ok) {
@@ -2720,13 +2754,14 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2720
2754
  {std::move(finalizeCallback), nullptr});
2721
2755
  #ifndef NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2722
2756
  napi_value value;
2723
- napi_status status =
2724
- napi_create_external_buffer(env,
2725
- length * sizeof(T),
2726
- data,
2727
- details::FinalizeData<T, Finalizer>::Wrapper,
2728
- finalizeData,
2729
- &value);
2757
+ napi_status status = napi_create_external_buffer(
2758
+ env,
2759
+ length * sizeof(T),
2760
+ data,
2761
+ details::PostFinalizerWrapper<
2762
+ details::FinalizeData<T, Finalizer>::Wrapper>,
2763
+ finalizeData,
2764
+ &value);
2730
2765
  if (status == details::napi_no_external_buffers_allowed) {
2731
2766
  #endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
2732
2767
  // If we can't create an external buffer, we'll just copy the data.
@@ -2759,7 +2794,8 @@ inline Buffer<T> Buffer<T>::NewOrCopy(napi_env env,
2759
2794
  env,
2760
2795
  length * sizeof(T),
2761
2796
  data,
2762
- details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
2797
+ details::PostFinalizerWrapper<
2798
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint>,
2763
2799
  finalizeData,
2764
2800
  &value);
2765
2801
  if (status == details::napi_no_external_buffers_allowed) {
@@ -3054,7 +3090,12 @@ inline void Error::ThrowAsJavaScriptException() const {
3054
3090
 
3055
3091
  status = napi_throw(_env, Value());
3056
3092
 
3057
- if (status == napi_pending_exception) {
3093
+ #ifdef NAPI_EXPERIMENTAL
3094
+ napi_status expected_failure_mode = napi_cannot_run_js;
3095
+ #else
3096
+ napi_status expected_failure_mode = napi_pending_exception;
3097
+ #endif
3098
+ if (status == expected_failure_mode) {
3058
3099
  // The environment must be terminating as we checked earlier and there
3059
3100
  // was no pending exception. In this case continuing will result
3060
3101
  // in a fatal error and there is nothing the author has done incorrectly
@@ -4428,7 +4469,12 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4428
4469
  napi_status status;
4429
4470
  napi_ref ref;
4430
4471
  T* instance = static_cast<T*>(this);
4431
- status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
4472
+ status = napi_wrap(env,
4473
+ wrapper,
4474
+ instance,
4475
+ details::PostFinalizerWrapper<FinalizeCallback>,
4476
+ nullptr,
4477
+ &ref);
4432
4478
  NAPI_THROW_IF_FAILED_VOID(env, status);
4433
4479
 
4434
4480
  Reference<Object>* instanceRef = instance;
@@ -4891,7 +4937,10 @@ inline napi_value ObjectWrap<T>::WrappedMethod(
4891
4937
  napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
4892
4938
  return details::WrapCallback([&] {
4893
4939
  const CallbackInfo cbInfo(env, info);
4894
- method(cbInfo, cbInfo[0]);
4940
+ // MSVC requires to copy 'method' function pointer to a local variable
4941
+ // before invoking it.
4942
+ auto m = method;
4943
+ m(cbInfo, cbInfo[0]);
4895
4944
  return nullptr;
4896
4945
  });
4897
4946
  }
@@ -5321,19 +5370,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5321
5370
  auto* finalizeData = new details::
5322
5371
  ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5323
5372
  {data, finalizeCallback});
5324
- napi_status status = napi_create_threadsafe_function(
5325
- env,
5326
- nullptr,
5327
- nullptr,
5328
- String::From(env, resourceName),
5329
- maxQueueSize,
5330
- initialThreadCount,
5331
- finalizeData,
5373
+ auto fini =
5332
5374
  details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5333
- FinalizeFinalizeWrapperWithDataAndContext,
5334
- context,
5335
- CallJsInternal,
5336
- &tsfn._tsfn);
5375
+ FinalizeFinalizeWrapperWithDataAndContext;
5376
+ napi_status status =
5377
+ napi_create_threadsafe_function(env,
5378
+ nullptr,
5379
+ nullptr,
5380
+ String::From(env, resourceName),
5381
+ maxQueueSize,
5382
+ initialThreadCount,
5383
+ finalizeData,
5384
+ fini,
5385
+ context,
5386
+ CallJsInternal,
5387
+ &tsfn._tsfn);
5337
5388
  if (status != napi_ok) {
5338
5389
  delete finalizeData;
5339
5390
  NAPI_THROW_IF_FAILED(
@@ -5365,19 +5416,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5365
5416
  auto* finalizeData = new details::
5366
5417
  ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5367
5418
  {data, finalizeCallback});
5368
- napi_status status = napi_create_threadsafe_function(
5369
- env,
5370
- nullptr,
5371
- resource,
5372
- String::From(env, resourceName),
5373
- maxQueueSize,
5374
- initialThreadCount,
5375
- finalizeData,
5419
+ auto fini =
5376
5420
  details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5377
- FinalizeFinalizeWrapperWithDataAndContext,
5378
- context,
5379
- CallJsInternal,
5380
- &tsfn._tsfn);
5421
+ FinalizeFinalizeWrapperWithDataAndContext;
5422
+ napi_status status =
5423
+ napi_create_threadsafe_function(env,
5424
+ nullptr,
5425
+ resource,
5426
+ String::From(env, resourceName),
5427
+ maxQueueSize,
5428
+ initialThreadCount,
5429
+ finalizeData,
5430
+ fini,
5431
+ context,
5432
+ CallJsInternal,
5433
+ &tsfn._tsfn);
5381
5434
  if (status != napi_ok) {
5382
5435
  delete finalizeData;
5383
5436
  NAPI_THROW_IF_FAILED(
@@ -5481,19 +5534,21 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5481
5534
  auto* finalizeData = new details::
5482
5535
  ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5483
5536
  {data, finalizeCallback});
5484
- napi_status status = napi_create_threadsafe_function(
5485
- env,
5486
- callback,
5487
- nullptr,
5488
- String::From(env, resourceName),
5489
- maxQueueSize,
5490
- initialThreadCount,
5491
- finalizeData,
5537
+ auto fini =
5492
5538
  details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5493
- FinalizeFinalizeWrapperWithDataAndContext,
5494
- context,
5495
- CallJsInternal,
5496
- &tsfn._tsfn);
5539
+ FinalizeFinalizeWrapperWithDataAndContext;
5540
+ napi_status status =
5541
+ napi_create_threadsafe_function(env,
5542
+ callback,
5543
+ nullptr,
5544
+ String::From(env, resourceName),
5545
+ maxQueueSize,
5546
+ initialThreadCount,
5547
+ finalizeData,
5548
+ fini,
5549
+ context,
5550
+ CallJsInternal,
5551
+ &tsfn._tsfn);
5497
5552
  if (status != napi_ok) {
5498
5553
  delete finalizeData;
5499
5554
  NAPI_THROW_IF_FAILED(
@@ -5527,6 +5582,9 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5527
5582
  auto* finalizeData = new details::
5528
5583
  ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5529
5584
  {data, finalizeCallback});
5585
+ auto fini =
5586
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5587
+ FinalizeFinalizeWrapperWithDataAndContext;
5530
5588
  napi_status status = napi_create_threadsafe_function(
5531
5589
  env,
5532
5590
  details::DefaultCallbackWrapper<
@@ -5538,8 +5596,7 @@ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5538
5596
  maxQueueSize,
5539
5597
  initialThreadCount,
5540
5598
  finalizeData,
5541
- details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5542
- FinalizeFinalizeWrapperWithDataAndContext,
5599
+ fini,
5543
5600
  context,
5544
5601
  CallJsInternal,
5545
5602
  &tsfn._tsfn);
package/napi.h CHANGED
@@ -142,6 +142,26 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t),
142
142
  } \
143
143
  } while (0)
144
144
 
145
+ // Internal check helper. Be careful that the formatted message length should be
146
+ // max 255 size and null terminated.
147
+ #define NAPI_INTERNAL_CHECK(expr, location, ...) \
148
+ do { \
149
+ if (!(expr)) { \
150
+ std::string msg = Napi::details::StringFormat(__VA_ARGS__); \
151
+ Napi::Error::Fatal(location, msg.c_str()); \
152
+ } \
153
+ } while (0)
154
+
155
+ #define NAPI_INTERNAL_CHECK_EQ(actual, expected, value_format, location) \
156
+ do { \
157
+ auto actual_value = (actual); \
158
+ NAPI_INTERNAL_CHECK(actual_value == (expected), \
159
+ location, \
160
+ "Expected " #actual " to be equal to " #expected \
161
+ ", but got " value_format ".", \
162
+ actual_value); \
163
+ } while (0)
164
+
145
165
  #define NAPI_FATAL_IF_FAILED(status, location, message) \
146
166
  NAPI_CHECK((status) == napi_ok, location, message)
147
167
 
@@ -1268,7 +1288,7 @@ class TypedArrayOf : public TypedArray {
1268
1288
  napi_typedarray_type type =
1269
1289
  TypedArray::TypedArrayTypeForPrimitiveType<T>()
1270
1290
  #else
1271
- napi_typedarray_type type
1291
+ napi_typedarray_type type
1272
1292
  #endif
1273
1293
  ///< Type of array, if different from the default array type for the
1274
1294
  ///< template parameter T.
@@ -1291,7 +1311,7 @@ class TypedArrayOf : public TypedArray {
1291
1311
  napi_typedarray_type type =
1292
1312
  TypedArray::TypedArrayTypeForPrimitiveType<T>()
1293
1313
  #else
1294
- napi_typedarray_type type
1314
+ napi_typedarray_type type
1295
1315
  #endif
1296
1316
  ///< Type of array, if different from the default array type for the
1297
1317
  ///< template parameter T.
@@ -1381,8 +1401,8 @@ class DataView : public Object {
1381
1401
  template <typename T>
1382
1402
  void WriteData(size_t byteOffset, T value) const;
1383
1403
 
1384
- void* _data;
1385
- size_t _length;
1404
+ void* _data{};
1405
+ size_t _length{};
1386
1406
  };
1387
1407
 
1388
1408
  class Function : public Object {
@@ -1715,7 +1735,7 @@ FunctionReference Persistent(Function value);
1715
1735
  ///
1716
1736
  /// Following C++ statements will not be executed. The exception will bubble
1717
1737
  /// up as a C++ exception of type `Napi::Error`, until it is either caught
1718
- /// while still in C++, or else automatically propataged as a JavaScript
1738
+ /// while still in C++, or else automatically propagated as a JavaScript
1719
1739
  /// exception when the callback returns to JavaScript.
1720
1740
  ///
1721
1741
  /// #### Example 2A - Propagating a Node-API C++ exception:
@@ -1888,7 +1908,7 @@ class CallbackInfo {
1888
1908
  napi_value _this;
1889
1909
  size_t _argc;
1890
1910
  napi_value* _argv;
1891
- napi_value _staticArgs[6];
1911
+ napi_value _staticArgs[6]{};
1892
1912
  napi_value* _dynamicArgs;
1893
1913
  void* _data;
1894
1914
  };
package/package.json CHANGED
@@ -374,7 +374,6 @@
374
374
  {
375
375
  "name": "Vladimir Morozov",
376
376
  "url": "https://github.com/vmoroz"
377
-
378
377
  },
379
378
  {
380
379
  "name": "WenheLI",
@@ -431,7 +430,8 @@
431
430
  "fs-extra": "^11.1.1",
432
431
  "path": "^0.12.7",
433
432
  "pre-commit": "^1.2.2",
434
- "safe-buffer": "^5.1.1"
433
+ "safe-buffer": "^5.1.1",
434
+ "semver": "^7.6.0"
435
435
  },
436
436
  "directories": {},
437
437
  "gypfile": false,
@@ -463,6 +463,9 @@
463
463
  "scripts": {
464
464
  "prebenchmark": "node-gyp rebuild -C benchmark",
465
465
  "benchmark": "node benchmark",
466
+ "create-coverage": "npm test --coverage",
467
+ "report-coverage-html": "rm -rf coverage-html && mkdir coverage-html && gcovr -e test --merge-mode-functions merge-use-line-max --html-nested ./coverage-html/index.html test",
468
+ "report-coverage-xml": "rm -rf coverage-xml && mkdir coverage-xml && gcovr -e test --merge-mode-functions merge-use-line-max --xml -o ./coverage-xml/coverage-cxx.xml test",
466
469
  "pretest": "node-gyp rebuild -C test",
467
470
  "test": "node test",
468
471
  "test:debug": "node-gyp rebuild -C test --debug && NODE_API_BUILD_CONFIG=Debug node ./test/index.js",
@@ -475,7 +478,7 @@
475
478
  "lint:fix": "node tools/clang-format --fix && node tools/eslint-format --fix"
476
479
  },
477
480
  "pre-commit": "lint",
478
- "version": "8.0.0",
481
+ "version": "8.1.0",
479
482
  "support": true,
480
483
  "engines": {
481
484
  "node": "^18 || ^20 || >= 21"
@@ -12,7 +12,7 @@ if (!dir) {
12
12
  process.exit(1);
13
13
  }
14
14
 
15
- const NodeApiVersion = require('../package.json').version;
15
+ const NodeApiVersion = require('../').version;
16
16
 
17
17
  const disable = args[1];
18
18
  let ConfigFileOperations;