@basemaps/lambda-tiler 6.19.0 → 6.20.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.
Files changed (157) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +2 -2
  3. package/build/__test__/tile.style.json.test.d.ts +2 -0
  4. package/build/__test__/tile.style.json.test.d.ts.map +1 -0
  5. package/build/__test__/tile.style.json.test.js +33 -0
  6. package/build/__test__/xyz.test.js +24 -23
  7. package/build/cli/dump.js +2 -2
  8. package/build/index.d.ts.map +1 -1
  9. package/build/index.js +2 -0
  10. package/build/routes/esri/rest.d.ts +10 -0
  11. package/build/routes/esri/rest.d.ts.map +1 -0
  12. package/build/routes/esri/rest.js +87 -0
  13. package/build/routes/imagery.d.ts +2 -0
  14. package/build/routes/imagery.d.ts.map +1 -1
  15. package/build/routes/imagery.js +3 -1
  16. package/build/routes/response.d.ts +4 -0
  17. package/build/routes/response.d.ts.map +1 -0
  18. package/build/routes/response.js +3 -0
  19. package/build/routes/tile.d.ts +0 -20
  20. package/build/routes/tile.d.ts.map +1 -1
  21. package/build/routes/tile.js +11 -161
  22. package/build/routes/tile.json.d.ts +10 -0
  23. package/build/routes/tile.json.d.ts.map +1 -0
  24. package/build/routes/tile.json.js +31 -0
  25. package/build/routes/tile.style.json.d.ts +10 -0
  26. package/build/routes/tile.style.json.d.ts.map +1 -0
  27. package/build/routes/tile.style.json.js +74 -0
  28. package/build/routes/tile.wmts.d.ts +9 -0
  29. package/build/routes/tile.wmts.d.ts.map +1 -0
  30. package/build/routes/tile.wmts.js +57 -0
  31. package/build/routes/tile.xyz.d.ts +13 -0
  32. package/build/routes/tile.xyz.d.ts.map +1 -0
  33. package/build/routes/tile.xyz.js +28 -0
  34. package/build/tile.set.raster.d.ts +2 -0
  35. package/build/tile.set.raster.d.ts.map +1 -1
  36. package/build/tile.set.raster.js +3 -1
  37. package/build/tile.set.vector.js +1 -1
  38. package/dist/index.js +10545 -9583
  39. package/dist/node_modules/color/README.md +7 -7
  40. package/dist/node_modules/color/index.js +173 -158
  41. package/dist/node_modules/color/package.json +18 -16
  42. package/dist/node_modules/color-convert/conversions.js +281 -310
  43. package/dist/node_modules/color-convert/index.js +27 -24
  44. package/dist/node_modules/color-convert/package.json +16 -14
  45. package/dist/node_modules/color-convert/route.js +22 -22
  46. package/dist/node_modules/color-name/package.json +17 -14
  47. package/dist/node_modules/color-string/package.json +5 -5
  48. package/dist/node_modules/decompress-response/index.d.ts +14 -21
  49. package/dist/node_modules/decompress-response/index.js +34 -16
  50. package/dist/node_modules/decompress-response/license +1 -1
  51. package/dist/node_modules/decompress-response/package.json +23 -17
  52. package/dist/node_modules/decompress-response/readme.md +2 -6
  53. package/dist/node_modules/detect-libc/package.json +0 -1
  54. package/dist/node_modules/mimic-response/index.d.ts +2 -2
  55. package/dist/node_modules/mimic-response/index.js +41 -2
  56. package/dist/node_modules/mimic-response/package.json +17 -17
  57. package/dist/node_modules/mimic-response/readme.md +22 -1
  58. package/dist/node_modules/node-abi/.circleci/config.yml +63 -0
  59. package/dist/node_modules/node-abi/.releaserc.json +9 -0
  60. package/dist/node_modules/node-abi/abi_registry.json +39 -4
  61. package/dist/node_modules/node-abi/index.js +5 -2
  62. package/dist/node_modules/node-abi/package.json +17 -16
  63. package/dist/node_modules/node-abi/test/index.js +7 -15
  64. package/dist/node_modules/node-addon-api/README.md +2 -2
  65. package/dist/node_modules/node-addon-api/except.gypi +20 -11
  66. package/dist/node_modules/node-addon-api/napi-inl.h +734 -196
  67. package/dist/node_modules/node-addon-api/napi.h +420 -164
  68. package/dist/node_modules/node-addon-api/noexcept.gypi +21 -11
  69. package/dist/node_modules/node-addon-api/package.json +43 -14
  70. package/dist/node_modules/node-addon-api/tools/clang-format.js +18 -17
  71. package/dist/node_modules/node-addon-api/tools/eslint-format.js +71 -0
  72. package/dist/node_modules/prebuild-install/CHANGELOG.md +24 -7
  73. package/dist/node_modules/prebuild-install/README.md +24 -4
  74. package/dist/node_modules/prebuild-install/asset.js +10 -10
  75. package/dist/node_modules/prebuild-install/bin.js +13 -13
  76. package/dist/node_modules/prebuild-install/download.js +22 -22
  77. package/dist/node_modules/prebuild-install/log.js +4 -4
  78. package/dist/node_modules/prebuild-install/node_modules/detect-libc/LICENSE +201 -0
  79. package/dist/node_modules/prebuild-install/node_modules/detect-libc/README.md +160 -0
  80. package/dist/node_modules/prebuild-install/node_modules/detect-libc/index.d.ts +11 -0
  81. package/dist/node_modules/prebuild-install/node_modules/detect-libc/lib/detect-libc.js +178 -0
  82. package/dist/node_modules/prebuild-install/node_modules/detect-libc/lib/process.js +16 -0
  83. package/dist/node_modules/prebuild-install/node_modules/detect-libc/package.json +71 -0
  84. package/dist/node_modules/prebuild-install/package.json +18 -19
  85. package/dist/node_modules/prebuild-install/proxy.js +10 -10
  86. package/dist/node_modules/prebuild-install/rc.js +12 -12
  87. package/dist/node_modules/prebuild-install/util.js +14 -14
  88. package/dist/node_modules/semver/package.json +1 -0
  89. package/dist/node_modules/sharp/README.md +2 -2
  90. package/dist/node_modules/sharp/binding.gyp +12 -9
  91. package/dist/node_modules/sharp/build/Release/sharp-linux-x64.node +0 -0
  92. package/dist/node_modules/sharp/install/dll-copy.js +6 -6
  93. package/dist/node_modules/sharp/install/libvips.js +4 -8
  94. package/dist/node_modules/sharp/lib/channel.js +11 -7
  95. package/dist/node_modules/sharp/lib/colour.js +42 -1
  96. package/dist/node_modules/sharp/lib/constructor.js +18 -31
  97. package/dist/node_modules/sharp/lib/input.js +45 -3
  98. package/dist/node_modules/sharp/lib/is.js +19 -5
  99. package/dist/node_modules/sharp/lib/libvips.js +4 -19
  100. package/dist/node_modules/sharp/lib/operation.js +28 -5
  101. package/dist/node_modules/sharp/lib/output.js +147 -16
  102. package/dist/node_modules/sharp/lib/sharp.js +31 -0
  103. package/dist/node_modules/sharp/lib/utility.js +3 -2
  104. package/dist/node_modules/sharp/package.json +32 -23
  105. package/dist/node_modules/sharp/src/common.cc +67 -11
  106. package/dist/node_modules/sharp/src/common.h +25 -5
  107. package/dist/node_modules/sharp/src/libvips/cplusplus/VConnection.cpp +0 -26
  108. package/dist/node_modules/sharp/src/libvips/cplusplus/VImage.cpp +54 -16
  109. package/dist/node_modules/sharp/src/libvips/cplusplus/VInterpolate.cpp +0 -13
  110. package/dist/node_modules/sharp/src/libvips/cplusplus/vips-operators.cpp +185 -1
  111. package/dist/node_modules/sharp/src/metadata.cc +14 -0
  112. package/dist/node_modules/sharp/src/metadata.h +1 -0
  113. package/dist/node_modules/sharp/src/operations.cc +29 -3
  114. package/dist/node_modules/sharp/src/operations.h +13 -2
  115. package/dist/node_modules/sharp/src/pipeline.cc +103 -35
  116. package/dist/node_modules/sharp/src/pipeline.h +23 -3
  117. package/dist/node_modules/sharp/src/utilities.cc +1 -1
  118. package/dist/node_modules/sharp/vendor/{8.10.6 → 8.11.3/linux-x64}/THIRD-PARTY-NOTICES.md +2 -3
  119. package/dist/node_modules/sharp/vendor/{8.10.6 → 8.11.3/linux-x64}/lib/libvips-cpp.so.42 +0 -0
  120. package/dist/node_modules/sharp/vendor/{8.10.6 → 8.11.3/linux-x64}/platform.json +0 -0
  121. package/dist/node_modules/sharp/vendor/8.11.3/linux-x64/versions.json +30 -0
  122. package/dist/node_modules/simple-get/.github/dependabot.yml +15 -0
  123. package/dist/node_modules/simple-get/.github/workflows/ci.yml +23 -0
  124. package/dist/node_modules/simple-get/README.md +17 -3
  125. package/dist/node_modules/simple-get/index.js +9 -0
  126. package/dist/node_modules/simple-get/package.json +27 -13
  127. package/dist/package-lock.json +51 -51
  128. package/dist/package.json +9 -9
  129. package/package.json +10 -10
  130. package/src/__test__/tile.style.json.test.ts +40 -0
  131. package/src/__test__/xyz.test.ts +32 -30
  132. package/src/cli/dump.ts +2 -2
  133. package/src/index.ts +2 -0
  134. package/src/routes/esri/rest.ts +90 -0
  135. package/src/routes/imagery.ts +3 -1
  136. package/src/routes/response.ts +4 -0
  137. package/src/routes/tile.json.ts +44 -0
  138. package/src/routes/tile.style.json.ts +77 -0
  139. package/src/routes/tile.ts +11 -183
  140. package/src/routes/tile.wmts.ts +59 -0
  141. package/src/routes/tile.xyz.ts +30 -0
  142. package/src/tile.set.raster.ts +4 -1
  143. package/src/tile.set.vector.ts +1 -1
  144. package/tsconfig.tsbuildinfo +1 -1
  145. package/dist/node_modules/color-name/.eslintrc.json +0 -43
  146. package/dist/node_modules/color-name/test.js +0 -7
  147. package/dist/node_modules/node-abi/.travis.yml +0 -17
  148. package/dist/node_modules/node-abi/node_modules/semver/CHANGELOG.md +0 -39
  149. package/dist/node_modules/node-abi/node_modules/semver/LICENSE +0 -15
  150. package/dist/node_modules/node-abi/node_modules/semver/README.md +0 -412
  151. package/dist/node_modules/node-abi/node_modules/semver/bin/semver +0 -160
  152. package/dist/node_modules/node-abi/node_modules/semver/package.json +0 -60
  153. package/dist/node_modules/node-abi/node_modules/semver/range.bnf +0 -16
  154. package/dist/node_modules/node-abi/node_modules/semver/semver.js +0 -1483
  155. package/dist/node_modules/node-addon-api/CHANGELOG.md +0 -722
  156. package/dist/node_modules/sharp/build/Release/sharp.node +0 -0
  157. package/dist/node_modules/sharp/vendor/8.10.6/versions.json +0 -31
@@ -14,6 +14,7 @@
14
14
  #include <cstring>
15
15
  #include <mutex>
16
16
  #include <type_traits>
17
+ #include <utility>
17
18
 
18
19
  namespace Napi {
19
20
 
@@ -377,6 +378,72 @@ inline napi_value RegisterModule(napi_env env,
377
378
  });
378
379
  }
379
380
 
381
+ ////////////////////////////////////////////////////////////////////////////////
382
+ // Maybe class
383
+ ////////////////////////////////////////////////////////////////////////////////
384
+
385
+ template <class T>
386
+ bool Maybe<T>::IsNothing() const {
387
+ return !_has_value;
388
+ }
389
+
390
+ template <class T>
391
+ bool Maybe<T>::IsJust() const {
392
+ return _has_value;
393
+ }
394
+
395
+ template <class T>
396
+ void Maybe<T>::Check() const {
397
+ NAPI_CHECK(IsJust(), "Napi::Maybe::Check", "Maybe value is Nothing.");
398
+ }
399
+
400
+ template <class T>
401
+ T Maybe<T>::Unwrap() const {
402
+ NAPI_CHECK(IsJust(), "Napi::Maybe::Unwrap", "Maybe value is Nothing.");
403
+ return _value;
404
+ }
405
+
406
+ template <class T>
407
+ T Maybe<T>::UnwrapOr(const T& default_value) const {
408
+ return _has_value ? _value : default_value;
409
+ }
410
+
411
+ template <class T>
412
+ bool Maybe<T>::UnwrapTo(T* out) const {
413
+ if (IsJust()) {
414
+ *out = _value;
415
+ return true;
416
+ };
417
+ return false;
418
+ }
419
+
420
+ template <class T>
421
+ bool Maybe<T>::operator==(const Maybe& other) const {
422
+ return (IsJust() == other.IsJust()) &&
423
+ (!IsJust() || Unwrap() == other.Unwrap());
424
+ }
425
+
426
+ template <class T>
427
+ bool Maybe<T>::operator!=(const Maybe& other) const {
428
+ return !operator==(other);
429
+ }
430
+
431
+ template <class T>
432
+ Maybe<T>::Maybe() : _has_value(false) {}
433
+
434
+ template <class T>
435
+ Maybe<T>::Maybe(const T& t) : _has_value(true), _value(t) {}
436
+
437
+ template <class T>
438
+ inline Maybe<T> Nothing() {
439
+ return Maybe<T>();
440
+ }
441
+
442
+ template <class T>
443
+ inline Maybe<T> Just(const T& t) {
444
+ return Maybe<T>(t);
445
+ }
446
+
380
447
  ////////////////////////////////////////////////////////////////////////////////
381
448
  // Env class
382
449
  ////////////////////////////////////////////////////////////////////////////////
@@ -426,21 +493,41 @@ inline Error Env::GetAndClearPendingException() {
426
493
  return Error(_env, value);
427
494
  }
428
495
 
429
- inline Value Env::RunScript(const char* utf8script) {
496
+ inline MaybeOrValue<Value> Env::RunScript(const char* utf8script) {
430
497
  String script = String::New(_env, utf8script);
431
498
  return RunScript(script);
432
499
  }
433
500
 
434
- inline Value Env::RunScript(const std::string& utf8script) {
501
+ inline MaybeOrValue<Value> Env::RunScript(const std::string& utf8script) {
435
502
  return RunScript(utf8script.c_str());
436
503
  }
437
504
 
438
- inline Value Env::RunScript(String script) {
505
+ inline MaybeOrValue<Value> Env::RunScript(String script) {
439
506
  napi_value result;
440
507
  napi_status status = napi_run_script(_env, script, &result);
441
- NAPI_THROW_IF_FAILED(_env, status, Undefined());
442
- return Value(_env, result);
508
+ NAPI_RETURN_OR_THROW_IF_FAILED(
509
+ _env, status, Napi::Value(_env, result), Napi::Value);
510
+ }
511
+
512
+ #if NAPI_VERSION > 2
513
+ template <typename Hook, typename Arg>
514
+ void Env::CleanupHook<Hook, Arg>::Wrapper(void* data) NAPI_NOEXCEPT {
515
+ auto* cleanupData =
516
+ static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(
517
+ data);
518
+ cleanupData->hook();
519
+ delete cleanupData;
520
+ }
521
+
522
+ template <typename Hook, typename Arg>
523
+ void Env::CleanupHook<Hook, Arg>::WrapperWithArg(void* data) NAPI_NOEXCEPT {
524
+ auto* cleanupData =
525
+ static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(
526
+ data);
527
+ cleanupData->hook(static_cast<Arg*>(cleanupData->arg));
528
+ delete cleanupData;
443
529
  }
530
+ #endif // NAPI_VERSION > 2
444
531
 
445
532
  #if NAPI_VERSION > 5
446
533
  template <typename T, Env::Finalizer<T> fini>
@@ -658,32 +745,32 @@ inline T Value::As() const {
658
745
  return T(_env, _value);
659
746
  }
660
747
 
661
- inline Boolean Value::ToBoolean() const {
748
+ inline MaybeOrValue<Boolean> Value::ToBoolean() const {
662
749
  napi_value result;
663
750
  napi_status status = napi_coerce_to_bool(_env, _value, &result);
664
- NAPI_THROW_IF_FAILED(_env, status, Boolean());
665
- return Boolean(_env, result);
751
+ NAPI_RETURN_OR_THROW_IF_FAILED(
752
+ _env, status, Napi::Boolean(_env, result), Napi::Boolean);
666
753
  }
667
754
 
668
- inline Number Value::ToNumber() const {
755
+ inline MaybeOrValue<Number> Value::ToNumber() const {
669
756
  napi_value result;
670
757
  napi_status status = napi_coerce_to_number(_env, _value, &result);
671
- NAPI_THROW_IF_FAILED(_env, status, Number());
672
- return Number(_env, result);
758
+ NAPI_RETURN_OR_THROW_IF_FAILED(
759
+ _env, status, Napi::Number(_env, result), Napi::Number);
673
760
  }
674
761
 
675
- inline String Value::ToString() const {
762
+ inline MaybeOrValue<String> Value::ToString() const {
676
763
  napi_value result;
677
764
  napi_status status = napi_coerce_to_string(_env, _value, &result);
678
- NAPI_THROW_IF_FAILED(_env, status, String());
679
- return String(_env, result);
765
+ NAPI_RETURN_OR_THROW_IF_FAILED(
766
+ _env, status, Napi::String(_env, result), Napi::String);
680
767
  }
681
768
 
682
- inline Object Value::ToObject() const {
769
+ inline MaybeOrValue<Object> Value::ToObject() const {
683
770
  napi_value result;
684
771
  napi_status status = napi_coerce_to_object(_env, _value, &result);
685
- NAPI_THROW_IF_FAILED(_env, status, Object());
686
- return Object(_env, result);
772
+ NAPI_RETURN_OR_THROW_IF_FAILED(
773
+ _env, status, Napi::Object(_env, result), Napi::Object);
687
774
  }
688
775
 
689
776
  ////////////////////////////////////////////////////////////////////////////////
@@ -900,6 +987,12 @@ inline String String::New(napi_env env, const std::u16string& val) {
900
987
  }
901
988
 
902
989
  inline String String::New(napi_env env, const char* val) {
990
+ // TODO(@gabrielschulhof) Remove if-statement when core's error handling is
991
+ // available in all supported versions.
992
+ if (val == nullptr) {
993
+ // Throw an error that looks like it came from core.
994
+ NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());
995
+ }
903
996
  napi_value value;
904
997
  napi_status status = napi_create_string_utf8(env, val, std::strlen(val), &value);
905
998
  NAPI_THROW_IF_FAILED(env, status, String());
@@ -908,6 +1001,12 @@ inline String String::New(napi_env env, const char* val) {
908
1001
 
909
1002
  inline String String::New(napi_env env, const char16_t* val) {
910
1003
  napi_value value;
1004
+ // TODO(@gabrielschulhof) Remove if-statement when core's error handling is
1005
+ // available in all supported versions.
1006
+ if (val == nullptr) {
1007
+ // Throw an error that looks like it came from core.
1008
+ NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());
1009
+ }
911
1010
  napi_status status = napi_create_string_utf16(env, val, std::u16string(val).size(), &value);
912
1011
  NAPI_THROW_IF_FAILED(env, status, String());
913
1012
  return String(env, value);
@@ -994,8 +1093,56 @@ inline Symbol Symbol::New(napi_env env, napi_value description) {
994
1093
  return Symbol(env, value);
995
1094
  }
996
1095
 
997
- inline Symbol Symbol::WellKnown(napi_env env, const std::string& name) {
1096
+ inline MaybeOrValue<Symbol> Symbol::WellKnown(napi_env env,
1097
+ const std::string& name) {
1098
+ #if defined(NODE_ADDON_API_ENABLE_MAYBE)
1099
+ Value symbol_obj;
1100
+ Value symbol_value;
1101
+ if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
1102
+ symbol_obj.As<Object>().Get(name).UnwrapTo(&symbol_value)) {
1103
+ return Just<Symbol>(symbol_value.As<Symbol>());
1104
+ }
1105
+ return Nothing<Symbol>();
1106
+ #else
998
1107
  return Napi::Env(env).Global().Get("Symbol").As<Object>().Get(name).As<Symbol>();
1108
+ #endif
1109
+ }
1110
+
1111
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env,
1112
+ const std::string& description) {
1113
+ napi_value descriptionValue = String::New(env, description);
1114
+ return Symbol::For(env, descriptionValue);
1115
+ }
1116
+
1117
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, const char* description) {
1118
+ napi_value descriptionValue = String::New(env, description);
1119
+ return Symbol::For(env, descriptionValue);
1120
+ }
1121
+
1122
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, String description) {
1123
+ return Symbol::For(env, static_cast<napi_value>(description));
1124
+ }
1125
+
1126
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, napi_value description) {
1127
+ #if defined(NODE_ADDON_API_ENABLE_MAYBE)
1128
+ Value symbol_obj;
1129
+ Value symbol_for_value;
1130
+ Value symbol_value;
1131
+ if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
1132
+ symbol_obj.As<Object>().Get("for").UnwrapTo(&symbol_for_value) &&
1133
+ symbol_for_value.As<Function>()
1134
+ .Call(symbol_obj, {description})
1135
+ .UnwrapTo(&symbol_value)) {
1136
+ return Just<Symbol>(symbol_value.As<Symbol>());
1137
+ }
1138
+ return Nothing<Symbol>();
1139
+ #else
1140
+ Object symbol_obj = Napi::Env(env).Global().Get("Symbol").As<Object>();
1141
+ return symbol_obj.Get("for")
1142
+ .As<Function>()
1143
+ .Call(symbol_obj, {description})
1144
+ .As<Symbol>();
1145
+ #endif
999
1146
  }
1000
1147
 
1001
1148
  inline Symbol::Symbol() : Name() {
@@ -1110,12 +1257,23 @@ String String::From(napi_env env, const T& value) {
1110
1257
 
1111
1258
  template <typename Key>
1112
1259
  inline Object::PropertyLValue<Key>::operator Value() const {
1113
- return Object(_env, _object).Get(_key);
1260
+ MaybeOrValue<Value> val = Object(_env, _object).Get(_key);
1261
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
1262
+ return val.Unwrap();
1263
+ #else
1264
+ return val;
1265
+ #endif
1114
1266
  }
1115
1267
 
1116
1268
  template <typename Key> template <typename ValueType>
1117
1269
  inline Object::PropertyLValue<Key>& Object::PropertyLValue<Key>::operator =(ValueType value) {
1118
- Object(_env, _object).Set(_key, value);
1270
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
1271
+ MaybeOrValue<bool> result =
1272
+ #endif
1273
+ Object(_env, _object).Set(_key, value);
1274
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
1275
+ result.Unwrap();
1276
+ #endif
1119
1277
  return *this;
1120
1278
  }
1121
1279
 
@@ -1148,208 +1306,200 @@ inline Object::PropertyLValue<uint32_t> Object::operator [](uint32_t index) {
1148
1306
  return PropertyLValue<uint32_t>(*this, index);
1149
1307
  }
1150
1308
 
1151
- inline Value Object::operator [](const char* utf8name) const {
1309
+ inline Object::PropertyLValue<Value> Object::operator[](Value index) {
1310
+ return PropertyLValue<Value>(*this, index);
1311
+ }
1312
+
1313
+ inline Object::PropertyLValue<Value> Object::operator[](Value index) const {
1314
+ return PropertyLValue<Value>(*this, index);
1315
+ }
1316
+
1317
+ inline MaybeOrValue<Value> Object::operator[](const char* utf8name) const {
1152
1318
  return Get(utf8name);
1153
1319
  }
1154
1320
 
1155
- inline Value Object::operator [](const std::string& utf8name) const {
1321
+ inline MaybeOrValue<Value> Object::operator[](
1322
+ const std::string& utf8name) const {
1156
1323
  return Get(utf8name);
1157
1324
  }
1158
1325
 
1159
- inline Value Object::operator [](uint32_t index) const {
1326
+ inline MaybeOrValue<Value> Object::operator[](uint32_t index) const {
1160
1327
  return Get(index);
1161
1328
  }
1162
1329
 
1163
- inline bool Object::Has(napi_value key) const {
1330
+ inline MaybeOrValue<bool> Object::Has(napi_value key) const {
1164
1331
  bool result;
1165
1332
  napi_status status = napi_has_property(_env, _value, key, &result);
1166
- NAPI_THROW_IF_FAILED(_env, status, false);
1167
- return result;
1333
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1168
1334
  }
1169
1335
 
1170
- inline bool Object::Has(Value key) const {
1336
+ inline MaybeOrValue<bool> Object::Has(Value key) const {
1171
1337
  bool result;
1172
1338
  napi_status status = napi_has_property(_env, _value, key, &result);
1173
- NAPI_THROW_IF_FAILED(_env, status, false);
1174
- return result;
1339
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1175
1340
  }
1176
1341
 
1177
- inline bool Object::Has(const char* utf8name) const {
1342
+ inline MaybeOrValue<bool> Object::Has(const char* utf8name) const {
1178
1343
  bool result;
1179
1344
  napi_status status = napi_has_named_property(_env, _value, utf8name, &result);
1180
- NAPI_THROW_IF_FAILED(_env, status, false);
1181
- return result;
1345
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1182
1346
  }
1183
1347
 
1184
- inline bool Object::Has(const std::string& utf8name) const {
1348
+ inline MaybeOrValue<bool> Object::Has(const std::string& utf8name) const {
1185
1349
  return Has(utf8name.c_str());
1186
1350
  }
1187
1351
 
1188
- inline bool Object::HasOwnProperty(napi_value key) const {
1352
+ inline MaybeOrValue<bool> Object::HasOwnProperty(napi_value key) const {
1189
1353
  bool result;
1190
1354
  napi_status status = napi_has_own_property(_env, _value, key, &result);
1191
- NAPI_THROW_IF_FAILED(_env, status, false);
1192
- return result;
1355
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1193
1356
  }
1194
1357
 
1195
- inline bool Object::HasOwnProperty(Value key) const {
1358
+ inline MaybeOrValue<bool> Object::HasOwnProperty(Value key) const {
1196
1359
  bool result;
1197
1360
  napi_status status = napi_has_own_property(_env, _value, key, &result);
1198
- NAPI_THROW_IF_FAILED(_env, status, false);
1199
- return result;
1361
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1200
1362
  }
1201
1363
 
1202
- inline bool Object::HasOwnProperty(const char* utf8name) const {
1364
+ inline MaybeOrValue<bool> Object::HasOwnProperty(const char* utf8name) const {
1203
1365
  napi_value key;
1204
1366
  napi_status status = napi_create_string_utf8(_env, utf8name, std::strlen(utf8name), &key);
1205
- NAPI_THROW_IF_FAILED(_env, status, false);
1367
+ NAPI_MAYBE_THROW_IF_FAILED(_env, status, bool);
1206
1368
  return HasOwnProperty(key);
1207
1369
  }
1208
1370
 
1209
- inline bool Object::HasOwnProperty(const std::string& utf8name) const {
1371
+ inline MaybeOrValue<bool> Object::HasOwnProperty(
1372
+ const std::string& utf8name) const {
1210
1373
  return HasOwnProperty(utf8name.c_str());
1211
1374
  }
1212
1375
 
1213
- inline Value Object::Get(napi_value key) const {
1376
+ inline MaybeOrValue<Value> Object::Get(napi_value key) const {
1214
1377
  napi_value result;
1215
1378
  napi_status status = napi_get_property(_env, _value, key, &result);
1216
- NAPI_THROW_IF_FAILED(_env, status, Value());
1217
- return Value(_env, result);
1379
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1218
1380
  }
1219
1381
 
1220
- inline Value Object::Get(Value key) const {
1382
+ inline MaybeOrValue<Value> Object::Get(Value key) const {
1221
1383
  napi_value result;
1222
1384
  napi_status status = napi_get_property(_env, _value, key, &result);
1223
- NAPI_THROW_IF_FAILED(_env, status, Value());
1224
- return Value(_env, result);
1385
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1225
1386
  }
1226
1387
 
1227
- inline Value Object::Get(const char* utf8name) const {
1388
+ inline MaybeOrValue<Value> Object::Get(const char* utf8name) const {
1228
1389
  napi_value result;
1229
1390
  napi_status status = napi_get_named_property(_env, _value, utf8name, &result);
1230
- NAPI_THROW_IF_FAILED(_env, status, Value());
1231
- return Value(_env, result);
1391
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1232
1392
  }
1233
1393
 
1234
- inline Value Object::Get(const std::string& utf8name) const {
1394
+ inline MaybeOrValue<Value> Object::Get(const std::string& utf8name) const {
1235
1395
  return Get(utf8name.c_str());
1236
1396
  }
1237
1397
 
1238
1398
  template <typename ValueType>
1239
- inline bool Object::Set(napi_value key, const ValueType& value) {
1399
+ inline MaybeOrValue<bool> Object::Set(napi_value key, const ValueType& value) {
1240
1400
  napi_status status =
1241
1401
  napi_set_property(_env, _value, key, Value::From(_env, value));
1242
- NAPI_THROW_IF_FAILED(_env, status, false);
1243
- return true;
1402
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1244
1403
  }
1245
1404
 
1246
1405
  template <typename ValueType>
1247
- inline bool Object::Set(Value key, const ValueType& value) {
1406
+ inline MaybeOrValue<bool> Object::Set(Value key, const ValueType& value) {
1248
1407
  napi_status status =
1249
1408
  napi_set_property(_env, _value, key, Value::From(_env, value));
1250
- NAPI_THROW_IF_FAILED(_env, status, false);
1251
- return true;
1409
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1252
1410
  }
1253
1411
 
1254
1412
  template <typename ValueType>
1255
- inline bool Object::Set(const char* utf8name, const ValueType& value) {
1413
+ inline MaybeOrValue<bool> Object::Set(const char* utf8name,
1414
+ const ValueType& value) {
1256
1415
  napi_status status =
1257
1416
  napi_set_named_property(_env, _value, utf8name, Value::From(_env, value));
1258
- NAPI_THROW_IF_FAILED(_env, status, false);
1259
- return true;
1417
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1260
1418
  }
1261
1419
 
1262
1420
  template <typename ValueType>
1263
- inline bool Object::Set(const std::string& utf8name, const ValueType& value) {
1421
+ inline MaybeOrValue<bool> Object::Set(const std::string& utf8name,
1422
+ const ValueType& value) {
1264
1423
  return Set(utf8name.c_str(), value);
1265
1424
  }
1266
1425
 
1267
- inline bool Object::Delete(napi_value key) {
1426
+ inline MaybeOrValue<bool> Object::Delete(napi_value key) {
1268
1427
  bool result;
1269
1428
  napi_status status = napi_delete_property(_env, _value, key, &result);
1270
- NAPI_THROW_IF_FAILED(_env, status, false);
1271
- return result;
1429
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1272
1430
  }
1273
1431
 
1274
- inline bool Object::Delete(Value key) {
1432
+ inline MaybeOrValue<bool> Object::Delete(Value key) {
1275
1433
  bool result;
1276
1434
  napi_status status = napi_delete_property(_env, _value, key, &result);
1277
- NAPI_THROW_IF_FAILED(_env, status, false);
1278
- return result;
1435
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1279
1436
  }
1280
1437
 
1281
- inline bool Object::Delete(const char* utf8name) {
1438
+ inline MaybeOrValue<bool> Object::Delete(const char* utf8name) {
1282
1439
  return Delete(String::New(_env, utf8name));
1283
1440
  }
1284
1441
 
1285
- inline bool Object::Delete(const std::string& utf8name) {
1442
+ inline MaybeOrValue<bool> Object::Delete(const std::string& utf8name) {
1286
1443
  return Delete(String::New(_env, utf8name));
1287
1444
  }
1288
1445
 
1289
- inline bool Object::Has(uint32_t index) const {
1446
+ inline MaybeOrValue<bool> Object::Has(uint32_t index) const {
1290
1447
  bool result;
1291
1448
  napi_status status = napi_has_element(_env, _value, index, &result);
1292
- NAPI_THROW_IF_FAILED(_env, status, false);
1293
- return result;
1449
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1294
1450
  }
1295
1451
 
1296
- inline Value Object::Get(uint32_t index) const {
1452
+ inline MaybeOrValue<Value> Object::Get(uint32_t index) const {
1297
1453
  napi_value value;
1298
1454
  napi_status status = napi_get_element(_env, _value, index, &value);
1299
- NAPI_THROW_IF_FAILED(_env, status, Value());
1300
- return Value(_env, value);
1455
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, value), Value);
1301
1456
  }
1302
1457
 
1303
1458
  template <typename ValueType>
1304
- inline bool Object::Set(uint32_t index, const ValueType& value) {
1459
+ inline MaybeOrValue<bool> Object::Set(uint32_t index, const ValueType& value) {
1305
1460
  napi_status status =
1306
1461
  napi_set_element(_env, _value, index, Value::From(_env, value));
1307
- NAPI_THROW_IF_FAILED(_env, status, false);
1308
- return true;
1462
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1309
1463
  }
1310
1464
 
1311
- inline bool Object::Delete(uint32_t index) {
1465
+ inline MaybeOrValue<bool> Object::Delete(uint32_t index) {
1312
1466
  bool result;
1313
1467
  napi_status status = napi_delete_element(_env, _value, index, &result);
1314
- NAPI_THROW_IF_FAILED(_env, status, false);
1315
- return result;
1468
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1316
1469
  }
1317
1470
 
1318
- inline Array Object::GetPropertyNames() const {
1471
+ inline MaybeOrValue<Array> Object::GetPropertyNames() const {
1319
1472
  napi_value result;
1320
1473
  napi_status status = napi_get_property_names(_env, _value, &result);
1321
- NAPI_THROW_IF_FAILED(_env, status, Array());
1322
- return Array(_env, result);
1474
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Array(_env, result), Array);
1323
1475
  }
1324
1476
 
1325
- inline bool Object::DefineProperty(const PropertyDescriptor& property) {
1477
+ inline MaybeOrValue<bool> Object::DefineProperty(
1478
+ const PropertyDescriptor& property) {
1326
1479
  napi_status status = napi_define_properties(_env, _value, 1,
1327
1480
  reinterpret_cast<const napi_property_descriptor*>(&property));
1328
- NAPI_THROW_IF_FAILED(_env, status, false);
1329
- return true;
1481
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1330
1482
  }
1331
1483
 
1332
- inline bool Object::DefineProperties(
1484
+ inline MaybeOrValue<bool> Object::DefineProperties(
1333
1485
  const std::initializer_list<PropertyDescriptor>& properties) {
1334
1486
  napi_status status = napi_define_properties(_env, _value, properties.size(),
1335
1487
  reinterpret_cast<const napi_property_descriptor*>(properties.begin()));
1336
- NAPI_THROW_IF_FAILED(_env, status, false);
1337
- return true;
1488
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1338
1489
  }
1339
1490
 
1340
- inline bool Object::DefineProperties(
1491
+ inline MaybeOrValue<bool> Object::DefineProperties(
1341
1492
  const std::vector<PropertyDescriptor>& properties) {
1342
1493
  napi_status status = napi_define_properties(_env, _value, properties.size(),
1343
1494
  reinterpret_cast<const napi_property_descriptor*>(properties.data()));
1344
- NAPI_THROW_IF_FAILED(_env, status, false);
1345
- return true;
1495
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1346
1496
  }
1347
1497
 
1348
- inline bool Object::InstanceOf(const Function& constructor) const {
1498
+ inline MaybeOrValue<bool> Object::InstanceOf(
1499
+ const Function& constructor) const {
1349
1500
  bool result;
1350
1501
  napi_status status = napi_instanceof(_env, _value, constructor, &result);
1351
- NAPI_THROW_IF_FAILED(_env, status, false);
1352
- return result;
1502
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1353
1503
  }
1354
1504
 
1355
1505
  template <typename Finalizer, typename T>
@@ -1388,17 +1538,92 @@ inline void Object::AddFinalizer(Finalizer finalizeCallback,
1388
1538
  }
1389
1539
  }
1390
1540
 
1541
+ #ifdef NAPI_CPP_EXCEPTIONS
1542
+ inline Object::const_iterator::const_iterator(const Object* object,
1543
+ const Type type) {
1544
+ _object = object;
1545
+ _keys = object->GetPropertyNames();
1546
+ _index = type == Type::BEGIN ? 0 : _keys.Length();
1547
+ }
1548
+
1549
+ inline Object::const_iterator Napi::Object::begin() const {
1550
+ const_iterator it(this, Object::const_iterator::Type::BEGIN);
1551
+ return it;
1552
+ }
1553
+
1554
+ inline Object::const_iterator Napi::Object::end() const {
1555
+ const_iterator it(this, Object::const_iterator::Type::END);
1556
+ return it;
1557
+ }
1558
+
1559
+ inline Object::const_iterator& Object::const_iterator::operator++() {
1560
+ ++_index;
1561
+ return *this;
1562
+ }
1563
+
1564
+ inline bool Object::const_iterator::operator==(
1565
+ const const_iterator& other) const {
1566
+ return _index == other._index;
1567
+ }
1568
+
1569
+ inline bool Object::const_iterator::operator!=(
1570
+ const const_iterator& other) const {
1571
+ return _index != other._index;
1572
+ }
1573
+
1574
+ inline const std::pair<Value, Object::PropertyLValue<Value>>
1575
+ Object::const_iterator::operator*() const {
1576
+ const Value key = _keys[_index];
1577
+ const PropertyLValue<Value> value = (*_object)[key];
1578
+ return {key, value};
1579
+ }
1580
+
1581
+ inline Object::iterator::iterator(Object* object, const Type type) {
1582
+ _object = object;
1583
+ _keys = object->GetPropertyNames();
1584
+ _index = type == Type::BEGIN ? 0 : _keys.Length();
1585
+ }
1586
+
1587
+ inline Object::iterator Napi::Object::begin() {
1588
+ iterator it(this, Object::iterator::Type::BEGIN);
1589
+ return it;
1590
+ }
1591
+
1592
+ inline Object::iterator Napi::Object::end() {
1593
+ iterator it(this, Object::iterator::Type::END);
1594
+ return it;
1595
+ }
1596
+
1597
+ inline Object::iterator& Object::iterator::operator++() {
1598
+ ++_index;
1599
+ return *this;
1600
+ }
1601
+
1602
+ inline bool Object::iterator::operator==(const iterator& other) const {
1603
+ return _index == other._index;
1604
+ }
1605
+
1606
+ inline bool Object::iterator::operator!=(const iterator& other) const {
1607
+ return _index != other._index;
1608
+ }
1609
+
1610
+ inline std::pair<Value, Object::PropertyLValue<Value>>
1611
+ Object::iterator::operator*() {
1612
+ Value key = _keys[_index];
1613
+ PropertyLValue<Value> value = (*_object)[key];
1614
+ return {key, value};
1615
+ }
1616
+ #endif // NAPI_CPP_EXCEPTIONS
1617
+
1391
1618
  #if NAPI_VERSION >= 8
1392
- inline bool Object::Freeze() {
1619
+ inline MaybeOrValue<bool> Object::Freeze() {
1393
1620
  napi_status status = napi_object_freeze(_env, _value);
1394
- NAPI_THROW_IF_FAILED(_env, status, false);
1395
- return true;
1621
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1396
1622
  }
1397
1623
 
1398
- inline bool Object::Seal() {
1624
+ inline MaybeOrValue<bool> Object::Seal() {
1399
1625
  napi_status status = napi_object_seal(_env, _value);
1400
- NAPI_THROW_IF_FAILED(_env, status, false);
1401
- return true;
1626
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1402
1627
  }
1403
1628
  #endif // NAPI_VERSION >= 8
1404
1629
 
@@ -1905,8 +2130,10 @@ inline TypedArrayOf<T>::TypedArrayOf(napi_env env, napi_value value)
1905
2130
  : TypedArray(env, value), _data(nullptr) {
1906
2131
  napi_status status = napi_ok;
1907
2132
  if (value != nullptr) {
2133
+ void* data = nullptr;
1908
2134
  status = napi_get_typedarray_info(
1909
- _env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
2135
+ _env, _value, &_type, &_length, &data, nullptr, nullptr);
2136
+ _data = static_cast<T*>(data);
1910
2137
  } else {
1911
2138
  _type = TypedArrayTypeForPrimitiveType<T>();
1912
2139
  _length = 0;
@@ -2015,7 +2242,7 @@ inline Function Function::New(napi_env env,
2015
2242
  void* data) {
2016
2243
  using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr)));
2017
2244
  using CbData = details::CallbackData<Callable, ReturnType>;
2018
- auto callbackData = new CbData({ cb, data });
2245
+ auto callbackData = new CbData{std::move(cb), data};
2019
2246
 
2020
2247
  napi_value value;
2021
2248
  napi_status status = CreateFunction(env,
@@ -2045,53 +2272,61 @@ inline Function::Function() : Object() {
2045
2272
  inline Function::Function(napi_env env, napi_value value) : Object(env, value) {
2046
2273
  }
2047
2274
 
2048
- inline Value Function::operator ()(const std::initializer_list<napi_value>& args) const {
2275
+ inline MaybeOrValue<Value> Function::operator()(
2276
+ const std::initializer_list<napi_value>& args) const {
2049
2277
  return Call(Env().Undefined(), args);
2050
2278
  }
2051
2279
 
2052
- inline Value Function::Call(const std::initializer_list<napi_value>& args) const {
2280
+ inline MaybeOrValue<Value> Function::Call(
2281
+ const std::initializer_list<napi_value>& args) const {
2053
2282
  return Call(Env().Undefined(), args);
2054
2283
  }
2055
2284
 
2056
- inline Value Function::Call(const std::vector<napi_value>& args) const {
2285
+ inline MaybeOrValue<Value> Function::Call(
2286
+ const std::vector<napi_value>& args) const {
2057
2287
  return Call(Env().Undefined(), args);
2058
2288
  }
2059
2289
 
2060
- inline Value Function::Call(size_t argc, const napi_value* args) const {
2290
+ inline MaybeOrValue<Value> Function::Call(size_t argc,
2291
+ const napi_value* args) const {
2061
2292
  return Call(Env().Undefined(), argc, args);
2062
2293
  }
2063
2294
 
2064
- inline Value Function::Call(napi_value recv, const std::initializer_list<napi_value>& args) const {
2295
+ inline MaybeOrValue<Value> Function::Call(
2296
+ napi_value recv, const std::initializer_list<napi_value>& args) const {
2065
2297
  return Call(recv, args.size(), args.begin());
2066
2298
  }
2067
2299
 
2068
- inline Value Function::Call(napi_value recv, const std::vector<napi_value>& args) const {
2300
+ inline MaybeOrValue<Value> Function::Call(
2301
+ napi_value recv, const std::vector<napi_value>& args) const {
2069
2302
  return Call(recv, args.size(), args.data());
2070
2303
  }
2071
2304
 
2072
- inline Value Function::Call(napi_value recv, size_t argc, const napi_value* args) const {
2305
+ inline MaybeOrValue<Value> Function::Call(napi_value recv,
2306
+ size_t argc,
2307
+ const napi_value* args) const {
2073
2308
  napi_value result;
2074
2309
  napi_status status = napi_call_function(
2075
2310
  _env, recv, _value, argc, args, &result);
2076
- NAPI_THROW_IF_FAILED(_env, status, Value());
2077
- return Value(_env, result);
2311
+ NAPI_RETURN_OR_THROW_IF_FAILED(
2312
+ _env, status, Napi::Value(_env, result), Napi::Value);
2078
2313
  }
2079
2314
 
2080
- inline Value Function::MakeCallback(
2315
+ inline MaybeOrValue<Value> Function::MakeCallback(
2081
2316
  napi_value recv,
2082
2317
  const std::initializer_list<napi_value>& args,
2083
2318
  napi_async_context context) const {
2084
2319
  return MakeCallback(recv, args.size(), args.begin(), context);
2085
2320
  }
2086
2321
 
2087
- inline Value Function::MakeCallback(
2322
+ inline MaybeOrValue<Value> Function::MakeCallback(
2088
2323
  napi_value recv,
2089
2324
  const std::vector<napi_value>& args,
2090
2325
  napi_async_context context) const {
2091
2326
  return MakeCallback(recv, args.size(), args.data(), context);
2092
2327
  }
2093
2328
 
2094
- inline Value Function::MakeCallback(
2329
+ inline MaybeOrValue<Value> Function::MakeCallback(
2095
2330
  napi_value recv,
2096
2331
  size_t argc,
2097
2332
  const napi_value* args,
@@ -2099,24 +2334,27 @@ inline Value Function::MakeCallback(
2099
2334
  napi_value result;
2100
2335
  napi_status status = napi_make_callback(
2101
2336
  _env, context, recv, _value, argc, args, &result);
2102
- NAPI_THROW_IF_FAILED(_env, status, Value());
2103
- return Value(_env, result);
2337
+ NAPI_RETURN_OR_THROW_IF_FAILED(
2338
+ _env, status, Napi::Value(_env, result), Napi::Value);
2104
2339
  }
2105
2340
 
2106
- inline Object Function::New(const std::initializer_list<napi_value>& args) const {
2341
+ inline MaybeOrValue<Object> Function::New(
2342
+ const std::initializer_list<napi_value>& args) const {
2107
2343
  return New(args.size(), args.begin());
2108
2344
  }
2109
2345
 
2110
- inline Object Function::New(const std::vector<napi_value>& args) const {
2346
+ inline MaybeOrValue<Object> Function::New(
2347
+ const std::vector<napi_value>& args) const {
2111
2348
  return New(args.size(), args.data());
2112
2349
  }
2113
2350
 
2114
- inline Object Function::New(size_t argc, const napi_value* args) const {
2351
+ inline MaybeOrValue<Object> Function::New(size_t argc,
2352
+ const napi_value* args) const {
2115
2353
  napi_value result;
2116
2354
  napi_status status = napi_new_instance(
2117
2355
  _env, _value, argc, args, &result);
2118
- NAPI_THROW_IF_FAILED(_env, status, Object());
2119
- return Object(_env, result);
2356
+ NAPI_RETURN_OR_THROW_IF_FAILED(
2357
+ _env, status, Napi::Object(_env, result), Napi::Object);
2120
2358
  }
2121
2359
 
2122
2360
  ////////////////////////////////////////////////////////////////////////////////
@@ -2282,12 +2520,23 @@ inline Error Error::New(napi_env env) {
2282
2520
  napi_status status;
2283
2521
  napi_value error = nullptr;
2284
2522
  bool is_exception_pending;
2285
- const napi_extended_error_info* info;
2523
+ napi_extended_error_info last_error_info_copy;
2286
2524
 
2287
- // We must retrieve the last error info before doing anything else, because
2288
- // doing anything else will replace the last error info.
2289
- status = napi_get_last_error_info(env, &info);
2290
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
2525
+ {
2526
+ // We must retrieve the last error info before doing anything else because
2527
+ // doing anything else will replace the last error info.
2528
+ const napi_extended_error_info* last_error_info;
2529
+ status = napi_get_last_error_info(env, &last_error_info);
2530
+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
2531
+
2532
+ // All fields of the `napi_extended_error_info` structure gets reset in
2533
+ // subsequent Node-API function calls on the same `env`. This includes a
2534
+ // call to `napi_is_exception_pending()`. So here it is necessary to make a
2535
+ // copy of the information as the `error_code` field is used later on.
2536
+ memcpy(&last_error_info_copy,
2537
+ last_error_info,
2538
+ sizeof(napi_extended_error_info));
2539
+ }
2291
2540
 
2292
2541
  status = napi_is_exception_pending(env, &is_exception_pending);
2293
2542
  NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
@@ -2298,8 +2547,9 @@ inline Error Error::New(napi_env env) {
2298
2547
  NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
2299
2548
  }
2300
2549
  else {
2301
- const char* error_message = info->error_message != nullptr ?
2302
- info->error_message : "Error in native callback";
2550
+ const char* error_message = last_error_info_copy.error_message != nullptr
2551
+ ? last_error_info_copy.error_message
2552
+ : "Error in native callback";
2303
2553
 
2304
2554
  napi_value message;
2305
2555
  status = napi_create_string_utf8(
@@ -2309,16 +2559,16 @@ inline Error Error::New(napi_env env) {
2309
2559
  &message);
2310
2560
  NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_string_utf8");
2311
2561
 
2312
- switch (info->error_code) {
2313
- case napi_object_expected:
2314
- case napi_string_expected:
2315
- case napi_boolean_expected:
2316
- case napi_number_expected:
2317
- status = napi_create_type_error(env, nullptr, message, &error);
2318
- break;
2319
- default:
2320
- status = napi_create_error(env, nullptr, message, &error);
2321
- break;
2562
+ switch (last_error_info_copy.error_code) {
2563
+ case napi_object_expected:
2564
+ case napi_string_expected:
2565
+ case napi_boolean_expected:
2566
+ case napi_number_expected:
2567
+ status = napi_create_type_error(env, nullptr, message, &error);
2568
+ break;
2569
+ default:
2570
+ status = napi_create_error(env, nullptr, message, &error);
2571
+ break;
2322
2572
  }
2323
2573
  NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_error");
2324
2574
  }
@@ -2343,14 +2593,80 @@ inline Error::Error() : ObjectReference() {
2343
2593
 
2344
2594
  inline Error::Error(napi_env env, napi_value value) : ObjectReference(env, nullptr) {
2345
2595
  if (value != nullptr) {
2596
+ // Attempting to create a reference on the error object.
2597
+ // If it's not a Object/Function/Symbol, this call will return an error
2598
+ // status.
2346
2599
  napi_status status = napi_create_reference(env, value, 1, &_ref);
2347
2600
 
2601
+ if (status != napi_ok) {
2602
+ napi_value wrappedErrorObj;
2603
+
2604
+ // Create an error object
2605
+ status = napi_create_object(env, &wrappedErrorObj);
2606
+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_create_object");
2607
+
2608
+ // property flag that we attach to show the error object is wrapped
2609
+ napi_property_descriptor wrapObjFlag = {
2610
+ ERROR_WRAP_VALUE, // Unique GUID identifier since Symbol isn't a
2611
+ // viable option
2612
+ nullptr,
2613
+ nullptr,
2614
+ nullptr,
2615
+ nullptr,
2616
+ Value::From(env, value),
2617
+ napi_enumerable,
2618
+ nullptr};
2619
+
2620
+ status = napi_define_properties(env, wrappedErrorObj, 1, &wrapObjFlag);
2621
+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_define_properties");
2622
+
2623
+ // Create a reference on the newly wrapped object
2624
+ status = napi_create_reference(env, wrappedErrorObj, 1, &_ref);
2625
+ }
2626
+
2348
2627
  // Avoid infinite recursion in the failure case.
2349
- // Don't try to construct & throw another Error instance.
2350
2628
  NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_create_reference");
2351
2629
  }
2352
2630
  }
2353
2631
 
2632
+ inline Object Error::Value() const {
2633
+ if (_ref == nullptr) {
2634
+ return Object(_env, nullptr);
2635
+ }
2636
+
2637
+ napi_value refValue;
2638
+ napi_status status = napi_get_reference_value(_env, _ref, &refValue);
2639
+ NAPI_THROW_IF_FAILED(_env, status, Object());
2640
+
2641
+ napi_valuetype type;
2642
+ status = napi_typeof(_env, refValue, &type);
2643
+ NAPI_THROW_IF_FAILED(_env, status, Object());
2644
+
2645
+ // If refValue isn't a symbol, then we proceed to whether the refValue has the
2646
+ // wrapped error flag
2647
+ if (type != napi_symbol) {
2648
+ // We are checking if the object is wrapped
2649
+ bool isWrappedObject = false;
2650
+
2651
+ status = napi_has_property(
2652
+ _env, refValue, String::From(_env, ERROR_WRAP_VALUE), &isWrappedObject);
2653
+
2654
+ // Don't care about status
2655
+ if (isWrappedObject) {
2656
+ napi_value unwrappedValue;
2657
+ status = napi_get_property(_env,
2658
+ refValue,
2659
+ String::From(_env, ERROR_WRAP_VALUE),
2660
+ &unwrappedValue);
2661
+ NAPI_THROW_IF_FAILED(_env, status, Object());
2662
+
2663
+ return Object(_env, unwrappedValue);
2664
+ }
2665
+ }
2666
+
2667
+ return Object(_env, refValue);
2668
+ }
2669
+
2354
2670
  inline Error::Error(Error&& other) : ObjectReference(std::move(other)) {
2355
2671
  }
2356
2672
 
@@ -2388,21 +2704,55 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT {
2388
2704
  // the std::string::operator=, because this method may not throw.
2389
2705
  }
2390
2706
  #else // NAPI_CPP_EXCEPTIONS
2707
+ #if defined(NODE_ADDON_API_ENABLE_MAYBE)
2708
+ Napi::Value message_val;
2709
+ if (Get("message").UnwrapTo(&message_val)) {
2710
+ _message = message_val.As<String>();
2711
+ }
2712
+ #else
2391
2713
  _message = Get("message").As<String>();
2714
+ #endif
2392
2715
  #endif // NAPI_CPP_EXCEPTIONS
2393
2716
  }
2394
2717
  return _message;
2395
2718
  }
2396
2719
 
2720
+ // we created an object on the &_ref
2397
2721
  inline void Error::ThrowAsJavaScriptException() const {
2398
2722
  HandleScope scope(_env);
2399
2723
  if (!IsEmpty()) {
2400
-
2724
+ #ifdef NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
2725
+ bool pendingException = false;
2726
+
2727
+ // check if there is already a pending exception. If so don't try to throw a
2728
+ // new one as that is not allowed/possible
2729
+ napi_status status = napi_is_exception_pending(_env, &pendingException);
2730
+
2731
+ if ((status != napi_ok) ||
2732
+ ((status == napi_ok) && (pendingException == false))) {
2733
+ // We intentionally don't use `NAPI_THROW_*` macros here to ensure
2734
+ // that there is no possible recursion as `ThrowAsJavaScriptException`
2735
+ // is part of `NAPI_THROW_*` macro definition for noexcept.
2736
+
2737
+ status = napi_throw(_env, Value());
2738
+
2739
+ if (status == napi_pending_exception) {
2740
+ // The environment must be terminating as we checked earlier and there
2741
+ // was no pending exception. In this case continuing will result
2742
+ // in a fatal error and there is nothing the author has done incorrectly
2743
+ // in their code that is worth flagging through a fatal error
2744
+ return;
2745
+ }
2746
+ } else {
2747
+ status = napi_pending_exception;
2748
+ }
2749
+ #else
2401
2750
  // We intentionally don't use `NAPI_THROW_*` macros here to ensure
2402
2751
  // that there is no possible recursion as `ThrowAsJavaScriptException`
2403
2752
  // is part of `NAPI_THROW_*` macro definition for noexcept.
2404
2753
 
2405
2754
  napi_status status = napi_throw(_env, Value());
2755
+ #endif
2406
2756
 
2407
2757
  #ifdef NAPI_CPP_EXCEPTIONS
2408
2758
  if (status != napi_ok) {
@@ -2583,7 +2933,7 @@ template <typename T>
2583
2933
  inline uint32_t Reference<T>::Ref() {
2584
2934
  uint32_t result;
2585
2935
  napi_status status = napi_reference_ref(_env, _ref, &result);
2586
- NAPI_THROW_IF_FAILED(_env, status, 1);
2936
+ NAPI_THROW_IF_FAILED(_env, status, 0);
2587
2937
  return result;
2588
2938
  }
2589
2939
 
@@ -2591,7 +2941,7 @@ template <typename T>
2591
2941
  inline uint32_t Reference<T>::Unref() {
2592
2942
  uint32_t result;
2593
2943
  napi_status status = napi_reference_unref(_env, _ref, &result);
2594
- NAPI_THROW_IF_FAILED(_env, status, 1);
2944
+ NAPI_THROW_IF_FAILED(_env, status, 0);
2595
2945
  return result;
2596
2946
  }
2597
2947
 
@@ -2679,101 +3029,147 @@ inline ObjectReference::ObjectReference(const ObjectReference& other)
2679
3029
  : Reference<Object>(other) {
2680
3030
  }
2681
3031
 
2682
- inline Napi::Value ObjectReference::Get(const char* utf8name) const {
3032
+ inline MaybeOrValue<Napi::Value> ObjectReference::Get(
3033
+ const char* utf8name) const {
2683
3034
  EscapableHandleScope scope(_env);
2684
- return scope.Escape(Value().Get(utf8name));
3035
+ MaybeOrValue<Napi::Value> result = Value().Get(utf8name);
3036
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3037
+ if (result.IsJust()) {
3038
+ return Just(scope.Escape(result.Unwrap()));
3039
+ }
3040
+ return result;
3041
+ #else
3042
+ if (scope.Env().IsExceptionPending()) {
3043
+ return Value();
3044
+ }
3045
+ return scope.Escape(result);
3046
+ #endif
2685
3047
  }
2686
3048
 
2687
- inline Napi::Value ObjectReference::Get(const std::string& utf8name) const {
3049
+ inline MaybeOrValue<Napi::Value> ObjectReference::Get(
3050
+ const std::string& utf8name) const {
2688
3051
  EscapableHandleScope scope(_env);
2689
- return scope.Escape(Value().Get(utf8name));
3052
+ MaybeOrValue<Napi::Value> result = Value().Get(utf8name);
3053
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3054
+ if (result.IsJust()) {
3055
+ return Just(scope.Escape(result.Unwrap()));
3056
+ }
3057
+ return result;
3058
+ #else
3059
+ if (scope.Env().IsExceptionPending()) {
3060
+ return Value();
3061
+ }
3062
+ return scope.Escape(result);
3063
+ #endif
2690
3064
  }
2691
3065
 
2692
- inline bool ObjectReference::Set(const char* utf8name, napi_value value) {
3066
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3067
+ napi_value value) {
2693
3068
  HandleScope scope(_env);
2694
3069
  return Value().Set(utf8name, value);
2695
3070
  }
2696
3071
 
2697
- inline bool ObjectReference::Set(const char* utf8name, Napi::Value value) {
3072
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3073
+ Napi::Value value) {
2698
3074
  HandleScope scope(_env);
2699
3075
  return Value().Set(utf8name, value);
2700
3076
  }
2701
3077
 
2702
- inline bool ObjectReference::Set(const char* utf8name, const char* utf8value) {
3078
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3079
+ const char* utf8value) {
2703
3080
  HandleScope scope(_env);
2704
3081
  return Value().Set(utf8name, utf8value);
2705
3082
  }
2706
3083
 
2707
- inline bool ObjectReference::Set(const char* utf8name, bool boolValue) {
3084
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3085
+ bool boolValue) {
2708
3086
  HandleScope scope(_env);
2709
3087
  return Value().Set(utf8name, boolValue);
2710
3088
  }
2711
3089
 
2712
- inline bool ObjectReference::Set(const char* utf8name, double numberValue) {
3090
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3091
+ double numberValue) {
2713
3092
  HandleScope scope(_env);
2714
3093
  return Value().Set(utf8name, numberValue);
2715
3094
  }
2716
3095
 
2717
- inline bool ObjectReference::Set(const std::string& utf8name,
2718
- napi_value value) {
3096
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3097
+ napi_value value) {
2719
3098
  HandleScope scope(_env);
2720
3099
  return Value().Set(utf8name, value);
2721
3100
  }
2722
3101
 
2723
- inline bool ObjectReference::Set(const std::string& utf8name,
2724
- Napi::Value value) {
3102
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3103
+ Napi::Value value) {
2725
3104
  HandleScope scope(_env);
2726
3105
  return Value().Set(utf8name, value);
2727
3106
  }
2728
3107
 
2729
- inline bool ObjectReference::Set(const std::string& utf8name,
2730
- std::string& utf8value) {
3108
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3109
+ std::string& utf8value) {
2731
3110
  HandleScope scope(_env);
2732
3111
  return Value().Set(utf8name, utf8value);
2733
3112
  }
2734
3113
 
2735
- inline bool ObjectReference::Set(const std::string& utf8name, bool boolValue) {
3114
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3115
+ bool boolValue) {
2736
3116
  HandleScope scope(_env);
2737
3117
  return Value().Set(utf8name, boolValue);
2738
3118
  }
2739
3119
 
2740
- inline bool ObjectReference::Set(const std::string& utf8name,
2741
- double numberValue) {
3120
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3121
+ double numberValue) {
2742
3122
  HandleScope scope(_env);
2743
3123
  return Value().Set(utf8name, numberValue);
2744
3124
  }
2745
3125
 
2746
- inline Napi::Value ObjectReference::Get(uint32_t index) const {
3126
+ inline MaybeOrValue<Napi::Value> ObjectReference::Get(uint32_t index) const {
2747
3127
  EscapableHandleScope scope(_env);
2748
- return scope.Escape(Value().Get(index));
3128
+ MaybeOrValue<Napi::Value> result = Value().Get(index);
3129
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3130
+ if (result.IsJust()) {
3131
+ return Just(scope.Escape(result.Unwrap()));
3132
+ }
3133
+ return result;
3134
+ #else
3135
+ if (scope.Env().IsExceptionPending()) {
3136
+ return Value();
3137
+ }
3138
+ return scope.Escape(result);
3139
+ #endif
2749
3140
  }
2750
3141
 
2751
- inline bool ObjectReference::Set(uint32_t index, napi_value value) {
3142
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3143
+ napi_value value) {
2752
3144
  HandleScope scope(_env);
2753
3145
  return Value().Set(index, value);
2754
3146
  }
2755
3147
 
2756
- inline bool ObjectReference::Set(uint32_t index, Napi::Value value) {
3148
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3149
+ Napi::Value value) {
2757
3150
  HandleScope scope(_env);
2758
3151
  return Value().Set(index, value);
2759
3152
  }
2760
3153
 
2761
- inline bool ObjectReference::Set(uint32_t index, const char* utf8value) {
3154
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3155
+ const char* utf8value) {
2762
3156
  HandleScope scope(_env);
2763
3157
  return Value().Set(index, utf8value);
2764
3158
  }
2765
3159
 
2766
- inline bool ObjectReference::Set(uint32_t index, const std::string& utf8value) {
3160
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3161
+ const std::string& utf8value) {
2767
3162
  HandleScope scope(_env);
2768
3163
  return Value().Set(index, utf8value);
2769
3164
  }
2770
3165
 
2771
- inline bool ObjectReference::Set(uint32_t index, bool boolValue) {
3166
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index, bool boolValue) {
2772
3167
  HandleScope scope(_env);
2773
3168
  return Value().Set(index, boolValue);
2774
3169
  }
2775
3170
 
2776
- inline bool ObjectReference::Set(uint32_t index, double numberValue) {
3171
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3172
+ double numberValue) {
2777
3173
  HandleScope scope(_env);
2778
3174
  return Value().Set(index, numberValue);
2779
3175
  }
@@ -2807,105 +3203,200 @@ inline FunctionReference& FunctionReference::operator =(FunctionReference&& othe
2807
3203
  return *this;
2808
3204
  }
2809
3205
 
2810
- inline Napi::Value FunctionReference::operator ()(
3206
+ inline MaybeOrValue<Napi::Value> FunctionReference::operator()(
2811
3207
  const std::initializer_list<napi_value>& args) const {
2812
3208
  EscapableHandleScope scope(_env);
2813
- return scope.Escape(Value()(args));
3209
+ MaybeOrValue<Napi::Value> result = Value()(args);
3210
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3211
+ if (result.IsJust()) {
3212
+ return Just(scope.Escape(result.Unwrap()));
3213
+ }
3214
+ return result;
3215
+ #else
3216
+ if (scope.Env().IsExceptionPending()) {
3217
+ return Value();
3218
+ }
3219
+ return scope.Escape(result);
3220
+ #endif
2814
3221
  }
2815
3222
 
2816
- inline Napi::Value FunctionReference::Call(const std::initializer_list<napi_value>& args) const {
3223
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3224
+ const std::initializer_list<napi_value>& args) const {
2817
3225
  EscapableHandleScope scope(_env);
2818
- Napi::Value result = Value().Call(args);
3226
+ MaybeOrValue<Napi::Value> result = Value().Call(args);
3227
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3228
+ if (result.IsJust()) {
3229
+ return Just(scope.Escape(result.Unwrap()));
3230
+ }
3231
+ return result;
3232
+ #else
2819
3233
  if (scope.Env().IsExceptionPending()) {
2820
3234
  return Value();
2821
3235
  }
2822
3236
  return scope.Escape(result);
3237
+ #endif
2823
3238
  }
2824
3239
 
2825
- inline Napi::Value FunctionReference::Call(const std::vector<napi_value>& args) const {
3240
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3241
+ const std::vector<napi_value>& args) const {
2826
3242
  EscapableHandleScope scope(_env);
2827
- Napi::Value result = Value().Call(args);
3243
+ MaybeOrValue<Napi::Value> result = Value().Call(args);
3244
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3245
+ if (result.IsJust()) {
3246
+ return Just(scope.Escape(result.Unwrap()));
3247
+ }
3248
+ return result;
3249
+ #else
2828
3250
  if (scope.Env().IsExceptionPending()) {
2829
3251
  return Value();
2830
3252
  }
2831
3253
  return scope.Escape(result);
3254
+ #endif
2832
3255
  }
2833
3256
 
2834
- inline Napi::Value FunctionReference::Call(
3257
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
2835
3258
  napi_value recv, const std::initializer_list<napi_value>& args) const {
2836
3259
  EscapableHandleScope scope(_env);
2837
- Napi::Value result = Value().Call(recv, args);
3260
+ MaybeOrValue<Napi::Value> result = Value().Call(recv, args);
3261
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3262
+ if (result.IsJust()) {
3263
+ return Just(scope.Escape(result.Unwrap()));
3264
+ }
3265
+ return result;
3266
+ #else
2838
3267
  if (scope.Env().IsExceptionPending()) {
2839
3268
  return Value();
2840
3269
  }
2841
3270
  return scope.Escape(result);
3271
+ #endif
2842
3272
  }
2843
3273
 
2844
- inline Napi::Value FunctionReference::Call(
3274
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
2845
3275
  napi_value recv, const std::vector<napi_value>& args) const {
2846
3276
  EscapableHandleScope scope(_env);
2847
- Napi::Value result = Value().Call(recv, args);
3277
+ MaybeOrValue<Napi::Value> result = Value().Call(recv, args);
3278
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3279
+ if (result.IsJust()) {
3280
+ return Just(scope.Escape(result.Unwrap()));
3281
+ }
3282
+ return result;
3283
+ #else
2848
3284
  if (scope.Env().IsExceptionPending()) {
2849
3285
  return Value();
2850
3286
  }
2851
3287
  return scope.Escape(result);
3288
+ #endif
2852
3289
  }
2853
3290
 
2854
- inline Napi::Value FunctionReference::Call(
3291
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
2855
3292
  napi_value recv, size_t argc, const napi_value* args) const {
2856
3293
  EscapableHandleScope scope(_env);
2857
- Napi::Value result = Value().Call(recv, argc, args);
3294
+ MaybeOrValue<Napi::Value> result = Value().Call(recv, argc, args);
3295
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3296
+ if (result.IsJust()) {
3297
+ return Just(scope.Escape(result.Unwrap()));
3298
+ }
3299
+ return result;
3300
+ #else
2858
3301
  if (scope.Env().IsExceptionPending()) {
2859
3302
  return Value();
2860
3303
  }
2861
3304
  return scope.Escape(result);
3305
+ #endif
2862
3306
  }
2863
3307
 
2864
- inline Napi::Value FunctionReference::MakeCallback(
3308
+ inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
2865
3309
  napi_value recv,
2866
3310
  const std::initializer_list<napi_value>& args,
2867
3311
  napi_async_context context) const {
2868
3312
  EscapableHandleScope scope(_env);
2869
- Napi::Value result = Value().MakeCallback(recv, args, context);
3313
+ MaybeOrValue<Napi::Value> result = Value().MakeCallback(recv, args, context);
3314
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3315
+ if (result.IsJust()) {
3316
+ return Just(scope.Escape(result.Unwrap()));
3317
+ }
3318
+
3319
+ return result;
3320
+ #else
2870
3321
  if (scope.Env().IsExceptionPending()) {
2871
3322
  return Value();
2872
3323
  }
2873
3324
  return scope.Escape(result);
3325
+ #endif
2874
3326
  }
2875
3327
 
2876
- inline Napi::Value FunctionReference::MakeCallback(
3328
+ inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
2877
3329
  napi_value recv,
2878
3330
  const std::vector<napi_value>& args,
2879
3331
  napi_async_context context) const {
2880
3332
  EscapableHandleScope scope(_env);
2881
- Napi::Value result = Value().MakeCallback(recv, args, context);
3333
+ MaybeOrValue<Napi::Value> result = Value().MakeCallback(recv, args, context);
3334
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3335
+ if (result.IsJust()) {
3336
+ return Just(scope.Escape(result.Unwrap()));
3337
+ }
3338
+ return result;
3339
+ #else
2882
3340
  if (scope.Env().IsExceptionPending()) {
2883
3341
  return Value();
2884
3342
  }
2885
3343
  return scope.Escape(result);
3344
+ #endif
2886
3345
  }
2887
3346
 
2888
- inline Napi::Value FunctionReference::MakeCallback(
3347
+ inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
2889
3348
  napi_value recv,
2890
3349
  size_t argc,
2891
3350
  const napi_value* args,
2892
3351
  napi_async_context context) const {
2893
3352
  EscapableHandleScope scope(_env);
2894
- Napi::Value result = Value().MakeCallback(recv, argc, args, context);
3353
+ MaybeOrValue<Napi::Value> result =
3354
+ Value().MakeCallback(recv, argc, args, context);
3355
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3356
+ if (result.IsJust()) {
3357
+ return Just(scope.Escape(result.Unwrap()));
3358
+ }
3359
+ return result;
3360
+ #else
2895
3361
  if (scope.Env().IsExceptionPending()) {
2896
3362
  return Value();
2897
3363
  }
2898
3364
  return scope.Escape(result);
3365
+ #endif
2899
3366
  }
2900
3367
 
2901
- inline Object FunctionReference::New(const std::initializer_list<napi_value>& args) const {
3368
+ inline MaybeOrValue<Object> FunctionReference::New(
3369
+ const std::initializer_list<napi_value>& args) const {
2902
3370
  EscapableHandleScope scope(_env);
2903
- return scope.Escape(Value().New(args)).As<Object>();
3371
+ MaybeOrValue<Object> result = Value().New(args);
3372
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3373
+ if (result.IsJust()) {
3374
+ return Just(scope.Escape(result.Unwrap()).As<Object>());
3375
+ }
3376
+ return result;
3377
+ #else
3378
+ if (scope.Env().IsExceptionPending()) {
3379
+ return Object();
3380
+ }
3381
+ return scope.Escape(result).As<Object>();
3382
+ #endif
2904
3383
  }
2905
3384
 
2906
- inline Object FunctionReference::New(const std::vector<napi_value>& args) const {
3385
+ inline MaybeOrValue<Object> FunctionReference::New(
3386
+ const std::vector<napi_value>& args) const {
2907
3387
  EscapableHandleScope scope(_env);
2908
- return scope.Escape(Value().New(args)).As<Object>();
3388
+ MaybeOrValue<Object> result = Value().New(args);
3389
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3390
+ if (result.IsJust()) {
3391
+ return Just(scope.Escape(result.Unwrap()).As<Object>());
3392
+ }
3393
+ return result;
3394
+ #else
3395
+ if (scope.Env().IsExceptionPending()) {
3396
+ return Object();
3397
+ }
3398
+ return scope.Escape(result).As<Object>();
3399
+ #endif
2909
3400
  }
2910
3401
 
2911
3402
  ////////////////////////////////////////////////////////////////////////////////
@@ -3643,10 +4134,10 @@ inline ObjectWrap<T>::~ObjectWrap() {
3643
4134
 
3644
4135
  template<typename T>
3645
4136
  inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
3646
- T* unwrapped;
3647
- napi_status status = napi_unwrap(wrapper.Env(), wrapper, reinterpret_cast<void**>(&unwrapped));
4137
+ void* unwrapped;
4138
+ napi_status status = napi_unwrap(wrapper.Env(), wrapper, &unwrapped);
3648
4139
  NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
3649
- return unwrapped;
4140
+ return static_cast<T*>(unwrapped);
3650
4141
  }
3651
4142
 
3652
4143
  template <typename T>
@@ -5666,6 +6157,53 @@ Addon<T>::DefineProperties(Object object,
5666
6157
  }
5667
6158
  #endif // NAPI_VERSION > 5
5668
6159
 
6160
+ #if NAPI_VERSION > 2
6161
+ template <typename Hook, typename Arg>
6162
+ Env::CleanupHook<Hook, Arg> Env::AddCleanupHook(Hook hook, Arg* arg) {
6163
+ return CleanupHook<Hook, Arg>(*this, hook, arg);
6164
+ }
6165
+
6166
+ template <typename Hook>
6167
+ Env::CleanupHook<Hook> Env::AddCleanupHook(Hook hook) {
6168
+ return CleanupHook<Hook>(*this, hook);
6169
+ }
6170
+
6171
+ template <typename Hook, typename Arg>
6172
+ Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook)
6173
+ : wrapper(Env::CleanupHook<Hook, Arg>::Wrapper) {
6174
+ data = new CleanupData{std::move(hook), nullptr};
6175
+ napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
6176
+ if (status != napi_ok) {
6177
+ delete data;
6178
+ data = nullptr;
6179
+ }
6180
+ }
6181
+
6182
+ template <typename Hook, typename Arg>
6183
+ Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook, Arg* arg)
6184
+ : wrapper(Env::CleanupHook<Hook, Arg>::WrapperWithArg) {
6185
+ data = new CleanupData{std::move(hook), arg};
6186
+ napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
6187
+ if (status != napi_ok) {
6188
+ delete data;
6189
+ data = nullptr;
6190
+ }
6191
+ }
6192
+
6193
+ template <class Hook, class Arg>
6194
+ bool Env::CleanupHook<Hook, Arg>::Remove(Env env) {
6195
+ napi_status status = napi_remove_env_cleanup_hook(env, wrapper, data);
6196
+ delete data;
6197
+ data = nullptr;
6198
+ return status == napi_ok;
6199
+ }
6200
+
6201
+ template <class Hook, class Arg>
6202
+ bool Env::CleanupHook<Hook, Arg>::IsEmpty() const {
6203
+ return data == nullptr;
6204
+ }
6205
+ #endif // NAPI_VERSION > 2
6206
+
5669
6207
  } // namespace Napi
5670
6208
 
5671
6209
  #endif // SRC_NAPI_INL_H_