Installation
Quick Take
Background
It’s easy to validate the absolute URL’s:
<a href="https://www.npmjs.com">z</a>
It’s harder to validate relative URL’s:
<a href="//example.com/path/resource.txt">z</a>
<a href="/path/resource.txt">z</a>
<a href="path/resource.txt">z</a>
<a href="/path/resource.txt">z</a>
<a href="../resource.txt">z</a>
<a href="./resource.txt">z</a>
<a href="resource.txt">z</a>
<a href="#fragment">z</a>
But spec-wise, at least theoretically, these are also correct values (see wikipedia for more).
Considering the base URI of http://a/b/c/d;p?q
, the following URI’s would get resolved accordingly:
<a href="g:h">z</a> -> "g:h"
<a href="g">z</a> -> "http://a/b/c/g"
<a href="./g">z</a> -> "http://a/b/c/g"
<a href="g/">z</a> -> "http://a/b/c/g/"
<a href="/g">z</a> -> "http://a/g"
<a href="//g">z</a> -> "http://g"
<a href="?y">z</a> -> "http://a/b/c/d;p?y"
<a href="g?y">z</a> -> "http://a/b/c/g?y"
<a href="#s">z</a> -> "http://a/b/c/d;p?q#s"
<a href="g#s">z</a> -> "http://a/b/c/g#s"
<a href="g?y#s">z</a> -> "http://a/b/c/g?y#s"
<a href=";x">z</a> -> "http://a/b/c/;x"
<a href="g;x">z</a> -> "http://a/b/c/g;x"
<a href="g;x?y#s">z</a> -> "http://a/b/c/g;x?y#s"
<a href="">z</a> -> "http://a/b/c/d;p?q"
<a href=".">z</a> -> "http://a/b/c/"
<a href="./">z</a> -> "http://a/b/c/"
<a href="..">z</a> -> "http://a/b/"
<a href="../">z</a> -> "http://a/b/"
<a href="../g">z</a> -> "http://a/b/g"
<a href="../..">z</a> -> "http://a/"
<a href="../../">z</a> -> "http://a/"
<a href="../../g">z</a> -> "http://a/g"
Validating them all
As you saw, relative URI’s can be pretty much anything, including empty string and random letters like zzz
.
What do we do?
The only thing left is to try to catch bad patterns.
Conceptually, this program tells if a given string is not messed up from the perspective of relative URI pattern, as far as our imperfect algorithm sees.
Mainly: no whitespace, no repeated things (tripple slashes or double question marks), no slashes or dots after a hash, two dots must not be followed by a letter and others.
API — isRel()
The main function isRel()
is imported like this:
It’s a function which takes two input arguments:
Input argument | Type | Obligatory | Description |
---|---|---|---|
str Type: String Obligatory: no | |||
str | String | no | The extracted value of HTML media attribute or CSS media query without @media or opening bracket. |
opts Type: Plain object Obligatory: no | |||
opts | Plain object | no | Optional Options Object. |
If passed str
is not a string, an error will be thrown.
The optional options object has the following shape:
Key | Type | Default | Description |
---|---|---|---|
flagUpUrisWithSchemes Type: boolean Default: true | |||
flagUpUrisWithSchemes | boolean | true | Should we yield false on URI’s with scheme (https:// for example)? |
Function returns a plain object:
For example:
{
res: false,
message: `Two consecutive hashes.`
}
or if schema-URI’s are flagged up via opts.flagUpUrisWithSchemes
, the message
value can be null
:
{
res: false,
message: null
}
or
{
res: true,
message: null
}
False res
and null
message happens only on schema-URI’s. By checking is message
set, we find out, were there real errors.
API — defaults
You can import defaults
:
It's a plain object:
The main function calculates the options to be used by merging the options you passed with these defaults.
API — version
You can import version
:
opts.flagUpUrisWithSchemes
When validating the URI’s which can be relative (for example, href
attribute values) one should use two libraries: one to check strict URI’s (those with schema) and one with relative URI’s (those without schema).
For example, is-url-superb
and this package.
If opts.flagUpUrisWithSchemes
is set to true
, this program will search for schemes and yield a falsy result if it detects a known <scheme>:
for example mailto:
.
Another challenge: URI with schema-as-error is not the same “error” — it’s not a “real error”. To distinguish the two we’ll set result object’s key message
to null
.
That is, seemingly correct URI will have a message null
:
import { isRel } from "is-relative-uri";
const str = `https://codsen.com`;
const res = isRel(str, { flagUpUrisWithSchemes: true });
console.log(JSON.stringify(res, null, 4));
// => {
// res: false,
// message: null
// }