@monocloud/auth-nextjs 0.1.1 → 0.1.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/dist/client/index.cjs +1 -1
- package/dist/client/index.d.mts +136 -3
- package/dist/client/index.mjs +1 -1
- package/dist/{client-BjnSJS59.cjs → client-Be6A2vEn.cjs} +149 -10
- package/dist/client-Be6A2vEn.cjs.map +1 -0
- package/dist/client-CnvBgZM-.mjs +244 -0
- package/dist/client-CnvBgZM-.mjs.map +1 -0
- package/dist/components/client/index.cjs +156 -3
- package/dist/components/client/index.cjs.map +1 -1
- package/dist/components/client/index.d.mts +156 -3
- package/dist/components/client/index.mjs +156 -3
- package/dist/components/client/index.mjs.map +1 -1
- package/dist/components/index.cjs +84 -1
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.mts +86 -1
- package/dist/components/index.mjs +84 -1
- package/dist/components/index.mjs.map +1 -1
- package/dist/index.cjs +716 -333
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1890 -56
- package/dist/index.mjs +691 -308
- package/dist/index.mjs.map +1 -1
- package/dist/{types-BleaXQUP.d.mts → types-DOfZTKa6.d.mts} +90 -141
- package/package.json +2 -2
- package/dist/client-0gaUvMR7.mjs +0 -105
- package/dist/client-0gaUvMR7.mjs.map +0 -1
- package/dist/client-BjnSJS59.cjs.map +0 -1
|
@@ -1,79 +1,32 @@
|
|
|
1
1
|
import { Authenticators, AuthorizationParams, DisplayOptions, MonoCloudUser, Prompt } from "@monocloud/auth-node-core";
|
|
2
|
-
import { NextFetchEvent, NextMiddleware, NextRequest, NextResponse } from "next/server";
|
|
3
2
|
import { JSX } from "react";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult, NextApiHandler, NextApiRequest, NextApiResponse } from "next/types";
|
|
7
|
-
import { IncomingMessage, ServerResponse } from "node:http";
|
|
3
|
+
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
|
|
4
|
+
import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult, NextApiRequest, NextApiResponse } from "next/types";
|
|
8
5
|
import { ParsedUrlQuery } from "node:querystring";
|
|
9
6
|
|
|
10
7
|
//#region src/types.d.ts
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Context object passed to App Router API route handlers.
|
|
11
|
+
* Contains the dynamic route parameters.
|
|
12
|
+
*/
|
|
11
13
|
interface AppRouterContext {
|
|
12
14
|
params: Record<string, string | string[]>;
|
|
13
15
|
}
|
|
14
|
-
type NextAnyRequest = NextRequest | NextApiRequest | (IncomingMessage & {
|
|
15
|
-
cookies: NextApiRequestCookies;
|
|
16
|
-
});
|
|
17
|
-
type NextAnyResponse = NextApiResponse | AppRouterContext | NextResponse | ServerResponse;
|
|
18
16
|
/**
|
|
19
|
-
*
|
|
17
|
+
* Return type of `monoCloudAuth()` handler.
|
|
20
18
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* @param ctx - The AppRouterContext or NextResponse object representing the response context.
|
|
25
|
-
* @returns A promise of the result.
|
|
26
|
-
*/
|
|
27
|
-
(req: NextRequest, ctx: AppRouterContext | NextResponse): Promise<TResult>;
|
|
28
|
-
/**
|
|
29
|
-
* @param req - The Next.js API request object.
|
|
30
|
-
* @param res - The Next.js API response object.
|
|
31
|
-
* @returns A promise of the result.
|
|
32
|
-
*/
|
|
33
|
-
(req: NextApiRequest, res: NextApiResponse): Promise<TResult>;
|
|
34
|
-
/**
|
|
35
|
-
* @param req - The Next.js request object.
|
|
36
|
-
* @param res - The Next.js response object.
|
|
37
|
-
* @returns A promise of the result.
|
|
38
|
-
*/
|
|
39
|
-
(req: NextAnyRequest, res: NextAnyResponse): Promise<TResult>;
|
|
40
|
-
/**
|
|
41
|
-
* @returns A promise of the result.
|
|
42
|
-
*/
|
|
43
|
-
(): Promise<TResult>;
|
|
44
|
-
}
|
|
19
|
+
type MonoCloudAuthHandler = (req: Request | NextRequest | NextApiRequest, resOrCtx?: Response | NextResponse<any> | NextApiResponse<any> | AppRouterContext) => Promise<Response | NextResponse | void | any>;
|
|
20
|
+
/** Return type of Next.js middleware/proxy */
|
|
21
|
+
type NextMiddlewareResult = NextResponse | Response | null | undefined | void;
|
|
45
22
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
23
|
+
* Handler function triggered when a user is denied access in Next.js Middleware.
|
|
24
|
+
*
|
|
25
|
+
* @param request - The incoming Next.js request.
|
|
26
|
+
* @param event - The Next.js fetch event.
|
|
27
|
+
* @param user - The authenticated user object (if available).
|
|
28
|
+
* @returns A `NextMiddlewareResult` (e.g., a redirect or rewrite) or a Promise resolving to one.
|
|
48
29
|
*/
|
|
49
|
-
type FuncHandler<TResult, TOptions = any> = BaseFuncHandler<TResult> & {
|
|
50
|
-
/**
|
|
51
|
-
* @param req - The Next.js request object.
|
|
52
|
-
* @param ctx - The context object, which can be either an AppRouterContext or a NextResponse.
|
|
53
|
-
* @param options - Additional options passed to the function (optional).
|
|
54
|
-
* @returns A promise of the result.
|
|
55
|
-
*/
|
|
56
|
-
(req: NextRequest, ctx: AppRouterContext | NextResponse, options?: TOptions): Promise<TResult>;
|
|
57
|
-
/**
|
|
58
|
-
* @param req - The Next.js API request object.
|
|
59
|
-
* @param res - The Next.js API response object.
|
|
60
|
-
* @param options - Additional options passed to the function (optional).
|
|
61
|
-
* @returns A promise of the result.
|
|
62
|
-
*/
|
|
63
|
-
(req: NextApiRequest, res: NextApiResponse, options?: TOptions): Promise<TResult>;
|
|
64
|
-
/**
|
|
65
|
-
* @param req - The generic Next.js request object.
|
|
66
|
-
* @param res - The generic Next.js response object.
|
|
67
|
-
* @param options - Additional options passed to the function (optional).
|
|
68
|
-
* @returns A promise of the result.
|
|
69
|
-
*/
|
|
70
|
-
(req: NextAnyRequest, res: NextAnyResponse, options?: TOptions): Promise<TResult>;
|
|
71
|
-
/**
|
|
72
|
-
* @param options - Additional options passed to the function (optional).
|
|
73
|
-
* @returns A promise of the result.
|
|
74
|
-
*/
|
|
75
|
-
(options?: TOptions): Promise<TResult>;
|
|
76
|
-
};
|
|
77
30
|
type NextMiddlewareOnAccessDenied = (request: NextRequest, event: NextFetchEvent, user?: MonoCloudUser) => NextMiddlewareResult | Promise<NextMiddlewareResult>;
|
|
78
31
|
/**
|
|
79
32
|
*
|
|
@@ -163,38 +116,25 @@ interface MonoCloudMiddlewareOptions {
|
|
|
163
116
|
onAccessDenied?: NextMiddlewareOnAccessDenied;
|
|
164
117
|
}
|
|
165
118
|
/**
|
|
166
|
-
* A
|
|
167
|
-
* This middleware function can be configured with options or directly invoked with request and event parameters.
|
|
119
|
+
* A subset of authorization parameters used on client side functions
|
|
168
120
|
*/
|
|
169
|
-
interface MonoCloudMiddleware {
|
|
170
|
-
/**
|
|
171
|
-
* A middleware that protects pages and apis and handles authentication.
|
|
172
|
-
*
|
|
173
|
-
* @param options - Options to configure the MonoCloud authentication middleware.
|
|
174
|
-
* @returns A Next.js middleware function.
|
|
175
|
-
*/
|
|
176
|
-
(options?: MonoCloudMiddlewareOptions): NextMiddleware;
|
|
177
|
-
/**
|
|
178
|
-
* A middleware that protects pages and apis and handles authentication.
|
|
179
|
-
*
|
|
180
|
-
* @returns A promise resolving to a Next.js middleware result or a Next.js middleware result.
|
|
181
|
-
*/
|
|
182
|
-
(
|
|
183
|
-
/**
|
|
184
|
-
* The Next.js request object.
|
|
185
|
-
*/
|
|
186
|
-
request: NextRequest,
|
|
187
|
-
/**
|
|
188
|
-
* The Next.js fetch event object.
|
|
189
|
-
*/
|
|
190
|
-
event: NextFetchEvent): Promise<NextMiddlewareResult> | NextMiddlewareResult;
|
|
191
|
-
}
|
|
192
121
|
type ExtraAuthParams = Pick<AuthorizationParams, 'scopes' | 'resource' | 'prompt' | 'display' | 'uiLocales' | 'acrValues' | 'authenticatorHint' | 'maxAge' | 'loginHint'>;
|
|
122
|
+
/**
|
|
123
|
+
* Represents a Next.js App Router React Server Component.
|
|
124
|
+
*
|
|
125
|
+
* @param props - The props object containing `params` and `searchParams`.
|
|
126
|
+
*
|
|
127
|
+
* @returns A JSX Element or a Promise resolving to one.
|
|
128
|
+
*/
|
|
193
129
|
type AppRouterPageHandler = (props: {
|
|
194
130
|
params?: Record<string, string | string[]>;
|
|
195
131
|
searchParams?: Record<string, string | string[] | undefined>;
|
|
196
132
|
}) => Promise<JSX.Element> | JSX.Element;
|
|
197
|
-
|
|
133
|
+
/** App Router API Route Handler */
|
|
134
|
+
type AppRouterApiHandlerFn = (req: NextRequest | Request, ctx: AppRouterContext) => Promise<Response | NextResponse> | Response | NextResponse;
|
|
135
|
+
/**
|
|
136
|
+
* Options for configuring `protectPage()` in the App Router.
|
|
137
|
+
*/
|
|
198
138
|
type ProtectAppPageOptions = {
|
|
199
139
|
/**
|
|
200
140
|
* The URL to return to after authentication.
|
|
@@ -213,6 +153,12 @@ type ProtectAppPageOptions = {
|
|
|
213
153
|
*/
|
|
214
154
|
authParams?: ExtraAuthParams;
|
|
215
155
|
} & GroupOptions;
|
|
156
|
+
/**
|
|
157
|
+
* Options for configuring `protectPage()` in the Pages Router.
|
|
158
|
+
*
|
|
159
|
+
* @typeParam P - The type of the props returned by `getServerSideProps`.
|
|
160
|
+
* @typeParam Q - The type of the parsed query object.
|
|
161
|
+
*/
|
|
216
162
|
type ProtectPagePageOptions<P extends Record<string, any> = Record<string, any>, Q extends ParsedUrlQuery = ParsedUrlQuery> = {
|
|
217
163
|
/**
|
|
218
164
|
* Function to fetch server-side props for the protected page handler.
|
|
@@ -235,77 +181,78 @@ type ProtectPagePageOptions<P extends Record<string, any> = Record<string, any>,
|
|
|
235
181
|
*/
|
|
236
182
|
authParams?: ExtraAuthParams;
|
|
237
183
|
} & GroupOptions;
|
|
184
|
+
/**
|
|
185
|
+
* Handler function triggered when a user is denied access in a Pages Router `getServerSideProps` flow.
|
|
186
|
+
*
|
|
187
|
+
* @typeParam P - The type of the props.
|
|
188
|
+
* @typeParam Q - The type of the parsed query object.
|
|
189
|
+
*
|
|
190
|
+
* @param context - The server-side props context extended with the optional user object.
|
|
191
|
+
*
|
|
192
|
+
* @returns The result for `getServerSideProps`.
|
|
193
|
+
*/
|
|
238
194
|
type ProtectPagePageOnAccessDeniedType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q> & {
|
|
239
195
|
user?: MonoCloudUser;
|
|
240
196
|
}) => Promise<GetServerSidePropsResult<P>> | GetServerSidePropsResult<P>;
|
|
241
|
-
type ProtectPagePageReturnType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q>) => Promise<GetServerSidePropsResult<P & {
|
|
242
|
-
user: MonoCloudUser;
|
|
243
|
-
}>>;
|
|
244
197
|
/**
|
|
245
|
-
*
|
|
246
|
-
*
|
|
198
|
+
* The return type of the `protectPage()` wrapper for Pages Router.
|
|
199
|
+
* It returns a function compatible with `getServerSideProps` that injects the user into props.
|
|
247
200
|
*
|
|
248
|
-
* @
|
|
249
|
-
* @
|
|
250
|
-
* @returns Protected page handler function.
|
|
251
|
-
*/
|
|
252
|
-
type ProtectPagePage = <P extends Record<string, any> = Record<string, any>, Q extends ParsedUrlQuery = ParsedUrlQuery>(
|
|
253
|
-
/**
|
|
254
|
-
* Protection options
|
|
255
|
-
*/
|
|
256
|
-
options?: ProtectPagePageOptions<P, Q>) => ProtectPagePageReturnType<P, Q>;
|
|
257
|
-
/**
|
|
258
|
-
* Type definition for protecting a server rendered AppRouter page handler function.
|
|
201
|
+
* @typeParam P - The type of the props.
|
|
202
|
+
* @typeParam Q - The type of the parsed query object.
|
|
259
203
|
*
|
|
260
|
-
* @returns
|
|
204
|
+
* @returns `GetServerSidePropsResult` with user injected
|
|
261
205
|
*/
|
|
262
|
-
type
|
|
206
|
+
type ProtectPagePageReturnType<P, Q extends ParsedUrlQuery = ParsedUrlQuery> = (context: GetServerSidePropsContext<Q>) => Promise<GetServerSidePropsResult<P & {
|
|
207
|
+
user: MonoCloudUser;
|
|
208
|
+
accessDenied?: boolean;
|
|
209
|
+
}>>;
|
|
263
210
|
/**
|
|
264
|
-
* The component
|
|
211
|
+
* The App Router server component that protectPage wraps and secures
|
|
265
212
|
*/
|
|
266
|
-
|
|
213
|
+
type ProtectedAppServerComponent = (props: {
|
|
267
214
|
user: MonoCloudUser;
|
|
268
215
|
params?: Record<string, string | string[]>;
|
|
269
216
|
searchParams?: Record<string, string | string[] | undefined>;
|
|
270
|
-
}) => Promise<JSX.Element> | JSX.Element
|
|
271
|
-
/**
|
|
272
|
-
* Protection options
|
|
273
|
-
*/
|
|
274
|
-
options?: ProtectAppPageOptions) => AppRouterPageHandler;
|
|
217
|
+
}) => Promise<JSX.Element> | JSX.Element;
|
|
275
218
|
/**
|
|
276
|
-
*
|
|
219
|
+
* Handler function triggered when a user is denied access in an App Router API route.
|
|
220
|
+
*
|
|
221
|
+
* @param req - The incoming Next.js request.
|
|
222
|
+
* @param ctx - The App Router context.
|
|
223
|
+
*
|
|
224
|
+
* @param user - The authenticated user object (if available).
|
|
225
|
+
*
|
|
226
|
+
* @returns A Response/NextResponse or Promise resolving to one.
|
|
277
227
|
*/
|
|
278
|
-
type
|
|
279
|
-
|
|
228
|
+
type AppRouterApiOnAccessDeniedHandler = (req: NextRequest, ctx: AppRouterContext, user?: MonoCloudUser) => Promise<Response> | Response;
|
|
229
|
+
/** Options for App Router `protectApi()` */
|
|
280
230
|
type ProtectApiAppOptions = {
|
|
281
231
|
/**
|
|
282
232
|
* Alternate app router api handler called when the user is not authenticated or is not a member of the specified groups.
|
|
283
233
|
*/
|
|
284
|
-
onAccessDenied?:
|
|
234
|
+
onAccessDenied?: AppRouterApiOnAccessDeniedHandler;
|
|
285
235
|
} & GroupOptions;
|
|
286
|
-
|
|
287
|
-
|
|
236
|
+
/**
|
|
237
|
+
* Handler function triggered when a user is denied access in a Pages Router API route.
|
|
238
|
+
*
|
|
239
|
+
* @param req - The incoming Next.js API request.
|
|
240
|
+
* @param res - The Next.js API response.
|
|
241
|
+
* @param user - The authenticated user object (if available).
|
|
242
|
+
*
|
|
243
|
+
* @returns
|
|
244
|
+
*/
|
|
245
|
+
type PageRouterApiOnAccessDeniedHandler = (req: NextApiRequest, res: NextApiResponse<any>, user?: MonoCloudUser) => Promise<unknown> | unknown;
|
|
246
|
+
/** Options for Page Router `protectApi()` */
|
|
288
247
|
type ProtectApiPageOptions = {
|
|
289
248
|
/**
|
|
290
249
|
* Alternate page router api handler called when the user is not authenticated or is not a member of the specified groups.
|
|
291
250
|
*/
|
|
292
|
-
onAccessDenied?:
|
|
251
|
+
onAccessDenied?: PageRouterApiOnAccessDeniedHandler;
|
|
293
252
|
} & GroupOptions;
|
|
294
|
-
type ProtectPageApi = (req: NextApiRequest, res: NextApiResponse, handler: NextApiHandler, options?: ProtectApiPageOptions) => Promise<unknown>;
|
|
295
|
-
type ProtectApiPage = (
|
|
296
253
|
/**
|
|
297
|
-
*
|
|
254
|
+
* Options for the `protect()` helper function.
|
|
298
255
|
*/
|
|
299
|
-
handler: NextApiHandler, options?: ProtectApiPageOptions) => NextApiHandler;
|
|
300
|
-
type ProtectApiApp = (
|
|
301
|
-
/**
|
|
302
|
-
* The api route handler function to protect
|
|
303
|
-
*/
|
|
304
|
-
handler: AppRouterApiHandlerFn, options?: ProtectApiAppOptions) => AppRouterApiHandlerFn;
|
|
305
|
-
/**
|
|
306
|
-
* Protects an api route handler.
|
|
307
|
-
*/
|
|
308
|
-
type ProtectApi = ProtectApiApp & ProtectApiPage;
|
|
309
256
|
type ProtectOptions = {
|
|
310
257
|
/**
|
|
311
258
|
* The url where the user will be redirected to after sign in.
|
|
@@ -317,11 +264,8 @@ type ProtectOptions = {
|
|
|
317
264
|
authParams?: ExtraAuthParams;
|
|
318
265
|
} & GroupOptions;
|
|
319
266
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
* @param options - The Protect options
|
|
267
|
+
* Configuration options for checking if a user belongs to specific groups.
|
|
323
268
|
*/
|
|
324
|
-
type Protect = (options?: ProtectOptions) => Promise<void>;
|
|
325
269
|
interface IsUserInGroupOptions {
|
|
326
270
|
/**
|
|
327
271
|
* The name of the groups claim in the user profile. Default: `groups`.
|
|
@@ -332,6 +276,9 @@ interface IsUserInGroupOptions {
|
|
|
332
276
|
*/
|
|
333
277
|
matchAll?: boolean;
|
|
334
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Extended configuration options that include a list of required groups.
|
|
281
|
+
*/
|
|
335
282
|
interface GroupOptions extends IsUserInGroupOptions {
|
|
336
283
|
/**
|
|
337
284
|
* A list of group IDs or names specifying the groups the user must belong to.
|
|
@@ -396,7 +343,9 @@ interface RedirectToSignOutOptions {
|
|
|
396
343
|
* The url authorization server should redirect the user to after a successful sign out. This url has to be registered in the client's sign out url section.
|
|
397
344
|
*/
|
|
398
345
|
postLogoutRedirectUri?: string;
|
|
346
|
+
/** Whether to also sign out the user from MonoCloud */
|
|
347
|
+
federated?: boolean;
|
|
399
348
|
}
|
|
400
349
|
//#endregion
|
|
401
|
-
export {
|
|
402
|
-
//# sourceMappingURL=types-
|
|
350
|
+
export { ProtectPagePageOptions as _, GroupOptions as a, RedirectToSignInOptions as b, MonoCloudAuthOptions as c, PageRouterApiOnAccessDeniedHandler as d, ProtectApiAppOptions as f, ProtectPagePageOnAccessDeniedType as g, ProtectOptions as h, ExtraAuthParams as i, MonoCloudMiddlewareOptions as l, ProtectAppPageOptions as m, AppRouterApiOnAccessDeniedHandler as n, IsUserInGroupOptions as o, ProtectApiPageOptions as p, AppRouterPageHandler as r, MonoCloudAuthHandler as s, AppRouterApiHandlerFn as t, NextMiddlewareResult as u, ProtectPagePageReturnType as v, RedirectToSignOutOptions as x, ProtectedAppServerComponent as y };
|
|
351
|
+
//# sourceMappingURL=types-DOfZTKa6.d.mts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monocloud/auth-nextjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "MonoCloud Next.js Authentication SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"monocloud",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"cookie": "1.1.1",
|
|
59
59
|
"swr": "2.3.8",
|
|
60
|
-
"@monocloud/auth-node-core": "0.1.
|
|
60
|
+
"@monocloud/auth-node-core": "0.1.2"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@edge-runtime/vm": "5.0.0",
|
package/dist/client-0gaUvMR7.mjs
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { isUserInGroup } from "@monocloud/auth-node-core/utils";
|
|
2
|
-
import useSWR from "swr";
|
|
3
|
-
import React, { useEffect } from "react";
|
|
4
|
-
|
|
5
|
-
//#region src/client/use-auth.tsx
|
|
6
|
-
/**
|
|
7
|
-
* @returns Authentication State
|
|
8
|
-
*/
|
|
9
|
-
const useAuth = () => {
|
|
10
|
-
const { data, error, isLoading, mutate } = useSWR(process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/userinfo`, async (url) => {
|
|
11
|
-
const res = await fetch(url, { credentials: "include" });
|
|
12
|
-
if (res.status === 204) return;
|
|
13
|
-
if (res.ok) return res.json();
|
|
14
|
-
throw new Error("Failed to fetch user");
|
|
15
|
-
});
|
|
16
|
-
if (error) return {
|
|
17
|
-
user: void 0,
|
|
18
|
-
isLoading: false,
|
|
19
|
-
isAuthenticated: false,
|
|
20
|
-
error,
|
|
21
|
-
refetch: () => mutate()
|
|
22
|
-
};
|
|
23
|
-
if (data) return {
|
|
24
|
-
user: data,
|
|
25
|
-
isLoading,
|
|
26
|
-
isAuthenticated: !!data && Object.keys(data).length > 0,
|
|
27
|
-
error: void 0,
|
|
28
|
-
refetch: () => mutate()
|
|
29
|
-
};
|
|
30
|
-
return {
|
|
31
|
-
user: void 0,
|
|
32
|
-
isLoading,
|
|
33
|
-
isAuthenticated: false,
|
|
34
|
-
error: void 0,
|
|
35
|
-
refetch: () => {}
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
//#endregion
|
|
40
|
-
//#region src/client/protect.tsx
|
|
41
|
-
const redirectToSignIn = (options) => {
|
|
42
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
43
|
-
searchParams.set("return_url", options.returnUrl ?? window.location.toString());
|
|
44
|
-
if (options === null || options === void 0 ? void 0 : options.scopes) searchParams.set("scope", options.scopes);
|
|
45
|
-
if (options === null || options === void 0 ? void 0 : options.resource) searchParams.set("resource", options.resource);
|
|
46
|
-
if (options === null || options === void 0 ? void 0 : options.acrValues) searchParams.set("acr_values", options.acrValues.join(" "));
|
|
47
|
-
if (options === null || options === void 0 ? void 0 : options.display) searchParams.set("display", options.display);
|
|
48
|
-
if (options === null || options === void 0 ? void 0 : options.prompt) searchParams.set("prompt", options.prompt);
|
|
49
|
-
if (options === null || options === void 0 ? void 0 : options.authenticatorHint) searchParams.set("authenticator_hint", options.authenticatorHint);
|
|
50
|
-
if (options === null || options === void 0 ? void 0 : options.uiLocales) searchParams.set("ui_locales", options.uiLocales);
|
|
51
|
-
if (options === null || options === void 0 ? void 0 : options.maxAge) searchParams.set("max_age", options.maxAge.toString());
|
|
52
|
-
if (options === null || options === void 0 ? void 0 : options.loginHint) searchParams.set("login_hint", options.loginHint);
|
|
53
|
-
window.location.assign(`${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/api/auth/signin`}?${searchParams.toString()}`);
|
|
54
|
-
};
|
|
55
|
-
const handlePageError = (error, options) => {
|
|
56
|
-
/* v8 ignore else -- @preserve */
|
|
57
|
-
if (options === null || options === void 0 ? void 0 : options.onError) return options.onError(error);
|
|
58
|
-
/* v8 ignore next -- @preserve */
|
|
59
|
-
throw error;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* Function to protect a client rendered page component.
|
|
63
|
-
* Ensures that only authenticated users can access the component.
|
|
64
|
-
*
|
|
65
|
-
* @param Component - The component to protect.
|
|
66
|
-
* @param options - The options.
|
|
67
|
-
*
|
|
68
|
-
* @returns Protected clinet rendered page component.
|
|
69
|
-
*/
|
|
70
|
-
const protectPage = (Component, options) => {
|
|
71
|
-
return (props) => {
|
|
72
|
-
const { user, error, isLoading } = useAuth();
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
if (!user && !isLoading && !error) {
|
|
75
|
-
if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return;
|
|
76
|
-
const authParams = (options === null || options === void 0 ? void 0 : options.authParams) ?? {};
|
|
77
|
-
redirectToSignIn({
|
|
78
|
-
returnUrl: options === null || options === void 0 ? void 0 : options.returnUrl,
|
|
79
|
-
...authParams
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}, [
|
|
83
|
-
user,
|
|
84
|
-
isLoading,
|
|
85
|
-
error
|
|
86
|
-
]);
|
|
87
|
-
if (error) return handlePageError(error, options);
|
|
88
|
-
if (!user && !isLoading && (options === null || options === void 0 ? void 0 : options.onAccessDenied)) return options.onAccessDenied();
|
|
89
|
-
if (user) {
|
|
90
|
-
if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(user, options.groups, options.groupsClaim ?? process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
|
|
91
|
-
const { onAccessDenied = () => /* @__PURE__ */ React.createElement("div", null, "Access Denied") } = options;
|
|
92
|
-
return onAccessDenied(user);
|
|
93
|
-
}
|
|
94
|
-
return /* @__PURE__ */ React.createElement(Component, {
|
|
95
|
-
user,
|
|
96
|
-
...props
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
//#endregion
|
|
104
|
-
export { redirectToSignIn as n, useAuth as r, protectPage as t };
|
|
105
|
-
//# sourceMappingURL=client-0gaUvMR7.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-0gaUvMR7.mjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport { MonoCloudUser } from '@monocloud/auth-node-core';\nimport useSWR from 'swr';\n\n/**\n * Authentication State returned by `useAuth` hook.\n */\nexport interface AuthState {\n /**\n * Flag indicating if the authentication state is still loading.\n */\n isLoading: boolean;\n /**\n * Flag indicating if the user is authenticated.\n */\n isAuthenticated: boolean;\n /**\n * Error encountered during authentication, if any.\n */\n error?: Error;\n /**\n * The authenticated user's information, if available.\n */\n user?: MonoCloudUser;\n /**\n * Function to refetch the authentication state.\n */\n refetch?: () => void;\n}\n\n/**\n * @returns Authentication State\n */\nexport const useAuth = (): AuthState => {\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ??\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/userinfo`,\n async (url: string) => {\n const res = await fetch(url, { credentials: 'include' });\n\n if (res.status === 204) {\n return undefined;\n }\n\n if (res.ok) {\n return res.json();\n }\n\n throw new Error('Failed to fetch user');\n }\n );\n\n if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch: () => mutate(),\n };\n }\n\n if (data) {\n return {\n user: data,\n isLoading,\n isAuthenticated: !!data && Object.keys(data).length > 0,\n error: undefined,\n refetch: () => mutate(),\n };\n }\n\n return {\n user: undefined,\n isLoading,\n isAuthenticated: false,\n error: undefined,\n /* v8 ignore next -- @preserve */\n refetch: (): void => {},\n };\n};\n","/* eslint-disable react/display-name */\n'use client';\n\nimport React, { ComponentType, JSX, useEffect } from 'react';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport { useAuth } from './use-auth';\nimport { ExtraAuthParams, GroupOptions } from '../types';\n\n/**\n * Options for configuring page protection.\n */\nexport type ProtectPageOptions = {\n /**\n *The url where the user will be redirected to after sign in\n */\n returnUrl?: string;\n\n /**\n * A custom react element to render when the user is not authenticated or is not a member of the specified groups.\n */\n onAccessDenied?: (user?: MonoCloudUser) => JSX.Element;\n\n /**\n * Authorization parameters to be used during authentication.\n */\n authParams?: ExtraAuthParams;\n\n /**\n * Callback function to handle errors.\n * If not provided, errors will be thrown.\n *\n * @param error - The error object.\n * @returns JSX element to handle the error.\n */\n onError?: (error: Error) => JSX.Element;\n} & GroupOptions;\n\nexport const redirectToSignIn = (\n options: { returnUrl?: string } & ExtraAuthParams\n): void => {\n const searchParams = new URLSearchParams(window.location.search);\n searchParams.set(\n 'return_url',\n options.returnUrl ?? window.location.toString()\n );\n\n if (options?.scopes) {\n searchParams.set('scope', options.scopes);\n }\n if (options?.resource) {\n searchParams.set('resource', options.resource);\n }\n\n if (options?.acrValues) {\n searchParams.set('acr_values', options.acrValues.join(' '));\n }\n\n if (options?.display) {\n searchParams.set('display', options.display);\n }\n\n if (options?.prompt) {\n searchParams.set('prompt', options.prompt);\n }\n\n if (options?.authenticatorHint) {\n searchParams.set('authenticator_hint', options.authenticatorHint);\n }\n\n if (options?.uiLocales) {\n searchParams.set('ui_locales', options.uiLocales);\n }\n\n if (options?.maxAge) {\n searchParams.set('max_age', options.maxAge.toString());\n }\n\n if (options?.loginHint) {\n searchParams.set('login_hint', options.loginHint);\n }\n\n window.location.assign(\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`}?${searchParams.toString()}`\n );\n};\n\nconst handlePageError = (\n error: Error,\n options?: ProtectPageOptions\n): JSX.Element => {\n /* v8 ignore else -- @preserve */\n if (options?.onError) {\n return options.onError(error);\n }\n\n /* v8 ignore next -- @preserve */\n throw error;\n};\n\n/**\n * Function to protect a client rendered page component.\n * Ensures that only authenticated users can access the component.\n *\n * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected clinet rendered page component.\n */\nexport const protectPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectPageOptions\n): React.FC<P> => {\n return props => {\n const { user, error, isLoading } = useAuth();\n\n useEffect(() => {\n if (!user && !isLoading && !error) {\n if (options?.onAccessDenied) {\n return;\n }\n\n const authParams = options?.authParams ?? {};\n redirectToSignIn({\n returnUrl: options?.returnUrl,\n ...authParams,\n });\n }\n }, [user, isLoading, error]);\n\n if (error) {\n return handlePageError(error, options);\n }\n\n if (!user && !isLoading && options?.onAccessDenied) {\n return options.onAccessDenied();\n }\n\n if (user) {\n if (\n options?.groups &&\n !isUserInGroup(\n user,\n options.groups,\n options.groupsClaim ??\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n options.matchAll\n )\n ) {\n const { onAccessDenied = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return onAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;AAkCA,MAAa,gBAA2B;CACtC,MAAM,EAAE,MAAM,OAAO,WAAW,WAAW,OACzC,QAAQ,IAAI,4CAEV,GAAG,QAAQ,IAAI,0BAA0B,GAAG,qBAC9C,OAAO,QAAgB;EACrB,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,MAAI,IAAI,WAAW,IACjB;AAGF,MAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,QAAM,IAAI,MAAM,uBAAuB;GAE1C;AAED,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP,eAAe,QAAQ;EACxB;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP,eAAe,QAAQ;EACxB;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;AC3CH,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAChE,cAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,UAAU,CAChD;AAED,uDAAI,QAAS,OACX,cAAa,IAAI,SAAS,QAAQ,OAAO;AAE3C,uDAAI,QAAS,SACX,cAAa,IAAI,YAAY,QAAQ,SAAS;AAGhD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,IAAI,CAAC;AAG7D,uDAAI,QAAS,QACX,cAAa,IAAI,WAAW,QAAQ,QAAQ;AAG9C,uDAAI,QAAS,OACX,cAAa,IAAI,UAAU,QAAQ,OAAO;AAG5C,uDAAI,QAAS,kBACX,cAAa,IAAI,sBAAsB,QAAQ,kBAAkB;AAGnE,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,uDAAI,QAAS,OACX,cAAa,IAAI,WAAW,QAAQ,OAAO,UAAU,CAAC;AAGxD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,QAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,UAAU,GACjJ;;AAGH,MAAM,mBACJ,OACA,YACgB;;AAEhB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;AAYR,MAAa,eACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,SAAS;AAE5C,kBAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,CAAC,cACC,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EAAE,uBAAoC,oCAAC,aAAI,gBAAmB,KAClE;AACF,WAAO,eAAe,KAAK;;AAG7B,UAAO,oCAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-BjnSJS59.cjs","names":[],"sources":["../src/client/use-auth.tsx","../src/client/protect.tsx"],"sourcesContent":["'use client';\n\nimport { MonoCloudUser } from '@monocloud/auth-node-core';\nimport useSWR from 'swr';\n\n/**\n * Authentication State returned by `useAuth` hook.\n */\nexport interface AuthState {\n /**\n * Flag indicating if the authentication state is still loading.\n */\n isLoading: boolean;\n /**\n * Flag indicating if the user is authenticated.\n */\n isAuthenticated: boolean;\n /**\n * Error encountered during authentication, if any.\n */\n error?: Error;\n /**\n * The authenticated user's information, if available.\n */\n user?: MonoCloudUser;\n /**\n * Function to refetch the authentication state.\n */\n refetch?: () => void;\n}\n\n/**\n * @returns Authentication State\n */\nexport const useAuth = (): AuthState => {\n const { data, error, isLoading, mutate } = useSWR<MonoCloudUser | undefined>(\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_USER_INFO_URL ??\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/userinfo`,\n async (url: string) => {\n const res = await fetch(url, { credentials: 'include' });\n\n if (res.status === 204) {\n return undefined;\n }\n\n if (res.ok) {\n return res.json();\n }\n\n throw new Error('Failed to fetch user');\n }\n );\n\n if (error) {\n return {\n user: undefined,\n isLoading: false,\n isAuthenticated: false,\n error: error as Error,\n refetch: () => mutate(),\n };\n }\n\n if (data) {\n return {\n user: data,\n isLoading,\n isAuthenticated: !!data && Object.keys(data).length > 0,\n error: undefined,\n refetch: () => mutate(),\n };\n }\n\n return {\n user: undefined,\n isLoading,\n isAuthenticated: false,\n error: undefined,\n /* v8 ignore next -- @preserve */\n refetch: (): void => {},\n };\n};\n","/* eslint-disable react/display-name */\n'use client';\n\nimport React, { ComponentType, JSX, useEffect } from 'react';\nimport type { MonoCloudUser } from '@monocloud/auth-node-core';\nimport { isUserInGroup } from '@monocloud/auth-node-core/utils';\nimport { useAuth } from './use-auth';\nimport { ExtraAuthParams, GroupOptions } from '../types';\n\n/**\n * Options for configuring page protection.\n */\nexport type ProtectPageOptions = {\n /**\n *The url where the user will be redirected to after sign in\n */\n returnUrl?: string;\n\n /**\n * A custom react element to render when the user is not authenticated or is not a member of the specified groups.\n */\n onAccessDenied?: (user?: MonoCloudUser) => JSX.Element;\n\n /**\n * Authorization parameters to be used during authentication.\n */\n authParams?: ExtraAuthParams;\n\n /**\n * Callback function to handle errors.\n * If not provided, errors will be thrown.\n *\n * @param error - The error object.\n * @returns JSX element to handle the error.\n */\n onError?: (error: Error) => JSX.Element;\n} & GroupOptions;\n\nexport const redirectToSignIn = (\n options: { returnUrl?: string } & ExtraAuthParams\n): void => {\n const searchParams = new URLSearchParams(window.location.search);\n searchParams.set(\n 'return_url',\n options.returnUrl ?? window.location.toString()\n );\n\n if (options?.scopes) {\n searchParams.set('scope', options.scopes);\n }\n if (options?.resource) {\n searchParams.set('resource', options.resource);\n }\n\n if (options?.acrValues) {\n searchParams.set('acr_values', options.acrValues.join(' '));\n }\n\n if (options?.display) {\n searchParams.set('display', options.display);\n }\n\n if (options?.prompt) {\n searchParams.set('prompt', options.prompt);\n }\n\n if (options?.authenticatorHint) {\n searchParams.set('authenticator_hint', options.authenticatorHint);\n }\n\n if (options?.uiLocales) {\n searchParams.set('ui_locales', options.uiLocales);\n }\n\n if (options?.maxAge) {\n searchParams.set('max_age', options.maxAge.toString());\n }\n\n if (options?.loginHint) {\n searchParams.set('login_hint', options.loginHint);\n }\n\n window.location.assign(\n // eslint-disable-next-line no-underscore-dangle\n `${process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_SIGNIN_URL ?? `${process.env.__NEXT_ROUTER_BASEPATH ?? ''}/api/auth/signin`}?${searchParams.toString()}`\n );\n};\n\nconst handlePageError = (\n error: Error,\n options?: ProtectPageOptions\n): JSX.Element => {\n /* v8 ignore else -- @preserve */\n if (options?.onError) {\n return options.onError(error);\n }\n\n /* v8 ignore next -- @preserve */\n throw error;\n};\n\n/**\n * Function to protect a client rendered page component.\n * Ensures that only authenticated users can access the component.\n *\n * @param Component - The component to protect.\n * @param options - The options.\n *\n * @returns Protected clinet rendered page component.\n */\nexport const protectPage = <P extends object>(\n Component: ComponentType<P & { user: MonoCloudUser }>,\n options?: ProtectPageOptions\n): React.FC<P> => {\n return props => {\n const { user, error, isLoading } = useAuth();\n\n useEffect(() => {\n if (!user && !isLoading && !error) {\n if (options?.onAccessDenied) {\n return;\n }\n\n const authParams = options?.authParams ?? {};\n redirectToSignIn({\n returnUrl: options?.returnUrl,\n ...authParams,\n });\n }\n }, [user, isLoading, error]);\n\n if (error) {\n return handlePageError(error, options);\n }\n\n if (!user && !isLoading && options?.onAccessDenied) {\n return options.onAccessDenied();\n }\n\n if (user) {\n if (\n options?.groups &&\n !isUserInGroup(\n user,\n options.groups,\n options.groupsClaim ??\n process.env.NEXT_PUBLIC_MONOCLOUD_AUTH_GROUPS_CLAIM,\n options.matchAll\n )\n ) {\n const { onAccessDenied = (): JSX.Element => <div>Access Denied</div> } =\n options;\n return onAccessDenied(user);\n }\n\n return <Component user={user} {...props} />;\n }\n\n return null;\n };\n};\n"],"mappings":";;;;;;;;;;;AAkCA,MAAa,gBAA2B;CACtC,MAAM,EAAE,MAAM,OAAO,WAAW,4BAC9B,QAAQ,IAAI,4CAEV,GAAG,QAAQ,IAAI,0BAA0B,GAAG,qBAC9C,OAAO,QAAgB;EACrB,MAAM,MAAM,MAAM,MAAM,KAAK,EAAE,aAAa,WAAW,CAAC;AAExD,MAAI,IAAI,WAAW,IACjB;AAGF,MAAI,IAAI,GACN,QAAO,IAAI,MAAM;AAGnB,QAAM,IAAI,MAAM,uBAAuB;GAE1C;AAED,KAAI,MACF,QAAO;EACL,MAAM;EACN,WAAW;EACX,iBAAiB;EACV;EACP,eAAe,QAAQ;EACxB;AAGH,KAAI,KACF,QAAO;EACL,MAAM;EACN;EACA,iBAAiB,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;EACtD,OAAO;EACP,eAAe,QAAQ;EACxB;AAGH,QAAO;EACL,MAAM;EACN;EACA,iBAAiB;EACjB,OAAO;EAEP,eAAqB;EACtB;;;;;AC3CH,MAAa,oBACX,YACS;CACT,MAAM,eAAe,IAAI,gBAAgB,OAAO,SAAS,OAAO;AAChE,cAAa,IACX,cACA,QAAQ,aAAa,OAAO,SAAS,UAAU,CAChD;AAED,uDAAI,QAAS,OACX,cAAa,IAAI,SAAS,QAAQ,OAAO;AAE3C,uDAAI,QAAS,SACX,cAAa,IAAI,YAAY,QAAQ,SAAS;AAGhD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU,KAAK,IAAI,CAAC;AAG7D,uDAAI,QAAS,QACX,cAAa,IAAI,WAAW,QAAQ,QAAQ;AAG9C,uDAAI,QAAS,OACX,cAAa,IAAI,UAAU,QAAQ,OAAO;AAG5C,uDAAI,QAAS,kBACX,cAAa,IAAI,sBAAsB,QAAQ,kBAAkB;AAGnE,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,uDAAI,QAAS,OACX,cAAa,IAAI,WAAW,QAAQ,OAAO,UAAU,CAAC;AAGxD,uDAAI,QAAS,UACX,cAAa,IAAI,cAAc,QAAQ,UAAU;AAGnD,QAAO,SAAS,OAEd,GAAG,QAAQ,IAAI,yCAAyC,GAAG,QAAQ,IAAI,0BAA0B,GAAG,kBAAkB,GAAG,aAAa,UAAU,GACjJ;;AAGH,MAAM,mBACJ,OACA,YACgB;;AAEhB,uDAAI,QAAS,QACX,QAAO,QAAQ,QAAQ,MAAM;;AAI/B,OAAM;;;;;;;;;;;AAYR,MAAa,eACX,WACA,YACgB;AAChB,SAAO,UAAS;EACd,MAAM,EAAE,MAAM,OAAO,cAAc,SAAS;AAE5C,6BAAgB;AACd,OAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO;AACjC,0DAAI,QAAS,eACX;IAGF,MAAM,gEAAa,QAAS,eAAc,EAAE;AAC5C,qBAAiB;KACf,6DAAW,QAAS;KACpB,GAAG;KACJ,CAAC;;KAEH;GAAC;GAAM;GAAW;GAAM,CAAC;AAE5B,MAAI,MACF,QAAO,gBAAgB,OAAO,QAAQ;AAGxC,MAAI,CAAC,QAAQ,CAAC,gEAAa,QAAS,gBAClC,QAAO,QAAQ,gBAAgB;AAGjC,MAAI,MAAM;AACR,0DACE,QAAS,WACT,oDACE,MACA,QAAQ,QACR,QAAQ,eACN,QAAQ,IAAI,yCACd,QAAQ,SACT,EACD;IACA,MAAM,EAAE,uBAAoC,4CAAC,aAAI,gBAAmB,KAClE;AACF,WAAO,eAAe,KAAK;;AAG7B,UAAO,4CAAC;IAAgB;IAAM,GAAI;KAAS;;AAG7C,SAAO"}
|