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

Implement URL.from #28482

Closed
wants to merge 5 commits into from
Closed

Implement URL.from #28482

wants to merge 5 commits into from

Conversation

viktor-ku
Copy link
Contributor

It should substitute legacy url.format with respect
to the new URL API.

Based on #25099

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

It should substitude legacy `url.format` with respect
to the new URL API.

Based on discussion: #25099
Copy link
Contributor

@vsemozhetbyt vsemozhetbyt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
Just some possible doc nits.

doc/api/url.md Outdated Show resolved Hide resolved
doc/api/url.md Outdated Show resolved Hide resolved
doc/api/url.md Outdated Show resolved Hide resolved
doc/api/url.md Outdated Show resolved Hide resolved
Copy link
Member

@joyeecheung joyeecheung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should invent non-standard extensions on the URL class - if we want to provide a convenient method (even just as an experiment), we could put it directly on url instead.


let flags = 0;

if (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we instead wrote this more like we do in the existing codebase?:

    if (protocol === 'file:' ||
        protocol === 'https:' ||
        protocol === 'wss:' ||
        protocol === 'http:' ||
        protocol === 'ftp:' ||
        protocol === 'ws:' ||
        protocol === 'gopher:') {
      flags |= URL_FLAGS_SPECIAL;
    } else if (!host) {
      flags |= URL_FLAGS_CANNOT_BE_BASE;
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? Where would be such example?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example of what it would look like? I provided one above.

@addaleax addaleax added semver-minor PRs that contain new features and should be released in the next minor version. url Issues and PRs related to the legacy built-in url module. whatwg-url Issues and PRs related to the WHATWG URL implementation. labels Jul 1, 2019
@viktor-ku
Copy link
Contributor Author

@joyeecheung you have the point and it is valid. But URL.from returns a standard URL instance. It even takes an object that represents URLContext. And I think URL.from is fine just because of that reason.

@joyeecheung
Copy link
Member

joyeecheung commented Jul 2, 2019

@viktor-ku It would make sense if we controlled the URL interface, but URL comes from the URL standard and is placed in the global object. Adding a non-standard helper to URL just creates platform disparity without obvious gains, and it would make the API unnecessarily confusing if the upstream does add a similar way to contrust URL out of an object but with a different API. We wouldn't have that kind of risk if the method is just on url, the only downside is that it might be slightly less intuitive but then that is subjective - you can argue that having a non-standard API that only Node.js has (and cannot be found in the URL standard or places like MDN) is also unintuitive.

@viktor-ku
Copy link
Contributor Author

Just a quick update: URL.from wasn't welcomed to whatwg/url spec, so I will rename URL.from to something like createURL and also address feedback I got here. Probably on the weekend.

Any thought on how to name such function?

@joyeecheung

@Fishrock123
Copy link
Contributor

Just a quick update: URL.from wasn't welcomed to whatwg/url spec

Could you link to that conversation? That seems silly. Web browsers also suffer from this.

@devsnek
Copy link
Member

devsnek commented Jul 10, 2019

@Fishrock123 previous convos: whatwg/url#354 and #12682

right now URL is designed such that it can only ever represent an unambiguous absolute url. The current minimal possible output from this API (':') is very far from what URL objects are supposed to be able to represent. In both discussions above, it was recommended that node introduce a new api (not URL) for relative urls.

@jasnell
Copy link
Member

jasnell commented Jul 15, 2019

I'm +1 on adding the URL.from() function but the implementation can be greatly simplified here using something like:

URL.from = function(args) {
  return Object.assign(new URL(`${args.protocol||'http:'}//${args.host}||'example.com'}`), args);
}

Albeit with argument checking added.

@devsnek
Copy link
Member

devsnek commented Jul 15, 2019

@jasnell needs an host too, just new URL('http:') is an error.

@jasnell
Copy link
Member

jasnell commented Jul 15, 2019

heh, yeah, I'd accidentally omitted that in the example above. Will fix!

@silverwind
Copy link
Contributor

silverwind commented Jul 15, 2019

Should probably throw if protocol or host are absent? Or document the example values, lol.

@jasnell
Copy link
Member

jasnell commented Jul 15, 2019

I think throwing would be appropriate if those aren't available. A number of different scenarios may need to be accounted for depending on the protocol that is given (my example above is an oversimplification). For instance, if the protocol is mailto:, then we shouldn't look for host, we should look for pathname... e.g.

Object.assign(new URL('mailto:bob@example.com'), { pathname: 'sally@example.org' })

We will essentially need to special case known special URL protocols and treat unknown ones generically, but doing so still simplifies the implementation relative to this PR

@viktor-ku
Copy link
Contributor Author

Let me respectfully disagree on that one. I know that it will simplify implementation, but why would you need to parse the entire string when you already know parts of the URL like host, protocol etc? I want to make this function perform well! And yes, I'd like to add as minimal validation as possible so it would be users job to know what they want.

So I am leaving URL.from then 👍

I will restrict passing anything expect of {} and it will be their job to build what they need. Perhaps, one can write a complex 3rd party library that can perform all kinds of validations, but those who know exactly what they need won't be punished.

@viktor-ku
Copy link
Contributor Author

PR has been updated!

```

All properties are optional in case you want to build your `URL` object
gradually (note that you have to pass an empty object in this case anyway)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
gradually (note that you have to pass an empty object in this case anyway)
gradually (note that you have to pass an empty object in this case anyway).

@@ -1323,6 +1362,12 @@ console.log(myURL.origin);
[`url.format()`]: #url_url_format_urlobject
[`url.href`]: #url_url_href
[`url.parse()`]: #url_url_parse_urlstring_parsequerystring_slashesdenotehost
[`url.protocol`]: #url_url_protocol
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: bottom references are usually sorted in ASCII order.

@tjconcept
Copy link
Contributor

What about hostname?

url.format({protocol: 'http', hostname: '::1'})
// http://[::1]/

@BridgeAR BridgeAR force-pushed the master branch 2 times, most recently from 8ae28ff to 2935f72 Compare May 31, 2020 12:19
@jasnell jasnell added the stalled Issues and PRs that are stalled. label Jul 7, 2020
@viktor-ku
Copy link
Contributor Author

I will be honest, I was, and still is pretty confused about what to do with this. Opinions have greatly divided amongst reviewers and at this point I really don't know how (and if) to proceed. Closing for now, because of that.

@viktor-ku viktor-ku closed this Jul 30, 2020
@jasnell
Copy link
Member

jasnell commented Jul 30, 2020

Thank you for the work on this @viktor-ku ... Yeah, can definitely understand the confusion, I think we're still working through exactly the right thing to do with this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-minor PRs that contain new features and should be released in the next minor version. stalled Issues and PRs that are stalled. url Issues and PRs related to the legacy built-in url module. whatwg-url Issues and PRs related to the WHATWG URL implementation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants