node-addon-api 8.2.2 → 8.3.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
@@ -19,7 +19,7 @@ and exception handling semantics with low overhead.
19
19
  API references are available in the [doc](doc/README.md) directory.
20
20
 
21
21
  <!-- x-release-please-start-version -->
22
- ## Current version: 8.2.2
22
+ ## Current version: 8.3.0
23
23
  <!-- x-release-please-end -->
24
24
 
25
25
  (See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
package/napi-inl.h CHANGED
@@ -79,19 +79,33 @@ inline napi_status AttachData(napi_env env,
79
79
  // For use in JS to C++ callback wrappers to catch any Napi::Error exceptions
80
80
  // and rethrow them as JavaScript exceptions before returning from the callback.
81
81
  template <typename Callable>
82
- inline napi_value WrapCallback(Callable callback) {
83
- #ifdef NAPI_CPP_EXCEPTIONS
82
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS_ALL
83
+ inline napi_value WrapCallback(napi_env env, Callable callback) {
84
+ #else
85
+ inline napi_value WrapCallback(napi_env, Callable callback) {
86
+ #endif
87
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
84
88
  try {
85
89
  return callback();
86
90
  } catch (const Error& e) {
87
91
  e.ThrowAsJavaScriptException();
88
92
  return nullptr;
89
93
  }
90
- #else // NAPI_CPP_EXCEPTIONS
94
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS_ALL
95
+ catch (const std::exception& e) {
96
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
97
+ return nullptr;
98
+ } catch (...) {
99
+ Napi::Error::New(env, "A native exception was thrown")
100
+ .ThrowAsJavaScriptException();
101
+ return nullptr;
102
+ }
103
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS_ALL
104
+ #else // NODE_ADDON_API_CPP_EXCEPTIONS
91
105
  // When C++ exceptions are disabled, errors are immediately thrown as JS
92
106
  // exceptions, so there is no need to catch and rethrow them here.
93
107
  return callback();
94
- #endif // NAPI_CPP_EXCEPTIONS
108
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
95
109
  }
96
110
 
97
111
  // For use in JS to C++ void callback wrappers to catch any Napi::Error
@@ -99,7 +113,7 @@ inline napi_value WrapCallback(Callable callback) {
99
113
  // the callback.
100
114
  template <typename Callable>
101
115
  inline void WrapVoidCallback(Callable callback) {
102
- #ifdef NAPI_CPP_EXCEPTIONS
116
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
103
117
  try {
104
118
  callback();
105
119
  } catch (const Error& e) {
@@ -112,10 +126,41 @@ inline void WrapVoidCallback(Callable callback) {
112
126
  #endif // NAPI_CPP_EXCEPTIONS
113
127
  }
114
128
 
129
+ // For use in JS to C++ void callback wrappers to catch _any_ thrown exception
130
+ // and rethrow them as JavaScript exceptions before returning from the callback,
131
+ // wrapping in an Napi::Error as needed.
132
+ template <typename Callable>
133
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS_ALL
134
+ inline void WrapVoidCallback(napi_env env, Callable callback) {
135
+ #else
136
+ inline void WrapVoidCallback(napi_env, Callable callback) {
137
+ #endif
138
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
139
+ try {
140
+ callback();
141
+ } catch (const Error& e) {
142
+ e.ThrowAsJavaScriptException();
143
+ }
144
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS_ALL
145
+ catch (const std::exception& e) {
146
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
147
+ } catch (...) {
148
+ Napi::Error::New(env, "A native exception was thrown")
149
+ .ThrowAsJavaScriptException();
150
+ }
151
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS_ALL
152
+ #else
153
+ // When C++ exceptions are disabled, there is no need to catch and rethrow C++
154
+ // exceptions. JS errors should be thrown with
155
+ // `Error::ThrowAsJavaScriptException`.
156
+ callback();
157
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
158
+ }
159
+
115
160
  template <typename Callable, typename Return>
116
161
  struct CallbackData {
117
162
  static inline napi_value Wrapper(napi_env env, napi_callback_info info) {
118
- return details::WrapCallback([&] {
163
+ return details::WrapCallback(env, [&] {
119
164
  CallbackInfo callbackInfo(env, info);
120
165
  CallbackData* callbackData =
121
166
  static_cast<CallbackData*>(callbackInfo.Data());
@@ -131,7 +176,7 @@ struct CallbackData {
131
176
  template <typename Callable>
132
177
  struct CallbackData<Callable, void> {
133
178
  static inline napi_value Wrapper(napi_env env, napi_callback_info info) {
134
- return details::WrapCallback([&] {
179
+ return details::WrapCallback(env, [&] {
135
180
  CallbackInfo callbackInfo(env, info);
136
181
  CallbackData* callbackData =
137
182
  static_cast<CallbackData*>(callbackInfo.Data());
@@ -148,7 +193,7 @@ struct CallbackData<Callable, void> {
148
193
  template <void (*Callback)(const CallbackInfo& info)>
149
194
  napi_value TemplatedVoidCallback(napi_env env,
150
195
  napi_callback_info info) NAPI_NOEXCEPT {
151
- return details::WrapCallback([&] {
196
+ return details::WrapCallback(env, [&] {
152
197
  CallbackInfo cbInfo(env, info);
153
198
  Callback(cbInfo);
154
199
  return nullptr;
@@ -158,7 +203,7 @@ napi_value TemplatedVoidCallback(napi_env env,
158
203
  template <Napi::Value (*Callback)(const CallbackInfo& info)>
159
204
  napi_value TemplatedCallback(napi_env env,
160
205
  napi_callback_info info) NAPI_NOEXCEPT {
161
- return details::WrapCallback([&] {
206
+ return details::WrapCallback(env, [&] {
162
207
  CallbackInfo cbInfo(env, info);
163
208
  // MSVC requires to copy 'Callback' function pointer to a local variable
164
209
  // before invoking it.
@@ -171,7 +216,7 @@ template <typename T,
171
216
  Napi::Value (T::*UnwrapCallback)(const CallbackInfo& info)>
172
217
  napi_value TemplatedInstanceCallback(napi_env env,
173
218
  napi_callback_info info) NAPI_NOEXCEPT {
174
- return details::WrapCallback([&] {
219
+ return details::WrapCallback(env, [&] {
175
220
  CallbackInfo cbInfo(env, info);
176
221
  T* instance = T::Unwrap(cbInfo.This().As<Object>());
177
222
  return instance ? (instance->*UnwrapCallback)(cbInfo) : Napi::Value();
@@ -181,7 +226,7 @@ napi_value TemplatedInstanceCallback(napi_env env,
181
226
  template <typename T, void (T::*UnwrapCallback)(const CallbackInfo& info)>
182
227
  napi_value TemplatedInstanceVoidCallback(napi_env env, napi_callback_info info)
183
228
  NAPI_NOEXCEPT {
184
- return details::WrapCallback([&] {
229
+ return details::WrapCallback(env, [&] {
185
230
  CallbackInfo cbInfo(env, info);
186
231
  T* instance = T::Unwrap(cbInfo.This().As<Object>());
187
232
  if (instance) (instance->*UnwrapCallback)(cbInfo);
@@ -264,7 +309,7 @@ struct FinalizeData {
264
309
  static inline void WrapperGCWithoutData(napi_env env,
265
310
  void* /*data*/,
266
311
  void* finalizeHint) NAPI_NOEXCEPT {
267
- WrapVoidCallback([&] {
312
+ WrapVoidCallback(env, [&] {
268
313
  FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
269
314
  finalizeData->callback(env);
270
315
  delete finalizeData;
@@ -274,7 +319,7 @@ struct FinalizeData {
274
319
  static inline void WrapperGC(napi_env env,
275
320
  void* data,
276
321
  void* finalizeHint) NAPI_NOEXCEPT {
277
- WrapVoidCallback([&] {
322
+ WrapVoidCallback(env, [&] {
278
323
  FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
279
324
  finalizeData->callback(env, static_cast<T*>(data));
280
325
  delete finalizeData;
@@ -284,7 +329,7 @@ struct FinalizeData {
284
329
  static inline void WrapperGCWithHint(napi_env env,
285
330
  void* data,
286
331
  void* finalizeHint) NAPI_NOEXCEPT {
287
- WrapVoidCallback([&] {
332
+ WrapVoidCallback(env, [&] {
288
333
  FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
289
334
  finalizeData->callback(env, static_cast<T*>(data), finalizeData->hint);
290
335
  delete finalizeData;
@@ -351,7 +396,7 @@ struct ThreadSafeFinalize {
351
396
  template <typename ContextType, typename DataType, typename CallJs, CallJs call>
352
397
  inline typename std::enable_if<call != static_cast<CallJs>(nullptr)>::type
353
398
  CallJsWrapper(napi_env env, napi_value jsCallback, void* context, void* data) {
354
- details::WrapVoidCallback([&]() {
399
+ details::WrapVoidCallback(env, [&]() {
355
400
  call(env,
356
401
  Function(env, jsCallback),
357
402
  static_cast<ContextType*>(context),
@@ -365,7 +410,7 @@ CallJsWrapper(napi_env env,
365
410
  napi_value jsCallback,
366
411
  void* /*context*/,
367
412
  void* /*data*/) {
368
- details::WrapVoidCallback([&]() {
413
+ details::WrapVoidCallback(env, [&]() {
369
414
  if (jsCallback != nullptr) {
370
415
  Function(env, jsCallback).Call(0, nullptr);
371
416
  }
@@ -399,7 +444,7 @@ template <typename Getter, typename Setter>
399
444
  struct AccessorCallbackData {
400
445
  static inline napi_value GetterWrapper(napi_env env,
401
446
  napi_callback_info info) {
402
- return details::WrapCallback([&] {
447
+ return details::WrapCallback(env, [&] {
403
448
  CallbackInfo callbackInfo(env, info);
404
449
  AccessorCallbackData* callbackData =
405
450
  static_cast<AccessorCallbackData*>(callbackInfo.Data());
@@ -410,7 +455,7 @@ struct AccessorCallbackData {
410
455
 
411
456
  static inline napi_value SetterWrapper(napi_env env,
412
457
  napi_callback_info info) {
413
- return details::WrapCallback([&] {
458
+ return details::WrapCallback(env, [&] {
414
459
  CallbackInfo callbackInfo(env, info);
415
460
  AccessorCallbackData* callbackData =
416
461
  static_cast<AccessorCallbackData*>(callbackInfo.Data());
@@ -501,7 +546,7 @@ class HasBasicFinalizer {
501
546
  inline napi_value RegisterModule(napi_env env,
502
547
  napi_value exports,
503
548
  ModuleRegisterCallback registerCallback) {
504
- return details::WrapCallback([&] {
549
+ return details::WrapCallback(env, [&] {
505
550
  return napi_value(
506
551
  registerCallback(Napi::Env(env), Napi::Object(env, exports)));
507
552
  });
@@ -1808,7 +1853,7 @@ inline void Object::AddFinalizer(Finalizer finalizeCallback,
1808
1853
  }
1809
1854
  }
1810
1855
 
1811
- #ifdef NAPI_CPP_EXCEPTIONS
1856
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
1812
1857
  inline Object::const_iterator::const_iterator(const Object* object,
1813
1858
  const Type type) {
1814
1859
  _object = object;
@@ -1883,7 +1928,7 @@ Object::iterator::operator*() {
1883
1928
  PropertyLValue<Value> value = (*_object)[key];
1884
1929
  return {key, value};
1885
1930
  }
1886
- #endif // NAPI_CPP_EXCEPTIONS
1931
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
1887
1932
 
1888
1933
  #if NAPI_VERSION >= 8
1889
1934
  inline MaybeOrValue<bool> Object::Freeze() const {
@@ -3159,14 +3204,14 @@ inline Error& Error::operator=(const Error& other) {
3159
3204
 
3160
3205
  inline const std::string& Error::Message() const NAPI_NOEXCEPT {
3161
3206
  if (_message.size() == 0 && _env != nullptr) {
3162
- #ifdef NAPI_CPP_EXCEPTIONS
3207
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
3163
3208
  try {
3164
3209
  _message = Get("message").As<String>();
3165
3210
  } catch (...) {
3166
3211
  // Catch all errors here, to include e.g. a std::bad_alloc from
3167
3212
  // the std::string::operator=, because this method may not throw.
3168
3213
  }
3169
- #else // NAPI_CPP_EXCEPTIONS
3214
+ #else // NODE_ADDON_API_CPP_EXCEPTIONS
3170
3215
  #if defined(NODE_ADDON_API_ENABLE_MAYBE)
3171
3216
  Napi::Value message_val;
3172
3217
  if (Get("message").UnwrapTo(&message_val)) {
@@ -3175,7 +3220,7 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT {
3175
3220
  #else
3176
3221
  _message = Get("message").As<String>();
3177
3222
  #endif
3178
- #endif // NAPI_CPP_EXCEPTIONS
3223
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
3179
3224
  }
3180
3225
  return _message;
3181
3226
  }
@@ -3222,24 +3267,24 @@ inline void Error::ThrowAsJavaScriptException() const {
3222
3267
  napi_status status = napi_throw(_env, Value());
3223
3268
  #endif
3224
3269
 
3225
- #ifdef NAPI_CPP_EXCEPTIONS
3270
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
3226
3271
  if (status != napi_ok) {
3227
3272
  throw Error::New(_env);
3228
3273
  }
3229
- #else // NAPI_CPP_EXCEPTIONS
3274
+ #else // NODE_ADDON_API_CPP_EXCEPTIONS
3230
3275
  NAPI_FATAL_IF_FAILED(
3231
3276
  status, "Error::ThrowAsJavaScriptException", "napi_throw");
3232
- #endif // NAPI_CPP_EXCEPTIONS
3277
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
3233
3278
  }
3234
3279
  }
3235
3280
 
3236
- #ifdef NAPI_CPP_EXCEPTIONS
3281
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
3237
3282
 
3238
3283
  inline const char* Error::what() const NAPI_NOEXCEPT {
3239
3284
  return Message().c_str();
3240
3285
  }
3241
3286
 
3242
- #endif // NAPI_CPP_EXCEPTIONS
3287
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
3243
3288
 
3244
3289
  inline const char* Error::ERROR_WRAP_VALUE() NAPI_NOEXCEPT {
3245
3290
  return "4bda9e7e-4913-4dbc-95de-891cbf66598e-errorVal";
@@ -4508,7 +4553,7 @@ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
4508
4553
  template <typename T>
4509
4554
  inline napi_value InstanceWrap<T>::InstanceVoidMethodCallbackWrapper(
4510
4555
  napi_env env, napi_callback_info info) {
4511
- return details::WrapCallback([&] {
4556
+ return details::WrapCallback(env, [&] {
4512
4557
  CallbackInfo callbackInfo(env, info);
4513
4558
  InstanceVoidMethodCallbackData* callbackData =
4514
4559
  reinterpret_cast<InstanceVoidMethodCallbackData*>(callbackInfo.Data());
@@ -4523,7 +4568,7 @@ inline napi_value InstanceWrap<T>::InstanceVoidMethodCallbackWrapper(
4523
4568
  template <typename T>
4524
4569
  inline napi_value InstanceWrap<T>::InstanceMethodCallbackWrapper(
4525
4570
  napi_env env, napi_callback_info info) {
4526
- return details::WrapCallback([&] {
4571
+ return details::WrapCallback(env, [&] {
4527
4572
  CallbackInfo callbackInfo(env, info);
4528
4573
  InstanceMethodCallbackData* callbackData =
4529
4574
  reinterpret_cast<InstanceMethodCallbackData*>(callbackInfo.Data());
@@ -4537,7 +4582,7 @@ inline napi_value InstanceWrap<T>::InstanceMethodCallbackWrapper(
4537
4582
  template <typename T>
4538
4583
  inline napi_value InstanceWrap<T>::InstanceGetterCallbackWrapper(
4539
4584
  napi_env env, napi_callback_info info) {
4540
- return details::WrapCallback([&] {
4585
+ return details::WrapCallback(env, [&] {
4541
4586
  CallbackInfo callbackInfo(env, info);
4542
4587
  InstanceAccessorCallbackData* callbackData =
4543
4588
  reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
@@ -4551,7 +4596,7 @@ inline napi_value InstanceWrap<T>::InstanceGetterCallbackWrapper(
4551
4596
  template <typename T>
4552
4597
  inline napi_value InstanceWrap<T>::InstanceSetterCallbackWrapper(
4553
4598
  napi_env env, napi_callback_info info) {
4554
- return details::WrapCallback([&] {
4599
+ return details::WrapCallback(env, [&] {
4555
4600
  CallbackInfo callbackInfo(env, info);
4556
4601
  InstanceAccessorCallbackData* callbackData =
4557
4602
  reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
@@ -4567,7 +4612,7 @@ template <typename T>
4567
4612
  template <typename InstanceWrap<T>::InstanceSetterCallback method>
4568
4613
  inline napi_value InstanceWrap<T>::WrappedMethod(
4569
4614
  napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
4570
- return details::WrapCallback([&] {
4615
+ return details::WrapCallback(env, [&] {
4571
4616
  const CallbackInfo cbInfo(env, info);
4572
4617
  T* instance = T::Unwrap(cbInfo.This().As<Object>());
4573
4618
  if (instance) (instance->*method)(cbInfo, cbInfo[0]);
@@ -4962,13 +5007,13 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
4962
5007
  bool isConstructCall = (new_target != nullptr);
4963
5008
  if (!isConstructCall) {
4964
5009
  return details::WrapCallback(
4965
- [&] { return T::OnCalledAsFunction(CallbackInfo(env, info)); });
5010
+ env, [&] { return T::OnCalledAsFunction(CallbackInfo(env, info)); });
4966
5011
  }
4967
5012
 
4968
- napi_value wrapper = details::WrapCallback([&] {
5013
+ napi_value wrapper = details::WrapCallback(env, [&] {
4969
5014
  CallbackInfo callbackInfo(env, info);
4970
5015
  T* instance = new T(callbackInfo);
4971
- #ifdef NAPI_CPP_EXCEPTIONS
5016
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
4972
5017
  instance->_construction_failed = false;
4973
5018
  #else
4974
5019
  if (callbackInfo.Env().IsExceptionPending()) {
@@ -4979,7 +5024,7 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
4979
5024
  } else {
4980
5025
  instance->_construction_failed = false;
4981
5026
  }
4982
- #endif // NAPI_CPP_EXCEPTIONS
5027
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
4983
5028
  return callbackInfo.This();
4984
5029
  });
4985
5030
 
@@ -4989,7 +5034,7 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
4989
5034
  template <typename T>
4990
5035
  inline napi_value ObjectWrap<T>::StaticVoidMethodCallbackWrapper(
4991
5036
  napi_env env, napi_callback_info info) {
4992
- return details::WrapCallback([&] {
5037
+ return details::WrapCallback(env, [&] {
4993
5038
  CallbackInfo callbackInfo(env, info);
4994
5039
  StaticVoidMethodCallbackData* callbackData =
4995
5040
  reinterpret_cast<StaticVoidMethodCallbackData*>(callbackInfo.Data());
@@ -5002,7 +5047,7 @@ inline napi_value ObjectWrap<T>::StaticVoidMethodCallbackWrapper(
5002
5047
  template <typename T>
5003
5048
  inline napi_value ObjectWrap<T>::StaticMethodCallbackWrapper(
5004
5049
  napi_env env, napi_callback_info info) {
5005
- return details::WrapCallback([&] {
5050
+ return details::WrapCallback(env, [&] {
5006
5051
  CallbackInfo callbackInfo(env, info);
5007
5052
  StaticMethodCallbackData* callbackData =
5008
5053
  reinterpret_cast<StaticMethodCallbackData*>(callbackInfo.Data());
@@ -5014,7 +5059,7 @@ inline napi_value ObjectWrap<T>::StaticMethodCallbackWrapper(
5014
5059
  template <typename T>
5015
5060
  inline napi_value ObjectWrap<T>::StaticGetterCallbackWrapper(
5016
5061
  napi_env env, napi_callback_info info) {
5017
- return details::WrapCallback([&] {
5062
+ return details::WrapCallback(env, [&] {
5018
5063
  CallbackInfo callbackInfo(env, info);
5019
5064
  StaticAccessorCallbackData* callbackData =
5020
5065
  reinterpret_cast<StaticAccessorCallbackData*>(callbackInfo.Data());
@@ -5026,7 +5071,7 @@ inline napi_value ObjectWrap<T>::StaticGetterCallbackWrapper(
5026
5071
  template <typename T>
5027
5072
  inline napi_value ObjectWrap<T>::StaticSetterCallbackWrapper(
5028
5073
  napi_env env, napi_callback_info info) {
5029
- return details::WrapCallback([&] {
5074
+ return details::WrapCallback(env, [&] {
5030
5075
  CallbackInfo callbackInfo(env, info);
5031
5076
  StaticAccessorCallbackData* callbackData =
5032
5077
  reinterpret_cast<StaticAccessorCallbackData*>(callbackInfo.Data());
@@ -5101,7 +5146,7 @@ template <typename T>
5101
5146
  template <typename ObjectWrap<T>::StaticSetterCallback method>
5102
5147
  inline napi_value ObjectWrap<T>::WrappedMethod(
5103
5148
  napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
5104
- return details::WrapCallback([&] {
5149
+ return details::WrapCallback(env, [&] {
5105
5150
  const CallbackInfo cbInfo(env, info);
5106
5151
  // MSVC requires to copy 'method' function pointer to a local variable
5107
5152
  // before invoking it.
@@ -5402,15 +5447,15 @@ inline void AsyncWorker::OnAsyncWorkExecute(napi_env env, void* asyncworker) {
5402
5447
  // must not run any method that would cause JavaScript to run. In practice,
5403
5448
  // this means that almost any use of napi_env will be incorrect.
5404
5449
  inline void AsyncWorker::OnExecute(Napi::Env /*DO_NOT_USE*/) {
5405
- #ifdef NAPI_CPP_EXCEPTIONS
5450
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
5406
5451
  try {
5407
5452
  Execute();
5408
5453
  } catch (const std::exception& e) {
5409
5454
  SetError(e.what());
5410
5455
  }
5411
- #else // NAPI_CPP_EXCEPTIONS
5456
+ #else // NODE_ADDON_API_CPP_EXCEPTIONS
5412
5457
  Execute();
5413
- #endif // NAPI_CPP_EXCEPTIONS
5458
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
5414
5459
  }
5415
5460
 
5416
5461
  inline void AsyncWorker::OnAsyncWorkComplete(napi_env env,
@@ -5419,10 +5464,10 @@ inline void AsyncWorker::OnAsyncWorkComplete(napi_env env,
5419
5464
  AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
5420
5465
  self->OnWorkComplete(env, status);
5421
5466
  }
5422
- inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) {
5467
+ inline void AsyncWorker::OnWorkComplete(Napi::Env env, napi_status status) {
5423
5468
  if (status != napi_cancelled) {
5424
5469
  HandleScope scope(_env);
5425
- details::WrapCallback([&] {
5470
+ details::WrapCallback(env, [&] {
5426
5471
  if (_error.size() == 0) {
5427
5472
  OnOK();
5428
5473
  } else {
@@ -6334,7 +6379,7 @@ inline void ThreadSafeFunction::CallJS(napi_env env,
6334
6379
  return;
6335
6380
  }
6336
6381
 
6337
- details::WrapVoidCallback([&]() {
6382
+ details::WrapVoidCallback(env, [&]() {
6338
6383
  if (data != nullptr) {
6339
6384
  auto* callbackWrapper = static_cast<CallbackWrapper*>(data);
6340
6385
  (*callbackWrapper)(env, Function(env, jsCallback));
package/napi.h CHANGED
@@ -37,22 +37,40 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t),
37
37
  #define NAPI_WIDE_TEXT(x) u##x
38
38
  #endif
39
39
 
40
+ // Backwards-compatibility to handle the rename of this macro definition, in
41
+ // case they are used within userland code.
42
+ #ifdef NAPI_CPP_EXCEPTIONS
43
+ #define NODE_ADDON_API_CPP_EXCEPTIONS
44
+ #endif
45
+ #if defined(NODE_ADDON_API_CPP_EXCEPTIONS) && !defined(NAPI_CPP_EXCEPTIONS)
46
+ #define NAPI_CPP_EXCEPTIONS
47
+ #endif
48
+ #ifdef NAPI_DISABLE_CPP_EXCEPTIONS
49
+ #define NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS
50
+ #endif
51
+ #if defined(NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS) && \
52
+ !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
53
+ #define NAPI_DISABLE_CPP_EXCEPTIONS
54
+ #endif
55
+
40
56
  // If C++ exceptions are not explicitly enabled or disabled, enable them
41
57
  // if exceptions were enabled in the compiler settings.
42
- #if !defined(NAPI_CPP_EXCEPTIONS) && !defined(NAPI_DISABLE_CPP_EXCEPTIONS)
58
+ #if !defined(NODE_ADDON_API_CPP_EXCEPTIONS) && \
59
+ !defined(NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS)
43
60
  #if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
44
- #define NAPI_CPP_EXCEPTIONS
61
+ #define NODE_ADDON_API_CPP_EXCEPTIONS
45
62
  #else
46
63
  #error Exception support not detected. \
47
- Define either NAPI_CPP_EXCEPTIONS or NAPI_DISABLE_CPP_EXCEPTIONS.
64
+ Define either NODE_ADDON_API_CPP_EXCEPTIONS or NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS.
48
65
  #endif
49
66
  #endif
50
67
 
51
- // If C++ NAPI_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE should
52
- // not be set
53
- #if defined(NAPI_CPP_EXCEPTIONS) && defined(NODE_ADDON_API_ENABLE_MAYBE)
68
+ // If C++ NODE_ADDON_API_CPP_EXCEPTIONS are enabled, NODE_ADDON_API_ENABLE_MAYBE
69
+ // should not be set
70
+ #if defined(NODE_ADDON_API_CPP_EXCEPTIONS) && \
71
+ defined(NODE_ADDON_API_ENABLE_MAYBE)
54
72
  #error NODE_ADDON_API_ENABLE_MAYBE should not be set when \
55
- NAPI_CPP_EXCEPTIONS is defined.
73
+ NODE_ADDON_API_CPP_EXCEPTIONS is defined.
56
74
  #endif
57
75
 
58
76
  #ifdef _NOEXCEPT
@@ -61,7 +79,7 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t),
61
79
  #define NAPI_NOEXCEPT noexcept
62
80
  #endif
63
81
 
64
- #ifdef NAPI_CPP_EXCEPTIONS
82
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
65
83
 
66
84
  // When C++ exceptions are enabled, Errors are thrown directly. There is no need
67
85
  // to return anything after the throw statements. The variadic parameter is an
@@ -78,7 +96,7 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t),
78
96
  #define NAPI_THROW_IF_FAILED_VOID(env, status) \
79
97
  if ((status) != napi_ok) throw Napi::Error::New(env);
80
98
 
81
- #else // NAPI_CPP_EXCEPTIONS
99
+ #else // NODE_ADDON_API_CPP_EXCEPTIONS
82
100
 
83
101
  // When C++ exceptions are disabled, Errors are thrown as JavaScript exceptions,
84
102
  // which are pending until the callback returns to JS. The variadic parameter
@@ -110,7 +128,7 @@ static_assert(sizeof(char16_t) == sizeof(wchar_t),
110
128
  return; \
111
129
  }
112
130
 
113
- #endif // NAPI_CPP_EXCEPTIONS
131
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
114
132
 
115
133
  #ifdef NODE_ADDON_API_ENABLE_MAYBE
116
134
  #define NAPI_MAYBE_THROW_IF_FAILED(env, status, type) \
@@ -1068,7 +1086,7 @@ class Object : public TypeTaggable {
1068
1086
  T* data,
1069
1087
  Hint* finalizeHint) const;
1070
1088
 
1071
- #ifdef NAPI_CPP_EXCEPTIONS
1089
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
1072
1090
  class const_iterator;
1073
1091
 
1074
1092
  inline const_iterator begin() const;
@@ -1080,7 +1098,7 @@ class Object : public TypeTaggable {
1080
1098
  inline iterator begin();
1081
1099
 
1082
1100
  inline iterator end();
1083
- #endif // NAPI_CPP_EXCEPTIONS
1101
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
1084
1102
 
1085
1103
  #if NAPI_VERSION >= 8
1086
1104
  /// This operation can fail in case of Proxy.[[GetPrototypeOf]] calling into
@@ -1132,7 +1150,7 @@ class Array : public Object {
1132
1150
  uint32_t Length() const;
1133
1151
  };
1134
1152
 
1135
- #ifdef NAPI_CPP_EXCEPTIONS
1153
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
1136
1154
  class Object::const_iterator {
1137
1155
  private:
1138
1156
  enum class Type { BEGIN, END };
@@ -1179,7 +1197,7 @@ class Object::iterator {
1179
1197
 
1180
1198
  friend class Object;
1181
1199
  };
1182
- #endif // NAPI_CPP_EXCEPTIONS
1200
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
1183
1201
 
1184
1202
  /// A JavaScript array buffer value.
1185
1203
  class ArrayBuffer : public Object {
@@ -1811,14 +1829,15 @@ FunctionReference Persistent(Function value);
1811
1829
  ///
1812
1830
  /// ### Handling Errors Without C++ Exceptions
1813
1831
  ///
1814
- /// If C++ exceptions are disabled (by defining `NAPI_DISABLE_CPP_EXCEPTIONS`)
1815
- /// then this class does not extend `std::exception`, and APIs in the `Napi`
1816
- /// namespace do not throw C++ exceptions when they fail. Instead, they raise
1817
- /// _pending_ JavaScript exceptions and return _empty_ `Value`s. Calling code
1818
- /// should check `Value::IsEmpty()` before attempting to use a returned value,
1819
- /// and may use methods on the `Env` class to check for, get, and clear a
1820
- /// pending JavaScript exception. If the pending exception is not cleared, it
1821
- /// will be thrown when the native callback returns to JavaScript.
1832
+ /// If C++ exceptions are disabled (by defining
1833
+ /// `NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS`) then this class does not extend
1834
+ /// `std::exception`, and APIs in the `Napi` namespace do not throw C++
1835
+ /// exceptions when they fail. Instead, they raise _pending_ JavaScript
1836
+ /// exceptions and return _empty_ `Value`s. Calling code should check
1837
+ /// `Value::IsEmpty()` before attempting to use a returned value, and may use
1838
+ /// methods on the `Env` class to check for, get, and clear a pending JavaScript
1839
+ /// exception. If the pending exception is not cleared, it will be thrown when
1840
+ /// the native callback returns to JavaScript.
1822
1841
  ///
1823
1842
  /// #### Example 1B - Throwing a JS exception
1824
1843
  ///
@@ -1853,10 +1872,10 @@ FunctionReference Persistent(Function value);
1853
1872
  /// Since the exception was cleared here, it will not be propagated as a
1854
1873
  /// JavaScript exception after the native callback returns.
1855
1874
  class Error : public ObjectReference
1856
- #ifdef NAPI_CPP_EXCEPTIONS
1875
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
1857
1876
  ,
1858
1877
  public std::exception
1859
- #endif // NAPI_CPP_EXCEPTIONS
1878
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
1860
1879
  {
1861
1880
  public:
1862
1881
  static Error New(napi_env env);
@@ -1879,9 +1898,9 @@ class Error : public ObjectReference
1879
1898
 
1880
1899
  Object Value() const;
1881
1900
 
1882
- #ifdef NAPI_CPP_EXCEPTIONS
1901
+ #ifdef NODE_ADDON_API_CPP_EXCEPTIONS
1883
1902
  const char* what() const NAPI_NOEXCEPT override;
1884
- #endif // NAPI_CPP_EXCEPTIONS
1903
+ #endif // NODE_ADDON_API_CPP_EXCEPTIONS
1885
1904
 
1886
1905
  protected:
1887
1906
  /// !cond INTERNAL
@@ -18,6 +18,16 @@
18
18
  'includes': ['except.gypi'],
19
19
  }
20
20
  },
21
+ {
22
+ 'target_name': 'node_addon_api_except_all',
23
+ 'type': 'none',
24
+ 'sources': [ 'napi.h', 'napi-inl.h' ],
25
+ 'direct_dependent_settings': {
26
+ 'include_dirs': [ '.' ],
27
+ 'includes': ['except.gypi'],
28
+ 'defines': [ 'NODE_ADDON_API_CPP_EXCEPTIONS_ALL' ]
29
+ }
30
+ },
21
31
  {
22
32
  'target_name': 'node_addon_api_maybe',
23
33
  'type': 'none',
package/noexcept.gypi CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- 'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
2
+ 'defines': [ 'NODE_ADDON_API_DISABLE_CPP_EXCEPTIONS' ],
3
3
  'cflags': [ '-fno-exceptions' ],
4
4
  'cflags_cc': [ '-fno-exceptions' ],
5
5
  'conditions': [
package/package.json CHANGED
@@ -421,16 +421,10 @@
421
421
  "benchmark": "^2.1.4",
422
422
  "bindings": "^1.5.0",
423
423
  "clang-format": "^1.4.0",
424
- "eslint": "^7.32.0",
425
- "eslint-config-semistandard": "^16.0.0",
426
- "eslint-config-standard": "^16.0.3",
427
- "eslint-plugin-import": "^2.24.2",
428
- "eslint-plugin-node": "^11.1.0",
429
- "eslint-plugin-promise": "^5.1.0",
424
+ "eslint": "^9.13.0",
430
425
  "fs-extra": "^11.1.1",
431
- "path": "^0.12.7",
426
+ "neostandard": "^0.11.7",
432
427
  "pre-commit": "^1.2.2",
433
- "safe-buffer": "^5.1.1",
434
428
  "semver": "^7.6.0"
435
429
  },
436
430
  "directories": {},
@@ -474,11 +468,11 @@
474
468
  "predev:incremental": "node-gyp configure build -C test --debug",
475
469
  "dev:incremental": "node test",
476
470
  "doc": "doxygen doc/Doxyfile",
477
- "lint": "node tools/eslint-format && node tools/clang-format",
478
- "lint:fix": "node tools/clang-format --fix && node tools/eslint-format --fix"
471
+ "lint": "eslint && node tools/clang-format",
472
+ "lint:fix": "eslint --fix && node tools/clang-format --fix"
479
473
  },
480
474
  "pre-commit": "lint",
481
- "version": "8.2.2",
475
+ "version": "8.3.0",
482
476
  "support": true,
483
477
  "engines": {
484
478
  "node": "^18 || ^20 || >= 21"
@@ -1,79 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const spawn = require('child_process').spawnSync;
4
-
5
- const filesToCheck = '*.js';
6
- const FORMAT_START = process.env.FORMAT_START || 'main';
7
- const IS_WIN = process.platform === 'win32';
8
- const ESLINT_PATH = IS_WIN ? 'node_modules\\.bin\\eslint.cmd' : 'node_modules/.bin/eslint';
9
-
10
- function main (args) {
11
- let fix = false;
12
- while (args.length > 0) {
13
- switch (args[0]) {
14
- case '-f':
15
- case '--fix':
16
- fix = true;
17
- break;
18
- default:
19
- }
20
- args.shift();
21
- }
22
-
23
- // Check js files that change on unstaged file
24
- const fileUnStaged = spawn(
25
- 'git',
26
- ['diff', '--name-only', '--diff-filter=d', FORMAT_START, filesToCheck],
27
- {
28
- encoding: 'utf-8'
29
- }
30
- );
31
-
32
- // Check js files that change on staged file
33
- const fileStaged = spawn(
34
- 'git',
35
- ['diff', '--name-only', '--cached', '--diff-filter=d', FORMAT_START, filesToCheck],
36
- {
37
- encoding: 'utf-8'
38
- }
39
- );
40
-
41
- const options = [
42
- ...fileStaged.stdout.split('\n').filter((f) => f !== ''),
43
- ...fileUnStaged.stdout.split('\n').filter((f) => f !== '')
44
- ];
45
-
46
- if (fix) {
47
- options.push('--fix');
48
- }
49
-
50
- const result = spawn(ESLINT_PATH, [...options], {
51
- encoding: 'utf-8'
52
- });
53
-
54
- if (result.error && result.error.errno === 'ENOENT') {
55
- console.error('Eslint not found! Eslint is supposed to be found at ', ESLINT_PATH);
56
- return 2;
57
- }
58
-
59
- if (result.status === 1) {
60
- console.error('Eslint error:', result.stdout);
61
- const fixCmd = 'npm run lint:fix';
62
- console.error(`ERROR: please run "${fixCmd}" to format changes in your commit
63
- Note that when running the command locally, please keep your local
64
- main branch and working branch up to date with nodejs/node-addon-api
65
- to exclude un-related complains.
66
- Or you can run "env FORMAT_START=upstream/main ${fixCmd}".
67
- Also fix JS files by yourself if necessary.`);
68
- return 1;
69
- }
70
-
71
- if (result.stderr) {
72
- console.error('Error running eslint:', result.stderr);
73
- return 2;
74
- }
75
- }
76
-
77
- if (require.main === module) {
78
- process.exitCode = main(process.argv.slice(2));
79
- }