Skip to content

Commit 820d97d

Browse files
cjihrigaddaleax
authored andcommitted
n-api: add napi_delete_property()
Fixes: #13924 PR-URL: #13934 Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jason Ginchereau <[email protected]>
1 parent 6316c9a commit 820d97d

File tree

5 files changed

+119
-0
lines changed

5 files changed

+119
-0
lines changed

doc/api/n-api.md

+23
Original file line numberDiff line numberDiff line change
@@ -2276,6 +2276,28 @@ Returns `napi_ok` if the API succeeded.
22762276
This API checks if the Object passed in has the named property.
22772277

22782278

2279+
#### *napi_delete_property*
2280+
<!-- YAML
2281+
added: REPLACEME
2282+
-->
2283+
```C
2284+
napi_status napi_delete_property(napi_env env,
2285+
napi_value object,
2286+
napi_value key,
2287+
bool* result);
2288+
```
2289+
2290+
- `[in] env`: The environment that the N-API call is invoked under.
2291+
- `[in] object`: The object to query.
2292+
- `[in] key`: The name of the property to delete.
2293+
- `[out] result`: Whether the property deletion succeeded or not. `result` can
2294+
optionally be ignored by passing `NULL`.
2295+
2296+
Returns `napi_ok` if the API succeeded.
2297+
2298+
This API attempts to delete the `key` own property from `object`.
2299+
2300+
22792301
#### *napi_set_named_property*
22802302
<!-- YAML
22812303
added: v8.0.0
@@ -3073,6 +3095,7 @@ support it:
30733095
[`napi_delete_async_work`]: #n_api_napi_delete_async_work
30743096
[`napi_define_class`]: #n_api_napi_define_class
30753097
[`napi_delete_element`]: #n_api_napi_delete_element
3098+
[`napi_delete_property`]: #n_api_napi_delete_property
30763099
[`napi_delete_reference`]: #n_api_napi_delete_reference
30773100
[`napi_escape_handle`]: #n_api_napi_escape_handle
30783101
[`napi_get_array_length`]: #n_api_napi_get_array_length

src/node_api.cc

+22
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,28 @@ napi_status napi_get_property(napi_env env,
10021002
return GET_RETURN_STATUS(env);
10031003
}
10041004

1005+
napi_status napi_delete_property(napi_env env,
1006+
napi_value object,
1007+
napi_value key,
1008+
bool* result) {
1009+
NAPI_PREAMBLE(env);
1010+
CHECK_ARG(env, key);
1011+
1012+
v8::Isolate* isolate = env->isolate;
1013+
v8::Local<v8::Context> context = isolate->GetCurrentContext();
1014+
v8::Local<v8::Value> k = v8impl::V8LocalValueFromJsValue(key);
1015+
v8::Local<v8::Object> obj;
1016+
1017+
CHECK_TO_OBJECT(env, context, obj, object);
1018+
v8::Maybe<bool> delete_maybe = obj->Delete(context, k);
1019+
CHECK_MAYBE_NOTHING(env, delete_maybe, napi_generic_failure);
1020+
1021+
if (result != NULL)
1022+
*result = delete_maybe.FromMaybe(false);
1023+
1024+
return GET_RETURN_STATUS(env);
1025+
}
1026+
10051027
napi_status napi_set_named_property(napi_env env,
10061028
napi_value object,
10071029
const char* utf8name,

src/node_api.h

+4
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ NAPI_EXTERN napi_status napi_get_property(napi_env env,
226226
napi_value object,
227227
napi_value key,
228228
napi_value* result);
229+
NAPI_EXTERN napi_status napi_delete_property(napi_env env,
230+
napi_value object,
231+
napi_value key,
232+
bool* result);
229233
NAPI_EXTERN napi_status napi_set_named_property(napi_env env,
230234
napi_value object,
231235
const char* utf8name,

test/addons-napi/test_object/test.js

+44
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,47 @@ assert.strictEqual(newObject.test_string, 'test string');
120120
assert(wrapper.protoA, true);
121121
assert(wrapper.protoB, true);
122122
}
123+
124+
{
125+
// Verify that normal and nonexistent properties can be deleted.
126+
const sym = Symbol();
127+
const obj = { foo: 'bar', [sym]: 'baz' };
128+
129+
assert.strictEqual('foo' in obj, true);
130+
assert.strictEqual(sym in obj, true);
131+
assert.strictEqual('does_not_exist' in obj, false);
132+
assert.strictEqual(test_object.Delete(obj, 'foo'), true);
133+
assert.strictEqual('foo' in obj, false);
134+
assert.strictEqual(sym in obj, true);
135+
assert.strictEqual('does_not_exist' in obj, false);
136+
assert.strictEqual(test_object.Delete(obj, sym), true);
137+
assert.strictEqual('foo' in obj, false);
138+
assert.strictEqual(sym in obj, false);
139+
assert.strictEqual('does_not_exist' in obj, false);
140+
}
141+
142+
{
143+
// Verify that non-configurable properties are not deleted.
144+
const obj = {};
145+
146+
Object.defineProperty(obj, 'foo', { configurable: false });
147+
assert.strictEqual(test_object.Delete(obj, 'foo'), false);
148+
assert.strictEqual('foo' in obj, true);
149+
}
150+
151+
{
152+
// Verify that prototype properties are not deleted.
153+
function Foo() {
154+
this.foo = 'bar';
155+
}
156+
157+
Foo.prototype.foo = 'baz';
158+
159+
const obj = new Foo();
160+
161+
assert.strictEqual(obj.foo, 'bar');
162+
assert.strictEqual(test_object.Delete(obj, 'foo'), true);
163+
assert.strictEqual(obj.foo, 'baz');
164+
assert.strictEqual(test_object.Delete(obj, 'foo'), true);
165+
assert.strictEqual(obj.foo, 'baz');
166+
}

test/addons-napi/test_object/test_object.c

+26
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,31 @@ napi_value Has(napi_env env, napi_callback_info info) {
8686
return ret;
8787
}
8888

89+
napi_value Delete(napi_env env, napi_callback_info info) {
90+
size_t argc = 2;
91+
napi_value args[2];
92+
93+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
94+
NAPI_ASSERT(env, argc == 2, "Wrong number of arguments");
95+
96+
napi_valuetype valuetype0;
97+
NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
98+
NAPI_ASSERT(env, valuetype0 == napi_object,
99+
"Wrong type of arguments. Expects an object as first argument.");
100+
101+
napi_valuetype valuetype1;
102+
NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
103+
NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
104+
"Wrong type of arguments. Expects a string or symbol as second.");
105+
106+
bool result;
107+
napi_value ret;
108+
NAPI_CALL(env, napi_delete_property(env, args[0], args[1], &result));
109+
NAPI_CALL(env, napi_get_boolean(env, result, &ret));
110+
111+
return ret;
112+
}
113+
89114
napi_value New(napi_env env, napi_callback_info info) {
90115
napi_value ret;
91116
NAPI_CALL(env, napi_create_object(env, &ret));
@@ -171,6 +196,7 @@ void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
171196
DECLARE_NAPI_PROPERTY("Get", Get),
172197
DECLARE_NAPI_PROPERTY("Set", Set),
173198
DECLARE_NAPI_PROPERTY("Has", Has),
199+
DECLARE_NAPI_PROPERTY("Delete", Delete),
174200
DECLARE_NAPI_PROPERTY("New", New),
175201
DECLARE_NAPI_PROPERTY("Inflate", Inflate),
176202
DECLARE_NAPI_PROPERTY("Wrap", Wrap),

0 commit comments

Comments
 (0)