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 |
|---|---|---|---|
strType: String Obligatory: no | |||
str | String | no | The extracted value of HTML media attribute or CSS media query without @media or opening bracket. |
optsType: 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 |
|---|---|---|---|
flagUpUrisWithSchemesType: 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
// }