@cloudflare/util-routes 1.0.1
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/.prettierrc +5 -0
- package/CHANGELOG.md +8 -0
- package/README.md +32 -0
- package/es/index.js +1 -0
- package/es/route.js +44 -0
- package/lib/index.js +17 -0
- package/lib/route.js +58 -0
- package/package.json +31 -0
- package/src/index.ts +1 -0
- package/src/route.ts +62 -0
package/.prettierrc
ADDED
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Routes utility
|
|
2
|
+
|
|
3
|
+
> Wraps path-to-regexp with a convenient, type-safe tagged template function
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
$ npm install @cloudflare/util-workers
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { $route } from '@cloudflare/util-routes'
|
|
15
|
+
|
|
16
|
+
const apiRoute = $route`/api/v4/accounts/${'accountId'}`
|
|
17
|
+
|
|
18
|
+
// toUrl requires `accountId` to be passed in according to the route pattern
|
|
19
|
+
apiRoute.toUrl()
|
|
20
|
+
// ^^^^^^^ Type Error: { accountId: string } is required
|
|
21
|
+
|
|
22
|
+
apiRoute.toUrl({ accountId: '123' }) // => /api/v4/accounts/123
|
|
23
|
+
|
|
24
|
+
// Routes can be composed
|
|
25
|
+
const domainsRoute = $route`${apiRoute}/domains`
|
|
26
|
+
domainsRoute.toUrl({ accountId: '123' }) // => /api/v4/accounts/123
|
|
27
|
+
|
|
28
|
+
const domainRoute = $route`${domainsRoute}/${'domainName'}`
|
|
29
|
+
// Now accountId and domainName are required
|
|
30
|
+
// => /api/v4/accounts/123/domains/abc.com
|
|
31
|
+
domainRoute.toUrl({ accountId: '123', domainName: 'abc.com' })
|
|
32
|
+
```
|
package/es/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './route';
|
package/es/route.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
2
|
+
|
|
3
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
4
|
+
|
|
5
|
+
import pathToRegExp from 'path-to-regexp';
|
|
6
|
+
export var RoutePatternResult =
|
|
7
|
+
/**
|
|
8
|
+
* Interperolate arguments into the route pattern
|
|
9
|
+
*/
|
|
10
|
+
function RoutePatternResult(pattern) {
|
|
11
|
+
_classCallCheck(this, RoutePatternResult);
|
|
12
|
+
|
|
13
|
+
_defineProperty(this, "pattern", void 0);
|
|
14
|
+
|
|
15
|
+
_defineProperty(this, "toUrl", void 0);
|
|
16
|
+
|
|
17
|
+
this.pattern = pattern;
|
|
18
|
+
this.toUrl = pathToRegExp.compile(this.pattern);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Tag a template string with route data
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export function route(strings) {
|
|
25
|
+
for (var _len = arguments.length, paramNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
26
|
+
paramNames[_key - 1] = arguments[_key];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var pattern = strings.reduce(function (accum, str, i) {
|
|
30
|
+
var result = accum + str;
|
|
31
|
+
var paramName = paramNames[i];
|
|
32
|
+
|
|
33
|
+
if (paramName instanceof RoutePatternResult) {
|
|
34
|
+
result += paramName.pattern;
|
|
35
|
+
} else if (typeof paramName === 'string') {
|
|
36
|
+
result += ':' + paramName;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}, ''); // Without casting to any, we get the following error:
|
|
41
|
+
// > Type instantiation is excessively deep and possibly infinite.
|
|
42
|
+
|
|
43
|
+
return new RoutePatternResult(pattern);
|
|
44
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
var _route = require("./route");
|
|
8
|
+
|
|
9
|
+
Object.keys(_route).forEach(function (key) {
|
|
10
|
+
if (key === "default" || key === "__esModule") return;
|
|
11
|
+
Object.defineProperty(exports, key, {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function get() {
|
|
14
|
+
return _route[key];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
});
|
package/lib/route.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.route = route;
|
|
7
|
+
exports.RoutePatternResult = void 0;
|
|
8
|
+
|
|
9
|
+
var _pathToRegexp = _interopRequireDefault(require("path-to-regexp"));
|
|
10
|
+
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
|
|
13
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
14
|
+
|
|
15
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
16
|
+
|
|
17
|
+
var RoutePatternResult =
|
|
18
|
+
/**
|
|
19
|
+
* Interperolate arguments into the route pattern
|
|
20
|
+
*/
|
|
21
|
+
function RoutePatternResult(pattern) {
|
|
22
|
+
_classCallCheck(this, RoutePatternResult);
|
|
23
|
+
|
|
24
|
+
_defineProperty(this, "pattern", void 0);
|
|
25
|
+
|
|
26
|
+
_defineProperty(this, "toUrl", void 0);
|
|
27
|
+
|
|
28
|
+
this.pattern = pattern;
|
|
29
|
+
this.toUrl = _pathToRegexp.default.compile(this.pattern);
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Tag a template string with route data
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
exports.RoutePatternResult = RoutePatternResult;
|
|
37
|
+
|
|
38
|
+
function route(strings) {
|
|
39
|
+
for (var _len = arguments.length, paramNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
40
|
+
paramNames[_key - 1] = arguments[_key];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var pattern = strings.reduce(function (accum, str, i) {
|
|
44
|
+
var result = accum + str;
|
|
45
|
+
var paramName = paramNames[i];
|
|
46
|
+
|
|
47
|
+
if (paramName instanceof RoutePatternResult) {
|
|
48
|
+
result += paramName.pattern;
|
|
49
|
+
} else if (typeof paramName === 'string') {
|
|
50
|
+
result += ':' + paramName;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return result;
|
|
54
|
+
}, ''); // Without casting to any, we get the following error:
|
|
55
|
+
// > Type instantiation is excessively deep and possibly infinite.
|
|
56
|
+
|
|
57
|
+
return new RoutePatternResult(pattern);
|
|
58
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cloudflare/util-routes",
|
|
3
|
+
"description": "Wraps path-to-regexp with a convenient, type-safe tagged template function",
|
|
4
|
+
"version": "1.0.1",
|
|
5
|
+
"types": "./src",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"module": "es/index.js",
|
|
8
|
+
"jsnext:main": "es/index.js",
|
|
9
|
+
"author": "Frontend Team <frontend@cloudflare.com>",
|
|
10
|
+
"contributors": [
|
|
11
|
+
"John Fawcett <jfawcett@cloudflare.com",
|
|
12
|
+
"Kevin Kipp <kkipp@cloudflare.com"
|
|
13
|
+
],
|
|
14
|
+
"license": "UNLICENSED",
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"registry": "http://registry.npmjs.org/",
|
|
17
|
+
"access": "restricted"
|
|
18
|
+
},
|
|
19
|
+
"stratus": {
|
|
20
|
+
"srcDirectory": "./src",
|
|
21
|
+
"isStandAloneApp": false,
|
|
22
|
+
"autoGeneratedReadme": false
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"path-to-regexp": "^3.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@cloudflare/types": "^1.1.10"
|
|
29
|
+
},
|
|
30
|
+
"gitHead": "56d60ce19198f937970c3440639bca8b79258f58"
|
|
31
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './route'
|
package/src/route.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import pathToRegExp from 'path-to-regexp'
|
|
2
|
+
import { ValueOfArray, Tail, Append, Head } from '@cloudflare/types'
|
|
3
|
+
|
|
4
|
+
export class RoutePatternResult<Param extends string> {
|
|
5
|
+
public readonly pattern: string
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Interperolate arguments into the route pattern
|
|
9
|
+
*/
|
|
10
|
+
readonly toUrl: (
|
|
11
|
+
args: { [K in Param]: string },
|
|
12
|
+
options?: pathToRegExp.PathFunctionOptions,
|
|
13
|
+
) => string
|
|
14
|
+
|
|
15
|
+
constructor(pattern: string) {
|
|
16
|
+
this.pattern = pattern
|
|
17
|
+
this.toUrl = pathToRegExp.compile(this.pattern)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Tag a template string with route data
|
|
23
|
+
*/
|
|
24
|
+
export function route<
|
|
25
|
+
Param extends string,
|
|
26
|
+
ParamOrPatternResult extends Array<Param | RoutePatternResult<string>>
|
|
27
|
+
>(
|
|
28
|
+
strings: TemplateStringsArray,
|
|
29
|
+
...paramNames: ParamOrPatternResult
|
|
30
|
+
): RoutePatternResultFromParams<ParamOrPatternResult> {
|
|
31
|
+
const pattern = strings.reduce((accum, str, i) => {
|
|
32
|
+
let result = accum + str
|
|
33
|
+
const paramName = paramNames[i]
|
|
34
|
+
|
|
35
|
+
if (paramName instanceof RoutePatternResult) {
|
|
36
|
+
result += paramName.pattern
|
|
37
|
+
} else if (typeof paramName === 'string') {
|
|
38
|
+
result += ':' + paramName
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return result
|
|
42
|
+
}, '')
|
|
43
|
+
|
|
44
|
+
// Without casting to any, we get the following error:
|
|
45
|
+
// > Type instantiation is excessively deep and possibly infinite.
|
|
46
|
+
return new RoutePatternResult<Param>(pattern) as any
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type RoutePatternResultFromParams<
|
|
50
|
+
Params extends Array<string | RoutePatternResult<string>>,
|
|
51
|
+
Result extends string[] = []
|
|
52
|
+
> = {
|
|
53
|
+
returnResult: RoutePatternResult<ValueOfArray<Result>>
|
|
54
|
+
recurse: RoutePatternResultFromParams<
|
|
55
|
+
Tail<Params>,
|
|
56
|
+
Append<ExtractParam<Head<Params>>, Result>
|
|
57
|
+
>
|
|
58
|
+
}[Head<Params> extends never ? 'returnResult' : 'recurse']
|
|
59
|
+
|
|
60
|
+
type ExtractParam<
|
|
61
|
+
T extends string | RoutePatternResult<string>
|
|
62
|
+
> = T extends RoutePatternResult<infer S> ? S : T
|