@cedarjs/router 8.0.0-canary.3541 → 8.0.0-canary.3542
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/AuthenticatedRoute.d.ts +4 -2
- package/dist/AuthenticatedRoute.d.ts.map +1 -1
- package/dist/AuthenticatedRoute.js +83 -29
- package/dist/Set.d.ts +48 -6
- package/dist/Set.d.ts.map +1 -1
- package/dist/analyzeRoutes.d.ts +3 -0
- package/dist/analyzeRoutes.d.ts.map +1 -1
- package/dist/analyzeRoutes.js +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/router-context.d.ts +19 -0
- package/dist/router-context.d.ts.map +1 -1
- package/dist/router-context.js +3 -1
- package/dist/router.d.ts +22 -2
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +11 -1
- package/dist/rsc/ServerRouter.js +9 -2
- package/dist/util.d.ts +10 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +16 -2
- package/package.json +6 -6
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { GeneratedRoutesMap } from './analyzeRoutes.js';
|
|
3
2
|
interface AuthenticatedRouteProps {
|
|
4
3
|
children: React.ReactNode | Thenable<React.ReactNode>;
|
|
5
4
|
roles?: string | string[];
|
|
6
|
-
|
|
5
|
+
userRoles?: string | string[];
|
|
6
|
+
orgRoles?: string | string[];
|
|
7
|
+
unauthenticated: string;
|
|
8
|
+
unauthorized?: string;
|
|
7
9
|
whileLoadingAuth?: () => React.ReactElement | null;
|
|
8
10
|
}
|
|
9
11
|
export declare const AuthenticatedRoute: React.FC<AuthenticatedRouteProps>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticatedRoute.d.ts","sourceRoot":"","sources":["../src/AuthenticatedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"AuthenticatedRoute.d.ts","sourceRoot":"","sources":["../src/AuthenticatedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACrD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,KAAK,CAAC,YAAY,GAAG,IAAI,CAAA;CACnD;AAsED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA4FhE,CAAA"}
|
|
@@ -1,10 +1,51 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useLocation } from "./location.js";
|
|
3
3
|
import { Redirect } from "./redirect.js";
|
|
4
4
|
import { useRouterState } from "./router-context.js";
|
|
5
|
+
import { paramsForRoute, pathParamsText } from "./util.js";
|
|
6
|
+
const REPLACE = { replace: true };
|
|
7
|
+
const useNoOrgRoles = () => null;
|
|
8
|
+
function currentPathParams(routerState, pathname) {
|
|
9
|
+
const route = Object.values(routerState.routes.pathRouteMap).find(
|
|
10
|
+
(candidate) => candidate.name === routerState.activeRouteName
|
|
11
|
+
);
|
|
12
|
+
if (!route?.path) {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
return pathParamsText(route.path, pathname, routerState.paramTypes);
|
|
16
|
+
}
|
|
17
|
+
function redirectPath(routes, name, params) {
|
|
18
|
+
if (!Object.hasOwn(routes.namedRoutesMap, name)) {
|
|
19
|
+
throw new Error(`We could not find a route named ${name}`);
|
|
20
|
+
}
|
|
21
|
+
const route = Object.values(routes.pathRouteMap).find(
|
|
22
|
+
(candidate) => candidate.name === name
|
|
23
|
+
);
|
|
24
|
+
if (!route) {
|
|
25
|
+
return routes.namedRoutesMap[name]();
|
|
26
|
+
}
|
|
27
|
+
const routeParams = {};
|
|
28
|
+
for (const [paramName] of paramsForRoute(route.path)) {
|
|
29
|
+
const value = params[paramName];
|
|
30
|
+
if (value === void 0) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Redirecting to route "${name}" requires the route parameter "${paramName}", which the current route doesn't have. Please choose a different route`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
routeParams[paramName] = value;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return routes.namedRoutesMap[name](routeParams);
|
|
39
|
+
} catch {
|
|
40
|
+
throw new Error(`Could not redirect to the route named ${name}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
5
43
|
const AuthenticatedRoute = ({
|
|
6
44
|
unauthenticated,
|
|
45
|
+
unauthorized,
|
|
7
46
|
roles,
|
|
47
|
+
userRoles,
|
|
48
|
+
orgRoles,
|
|
8
49
|
whileLoadingAuth,
|
|
9
50
|
children
|
|
10
51
|
}) => {
|
|
@@ -14,35 +55,48 @@ const AuthenticatedRoute = ({
|
|
|
14
55
|
isAuthenticated,
|
|
15
56
|
hasRole
|
|
16
57
|
} = routerState.useAuth();
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
unauthenticatedPath = generatedRoutesMap[unauthenticated]();
|
|
32
|
-
} catch (e) {
|
|
33
|
-
if (e instanceof Error && /Missing parameter .* for route/.test(e.message)) {
|
|
34
|
-
throw new Error(
|
|
35
|
-
`Redirecting to route "${unauthenticated}" would require route parameters, which currently is not supported. Please choose a different route`
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
throw new Error(
|
|
39
|
-
`Could not redirect to the route named ${unauthenticated}`
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
return /* @__PURE__ */ React.createElement(Redirect, { to: `${unauthenticatedPath}?redirectTo=${currentLocation}` });
|
|
58
|
+
const { pathname } = useLocation();
|
|
59
|
+
const pathParams = currentPathParams(routerState, pathname);
|
|
60
|
+
const useOrgRoles = routerState.useOrgRoles ?? useNoOrgRoles;
|
|
61
|
+
const hasOrgRole = useOrgRoles(routerState.useAuth, pathParams);
|
|
62
|
+
if (orgRoles !== void 0 && !hasOrgRole) {
|
|
63
|
+
if (!routerState.useOrgRoles) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
"A PrivateSet with `orgRoles` needs `useOrgRoles` on the Router to check the role with. Please pass `useOrgRoles` from `@cedarjs/tenancy/web`: <Router useAuth={useAuth} useOrgRoles={useOrgRoles}>"
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (pathParams["orgSlug"] === void 0) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
"A PrivateSet with `orgRoles` needs an organization to check the role in, and the route has no `orgSlug` param. Please only use `orgRoles` on routes with `{orgSlug}` in their path, or pass the Router a `useOrgRoles` that finds the organization another way"
|
|
71
|
+
);
|
|
43
72
|
}
|
|
73
|
+
throw new Error(
|
|
74
|
+
"A PrivateSet with `orgRoles` got no role check from the Router's `useOrgRoles` for this route, so there is no organization to check the role in"
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
const hasRequiredRoles = (!roles || hasRole(roles)) && (!userRoles || hasRole(userRoles)) && (orgRoles === void 0 || !!hasOrgRole && hasOrgRole(orgRoles));
|
|
78
|
+
if (isAuthenticated && hasRequiredRoles) {
|
|
79
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
80
|
+
}
|
|
81
|
+
if (authLoading) {
|
|
82
|
+
return whileLoadingAuth?.() || null;
|
|
83
|
+
}
|
|
84
|
+
if (isAuthenticated && unauthorized) {
|
|
85
|
+
return /* @__PURE__ */ React.createElement(
|
|
86
|
+
Redirect,
|
|
87
|
+
{
|
|
88
|
+
to: redirectPath(routerState.routes, unauthorized, pathParams),
|
|
89
|
+
options: REPLACE
|
|
90
|
+
}
|
|
91
|
+
);
|
|
44
92
|
}
|
|
45
|
-
|
|
93
|
+
const currentLocation = globalThis.location.pathname + encodeURIComponent(globalThis.location.search);
|
|
94
|
+
const unauthenticatedPath = redirectPath(
|
|
95
|
+
routerState.routes,
|
|
96
|
+
unauthenticated,
|
|
97
|
+
pathParams
|
|
98
|
+
);
|
|
99
|
+
return /* @__PURE__ */ React.createElement(Redirect, { to: `${unauthenticatedPath}?redirectTo=${currentLocation}` });
|
|
46
100
|
};
|
|
47
101
|
export {
|
|
48
102
|
AuthenticatedRoute
|
package/dist/Set.d.ts
CHANGED
|
@@ -26,12 +26,35 @@ export interface WrapperProps {
|
|
|
26
26
|
*/
|
|
27
27
|
export type WrapperType = ComponentType<WrapperProps>;
|
|
28
28
|
/**
|
|
29
|
-
* The
|
|
30
|
-
* `
|
|
29
|
+
* The role props. An app with tenancy (see `AuthTenancy`) has `userRoles` and
|
|
30
|
+
* `orgRoles` instead of `roles`: there, every role check says which kind it
|
|
31
|
+
* is.
|
|
31
32
|
*/
|
|
32
33
|
type SetRoles = AuthTenancy extends {
|
|
33
34
|
enabled: true;
|
|
34
|
-
} ?
|
|
35
|
+
} ? {
|
|
36
|
+
/**
|
|
37
|
+
* Route is permitted when authenticated and user has any of the
|
|
38
|
+
* provided roles such as "admin" or ["admin", "editor"], in
|
|
39
|
+
* `currentUser.roles`, as opposed to a role in the organization they're
|
|
40
|
+
* in (see `orgRoles`). With `orgRoles` as well, they need both.
|
|
41
|
+
*/
|
|
42
|
+
userRoles?: string | string[];
|
|
43
|
+
/**
|
|
44
|
+
* Route is permitted when authenticated and user has any of the
|
|
45
|
+
* provided roles such as "owner" or ["owner", "admin"] in the current
|
|
46
|
+
* organization. With `userRoles` as well, they need both.
|
|
47
|
+
*
|
|
48
|
+
* The organization is the one with the route's `orgSlug` param, and
|
|
49
|
+
* the router checks the role with the `useOrgRoles` passed to it:
|
|
50
|
+
*
|
|
51
|
+
* <Router useAuth={useAuth} useOrgRoles={useOrgRoles}>
|
|
52
|
+
*
|
|
53
|
+
* A `PrivateSet` with `orgRoles` throws without `useOrgRoles` on the
|
|
54
|
+
* router, or on a route without `{orgSlug}` in its path.
|
|
55
|
+
*/
|
|
56
|
+
orgRoles?: string | string[];
|
|
57
|
+
} : {
|
|
35
58
|
/**
|
|
36
59
|
* Route is permitted when authenticated and user has any of the
|
|
37
60
|
* provided roles such as "admin" or ["admin", "editor"], in
|
|
@@ -61,6 +84,13 @@ interface SetProps extends SetRoles {
|
|
|
61
84
|
* @deprecated Please use `<PrivateSet>` instead and specify this prop there
|
|
62
85
|
*/
|
|
63
86
|
unauthenticated?: string;
|
|
87
|
+
/**
|
|
88
|
+
* The page name where a user will be redirected when authenticated but
|
|
89
|
+
* without the required roles
|
|
90
|
+
*
|
|
91
|
+
* @deprecated Please use `<PrivateSet>` instead and specify this prop there
|
|
92
|
+
*/
|
|
93
|
+
unauthorized?: string;
|
|
64
94
|
/** Prerender all pages in the set */
|
|
65
95
|
prerender?: boolean;
|
|
66
96
|
children: ReactNode;
|
|
@@ -77,16 +107,28 @@ interface SetProps extends SetRoles {
|
|
|
77
107
|
* </Set>
|
|
78
108
|
*/
|
|
79
109
|
export declare function Set(props: SetProps): React.JSX.Element;
|
|
80
|
-
type PrivateSetProps = Omit<SetProps, 'private' | 'unauthenticated'> & {
|
|
81
|
-
/**
|
|
110
|
+
type PrivateSetProps = Omit<SetProps, 'private' | 'unauthenticated' | 'unauthorized'> & {
|
|
111
|
+
/**
|
|
112
|
+
* The page name where a user will be redirected when not authenticated.
|
|
113
|
+
* Also where one without the required roles is redirected, unless the set
|
|
114
|
+
* has `unauthorized`.
|
|
115
|
+
*/
|
|
82
116
|
unauthenticated: string;
|
|
117
|
+
/**
|
|
118
|
+
* The page name where a user will be redirected when authenticated but
|
|
119
|
+
* without the required roles. Without it, they're redirected to
|
|
120
|
+
* `unauthenticated`.
|
|
121
|
+
*/
|
|
122
|
+
unauthorized?: string;
|
|
83
123
|
};
|
|
84
124
|
/** @deprecated Please use `<PrivateSet>` instead */
|
|
85
125
|
export declare function Private(props: PrivateSetProps): React.JSX.Element;
|
|
86
126
|
/**
|
|
87
127
|
* Wraps a set of routes that require the user to be authenticated before
|
|
88
128
|
* rendering. Unauthenticated users are redirected to the route named by
|
|
89
|
-
* `unauthenticated
|
|
129
|
+
* `unauthenticated`, and users without the required roles to the one named by
|
|
130
|
+
* `unauthorized`. Either route can have path params the current route has,
|
|
131
|
+
* like `orgSlug`: they're filled in from the current route.
|
|
90
132
|
*
|
|
91
133
|
* Coming from React Router or a similar library and looking for something
|
|
92
134
|
* like `RequireAuth` or `ProtectedRoute`? This is the Cedar equivalent.
|
package/dist/Set.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../src/Set.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACnE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;IAC/C,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,YAAY,CAAC,CAAA;AAErD
|
|
1
|
+
{"version":3,"file":"Set.d.ts","sourceRoot":"","sources":["../src/Set.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACnE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;IAC/C,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC,YAAY,CAAC,CAAA;AAErD;;;;GAIG;AACH,KAAK,QAAQ,GAAG,WAAW,SAAS;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjD;IACE;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC7B;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC7B,GACD;IACE;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC1B,CAAA;AAEL,UAAU,QAAS,SAAQ,QAAQ;IACjC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,WAAW,EAAE,CAAA;IAC3C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;IAC5C,gBAAgB,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;CAC7C;AAED;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,qBAIlC;AAED,KAAK,eAAe,GAAG,IAAI,CACzB,QAAQ,EACR,SAAS,GAAG,iBAAiB,GAAG,cAAc,CAC/C,GAAG;IACF;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,oDAAoD;AACpD,wBAAgB,OAAO,CAAC,KAAK,EAAE,eAAe,qBAI7C;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,qBAIhD;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,KAAG,IAAI,IAAI,YAAY,CAAC,QAAQ,CAOxE,CAAA;AAED,eAAO,MAAM,gBAAgB,GAC3B,MAAM,SAAS,KACd,IAAI,IAAI,YAAY,CAAC,eAAe,CAEtC,CAAA;AAGD,eAAO,MAAM,aAAa,GACxB,MAAM,SAAS,KACd,IAAI,IAAI,YAAY,CAAC,eAAe,CAEtC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,aAKpB"}
|
package/dist/analyzeRoutes.d.ts
CHANGED
|
@@ -14,7 +14,10 @@ export type Wrappers = readonly WrapperType[];
|
|
|
14
14
|
interface SetRenderProps {
|
|
15
15
|
private?: boolean;
|
|
16
16
|
unauthenticated?: string;
|
|
17
|
+
unauthorized?: string;
|
|
17
18
|
roles?: string | string[];
|
|
19
|
+
userRoles?: string | string[];
|
|
20
|
+
orgRoles?: string | string[];
|
|
18
21
|
whileLoadingAuth?: () => ReactElement | null;
|
|
19
22
|
}
|
|
20
23
|
interface Set {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzeRoutes.d.ts","sourceRoot":"","sources":["../src/analyzeRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAQzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,WAAW,CAAA;AAElB,KAAK,gBAAgB,GAAG,MAAM,YAAY,GAAG,IAAI,CAAA;AAIjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,CACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,KACtD,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,WAAW,EAAE,CAAA;AAE7C;;;GAGG;AACH,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"analyzeRoutes.d.ts","sourceRoot":"","sources":["../src/analyzeRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAQzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,WAAW,CAAA;AAElB,KAAK,gBAAgB,GAAG,MAAM,YAAY,GAAG,IAAI,CAAA;AAIjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,CACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,KACtD,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,WAAW,EAAE,CAAA;AAE7C;;;GAGG;AACH,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAEzB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAA;CAC7C;AAED,UAAU,GAAG;IACX,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,cAAc,CAAA;CACtB;AAmDD,KAAK,SAAS,GAAG,MAAM,CAAA;AAEvB;;;;GAIG;AACH,UAAU,aAAa;IACrB,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,GAAG,EAAE,CAAA;CACZ;AAED,UAAU,oBAAoB;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC3C;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,EACnB,EAAE,eAAe,EAAE,cAAc,EAAE,EAAE,oBAAoB;;;;;;EAqK1D"}
|
package/dist/analyzeRoutes.js
CHANGED
|
@@ -19,9 +19,18 @@ function pickSetRenderProps(props) {
|
|
|
19
19
|
if (props.unauthenticated !== void 0) {
|
|
20
20
|
picked.unauthenticated = props.unauthenticated;
|
|
21
21
|
}
|
|
22
|
+
if (props.unauthorized !== void 0) {
|
|
23
|
+
picked.unauthorized = props.unauthorized;
|
|
24
|
+
}
|
|
22
25
|
if (props.roles !== void 0) {
|
|
23
26
|
picked.roles = props.roles;
|
|
24
27
|
}
|
|
28
|
+
if (props.userRoles !== void 0) {
|
|
29
|
+
picked.userRoles = props.userRoles;
|
|
30
|
+
}
|
|
31
|
+
if (props.orgRoles !== void 0) {
|
|
32
|
+
picked.orgRoles = props.orgRoles;
|
|
33
|
+
}
|
|
25
34
|
if (props.whileLoadingAuth !== void 0) {
|
|
26
35
|
picked.whileLoadingAuth = props.whileLoadingAuth;
|
|
27
36
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { Redirect } from './redirect.js';
|
|
|
6
6
|
export { usePageLoadingContext, PageLoadingContextProvider, } from './PageLoadingContext.js';
|
|
7
7
|
export { useParams, ParamsProvider, ParamsContext } from './params.js';
|
|
8
8
|
export { Router } from './router.js';
|
|
9
|
+
export type { UseOrgRoles } from './router-context.js';
|
|
9
10
|
export { Route } from './Route.js';
|
|
10
11
|
export { namedRoutes as routes } from './namedRoutes.js';
|
|
11
12
|
export { Set, Private, PrivateSet, isSetNode, isPrivateSetNode, isPrivateNode, } from './Set.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,WAAW,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,EACL,GAAG,EACH,OAAO,EACP,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEzD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACtE,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACxD,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE1D;;;;;;;;;GASG;AAGH,MAAM,WAAW,eAAe;CAAG;AAGnC,cAAc,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,WAAW,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAExD,OAAO,EACL,GAAG,EACH,OAAO,EACP,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,aAAa,GACd,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEzD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACtE,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACxD,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAE/B,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE1D;;;;;;;;;GASG;AAGH,MAAM,WAAW,eAAe;CAAG;AAGnC,cAAc,uBAAuB,CAAA"}
|
package/dist/router-context.d.ts
CHANGED
|
@@ -5,9 +5,28 @@ import type { AuthContextInterface } from '@cedarjs/auth' with {
|
|
|
5
5
|
import type { analyzeRoutes } from './analyzeRoutes.js';
|
|
6
6
|
import type { ParamType } from './util.js';
|
|
7
7
|
type UseAuth = () => AuthContextInterface<unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Checks the user's role in the organization of the current route, for
|
|
10
|
+
* `<PrivateSet orgRoles>`, given the router's `useAuth` and the route's path
|
|
11
|
+
* params: `null` when the route isn't in an organization. In apps with
|
|
12
|
+
* tenancy, `useOrgRoles` from `@cedarjs/tenancy/web` is one. The router
|
|
13
|
+
* calls it like a hook, on every render of a private set.
|
|
14
|
+
*
|
|
15
|
+
* One of the app's own can answer in three ways:
|
|
16
|
+
* - a check, which the router uses for `orgRoles`. One that always returns
|
|
17
|
+
* `false` denies access and redirects to `unauthorized`.
|
|
18
|
+
* - `null`, for no organization: a set with `orgRoles` then throws the
|
|
19
|
+
* router's own error.
|
|
20
|
+
* - throw an error of its own, such as for an organization that's been
|
|
21
|
+
* suspended. It reaches the app's error boundary like any error thrown
|
|
22
|
+
* while rendering.
|
|
23
|
+
*/
|
|
24
|
+
export type UseOrgRoles = (useAuth: UseAuth, params: Record<string, string>) => ((roles: string | string[]) => boolean) | null;
|
|
8
25
|
export interface RouterState {
|
|
9
26
|
paramTypes?: Record<string, ParamType>;
|
|
10
27
|
useAuth: UseAuth;
|
|
28
|
+
/** Unset in apps that don't pass one to the router */
|
|
29
|
+
useOrgRoles?: UseOrgRoles;
|
|
11
30
|
routes: ReturnType<typeof analyzeRoutes>;
|
|
12
31
|
activeRouteName?: string | undefined | null;
|
|
13
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../src/router-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;IACxD,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAGD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,KAAK,OAAO,GAAG,MAAM,oBAAoB,CACvC,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,CACR,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;CAC5C;AAID,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CACtD,WAAW,EACX,SAAS,CACV;IACC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,
|
|
1
|
+
{"version":3,"file":"router-context.d.ts","sourceRoot":"","sources":["../src/router-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;IACxD,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAGD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,KAAK,OAAO,GAAG,MAAM,oBAAoB,CACvC,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,CACR,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,IAAI,CAAA;AAEnD,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,sDAAsD;IACtD,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;CAC5C;AAID,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CACtD,WAAW,EACX,SAAS,CACV;IACC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAwBtE,CAAA;AAED,eAAO,MAAM,cAAc,mBAU1B,CAAA"}
|
package/dist/router-context.js
CHANGED
|
@@ -3,6 +3,7 @@ import { useNoAuth } from "@cedarjs/auth";
|
|
|
3
3
|
const RouterStateContext = createContext(void 0);
|
|
4
4
|
const RouterContextProvider = ({
|
|
5
5
|
useAuth,
|
|
6
|
+
useOrgRoles,
|
|
6
7
|
paramTypes,
|
|
7
8
|
routes,
|
|
8
9
|
activeRouteName,
|
|
@@ -11,11 +12,12 @@ const RouterContextProvider = ({
|
|
|
11
12
|
const state = useMemo(
|
|
12
13
|
() => ({
|
|
13
14
|
useAuth: useAuth || useNoAuth,
|
|
15
|
+
useOrgRoles,
|
|
14
16
|
paramTypes,
|
|
15
17
|
routes,
|
|
16
18
|
activeRouteName
|
|
17
19
|
}),
|
|
18
|
-
[useAuth, paramTypes, routes, activeRouteName]
|
|
20
|
+
[useAuth, useOrgRoles, paramTypes, routes, activeRouteName]
|
|
19
21
|
);
|
|
20
22
|
return /* @__PURE__ */ React.createElement(RouterStateContext.Provider, { value: state }, children);
|
|
21
23
|
};
|
package/dist/router.d.ts
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AuthTenancy } from '@cedarjs/auth' with {
|
|
4
|
+
'resolution-mode': 'import'
|
|
5
|
+
};
|
|
6
|
+
import type { RouterContextProviderProps, UseOrgRoles } from './router-context.js';
|
|
4
7
|
import type { TrailingSlashesTypes } from './util.js';
|
|
5
|
-
|
|
8
|
+
/**
|
|
9
|
+
* `useOrgRoles`, only in an app with tenancy (see `AuthTenancy`), where sets
|
|
10
|
+
* have `orgRoles`
|
|
11
|
+
*/
|
|
12
|
+
type RouterOrgRoles = AuthTenancy extends {
|
|
13
|
+
enabled: true;
|
|
14
|
+
} ? {
|
|
15
|
+
/**
|
|
16
|
+
* Checks the user's role in the organization of the current route, for
|
|
17
|
+
* `<PrivateSet orgRoles>`. Pass `useOrgRoles` from
|
|
18
|
+
* `@cedarjs/tenancy/web`:
|
|
19
|
+
*
|
|
20
|
+
* <Router useAuth={useAuth} useOrgRoles={useOrgRoles}>
|
|
21
|
+
*/
|
|
22
|
+
useOrgRoles?: UseOrgRoles;
|
|
23
|
+
} : Record<never, never>;
|
|
24
|
+
export interface RouterProps extends Omit<RouterContextProviderProps, 'routes' | 'activeRouteName' | 'useOrgRoles'>, RouterOrgRoles {
|
|
6
25
|
trailingSlashes?: TrailingSlashesTypes;
|
|
7
26
|
pageLoadingDelay?: number;
|
|
8
27
|
children: ReactNode;
|
|
9
28
|
}
|
|
10
29
|
export declare const Router: React.FC<RouterProps>;
|
|
30
|
+
export {};
|
|
11
31
|
//# sourceMappingURL=router.d.ts.map
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AACpD,OAAO,KAAwB,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AACpD,OAAO,KAAwB,MAAM,OAAO,CAAA;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;IAC/C,iBAAiB,EAAE,QAAQ;CAC5B,CAAA;AAYD,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,MAAM,qBAAqB,CAAA;AAK5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAErD;;;GAGG;AACH,KAAK,cAAc,GAAG,WAAW,SAAS;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACvD;IACE;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B,GACD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAExB,MAAM,WAAW,WACf,SACE,IAAI,CACF,0BAA0B,EAC1B,QAAQ,GAAG,iBAAiB,GAAG,aAAa,CAC7C,EACD,cAAc;IAChB,eAAe,CAAC,EAAE,oBAAoB,CAAA;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAsCD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAwB,CAAA"}
|
package/dist/router.js
CHANGED
|
@@ -12,8 +12,9 @@ import { RouterContextProvider } from "./router-context.js";
|
|
|
12
12
|
import { wrapWithSetWrappers } from "./Set.js";
|
|
13
13
|
import { SplashPage } from "./splash-page.js";
|
|
14
14
|
import { matchPath, parseSearch, replaceParams, validatePath } from "./util.js";
|
|
15
|
-
const
|
|
15
|
+
const RouterImplementation = ({
|
|
16
16
|
useAuth,
|
|
17
|
+
useOrgRoles,
|
|
17
18
|
paramTypes,
|
|
18
19
|
pageLoadingDelay,
|
|
19
20
|
trailingSlashes = "never",
|
|
@@ -26,6 +27,7 @@ const Router = ({
|
|
|
26
27
|
LocationAwareRouter,
|
|
27
28
|
{
|
|
28
29
|
useAuth,
|
|
30
|
+
useOrgRoles,
|
|
29
31
|
paramTypes,
|
|
30
32
|
pageLoadingDelay
|
|
31
33
|
},
|
|
@@ -33,8 +35,11 @@ const Router = ({
|
|
|
33
35
|
))
|
|
34
36
|
);
|
|
35
37
|
};
|
|
38
|
+
RouterImplementation.displayName = "Router";
|
|
39
|
+
const Router = RouterImplementation;
|
|
36
40
|
const LocationAwareRouter = ({
|
|
37
41
|
useAuth,
|
|
42
|
+
useOrgRoles,
|
|
38
43
|
paramTypes,
|
|
39
44
|
pageLoadingDelay,
|
|
40
45
|
children
|
|
@@ -78,6 +83,7 @@ const LocationAwareRouter = ({
|
|
|
78
83
|
RouterContextProvider,
|
|
79
84
|
{
|
|
80
85
|
useAuth,
|
|
86
|
+
useOrgRoles,
|
|
81
87
|
paramTypes,
|
|
82
88
|
routes: analyzeRoutesResult
|
|
83
89
|
},
|
|
@@ -122,6 +128,7 @@ const LocationAwareRouter = ({
|
|
|
122
128
|
RouterContextProvider,
|
|
123
129
|
{
|
|
124
130
|
useAuth,
|
|
131
|
+
useOrgRoles,
|
|
125
132
|
paramTypes,
|
|
126
133
|
routes: analyzeRoutesResult,
|
|
127
134
|
activeRouteName: name
|
|
@@ -154,7 +161,10 @@ const WrappedPage = memo(({ sets, children }) => {
|
|
|
154
161
|
AuthenticatedRoute,
|
|
155
162
|
{
|
|
156
163
|
unauthenticated,
|
|
164
|
+
unauthorized: set.props.unauthorized,
|
|
157
165
|
roles: set.props.roles,
|
|
166
|
+
userRoles: set.props.userRoles,
|
|
167
|
+
orgRoles: set.props.orgRoles,
|
|
158
168
|
whileLoadingAuth: set.props.whileLoadingAuth
|
|
159
169
|
},
|
|
160
170
|
wrapped
|
package/dist/rsc/ServerRouter.js
CHANGED
|
@@ -96,10 +96,15 @@ function hasRole(requiredRoles) {
|
|
|
96
96
|
}
|
|
97
97
|
const AuthenticatedRoute = ({
|
|
98
98
|
children,
|
|
99
|
-
roles
|
|
99
|
+
roles,
|
|
100
|
+
userRoles,
|
|
101
|
+
orgRoles
|
|
100
102
|
}) => {
|
|
101
103
|
const { isAuthenticated } = getAuthState();
|
|
102
|
-
|
|
104
|
+
if (orgRoles !== void 0) {
|
|
105
|
+
throw new Error("`orgRoles` is not supported with RSC yet");
|
|
106
|
+
}
|
|
107
|
+
const isAuthorized = isAuthenticated && (!roles || hasRole(roles)) && (!userRoles || hasRole(userRoles));
|
|
103
108
|
if (isAuthorized) {
|
|
104
109
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
105
110
|
}
|
|
@@ -126,6 +131,8 @@ const WrappedPage = ({ routeLoaderElement, sets }) => {
|
|
|
126
131
|
{
|
|
127
132
|
unauthenticated,
|
|
128
133
|
roles: set.props.roles,
|
|
134
|
+
userRoles: set.props.userRoles,
|
|
135
|
+
orgRoles: set.props.orgRoles,
|
|
129
136
|
whileLoadingAuth: set.props.whileLoadingAuth
|
|
130
137
|
},
|
|
131
138
|
wrapped
|
package/dist/util.d.ts
CHANGED
|
@@ -50,6 +50,16 @@ export declare function matchPath(routeDefinition: string, pathname: string, { u
|
|
|
50
50
|
match: boolean;
|
|
51
51
|
params: Record<string, unknown>;
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* The path params of `pathname` for the route `routeDefinition`, as the text
|
|
55
|
+
* in the path, without parsing them with their param types. For putting into
|
|
56
|
+
* another route's path, where a parsed value (whatever a custom type's `parse`
|
|
57
|
+
* returns, say) wouldn't be the same text.
|
|
58
|
+
*
|
|
59
|
+
* pathParamsText('/post/{id:Int}', '/post/7')
|
|
60
|
+
* => { id: '7' }
|
|
61
|
+
*/
|
|
62
|
+
export declare function pathParamsText(routeDefinition: string, pathname: string, userParamTypes?: Record<string, ParamType>): Record<string, string>;
|
|
53
63
|
interface GetRouteRegexOptions {
|
|
54
64
|
matchSubPaths?: boolean;
|
|
55
65
|
allParamTypes?: Record<string, ParamType>;
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,cA0B3C;AAED,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAA;AAElE,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAA;CAChC;AAwBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,EACE,cAAc,EACd,aAAa,GACd,GAAE;IACD,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAA;CAIxB;;;;;;EA2CF;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAM,0BAgB/C;AAED,UAAU,oBAAoB;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CAC1C;AACD;;;;;GAKG;AAEH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,EACE,aAAqB,EACrB,aAA8B,GAC/B,GAAE,oBAAoB,GAAG,SAAc;;;;EA+BzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EACJ,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,eAAe,GAAG,SAAS,MAW7E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAyC3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,UAiCnC;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAExE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,6BAQtD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,YAMvB"}
|
package/dist/util.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function paramsForRoute(route) {
|
|
2
|
-
const params = [...route.matchAll(/\{([^}]+)\}/g)];
|
|
2
|
+
const params = [...route.matchAll(/\{([^{}]+)\}/g)];
|
|
3
3
|
return params.map((match) => match[1]).map((match) => {
|
|
4
4
|
const parts = match.split(":");
|
|
5
5
|
let name = parts[0];
|
|
@@ -70,6 +70,19 @@ function matchPath(routeDefinition, pathname, {
|
|
|
70
70
|
}
|
|
71
71
|
return { match: true };
|
|
72
72
|
}
|
|
73
|
+
function pathParamsText(routeDefinition, pathname, userParamTypes = {}) {
|
|
74
|
+
const { matchRegex, routeParams } = getRouteRegexAndParams(routeDefinition, {
|
|
75
|
+
allParamTypes: { ...coreParamTypes, ...userParamTypes }
|
|
76
|
+
});
|
|
77
|
+
const match = matchRegex.exec(pathname);
|
|
78
|
+
const params = {};
|
|
79
|
+
if (match) {
|
|
80
|
+
routeParams.forEach(([name], index) => {
|
|
81
|
+
params[name] = match[index + 1];
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return params;
|
|
85
|
+
}
|
|
73
86
|
function getRouteRegexAndParams(route, {
|
|
74
87
|
matchSubPaths = false,
|
|
75
88
|
allParamTypes = coreParamTypes
|
|
@@ -140,7 +153,7 @@ function replaceParams(route, args = {}) {
|
|
|
140
153
|
const [name, _type, match] = param;
|
|
141
154
|
const value = args[name];
|
|
142
155
|
if (value !== void 0) {
|
|
143
|
-
path = path.replace(match, value);
|
|
156
|
+
path = path.replace(match, () => String(value));
|
|
144
157
|
} else {
|
|
145
158
|
throw new Error(
|
|
146
159
|
`Missing parameter '${name}' for route '${route}' when generating a navigation URL.`
|
|
@@ -178,6 +191,7 @@ export {
|
|
|
178
191
|
matchPath,
|
|
179
192
|
paramsForRoute,
|
|
180
193
|
parseSearch,
|
|
194
|
+
pathParamsText,
|
|
181
195
|
replaceParams,
|
|
182
196
|
validatePath
|
|
183
197
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/router",
|
|
3
|
-
"version": "8.0.0-canary.
|
|
3
|
+
"version": "8.0.0-canary.3542",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -52,15 +52,15 @@
|
|
|
52
52
|
"test:watch": "vitest watch"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@cedarjs/project-config": "8.0.0-canary.
|
|
56
|
-
"@cedarjs/server-store": "8.0.0-canary.
|
|
55
|
+
"@cedarjs/project-config": "8.0.0-canary.3542",
|
|
56
|
+
"@cedarjs/server-store": "8.0.0-canary.3542",
|
|
57
57
|
"react-server-dom-webpack": "19.3.1",
|
|
58
58
|
"ts-toolbelt": "9.6.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@arethetypeswrong/cli": "0.18.5",
|
|
62
|
-
"@cedarjs/auth": "8.0.0-canary.
|
|
63
|
-
"@cedarjs/framework-tools": "8.0.0-canary.
|
|
62
|
+
"@cedarjs/auth": "8.0.0-canary.3542",
|
|
63
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3542",
|
|
64
64
|
"@testing-library/jest-dom": "6.9.1",
|
|
65
65
|
"@types/react": "^19.2.0",
|
|
66
66
|
"@types/react-dom": "^19.2.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"vitest": "4.1.12"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@cedarjs/auth": "8.0.0-canary.
|
|
77
|
+
"@cedarjs/auth": "8.0.0-canary.3542",
|
|
78
78
|
"react": "19.3.1",
|
|
79
79
|
"react-dom": "19.3.1"
|
|
80
80
|
},
|