alepha 0.9.1 → 0.9.3

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/react/auth.d.ts CHANGED
@@ -1,187 +1,411 @@
1
- import * as _alepha_core0$1 from "alepha";
2
- import * as _alepha_core4 from "alepha";
1
+ import * as _alepha_core1 from "alepha";
2
+ import * as _alepha_core5 from "alepha";
3
3
  import * as _alepha_core0 from "alepha";
4
- import { Alepha, Async, Descriptor, KIND } from "alepha";
4
+ import { Alepha, Async, Descriptor, KIND, Static } from "alepha";
5
5
  import * as _alepha_server_cookies0 from "alepha/server/cookies";
6
6
  import { Cookies, ServerCookiesProvider } from "alepha/server/cookies";
7
+ import { DateTimeProvider } from "alepha/datetime";
8
+ import { AccessTokenResponse, RealmDescriptor, SecurityProvider, UserAccountInfo, UserAccountToken } from "alepha/security";
9
+ import { Configuration } from "openid-client";
7
10
  import * as _alepha_server0 from "alepha/server";
8
11
  import { HttpClient } from "alepha/server";
9
- import { Configuration } from "openid-client";
10
- import { HttpVirtualClient } from "alepha/server/links";
11
- import { UserAccountToken } from "alepha/security";
12
+ import * as _alepha_server_links0 from "alepha/server/links";
13
+ import { HttpVirtualClient, LinkProvider, ServerLinksProvider } from "alepha/server/links";
14
+ import * as _sinclair_typebox92 from "@sinclair/typebox";
12
15
  import * as _sinclair_typebox0 from "@sinclair/typebox";
13
16
 
14
- //#region src/descriptors/$auth.d.ts
15
- declare const $auth: {
16
- (options: AuthDescriptorOptions): AuthDescriptor;
17
- [KIND]: typeof AuthDescriptor;
18
- };
19
- interface AuthDescriptorOptions {
20
- name?: string;
21
- fallback?: () => Async<AccessToken>;
22
- oidc?: {
23
- issuer: string;
24
- clientId: string;
25
- clientSecret?: string;
26
- redirectUri?: string;
27
- useIdToken?: boolean;
28
- logoutUri?: string;
29
- };
30
- }
31
- declare class AuthDescriptor extends Descriptor<AuthDescriptorOptions> {
32
- get name(): string;
33
- jwks(): string;
34
- }
35
- type AccessToken = string;
36
- //# sourceMappingURL=$auth.d.ts.map
17
+ //#region src/schemas/tokensSchema.d.ts
18
+ declare const tokensSchema: _sinclair_typebox92.TObject<{
19
+ provider: _sinclair_typebox92.TString;
20
+ access_token: _sinclair_typebox92.TString;
21
+ issued_at: _sinclair_typebox92.TNumber;
22
+ expires_in: _sinclair_typebox92.TOptional<_sinclair_typebox92.TNumber>;
23
+ refresh_token: _sinclair_typebox92.TOptional<_sinclair_typebox92.TString>;
24
+ refresh_token_expires_in: _sinclair_typebox92.TOptional<_sinclair_typebox92.TNumber>;
25
+ id_token: _sinclair_typebox92.TOptional<_sinclair_typebox92.TString>;
26
+ scope: _sinclair_typebox92.TOptional<_sinclair_typebox92.TString>;
27
+ }>;
28
+ type Tokens = Static<typeof tokensSchema>;
29
+ //# sourceMappingURL=tokensSchema.d.ts.map
37
30
  //#endregion
38
31
  //#region src/providers/ReactAuthProvider.d.ts
39
32
  declare class ReactAuthProvider {
40
- protected readonly log: _alepha_core0$1.Logger;
33
+ protected readonly log: _alepha_core1.Logger;
41
34
  protected readonly alepha: Alepha;
42
35
  protected readonly serverCookiesProvider: ServerCookiesProvider;
43
- protected authProviders: AuthProvider[];
44
- protected readonly authorizationCode: _alepha_server_cookies0.CookieDescriptor<_sinclair_typebox0.TObject<{
36
+ protected readonly securityProvider: SecurityProvider;
37
+ protected readonly dateTimeProvider: DateTimeProvider;
38
+ protected readonly serverLinksProvider: ServerLinksProvider;
39
+ protected readonly authorizationCode: _alepha_server_cookies0.AbstractCookieDescriptor<_sinclair_typebox0.TObject<{
40
+ provider: _sinclair_typebox0.TString;
45
41
  codeVerifier: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
46
42
  redirectUri: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
43
+ state: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
44
+ nonce: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
47
45
  }>>;
48
- readonly tokens: _alepha_server_cookies0.CookieDescriptor<_sinclair_typebox0.TObject<{
49
- provider: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
50
- access_token: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
46
+ readonly tokens: _alepha_server_cookies0.AbstractCookieDescriptor<_sinclair_typebox0.TObject<{
47
+ provider: _sinclair_typebox0.TString;
48
+ access_token: _sinclair_typebox0.TString;
49
+ issued_at: _sinclair_typebox0.TNumber;
51
50
  expires_in: _sinclair_typebox0.TOptional<_sinclair_typebox0.TNumber>;
52
51
  refresh_token: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
52
+ refresh_token_expires_in: _sinclair_typebox0.TOptional<_sinclair_typebox0.TNumber>;
53
53
  id_token: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
54
54
  scope: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
55
- issued_at: _sinclair_typebox0.TOptional<_sinclair_typebox0.TNumber>;
56
55
  }>>;
57
- readonly user: _alepha_server_cookies0.CookieDescriptor<_sinclair_typebox0.TObject<{
58
- id: _sinclair_typebox0.TString;
59
- name: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
60
- email: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
61
- picture: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
62
- }>>;
63
- readonly onRender: _alepha_core0$1.HookDescriptor<"react:server:render:begin">;
64
- protected readonly configure: _alepha_core0$1.HookDescriptor<"configure">;
65
- protected getAccessTokenFromCookies(tokens: SessionTokens): Promise<string | undefined>;
56
+ readonly onRender: _alepha_core1.HookDescriptor<"react:server:render:begin">;
57
+ get identities(): Array<AuthDescriptor>;
58
+ protected readonly configure: _alepha_core1.HookDescriptor<"configure">;
59
+ protected getAccessTokens(tokens: Tokens): string | undefined;
66
60
  /**
67
- * Configure Fastify to forward Session Access Token to Header Authorization.
61
+ * Fill request headers with access token from cookies or fallback to provider's fallback function.
68
62
  */
69
- protected readonly onRequest: _alepha_core0$1.HookDescriptor<"server:onRequest">;
63
+ protected readonly onRequest: _alepha_core1.HookDescriptor<"server:onRequest">;
70
64
  /**
71
- *
72
- * @param cookies
73
- * @protected
65
+ * Convert cookies to tokens.
66
+ * If the tokens are expired, try to refresh them using the refresh token.
74
67
  */
75
- protected refresh(cookies: Cookies): Promise<SessionTokens | undefined>;
76
- readonly login: _alepha_server0.RouteDescriptor<{
68
+ protected cookiesToTokens(cookies: Cookies): Promise<Tokens | undefined>;
69
+ readonly userinfo: _alepha_server0.ActionDescriptor<{
70
+ response: _sinclair_typebox0.TObject<{
71
+ id: _sinclair_typebox0.TString;
72
+ name: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
73
+ email: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
74
+ picture: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
75
+ organizations: _sinclair_typebox0.TOptional<_sinclair_typebox0.TArray<_sinclair_typebox0.TString>>;
76
+ roles: _sinclair_typebox0.TOptional<_sinclair_typebox0.TArray<_sinclair_typebox0.TString>>;
77
+ }>;
78
+ }>;
79
+ readonly token: _alepha_server0.RouteDescriptor<{
77
80
  query: _sinclair_typebox0.TObject<{
78
- redirect: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
79
- provider: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
81
+ provider: _sinclair_typebox0.TString;
82
+ }>;
83
+ body: _sinclair_typebox0.TObject<{
84
+ username: _sinclair_typebox0.TString;
85
+ password: _sinclair_typebox0.TString;
86
+ }>;
87
+ response: _sinclair_typebox0.TObject<{
88
+ provider: _sinclair_typebox0.TString;
89
+ access_token: _sinclair_typebox0.TString;
90
+ issued_at: _sinclair_typebox0.TNumber;
91
+ expires_in: _sinclair_typebox0.TOptional<_sinclair_typebox0.TNumber>;
92
+ refresh_token: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
93
+ refresh_token_expires_in: _sinclair_typebox0.TOptional<_sinclair_typebox0.TNumber>;
94
+ id_token: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
95
+ scope: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
96
+ user: _sinclair_typebox0.TObject<{
97
+ id: _sinclair_typebox0.TString;
98
+ name: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
99
+ email: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
100
+ picture: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
101
+ organizations: _sinclair_typebox0.TOptional<_sinclair_typebox0.TArray<_sinclair_typebox0.TString>>;
102
+ roles: _sinclair_typebox0.TOptional<_sinclair_typebox0.TArray<_sinclair_typebox0.TString>>;
103
+ }>;
104
+ links: _sinclair_typebox0.TObject<{
105
+ prefix: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
106
+ links: _sinclair_typebox0.TArray<_sinclair_typebox0.TObject<{
107
+ name: _sinclair_typebox0.TString;
108
+ path: _sinclair_typebox0.TString;
109
+ method: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
110
+ group: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
111
+ requestBodyType: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
112
+ service: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
113
+ }>>;
114
+ }>;
80
115
  }>;
81
116
  }>;
82
- readonly callback: _alepha_server0.RouteDescriptor<{
117
+ readonly login: _alepha_server0.RouteDescriptor<{
83
118
  query: _sinclair_typebox0.TObject<{
84
- provider: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
119
+ provider: _sinclair_typebox0.TString;
120
+ redirect_uri: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
85
121
  }>;
86
122
  }>;
87
123
  /**
88
- *
89
- * @param accessToken
90
- * @protected
91
- */
92
- protected userFromAccessToken(accessToken: string): {
93
- id: any;
94
- name: any;
95
- email: any;
96
- picture: any;
97
- } | undefined;
124
+ * Callback for OAuth2/OIDC providers.
125
+ * It handles the authorization code flow and retrieves the access token.
126
+ */
127
+ readonly callback: _alepha_server0.RouteDescriptor<_alepha_server0.RequestConfigSchema>;
98
128
  readonly logout: _alepha_server0.RouteDescriptor<{
99
129
  query: _sinclair_typebox0.TObject<{
100
- redirect: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
101
- provider: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
130
+ post_logout_redirect_uri: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
102
131
  }>;
103
132
  }>;
133
+ protected provider(opts: string | {
134
+ provider: string;
135
+ }): AuthDescriptor;
136
+ protected setTokens(tokens: Tokens, cookies?: Cookies): void;
137
+ }
138
+ interface OAuth2UserInfo {
139
+ sub: string;
140
+ name?: string;
141
+ given_name?: string;
142
+ family_name?: string;
143
+ middle_name?: string;
144
+ nickname?: string;
145
+ preferred_username?: string;
146
+ profile?: string;
147
+ picture?: string;
148
+ website?: string;
149
+ email?: string;
150
+ email_verified?: boolean;
151
+ gender?: string;
152
+ birthdate?: string;
153
+ zoneinfo?: string;
154
+ locale?: string;
155
+ phone_number?: string;
156
+ phone_number_verified?: boolean;
157
+ address?: {
158
+ formatted?: string;
159
+ street_address?: string;
160
+ locality?: string;
161
+ region?: string;
162
+ postal_code?: string;
163
+ country?: string;
164
+ };
165
+ updated_at?: number;
166
+ [key: string]: unknown;
167
+ }
168
+ //# sourceMappingURL=ReactAuthProvider.d.ts.map
169
+ //#endregion
170
+ //#region src/descriptors/$auth.d.ts
171
+ declare const $auth: {
172
+ (options: AuthDescriptorOptions): AuthDescriptor;
173
+ [KIND]: typeof AuthDescriptor;
174
+ };
175
+ type AuthDescriptorOptions = {
104
176
  /**
105
- *
106
- * @param name
107
- * @protected
108
- */
109
- protected provider(name?: string): Promise<{
110
- client: Configuration;
111
- name: string;
112
- redirectUri: string;
113
- fallback?: () => Async<AccessToken>;
114
- useIdToken?: boolean;
115
- logoutUri?: string;
116
- }>;
177
+ * Name of the identity provider.
178
+ * If not provided, it will be derived from the property key.
179
+ */
180
+ name?: string;
117
181
  /**
182
+ * If true, auth provider will be skipped.
183
+ */
184
+ disabled?: boolean;
185
+ } & (AuthExternal | AuthInternal);
186
+ /**
187
+ * When you let an external service handle authentication. (e.g. Keycloak, Auth0, etc.)
188
+ */
189
+ type AuthExternal = {
190
+ /**
191
+ * Only OIDC is supported for external authentication.
192
+ */
193
+ oidc: OidcOptions;
194
+ /**
195
+ * For anonymous access, this will expect a service account access token.
118
196
  *
119
- * @param file
120
- * @protected
197
+ * ```ts
198
+ * class App {
199
+ * anonymous = $serviceAccount(...);
200
+ * auth = $auth({
201
+ * // ... config ...
202
+ * fallback: this.anonymous,
203
+ * })
204
+ * }
205
+ * ```
121
206
  */
122
- protected isViteFile(file: string): boolean;
123
- }
124
- interface SessionTokens {
125
- access_token?: string;
126
- expires_in?: number;
127
- refresh_token?: string;
128
- id_token?: string;
129
- scope?: string;
130
- issued_at?: number;
131
- provider?: string;
132
- }
133
- interface AuthProvider {
134
- name: string;
135
- redirectUri: string;
136
- client: {
137
- get: () => Promise<Configuration>;
138
- };
139
207
  fallback?: () => Async<AccessToken>;
208
+ };
209
+ /**
210
+ * When using your own authentication system, e.g. using a database to store user accounts.
211
+ * This is usually used with a custom login form.
212
+ *
213
+ * This relies on the `realm`, which is used to create/verify the access token.
214
+ */
215
+ type AuthInternal = {
216
+ realm: RealmDescriptor;
217
+ } & ({
218
+ /**
219
+ * The common username/password authentication.
220
+ *
221
+ * - It uses the OAuth2 Client Credentials flow to obtain an access token.
222
+ *
223
+ * This is usually used with a custom login form on your website or mobile app.
224
+ */
225
+ credentials: CredentialsOptions;
226
+ } | {
227
+ /**
228
+ * OAuth2 authentication. Delegates authentication to an OAuth2 provider. (e.g. Google, GitHub, etc.)
229
+ *
230
+ * - It uses the OAuth2 Authorization Code flow to obtain an access token and user information.
231
+ *
232
+ * This is usually used with a login button that redirects to the OAuth2 provider.
233
+ */
234
+ oauth: OAuth2Options;
235
+ } | {
236
+ /**
237
+ * Like OAuth2, but uses OIDC (OpenID Connect) for authentication and user information retrieval.
238
+ * OIDC is an identity layer on top of OAuth2, providing user authentication and profile information.
239
+ *
240
+ * - It uses the OAuth2 Authorization Code flow to obtain an access token and user information.
241
+ * - PCKE (Proof Key for Code Exchange) is recommended for security.
242
+ *
243
+ * This is usually used with a login button that redirects to the OIDC provider.
244
+ */
245
+ oidc: OidcOptions;
246
+ });
247
+ type CredentialsOptions = {
248
+ user: (entry: {
249
+ username: string;
250
+ password: string;
251
+ }) => Async<UserAccountInfo>;
252
+ };
253
+ interface OidcOptions {
254
+ /**
255
+ * URL of the OIDC issuer.
256
+ */
257
+ issuer: string;
258
+ /**
259
+ * Client ID for the OIDC client.
260
+ */
261
+ clientId: string;
262
+ /**
263
+ * Client secret for the OIDC client.
264
+ * Optional if PKCE (Proof Key for Code Exchange) is used.
265
+ */
266
+ clientSecret?: string;
267
+ /**
268
+ * Redirect URI for the OIDC client.
269
+ * This is where the user will be redirected after authentication.
270
+ */
271
+ redirectUri?: string;
272
+ /**
273
+ * For external auth providers only.
274
+ * Take the ID token instead of the access token for validation.
275
+ */
140
276
  useIdToken?: boolean;
277
+ /**
278
+ * URI to redirect the user after logout.
279
+ */
141
280
  logoutUri?: string;
281
+ /**
282
+ * Optional scope for the OIDC client.
283
+ * @default "openid profile email".
284
+ */
285
+ scope?: string;
286
+ user?: (tokens: {
287
+ id_token?: string;
288
+ access_token: string;
289
+ expires_in?: number;
290
+ scope?: string;
291
+ user: OAuth2UserInfo;
292
+ }) => Async<UserAccountInfo>;
142
293
  }
143
- interface ReactUser {
144
- id: string;
145
- name?: string;
146
- email?: string;
294
+ interface OAuth2Options {
295
+ /**
296
+ * URL of the OAuth2 authorization endpoint.
297
+ */
298
+ clientId: string;
299
+ /**
300
+ * Client secret for the OAuth2 client.
301
+ */
302
+ clientSecret: string;
303
+ /**
304
+ * URL of the OAuth2 authorization endpoint.
305
+ */
306
+ authorization: string;
307
+ /**
308
+ * URL of the OAuth2 token endpoint.
309
+ */
310
+ token: string;
311
+ /**
312
+ * Function to retrieve user profile information from the OAuth2 tokens.
313
+ */
314
+ user: (tokens: Tokens) => Async<UserAccountInfo>;
315
+ /**
316
+ * URL of the OAuth2 authorization endpoint.
317
+ */
318
+ redirectUri?: string;
319
+ /**
320
+ * URL of the OAuth2 authorization endpoint.
321
+ */
322
+ scope?: string;
147
323
  }
148
- //# sourceMappingURL=ReactAuthProvider.d.ts.map
324
+ declare class AuthDescriptor extends Descriptor<AuthDescriptorOptions> {
325
+ protected readonly securityProvider: SecurityProvider;
326
+ protected readonly dateTimeProvider: DateTimeProvider;
327
+ oauth?: Configuration;
328
+ get name(): string;
329
+ get jwks_uri(): string;
330
+ get scope(): string | undefined;
331
+ get redirect_uri(): string | undefined;
332
+ /**
333
+ * Refreshes the access token using the refresh token.
334
+ */
335
+ refresh(tokens: Tokens): Promise<AccessTokenResponse>;
336
+ /**
337
+ * Extracts user information from the access token.
338
+ * This is used to create a user account from the access token.
339
+ */
340
+ user(tokens: Tokens): Promise<UserAccountInfo>;
341
+ protected getUserFromIdToken(idToken: string): OAuth2UserInfo;
342
+ prepare(): Promise<void>;
343
+ }
344
+ type AccessToken = string | {
345
+ token: () => Async<string>;
346
+ };
347
+ //# sourceMappingURL=$auth.d.ts.map
149
348
  //#endregion
150
349
  //#region src/hooks/useAuth.d.ts
151
- declare const useAuth: () => AuthHook;
152
- interface AuthHook {
153
- user?: UserAccountToken;
350
+ declare const useAuth: <T extends object = any>() => {
351
+ user: {
352
+ name?: string | undefined;
353
+ email?: string | undefined;
354
+ picture?: string | undefined;
355
+ organizations?: string[] | undefined;
356
+ roles?: string[] | undefined;
357
+ id: string;
358
+ } | undefined;
154
359
  logout: () => void;
155
- login: (provider?: string) => void;
156
- can: <T extends object>(name: keyof HttpVirtualClient<T>) => boolean;
157
- }
360
+ login: (provider: keyof T, options?: {
361
+ username?: string;
362
+ password?: string;
363
+ redirect?: string;
364
+ [extra: string]: any;
365
+ }) => Promise<void>;
366
+ can: <Api extends object = any>(name: keyof HttpVirtualClient<Api>) => boolean;
367
+ };
158
368
  //# sourceMappingURL=useAuth.d.ts.map
159
369
  //#endregion
160
370
  //#region src/services/ReactAuth.d.ts
161
371
  declare class ReactAuth {
162
- protected readonly log: _alepha_core4.Logger;
372
+ protected readonly log: _alepha_core5.Logger;
163
373
  protected readonly alepha: Alepha;
374
+ protected readonly auth: _alepha_server_links0.HttpVirtualClient<ReactAuthProvider>;
164
375
  protected readonly client: HttpClient;
376
+ protected readonly linkProvider: LinkProvider;
165
377
  static path: {
166
378
  login: string;
167
379
  callback: string;
168
380
  logout: string;
381
+ token: string;
382
+ userinfo: string;
169
383
  };
170
- readonly onRender: _alepha_core4.HookDescriptor<"react:transition:begin">;
384
+ protected readonly onFetchRequest: _alepha_core5.HookDescriptor<"client:onRequest">;
385
+ readonly onRender: _alepha_core5.HookDescriptor<"react:transition:begin">;
171
386
  get user(): UserAccountToken | undefined;
172
- protected getUserFromCookies(): UserAccountToken | undefined;
173
- login(): void;
387
+ login(provider: string, options: {
388
+ username?: string;
389
+ password?: string;
390
+ redirect?: string;
391
+ [extra: string]: any;
392
+ }): Promise<void>;
174
393
  logout(): void;
175
394
  }
176
395
  //# sourceMappingURL=ReactAuth.d.ts.map
177
396
  //#endregion
178
397
  //#region src/index.d.ts
398
+ declare module "alepha" {
399
+ interface State {
400
+ user?: UserAccountInfo;
401
+ }
402
+ }
179
403
  declare module "alepha/react" {
180
404
  interface PageReactContext {
181
- user?: UserAccountToken;
405
+ user?: UserAccountInfo;
182
406
  }
183
407
  interface ReactHydrationState {
184
- user?: ReactUser;
408
+ user?: UserAccountInfo;
185
409
  }
186
410
  }
187
411
  /**
@@ -190,9 +414,9 @@ declare module "alepha/react" {
190
414
  * @see {@link ReactAuthProvider}
191
415
  * @module alepha.react.auth
192
416
  */
193
- declare const AlephaReactAuth: _alepha_core0.ModuleDescriptor;
417
+ declare const AlephaReactAuth: _alepha_core0.Service<_alepha_core0.Module>;
194
418
  //# sourceMappingURL=index.d.ts.map
195
419
 
196
420
  //#endregion
197
- export { $auth, AccessToken, AlephaReactAuth, AuthDescriptor, AuthDescriptorOptions, AuthHook, AuthProvider, ReactAuth, ReactAuthProvider, ReactUser, SessionTokens, useAuth };
421
+ export { $auth, AccessToken, AlephaReactAuth, AuthDescriptor, AuthDescriptorOptions, AuthExternal, AuthInternal, CredentialsOptions, OAuth2Options, OAuth2UserInfo, OidcOptions, ReactAuth, ReactAuthProvider, useAuth };
198
422
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  'use strict';
2
- var m = require('@alepha/testing');
2
+ var m = require('@alepha/react-form');
3
3
  Object.keys(m).forEach(function (k) {
4
4
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
5
5
  enumerable: true,
@@ -0,0 +1,126 @@
1
+ import * as _alepha_core0 from "alepha";
2
+ import { Static, TObject, TSchema } from "alepha";
3
+ import { InputHTMLAttributes } from "react";
4
+
5
+ //#region src/hooks/useForm.d.ts
6
+
7
+ /**
8
+ * Custom hook to create a form with validation and field management.
9
+ * This hook uses TypeBox schemas to define the structure and validation rules for the form.
10
+ * It provides a way to handle form submission, field creation, and value management.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { t } from "alepha";
15
+ *
16
+ * const form = useForm({
17
+ * schema: t.object({
18
+ * username: t.string(),
19
+ * password: t.string(),
20
+ * }),
21
+ * handler: (values) => {
22
+ * console.log("Form submitted with values:", values);
23
+ * },
24
+ * });
25
+ *
26
+ * return (
27
+ * <form onSubmit={form.onSubmit}>
28
+ * <input {...form.input("username")} />
29
+ * <input {...form.input("password")} />
30
+ * <button type="submit">Submit</button>
31
+ * </form>
32
+ * );
33
+ * ```
34
+ */
35
+ declare const useForm: <T extends TObject>(options: UseFormOptions<T>) => UseFormReturn<T>;
36
+ declare const getValueFromInput: (input: FormDataEntryValue, schema: TSchema) => any;
37
+ declare const valueToInputEntry: (value: any) => string | number;
38
+ type UseFormOptions<T extends TObject> = {
39
+ /**
40
+ * The schema defining the structure and validation rules for the form.
41
+ * This should be a TypeBox schema object.
42
+ */
43
+ schema: T;
44
+ /**
45
+ * Callback function to handle form submission.
46
+ * This function will receive the parsed and validated form values.
47
+ */
48
+ handler: (values: Static<T>, args: {
49
+ form: HTMLFormElement;
50
+ }) => unknown;
51
+ /**
52
+ * Optional initial values for the form fields.
53
+ * This can be used to pre-populate the form with existing data.
54
+ */
55
+ initialValues?: Static<T>;
56
+ /**
57
+ * Optional function to create custom field attributes.
58
+ * This can be used to add custom validation, styles, or other attributes.
59
+ */
60
+ onCreateField?: (name: keyof Static<T> & string, schema: TSchema) => InputHTMLAttributes<unknown>;
61
+ /**
62
+ * If defined, this will generate a unique ID for each field, prefixed with this string.
63
+ *
64
+ * > "username" with id="form-123" will become "form-123-username".
65
+ *
66
+ * If omitted, IDs will not be generated.
67
+ */
68
+ id?: string;
69
+ onError?: (error: Error, args: {
70
+ form: HTMLFormElement;
71
+ }) => void;
72
+ onChange?: (key: string, value: any, store: Record<string, any>) => void;
73
+ };
74
+ type UseFormReturn<T extends TObject> = {
75
+ /**
76
+ * Function to handle form submission.
77
+ * This should be attached to the form's onSubmit event.
78
+ *
79
+ * @example
80
+ * ```tsx
81
+ * const form = useForm();
82
+ *
83
+ * return <form onSubmit={form.onSubmit}></form>;
84
+ * ```
85
+ */
86
+ onSubmit?: (event: FormEventLike) => void;
87
+ /**
88
+ * Creates an input field for the specified schema property.
89
+ */
90
+ input: SchemaToInput<T>;
91
+ };
92
+ type SchemaToInput<T extends TObject> = { [K in keyof T["properties"]]: T["properties"][K] extends TObject ? SchemaToInput<T["properties"][K]> : InputField };
93
+ interface FormEventLike {
94
+ currentTarget: HTMLFormElement;
95
+ preventDefault: () => void;
96
+ }
97
+ interface InputField {
98
+ path: string;
99
+ props: InputHTMLAttributesLike;
100
+ schema: TSchema;
101
+ set: (value: any) => void;
102
+ }
103
+ type InputHTMLAttributesLike = Pick<InputHTMLAttributes<unknown>, "id" | "name" | "type" | "value" | "defaultValue" | "onChange" | "required" | "maxLength" | "minLength" | "aria-label"> & {
104
+ value?: any;
105
+ defaultValue?: any;
106
+ };
107
+ //# sourceMappingURL=useForm.d.ts.map
108
+ //#endregion
109
+ //#region src/index.d.ts
110
+ /**
111
+ * React hooks for managing forms in Alepha applications.
112
+ *
113
+ * This module provides a set of hooks to simplify form handling, validation, and submission in React applications built with Alepha.
114
+ *
115
+ * It includes:
116
+ * - `useForm`: A hook for managing form state, validation, and submission.
117
+ *
118
+ * @see {@link useForm}
119
+ * @module alepha.react.form
120
+ */
121
+ declare const AlephaReactForm: _alepha_core0.Service<_alepha_core0.Module>;
122
+ //# sourceMappingURL=index.d.ts.map
123
+
124
+ //#endregion
125
+ export { AlephaReactForm, FormEventLike, InputField, InputHTMLAttributesLike, SchemaToInput, UseFormOptions, UseFormReturn, getValueFromInput, useForm, valueToInputEntry };
126
+ //# sourceMappingURL=index.d.ts.map
package/react/form.js ADDED
@@ -0,0 +1 @@
1
+ export * from '@alepha/react-form'