URI.js
                                
                                
                                
                                    URI.js copied to clipboard
                            
                            
                            
                        bug: cannot get domain of URI missing protocol
> URI('portquiz.net:8').domain()
< ""
                                    
                                    
                                    
                                
host() and port()also don't work.
> URI.parse('portquiz.net:8')
< Object {protocol: "portquiz.net", urn: true, path: "8"}
Looks due to https://github.com/medialize/URI.js/blob/gh-pages/src/URI.js#L494
What protocols include .+-? https://github.com/medialize/URI.js/blob/gh-pages/src/URI.js#L199
yes, that's known behavior - not a bug. see #232 or #187 for details.
This seems like an unintuitive result for a very common scenario.
Maybe have URI() and URI.parse() ignore the literal spec, and introduce a new function URI.strictParse() which follows it?  Having every user write a preprocessing method is a bit wasteful.
This seems like an unintuitive result for a very common scenario.
I don't disagree, judging by the number of people who got stumped by this so far.
Maybe have URI() and URI.parse() ignore the literal spec, and introduce a new function URI.strictParse() which follows it? Having every user write a preprocessing method is a bit wasteful.
Since the developer likely knows what data they're dealing with, they could go with URI.parseAsHttp(input) instead of URI(input) to state their expectation of working with an HTTP/S URL. We're certainly not changing the way URI works right now, but we can easily add this feature in a non-breaking way. Should we start by bikeshedding the API? Do you want to implement this and send a PR after discussions?
Here are a few quick thoughts
URI.parseAsHttp(input)with leads to a number of new functions if we were to add support for more protocols- because of the existing signature of 
URI.parse(inputString, outputMap), we can't easily add an options object as another argument. I'm not sure I likeURI.parse({uri: inputString, option1: true}, outputMap)to get around that - since 
URI.parseis an internal method and the proposed new function an external method (i.e. it is not ever used internally, only called by the developer to initiate working with URI), we could go withURI.parseWithDefault(inputString, optionsMap). This wayoptionsMapcould contain defaults for all the components, not only the protocol. This looks dangerously close toURI(inputString, relativeBase), though. 
Maybe something like this:
> URI.parse('portquiz.net:8').withDefaults({protocol: 'http'})
< Object {protocol: "http", domain: "portquiz.net", port: "8"}
where withDefaults returns a new URI object?
URI.parse('portquiz.net:8').withDefaults({protocol: 'http'})
that's not going to work (easily) because at the point withDefaults() is evaluated, the "wrong interpretation" of your input string has already happened.
Sure, but we should be able to toString the URI object to get back the original string, and re-parse from there with the defaults.
Sure, but we should be able to toString the URI object to get back the original string, and re-parse from there with the defaults.
why knowingly parse the string twice? unless you expect .withDefaults() to not engage very often (which is an assumption I'm not ready to share).
Doesn't seem too expensive to do so, and makes the API clean.
Alternatively, you could flip the order to only parse once:
URI.withDefaults({protocol: 'http'}).parse('portquiz.net:8')
which is also pretty clean.
Mind re-opening this issue to get more pairs of eyes reviewing any proposals?
Why do you consider URI.withDefaults({protocol: 'http'}).parse('portquiz.net:8') better than URI.parseWithDefaults('portquiz.net:8', {protocol: 'http'})?
I'm partial to the builder pattern for flexibility/future-proofing and readability. A lot of good discussion here which I'd do a disservice to if I were to try to summarize.
In that case I'd prefer to go the functional programming route:
URI.withDefaults({ protocol: 'http' })('portquiz.net:8');
var httpUri = URI.withDefaults({ protocol: 'http' });
[ 'portquiz.net:8' ].map(httpUri);
This would allow the API user to do the work only once.
Now the next question (less question, more obstacle) is if the defaults transcend the URI.parse() method, so that the following behaves the same way:
var uri = URI.withDefaults({ protocol: 'http' })('portquiz.net:8');
uri.href('portquiz.net:9')
I guess URI.withDefaults() would work like a factory, bootstrapping the URI "class" so that any instance of that customized URI behaves consistently. We've dealt with this in an ugly and global way in the past, as URI.escapeQuerySpace can attest.
Sure, that sounds really reasonable.
I'm running into this as well. I want to parse a list of URLs that may or may not contain protocols, it may even just be a path.
i.e.:
['http://hostname:port/path?query', 'hostname:port', '/path']
Based on: https://medialize.github.io/URI.js/about-uris.html
It would think we could even have a flag that will ensure we always parse a URL instead of a URN?
Or simply URI.parseURL(urlString) so I could do new URI(URI.parseURL(urlString))
I'd love to see this implemented.
I've implemented a possible solution using @MichielVanderlee 's suggestion.
https://github.com/medialize/URI.js/pull/374
This allows me to now do let uri = new URI(URI.toUri('somesite.com', {scheme: 'http'}));
after which, uri.domain() will return the expected somesite.com
We'll see if it's worthy of being pulled in, but for now, it's working for my needs.