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

src: add Env::GetModuleFileName #1327

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 11 additions & 0 deletions doc/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ addon. The item will be passed to the function `fini` which gets called when an
instance of the addon is unloaded. This overload accepts an additional hint to
be passed to `fini`.

### GetModuleFileName

```cpp
std::string_view Napi::Env::GetModuleFileName() const;
```

Returns a A URL containing the absolute path of the location from which the
add-on was loaded. For a file on the local file system it will start with
`file://`. The `string_view` data is null-terminated and owned by env and is
only valid while the add-on is loaded.

### AddCleanupHook

```cpp
Expand Down
8 changes: 8 additions & 0 deletions napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,14 @@ void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) {
}
#endif // NAPI_VERSION > 5

#if NAPI_VERSION > 8
inline std::string_view Env::GetModuleFileName() const {
const char* result;
napi_status status = node_api_get_module_file_name(_env, &result);
Copy link
Member

@legendecas legendecas Jun 13, 2023

Choose a reason for hiding this comment

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

Node.js v16.x (and add-ons compiled with the common.gypi shipped with Node.js) is still compiled with C++14, however std::string_view is available since c++17. I think we should avoid using c++17 features here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mhmm mhmm that makes sense ... So then would we prefer the alternative of node-addon-api returning a new std::string by copying the const char* result?

Copy link
Member

Choose a reason for hiding this comment

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

Would it be good to return the const char* result? If needed, copying the result with std::string is fairly easy.

NAPI_THROW_IF_FAILED(*this, status, std::string_view());
return std::string_view(result);
}
#endif // NAPI_VERSION > 8
////////////////////////////////////////////////////////////////////////////////
// Value class
////////////////////////////////////////////////////////////////////////////////
Expand Down
4 changes: 4 additions & 0 deletions napi.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ class Env {
} * data;
};
#endif // NAPI_VERSION > 2

#if NAPI_VERSION > 8
std::string_view GetModuleFileName() const;
#endif // NAPI_VERSION > 8
};

/// A JavaScript value of unknown type.
Expand Down
7 changes: 6 additions & 1 deletion test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ Object InitThunkingManual(Env env);
Object InitObjectFreezeSeal(Env env);
Object InitTypeTaggable(Env env);
#endif

#if (NAPI_VERSION > 8)
Object InitEnvMiscellaneous(Env env);
#endif
#if defined(NODE_ADDON_API_ENABLE_MAYBE)
Object InitMaybeCheck(Env env);
#endif
Expand Down Expand Up @@ -171,6 +173,9 @@ Object Init(Env env, Object exports) {
exports.Set("object_freeze_seal", InitObjectFreezeSeal(env));
exports.Set("type_taggable", InitTypeTaggable(env));
#endif
#if (NAPI_VERSION > 8)
exports.Set("env_misc", InitEnvMiscellaneous(env));
#endif

#if defined(NODE_ADDON_API_ENABLE_MAYBE)
exports.Set("maybe_check", InitMaybeCheck(env));
Expand Down
1 change: 1 addition & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
'dataview/dataview.cc',
'dataview/dataview_read_write.cc',
'env_cleanup.cc',
'env_misc.cc',
'error.cc',
'error_handling_for_primitives.cc',
'external.cc',
Expand Down
2 changes: 1 addition & 1 deletion test/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ exports.runTest = async function (test, buildType, buildPathRoot = process.env.B
].map(it => require.resolve(it));

for (const item of bindings) {
await Promise.resolve(test(require(item)))
await Promise.resolve(test(require(item), { bindingPath: item }))
.finally(exports.mustCall());
}
};
Expand Down
25 changes: 25 additions & 0 deletions test/env_misc.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "napi.h"
#include "test_helper.h"

#if (NAPI_VERSION > 8)

using namespace Napi;

namespace {

Value GetModuleFileName(const CallbackInfo& info) {
Env env = info.Env();
return String::New(env, env.GetModuleFileName().data());
}

} // end anonymous namespace

Object InitEnvMiscellaneous(Env env) {
Object exports = Object::New(env);

exports["get_module_file_name"] = Function::New(env, GetModuleFileName);

return exports;
}

#endif
12 changes: 12 additions & 0 deletions test/env_misc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const assert = require('assert');
const { pathToFileURL } = require('url');

module.exports = require('./common').runTest(test);

function test (binding, { bindingPath } = {}) {
const path = binding.env_misc.get_module_file_name();
const bindingFileUrl = pathToFileURL(bindingPath).toString();
assert(bindingFileUrl === path);
}
4 changes: 4 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ if (napiVersion < 8 && !filterConditionsProvided) {
testModules.splice(testModules.indexOf('type_taggable'), 1);
}

if (napiVersion < 9 && !filterConditionsProvided) {
testModules.splice(testModules.indexOf('env_misc'), 1);
}

(async function () {
console.log(`Testing with Node-API Version '${napiVersion}'.`);

Expand Down