urlpattern icon indicating copy to clipboard operation
urlpattern copied to clipboard

URLPattern search param order matters

Open reggi opened this issue 2 years ago • 2 comments

Currently search query parameters are fixed and matches will only occur if they are in the URL in the same order.

new URLPattern({ search: "alpha=true&beta=true" }).exec("https://example.com/hello?alpha=true&beta=true")
{
  inputs: [ "https://example.com/hello?alpha=true&beta=true" ],
  protocol: { input: "https", groups: { "0": "https" } },
  username: { input: "", groups: { "0": "" } },
  password: { input: "", groups: { "0": "" } },
  hostname: { input: "example.com", groups: { "0": "example.com" } },
  port: { input: "", groups: { "0": "" } },
  pathname: { input: "/hello", groups: { "0": "/hello" } },
  search: { input: "alpha=true&beta=true", groups: {} },
  hash: { input: "", groups: { "0": "" } }
}

new URLPattern({ search: "alpha=true&beta=true" }).exec("https://example.com/hello?beta=true&alpha=true")
null

Realizing this I sought out to create a regex pattern that would help solve this:

This regex will require alpha and beta but will also match extra query parameters.

const searchRegExp = (search: string) => `^${search.split('&').map(v => `(?=.*${v})`).join('')}.*$`
searchRegExp('alpha=true&beta=true')
^(?=.*alpha=true)(?=.*beta=true).*$

Here's the match working:

'alpha=true&beta=true'.match(/^(?=.*alpha=true)(?=.*beta=true).*$/)
[ "alpha=true&beta=true" ]
'beta=true&alpha=true'.match(/^(?=.*alpha=true)(?=.*beta=true).*$/)
[ "beta=true&alpha=true" ]

However because there's a positive lookahead in the pattern I think the error is requesting it must not start with ? because this code takes into account the ? in the beginning of any search params string. It would seem that you can't use a ? in the regex because of this collision.

> new URLPattern({ search: "/^(?=.*alpha=true)(?=.*beta=true).*$/" }).exec("https://example.com/hello?alpha=true&beta=true")
Uncaught TypeError: tokenizer error: invalid regex: must not start with ?, and may only contain ascii (at char 2)
    at new URLPattern (ext:deno_url/01_urlpattern.js:70:28)
    at <anonymous>:2:1

I just thought I'd document this behavior for others. Feel free to merge / close this ticket.

reggi avatar May 01 '23 00:05 reggi

Right, URLPattern is not very useful for filtering on specific query parameters because of the ordering issue. We could enahance the API to better support this, but right now its perhaps more natural to use something like URLSearchParams.

I think to solve this we would need to find a reasonable API shape and somehow prove out it would be effective with web developers.

wanderview avatar May 03 '23 17:05 wanderview

@reggi You may be interested in this related discussion: https://github.com/WICG/urlpattern/issues/150

bathos avatar May 03 '23 18:05 bathos