Skip to content

Commit

Permalink
src: first pass on adding version management apis
Browse files Browse the repository at this point in the history
PR-URL: nodejs/node-addon-api#325
Reviewed-By: Michael Dawson <[email protected]>
  • Loading branch information
John French committed Sep 18, 2018
1 parent 91d3c29 commit b308bea
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ still a work in progress as its not yet complete).
- [Async Operations](doc/async_operations.md)
- [AsyncWorker](doc/async_worker.md)
- [Promises](doc/promises.md)
- [Version management](doc/version_management.md)

<a name="examples"></a>

Expand Down
43 changes: 43 additions & 0 deletions doc/version_management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# VersionManagement

The `Napi::VersionManagement` class contains methods that allow information
to be retrieved about the version of N-API and Node.js. In some cases it is
important to make decisions based on different versions of the system.

## Methods

### GetNapiVersion

Retrieves the highest N-API version supported by Node.js runtime.

```cpp
static uint32_t GetNapiVersion(Env env);
```
- `[in] env`: The environment in which the API is invoked under.
Returns the highest N-API version supported by Node.js runtime.
### GetNodeVersion
Retrives information about Node.js version present on the system. All the
information is stored in the `napi_node_version` structrue that is defined as
shown below:
```cpp
typedef struct {
uint32_t major;
uint32_t minor;
uint32_t patch;
const char* release;
} napi_node_version;
````
```cpp
static const napi_node_version* GetNodeVersion(Env env);
```

- `[in] env`: The environment in which the API is invoked under.

Returns the structure a pointer to the structure `napi_node_version` populated by
the version information of Node.js runtime.
18 changes: 18 additions & 0 deletions napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3319,6 +3319,24 @@ inline int64_t MemoryManagement::AdjustExternalMemory(Env env, int64_t change_in
return result;
}

////////////////////////////////////////////////////////////////////////////////
// Version Management class
////////////////////////////////////////////////////////////////////////////////

inline uint32_t VersionManagement::GetNapiVersion(Env env) {
uint32_t result;
napi_status status = napi_get_version(env, &result);
NAPI_THROW_IF_FAILED(env, status, 0);
return result;
}

inline const napi_node_version* VersionManagement::GetNodeVersion(Env env) {
const napi_node_version* result;
napi_status status = napi_get_node_version(env, &result);
NAPI_THROW_IF_FAILED(env, status, 0);
return result;
}

// These macros shouldn't be useful in user code.
#undef NAPI_THROW
#undef NAPI_THROW_IF_FAILED
Expand Down
7 changes: 7 additions & 0 deletions napi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,13 @@ namespace Napi {
static int64_t AdjustExternalMemory(Env env, int64_t change_in_bytes);
};

// Version management
class VersionManagement {
public:
static uint32_t GetNapiVersion(Env env);
static const napi_node_version* GetNodeVersion(Env env);
};

} // namespace Napi

// Inline implementations of all the above class methods are included here.
Expand Down
2 changes: 2 additions & 0 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Object InitPromise(Env env);
Object InitTypedArray(Env env);
Object InitObjectWrap(Env env);
Object InitObjectReference(Env env);
Object InitVersionManagement(Env env);

Object Init(Env env, Object exports) {
exports.Set("arraybuffer", InitArrayBuffer(env));
Expand All @@ -45,6 +46,7 @@ Object Init(Env env, Object exports) {
exports.Set("typedarray", InitTypedArray(env));
exports.Set("objectwrap", InitObjectWrap(env));
exports.Set("objectreference", InitObjectReference(env));
exports.Set("version_management", InitVersionManagement(env));
return exports;
}

Expand Down
1 change: 1 addition & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
'typedarray.cc',
'objectwrap.cc',
'objectreference.cc',
'version_management.cc'
],
'include_dirs': ["<!@(node -p \"require('../').include\")"],
'dependencies': ["<!(node -p \"require('../').gyp\")"],
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ let testModules = [
'typedarray',
'objectwrap',
'objectreference',
'version_management'
];

if (typeof global.gc === 'function') {
Expand Down
27 changes: 27 additions & 0 deletions test/version_management.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "napi.h"

using namespace Napi;

Value getNapiVersion(const CallbackInfo& info) {
Napi::Env env = info.Env();
uint32_t napi_version = VersionManagement::GetNapiVersion(env);
return Number::New(env, napi_version);
}

Value getNodeVersion(const CallbackInfo& info) {
Napi::Env env = info.Env();
const napi_node_version* node_version = VersionManagement::GetNodeVersion(env);
Object version = Object::New(env);
version.Set("major", Number::New(env, node_version->major));
version.Set("minor", Number::New(env, node_version->minor));
version.Set("patch", Number::New(env, node_version->patch));
version.Set("release", String::New(env, node_version->release));
return version;
}

Object InitVersionManagement(Env env) {
Object exports = Object::New(env);
exports["getNapiVersion"] = Function::New(env, getNapiVersion);
exports["getNodeVersion"] = Function::New(env, getNodeVersion);
return exports;
}
32 changes: 32 additions & 0 deletions test/version_management.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));

function parseVersion() {
const expected = {};
expected.napi = parseInt(process.versions.napi);
expected.release = process.release.name;
const nodeVersion = process.versions.node.split('.');
expected.major = parseInt(nodeVersion[0]);
expected.minor = parseInt(nodeVersion[1]);
expected.patch = parseInt(nodeVersion[2]);
return expected;
}

function test(binding) {

const expected = parseVersion();

const napiVersion = binding.version_management.getNapiVersion();
assert.strictEqual(napiVersion, expected.napi);

const nodeVersion = binding.version_management.getNodeVersion();
assert.strictEqual(nodeVersion.major, expected.major);
assert.strictEqual(nodeVersion.minor, expected.minor);
assert.strictEqual(nodeVersion.patch, expected.patch);
assert.strictEqual(nodeVersion.release, expected.release);

}

0 comments on commit b308bea

Please sign in to comment.