Skip to content

Latest commit

History

48 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Parser for Internationalized Resource Identifier

A parser for IRIs.

How this works

Parsing an IRI produces either an IRL or an URN. IRL is a non-standard representation of a URL that this library introduces, as it is very useful. An IRL object:

  • keeps the URL in its original Unicode form (i.e. https://çağlayan.info/user/çağlayan/), without projecting the URL string into ASCII space as the URL specification requires.
  • nevertheless makes the standards-compliant representation of the URL available through its url property (i.e. https://xn--alayan-vua36b.info/user/%C3%A7a%C4%9Flayan/).

This library provides a tagged template parser named iri, which is generally all that is needed to parse an IRI:

import{iri}from'https://esm.sh/gh/doga/IRI@3.1.6/mod.mjs';consthost='localhost',anIri=iri`http://${host}`;// an IRL instance

This library provides other classes and tagged template parsers as well, as shown in the detailed usage example below.

Usage example

Parse IRIs.
description = '''
Shows how to use this library for parsing IRIs.
'''
import{IriParser,IRI,IRL,URN,iri,irl,url,urn}from'https://esm.sh/gh/doga/IRI@3.1.6/mod.mjs';constiris=[iri`https://çağlayan.info/user/çağlayan/?çağlayan#çağlayan`,// IRLIriParser.parse('https://çağlayan.info/user/çağlayan/?çağlayan#çağlayan'),// IRLiri``,// nullirl`https://çağlayan.info/user/çağlayan/`,// IRLirl`https://xn--alayan-vua36b.info/user/%C3%A7a%C4%9Flayan/`,// IRLnewIRL('https://çağlayan.info/user/çağlayan/'),// IRLurl`https://xn--alayan-vua36b.info/user/%C3%A7a%C4%9Flayan/`,// URLIriParser.parse('https://xn--alayan-vua36b.info/user/%C3%A7a%C4%9Flayan/'),// IRLurn`urn:ietf:rfc:2648`,// URNIriParser.parse('urn:ietf:rfc:2648'),// URN];for(constiri1ofiris){if(!iri1)continue;if(iri1instanceofURN){console.group(`URN: ${iri1}`);console.info(` namespace 👉 ${iri1.namespace} namespaceSpecific 👉 ${iri1.namespaceSpecific} resolver 👉 ${iri1.resolver} query 👉 ${iri1.query} fragment 👉 ${iri1.fragment} `);console.groupEnd();}elseif(iri1instanceofURL){console.group(`URL: ${iri1}`);console.info(` URL: origin 👉 ${iri1.origin} hostname 👉 ${iri1.hostname} host 👉 ${iri1.host} pathname 👉 ${iri1.pathname} hash 👉 ${iri1.hash} search 👉 ${iri1.search} `);console.groupEnd();}elseif(iri1instanceofIRL){// URL with Unicode charactersconsole.group(`IRL: ${iri1}`);console.info(` IRL: origin 👉 ${iri1.origin} hostname 👉 ${iri1.hostname} host 👉 ${iri1.host} pathname 👉 ${iri1.pathname} hash 👉 ${iri1.hash} search 👉 ${iri1.search} URL: origin 👉 ${iri1.url.origin} hostname 👉 ${iri1.url.hostname} host 👉 ${iri1.url.host} pathname 👉 ${iri1.url.pathname} hash 👉 ${iri1.url.hash} search 👉 ${iri1.url.search} `);console.groupEnd();}}

Sample output for the code above:

step 1 of 1 // Parse IRIs using tagged templates.
IRL: https://çağlayan.info/user/çağlayan/?çağlayan#çağlayan
IRL:
origin 👉 https://çağlayan.info
hostname 👉 çağlayan.info
host 👉 çağlayan.info
pathname 👉 /user/çağlayan/
hash 👉 #çağlayan
search 👉 ?çağlayan
URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 #%C3%A7a%C4%9Flayan
search 👉 ?%C3%A7a%C4%9Flayan
IRL: https://çağlayan.info/user/çağlayan/?çağlayan#çağlayan
IRL:
origin 👉 https://çağlayan.info
hostname 👉 çağlayan.info
host 👉 çağlayan.info
pathname 👉 /user/çağlayan/
hash 👉 #çağlayan
search 👉 ?çağlayan
URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 #%C3%A7a%C4%9Flayan
search 👉 ?%C3%A7a%C4%9Flayan
IRL: https://çağlayan.info/user/çağlayan/
IRL:
origin 👉 https://çağlayan.info
hostname 👉 çağlayan.info
host 👉 çağlayan.info
pathname 👉 /user/çağlayan/
hash 👉 search 👉 URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 search 👉 IRL: https://çağlayan.info/user/çağlayan/
IRL:
origin 👉 https://çağlayan.info
hostname 👉 çağlayan.info
host 👉 çağlayan.info
pathname 👉 /user/çağlayan/
hash 👉 search 👉 URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 search 👉 IRL: https://çağlayan.info/user/çağlayan/
IRL:
origin 👉 https://çağlayan.info
hostname 👉 çağlayan.info
host 👉 çağlayan.info
pathname 👉 /user/çağlayan/
hash 👉 search 👉 URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 search 👉 URL: https://xn--alayan-vua36b.info/user/%C3%A7a%C4%9Flayan/
URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 search 👉 IRL: https://çağlayan.info/user/çağlayan/
IRL:
origin 👉 https://çağlayan.info
hostname 👉 çağlayan.info
host 👉 çağlayan.info
pathname 👉 /user/çağlayan/
hash 👉 search 👉 URL:
origin 👉 https://xn--alayan-vua36b.info
hostname 👉 xn--alayan-vua36b.info
host 👉 xn--alayan-vua36b.info
pathname 👉 /user/%C3%A7a%C4%9Flayan/
hash 👉 search 👉 URN: urn:ietf:rfc:2648
namespace 👉 ietf
namespaceSpecific 👉 rfc:2648
resolver 👉 undefined
query 👉 undefined
fragment 👉 undefined
URN: urn:ietf:rfc:2648
namespace 👉 ietf
namespaceSpecific 👉 rfc:2648
resolver 👉 undefined
query 👉 undefined
fragment 👉 undefined

Running the usage example

Run the example above by typing this in your terminal (requires Deno 2+):

deno run --allow-net --allow-run --allow-env --allow-read jsr:@andrewbrey/mdrb@3.0.4 --dax=false --mode=isolated 'https://raw.githubusercontent.com/doga/IRI/master/README.md'

Class diagram

---
title: Class diagram
---
classDiagram
class URL {
+string host
+string pathname
...
}
note for IRL "𝘜𝘯𝘪𝘤𝘰𝘥𝘦 𝘳𝘦𝘱𝘳𝘦𝘴𝘦𝘯𝘵𝘢𝘵𝘪𝘰𝘯 𝘰𝘧 𝘢 𝘜𝘙𝘓."
class IRL {
+URL url
+string host
+string pathname
...
}
IRL *-- URL : has property
class URN{
+string namespace
+string namespaceSpecific
...
}
class IriParser {
+parse() IRI$
}
IriParser ..> IRL : depends on
IriParser ..> URN : depends on
class IRI {
+string str
+toString() string
+equals(other) boolean
}
IRI <|-- URN : extends
IRI <|-- IRL : extends
Loading

Besides these classes, this library also provides the tagged template parsers iri, irl, url, and urn.

About

An IRI parser. Parses URLs and URNs.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages