tungsten 0.2.12 → 0.2.13
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/dist/Servers/routing.js +1 -1
- package/dist/routing/Match.type.d.ts +9 -0
- package/dist/routing/Match.type.d.ts.map +1 -1
- package/dist/routing/RouteDataFunction.type.d.ts +3 -1
- package/dist/routing/RouteDataFunction.type.d.ts.map +1 -1
- package/dist/routing/matchPath.d.ts.map +1 -1
- package/dist/routing/matchPath.js +14 -2
- package/dist/routing/matchPath.sxyt.js +23 -0
- package/dist/routing/splitRequest.d.ts +17 -0
- package/dist/routing/splitRequest.d.ts.map +1 -0
- package/dist/routing/splitRequest.js +29 -0
- package/dist/routing/splitRequest.sxyt.d.ts +2 -0
- package/dist/routing/splitRequest.sxyt.d.ts.map +1 -0
- package/dist/routing/splitRequest.sxyt.js +47 -0
- package/package.json +1 -1
package/dist/Servers/routing.js
CHANGED
|
@@ -23,7 +23,7 @@ export async function routing(location, routes, serverDataLoading = null) {
|
|
|
23
23
|
let data = undefined;
|
|
24
24
|
if (route.data) {
|
|
25
25
|
if (serverDataLoading) serverDataLoading.value = true;
|
|
26
|
-
data = await route.data(params, location);
|
|
26
|
+
data = await route.data(params, location, match.query);
|
|
27
27
|
if (serverDataLoading) serverDataLoading.value = false;
|
|
28
28
|
}
|
|
29
29
|
//console.log('route data is', data)
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
export type Match = {
|
|
2
2
|
pattern: string;
|
|
3
|
+
/** The full request string as received, including any query string and hash. */
|
|
3
4
|
request: string;
|
|
5
|
+
/** The path portion of the request only (query string and hash removed). */
|
|
6
|
+
pathname: string;
|
|
4
7
|
params: {
|
|
5
8
|
[key: string]: string;
|
|
6
9
|
};
|
|
10
|
+
/** Parsed query string parameters (empty object when there is no query string). */
|
|
11
|
+
query: {
|
|
12
|
+
[key: string]: string;
|
|
13
|
+
};
|
|
14
|
+
/** The hash fragment without the leading '#' (empty string when there is none). */
|
|
15
|
+
hash: string;
|
|
7
16
|
};
|
|
8
17
|
//# sourceMappingURL=Match.type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Match.type.d.ts","sourceRoot":"","sources":["../../src/routing/Match.type.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,KAAK,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"Match.type.d.ts","sourceRoot":"","sources":["../../src/routing/Match.type.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,KAAK,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACjC,mFAAmF;IACnF,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAChC,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAA;CACf,CAAA"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { RoutingRedirect } from './RoutingRedirect.js';
|
|
2
2
|
import { WebRedirect } from './WebRedirect.js';
|
|
3
|
-
export type RouteDataFunction<Params extends object, DataType> = (params: Params, location: string
|
|
3
|
+
export type RouteDataFunction<Params extends object, DataType> = (params: Params, location: string, query: {
|
|
4
|
+
[key: string]: string;
|
|
5
|
+
}) => Promise<DataType | RoutingRedirect | WebRedirect>;
|
|
4
6
|
//# sourceMappingURL=RouteDataFunction.type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteDataFunction.type.d.ts","sourceRoot":"","sources":["../../src/routing/RouteDataFunction.type.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,MAAM,iBAAiB,CAAC,MAAM,SAAS,MAAM,EAAE,QAAQ,IACvD,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,eAAe,GAAG,WAAW,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"RouteDataFunction.type.d.ts","sourceRoot":"","sources":["../../src/routing/RouteDataFunction.type.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,MAAM,iBAAiB,CAAC,MAAM,SAAS,MAAM,EAAE,QAAQ,IACvD,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,KAC9D,OAAO,CAAC,QAAQ,GAAG,eAAe,GAAG,WAAW,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchPath.d.ts","sourceRoot":"","sources":["../../src/routing/matchPath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"matchPath.d.ts","sourceRoot":"","sources":["../../src/routing/matchPath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAM5C,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAqE9E"}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { compareRequestToRegex } from "./compareRequestToRegex.js";
|
|
2
2
|
import { patternToRegex } from "./patternToRegex.js";
|
|
3
|
+
import { splitRequest } from "./splitRequest.js";
|
|
3
4
|
export function matchPath(pattern, request) {
|
|
4
5
|
// pathToRegexp(path, keys?, options?)
|
|
5
6
|
// match(path)
|
|
6
7
|
// parse(path)
|
|
7
8
|
// compile(path)
|
|
9
|
+
// Match only the path portion of the request, like Express: strip the query
|
|
10
|
+
// string and hash fragment before testing against the anchored (^…$) regex.
|
|
11
|
+
// Otherwise a request like '/foo?bar=1' would never match the pattern '/foo'.
|
|
12
|
+
const {
|
|
13
|
+
pathname,
|
|
14
|
+
query,
|
|
15
|
+
hash
|
|
16
|
+
} = splitRequest(request);
|
|
8
17
|
const {
|
|
9
18
|
regex,
|
|
10
19
|
keys
|
|
@@ -14,13 +23,16 @@ export function matchPath(pattern, request) {
|
|
|
14
23
|
const {
|
|
15
24
|
success,
|
|
16
25
|
params
|
|
17
|
-
} = compareRequestToRegex(
|
|
26
|
+
} = compareRequestToRegex(pathname, regex, keys);
|
|
18
27
|
//console.log('regex', regex, 'keys', keys, 'success', success)
|
|
19
28
|
if (success) {
|
|
20
29
|
return {
|
|
21
30
|
pattern,
|
|
22
31
|
request,
|
|
23
|
-
|
|
32
|
+
pathname,
|
|
33
|
+
params,
|
|
34
|
+
query,
|
|
35
|
+
hash
|
|
24
36
|
};
|
|
25
37
|
}
|
|
26
38
|
return null;
|
|
@@ -15,4 +15,27 @@ describe('routing/matchPath()', ({
|
|
|
15
15
|
const match = matchPath('/foo/', '/foo');
|
|
16
16
|
expect(match).not.to.equal(null);
|
|
17
17
|
});
|
|
18
|
+
it(`matches /foo when the request has a query string`, () => {
|
|
19
|
+
const match = matchPath('/foo', '/foo?bar=1');
|
|
20
|
+
expect(match).not.to.equal(null);
|
|
21
|
+
expect(match.query).to.deep.equal({
|
|
22
|
+
bar: '1'
|
|
23
|
+
});
|
|
24
|
+
expect(match.pathname).to.equal('/foo');
|
|
25
|
+
});
|
|
26
|
+
it(`matches /foo when the request has a hash fragment`, () => {
|
|
27
|
+
const match = matchPath('/foo', '/foo#section');
|
|
28
|
+
expect(match).not.to.equal(null);
|
|
29
|
+
expect(match.hash).to.equal('section');
|
|
30
|
+
});
|
|
31
|
+
it(`matches a dynamic route with a query string and captures the param`, () => {
|
|
32
|
+
const match = matchPath('/leads/:id/details', '/leads/5/details?queue=1');
|
|
33
|
+
expect(match).not.to.equal(null);
|
|
34
|
+
expect(match.params).to.deep.equal({
|
|
35
|
+
id: '5'
|
|
36
|
+
});
|
|
37
|
+
expect(match.query).to.deep.equal({
|
|
38
|
+
queue: '1'
|
|
39
|
+
});
|
|
40
|
+
});
|
|
18
41
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SplitRequest = {
|
|
2
|
+
pathname: string;
|
|
3
|
+
query: {
|
|
4
|
+
[key: string]: string;
|
|
5
|
+
};
|
|
6
|
+
hash: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Split an incoming request string into its path, query, and hash parts, the
|
|
10
|
+
* way a URL is structured: `/path?query#hash`. Only `pathname` should be used
|
|
11
|
+
* for route matching (query and hash are not part of the path).
|
|
12
|
+
*
|
|
13
|
+
* The hash is separated first because a URL's fragment can itself contain a
|
|
14
|
+
* '?' that is not a query delimiter (e.g. '/foo#a?b').
|
|
15
|
+
*/
|
|
16
|
+
export declare function splitRequest(request: string): SplitRequest;
|
|
17
|
+
//# sourceMappingURL=splitRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"splitRequest.d.ts","sourceRoot":"","sources":["../../src/routing/splitRequest.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAwB1D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split an incoming request string into its path, query, and hash parts, the
|
|
3
|
+
* way a URL is structured: `/path?query#hash`. Only `pathname` should be used
|
|
4
|
+
* for route matching (query and hash are not part of the path).
|
|
5
|
+
*
|
|
6
|
+
* The hash is separated first because a URL's fragment can itself contain a
|
|
7
|
+
* '?' that is not a query delimiter (e.g. '/foo#a?b').
|
|
8
|
+
*/
|
|
9
|
+
export function splitRequest(request) {
|
|
10
|
+
let rest = request;
|
|
11
|
+
let hash = '';
|
|
12
|
+
let query = {};
|
|
13
|
+
const hashIndex = rest.indexOf('#');
|
|
14
|
+
if (hashIndex !== -1) {
|
|
15
|
+
hash = rest.slice(hashIndex + 1);
|
|
16
|
+
rest = rest.slice(0, hashIndex);
|
|
17
|
+
}
|
|
18
|
+
const queryIndex = rest.indexOf('?');
|
|
19
|
+
if (queryIndex !== -1) {
|
|
20
|
+
const search = rest.slice(queryIndex + 1);
|
|
21
|
+
rest = rest.slice(0, queryIndex);
|
|
22
|
+
query = Object.fromEntries(new URLSearchParams(search));
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
pathname: rest,
|
|
26
|
+
query,
|
|
27
|
+
hash
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"splitRequest.sxyt.d.ts","sourceRoot":"","sources":["../../src/routing/splitRequest.sxyt.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe } from 'sxy-test-runner';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
import { splitRequest } from "./splitRequest.js";
|
|
4
|
+
describe('routing/splitRequest()', ({
|
|
5
|
+
it
|
|
6
|
+
}) => {
|
|
7
|
+
it(`returns the path unchanged when there is no query or hash`, () => {
|
|
8
|
+
expect(splitRequest('/foo/bar')).to.deep.equal({
|
|
9
|
+
pathname: '/foo/bar',
|
|
10
|
+
query: {},
|
|
11
|
+
hash: ''
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
it(`splits off a query string and parses it`, () => {
|
|
15
|
+
expect(splitRequest('/foo?a=1&b=2')).to.deep.equal({
|
|
16
|
+
pathname: '/foo',
|
|
17
|
+
query: {
|
|
18
|
+
a: '1',
|
|
19
|
+
b: '2'
|
|
20
|
+
},
|
|
21
|
+
hash: ''
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
it(`splits off a hash fragment`, () => {
|
|
25
|
+
expect(splitRequest('/foo#section')).to.deep.equal({
|
|
26
|
+
pathname: '/foo',
|
|
27
|
+
query: {},
|
|
28
|
+
hash: 'section'
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it(`splits off both query and hash`, () => {
|
|
32
|
+
expect(splitRequest('/foo?a=1#section')).to.deep.equal({
|
|
33
|
+
pathname: '/foo',
|
|
34
|
+
query: {
|
|
35
|
+
a: '1'
|
|
36
|
+
},
|
|
37
|
+
hash: 'section'
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
it(`does not treat a '?' inside the hash as a query delimiter`, () => {
|
|
41
|
+
expect(splitRequest('/foo#a?b')).to.deep.equal({
|
|
42
|
+
pathname: '/foo',
|
|
43
|
+
query: {},
|
|
44
|
+
hash: 'a?b'
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|