Package Exports
- churi
- churi/compiler
- churi/deserializer
- churi/serializer
Readme
Charged URI
An URI that may contain arbitrary JavaScript values encoded with URI charge micro-format.
It is like JSON for GET requests, but can do even more.
Various URI parts could be charged:
- query parameter values,
- positional argument immediately following
?within query, - Matrix URI parameter values,
- path fragments,
- URI hash (anchor) parameter values,
- positional argument immediately following
#within hash, - username and authentication parameters.
Example:
https://example.com/api(!v3.0)/user;id=0n302875106592253/article;slug=hello-world/comments?date=since(!date'1970-01-01)till(!now)&range=from(10)to(20), where:
/api(!v3.0)is a path fragment charged with!v3.0entity.Entities are URI charge format extensions treated by custom handlers.
/user;id=0n302875106592253is a path fragment charged with user ID specified asusermatrix parameter.Notice the
0nprefix preceding BigInt value (unsupported by JSON)./article;slug=hello-worldis a path fragment with simple string matrix parameter.?date=since(!date'1970-01-01)till(!now)is a query parameter charged with map value.Notice the
!date'1970-01-01and!nowentities.The
dateparameter charge corresponds to JavaScript object literal like:{ since: new Date('1970-01-01'), till: new Date(), }
&range=from(10)to(20)is a query parameter charged with map value corresponding to JavaScript object literal like:{ from: 10, // A number rather a string! to: 20, // A number rather a string! }
Usage
This library represents Charged URIs as ChURI class instances. The latter resembles standard URL class, except it is
read-only. It also provides access to:
- query parameter charges,
- path fragments and their charges,
- matrix parameters and their charges.
Everything is built on demand. Nothing is parsed until requested.
Given the example above:
import { ChURI } from 'churi';
const { route, searchParams: query } = new ChURI(
'https://example.com' +
'/api(!v3.0)' +
'/user;id=0n302875106592253' +
'/article;slug=hello-world' +
'/comments' +
`?date=since(!date'1970-01-01)till(!now)` +
'&range=from(10)to(20)',
);
console.debug(route.path);
// /api(!v3.0)/user;id=0n302875106592253/article;slug=hello-world/comments
console.debug(route.name, route.matrix.arg.get('api').value);
// api !v3.0
console.debug(route.at(1).name, route.at(1).matrix.getCharge('id').value);
// user 302875106592253n
console.debug(route.at(2).name, route.at(2).matrix.getCharge('slug').value);
// article hello-world
console.debug(query.getCharge('date').get('since').value);
// 1970-01-01T00:00:00.000Z
console.debug(query.getCharge('range').get('from').value, query.getCharge('range').get('to').value);
// 10 20Charging
The ChURI class is read-only. It disallows URI manipulations.
To build Charged URI a tagged template can be used.
The following code reconstructs the URI from example above:
import { churi, UcEntity } from 'churi';
console.debug(churi`
https://example.com
/api(${new UcEntity('!v3.0')})
/user;id=${302875106592253n}
/article;slug=${'hello-world'}
/comments
?date=${{
since: new UcEntity("!date'1970-01-01"),
till: new UcEntity('!now'),
}}
&range=${{
from: 10,
to: 20,
}}
`);The UcEntity above used to avoid escaping and percent-encoding and should be used with care.
Instead, a Charged URI string can be built with chargeURI() function.
import { chargeURI, UcEntity } from 'churi';
console.debug(
`https://example.com` +
`/api(${chargeURI(new UcEntity('!v3.0'))})` +
`/user;id=${chargeURI(302875106592253n)}` +
`/article;slug=${chargeURI('hello-world')}` +
`/comments` +
`?date=${chargeURI({
since: new UcEntity("!date'1970-01-01"),
till: new UcEntity('!now'),
})}` +
`&range=${chargeURI({
from: 10,
to: 20,
})}`,
);Charging can be customized by implementing a chargeURI() method of URIChargeable interface. If not implemented,
a toJSON() method will be used. Otherwise, predefined serialization algorithm will be applied similar to JSON one.
URI Charge Processing
URI charge can be parsed from string and represented:
- as
URIChargeinstance byparseURICharge()function, or - as native
JavaScriptvalue byparseUcValue()one.
See API documentation for more info.