@uxf/router 11.72.5 → 11.80.2
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/README.md +69 -1
- package/package.json +1 -1
- package/{index.d.ts → router/index.d.ts} +1 -0
- package/{index.js → router/index.js} +1 -0
- package/router/merge-route-matchers.d.ts +2 -0
- package/router/merge-route-matchers.js +6 -0
- package/{router.d.ts → router/router.d.ts} +23 -3
- package/{router.js → router/router.js} +32 -2
- package/{router.test.js → router/router.test.js} +48 -1
- package/router/routes-check/__test__/app/app-directory/[param]/page.d.ts +0 -0
- package/router/routes-check/__test__/app/app-directory/[param]/page.js +1 -0
- package/router/routes-check/__test__/app/app-directory/page.d.ts +0 -0
- package/router/routes-check/__test__/app/app-directory/page.js +1 -0
- package/router/routes-check/__test__/pages/index.d.ts +0 -0
- package/router/routes-check/__test__/pages/index.js +1 -0
- package/router/routes-check/__test__/pages/product/[id].d.ts +0 -0
- package/router/routes-check/__test__/pages/product/[id].js +1 -0
- package/router/routes-check/__test__/pages/product/edit.d.ts +0 -0
- package/router/routes-check/__test__/pages/product/edit.js +1 -0
- package/router/routes-check/__test__/pages/product/index.d.ts +0 -0
- package/router/routes-check/__test__/pages/product/index.js +1 -0
- package/router/routes-check/__test__/pages/product-2/[id]/index.d.ts +0 -0
- package/router/routes-check/__test__/pages/product-2/[id]/index.js +1 -0
- /package/{helper.d.ts → router/helper.d.ts} +0 -0
- /package/{helper.js → router/helper.js} +0 -0
- /package/{helper.test.d.ts → router/helper.test.d.ts} +0 -0
- /package/{helper.test.js → router/helper.test.js} +0 -0
- /package/{router.test.d.ts → router/router.test.d.ts} +0 -0
- /package/{routes-check → router/routes-check}/routes-check.d.ts +0 -0
- /package/{routes-check → router/routes-check}/routes-check.js +0 -0
- /package/{routes-check → router/routes-check}/routes-check.test.d.ts +0 -0
- /package/{routes-check → router/routes-check}/routes-check.test.js +0 -0
- /package/{sitemap-generator.d.ts → router/sitemap-generator.d.ts} +0 -0
- /package/{sitemap-generator.js → router/sitemap-generator.js} +0 -0
- /package/{sitemap-generator.test.d.ts → router/sitemap-generator.test.d.ts} +0 -0
- /package/{sitemap-generator.test.js → router/sitemap-generator.test.js} +0 -0
- /package/{superstruct → router/superstruct}/array.d.ts +0 -0
- /package/{superstruct → router/superstruct}/array.js +0 -0
- /package/{superstruct → router/superstruct}/boolean.d.ts +0 -0
- /package/{superstruct → router/superstruct}/boolean.js +0 -0
- /package/{superstruct → router/superstruct}/index.d.ts +0 -0
- /package/{superstruct → router/superstruct}/index.js +0 -0
- /package/{superstruct → router/superstruct}/integer.d.ts +0 -0
- /package/{superstruct → router/superstruct}/integer.js +0 -0
- /package/{types.d.ts → router/types.d.ts} +0 -0
- /package/{types.js → router/types.js} +0 -0
- /package/{utils → router/utils}/object-to-xml.d.ts +0 -0
- /package/{utils → router/utils}/object-to-xml.js +0 -0
- /package/{utils → router/utils}/object-to-xml.test.d.ts +0 -0
- /package/{utils → router/utils}/object-to-xml.test.js +0 -0
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ export default createRouter(
|
|
|
52
52
|
// routes/index.ts
|
|
53
53
|
|
|
54
54
|
import router from "./routes";
|
|
55
|
-
import { UxfGetServerSideProps, UxfGetStaticProps } from "@uxf/router";
|
|
55
|
+
import { UxfGetServerSideProps, UxfGetStaticProps, ExtractSchema } from "@uxf/router";
|
|
56
56
|
import { PreviewData as NextPreviewData } from "next/types";
|
|
57
57
|
|
|
58
58
|
export const {
|
|
@@ -62,6 +62,8 @@ export const {
|
|
|
62
62
|
useQueryParamsStatic
|
|
63
63
|
} = router;
|
|
64
64
|
|
|
65
|
+
export type GetRouteSchema<K extends keyof RouteList> = ExtractSchema<RouteList[K]>;
|
|
66
|
+
|
|
65
67
|
export type GetStaticProps<
|
|
66
68
|
Route extends keyof RouteList,
|
|
67
69
|
Props extends { [key: string]: any } = { [key: string]: any },
|
|
@@ -119,6 +121,72 @@ export default () => (
|
|
|
119
121
|
)
|
|
120
122
|
```
|
|
121
123
|
|
|
124
|
+
## RouteMatcher
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { createRouteMatcher } from "@app-routes";
|
|
128
|
+
|
|
129
|
+
// create active resolver
|
|
130
|
+
const routeMatcher = createRouteMatcher("admin/index", { param1: 123 });
|
|
131
|
+
// or
|
|
132
|
+
const routeMatcher = createRouteMatcher("admin/index");
|
|
133
|
+
|
|
134
|
+
// how to use in component
|
|
135
|
+
|
|
136
|
+
function MyComponent() {
|
|
137
|
+
const router = useRouter();
|
|
138
|
+
const isRouteActive = routeMatcher(router);
|
|
139
|
+
|
|
140
|
+
return <div>{isRouteActive ? "active" : "not active"}</div>;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Custom route matchers
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
function createPathnameRouteMatcher(path: string): RouteMatcher {
|
|
148
|
+
return (router) => {
|
|
149
|
+
return router.pathname.startsWith(path);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { getCurrentRoute } from "@app-routes";
|
|
156
|
+
|
|
157
|
+
function createCustomRouteMatcher(): RouteMatcher {
|
|
158
|
+
return (router) => {
|
|
159
|
+
const { route, params } = getCurrentRoute(router);
|
|
160
|
+
if (route === "admin/index") {
|
|
161
|
+
// do something
|
|
162
|
+
} else if (route === "admin/form") {
|
|
163
|
+
// do something
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Merge multiple route matchers
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { mergeRouteMatchers } from "@uxf/router";
|
|
173
|
+
|
|
174
|
+
const routeMatcher = mergeRouteMatchers([
|
|
175
|
+
createRouteMatcher("admin/index"),
|
|
176
|
+
createRouteMatcher("admin/form"),
|
|
177
|
+
]);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Type-safe route params
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { GetRouteSchema } from "@app-routes";
|
|
184
|
+
|
|
185
|
+
const blogProps: GetRouteSchema<"blog/detail"> = {
|
|
186
|
+
id: 1,
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
122
190
|
## GetStaticProps
|
|
123
191
|
|
|
124
192
|
```tsx
|
package/package.json
CHANGED
|
@@ -15,5 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./helper"), exports);
|
|
18
|
+
__exportStar(require("./merge-route-matchers"), exports);
|
|
18
19
|
__exportStar(require("./router"), exports);
|
|
19
20
|
__exportStar(require("./types"), exports);
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { LinkProps } from "next/link";
|
|
2
|
+
import { NextRouter } from "next/router";
|
|
2
3
|
import { Infer, Struct } from "superstruct";
|
|
3
4
|
import { SitemapGeneratorOptions, SitemapGeneratorType, SitemapRouteResolvers } from "./sitemap-generator";
|
|
4
5
|
import { QueryParams, RoutesDefinition } from "./types";
|
|
5
|
-
|
|
6
|
+
interface TransitionOptions {
|
|
7
|
+
shallow?: boolean;
|
|
8
|
+
locale?: string | false;
|
|
9
|
+
scroll?: boolean;
|
|
10
|
+
unstable_skipClientCache?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type ExtractSchema<T> = T extends {
|
|
6
13
|
schema: Struct<infer U, any>;
|
|
7
14
|
} ? U : null;
|
|
8
15
|
type Options = {
|
|
@@ -14,20 +21,32 @@ type LocaleOptions<Locales extends string[]> = {
|
|
|
14
21
|
export type FunctionParametersGenerator<Locales extends string[], RouteList extends RoutesDefinition<Locales>> = {
|
|
15
22
|
[K in keyof RouteList]: RouteList[K]["path"] extends string ? "schema" extends keyof RouteList[K] ? [K, ExtractSchema<RouteList[K]>, Options?] : [K, null?, Options?] : "schema" extends keyof RouteList[K] ? [K, ExtractSchema<RouteList[K]>, Options & LocaleOptions<Locales>] : [K, null, Options & LocaleOptions<Locales>];
|
|
16
23
|
}[keyof RouteList];
|
|
24
|
+
export type FunctionParametersGeneratorWithPartialParams<Locales extends string[], RouteList extends RoutesDefinition<Locales>> = {
|
|
25
|
+
[K in keyof RouteList]: "schema" extends keyof RouteList[K] ? [K, Partial<ExtractSchema<RouteList[K]>>?] : [K, null?];
|
|
26
|
+
}[keyof RouteList];
|
|
17
27
|
type RouteFunction<Locales extends string[], RouteList extends RoutesDefinition<Locales>> = (...args: FunctionParametersGenerator<Locales, RouteList>) => LinkProps["href"];
|
|
18
28
|
type RouteToUrlFunction<Locales extends string[], RouteList extends RoutesDefinition<Locales>> = (...args: FunctionParametersGenerator<Locales, RouteList>) => string;
|
|
19
29
|
type QueryParamsResult<Nullable extends boolean, T extends keyof RouteList, Locales extends string[], RouteList extends RoutesDefinition<Locales>> = [
|
|
20
30
|
Nullable extends true ? Infer<NonNullable<RouteList[T]["schema"]>> | null : Infer<NonNullable<RouteList[T]["schema"]>>,
|
|
21
31
|
{
|
|
22
|
-
push: (params: Infer<NonNullable<RouteList[T]["schema"]
|
|
23
|
-
replace: (params: Infer<NonNullable<RouteList[T]["schema"]
|
|
32
|
+
push: (params: Infer<NonNullable<RouteList[T]["schema"]>>, options?: TransitionOptions) => Promise<boolean>;
|
|
33
|
+
replace: (params: Infer<NonNullable<RouteList[T]["schema"]>>, options?: TransitionOptions) => Promise<boolean>;
|
|
24
34
|
}
|
|
25
35
|
];
|
|
36
|
+
type SimplyNextRouter = Pick<NextRouter, "pathname" | "query" | "isReady">;
|
|
37
|
+
export type RouteMatcher = (router: SimplyNextRouter) => boolean;
|
|
38
|
+
type CurrentRoute<RouteList extends RoutesDefinition<any>> = {
|
|
39
|
+
[K in keyof RouteList]: {
|
|
40
|
+
route: K;
|
|
41
|
+
params: "schema" extends keyof RouteList[K] ? ExtractSchema<RouteList[K]> | null : null;
|
|
42
|
+
};
|
|
43
|
+
}[keyof RouteList];
|
|
26
44
|
type Router<Locales extends string[], RouteList extends RoutesDefinition<Locales>> = {
|
|
27
45
|
route: RouteFunction<Locales, RouteList>;
|
|
28
46
|
routeToUrl: RouteToUrlFunction<Locales, RouteList>;
|
|
29
47
|
createSitemapGenerator: (resolvers: SitemapRouteResolvers<Locales, RouteList>, options?: SitemapGeneratorOptions) => SitemapGeneratorType;
|
|
30
48
|
routes: RouteList;
|
|
49
|
+
getCurrentRoute: (router: SimplyNextRouter) => CurrentRoute<RouteList>;
|
|
31
50
|
useActiveRoute: () => ActiveRoute<Locales, RouteList>;
|
|
32
51
|
/**
|
|
33
52
|
* @deprecated use useQueryParamsStatic or useQueryParams instead
|
|
@@ -35,6 +54,7 @@ type Router<Locales extends string[], RouteList extends RoutesDefinition<Locales
|
|
|
35
54
|
useQueryParamsDeprecated: <T extends keyof RouteList>() => QueryParams<RouteList, T>;
|
|
36
55
|
useQueryParams: <T extends keyof RouteList>(routeName: T) => QueryParamsResult<false, T, Locales, RouteList>;
|
|
37
56
|
useQueryParamsStatic: <T extends keyof RouteList>(routeName: T) => QueryParamsResult<true, T, Locales, RouteList>;
|
|
57
|
+
createRouteMatcher: (...args: FunctionParametersGeneratorWithPartialParams<Locales, RouteList>) => RouteMatcher;
|
|
38
58
|
};
|
|
39
59
|
type RouterOptions<L extends string[]> = {
|
|
40
60
|
baseUrl?: string;
|
|
@@ -71,6 +71,17 @@ function createRouter(routes, routerOptions) {
|
|
|
71
71
|
}
|
|
72
72
|
return (options === null || options === void 0 ? void 0 : options.shouldBeAbsolute) ? `${routerOptions.baseUrl}${pathname}` : pathname;
|
|
73
73
|
};
|
|
74
|
+
const getCurrentRoute = (router) => {
|
|
75
|
+
const activeRoute = Object.keys(routes).find((route) => typeof routes[route].path === "string"
|
|
76
|
+
? routes[route].path === router.pathname
|
|
77
|
+
: Object.values(routes[route].path).includes(router.pathname));
|
|
78
|
+
if (!activeRoute) {
|
|
79
|
+
throw new Error("Active route not found.");
|
|
80
|
+
}
|
|
81
|
+
const schema = routes[activeRoute].schema;
|
|
82
|
+
const params = router.isReady && schema ? (0, superstruct_1.mask)(router.query, schema) : null;
|
|
83
|
+
return { route: activeRoute, params };
|
|
84
|
+
};
|
|
74
85
|
return {
|
|
75
86
|
route(...args) {
|
|
76
87
|
var _a;
|
|
@@ -115,8 +126,8 @@ function createRouter(routes, routerOptions) {
|
|
|
115
126
|
return [
|
|
116
127
|
(0, superstruct_1.mask)(router.query, schema),
|
|
117
128
|
{
|
|
118
|
-
push: (params) => router.push(routeToUrl(routeName, params, {})),
|
|
119
|
-
replace: (params) => router.replace(routeToUrl(routeName, params, {})),
|
|
129
|
+
push: (params, options) => router.push(routeToUrl(routeName, params, {}), undefined, options),
|
|
130
|
+
replace: (params, options) => router.replace(routeToUrl(routeName, params, {}), undefined, options),
|
|
120
131
|
},
|
|
121
132
|
];
|
|
122
133
|
},
|
|
@@ -134,5 +145,24 @@ function createRouter(routes, routerOptions) {
|
|
|
134
145
|
},
|
|
135
146
|
];
|
|
136
147
|
},
|
|
148
|
+
getCurrentRoute,
|
|
149
|
+
createRouteMatcher(...args) {
|
|
150
|
+
const [requiredRouteName, requiredParams] = args;
|
|
151
|
+
return (router) => {
|
|
152
|
+
const { route, params } = getCurrentRoute(router);
|
|
153
|
+
if (route !== requiredRouteName) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (!requiredParams || Object.keys(requiredParams).length === 0) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
for (const [paramName, paramValue] of Object.entries(requiredParams)) {
|
|
160
|
+
if ((params === null || params === void 0 ? void 0 : params[paramName]) !== paramValue) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
};
|
|
166
|
+
},
|
|
137
167
|
};
|
|
138
168
|
}
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const superstruct_1 = require("superstruct");
|
|
4
|
+
const merge_route_matchers_1 = require("./merge-route-matchers");
|
|
4
5
|
const router_1 = require("./router");
|
|
5
6
|
const superstruct_2 = require("./superstruct");
|
|
6
|
-
const { routeToUrl } = (0, router_1.createRouter)({
|
|
7
|
+
const { routeToUrl, createRouteMatcher } = (0, router_1.createRouter)({
|
|
7
8
|
index: {
|
|
8
9
|
path: "/",
|
|
9
10
|
schema: (0, superstruct_1.object)({
|
|
10
11
|
queryParam: (0, superstruct_1.optional)((0, superstruct_1.string)()),
|
|
11
12
|
}),
|
|
12
13
|
},
|
|
14
|
+
manyParameters: {
|
|
15
|
+
path: "/many-parameters/[param1]/form/[param2]",
|
|
16
|
+
schema: (0, superstruct_1.object)({
|
|
17
|
+
param1: (0, superstruct_1.string)(),
|
|
18
|
+
param2: (0, superstruct_1.string)(),
|
|
19
|
+
queryParam1: (0, superstruct_1.optional)((0, superstruct_1.string)()),
|
|
20
|
+
queryParam2: (0, superstruct_1.optional)((0, superstruct_1.string)()),
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
13
23
|
catchAllSegments: {
|
|
14
24
|
path: "/catch-all/[...pathParams]",
|
|
15
25
|
schema: (0, superstruct_1.object)({
|
|
@@ -127,3 +137,40 @@ const DATA = [
|
|
|
127
137
|
test("routeToUrl", () => {
|
|
128
138
|
DATA.map(({ actual, expected }) => expect(actual).toBe(expected));
|
|
129
139
|
});
|
|
140
|
+
test("create route matcher", () => {
|
|
141
|
+
expect(createRouteMatcher("manyParameters", { param1: "value-1" })({
|
|
142
|
+
isReady: true,
|
|
143
|
+
pathname: "/many-parameters/[param1]/form/[param2]",
|
|
144
|
+
query: { param1: "value-1", param2: "any", queryParam1: "any", queryParam2: "any" },
|
|
145
|
+
})).toBe(true);
|
|
146
|
+
expect(createRouteMatcher("manyParameters", { param1: "value-1" })({
|
|
147
|
+
isReady: true,
|
|
148
|
+
pathname: "/many-parameters/[param1]/form/[param2]",
|
|
149
|
+
query: { param1: "any", param2: "any" },
|
|
150
|
+
})).toBe(false);
|
|
151
|
+
expect(createRouteMatcher("manyParameters", { param1: "value-1", queryParam1: "query-1" })({
|
|
152
|
+
isReady: true,
|
|
153
|
+
pathname: "/many-parameters/[param1]/form/[param2]",
|
|
154
|
+
query: { param1: "value-1", param2: "any", queryParam1: "query-1" },
|
|
155
|
+
})).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
test("merge route matchers", () => {
|
|
158
|
+
const routeMatcher1 = createRouteMatcher("manyParameters", { param1: "value-1", queryParam1: "query-1" });
|
|
159
|
+
const routeMatcher2 = createRouteMatcher("manyParameters", { param1: "value-2", queryParam1: "query-2" });
|
|
160
|
+
const routeMatcher = (0, merge_route_matchers_1.mergeRouteMatchers)([routeMatcher1, routeMatcher2]);
|
|
161
|
+
expect(routeMatcher({
|
|
162
|
+
pathname: "/many-parameters/[param1]/form/[param2]",
|
|
163
|
+
query: { param1: "value-1", queryParam1: "query-1", param2: "any" },
|
|
164
|
+
isReady: true,
|
|
165
|
+
})).toBe(true);
|
|
166
|
+
expect(routeMatcher({
|
|
167
|
+
pathname: "/many-parameters/[param1]/form/[param2]",
|
|
168
|
+
query: { param1: "value-2", queryParam1: "query-2", param2: "any" },
|
|
169
|
+
isReady: true,
|
|
170
|
+
})).toBe(true);
|
|
171
|
+
expect(routeMatcher({
|
|
172
|
+
pathname: "/many-parameters/[param1]/form/[param2]",
|
|
173
|
+
query: { param1: "value-3", queryParam1: "query-3", param2: "any" },
|
|
174
|
+
isReady: true,
|
|
175
|
+
})).toBe(false);
|
|
176
|
+
});
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|