url-templates
v1.0.4
Published
A url-template validator, expander and inspector as defined by RFC 6570
Downloads
737
Maintainers
Readme
title: URL Templates
description: A URL Template validator, expander and inspector
Overview
A URL Template validator, expander and inspector — fully RFC 6570 compliant. Passes all the 252 tests from the uritemplate-test suite. Minimal, zero dependency, sync API; exposes AST for linters/interfaces and both validated and non-validated expansion paths.
Install
npm i url-templatesUsage
This library provides the following url-template functions:
Validation
const { isUrlTemplate } = require('url-templates');
try {
console.log('valid:', isUrlTemplate('/users/{id}')); // true
} catch (error) {
console.error('invalid:', error.message);
}Note:
It returns true or throws an error.
Inspection
const { inspect } = require('url-templates');
try {
console.dir(inspect('/search{?q*,lang:2}'), { depth: null });
// [ '/search', { '?': [ { key: 'q', explode: true }, { key: 'lang', limit: 2 } ] } ]
} catch (error) {
console.error('invalid:', error.message);
}Note:
- Same as with
isUrlTemplate, but if valid returns the parsedASTinstead oftrue.
Expansion with validation
const { parseTemplate } = require('url-templates');
try {
console.log(parseTemplate('/items/{id}').expand({ id: 42 })); // '/items/42'
} catch (error) {
console.error('parse/validation error:', error.message);
}Note:
- If valid returns the
expand(vars)function which returns the expandedurl-template. Otherwise, it throws anerror. Theexpandfunction also throwserroriflimitis defined onobjects(isUrlTemplatefunction cannot know that without runtime vars).
Expansion without validation
const { compile } = require('url-templates');
console.log(compile('/broken{').expand({})); // returns '/broken{'; invalid parts left for postprocessing
console.log(compile('/good{id}').expand({ id: 42 })); // returns '/good42';
console.log(compile('/undefined{id}').expand({ id: undefined })); // returns '/undefined{id}';Note:
- Returns a usable expander without validation for cases where validation is done elsewhere, or for the cases where some sort of postprocessing will follow. A good example of postprocessing is described next:
Multi pass expansion without validation
Example 1
const { compile } = require('url-templates');
const vars1 = { anotherPattern: '{foo}', andAnotherPattern: '{bar,baz}' };
const vars2 = { foo: 1, bar: 2, baz: 3 };
const firstPass = decodeURIComponent(compile('[{anotherPattern},{andAnotherPattern}]').expand(vars1));
console.log(firstPass); // returns '[{foo},{bar,baz}]';
console.log(compile(firstPass).expand(vars2)); // returns '[1,2,3]';Example 2
const { compile } = require('url-templates');
const vars1 = { foo: 1 };
const vars2 = { bar: 2, baz: 3 };
const firstPass = decodeURIComponent(compile('[{foo},{bar,baz}]').expand(vars1));
console.log(firstPass); // returns '[1,{bar,baz}]';
console.log(compile(firstPass).expand(vars2)); // returns '[1,2,3]';Important Note:
- The first pass will preserve the
{bar,baz}expression only if the supplied variable has none of its members. This method can also be used to preserve quantifiers like{1,4}in regular expressions.
Example 3 (transform with callback)
const { compile } = require('url-templates');
const vars1 = { foo: 1 };
const vars2 = { bar: 2, baz: 3 };
const firstPass = decodeURIComponent(compile('[{foo},{bar,baz}]').expand(vars1));
console.log(firstPass); // returns '[1,{bar,baz}]';
console.log(compile(firstPass).expand(vars2, (key) => key === 'baz' ? vars2[key] * 10 : vars2[key])); // returns '[1,2,30]';Note:
- The optional
callbackfunction argument is present on eachexpandfunction.
Recursively compile and expand without validation
If all the required template members are present in a single object, then the above multi-pass compilation and expansion can be done recursively as follows:
Example 1
const { recursiveCompile } = require('url-templates');
const vars = { start: '[{foo},{bar,baz}]', foo: 1, bar: 2, baz: 3 };
console.log(recursiveCompile(vars, 'start')); // returns '[1,2,3]';Example 2
const { recursiveCompile } = require('url-templates');
const vars = { start: '[{foo},{boo}]', boo: '{bar,baz}', foo: 1, bar: 2, baz: 3 };
console.log(recursiveCompile(vars, 'start')); // returns '[1,2,3]';Example 3 (transform with callback)
const { recursiveCompile } = require('url-templates');
const vars = { start: '[{foo},{bar,baz}]', foo: 1, bar: 2, baz: 3 };
console.log(recursiveCompile(vars, 'start', (key) => vars[key] * 2)); // returns '[2,4,6]';