@alepha/react 0.5.1 → 0.6.0

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.
@@ -1,25 +1,14 @@
1
1
  import * as _alepha_core from '@alepha/core';
2
- import { Static as Static$1, TSchema as TSchema$1, Async, KIND, EventEmitter, Alepha, ClassEntry, TObject as TObject$1 } from '@alepha/core';
2
+ import { EventEmitter, Alepha, TSchema as TSchema$1, Static as Static$1, Async, KIND, Class, TObject as TObject$1 } from '@alepha/core';
3
3
  import * as react from 'react';
4
- import { ReactNode, FC } from 'react';
4
+ import react__default, { ReactNode, AnchorHTMLAttributes, FC } from 'react';
5
+ import * as react_jsx_runtime from 'react/jsx-runtime';
6
+ import { UserAccountToken } from '@alepha/security';
5
7
  import * as _alepha_server from '@alepha/server';
6
- import { ServerProvider, HttpClient, ServeDescriptorOptions, RouteObject } from '@alepha/server';
7
- import * as _alepha_cache from '@alepha/cache';
8
- import { SecurityProvider, UserAccountToken, UserAccountInfo } from '@alepha/security';
9
- import { Configuration } from 'openid-client';
10
- import { MatchFunction, ParamData } from 'path-to-regexp';
8
+ import { FastifyCookieProvider, CookieManager, HttpClient, ServerProvider, ServeDescriptorOptions, CreateRoute } from '@alepha/server';
11
9
  import { Root } from 'react-dom/client';
12
-
13
- interface NestedViewProps {
14
- children?: ReactNode;
15
- }
16
- /**
17
- * Nested view component
18
- *
19
- * @param props
20
- * @constructor
21
- */
22
- declare const NestedView: (props: NestedViewProps) => string | number | boolean | react.ReactElement<any, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null;
10
+ import { MatchFunction, ParamData } from 'path-to-regexp';
11
+ import { Configuration } from 'openid-client';
23
12
 
24
13
  /** Symbol key applied to readonly types */
25
14
  declare const ReadonlyKind: unique symbol;
@@ -62,23 +51,23 @@ interface TBoolean extends TSchema {
62
51
  type: 'boolean';
63
52
  }
64
53
 
54
+ interface NumberOptions extends SchemaOptions {
55
+ exclusiveMaximum?: number;
56
+ exclusiveMinimum?: number;
57
+ maximum?: number;
58
+ minimum?: number;
59
+ multipleOf?: number;
60
+ }
61
+ interface TNumber extends TSchema, NumberOptions {
62
+ [Kind]: 'Number';
63
+ static: number;
64
+ type: 'number';
65
+ }
66
+
65
67
  type TOptional<T extends TSchema> = T & {
66
68
  [OptionalKind]: 'Optional';
67
69
  };
68
70
 
69
- type RecordStatic<Key extends TSchema, Type extends TSchema, P extends unknown[]> = (Evaluate<{
70
- [_ in Assert<Static<Key>, PropertyKey>]: Static<Type, P>;
71
- }>);
72
- interface TRecord<Key extends TSchema = TSchema, Type extends TSchema = TSchema> extends TSchema {
73
- [Kind]: 'Record';
74
- static: RecordStatic<Key, Type, this['params']>;
75
- type: 'object';
76
- patternProperties: {
77
- [pattern: string]: Type;
78
- };
79
- additionalProperties: TAdditionalProperties;
80
- }
81
-
82
71
  /** Creates a static type from a TypeBox type */
83
72
  type Static<Type extends TSchema, Params extends unknown[] = [], Result = (Type & {
84
73
  params: Params;
@@ -118,7 +107,6 @@ interface TObject<T extends TProperties = TProperties> extends TSchema, ObjectOp
118
107
  required?: string[];
119
108
  }
120
109
 
121
- type Assert<T, E> = T extends E ? T : never;
122
110
  type Evaluate<T> = T extends infer O ? {
123
111
  [K in keyof O]: O[K];
124
112
  } : never;
@@ -152,607 +140,728 @@ interface TSchema extends TKind, SchemaOptions {
152
140
  static: unknown;
153
141
  }
154
142
 
155
- declare const sessionUserSchema: _alepha_core.TObject<{
156
- id: TString;
157
- name: TOptional<TString>;
158
- }>;
159
- declare const sessionSchema: _alepha_core.TObject<{
160
- user: TOptional<_alepha_core.TObject<{
161
- id: TString;
162
- name: TOptional<TString>;
163
- }>>;
164
- }>;
165
- type Session = Static$1<typeof sessionSchema>;
166
- declare const envSchema$1: _alepha_core.TObject<{
167
- REACT_OIDC_ISSUER: TOptional<TString>;
168
- REACT_OIDC_CLIENT_ID: TOptional<TString>;
169
- REACT_OIDC_CLIENT_SECRET: TOptional<TString>;
170
- REACT_OIDC_REDIRECT_URI: TOptional<TString>;
171
- }>;
172
- declare module "fastify" {
173
- interface FastifyRequest {
174
- session?: ReactServerSession;
175
- }
143
+ interface NestedViewProps {
144
+ children?: ReactNode;
176
145
  }
177
- declare module "@alepha/core" {
178
- interface Env extends Partial<Static$1<typeof envSchema$1>> {
179
- }
146
+ /**
147
+ * Nested view component
148
+ *
149
+ * @param props
150
+ * @constructor
151
+ */
152
+ declare const NestedView: (props: NestedViewProps) => string | number | boolean | react.ReactElement<any, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null;
153
+
154
+ interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
155
+ to: string;
156
+ children?: react__default.ReactNode;
180
157
  }
181
- declare class ReactSessionProvider {
182
- protected readonly SSID = "ssid";
158
+ declare const Link: (props: LinkProps) => react_jsx_runtime.JSX.Element;
159
+
160
+ declare class Router extends EventEmitter<RouterEvents> {
183
161
  protected readonly log: _alepha_core.Logger;
184
- protected readonly env: {
185
- REACT_OIDC_ISSUER?: string | undefined;
186
- REACT_OIDC_CLIENT_ID?: string | undefined;
187
- REACT_OIDC_CLIENT_SECRET?: string | undefined;
188
- REACT_OIDC_REDIRECT_URI?: string | undefined;
189
- };
190
- protected readonly serverProvider: ServerProvider;
191
- protected readonly securityProvider: SecurityProvider;
192
- protected readonly sessions: _alepha_cache.CacheDescriptor<ReactServerSession, any[]>;
193
- protected clients: Configuration[];
194
- get redirectUri(): string;
195
- protected readonly configure: _alepha_core.HookDescriptor<"configure">;
162
+ protected readonly alepha: Alepha;
163
+ protected readonly pages: PageRoute[];
164
+ protected notFoundPageRoute?: PageRoute;
196
165
  /**
166
+ * Get the page by name.
197
167
  *
198
- * @param sessionId
199
- * @param session
200
- * @protected
168
+ * @param name - Page name
169
+ * @return PageRoute
201
170
  */
202
- protected setSession(sessionId: string, session: ReactServerSession): Promise<void>;
171
+ page(name: string): PageRoute;
203
172
  /**
204
173
  *
205
- * @param sessionId
206
- * @protected
207
174
  */
208
- protected getSession(sessionId: string): Promise<ReactServerSession | undefined>;
175
+ root(state: RouterState, context?: PageContext): ReactNode;
209
176
  /**
210
177
  *
211
- * @protected
178
+ * @param url
179
+ * @param options
212
180
  */
213
- protected readonly beforeRequest: _alepha_core.HookDescriptor<"configure:fastify">;
181
+ render(url: string, options?: RouterRenderOptions): Promise<RouterRenderResult>;
214
182
  /**
215
183
  *
184
+ * @param url
185
+ * @param options
186
+ * @param context
187
+ * @protected
216
188
  */
217
- readonly login: _alepha_server.RouteDescriptor<{
218
- query: _alepha_core.TObject<{
219
- redirect: TOptional<TString>;
220
- }>;
221
- }>;
189
+ match(url: string, options?: RouterMatchOptions, context?: RouterRenderContext): Promise<Layer[]>;
222
190
  /**
191
+ * Create layers for the given route.
223
192
  *
193
+ * @param url
194
+ * @param route
195
+ * @param params
196
+ * @param query
197
+ * @param previous
198
+ * @param args
199
+ * @param renderContext
200
+ * @protected
224
201
  */
225
- readonly callback: _alepha_server.RouteDescriptor<{
226
- headers: TRecord<TString, TString>;
227
- cookies: _alepha_core.TObject<{
228
- ssid: TString;
229
- }>;
230
- }>;
231
- readonly logout: _alepha_server.RouteDescriptor<{
232
- query: _alepha_core.TObject<{
233
- redirect: TOptional<TString>;
234
- }>;
235
- cookies: _alepha_core.TObject<{
236
- ssid: TString;
237
- }>;
238
- }>;
239
- readonly session: _alepha_server.RouteDescriptor<{
240
- headers: _alepha_core.TObject<{
241
- authorization: TString;
242
- }>;
243
- response: _alepha_core.TObject<{
244
- user: TOptional<_alepha_core.TObject<{
245
- id: TString;
246
- name: TOptional<TString>;
247
- }>>;
248
- }>;
249
- }>;
250
- }
251
- interface ReactServerSession {
252
- access_token?: string;
253
- expires_in?: number;
254
- refresh_token?: string;
255
- id_token?: string;
256
- scope?: string;
257
- issued_at?: number;
258
- authorizationCodeGrant?: {
259
- codeVerifier: string;
260
- redirectUri: string;
261
- nonce?: string;
262
- max_age?: number;
263
- state?: string;
264
- };
265
- }
266
-
267
- declare class ReactBrowserProvider {
268
- protected readonly log: _alepha_core.Logger;
269
- protected readonly client: HttpClient;
270
- protected readonly router: Router;
271
- protected root: Root;
272
- transitioning?: {
273
- to: string;
274
- };
275
- state: RouterState;
202
+ createLayers(url: string, route: PageRoute, params?: Record<string, any>, query?: Record<string, string>, previous?: PreviousLayerData[], args?: PageContext, renderContext?: RouterRenderContext): Promise<Layer[]>;
276
203
  /**
277
204
  *
205
+ * @param route
206
+ * @protected
278
207
  */
279
- get document(): Document;
208
+ protected getErrorHandler(route: PageRoute): react.FC<{
209
+ error: Error;
210
+ url: string;
211
+ }> | undefined;
280
212
  /**
281
213
  *
214
+ * @param page
215
+ * @param props
216
+ * @protected
282
217
  */
283
- get history(): History;
218
+ protected createElement(page: PageRoute, props: Record<string, any>): Promise<ReactNode>;
284
219
  /**
220
+ * Merge the render context with the page context.
285
221
  *
222
+ * @param page
223
+ * @param ctx
224
+ * @param props
225
+ * @protected
286
226
  */
287
- get url(): string;
227
+ protected mergeRenderContext(page: PageRoute, ctx: RouterRenderContext, props: Record<string, any>): void;
288
228
  /**
289
229
  *
290
- * @param props
230
+ * @param e
231
+ * @protected
291
232
  */
292
- invalidate(props?: Record<string, any>): Promise<void>;
233
+ protected renderError(e: Error): ReactNode;
293
234
  /**
235
+ * Render an empty view.
294
236
  *
295
- * @param url
296
- * @param options
237
+ * @protected
297
238
  */
298
- go(url: string, options?: RouterGoOptions): Promise<void>;
239
+ protected renderEmptyView(): ReactNode;
240
+ /**
241
+ * Create a valid href for the given page.
242
+ * @param page
243
+ * @param params
244
+ */
245
+ href(page: {
246
+ options: {
247
+ name?: string;
248
+ };
249
+ }, params?: Record<string, any>): string;
299
250
  /**
300
251
  *
301
- * @param options
252
+ * @param index
253
+ * @param path
254
+ * @param view
302
255
  * @protected
303
256
  */
304
- protected render(options?: {
305
- url?: string;
306
- previous?: PreviousLayerData[];
307
- }): Promise<{
308
- url: string;
309
- }>;
257
+ protected renderView(index: number, path: string, view?: ReactNode): ReactNode;
310
258
  /**
311
- * Get embedded layers from the server.
312
259
  *
260
+ * @param entry
261
+ */
262
+ add(entry: PageRouteEntry): void;
263
+ /**
264
+ * Create a match function for the given page.
265
+ *
266
+ * @param page
313
267
  * @protected
314
268
  */
315
- protected getEmbeddedCache(): {
316
- session?: Session;
317
- layers?: PreviousLayerData[];
269
+ protected createMatchFunction(page: PageRoute): {
270
+ exec: MatchFunction<ParamData>;
271
+ path: string;
318
272
  } | undefined;
319
273
  /**
320
274
  *
321
- * @protected
322
275
  */
323
- protected getRootElement(): HTMLElement;
276
+ empty(): boolean;
324
277
  /**
325
278
  *
326
279
  * @protected
327
280
  */
328
- protected ready: _alepha_core.HookDescriptor<"ready">;
281
+ protected _next: number;
329
282
  /**
330
283
  *
331
284
  * @protected
332
285
  */
333
- protected stop: _alepha_core.HookDescriptor<"stop">;
334
- }
335
- /**
336
- *
337
- */
338
- interface RouterGoOptions {
339
- replace?: boolean;
340
- match?: RouterMatchOptions;
286
+ protected nextId(): string;
341
287
  }
342
-
343
- declare class RouterHookApi {
344
- private readonly state;
345
- private readonly layer;
346
- private readonly browser?;
347
- constructor(state: RouterState, layer: {
288
+ interface PageRouteEntry extends Omit<PageDescriptorOptions, "children" | "parent"> {
289
+ /**
290
+ *
291
+ */
292
+ name?: string;
293
+ /**
294
+ *
295
+ */
296
+ match?: {
297
+ /**
298
+ *
299
+ */
300
+ exec: MatchFunction<ParamData>;
301
+ /**
302
+ *
303
+ */
348
304
  path: string;
349
- }, browser?: ReactBrowserProvider | undefined);
305
+ };
350
306
  /**
351
307
  *
352
308
  */
353
- get current(): RouterState;
309
+ children?: PageRouteEntry[];
354
310
  /**
355
311
  *
356
312
  */
357
- get pathname(): string;
313
+ parent?: PageRoute;
314
+ }
315
+ interface PageRoute extends PageRouteEntry {
358
316
  /**
359
317
  *
360
318
  */
361
- get query(): Record<string, string>;
319
+ name: string;
362
320
  /**
363
321
  *
364
322
  */
365
- back(): Promise<void>;
323
+ parent?: PageRoute;
324
+ }
325
+ interface Layer {
366
326
  /**
367
327
  *
368
328
  */
369
- forward(): Promise<void>;
329
+ config?: {
330
+ /**
331
+ *
332
+ */
333
+ query?: Record<string, any>;
334
+ /**
335
+ *
336
+ */
337
+ params?: Record<string, any>;
338
+ /**
339
+ *
340
+ */
341
+ context?: Record<string, any>;
342
+ };
370
343
  /**
371
344
  *
372
- * @param props
373
345
  */
374
- invalidate(props?: Record<string, any>): Promise<void>;
346
+ name: string;
375
347
  /**
376
- * Create a valid href for the given pathname.
377
348
  *
378
- * @param pathname
379
- * @param layer
380
349
  */
381
- createHref(pathname: HrefLike, layer?: {
382
- path: string;
383
- }): string;
350
+ props?: Record<string, any>;
384
351
  /**
385
352
  *
386
- * @param path
387
- * @param options
388
353
  */
389
- go(path: HrefLike, options?: RouterGoOptions): Promise<void>;
354
+ part?: string;
390
355
  /**
391
356
  *
392
- * @param path
393
357
  */
394
- createAnchorProps(path: string): AnchorProps;
358
+ element: ReactNode;
395
359
  /**
396
- * Set query params.
397
360
  *
398
- * @param record
399
- * @param options
400
361
  */
401
- setQueryParams(record: Record<string, any>, options?: {
402
- /**
403
- * If true, this will merge current query params with the new ones.
404
- */
405
- merge?: boolean;
406
- /**
407
- * If true, this will add a new entry to the history stack.
408
- */
409
- push?: boolean;
410
- }): void;
362
+ index: number;
363
+ /**
364
+ *
365
+ */
366
+ path: string;
411
367
  }
412
- type HrefLike = string | {
413
- options: {
414
- path?: string;
415
- name?: string;
416
- };
417
- };
418
-
419
- declare const pageDescriptorKey = "PAGE";
420
- interface PageDescriptorConfigSchema {
421
- query?: TSchema$1;
422
- params?: TSchema$1;
368
+ /**
369
+ *
370
+ */
371
+ type PreviousLayerData = Omit<Layer, "element">;
372
+ interface AnchorProps {
373
+ /**
374
+ *
375
+ */
376
+ href?: string;
377
+ /**
378
+ *
379
+ * @param ev
380
+ */
381
+ onClick?: (ev: any) => any;
423
382
  }
424
- type TPropsDefault = any;
425
- type TPropsParentDefault = object;
426
- interface PageDescriptorOptions<TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> {
427
- parent?: {
428
- options: PageDescriptorOptions<any, TPropsParent>;
429
- };
430
- name?: string;
431
- path?: string;
432
- schema?: TConfig;
433
- abstract?: boolean;
434
- resolve?: (config: PageDescriptorConfigValue<TConfig> & TPropsParent & {
435
- user?: UserAccountToken;
436
- }) => Async<TProps>;
437
- component?: FC<TProps & TPropsParent>;
438
- lazy?: () => Promise<{
439
- default: FC<TProps & TPropsParent>;
440
- }>;
441
- children?: () => Array<{
442
- options: PageDescriptorOptions;
443
- }>;
444
- notFoundHandler?: FC<{
445
- error: Error;
446
- }>;
447
- errorHandler?: FC<{
448
- error: Error;
449
- url: string;
450
- }>;
383
+ interface RouterMatchOptions {
384
+ /**
385
+ *
386
+ */
387
+ previous?: PreviousLayerData[];
388
+ /**
389
+ *
390
+ */
391
+ args?: PageContext;
451
392
  }
452
- interface PageDescriptorConfigValue<TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema> {
453
- query: TConfig["query"] extends TSchema$1 ? Static$1<TConfig["query"]> : Record<string, string>;
454
- params: TConfig["params"] extends TSchema$1 ? Static$1<TConfig["params"]> : Record<string, string>;
393
+ interface RouterEvents {
394
+ /**
395
+ *
396
+ */
397
+ begin: undefined;
398
+ /**
399
+ *
400
+ */
401
+ success: undefined;
402
+ /**
403
+ *
404
+ */
405
+ error: Error;
406
+ /**
407
+ *
408
+ */
409
+ end: RouterState;
410
+ }
411
+ interface RouterState {
412
+ /**
413
+ *
414
+ */
455
415
  pathname: string;
416
+ /**
417
+ *
418
+ */
419
+ search: string;
420
+ /**
421
+ *
422
+ */
423
+ layers: Array<Layer>;
424
+ /**
425
+ *
426
+ */
427
+ context: RouterRenderContext;
456
428
  }
457
- interface PageDescriptor<TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> {
458
- [KIND]: typeof pageDescriptorKey;
459
- render: (options?: {
460
- params?: Record<string, string>;
461
- query?: Record<string, string>;
462
- }) => Promise<string>;
463
- go: () => void;
464
- createAnchorProps: (routerHook: RouterHookApi) => {
465
- href: string;
466
- onClick: () => void;
467
- };
468
- options: PageDescriptorOptions<TConfig, TProps, TPropsParent>;
429
+ interface RouterRenderContext {
430
+ /**
431
+ *
432
+ */
433
+ helmet?: RouterRenderHelmetContext;
469
434
  }
470
- declare const $page: {
471
- <TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema, TProps extends object = any, TPropsParent extends object = object>(options: PageDescriptorOptions<TConfig, TProps, TPropsParent>): PageDescriptor<TConfig, TProps, TPropsParent>;
472
- [KIND]: string;
473
- };
474
-
475
- declare class RedirectException extends Error {
476
- readonly page: HrefLike;
477
- constructor(page: HrefLike);
435
+ interface RouterRenderOptions extends RouterMatchOptions {
436
+ /**
437
+ * State to update.
438
+ */
439
+ state?: RouterState;
478
440
  }
479
- declare class Router extends EventEmitter<RouterEvents> {
480
- protected readonly log: _alepha_core.Logger;
481
- protected readonly alepha: Alepha;
482
- protected readonly pages: PageRoute[];
483
- protected notFoundPageRoute?: PageRoute;
441
+ interface RouterStackItem {
484
442
  /**
485
- * Get the page by name.
486
443
  *
487
- * @param name - Page name
488
- * @return PageRoute
489
444
  */
490
- page(name: string): PageRoute;
445
+ route: PageRoute;
491
446
  /**
492
447
  *
493
448
  */
494
- root(state: RouterState, opts?: {
495
- user?: UserAccountInfo;
496
- }): ReactNode;
449
+ config?: Record<string, any>;
497
450
  /**
498
451
  *
499
- * @param url
500
- * @param options
501
452
  */
502
- render(url: string, options?: RouterRenderOptions): Promise<{
503
- element: ReactNode;
504
- layers: Layer[];
505
- redirect?: string;
506
- }>;
453
+ props?: Record<string, any>;
507
454
  /**
508
455
  *
509
- * @param url
510
- * @param options
511
- * @protected
512
456
  */
513
- match(url: string, options?: RouterMatchOptions): Promise<Layer[]>;
457
+ error?: Error;
458
+ }
459
+ interface RouterRenderHelmetContext {
514
460
  /**
515
- * Create layers for the given route.
516
461
  *
517
- * @param route
518
- * @param params
519
- * @param query
520
- * @param previous
521
- * @param user
522
- * @protected
523
462
  */
524
- createLayers(url: string, route: PageRoute, params?: Record<string, any>, query?: Record<string, string>, previous?: PreviousLayerData[], user?: UserAccountInfo): Promise<Layer[]>;
463
+ title?: string;
525
464
  /**
526
465
  *
527
- * @param route
528
- * @protected
529
466
  */
530
- protected getErrorHandler(route: PageRoute): react.FC<{
531
- error: Error;
532
- url: string;
533
- }> | undefined;
467
+ html?: {
468
+ attributes?: Record<string, string>;
469
+ };
534
470
  /**
535
471
  *
536
- * @param page
537
- * @param props
538
- * @protected
539
472
  */
540
- protected createElement(page: PageRoute, props: Record<string, any>): Promise<ReactNode>;
473
+ body?: {
474
+ attributes?: Record<string, string>;
475
+ };
541
476
  /**
542
477
  *
543
- * @param e
544
- * @protected
545
478
  */
546
- protected renderError(e: Error): ReactNode;
479
+ meta?: Array<{
480
+ name: string;
481
+ content: string;
482
+ }>;
483
+ }
484
+ interface RouterRenderResult {
547
485
  /**
548
- * Render an empty view.
549
486
  *
550
- * @protected
551
487
  */
552
- protected renderEmptyView(): ReactNode;
488
+ element: ReactNode;
553
489
  /**
554
- * Create a valid href for the given page.
555
- * @param page
556
- * @param params
490
+ *
557
491
  */
558
- href(page: {
559
- options: {
560
- name?: string;
561
- };
562
- }, params?: Record<string, any>): string;
492
+ layers: Layer[];
563
493
  /**
564
494
  *
565
- * @param index
566
- * @param path
567
- * @param view
568
- * @protected
569
495
  */
570
- protected renderView(index: number, path: string, view?: ReactNode): ReactNode;
496
+ redirect?: string;
571
497
  /**
572
498
  *
573
- * @param entry
574
499
  */
575
- add(entry: PageRouteEntry): void;
500
+ context: RouterRenderContext;
501
+ }
502
+
503
+ declare class ReactAuthProvider {
504
+ protected readonly log: _alepha_core.Logger;
505
+ protected readonly alepha: Alepha;
506
+ protected readonly fastifyCookieProvider: FastifyCookieProvider;
507
+ protected authProviders: AuthProvider[];
508
+ protected readonly authorizationCode: _alepha_server.CookieDescriptor<TObject<{
509
+ codeVerifier: TOptional<TString>;
510
+ redirectUri: TOptional<TString>;
511
+ }>>;
512
+ protected readonly tokens: _alepha_server.CookieDescriptor<TObject<{
513
+ access_token: TOptional<TString>;
514
+ expires_in: TOptional<TNumber>;
515
+ refresh_token: TOptional<TString>;
516
+ id_token: TOptional<TString>;
517
+ scope: TOptional<TString>;
518
+ issued_at: TOptional<TNumber>;
519
+ }>>;
520
+ protected readonly user: _alepha_server.CookieDescriptor<TObject<{
521
+ id: TString;
522
+ name: TOptional<TString>;
523
+ email: TOptional<TString>;
524
+ }>>;
525
+ protected readonly configure: _alepha_core.HookDescriptor<"configure">;
526
+ /**
527
+ * Configure Fastify to forward Session Access Token to Header Authorization.
528
+ */
529
+ protected readonly configureFastify: _alepha_core.HookDescriptor<"configure:fastify">;
576
530
  /**
577
- * Create a match function for the given page.
578
531
  *
579
- * @param page
532
+ * @param cookies
580
533
  * @protected
581
534
  */
582
- protected createMatchFunction(page: PageRoute): {
583
- exec: MatchFunction<ParamData>;
584
- path: string;
585
- } | undefined;
535
+ protected refresh(cookies: CookieManager): Promise<SessionTokens | undefined>;
586
536
  /**
587
537
  *
588
538
  */
589
- empty(): boolean;
539
+ readonly login: _alepha_server.RouteDescriptor<{
540
+ query: TObject<{
541
+ redirect: TOptional<TString>;
542
+ provider: TOptional<TString>;
543
+ }>;
544
+ }, false>;
590
545
  /**
591
546
  *
592
- * @protected
593
547
  */
594
- protected _next: number;
548
+ readonly callback: _alepha_server.RouteDescriptor<{
549
+ query: TObject<{
550
+ provider: TOptional<TString>;
551
+ }>;
552
+ }, false>;
595
553
  /**
596
554
  *
555
+ * @param accessToken
597
556
  * @protected
598
557
  */
599
- protected nextId(): string;
600
- }
601
- interface PageRouteEntry extends Omit<PageDescriptorOptions, "children" | "parent"> {
558
+ protected userFromAccessToken(accessToken: string): {
559
+ id: any;
560
+ name: any;
561
+ email: any;
562
+ } | undefined;
602
563
  /**
603
564
  *
604
565
  */
605
- name?: string;
566
+ readonly logout: _alepha_server.RouteDescriptor<{
567
+ query: TObject<{
568
+ redirect: TOptional<TString>;
569
+ provider: TOptional<TString>;
570
+ }>;
571
+ }, false>;
606
572
  /**
607
573
  *
574
+ * @param name
575
+ * @protected
608
576
  */
609
- match?: {
610
- /**
611
- *
612
- */
613
- exec: MatchFunction<ParamData>;
614
- /**
615
- *
616
- */
617
- path: string;
618
- };
577
+ protected provider(name?: string): AuthProvider;
619
578
  /**
620
579
  *
580
+ * @param file
581
+ * @protected
621
582
  */
622
- children?: PageRouteEntry[];
583
+ protected isViteFile(file: string): boolean;
584
+ }
585
+ interface SessionTokens {
586
+ access_token?: string;
587
+ expires_in?: number;
588
+ refresh_token?: string;
589
+ id_token?: string;
590
+ scope?: string;
591
+ issued_at?: number;
592
+ }
593
+ interface SessionAuthorizationCode {
594
+ codeVerifier?: string;
595
+ redirectUri?: string;
596
+ nonce?: string;
597
+ max_age?: number;
598
+ state?: string;
599
+ }
600
+ interface AuthProvider {
601
+ name: string;
602
+ redirectUri: string;
603
+ client: Configuration;
604
+ }
605
+ interface ReactUser {
606
+ id: string;
607
+ name?: string;
608
+ email?: string;
609
+ }
610
+ interface ReactHydrationState {
611
+ user?: ReactUser;
612
+ auth?: "server" | "client";
613
+ layers?: PreviousLayerData[];
614
+ }
615
+
616
+ declare class ReactBrowserProvider {
617
+ protected readonly log: _alepha_core.Logger;
618
+ protected readonly client: HttpClient;
619
+ protected readonly router: Router;
620
+ protected root: Root;
621
+ transitioning?: {
622
+ to: string;
623
+ };
624
+ state: RouterState;
623
625
  /**
624
626
  *
625
627
  */
626
- parent?: PageRoute;
627
- }
628
- interface PageRoute extends PageRouteEntry {
628
+ get document(): Document;
629
629
  /**
630
630
  *
631
631
  */
632
- name: string;
632
+ get history(): History;
633
633
  /**
634
634
  *
635
635
  */
636
- parent?: PageRoute;
637
- }
638
- interface Layer {
636
+ get url(): string;
639
637
  /**
640
638
  *
639
+ * @param props
641
640
  */
642
- config?: {
643
- /**
644
- *
645
- */
646
- query?: Record<string, any>;
647
- /**
648
- *
649
- */
650
- params?: Record<string, any>;
651
- /**
652
- *
653
- */
654
- context?: Record<string, any>;
655
- };
641
+ invalidate(props?: Record<string, any>): Promise<void>;
656
642
  /**
657
643
  *
644
+ * @param url
645
+ * @param options
658
646
  */
659
- name: string;
647
+ go(url: string, options?: RouterGoOptions): Promise<void>;
660
648
  /**
661
649
  *
650
+ * @param options
651
+ * @protected
662
652
  */
663
- props?: Record<string, any>;
653
+ protected render(options?: {
654
+ url?: string;
655
+ previous?: PreviousLayerData[];
656
+ }): Promise<{
657
+ url: string;
658
+ }>;
659
+ protected renderHelmetContext(ctx: RouterRenderHelmetContext): void;
664
660
  /**
661
+ * Get embedded layers from the server.
665
662
  *
663
+ * @protected
666
664
  */
667
- part?: string;
665
+ protected getHydrationState(): ReactHydrationState | undefined;
668
666
  /**
669
667
  *
668
+ * @protected
670
669
  */
671
- element: ReactNode;
670
+ protected getRootElement(): HTMLElement;
671
+ protected getUserFromCookies(): UserAccountToken | undefined;
672
672
  /**
673
673
  *
674
+ * @protected
674
675
  */
675
- index: number;
676
+ protected ready: _alepha_core.HookDescriptor<"ready">;
676
677
  /**
677
678
  *
679
+ * @protected
678
680
  */
679
- path: string;
681
+ protected stop: _alepha_core.HookDescriptor<"stop">;
680
682
  }
681
683
  /**
682
684
  *
683
685
  */
684
- type PreviousLayerData = Omit<Layer, "element">;
685
- interface AnchorProps {
686
+ interface RouterGoOptions {
687
+ replace?: boolean;
688
+ match?: RouterMatchOptions;
689
+ }
690
+
691
+ declare class RouterHookApi {
692
+ private readonly state;
693
+ private readonly layer;
694
+ private readonly browser?;
695
+ constructor(state: RouterState, layer: {
696
+ path: string;
697
+ }, browser?: ReactBrowserProvider | undefined);
686
698
  /**
687
699
  *
688
700
  */
689
- href?: string;
701
+ get current(): RouterState;
690
702
  /**
691
703
  *
692
- * @param ev
693
704
  */
694
- onClick?: (ev: any) => any;
695
- }
696
- interface RouterMatchOptions {
705
+ get pathname(): string;
697
706
  /**
698
707
  *
699
708
  */
700
- previous?: PreviousLayerData[];
709
+ get query(): Record<string, string>;
701
710
  /**
702
711
  *
703
712
  */
704
- user?: UserAccountInfo;
705
- }
706
- interface RouterEvents {
713
+ back(): Promise<void>;
707
714
  /**
708
715
  *
709
716
  */
710
- begin: undefined;
717
+ forward(): Promise<void>;
711
718
  /**
712
719
  *
720
+ * @param props
713
721
  */
714
- success: undefined;
722
+ invalidate(props?: Record<string, any>): Promise<void>;
715
723
  /**
724
+ * Create a valid href for the given pathname.
716
725
  *
726
+ * @param pathname
727
+ * @param layer
717
728
  */
718
- error: Error;
729
+ createHref(pathname: HrefLike, layer?: {
730
+ path: string;
731
+ }): string;
719
732
  /**
720
733
  *
734
+ * @param path
735
+ * @param options
721
736
  */
722
- end: RouterState;
737
+ go(path: HrefLike, options?: RouterGoOptions): Promise<void>;
738
+ /**
739
+ *
740
+ * @param path
741
+ */
742
+ createAnchorProps(path: string): AnchorProps;
743
+ /**
744
+ * Set query params.
745
+ *
746
+ * @param record
747
+ * @param options
748
+ */
749
+ setQueryParams(record: Record<string, any>, options?: {
750
+ /**
751
+ * If true, this will merge current query params with the new ones.
752
+ */
753
+ merge?: boolean;
754
+ /**
755
+ * If true, this will add a new entry to the history stack.
756
+ */
757
+ push?: boolean;
758
+ }): void;
723
759
  }
724
- interface RouterState {
760
+ type HrefLike = string | {
761
+ options: {
762
+ path?: string;
763
+ name?: string;
764
+ };
765
+ };
766
+
767
+ declare const pageDescriptorKey = "PAGE";
768
+ interface PageDescriptorConfigSchema {
769
+ query?: TSchema$1;
770
+ params?: TSchema$1;
771
+ }
772
+ type TPropsDefault = any;
773
+ type TPropsParentDefault = object;
774
+ interface PageDescriptorOptions<TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> {
725
775
  /**
726
776
  *
727
777
  */
728
- pathname: string;
778
+ name?: string;
729
779
  /**
730
780
  *
731
781
  */
732
- search: string;
782
+ path?: string;
733
783
  /**
734
784
  *
735
785
  */
736
- layers: Array<Layer>;
737
- }
738
- interface RouterRenderOptions extends RouterMatchOptions {
786
+ schema?: TConfig;
739
787
  /**
740
- * State to update.
788
+ * Function to call when the page is loaded.
741
789
  */
742
- state?: RouterState;
790
+ resolve?: (config: PageDescriptorConfigValue<TConfig> & TPropsParent & {
791
+ context: PageContext;
792
+ }, context: PageContext) => Async<TProps>;
793
+ /**
794
+ * Component to render when the page is loaded.
795
+ */
796
+ component?: FC<TProps & TPropsParent>;
797
+ /**
798
+ * Component to render when the page is loaded. (like .component)
799
+ */
800
+ lazy?: () => Promise<{
801
+ default: FC<TProps & TPropsParent>;
802
+ }>;
803
+ /**
804
+ *
805
+ */
806
+ children?: () => Array<{
807
+ options: PageDescriptorOptions;
808
+ }>;
809
+ /**
810
+ *
811
+ */
812
+ parent?: {
813
+ options: PageDescriptorOptions<any, TPropsParent>;
814
+ };
815
+ /**
816
+ *
817
+ */
818
+ helmet?: RouterRenderHelmetContext | ((props: TProps) => RouterRenderHelmetContext);
819
+ /**
820
+ *
821
+ */
822
+ notFoundHandler?: FC<{
823
+ error: Error;
824
+ }>;
825
+ /**
826
+ *
827
+ */
828
+ errorHandler?: FC<{
829
+ error: Error;
830
+ url: string;
831
+ }>;
743
832
  }
744
- interface RouterStackItem {
745
- route: PageRoute;
746
- config?: Record<string, any>;
747
- props?: Record<string, any>;
748
- error?: Error;
833
+ interface PageContext {
834
+ user?: UserAccountToken;
835
+ cookies?: CookieManager;
749
836
  }
837
+ interface PageDescriptorConfigValue<TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema> {
838
+ query: TConfig["query"] extends TSchema$1 ? Static$1<TConfig["query"]> : Record<string, string>;
839
+ params: TConfig["params"] extends TSchema$1 ? Static$1<TConfig["params"]> : Record<string, string>;
840
+ pathname: string;
841
+ }
842
+ interface PageDescriptor<TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema, TProps extends object = TPropsDefault, TPropsParent extends object = TPropsParentDefault> {
843
+ [KIND]: typeof pageDescriptorKey;
844
+ render: (options?: {
845
+ params?: Record<string, string>;
846
+ query?: Record<string, string>;
847
+ }) => Promise<string>;
848
+ go: () => void;
849
+ createAnchorProps: (routerHook: RouterHookApi) => {
850
+ href: string;
851
+ onClick: () => void;
852
+ };
853
+ options: PageDescriptorOptions<TConfig, TProps, TPropsParent>;
854
+ }
855
+ declare const $page: {
856
+ <TConfig extends PageDescriptorConfigSchema = PageDescriptorConfigSchema, TProps extends object = any, TPropsParent extends object = object>(options: PageDescriptorOptions<TConfig, TProps, TPropsParent>): PageDescriptor<TConfig, TProps, TPropsParent>;
857
+ [KIND]: string;
858
+ };
750
859
 
751
860
  interface RouterContextValue {
752
861
  router: Router;
753
862
  alepha: Alepha;
754
863
  state: RouterState;
755
- session?: Session;
864
+ args: PageContext;
756
865
  }
757
866
  declare const RouterContext: react.Context<RouterContextValue | undefined>;
758
867
 
@@ -762,17 +871,38 @@ interface RouterLayerContextValue {
762
871
  }
763
872
  declare const RouterLayerContext: react.Context<RouterLayerContextValue | undefined>;
764
873
 
765
- declare const useActive: (path: HrefLike) => UseActiveHook;
766
- interface UseActiveHook {
767
- isActive: boolean;
768
- anchorProps: AnchorProps;
769
- isPending: boolean;
874
+ declare class Auth {
875
+ alepha: Alepha;
876
+ log: _alepha_core.Logger;
877
+ client: HttpClient;
878
+ api: string;
879
+ start: _alepha_core.HookDescriptor<"start">;
880
+ login: (provider?: string) => void;
881
+ logout: () => void;
882
+ }
883
+
884
+ declare const KEY = "AUTH";
885
+ interface AuthDescriptorOptions {
770
886
  name?: string;
887
+ oidc?: {
888
+ issuer: string;
889
+ clientId: string;
890
+ clientSecret?: string;
891
+ redirectUri?: string;
892
+ };
771
893
  }
894
+ interface AuthDescriptor {
895
+ [KIND]: typeof KEY;
896
+ options: AuthDescriptorOptions;
897
+ }
898
+ declare const $auth: {
899
+ (options: AuthDescriptorOptions): AuthDescriptor;
900
+ [KIND]: string;
901
+ };
772
902
 
773
- declare const useClient: () => HttpClient;
903
+ declare const useInject: <T extends object>(clazz: Class<T>) => T;
774
904
 
775
- declare const useInject: <T extends object>(classEntry: ClassEntry<T>) => T;
905
+ declare const useClient: () => HttpClient;
776
906
 
777
907
  interface UseQueryParamsHookOptions {
778
908
  format?: "base64" | "querystring";
@@ -794,6 +924,21 @@ declare const useRouterEvents: (opts?: {
794
924
 
795
925
  declare const useRouterState: () => RouterState;
796
926
 
927
+ declare const useActive: (path: HrefLike) => UseActiveHook;
928
+ interface UseActiveHook {
929
+ isActive: boolean;
930
+ anchorProps: AnchorProps;
931
+ isPending: boolean;
932
+ name?: string;
933
+ }
934
+
935
+ declare const useAuth: () => AuthHook;
936
+ interface AuthHook {
937
+ user?: UserAccountToken;
938
+ logout: () => void;
939
+ login: (provider?: string) => void;
940
+ }
941
+
797
942
  declare class PageDescriptorProvider {
798
943
  protected readonly alepha: Alepha;
799
944
  protected readonly router: Router;
@@ -813,14 +958,17 @@ declare class PageDescriptorProvider {
813
958
  }): PageRouteEntry;
814
959
  }
815
960
 
816
- declare const envSchema: TObject<{
961
+ declare const envSchema$1: TObject<{
817
962
  REACT_SERVER_DIST: TString;
818
963
  REACT_SERVER_PREFIX: TString;
819
964
  REACT_SSR_ENABLED: TBoolean;
820
965
  REACT_SSR_OUTLET: TString;
821
966
  }>;
822
967
  declare module "@alepha/core" {
823
- interface Env extends Partial<Static$1<typeof envSchema>> {
968
+ interface Env extends Partial<Static$1<typeof envSchema$1>> {
969
+ }
970
+ interface State {
971
+ "ReactServerProvider.template"?: string;
824
972
  }
825
973
  }
826
974
  declare class ReactServerProvider {
@@ -836,6 +984,13 @@ declare class ReactServerProvider {
836
984
  };
837
985
  protected readonly configure: _alepha_core.HookDescriptor<"configure">;
838
986
  protected configureRoutes(): Promise<void>;
987
+ /**
988
+ * Check if the template contains the outlet.
989
+ *
990
+ * @param template
991
+ * @protected
992
+ */
993
+ protected checkTemplate(template: string): string;
839
994
  /**
840
995
  *
841
996
  * @param root
@@ -847,26 +1002,42 @@ declare class ReactServerProvider {
847
1002
  * @param templateLoader
848
1003
  * @protected
849
1004
  */
850
- protected createHandler(templateLoader: () => Promise<string | undefined>): RouteObject;
1005
+ protected createHandler(templateLoader: () => Promise<string | undefined>): CreateRoute;
851
1006
  protected processDescriptors(): void;
852
1007
  /**
853
1008
  *
854
1009
  * @param url
855
1010
  * @protected
856
1011
  */
857
- protected notFoundHandler(url: string): Response | undefined;
1012
+ protected notFoundHandler(url: URL): Response | undefined;
858
1013
  /**
859
1014
  *
860
1015
  * @param url
861
1016
  * @param template
862
- * @param user
1017
+ * @param page
863
1018
  */
864
- ssr(url: string, template?: string, user?: UserAccountInfo): Promise<Response>;
1019
+ ssr(url: URL, template?: string, page?: PageContext): Promise<Response>;
1020
+ protected renderHelmetContext(template: string, helmetContext: RouterRenderHelmetContext): string;
1021
+ }
1022
+
1023
+ declare class RedirectionError extends Error {
1024
+ readonly page: HrefLike;
1025
+ constructor(page: HrefLike);
865
1026
  }
866
1027
 
1028
+ declare const envSchema: _alepha_core.TObject<{
1029
+ REACT_AUTH_ENABLED: TBoolean;
1030
+ }>;
1031
+ declare module "@alepha/core" {
1032
+ interface Env extends Partial<Static$1<typeof envSchema>> {
1033
+ }
1034
+ }
867
1035
  declare class ReactModule {
1036
+ protected readonly env: {
1037
+ REACT_AUTH_ENABLED: boolean;
1038
+ };
868
1039
  protected readonly alepha: Alepha;
869
1040
  constructor();
870
1041
  }
871
1042
 
872
- export { $page, type AnchorProps, type HrefLike, type Layer, NestedView, type PageDescriptor, type PageDescriptorConfigSchema, type PageDescriptorConfigValue, type PageDescriptorOptions, PageDescriptorProvider, type PageRoute, type PageRouteEntry, type PreviousLayerData, ReactBrowserProvider, ReactModule, ReactServerProvider, type ReactServerSession, ReactSessionProvider, RedirectException, Router, RouterContext, type RouterContextValue, type RouterEvents, type RouterGoOptions, RouterHookApi, RouterLayerContext, type RouterLayerContextValue, type RouterMatchOptions, type RouterRenderOptions, type RouterStackItem, type RouterState, type Session, type TPropsDefault, type TPropsParentDefault, type UseActiveHook, type UseQueryParamsHookOptions, envSchema, pageDescriptorKey, sessionSchema, sessionUserSchema, useActive, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState };
1043
+ export { $auth, $page, type AnchorProps, Auth, type AuthDescriptor, type AuthDescriptorOptions, type AuthHook, type AuthProvider, type HrefLike, type Layer, Link, NestedView, type PageContext, type PageDescriptor, type PageDescriptorConfigSchema, type PageDescriptorConfigValue, type PageDescriptorOptions, PageDescriptorProvider, type PageRoute, type PageRouteEntry, type PreviousLayerData, ReactAuthProvider, ReactBrowserProvider, type ReactHydrationState, ReactModule, ReactServerProvider, type ReactUser, RedirectionError, Router, RouterContext, type RouterContextValue, type RouterEvents, type RouterGoOptions, RouterHookApi, RouterLayerContext, type RouterLayerContextValue, type RouterMatchOptions, type RouterRenderContext, type RouterRenderHelmetContext, type RouterRenderOptions, type RouterRenderResult, type RouterStackItem, type RouterState, type SessionAuthorizationCode, type SessionTokens, type TPropsDefault, type TPropsParentDefault, type UseActiveHook, type UseQueryParamsHookOptions, envSchema$1 as envSchema, pageDescriptorKey, useActive, useAuth, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState };