Skip to content

Commit

Permalink
n-api: add napi_get_node_version
Browse files Browse the repository at this point in the history
Add `napi_get_node_version`, to help with feature-detecting
Node.js as an environment.

Backport-PR-URL: #19447
PR-URL: #14696
Reviewed-By: Kyle Farnung <kfarnung@microsoft.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
  • Loading branch information
addaleax authored and MylesBorins committed Apr 16, 2018
1 parent b29eb69 commit 951adbe
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 1 deletion.
31 changes: 31 additions & 0 deletions doc/api/n-api.md
Expand Up @@ -3285,6 +3285,35 @@ callback invocation, even if it has been successfully cancelled.

## Version Management

### napi_get_node_version
<!-- YAML
added: REPLACEME
-->

```C
typedef struct {
uint32_t major;
uint32_t minor;
uint32_t patch;
const char* release;
} napi_node_version;

NAPI_EXTERN
napi_status napi_get_node_version(napi_env env,
const napi_node_version** version);
```
- `[in] env`: The environment that the API is invoked under.
- `[out] version`: A pointer to version information for Node itself.
Returns `napi_ok` if the API succeeded.
This function fills the `version` struct with the major, minor and patch version
of Node that is currently running, and the `release` field with the
value of [`process.release.name`][`process.release`].
The returned buffer is statically allocated and does not need to be freed.
### napi_get_version
<!-- YAML
added: REPLACEME
Expand Down Expand Up @@ -3369,3 +3398,5 @@ support it:
[`napi_throw_type_error`]: #n_api_napi_throw_type_error
[`napi_unwrap`]: #n_api_napi_unwrap
[`napi_wrap`]: #n_api_napi_wrap

[`process.release`]: process.html#process_process_release
3 changes: 2 additions & 1 deletion src/node.cc
Expand Up @@ -3254,7 +3254,8 @@ void SetupProcessObject(Environment* env,
// process.release
Local<Object> release = Object::New(env->isolate());
READONLY_PROPERTY(process, "release", release);
READONLY_PROPERTY(release, "name", OneByteString(env->isolate(), "node"));
READONLY_PROPERTY(release, "name",
OneByteString(env->isolate(), NODE_RELEASE));

#if NODE_VERSION_IS_LTS
READONLY_PROPERTY(release, "lts",
Expand Down
14 changes: 14 additions & 0 deletions src/node_api.cc
Expand Up @@ -3122,6 +3122,20 @@ napi_status napi_get_version(napi_env env, uint32_t* result) {
return napi_clear_last_error(env);
}

napi_status napi_get_node_version(napi_env env,
const napi_node_version** result) {
CHECK_ENV(env);
CHECK_ARG(env, result);
static const napi_node_version version = {
NODE_MAJOR_VERSION,
NODE_MINOR_VERSION,
NODE_PATCH_VERSION,
NODE_RELEASE
};
*result = &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
Expand Up @@ -536,6 +536,10 @@ NAPI_EXTERN napi_status napi_cancel_async_work(napi_env env,
// version management
NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result);

NAPI_EXTERN
napi_status napi_get_node_version(napi_env env,
const napi_node_version** version);

EXTERN_C_END

#endif // SRC_NODE_API_H_
7 changes: 7 additions & 0 deletions src/node_api_types.h
Expand Up @@ -102,4 +102,11 @@ typedef struct {
napi_status error_code;
} napi_extended_error_info;

typedef struct {
uint32_t major;
uint32_t minor;
uint32_t patch;
const char* release;
} napi_node_version;

#endif // SRC_NODE_API_TYPES_H_
4 changes: 4 additions & 0 deletions src/node_version.h
Expand Up @@ -15,6 +15,10 @@
#define NODE_STRINGIFY_HELPER(n) #n
#endif

#ifndef NODE_RELEASE
#define NODE_RELEASE "node"
#endif

#ifndef NODE_TAG
# if NODE_VERSION_IS_RELEASE
# define NODE_TAG ""
Expand Down
5 changes: 5 additions & 0 deletions test/addons-napi/test_general/test.js
Expand Up @@ -35,6 +35,11 @@ assert.ok(test_general.testGetPrototype(baseObject) !==
// expected version is currently 1
assert.strictEqual(test_general.testGetVersion(), 1);

const [ major, minor, patch, release ] = test_general.testGetNodeVersion();
assert.strictEqual(process.version.split('-')[0],
`v${major}.${minor}.${patch}`);
assert.strictEqual(release, process.release.name);

[
123,
'test string',
Expand Down
20 changes: 20 additions & 0 deletions test/addons-napi/test_general/test_general.c
Expand Up @@ -33,6 +33,25 @@ napi_value testGetVersion(napi_env env, napi_callback_info info) {
return result;
}

napi_value testGetNodeVersion(napi_env env, napi_callback_info info) {
const napi_node_version* node_version;
napi_value result, major, minor, patch, release;
NAPI_CALL(env, napi_get_node_version(env, &node_version));
NAPI_CALL(env, napi_create_uint32(env, node_version->major, &major));
NAPI_CALL(env, napi_create_uint32(env, node_version->minor, &minor));
NAPI_CALL(env, napi_create_uint32(env, node_version->patch, &patch));
NAPI_CALL(env, napi_create_string_utf8(env,
node_version->release,
(size_t)-1,
&release));
NAPI_CALL(env, napi_create_array_with_length(env, 4, &result));
NAPI_CALL(env, napi_set_element(env, result, 0, major));
NAPI_CALL(env, napi_set_element(env, result, 1, minor));
NAPI_CALL(env, napi_set_element(env, result, 2, patch));
NAPI_CALL(env, napi_set_element(env, result, 3, release));
return result;
}

napi_value doInstanceOf(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2];
Expand Down Expand Up @@ -142,6 +161,7 @@ void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals),
DECLARE_NAPI_PROPERTY("testGetPrototype", testGetPrototype),
DECLARE_NAPI_PROPERTY("testGetVersion", testGetVersion),
DECLARE_NAPI_PROPERTY("testGetNodeVersion", testGetNodeVersion),
DECLARE_NAPI_PROPERTY("doInstanceOf", doInstanceOf),
DECLARE_NAPI_PROPERTY("getUndefined", getUndefined),
DECLARE_NAPI_PROPERTY("getNull", getNull),
Expand Down

0 comments on commit 951adbe

Please sign in to comment.