Skip to content

Commit 9c1a0bb

Browse files
author
Mert Can Altin
committed
node-api: add support for napi_set_named_property_len function
1 parent 9807ede commit 9c1a0bb

File tree

5 files changed

+120
-0
lines changed

5 files changed

+120
-0
lines changed

doc/api/n-api.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3134,6 +3134,35 @@ overhead in creating/storing strings with this method.
31343134
The JavaScript `string` type is described in
31353135
[Section 6.1.4][] of the ECMAScript Language Specification.
31363136

3137+
#### `napi_set_named_property_len`
3138+
3139+
<!-- YAML
3140+
added:
3141+
- v22.1.0
3142+
-->
3143+
3144+
> **Stability**: 1 - Experimental
3145+
3146+
```c
3147+
napi_status NAPI_CDECL napi_set_named_property_len(napi_env env,
3148+
napi_value object,
3149+
const char* utf8name,
3150+
size_t name_length,
3151+
napi_value value);
3152+
```
3153+
3154+
* `[in] env`: The environment that the API is invoked under.
3155+
* `[in] object`: The JavaScript object on which to set the named property.
3156+
* `[in] utf8name`: Character buffer representing a UTF-8-encoded string.
3157+
* `[in] name_length`: The length of the string in bytes, or NAPI\_AUTO\_LENGTH if it is null-terminated.
3158+
* `[in] value`: The napi\_value representing the value to set as the named property.
3159+
Returns napi\_ok if the API succeeded.
3160+
3161+
This API sets a named property on a JavaScript object, treating '\0'
3162+
characters as values rather than terminators. This allows for more
3163+
flexible property names, especially when dealing with virtual module
3164+
names or other scenarios where '\0' characters are used as part of the name.
3165+
31373166
### Functions to convert from Node-API to C types
31383167

31393168
#### `napi_get_array_length`

src/js_native_api.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_utf16(
118118
napi_env env, const char16_t* str, size_t length, napi_value* result);
119119
#endif // NAPI_EXPERIMENTAL
120120

121+
#ifdef NAPI_EXPERIMENTAL
122+
#define NODE_API_EXPERIMENTAL_HAS_PROPERTY_KEYS
123+
NAPI_EXTERN napi_status NAPI_CDECL
124+
napi_set_named_property_len(napi_env env,
125+
napi_value object,
126+
const char* utf8name,
127+
size_t name_length,
128+
napi_value value);
129+
#endif // NAPI_EXPERIMENTAL
130+
121131
NAPI_EXTERN napi_status NAPI_CDECL napi_create_symbol(napi_env env,
122132
napi_value description,
123133
napi_value* result);

src/js_native_api_v8.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,24 @@ napi_status NAPI_CDECL node_api_create_property_key_utf16(napi_env env,
17181718
});
17191719
}
17201720

1721+
napi_status NAPI_CDECL napi_set_named_property_len(napi_env env,
1722+
napi_value object,
1723+
const char* utf8name,
1724+
size_t name_length,
1725+
napi_value value) {
1726+
std::u16string utf16name;
1727+
napi_status status =
1728+
CHECK_NEW_FROM_UTF8_LEN(env, utf8name, name_length, &utf16name);
1729+
if (status != napi_ok) {
1730+
return status;
1731+
}
1732+
1733+
status = napi_set_named_property(
1734+
env, object, utf16name.data(), utf16name.length(), value);
1735+
1736+
return status;
1737+
}
1738+
17211739
napi_status NAPI_CDECL napi_create_double(napi_env env,
17221740
double value,
17231741
napi_value* result) {

test/js-native-api/test_string/test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str6), str6);
130130
assert.strictEqual(test_string.Utf16Length(str6), 5);
131131
assert.strictEqual(test_string.Utf8Length(str6), 14);
132132

133+
const obj1 = test_string.TestSetNamedPropertyLen();
134+
assert.strictEqual(typeof obj1, 'object');
135+
assert.strictEqual(Object.keys(obj1).length, 1);
136+
assert.strictEqual(obj1['\0test'], 42);
137+
138+
const obj2 = test_string.TestSetNamedPropertyLenAutoLength();
139+
assert.strictEqual(typeof obj2, 'object');
140+
assert.strictEqual(Object.keys(obj2).length, 1);
141+
assert.strictEqual(obj2['\0test'], 42);
142+
133143
assert.throws(() => {
134144
test_string.TestLargeUtf8();
135145
}, /^Error: Invalid argument$/);

test/js-native-api/test_string/test_string.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,59 @@ static napi_value TestPropertyKeyUtf16AutoLength(napi_env env,
310310
auto_length);
311311
}
312312

313+
static napi_value TestSetNamedPropertyLen(napi_env env, napi_callback_info info) {
314+
size_t argc = 0;
315+
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
316+
317+
if (argc < 1) {
318+
napi_throw_error(env, nullptr, "Invalid number of arguments");
319+
return nullptr;
320+
}
321+
322+
napi_value object;
323+
napi_create_object(env, &object);
324+
325+
const char* key = "\0test";
326+
napi_value value;
327+
napi_create_int32(env, 42, &value);
328+
329+
napi_status status =
330+
napi_set_named_property_len(env, object, key, strlen(key), value);
331+
if (status != napi_ok) {
332+
napi_throw_error(env, nullptr, "Failed to set named property");
333+
return nullptr;
334+
}
335+
336+
return object;
337+
}
338+
339+
static napi_value TestSetNamedPropertyLenAutoLength(napi_env env,
340+
napi_callback_info info) {
341+
size_t argc = 0;
342+
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
343+
344+
if (argc < 1) {
345+
napi_throw_error(env, nullptr, "Invalid number of arguments");
346+
return nullptr;
347+
}
348+
349+
napi_value object;
350+
napi_create_object(env, &object);
351+
352+
const char* key = "\0test";
353+
napi_value value;
354+
napi_create_int32(env, 42, &value);
355+
356+
napi_status status =
357+
napi_set_named_property_len(env, object, key, strlen(key), value);
358+
if (status != napi_ok) {
359+
napi_throw_error(env, nullptr, "Failed to set named property");
360+
return nullptr;
361+
}
362+
363+
return object;
364+
}
365+
313366
static napi_value Utf16Length(napi_env env, napi_callback_info info) {
314367
napi_value args[1];
315368
NODE_API_CALL(env, validate_and_retrieve_single_string_arg(env, info, args));

0 commit comments

Comments
 (0)