Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
47 changes: 18 additions & 29 deletions src/node_url_pattern.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,32 +307,21 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
auto tmpl = env->urlpatterninit_template();
if (tmpl.IsEmpty()) {
static constexpr std::string_view namesVec[] = {
"protocol",
"username",
"password",
"baseURL",
"hash",
"hostname",
"port",
"password",
"pathname",
"port",
"protocol",
"search",
"hash",
"baseURL",
"username",
};
tmpl = DictionaryTemplate::New(isolate, namesVec);
env->set_urlpatterninit_template(tmpl);
}

MaybeLocal<Value> values[] = {
Undefined(isolate), // protocol
Undefined(isolate), // username
Undefined(isolate), // password
Undefined(isolate), // hostname
Undefined(isolate), // port
Undefined(isolate), // pathname
Undefined(isolate), // search
Undefined(isolate), // hash
Undefined(isolate), // baseURL
};

MaybeLocal<Value> values[9];
int idx = 0;
Local<Value> temp;
const auto trySet = [&](const std::optional<std::string>& val) {
Expand All @@ -346,28 +335,28 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
return true;
};

if (!trySet(init.protocol) || !trySet(init.username) ||
!trySet(init.password) || !trySet(init.hostname) || !trySet(init.port) ||
!trySet(init.pathname) || !trySet(init.search) || !trySet(init.hash) ||
!trySet(init.base_url)) {
if (!trySet(init.base_url) || !trySet(init.hash) || !trySet(init.hostname) ||
!trySet(init.password) || !trySet(init.pathname) || !trySet(init.port) ||
!trySet(init.protocol) || !trySet(init.search) ||
!trySet(init.username)) {
return {};
}
return NewDictionaryInstance(env->context(), tmpl, values);
return tmpl->NewInstance(context, values);
}

std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject(
Environment* env, Local<Object> obj) {
ada::url_pattern_init init{};
Local<String> components[] = {
env->protocol_string(),
env->username_string(),
env->password_string(),
env->base_url_string(),
env->hash_string(),
env->hostname_string(),
env->port_string(),
env->password_string(),
env->pathname_string(),
env->port_string(),
env->protocol_string(),
env->search_string(),
env->hash_string(),
env->base_url_string(),
env->username_string(),
};
auto isolate = env->isolate();
const auto set_parameter = [&](std::string_view key, std::string_view value) {
Expand Down
40 changes: 40 additions & 0 deletions test/parallel/test-urlpattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@ assert.throws(() => {
message: 'boom',
});

{
const accessed = [];
const expected = [
'baseURL',
'hash',
'hostname',
'password',
'pathname',
'port',
'protocol',
'search',
'username',
];
const init = new Proxy({}, {
get(target, name, receiver) {
accessed.push(name);
return Reflect.get(target, name, receiver);
},
});

new URLPattern(init);
assert.deepStrictEqual(accessed, expected);
}

// Verify that if an error is thrown while accessing the ignoreCase
// option, the error is appropriately propagated.
assert.throws(() => {
Expand All @@ -26,3 +50,19 @@ assert.throws(() => {
}, {
message: 'boom'
});

{
const input = new URLPattern({ pathname: '/x' })
.exec({
protocol: 'https',
pathname: '/x',
username: undefined,
}).inputs[0];

assert.deepStrictEqual(Object.keys(input), ['pathname', 'protocol']);
assert.strictEqual('username' in input, false);
assert.deepStrictEqual({ ...input }, {
pathname: '/x',
protocol: 'https',
});
}
Loading