JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 5
  • Score
    100M100P100Q28473F
  • License MIT

Charged URI

Package Exports

  • churi
  • churi/compiler
  • churi/deserializer
  • churi/serializer

Readme

Charged URI

NPM Build Status Code Quality Coverage GitHub Project API Documentation

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.0 entity.

    Entities are URI charge format extensions treated by custom handlers.

  • /user;id=0n302875106592253 is a path fragment charged with user ID specified as user matrix parameter.

    Notice the 0n prefix preceding BigInt value (unsupported by JSON).

  • /article;slug=hello-world is 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-01 and !now entities.

    The date parameter 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!
    }

Read more about URI charge format >>>

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 20

Charging

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 URICharge instance by parseURICharge() function, or
  • as native JavaScript value by parseUcValue() one.

See API documentation for more info.