url-templates 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +24 -6
- package/index.js +13 -2
- package/package.json +1 -1
- package/readme.md +46 -4
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Validate a template.
|
|
3
|
-
*
|
|
3
|
+
* @returns true or throws a detailed error.
|
|
4
4
|
*
|
|
5
5
|
* @throws {TypeError | Error}
|
|
6
6
|
*/
|
|
@@ -8,29 +8,47 @@ declare function isUrlTemplate(template: string): boolean;
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Inspect a template.
|
|
11
|
-
*
|
|
11
|
+
* @returns the parsed AST.
|
|
12
12
|
*/
|
|
13
13
|
declare function inspect(template: string): any[];
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Expand the compiled template by given vars.
|
|
17
|
+
* @param vars - the object containing expansion variables.
|
|
18
|
+
* @param callback - optional function that receives the current key and should return a replacement for current value.
|
|
19
|
+
* @returns the expanded template.
|
|
20
|
+
*/
|
|
21
|
+
declare function expand(vars: any, callback?: { key: string }): string
|
|
22
|
+
|
|
15
23
|
/**
|
|
16
24
|
* Parse and validate a template.
|
|
17
|
-
*
|
|
25
|
+
* @returns an object with an expand() method.
|
|
18
26
|
*
|
|
19
27
|
* @throws {TypeError | Error}
|
|
20
28
|
*/
|
|
21
|
-
declare function parseTemplate(template: string): { expand
|
|
29
|
+
declare function parseTemplate(template: string): { expand: typeof expand };
|
|
22
30
|
|
|
23
31
|
/**
|
|
24
32
|
* Compile a template without validation.
|
|
25
|
-
*
|
|
33
|
+
* @returns an object with an expand() method.
|
|
34
|
+
*/
|
|
35
|
+
declare function compile(template: string): { expand: typeof expand };
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Recursively compile a template without validation.
|
|
39
|
+
* @param vars - the object containing expansion variables.
|
|
40
|
+
* @param templateKey - starter template key, must be a vars[key].
|
|
41
|
+
* @param callback - optional function that receives the current key and should return a replacement for current value.
|
|
42
|
+
* @returns the recursively compiled and expanded template.
|
|
26
43
|
*/
|
|
27
|
-
declare function
|
|
44
|
+
declare function recursiveCompile(vars: object, templateKey: string, callback?: { key: string } ): string;
|
|
28
45
|
|
|
29
46
|
declare const urlTemplates: {
|
|
30
47
|
isUrlTemplate: typeof isUrlTemplate;
|
|
31
48
|
inspect: typeof inspect;
|
|
32
49
|
parseTemplate: typeof parseTemplate;
|
|
33
50
|
compile: typeof compile;
|
|
51
|
+
recursiveCompile: typeof recursiveCompile;
|
|
34
52
|
};
|
|
35
53
|
|
|
36
54
|
export = urlTemplates;
|
package/index.js
CHANGED
|
@@ -55,7 +55,7 @@ function isUrlTemplate(template, inspect) {
|
|
|
55
55
|
function parseTemplate(template, validate) {
|
|
56
56
|
if (validate) isUrlTemplate(template);
|
|
57
57
|
return {
|
|
58
|
-
expand: (vars = {}) =>
|
|
58
|
+
expand: (vars = {}, callback) =>
|
|
59
59
|
template.replace(/([^\{\}]+)|\{([^\{\}])([^\{\}]*)\}/g, (match, literal, first, expression) => {
|
|
60
60
|
if (first + expression) {
|
|
61
61
|
const values = [];
|
|
@@ -64,7 +64,7 @@ function parseTemplate(template, validate) {
|
|
|
64
64
|
expression.split(/,/g).forEach((variable) => {
|
|
65
65
|
const match = /(?<key>[^:\*]*)(?::(?<length>\d+)|(?<explode>\*))?/.exec(variable).groups;
|
|
66
66
|
const key = match.key;
|
|
67
|
-
const value = vars[key];
|
|
67
|
+
const value = typeof callback === 'function' ? callback(key) : vars[key];
|
|
68
68
|
if (!isDefined(value)) defined--;
|
|
69
69
|
if (isDefined(value) && value !== '') {
|
|
70
70
|
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
@@ -114,10 +114,21 @@ function parseTemplate(template, validate) {
|
|
|
114
114
|
}),
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
+
// recursive compile
|
|
118
|
+
function recursiveCompile(vars, key, callback) {
|
|
119
|
+
let prev;
|
|
120
|
+
let result = vars[key];
|
|
121
|
+
do {
|
|
122
|
+
prev = result;
|
|
123
|
+
result = decodeURIComponent(parseTemplate(result).expand(vars, callback));
|
|
124
|
+
} while (result !== prev);
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
117
127
|
// export
|
|
118
128
|
module.exports = {
|
|
119
129
|
parseTemplate: (template) => parseTemplate(template, true),
|
|
120
130
|
isUrlTemplate: (template) => isUrlTemplate(template),
|
|
121
131
|
inspect: (template) => isUrlTemplate(template, true),
|
|
122
132
|
compile: (template) => parseTemplate(template),
|
|
133
|
+
recursiveCompile,
|
|
123
134
|
};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -48,7 +48,7 @@ try {
|
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
**Note:**
|
|
51
|
-
Same as with `isUrlTemplate`, but if valid returns the parsed `AST` instead of `true`.
|
|
51
|
+
- Same as with `isUrlTemplate`, but if valid returns the parsed `AST` instead of `true`.
|
|
52
52
|
|
|
53
53
|
### Expansion with validation
|
|
54
54
|
|
|
@@ -62,7 +62,7 @@ try {
|
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
**Note:**
|
|
65
|
-
If valid returns the `expand(vars)` function which returns the expanded `url-template`. Otherwise, it throws an `error`. The `expand` function also throws `error` if `limit` is defined on `objects` (`isUrlTemplate` function cannot know that without runtime vars).
|
|
65
|
+
- If valid returns the `expand(vars)` function which returns the expanded `url-template`. Otherwise, it throws an `error`. The `expand` function also throws `error` if `limit` is defined on `objects` (`isUrlTemplate` function cannot know that without runtime vars).
|
|
66
66
|
|
|
67
67
|
### Expansion without validation
|
|
68
68
|
|
|
@@ -74,7 +74,7 @@ console.log(compile('/undefined{id}').expand({ id: undefined })); // returns '/u
|
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
**Note:**
|
|
77
|
-
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:
|
|
77
|
+
- 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:
|
|
78
78
|
|
|
79
79
|
### Multi pass expansion without validation
|
|
80
80
|
|
|
@@ -101,4 +101,46 @@ console.log(compile(firstPass).expand(vars2)); // returns '[1,2,3]';
|
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
**Important Note:**
|
|
104
|
-
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
|
|
104
|
+
- 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.
|
|
105
|
+
|
|
106
|
+
**Example 3 (transform with callback)**
|
|
107
|
+
|
|
108
|
+
```js title="js"
|
|
109
|
+
const { compile } = require('url-templates');
|
|
110
|
+
const vars1 = { foo: 1 };
|
|
111
|
+
const vars2 = { bar: 2, baz: 3 };
|
|
112
|
+
const firstPass = decodeURIComponent(compile('[{foo},{bar,baz}]').expand(vars1));
|
|
113
|
+
console.log(firstPass); // returns '[1,{bar,baz}]';
|
|
114
|
+
console.log(compile(firstPass).expand(vars2, (key) => key === 'baz' ? vars2[key] * 10 : vars2[key])); // returns '[1,2,30]';
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Note:**
|
|
118
|
+
- The optional `callback` function argument is present on each `expand` function.
|
|
119
|
+
|
|
120
|
+
### Recursively compile and expand without validation
|
|
121
|
+
|
|
122
|
+
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:
|
|
123
|
+
|
|
124
|
+
**Example 1**
|
|
125
|
+
|
|
126
|
+
```js title="js"
|
|
127
|
+
const { recursiveCompile } = require('url-templates');
|
|
128
|
+
const vars = { start: '[{foo},{bar,baz}]', foo: 1, bar: 2, baz: 3 };
|
|
129
|
+
console.log(recursiveCompile(vars, 'start')); // returns '[1,2,3]';
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Example 2**
|
|
133
|
+
|
|
134
|
+
```js title="js"
|
|
135
|
+
const { recursiveCompile } = require('url-templates');
|
|
136
|
+
const vars = { start: '[{foo},{boo}]', boo: '{bar,baz}', foo: 1, bar: 2, baz: 3 };
|
|
137
|
+
console.log(recursiveCompile(vars, 'start')); // returns '[1,2,3]';
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Example 3 (transform with callback)**
|
|
141
|
+
|
|
142
|
+
```js title="js"
|
|
143
|
+
const { recursiveCompile } = require('url-templates');
|
|
144
|
+
const vars = { start: '[{foo},{bar,baz}]', foo: 1, bar: 2, baz: 3 };
|
|
145
|
+
console.log(recursiveCompile(vars, 'start', (key) => vars[key] * 2)); // returns '[2,4,6]';
|
|
146
|
+
```
|