Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

n-api: add napi_get_version #13207

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2946,6 +2946,34 @@ 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
<!-- YAML
added: REPLACEME
-->
```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. Since
the goal is forward compatibility, older versions may not support
the new functions even if we port empty stubs to earlier Node.js
versions in order to facilitate use of the new functions with later
Node.js releases. To support this case an addon can call
`napi_get_version` to check which level of N-API is supported
at run time. Based on the result of this check the addon can
implement appropriate code paths when functions
are, or are not, fully implemented.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would omit the mention of backporting stubs, since that wouldn't provide addon developers any real guarantees because many applications will not have the updates with the backported stubs. Instead, if addon developers desire backward compatibility with Node versions having older N-API versions, we should recommend dynamically loading APIs that might not be present, after checking the version.

I'd suggest changing this paragraph to something like this:

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. To allow
an addon to use a newer API when it's available while providing a
fallback behavior when it's not, first call `napi_get_version()` to
determine if the API is available, then use `uv_dlsym()` to dynamically
load a pointer to the function.



[Aynchronous Operations]: #n_api_asynchronous_operations
[Basic N-API Data Types]: #n_api_basic_n_api_data_types
Expand Down
9 changes: 9 additions & 0 deletions src/node_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "uv.h"
#include "node_api.h"

#define NAPI_VERSION 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhdawson - Was there any reason this is not inside src/node_api.h instead?


static
napi_status napi_set_last_error(napi_env env, napi_status error_code,
uint32_t engine_error_code = 0,
Expand Down Expand Up @@ -2713,6 +2715,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) {
Expand Down
4 changes: 4 additions & 0 deletions src/node_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
4 changes: 4 additions & 0 deletions test/addons-napi/test_general/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test going to need to be updated every time the napi version is bumped?

9 changes: 9 additions & 0 deletions test/addons-napi/test_general/test_general.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down