@koordinates/xstate-tree 4.7.0 → 4.8.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.
|
@@ -69,7 +69,7 @@ function buildCreateRoute(history, basePath) {
|
|
|
69
69
|
}
|
|
70
70
|
return parentRoutes;
|
|
71
71
|
}
|
|
72
|
-
return ({ event, matcher, reverser, paramsSchema, querySchema, redirect, preload, }) => {
|
|
72
|
+
return ({ event, matcher, reverser, paramsSchema, querySchema, redirect, preload, canMatch, }) => {
|
|
73
73
|
let fullParamsSchema = paramsSchema;
|
|
74
74
|
let parentRoute = baseRoute;
|
|
75
75
|
while (fullParamsSchema && parentRoute) {
|
|
@@ -86,6 +86,7 @@ function buildCreateRoute(history, basePath) {
|
|
|
86
86
|
querySchema,
|
|
87
87
|
parent: baseRoute,
|
|
88
88
|
redirect,
|
|
89
|
+
canMatch,
|
|
89
90
|
matcher: matcher,
|
|
90
91
|
reverser: reverser,
|
|
91
92
|
// @ts-ignore :cry:
|
|
@@ -95,19 +96,34 @@ function buildCreateRoute(history, basePath) {
|
|
|
95
96
|
},
|
|
96
97
|
// @ts-ignore :cry:
|
|
97
98
|
matches(suppliedUrl, search) {
|
|
98
|
-
var _a, _b, _c;
|
|
99
|
+
var _a, _b, _c, _d, _e;
|
|
99
100
|
const fullUrl = suppliedUrl.endsWith("/")
|
|
100
101
|
? suppliedUrl
|
|
101
102
|
: suppliedUrl + "/";
|
|
102
103
|
let url = fullUrl;
|
|
103
104
|
const parentRoutes = getParentArray();
|
|
104
105
|
let params = {};
|
|
106
|
+
const parsedQuery = (0, query_string_1.parse)(search);
|
|
105
107
|
while (parentRoutes.length) {
|
|
106
108
|
const parentRoute = parentRoutes.shift();
|
|
107
109
|
const parentMatch = parentRoute.matcher(url, undefined);
|
|
108
110
|
if (parentMatch === false) {
|
|
109
111
|
return false;
|
|
110
112
|
}
|
|
113
|
+
// Evaluate parent's canMatch predicate if provided
|
|
114
|
+
if (parentRoute.canMatch) {
|
|
115
|
+
const accumulatedParams = {
|
|
116
|
+
...params,
|
|
117
|
+
...((_a = parentMatch.params) !== null && _a !== void 0 ? _a : {}),
|
|
118
|
+
};
|
|
119
|
+
const canMatchResult = parentRoute.canMatch({
|
|
120
|
+
params: accumulatedParams,
|
|
121
|
+
query: parsedQuery,
|
|
122
|
+
});
|
|
123
|
+
if (!canMatchResult) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
111
127
|
url = url.slice(parentMatch.matchLength);
|
|
112
128
|
// All routes assume the url starts with a /
|
|
113
129
|
// so if the parent route matches the / in the url, which consumes it
|
|
@@ -115,7 +131,7 @@ function buildCreateRoute(history, basePath) {
|
|
|
115
131
|
if (!url.startsWith("/")) {
|
|
116
132
|
url = "/" + url;
|
|
117
133
|
}
|
|
118
|
-
params = { ...params, ...((
|
|
134
|
+
params = { ...params, ...((_b = parentMatch.params) !== null && _b !== void 0 ? _b : {}) };
|
|
119
135
|
}
|
|
120
136
|
const matches = matcher(url, (0, query_string_1.parse)(search));
|
|
121
137
|
// if there is any URL left after matching this route, the last to match
|
|
@@ -125,7 +141,7 @@ function buildCreateRoute(history, basePath) {
|
|
|
125
141
|
}
|
|
126
142
|
const fullParams = {
|
|
127
143
|
...params,
|
|
128
|
-
...((
|
|
144
|
+
...((_c = matches.params) !== null && _c !== void 0 ? _c : {}),
|
|
129
145
|
};
|
|
130
146
|
if (fullParamsSchema) {
|
|
131
147
|
fullParamsSchema.parse(fullParams);
|
|
@@ -133,11 +149,21 @@ function buildCreateRoute(history, basePath) {
|
|
|
133
149
|
if (querySchema) {
|
|
134
150
|
querySchema.parse(matches.query);
|
|
135
151
|
}
|
|
152
|
+
// Check canMatch predicate if provided
|
|
153
|
+
if (canMatch) {
|
|
154
|
+
const canMatchResult = canMatch({
|
|
155
|
+
params: fullParams,
|
|
156
|
+
query: (_d = matches.query) !== null && _d !== void 0 ? _d : {},
|
|
157
|
+
});
|
|
158
|
+
if (!canMatchResult) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
136
162
|
return {
|
|
137
163
|
originalUrl: `${fullUrl}${search}`,
|
|
138
164
|
type: event,
|
|
139
165
|
params: fullParams,
|
|
140
|
-
query: (
|
|
166
|
+
query: (_e = matches.query) !== null && _e !== void 0 ? _e : {},
|
|
141
167
|
};
|
|
142
168
|
},
|
|
143
169
|
// @ts-ignore :cry:
|
package/lib/xstate-tree.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ export declare type AnyRoute = {
|
|
|
60
60
|
matcher: (url: string, query: ParsedQuery<string> | undefined) => any;
|
|
61
61
|
reverser: any;
|
|
62
62
|
redirect?: any;
|
|
63
|
+
canMatch?: any;
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
/**
|
|
@@ -129,6 +130,7 @@ export declare function buildCreateRoute(history: () => XstateTreeHistory, baseP
|
|
|
129
130
|
meta?: TMeta | undefined;
|
|
130
131
|
redirect?: RouteRedirect<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta> & SharedMeta> | undefined;
|
|
131
132
|
preload?: RouteArgumentFunctions<void, MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta>, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta>>> | undefined;
|
|
133
|
+
canMatch?: RouteArgumentFunctions<boolean, MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta> & SharedMeta, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta> & SharedMeta>> | undefined;
|
|
132
134
|
}) => Route<MergeRouteTypes<RouteParams<TBaseRoute>, ResolveZodType<TParamsSchema>>, ResolveZodType<TQuerySchema>, TEvent, MergeRouteTypes<RouteMeta<TBaseRoute>, TMeta> & SharedMeta>;
|
|
133
135
|
route<TBaseRoute_1 extends AnyRoute>(baseRoute?: TBaseRoute_1 | undefined): <TEvent_1 extends string, TParamsSchema_1 extends Z.ZodObject<any, "strip", Z.ZodTypeAny, {
|
|
134
136
|
[x: string]: any;
|
|
@@ -138,7 +140,7 @@ export declare function buildCreateRoute(history: () => XstateTreeHistory, baseP
|
|
|
138
140
|
[x: string]: any;
|
|
139
141
|
}, {
|
|
140
142
|
[x: string]: any;
|
|
141
|
-
}> | undefined, TMeta_1 extends Record<string, unknown>>({ event, matcher, reverser, paramsSchema, querySchema, redirect, preload, }: {
|
|
143
|
+
}> | undefined, TMeta_1 extends Record<string, unknown>>({ event, matcher, reverser, paramsSchema, querySchema, redirect, preload, canMatch, }: {
|
|
142
144
|
event: TEvent_1;
|
|
143
145
|
paramsSchema?: TParamsSchema_1 | undefined;
|
|
144
146
|
querySchema?: TQuerySchema_1 | undefined;
|
|
@@ -160,6 +162,7 @@ export declare function buildCreateRoute(history: () => XstateTreeHistory, baseP
|
|
|
160
162
|
*/
|
|
161
163
|
reverser: RouteArgumentFunctions<string, MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>>>;
|
|
162
164
|
preload?: RouteArgumentFunctions<void, MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1>>> | undefined;
|
|
165
|
+
canMatch?: RouteArgumentFunctions<boolean, MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1> & SharedMeta, RouteArguments<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1> & SharedMeta>> | undefined;
|
|
163
166
|
}) => Route<MergeRouteTypes<RouteParams<TBaseRoute_1>, ResolveZodType<TParamsSchema_1>>, ResolveZodType<TQuerySchema_1>, TEvent_1, MergeRouteTypes<RouteMeta<TBaseRoute_1>, TMeta_1> & SharedMeta>;
|
|
164
167
|
};
|
|
165
168
|
|
|
@@ -591,6 +594,12 @@ export declare type Route<TParams, TQuery, TEvent, TMeta> = {
|
|
|
591
594
|
paramsSchema?: Z.ZodObject<any>;
|
|
592
595
|
querySchema?: Z.ZodObject<any>;
|
|
593
596
|
redirect?: RouteRedirect<TParams, TQuery, TMeta>;
|
|
597
|
+
/**
|
|
598
|
+
* Optional predicate to control whether this route can be matched.
|
|
599
|
+
* Called after URL matching but before the route is considered matched.
|
|
600
|
+
* Useful for access control or conditional routing.
|
|
601
|
+
*/
|
|
602
|
+
canMatch?: RouteArgumentFunctions<boolean, TParams, TQuery, TMeta>;
|
|
594
603
|
};
|
|
595
604
|
|
|
596
605
|
/**
|
package/package.json
CHANGED