node-addon-api 8.5.0 → 8.7.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.5.0
22
+ ## Current version: 8.7.0
23
23
  <!-- x-release-please-end -->
24
24
 
25
25
  (See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)
package/common.gypi CHANGED
@@ -5,7 +5,7 @@
5
5
  },
6
6
  'conditions': [
7
7
  ['NAPI_VERSION!=""', { 'defines': ['NAPI_VERSION=<@(NAPI_VERSION)'] } ],
8
- ['NAPI_VERSION==2147483647', { 'defines': ['NAPI_EXPERIMENTAL'] } ],
8
+ ['NAPI_VERSION==2147483647', { 'defines': ['NAPI_EXPERIMENTAL', 'NODE_API_EXPERIMENTAL_NO_WARNING'] } ],
9
9
  ['disable_deprecated=="true"', {
10
10
  'defines': ['NODE_ADDON_API_DISABLE_DEPRECATED']
11
11
  }],
package/napi-inl.h CHANGED
@@ -21,6 +21,12 @@
21
21
  #include <type_traits>
22
22
  #include <utility>
23
23
 
24
+ #if defined(__clang__) || defined(__GNUC__)
25
+ #define NAPI_NO_SANITIZE_VPTR __attribute__((no_sanitize("vptr")))
26
+ #else
27
+ #define NAPI_NO_SANITIZE_VPTR
28
+ #endif
29
+
24
30
  namespace Napi {
25
31
 
26
32
  #ifdef NAPI_CPP_CUSTOM_NAMESPACE
@@ -934,6 +940,19 @@ inline bool Value::IsExternal() const {
934
940
  return Type() == napi_external;
935
941
  }
936
942
 
943
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
944
+ inline bool Value::IsSharedArrayBuffer() const {
945
+ if (IsEmpty()) {
946
+ return false;
947
+ }
948
+
949
+ bool result;
950
+ napi_status status = node_api_is_sharedarraybuffer(_env, _value, &result);
951
+ NAPI_THROW_IF_FAILED(_env, status, false);
952
+ return result;
953
+ }
954
+ #endif
955
+
937
956
  template <typename T>
938
957
  inline T Value::As() const {
939
958
  #ifdef NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS
@@ -1180,6 +1199,13 @@ inline Date Date::New(napi_env env, double val) {
1180
1199
  return Date(env, value);
1181
1200
  }
1182
1201
 
1202
+ inline Date Date::New(napi_env env, std::chrono::system_clock::time_point tp) {
1203
+ using namespace std::chrono;
1204
+ auto ms = static_cast<double>(
1205
+ duration_cast<milliseconds>(tp.time_since_epoch()).count());
1206
+ return Date::New(env, ms);
1207
+ }
1208
+
1183
1209
  inline void Date::CheckCast(napi_env env, napi_value value) {
1184
1210
  NAPI_CHECK(value != nullptr, "Date::CheckCast", "empty value");
1185
1211
 
@@ -1947,6 +1973,19 @@ inline MaybeOrValue<bool> Object::Seal() const {
1947
1973
  }
1948
1974
  #endif // NAPI_VERSION >= 8
1949
1975
 
1976
+ inline MaybeOrValue<Object> Object::GetPrototype() const {
1977
+ napi_value result;
1978
+ napi_status status = napi_get_prototype(_env, _value, &result);
1979
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Object(_env, result), Object);
1980
+ }
1981
+
1982
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
1983
+ inline MaybeOrValue<bool> Object::SetPrototype(const Object& value) const {
1984
+ napi_status status = node_api_set_prototype(_env, _value, value);
1985
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1986
+ }
1987
+ #endif
1988
+
1950
1989
  ////////////////////////////////////////////////////////////////////////////////
1951
1990
  // External class
1952
1991
  ////////////////////////////////////////////////////////////////////////////////
@@ -2068,6 +2107,55 @@ inline uint32_t Array::Length() const {
2068
2107
  return result;
2069
2108
  }
2070
2109
 
2110
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
2111
+ ////////////////////////////////////////////////////////////////////////////////
2112
+ // SharedArrayBuffer class
2113
+ ////////////////////////////////////////////////////////////////////////////////
2114
+
2115
+ inline SharedArrayBuffer::SharedArrayBuffer() : Object() {}
2116
+
2117
+ inline SharedArrayBuffer::SharedArrayBuffer(napi_env env, napi_value value)
2118
+ : Object(env, value) {}
2119
+
2120
+ inline void SharedArrayBuffer::CheckCast(napi_env env, napi_value value) {
2121
+ NAPI_CHECK(value != nullptr, "SharedArrayBuffer::CheckCast", "empty value");
2122
+
2123
+ bool result;
2124
+ napi_status status = node_api_is_sharedarraybuffer(env, value, &result);
2125
+ NAPI_CHECK(status == napi_ok,
2126
+ "SharedArrayBuffer::CheckCast",
2127
+ "node_api_is_sharedarraybuffer failed");
2128
+ NAPI_CHECK(
2129
+ result, "SharedArrayBuffer::CheckCast", "value is not sharedarraybuffer");
2130
+ }
2131
+
2132
+ inline SharedArrayBuffer SharedArrayBuffer::New(napi_env env,
2133
+ size_t byteLength) {
2134
+ napi_value value;
2135
+ void* data;
2136
+ napi_status status =
2137
+ node_api_create_sharedarraybuffer(env, byteLength, &data, &value);
2138
+ NAPI_THROW_IF_FAILED(env, status, SharedArrayBuffer());
2139
+
2140
+ return SharedArrayBuffer(env, value);
2141
+ }
2142
+
2143
+ inline void* SharedArrayBuffer::Data() {
2144
+ void* data;
2145
+ napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr);
2146
+ NAPI_THROW_IF_FAILED(_env, status, nullptr);
2147
+ return data;
2148
+ }
2149
+
2150
+ inline size_t SharedArrayBuffer::ByteLength() {
2151
+ size_t length;
2152
+ napi_status status =
2153
+ napi_get_arraybuffer_info(_env, _value, nullptr, &length);
2154
+ NAPI_THROW_IF_FAILED(_env, status, 0);
2155
+ return length;
2156
+ }
2157
+ #endif // NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
2158
+
2071
2159
  ////////////////////////////////////////////////////////////////////////////////
2072
2160
  // ArrayBuffer class
2073
2161
  ////////////////////////////////////////////////////////////////////////////////
@@ -2221,6 +2309,39 @@ inline DataView DataView::New(napi_env env,
2221
2309
  return DataView(env, value);
2222
2310
  }
2223
2311
 
2312
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
2313
+ inline DataView DataView::New(napi_env env,
2314
+ Napi::SharedArrayBuffer arrayBuffer) {
2315
+ return New(env, arrayBuffer, 0, arrayBuffer.ByteLength());
2316
+ }
2317
+
2318
+ inline DataView DataView::New(napi_env env,
2319
+ Napi::SharedArrayBuffer arrayBuffer,
2320
+ size_t byteOffset) {
2321
+ if (byteOffset > arrayBuffer.ByteLength()) {
2322
+ NAPI_THROW(RangeError::New(
2323
+ env, "Start offset is outside the bounds of the buffer"),
2324
+ DataView());
2325
+ }
2326
+ return New(
2327
+ env, arrayBuffer, byteOffset, arrayBuffer.ByteLength() - byteOffset);
2328
+ }
2329
+
2330
+ inline DataView DataView::New(napi_env env,
2331
+ Napi::SharedArrayBuffer arrayBuffer,
2332
+ size_t byteOffset,
2333
+ size_t byteLength) {
2334
+ if (byteOffset + byteLength > arrayBuffer.ByteLength()) {
2335
+ NAPI_THROW(RangeError::New(env, "Invalid DataView length"), DataView());
2336
+ }
2337
+ napi_value value;
2338
+ napi_status status =
2339
+ napi_create_dataview(env, byteLength, arrayBuffer, byteOffset, &value);
2340
+ NAPI_THROW_IF_FAILED(env, status, DataView());
2341
+ return DataView(env, value);
2342
+ }
2343
+ #endif // NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
2344
+
2224
2345
  inline void DataView::CheckCast(napi_env env, napi_value value) {
2225
2346
  NAPI_CHECK(value != nullptr, "DataView::CheckCast", "empty value");
2226
2347
 
@@ -2244,6 +2365,10 @@ inline DataView::DataView(napi_env env, napi_value value) : Object(env, value) {
2244
2365
  }
2245
2366
 
2246
2367
  inline Napi::ArrayBuffer DataView::ArrayBuffer() const {
2368
+ return Buffer().As<Napi::ArrayBuffer>();
2369
+ }
2370
+
2371
+ inline Napi::Value DataView::Buffer() const {
2247
2372
  napi_value arrayBuffer;
2248
2373
  napi_status status = napi_get_dataview_info(_env,
2249
2374
  _value /* dataView */,
@@ -2251,8 +2376,8 @@ inline Napi::ArrayBuffer DataView::ArrayBuffer() const {
2251
2376
  nullptr /* data */,
2252
2377
  &arrayBuffer /* arrayBuffer */,
2253
2378
  nullptr /* byteOffset */);
2254
- NAPI_THROW_IF_FAILED(_env, status, Napi::ArrayBuffer());
2255
- return Napi::ArrayBuffer(_env, arrayBuffer);
2379
+ NAPI_THROW_IF_FAILED(_env, status, Napi::Value());
2380
+ return Napi::Value(_env, arrayBuffer);
2256
2381
  }
2257
2382
 
2258
2383
  inline size_t DataView::ByteOffset() const {
@@ -3741,8 +3866,8 @@ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3741
3866
  return Value().Set(utf8name, value);
3742
3867
  }
3743
3868
 
3744
- inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3745
- std::string& utf8value) const {
3869
+ inline MaybeOrValue<bool> ObjectReference::Set(
3870
+ const std::string& utf8name, const std::string& utf8value) const {
3746
3871
  HandleScope scope(_env);
3747
3872
  return Value().Set(utf8name, utf8value);
3748
3873
  }
@@ -4717,7 +4842,8 @@ inline napi_value InstanceWrap<T>::WrappedMethod(
4717
4842
  ////////////////////////////////////////////////////////////////////////////////
4718
4843
 
4719
4844
  template <typename T>
4720
- inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4845
+ inline NAPI_NO_SANITIZE_VPTR ObjectWrap<T>::ObjectWrap(
4846
+ const Napi::CallbackInfo& callbackInfo) {
4721
4847
  napi_env env = callbackInfo.Env();
4722
4848
  napi_value wrapper = callbackInfo.This();
4723
4849
  napi_status status;
@@ -4731,7 +4857,7 @@ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4731
4857
  }
4732
4858
 
4733
4859
  template <typename T>
4734
- inline ObjectWrap<T>::~ObjectWrap() {
4860
+ inline NAPI_NO_SANITIZE_VPTR ObjectWrap<T>::~ObjectWrap() {
4735
4861
  // If the JS object still exists at this point, remove the finalizer added
4736
4862
  // through `napi_wrap()`.
4737
4863
  if (!IsEmpty() && !_finalized) {
@@ -4744,8 +4870,12 @@ inline ObjectWrap<T>::~ObjectWrap() {
4744
4870
  }
4745
4871
  }
4746
4872
 
4873
+ // with RTTI turned on, modern compilers check to see if virtual function
4874
+ // pointers are stripped of RTTI by void casts. this is intrinsic to how Unwrap
4875
+ // works, so we inject a compiler pragma to turn off that check just for the
4876
+ // affected methods. this compiler check is on by default in Android NDK 29.
4747
4877
  template <typename T>
4748
- inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
4878
+ inline NAPI_NO_SANITIZE_VPTR T* ObjectWrap<T>::Unwrap(Object wrapper) {
4749
4879
  void* unwrapped;
4750
4880
  napi_status status = napi_unwrap(wrapper.Env(), wrapper, &unwrapped);
4751
4881
  NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
@@ -7030,4 +7160,6 @@ inline void BasicEnv::PostFinalizer(FinalizerType finalizeCallback,
7030
7160
 
7031
7161
  } // namespace Napi
7032
7162
 
7163
+ #undef NAPI_NO_SANITIZE_VPTR
7164
+
7033
7165
  #endif // SRC_NAPI_INL_H_
package/napi.h CHANGED
@@ -17,6 +17,7 @@
17
17
  #if NAPI_HAS_THREADS
18
18
  #include <mutex>
19
19
  #endif // NAPI_HAS_THREADS
20
+ #include <chrono>
20
21
  #include <string>
21
22
  #include <vector>
22
23
 
@@ -359,10 +360,10 @@ class BasicEnv {
359
360
  // ... occurs when comparing foo.Env() == bar.Env() or foo.Env() == nullptr
360
361
  bool operator==(const BasicEnv& other) const {
361
362
  return _env == other._env;
362
- };
363
+ }
363
364
  bool operator==(std::nullptr_t /*other*/) const {
364
365
  return _env == nullptr;
365
- };
366
+ }
366
367
 
367
368
  #if NAPI_VERSION > 2
368
369
  template <typename Hook, typename Arg = void>
@@ -543,6 +544,9 @@ class Value {
543
544
  bool IsDataView() const; ///< Tests if a value is a JavaScript data view.
544
545
  bool IsBuffer() const; ///< Tests if a value is a Node buffer.
545
546
  bool IsExternal() const; ///< Tests if a value is a pointer to external data.
547
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
548
+ bool IsSharedArrayBuffer() const;
549
+ #endif
546
550
 
547
551
  /// Casts to another type of `Napi::Value`, when the actual type is known or
548
552
  /// assumed.
@@ -682,6 +686,12 @@ class Date : public Value {
682
686
  double value ///< Number value
683
687
  );
684
688
 
689
+ /// Creates a new Date value from a std::chrono::system_clock::time_point.
690
+ static Date New(
691
+ napi_env env, ///< Node-API environment
692
+ std::chrono::system_clock::time_point time_point ///< Time point value
693
+ );
694
+
685
695
  static void CheckCast(napi_env env, napi_value value);
686
696
 
687
697
  Date(); ///< Creates a new _empty_ Date instance.
@@ -1115,6 +1125,12 @@ class Object : public TypeTaggable {
1115
1125
  /// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
1116
1126
  MaybeOrValue<bool> Seal() const;
1117
1127
  #endif // NAPI_VERSION >= 8
1128
+
1129
+ MaybeOrValue<Object> GetPrototype() const;
1130
+
1131
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SET_PROTOTYPE
1132
+ MaybeOrValue<bool> SetPrototype(const Object& value) const;
1133
+ #endif
1118
1134
  };
1119
1135
 
1120
1136
  template <typename T>
@@ -1202,6 +1218,21 @@ class Object::iterator {
1202
1218
  };
1203
1219
  #endif // NODE_ADDON_API_CPP_EXCEPTIONS
1204
1220
 
1221
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
1222
+ class SharedArrayBuffer : public Object {
1223
+ public:
1224
+ SharedArrayBuffer();
1225
+ SharedArrayBuffer(napi_env env, napi_value value);
1226
+
1227
+ static SharedArrayBuffer New(napi_env env, size_t byteLength);
1228
+
1229
+ static void CheckCast(napi_env env, napi_value value);
1230
+
1231
+ void* Data();
1232
+ size_t ByteLength();
1233
+ };
1234
+ #endif
1235
+
1205
1236
  /// A JavaScript array buffer value.
1206
1237
  class ArrayBuffer : public Object {
1207
1238
  public:
@@ -1432,13 +1463,37 @@ class DataView : public Object {
1432
1463
  size_t byteOffset,
1433
1464
  size_t byteLength);
1434
1465
 
1466
+ #ifdef NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
1467
+ static DataView New(napi_env env, Napi::SharedArrayBuffer arrayBuffer);
1468
+ static DataView New(napi_env env,
1469
+ Napi::SharedArrayBuffer arrayBuffer,
1470
+ size_t byteOffset);
1471
+ static DataView New(napi_env env,
1472
+ Napi::SharedArrayBuffer arrayBuffer,
1473
+ size_t byteOffset,
1474
+ size_t byteLength);
1475
+ #endif
1476
+
1435
1477
  static void CheckCast(napi_env env, napi_value value);
1436
1478
 
1437
1479
  DataView(); ///< Creates a new _empty_ DataView instance.
1438
1480
  DataView(napi_env env,
1439
1481
  napi_value value); ///< Wraps a Node-API value primitive.
1440
1482
 
1441
- Napi::ArrayBuffer ArrayBuffer() const; ///< Gets the backing array buffer.
1483
+ // Gets the backing `ArrayBuffer`.
1484
+ //
1485
+ // If this `DataView` is not backed by an `ArrayBuffer`, this method will
1486
+ // terminate the process with a fatal error when using
1487
+ // `NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS` or exhibit undefined behavior
1488
+ // otherwise. Use `Buffer()` instead to get the backing buffer without
1489
+ // assuming its type.
1490
+ Napi::ArrayBuffer ArrayBuffer() const;
1491
+
1492
+ // Gets the backing buffer (an `ArrayBuffer` or `SharedArrayBuffer`).
1493
+ //
1494
+ // Use `IsArrayBuffer()` or `IsSharedArrayBuffer()` to check the type of the
1495
+ // backing buffer prior to casting with `As<T>()`.
1496
+ Napi::Value Buffer() const;
1442
1497
  size_t ByteOffset()
1443
1498
  const; ///< Gets the offset into the buffer where the array starts.
1444
1499
  size_t ByteLength() const; ///< Gets the length of the array in bytes.
@@ -1715,7 +1770,7 @@ class ObjectReference : public Reference<Object> {
1715
1770
  MaybeOrValue<bool> Set(const std::string& utf8name, napi_value value) const;
1716
1771
  MaybeOrValue<bool> Set(const std::string& utf8name, Napi::Value value) const;
1717
1772
  MaybeOrValue<bool> Set(const std::string& utf8name,
1718
- std::string& utf8value) const;
1773
+ const std::string& utf8value) const;
1719
1774
  MaybeOrValue<bool> Set(const std::string& utf8name, bool boolValue) const;
1720
1775
  MaybeOrValue<bool> Set(const std::string& utf8name, double numberValue) const;
1721
1776
 
@@ -3108,8 +3163,8 @@ class AsyncProgressWorkerBase : public AsyncWorker {
3108
3163
 
3109
3164
  AsyncProgressWorkerBase* asyncprogressworker() {
3110
3165
  return _asyncprogressworker;
3111
- };
3112
- DataType* data() { return _data; };
3166
+ }
3167
+ DataType* data() { return _data; }
3113
3168
 
3114
3169
  private:
3115
3170
  AsyncProgressWorkerBase* _asyncprogressworker;
package/package.json CHANGED
@@ -472,7 +472,7 @@
472
472
  "lint:fix": "eslint --fix && node tools/clang-format --fix"
473
473
  },
474
474
  "pre-commit": "lint",
475
- "version": "8.5.0",
475
+ "version": "8.7.0",
476
476
  "support": true,
477
477
  "engines": {
478
478
  "node": "^18 || ^20 || >= 21"