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

URLPattern search param order matters #176

Open
reggi opened this issue May 1, 2023 · 2 comments
Open

URLPattern search param order matters #176

reggi opened this issue May 1, 2023 · 2 comments

Comments

@reggi
Copy link

reggi commented May 1, 2023

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.

@wanderview
Copy link
Member

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.

@bathos
Copy link

bathos commented May 3, 2023

@reggi You may be interested in this related discussion: #150

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants