diff --git a/doc/api/n-api.md b/doc/api/n-api.md index d3efd09ab15ec0..e151a7357fbb58 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -2946,6 +2946,35 @@ the `complete` callback will be invoked with a status value of `napi_cancelled`. The work should not be deleted before the `complete` callback invocation, even if it has been successfully cancelled. +## Version Management + +### napi_get_version + +```C +NAPI_EXTERN napi_status napi_get_version(napi_env env, + uint32_t* result); +``` + +- `[in] env`: The environment that the API is invoked under. +- `[out] result`: The highest version of N-API supported. + +Returns `napi_ok` if the API succeeded. + +This API returns the highest N-API version supported by the +Node.js runtime. N-API is planned to be additive such that +newer releases of Node.js may support additional API functions. +In order to allow an addon to use a newer function when running with +versions of Node.js that support it, while providing +fallback behavior when running with Node.js versions that don't +support it: + +* Call `napi_get_version()` to determine if the API is available. +* If available, dynamically load a pointer to the function using `uv_dlsym()`. +* Use the dynamically loaded pointer to invoke the function. +* If the function is not available, provide an alternate implementation + that does not use the function. [Aynchronous Operations]: #n_api_asynchronous_operations [Basic N-API Data Types]: #n_api_basic_n_api_data_types diff --git a/src/node_api.cc b/src/node_api.cc index 976bf15f3ca423..7a485283bbb13d 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -20,6 +20,8 @@ #include "env-inl.h" #include "node_api_backport.h" +#define NAPI_VERSION 1 + static napi_status napi_set_last_error(napi_env env, napi_status error_code, uint32_t engine_error_code = 0, @@ -2715,6 +2717,13 @@ napi_status napi_get_typedarray_info(napi_env env, return napi_clear_last_error(env); } +napi_status napi_get_version(napi_env env, uint32_t* result) { + CHECK_ENV(env); + CHECK_ARG(env, result); + *result = NAPI_VERSION; + return napi_clear_last_error(env); +} + namespace uvimpl { static napi_status ConvertUVErrorCode(int code) { diff --git a/src/node_api.h b/src/node_api.h index 5a95c030a35272..a1840943602ce3 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -478,6 +478,10 @@ NAPI_EXTERN napi_status napi_queue_async_work(napi_env env, NAPI_EXTERN napi_status napi_cancel_async_work(napi_env env, napi_async_work work); + +// version management +NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result); + EXTERN_C_END #endif // SRC_NODE_API_H_ diff --git a/test/addons-napi/test_general/test.js b/test/addons-napi/test_general/test.js index a2e57126ce8c22..614cf0f4f0e7c4 100644 --- a/test/addons-napi/test_general/test.js +++ b/test/addons-napi/test_general/test.js @@ -30,3 +30,7 @@ assert.strictEqual(test_general.testGetPrototype(extendedObject), assert.ok(test_general.testGetPrototype(baseObject) !== test_general.testGetPrototype(extendedObject), 'Prototypes for base and extended should be different'); + +// test version management funcitons +// expected version is currently 1 +assert.strictEqual(test_general.testGetVersion(), 1); diff --git a/test/addons-napi/test_general/test_general.c b/test/addons-napi/test_general/test_general.c index 17911b36253df1..585a3bf2b3ff0d 100644 --- a/test/addons-napi/test_general/test_general.c +++ b/test/addons-napi/test_general/test_general.c @@ -25,10 +25,19 @@ napi_value testGetPrototype(napi_env env, napi_callback_info info) { return result; } +napi_value testGetVersion(napi_env env, napi_callback_info info) { + uint32_t version; + napi_value result; + NAPI_CALL(env, napi_get_version(env, &version)); + NAPI_CALL(env ,napi_create_number(env, version, &result)); + return result; +} + void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_property_descriptor descriptors[] = { DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals), DECLARE_NAPI_PROPERTY("testGetPrototype", testGetPrototype), + DECLARE_NAPI_PROPERTY("testGetVersion", testGetVersion), }; NAPI_CALL_RETURN_VOID(env, napi_define_properties(