appos 0.4.3-0 → 0.5.0-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.
Files changed (43) hide show
  1. package/dist/exports/api/index.d.mts +3 -3
  2. package/dist/exports/api/index.mjs +34 -9
  3. package/dist/exports/api/workflows/index.d.mts +2 -2
  4. package/dist/exports/api/workflows/index.mjs +2 -2
  5. package/dist/exports/{auth-By0xx0MI.d.mts → auth-DVv5fNvd.d.mts} +166 -51
  6. package/dist/exports/cli/index.d.mts +2 -2
  7. package/dist/exports/cli/index.mjs +87 -13
  8. package/dist/exports/{constants-BePPc_yF.mjs → constants-BicCnEiJ.mjs} +7 -1
  9. package/dist/exports/{index-Bpo5QE7k.d.mts → index-D3decHVs.d.mts} +3 -3
  10. package/dist/exports/{openapi-crG3j4xx.mjs → openapi-uisUTLq7.mjs} +45 -102
  11. package/dist/exports/{send-email-Bgcdjy-e.mjs → send-email-CXxlkfFL.mjs} +1 -1
  12. package/dist/exports/{server-BlNxgHUc.mjs → server-CA4aI0U6.mjs} +6 -2
  13. package/dist/exports/storybook/index.d.ts +43 -0
  14. package/dist/exports/storybook/index.js +43 -0
  15. package/dist/exports/tests/api.d.mts +2 -2
  16. package/dist/exports/tests/api.mjs +3 -3
  17. package/dist/exports/vite/index.mjs +51 -2
  18. package/dist/exports/web/index.d.ts +718 -366
  19. package/dist/exports/web/index.js +1299 -792
  20. package/dist/exports/web/routes.d.mts +1 -1
  21. package/dist/exports/web/ssr.d.mts +2 -2
  22. package/package.json +35 -12
  23. package/src/storybook/.storybook/main.ts +100 -0
  24. package/src/storybook/.storybook/manager.ts +75 -0
  25. package/src/storybook/.storybook/preview.ts +37 -0
  26. package/src/storybook/components/ColorGrid.tsx +324 -0
  27. package/src/storybook/components/IconGallery.tsx +268 -0
  28. package/src/storybook/components/SpacingScale.tsx +236 -0
  29. package/src/storybook/components/TypographyScale.tsx +277 -0
  30. package/src/storybook/components/index.ts +3 -0
  31. package/src/storybook/docs/Introduction.mdx +29 -0
  32. package/src/storybook/docs/foundations/Colors.mdx +27 -0
  33. package/src/storybook/docs/foundations/Icons.mdx +26 -0
  34. package/src/storybook/docs/foundations/Spacing.mdx +23 -0
  35. package/src/storybook/docs/foundations/Typography.mdx +39 -0
  36. package/src/storybook/vite.config.ts +24 -0
  37. package/src/web/lib/colors.ts +220 -0
  38. package/src/web/routes/auth/_layout.tsx +5 -11
  39. package/src/web/ui/button.stories.tsx +260 -0
  40. package/src/web/ui/globals.css +2 -0
  41. package/src/web/ui/locales/en/ui.json +13 -30
  42. package/src/web/ui/locales/zh-CN/ui.json +17 -34
  43. package/src/web/ui/locales/zh-TW/ui.json +17 -34
@@ -1,5 +1,5 @@
1
- import { C as defineTestDatabase, D as defineLogger, E as Logger, S as defineMigrationOpts, T as DefineLoggerOptions, _ as DefineTestDatabaseOptions, a as AuthConfig, b as dbChanges, c as DefineAuthOptions, d as createAccessControl, f as defineAuth, g as DefineDatabaseOptions, h as Database, i as Auth, l as Role, n as AccessController, o as AuthPasskeyConfig, p as defineEndpointRateLimits, r as AuditAction, s as AuthSessionConfig, t as AccessControlRoles, u as auditActionSchema, v as MigrationType, w as migrationsSchema, x as defineDatabase, y as QualifiedTableNames } from "../auth-By0xx0MI.mjs";
2
- import { $ as StorageAttachment, A as defaultI18nConfig, At as EventBus, B as ServerConfig, Bt as Cache, C as scanAPIRoutes, Ct as defineQueue, D as loadMiddleware, Dt as DbChangeInput, E as defineMiddleware, Et as loadWorkflows, F as DefineAppContextOpts, Ft as defineEventBus, G as DefineStorageOptions, H as defineAppContainer, Ht as defineCache, I as SessionData, It as loadEvents, J as defineS3Disk, K as Storage, L as defineAppContext, Lt as Config, M as i18n, Mt as dbChangeInputSchema, N as defineAuthSchema, Nt as dbChangesEvent, Ot as DefineEventBusOptions, P as AppContext, Pt as defineEvent, Q as NewStorageVariantRecord, R as AppContainer, Rt as baseSchema, S as registerRoutes, St as WorkflowStartOptions, T as Middleware, Tt as defineWorkflow, U as DatabaseWithStorage, V as WorkerConfig, Vt as DefineCacheOptions, W as DefineS3DiskOptions, X as NewStorageAttachment, Y as defineStorage, Z as NewStorageBlob, _ as defineOpenAPIConfig, _t as QueueFactoryContext, a as defineRedisClient, at as defineStorageSchema, b as generateOpenAPIDocument, bt as WorkflowContext, c as DefineOpenAPIConfigInput, ct as Mailer, d as OpenAPIMethodSpec, dt as MailerPayloadReact, et as StorageBlob, f as OpenAPIObjectConfigV31, ft as MailerWithQueue, g as defineOpenAPI, gt as QueueFactory, h as ValidationErrorResponse, ht as Queue, i as RedisClient, it as StorageVariantRecord, j as defineI18n, jt as EventContext, k as I18nInitOptions, kt as Event, l as DefineOpenAPIReturn, lt as MailerPayload, m as RouteModule, mt as DefineQueueOptions, nt as StorageRelationsConfig, o as withOtelSpan, ot as DefineMailerOptions, p as OpenAPIRegistration, pt as defineMailer, q as StorageService, r as DefineRedisClientOptions, rt as StorageTables, s as DefineOpenAPIConfig, st as DefineMailerOptionsWithQueue, t as CustomTypeOptions, tt as StorageRelations, u as HandlerParams, ut as MailerPayloadHtml, v as defineOpenAPIEndpoint, vt as QueueRateLimit, w as writeOpenAPISpecs, wt as defineScheduledWorkflow, x as loadAndRegisterAPIRoutes, xt as WorkflowHandle, y as defineTypedResponses, yt as ScheduledWorkflowContext, z as Container, zt as defineConfig } from "../index-Bpo5QE7k.mjs";
1
+ import { A as defineLogger, C as dbChanges, D as migrationsSchema, E as defineTestDatabase, O as DefineLoggerOptions, S as QualifiedTableNames, T as defineMigrationOpts, a as AuthCaptchaConfig, b as DefineTestDatabaseOptions, c as AuthSessionConfig, d as Role, f as auditActionSchema, g as defineEndpointRateLimits, h as defineAuth, i as Auth, k as Logger, l as CaptchaProvider, m as createAccessControl, n as AccessController, o as AuthConfig, p as captchaProviders, r as AuditAction, s as AuthPasskeyConfig, t as AccessControlRoles, u as DefineAuthOptions, v as Database, w as defineDatabase, x as MigrationType, y as DefineDatabaseOptions } from "../auth-DVv5fNvd.mjs";
2
+ import { $ as StorageAttachment, A as defaultI18nConfig, At as EventBus, B as ServerConfig, Bt as Cache, C as scanAPIRoutes, Ct as defineQueue, D as loadMiddleware, Dt as DbChangeInput, E as defineMiddleware, Et as loadWorkflows, F as DefineAppContextOpts, Ft as defineEventBus, G as DefineStorageOptions, H as defineAppContainer, Ht as defineCache, I as SessionData, It as loadEvents, J as defineS3Disk, K as Storage, L as defineAppContext, Lt as Config, M as i18n, Mt as dbChangeInputSchema, N as defineAuthSchema, Nt as dbChangesEvent, Ot as DefineEventBusOptions, P as AppContext, Pt as defineEvent, Q as NewStorageVariantRecord, R as AppContainer, Rt as baseSchema, S as registerRoutes, St as WorkflowStartOptions, T as Middleware, Tt as defineWorkflow, U as DatabaseWithStorage, V as WorkerConfig, Vt as DefineCacheOptions, W as DefineS3DiskOptions, X as NewStorageAttachment, Y as defineStorage, Z as NewStorageBlob, _ as defineOpenAPIConfig, _t as QueueFactoryContext, a as defineRedisClient, at as defineStorageSchema, b as generateOpenAPIDocument, bt as WorkflowContext, c as DefineOpenAPIConfigInput, ct as Mailer, d as OpenAPIMethodSpec, dt as MailerPayloadReact, et as StorageBlob, f as OpenAPIObjectConfigV31, ft as MailerWithQueue, g as defineOpenAPI, gt as QueueFactory, h as ValidationErrorResponse, ht as Queue, i as RedisClient, it as StorageVariantRecord, j as defineI18n, jt as EventContext, k as I18nInitOptions, kt as Event, l as DefineOpenAPIReturn, lt as MailerPayload, m as RouteModule, mt as DefineQueueOptions, nt as StorageRelationsConfig, o as withOtelSpan, ot as DefineMailerOptions, p as OpenAPIRegistration, pt as defineMailer, q as StorageService, r as DefineRedisClientOptions, rt as StorageTables, s as DefineOpenAPIConfig, st as DefineMailerOptionsWithQueue, t as CustomTypeOptions, tt as StorageRelations, u as HandlerParams, ut as MailerPayloadHtml, v as defineOpenAPIEndpoint, vt as QueueRateLimit, w as writeOpenAPISpecs, wt as defineScheduledWorkflow, x as loadAndRegisterAPIRoutes, xt as WorkflowHandle, y as defineTypedResponses, yt as ScheduledWorkflowContext, z as Container, zt as defineConfig } from "../index-D3decHVs.mjs";
3
3
  import "../orm-CJrd147z.mjs";
4
4
  import "../instrumentation-CFIspF8-.mjs";
5
- export { AccessControlRoles, AccessController, AppContainer, AppContext, AuditAction, Auth, AuthConfig, AuthPasskeyConfig, AuthSessionConfig, Cache, Config, Container, CustomTypeOptions, Database, DatabaseWithStorage, DbChangeInput, DefineAppContextOpts, DefineAuthOptions, DefineCacheOptions, DefineDatabaseOptions, DefineEventBusOptions, DefineLoggerOptions, DefineMailerOptions, DefineMailerOptionsWithQueue, DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, DefineQueueOptions, DefineRedisClientOptions, DefineS3DiskOptions, DefineStorageOptions, DefineTestDatabaseOptions, Event, EventBus, EventContext, HandlerParams, I18nInitOptions, Logger, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, MailerWithQueue, Middleware, MigrationType, NewStorageAttachment, NewStorageBlob, NewStorageVariantRecord, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, QualifiedTableNames, Queue, QueueFactory, QueueFactoryContext, QueueRateLimit, RedisClient, Role, RouteModule, ScheduledWorkflowContext, ServerConfig, SessionData, Storage, StorageAttachment, StorageBlob, StorageRelations, StorageRelationsConfig, StorageService, StorageTables, StorageVariantRecord, ValidationErrorResponse, WorkerConfig, WorkflowContext, WorkflowHandle, WorkflowStartOptions, auditActionSchema, baseSchema, createAccessControl, dbChangeInputSchema, dbChanges, dbChangesEvent, defaultI18nConfig, defineAppContainer, defineAppContext, defineAuth, defineAuthSchema, defineCache, defineConfig, defineDatabase, defineEndpointRateLimits, defineEvent, defineEventBus, defineI18n, defineLogger, defineMailer, defineMiddleware, defineMigrationOpts, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineQueue, defineRedisClient, defineS3Disk, defineScheduledWorkflow, defineStorage, defineStorageSchema, defineTestDatabase, defineTypedResponses, defineWorkflow, generateOpenAPIDocument, i18n, loadAndRegisterAPIRoutes, loadEvents, loadMiddleware, loadWorkflows, migrationsSchema, registerRoutes, scanAPIRoutes, withOtelSpan, writeOpenAPISpecs };
5
+ export { AccessControlRoles, AccessController, AppContainer, AppContext, AuditAction, Auth, AuthCaptchaConfig, AuthConfig, AuthPasskeyConfig, AuthSessionConfig, Cache, CaptchaProvider, Config, Container, CustomTypeOptions, Database, DatabaseWithStorage, DbChangeInput, DefineAppContextOpts, DefineAuthOptions, DefineCacheOptions, DefineDatabaseOptions, DefineEventBusOptions, DefineLoggerOptions, DefineMailerOptions, DefineMailerOptionsWithQueue, DefineOpenAPIConfig, DefineOpenAPIConfigInput, DefineOpenAPIReturn, DefineQueueOptions, DefineRedisClientOptions, DefineS3DiskOptions, DefineStorageOptions, DefineTestDatabaseOptions, Event, EventBus, EventContext, HandlerParams, I18nInitOptions, Logger, Mailer, MailerPayload, MailerPayloadHtml, MailerPayloadReact, MailerWithQueue, Middleware, MigrationType, NewStorageAttachment, NewStorageBlob, NewStorageVariantRecord, OpenAPIMethodSpec, OpenAPIObjectConfigV31, OpenAPIRegistration, QualifiedTableNames, Queue, QueueFactory, QueueFactoryContext, QueueRateLimit, RedisClient, Role, RouteModule, ScheduledWorkflowContext, ServerConfig, SessionData, Storage, StorageAttachment, StorageBlob, StorageRelations, StorageRelationsConfig, StorageService, StorageTables, StorageVariantRecord, ValidationErrorResponse, WorkerConfig, WorkflowContext, WorkflowHandle, WorkflowStartOptions, auditActionSchema, baseSchema, captchaProviders, createAccessControl, dbChangeInputSchema, dbChanges, dbChangesEvent, defaultI18nConfig, defineAppContainer, defineAppContext, defineAuth, defineAuthSchema, defineCache, defineConfig, defineDatabase, defineEndpointRateLimits, defineEvent, defineEventBus, defineI18n, defineLogger, defineMailer, defineMiddleware, defineMigrationOpts, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineQueue, defineRedisClient, defineS3Disk, defineScheduledWorkflow, defineStorage, defineStorageSchema, defineTestDatabase, defineTypedResponses, defineWorkflow, generateOpenAPIDocument, i18n, loadAndRegisterAPIRoutes, loadEvents, loadMiddleware, loadWorkflows, migrationsSchema, registerRoutes, scanAPIRoutes, withOtelSpan, writeOpenAPISpecs };
@@ -1,14 +1,14 @@
1
1
  import { t as defineAppContext } from "../app-context-LF4QmPUC.mjs";
2
- import { _ as defineAuthSchema, a as loadWorkflows, c as generatePreview, d as dbChangeInputSchema, f as dbChangesEvent, g as defineRedisClient, h as loadEvents, i as defineWorkflow, l as generateImageVariant, m as defineEventBus, n as defineQueue, o as purgeAttachment, p as defineEvent, r as defineScheduledWorkflow, t as sendEmail, u as extractBlobMetadata } from "../send-email-Bgcdjy-e.mjs";
3
- import { f as PUBLIC_DIR, l as LOCALES_DIR } from "../constants-BePPc_yF.mjs";
4
- import { _ as defineMigrationOpts, a as generateOpenAPIDocument, c as scanAPIRoutes, d as loadMiddleware, f as ui_default$2, g as defineDatabase, h as dbChanges, i as defineTypedResponses, l as writeOpenAPISpecs, m as ui_default, n as defineOpenAPIConfig, o as loadAndRegisterAPIRoutes, p as ui_default$1, r as defineOpenAPIEndpoint, s as registerRoutes, t as defineOpenAPI, u as defineMiddleware, v as defineTestDatabase, y as migrationsSchema } from "../openapi-crG3j4xx.mjs";
2
+ import { _ as defineAuthSchema, a as loadWorkflows, c as generatePreview, d as dbChangeInputSchema, f as dbChangesEvent, g as defineRedisClient, h as loadEvents, i as defineWorkflow, l as generateImageVariant, m as defineEventBus, n as defineQueue, o as purgeAttachment, p as defineEvent, r as defineScheduledWorkflow, t as sendEmail, u as extractBlobMetadata } from "../send-email-CXxlkfFL.mjs";
3
+ import { p as PUBLIC_DIR, u as LOCALES_DIR } from "../constants-BicCnEiJ.mjs";
4
+ import { _ as defineMigrationOpts, a as generateOpenAPIDocument, c as scanAPIRoutes, d as loadMiddleware, f as ui_default$2, g as defineDatabase, h as dbChanges, i as defineTypedResponses, l as writeOpenAPISpecs, m as ui_default, n as defineOpenAPIConfig, o as loadAndRegisterAPIRoutes, p as ui_default$1, r as defineOpenAPIEndpoint, s as registerRoutes, t as defineOpenAPI, u as defineMiddleware, v as defineTestDatabase, y as migrationsSchema } from "../openapi-uisUTLq7.mjs";
5
5
  import { t as instrumentation_exports } from "../instrumentation-DkoLNAtz.mjs";
6
6
  import { _ as pgTable, c as orm_exports, t as index, w as unique } from "../orm-COJ9l6sS.mjs";
7
7
  import { passkey } from "@better-auth/passkey";
8
8
  import { sso } from "@better-auth/sso";
9
9
  import { betterAuth } from "better-auth";
10
10
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
11
- import { admin, anonymous, apiKey, emailOTP, magicLink, multiSession, phoneNumber, twoFactor, username } from "better-auth/plugins";
11
+ import { admin, anonymous, apiKey, captcha, emailOTP, lastLoginMethod, magicLink, multiSession, phoneNumber, twoFactor, username } from "better-auth/plugins";
12
12
  import { createAccessControl } from "better-auth/plugins/access";
13
13
  import { z } from "zod";
14
14
  import "@better-auth/passkey/client";
@@ -45,6 +45,21 @@ const AUTH_BASE_URL = "";
45
45
  //#endregion
46
46
  //#region src/api/auth.ts
47
47
  /**
48
+ * Array of all supported captcha providers.
49
+ * Use with z.enum() for config validation.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * CAPTCHA_PROVIDER: z.enum(captchaProviders).optional(),
54
+ * ```
55
+ */
56
+ const captchaProviders = [
57
+ "cloudflare-turnstile",
58
+ "google-recaptcha",
59
+ "hcaptcha",
60
+ "captchafox"
61
+ ];
62
+ /**
48
63
  * Standard audit log actions following OCSF/CADF standards. Zod enum provides
49
64
  * both runtime validation and TypeScript type.
50
65
  *
@@ -204,20 +219,30 @@ function defineAuth(opts) {
204
219
  trustEmailVerified: config.plugins.sso.trustEmailVerified,
205
220
  domainVerification: config.plugins.sso.domainVerification ? { enabled: true } : void 0
206
221
  }));
222
+ if (config.plugins?.lastUsedMethod) plugins.push(lastLoginMethod({ storeInDatabase: config.plugins.lastUsedMethod.storeInDatabase }));
223
+ if (config.plugins?.captcha) {
224
+ const captchaConfig = opts.captcha;
225
+ plugins.push(captcha({
226
+ provider: config.plugins.captcha.provider,
227
+ secretKey: captchaConfig?.secretKey ?? "",
228
+ endpoints: config.plugins.captcha.endpoints,
229
+ minScore: captchaConfig?.minScore
230
+ }));
231
+ }
207
232
  const socialProviders = {};
208
- if (config.oauth?.google) socialProviders.google = {
233
+ if (config.methods?.oauth?.google) socialProviders.google = {
209
234
  clientId: oauth?.google?.clientId ?? process.env.GOOGLE_CLIENT_ID ?? "",
210
235
  clientSecret: oauth?.google?.clientSecret ?? process.env.GOOGLE_CLIENT_SECRET ?? ""
211
236
  };
212
- if (config.oauth?.github) socialProviders.github = {
237
+ if (config.methods?.oauth?.github) socialProviders.github = {
213
238
  clientId: oauth?.github?.clientId ?? process.env.GITHUB_CLIENT_ID ?? "",
214
239
  clientSecret: oauth?.github?.clientSecret ?? process.env.GITHUB_CLIENT_SECRET ?? ""
215
240
  };
216
- if (config.oauth?.apple) socialProviders.apple = {
241
+ if (config.methods?.oauth?.apple) socialProviders.apple = {
217
242
  clientId: oauth?.apple?.clientId ?? process.env.APPLE_CLIENT_ID ?? "",
218
243
  clientSecret: oauth?.apple?.clientSecret ?? process.env.APPLE_CLIENT_SECRET ?? ""
219
244
  };
220
- if (config.oauth?.facebook) socialProviders.facebook = {
245
+ if (config.methods?.oauth?.facebook) socialProviders.facebook = {
221
246
  clientId: oauth?.facebook?.clientId ?? process.env.FACEBOOK_CLIENT_ID ?? "",
222
247
  clientSecret: oauth?.facebook?.clientSecret ?? process.env.FACEBOOK_CLIENT_SECRET ?? ""
223
248
  };
@@ -1515,4 +1540,4 @@ function defineStorageSchema() {
1515
1540
  }
1516
1541
 
1517
1542
  //#endregion
1518
- export { StorageService, auditActionSchema, baseSchema, createAccessControl, dbChangeInputSchema, dbChanges, dbChangesEvent, defaultI18nConfig, defineAppContainer, defineAppContext, defineAuth, defineAuthSchema, defineCache, defineConfig, defineDatabase, defineEndpointRateLimits, defineEvent, defineEventBus, defineI18n, defineLogger, defineMailer, defineMiddleware, defineMigrationOpts, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineQueue, defineRedisClient, defineS3Disk, defineScheduledWorkflow, defineStorage, defineStorageSchema, defineTestDatabase, defineTypedResponses, defineWorkflow, generateOpenAPIDocument, loadAndRegisterAPIRoutes, loadEvents, loadMiddleware, loadWorkflows, migrationsSchema, registerRoutes, scanAPIRoutes, withOtelSpan, writeOpenAPISpecs };
1543
+ export { StorageService, auditActionSchema, baseSchema, captchaProviders, createAccessControl, dbChangeInputSchema, dbChanges, dbChangesEvent, defaultI18nConfig, defineAppContainer, defineAppContext, defineAuth, defineAuthSchema, defineCache, defineConfig, defineDatabase, defineEndpointRateLimits, defineEvent, defineEventBus, defineI18n, defineLogger, defineMailer, defineMiddleware, defineMigrationOpts, defineOpenAPI, defineOpenAPIConfig, defineOpenAPIEndpoint, defineQueue, defineRedisClient, defineS3Disk, defineScheduledWorkflow, defineStorage, defineStorageSchema, defineTestDatabase, defineTypedResponses, defineWorkflow, generateOpenAPIDocument, loadAndRegisterAPIRoutes, loadEvents, loadMiddleware, loadWorkflows, migrationsSchema, registerRoutes, scanAPIRoutes, withOtelSpan, writeOpenAPISpecs };
@@ -1,5 +1,5 @@
1
- import "../../auth-By0xx0MI.mjs";
2
- import { St as WorkflowStartOptions, xt as WorkflowHandle, z as Container } from "../../index-Bpo5QE7k.mjs";
1
+ import "../../auth-DVv5fNvd.mjs";
2
+ import { St as WorkflowStartOptions, xt as WorkflowHandle, z as Container } from "../../index-D3decHVs.mjs";
3
3
  import "../../orm-CJrd147z.mjs";
4
4
  import "../../instrumentation-CFIspF8-.mjs";
5
5
  import { z } from "zod";
@@ -1,4 +1,4 @@
1
- import { s as trackDbChanges } from "../../send-email-Bgcdjy-e.mjs";
2
- import "../../constants-BePPc_yF.mjs";
1
+ import { s as trackDbChanges } from "../../send-email-CXxlkfFL.mjs";
2
+ import "../../constants-BicCnEiJ.mjs";
3
3
 
4
4
  export { trackDbChanges };
@@ -1,4 +1,5 @@
1
- import { betterAuth } from "better-auth";
1
+ import { PasskeyOptions } from "@better-auth/passkey";
2
+ import { BetterAuthOptions, betterAuth } from "better-auth";
2
3
  import { Role, createAccessControl } from "better-auth/plugins/access";
3
4
  import { z } from "zod";
4
5
  import * as drizzle_orm0 from "drizzle-orm";
@@ -183,6 +184,20 @@ type AccessController = ReturnType<typeof createAccessControl>;
183
184
  * Type for roles created via ac.newRole().
184
185
  */
185
186
  type AccessControlRoles = Record<string, Role>;
187
+ /**
188
+ * Array of all supported captcha providers.
189
+ * Use with z.enum() for config validation.
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * CAPTCHA_PROVIDER: z.enum(captchaProviders).optional(),
194
+ * ```
195
+ */
196
+ declare const captchaProviders: readonly ["cloudflare-turnstile", "google-recaptcha", "hcaptcha", "captchafox"];
197
+ /**
198
+ * Captcha provider type.
199
+ */
200
+ type CaptchaProvider = (typeof captchaProviders)[number];
186
201
  /**
187
202
  * Standard audit log actions following OCSF/CADF standards. Zod enum provides
188
203
  * both runtime validation and TypeScript type.
@@ -194,12 +209,12 @@ type AccessControlRoles = Record<string, Role>;
194
209
  */
195
210
  declare const auditActionSchema: z.ZodEnum<{
196
211
  DELETE: "DELETE";
212
+ INSERT: "INSERT";
213
+ UPDATE: "UPDATE";
197
214
  LOGIN: "LOGIN";
198
215
  LOGOUT: "LOGOUT";
199
- INSERT: "INSERT";
200
216
  PASSWORD_CHANGE: "PASSWORD_CHANGE";
201
217
  TRUNCATE: "TRUNCATE";
202
- UPDATE: "UPDATE";
203
218
  }>;
204
219
  /**
205
220
  * TypeScript type extracted from Zod enum.
@@ -296,15 +311,15 @@ interface AuthConfig {
296
311
  otpLength?: number;
297
312
  expiresIn?: number;
298
313
  };
299
- };
300
- /**
301
- * OAuth providers - true = enabled, undefined/false = disabled.
302
- **/
303
- oauth?: {
304
- google?: boolean;
305
- github?: boolean;
306
- apple?: boolean;
307
- facebook?: boolean;
314
+ /**
315
+ * OAuth providers - true = enabled, undefined/false = disabled.
316
+ **/
317
+ oauth?: {
318
+ google?: boolean;
319
+ github?: boolean;
320
+ apple?: boolean;
321
+ facebook?: boolean;
322
+ };
308
323
  };
309
324
  /**
310
325
  * Plugins - if defined, it's enabled.
@@ -381,10 +396,58 @@ interface AuthConfig {
381
396
  trustEmailVerified?: boolean;
382
397
  domainVerification?: boolean;
383
398
  };
399
+ /**
400
+ * Last used login method plugin. If defined, enabled.
401
+ * Tracks the most recent authentication method used by each user.
402
+ **/
403
+ lastUsedMethod?: {
404
+ /**
405
+ * Persist last used method to database for cross-device access.
406
+ *
407
+ * @default false (cookie-only storage)
408
+ */
409
+ storeInDatabase?: boolean;
410
+ };
411
+ /**
412
+ * Captcha plugin. If defined, enabled.
413
+ * Protects auth endpoints from bots and abuse.
414
+ **/
415
+ captcha?: {
416
+ /**
417
+ * Captcha provider to use.
418
+ * For Google reCAPTCHA: v2 vs v3 is determined by server-side minScore config.
419
+ */
420
+ provider: "cloudflare-turnstile" | "google-recaptcha" | "hcaptcha" | "captchafox";
421
+ /**
422
+ * Public site key for the captcha widget (safe to expose in client).
423
+ */
424
+ siteKey: string;
425
+ /**
426
+ * Endpoints to protect with captcha validation.
427
+ * Uses substring matching via `request.url.includes(endpoint)`.
428
+ *
429
+ * @default ["/sign-up/email", "/sign-in/email", "/request-password-reset"]
430
+ *
431
+ * @example
432
+ * ```typescript
433
+ * // Protect high-risk endpoints (recommended)
434
+ * endpoints: [
435
+ * "/sign-up/email",
436
+ * "/sign-in/email",
437
+ * "/sign-in/magic-link",
438
+ * "/request-password-reset",
439
+ * "/email-otp/send-verification-otp",
440
+ * "/send-verification-email",
441
+ * "/phone-number/send-otp",
442
+ * ]
443
+ * ```
444
+ */
445
+ endpoints?: string[];
446
+ };
384
447
  };
385
448
  /**
386
449
  * Brand configuration for auth pages.
387
- * Controls the logo and app name displayed on authentication screens.
450
+ * Controls the logo, app name, layout, and legal URLs displayed on authentication screens.
388
451
  */
389
452
  brand?: {
390
453
  /**
@@ -405,6 +468,27 @@ interface AuthConfig {
405
468
  * @default "AppOS"
406
469
  */
407
470
  name?: string;
471
+ /**
472
+ * URL to the privacy policy page.
473
+ *
474
+ * @default "/legal/privacy-policy"
475
+ */
476
+ privacyUrl?: string;
477
+ /**
478
+ * URL to the terms of service page.
479
+ *
480
+ * @default "/legal/terms"
481
+ */
482
+ termsUrl?: string;
483
+ /**
484
+ * Layout variant for auth pages.
485
+ * - "centered": Card centered on page (default)
486
+ * - "split": Two-column layout with branding on left
487
+ * - "minimal": Simple centered layout without trust signals
488
+ *
489
+ * @default "centered"
490
+ */
491
+ layoutVariant?: "centered" | "split" | "minimal";
408
492
  };
409
493
  /**
410
494
  * Rate limiting configuration for auth endpoints.
@@ -508,8 +592,10 @@ type RequiredHooks<T extends AuthConfig> = (T["methods"] extends {
508
592
  * Conditionally required OAuth credentials based on config.
509
593
  * If an OAuth provider is enabled in config, its credentials are REQUIRED.
510
594
  */
511
- type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
512
- google: true;
595
+ type RequiredOAuth<T extends AuthConfig> = (T["methods"] extends {
596
+ oauth: {
597
+ google: true;
598
+ };
513
599
  } ? {
514
600
  google: {
515
601
  clientId: string;
@@ -520,8 +606,10 @@ type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
520
606
  clientId: string;
521
607
  clientSecret: string;
522
608
  };
523
- }) & (T["oauth"] extends {
524
- github: true;
609
+ }) & (T["methods"] extends {
610
+ oauth: {
611
+ github: true;
612
+ };
525
613
  } ? {
526
614
  github: {
527
615
  clientId: string;
@@ -532,8 +620,10 @@ type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
532
620
  clientId: string;
533
621
  clientSecret: string;
534
622
  };
535
- }) & (T["oauth"] extends {
536
- apple: true;
623
+ }) & (T["methods"] extends {
624
+ oauth: {
625
+ apple: true;
626
+ };
537
627
  } ? {
538
628
  apple: {
539
629
  clientId: string;
@@ -544,8 +634,10 @@ type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
544
634
  clientId: string;
545
635
  clientSecret: string;
546
636
  };
547
- }) & (T["oauth"] extends {
548
- facebook: true;
637
+ }) & (T["methods"] extends {
638
+ oauth: {
639
+ facebook: true;
640
+ };
549
641
  } ? {
550
642
  facebook: {
551
643
  clientId: string;
@@ -560,14 +652,22 @@ type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
560
652
  /**
561
653
  * Check if any OAuth provider is enabled.
562
654
  **/
563
- type HasOAuthEnabled<T extends AuthConfig> = T["oauth"] extends {
564
- google: true;
655
+ type HasOAuthEnabled<T extends AuthConfig> = T["methods"] extends {
656
+ oauth: {
657
+ google: true;
658
+ };
565
659
  } | {
566
- github: true;
660
+ oauth: {
661
+ github: true;
662
+ };
567
663
  } | {
568
- apple: true;
664
+ oauth: {
665
+ apple: true;
666
+ };
569
667
  } | {
570
- facebook: true;
668
+ oauth: {
669
+ facebook: true;
670
+ };
571
671
  } ? true : false;
572
672
  /**
573
673
  * Check if passkey is enabled
@@ -575,41 +675,52 @@ type HasOAuthEnabled<T extends AuthConfig> = T["oauth"] extends {
575
675
  type HasPasskeyEnabled<T extends AuthConfig> = T["methods"] extends {
576
676
  passkey: object;
577
677
  } ? true : false;
678
+ /**
679
+ * Check if captcha is enabled
680
+ **/
681
+ type HasCaptchaEnabled<T extends AuthConfig> = T["plugins"] extends {
682
+ captcha: object;
683
+ } ? true : false;
684
+ /**
685
+ * Helper type to extract Better Auth's session options.
686
+ */
687
+ type BetterAuthSessionOptions = NonNullable<BetterAuthOptions["session"]>;
578
688
  /**
579
689
  * Server-only session configuration.
690
+ * Derived from Better Auth's BetterAuthOptions['session'] for type safety.
580
691
  */
581
- interface AuthSessionConfig {
582
- /**
583
- * Session duration in seconds.
584
- *
585
- * @default 604800 (7 days)
586
- */
587
- expiresIn?: number;
588
- /**
589
- * How often to update session in seconds.
590
- *
591
- * @default 86400 (1 day)
592
- */
593
- updateAge?: number;
692
+ type AuthSessionConfig = Pick<BetterAuthSessionOptions, "expiresIn" | "updateAge" | "freshAge">;
693
+ /**
694
+ * Server-only passkey configuration (required if passkey is enabled).
695
+ * Derived from Better Auth's PasskeyOptions with rpID made required
696
+ * and origin narrowed to string (appos doesn't support array origins).
697
+ */
698
+ type AuthPasskeyConfig = Required<Pick<PasskeyOptions, "rpID">> & {
594
699
  /**
595
- * Session freshness in seconds for sensitive ops.
596
- *
597
- * @default 86400 (1 day)
700
+ * Origin URL for passkey verification (e.g., "http://localhost:8000").
701
+ * Unlike Better Auth which supports string | string[] | null, appos
702
+ * requires a single origin string for simplicity.
598
703
  */
599
- freshAge?: number;
600
- }
704
+ origin: string;
705
+ };
601
706
  /**
602
- * Server-only passkey configuration (required if passkey is enabled).
707
+ * Server-only captcha configuration (required if captcha is enabled).
708
+ * These fields align with Better Auth's captcha plugin options.
603
709
  */
604
- interface AuthPasskeyConfig {
710
+ interface AuthCaptchaConfig {
605
711
  /**
606
- * Relying Party ID - domain for passkey (e.g., "example.com" or "localhost").
712
+ * Secret key for server-side captcha validation.
713
+ * Keep this secret - never expose in client code.
607
714
  */
608
- rpID: string;
715
+ secretKey: string;
609
716
  /**
610
- * Origin URL for passkey verification (e.g., "http://localhost:8000").
717
+ * Minimum score threshold for Google reCAPTCHA v3.
718
+ * Scores range from 0.0 (bot) to 1.0 (human).
719
+ * Only applicable when using Google reCAPTCHA.
720
+ *
721
+ * @default 0.5
611
722
  */
612
- origin: string;
723
+ minScore?: number;
613
724
  }
614
725
  /**
615
726
  * Fully type-safe options for defineAuth().
@@ -676,6 +787,10 @@ type DefineAuthOptions<T extends AuthConfig, TDb = unknown> = {
676
787
  passkey: AuthPasskeyConfig;
677
788
  } : {
678
789
  passkey?: AuthPasskeyConfig;
790
+ }) & (HasCaptchaEnabled<T> extends true ? {
791
+ captcha: AuthCaptchaConfig;
792
+ } : {
793
+ captcha?: AuthCaptchaConfig;
679
794
  });
680
795
  /**
681
796
  * Rate limit rule for a single endpoint.
@@ -756,4 +871,4 @@ declare function defineAuth<T extends AuthConfig, TDb extends Record<"primary",
756
871
  */
757
872
  type Auth$1<TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>> = ReturnType<typeof defineAuth<AuthConfig, TDb>>;
758
873
  //#endregion
759
- export { defineTestDatabase as C, defineLogger as D, Logger as E, defineMigrationOpts as S, DefineLoggerOptions as T, DefineTestDatabaseOptions as _, AuthConfig as a, dbChanges as b, DefineAuthOptions as c, createAccessControl as d, defineAuth as f, DefineDatabaseOptions as g, Database as h, Auth$1 as i, Role as l, AuthPaths as m, AccessController as n, AuthPasskeyConfig as o, defineEndpointRateLimits as p, AuditAction as r, AuthSessionConfig as s, AccessControlRoles as t, auditActionSchema as u, MigrationType as v, migrationsSchema as w, defineDatabase as x, QualifiedTableNames as y };
874
+ export { defineLogger as A, dbChanges as C, migrationsSchema as D, defineTestDatabase as E, DefineLoggerOptions as O, QualifiedTableNames as S, defineMigrationOpts as T, AuthPaths as _, AuthCaptchaConfig as a, DefineTestDatabaseOptions as b, AuthSessionConfig as c, Role as d, auditActionSchema as f, defineEndpointRateLimits as g, defineAuth as h, Auth$1 as i, Logger as k, CaptchaProvider as l, createAccessControl as m, AccessController as n, AuthConfig as o, captchaProviders as p, AuditAction as r, AuthPasskeyConfig as s, AccessControlRoles as t, DefineAuthOptions as u, Database as v, defineDatabase as w, MigrationType as x, DefineDatabaseOptions as y };
@@ -1,5 +1,5 @@
1
- import "../auth-By0xx0MI.mjs";
2
- import { z as Container } from "../index-Bpo5QE7k.mjs";
1
+ import "../auth-DVv5fNvd.mjs";
2
+ import { z as Container } from "../index-D3decHVs.mjs";
3
3
  import "../orm-CJrd147z.mjs";
4
4
  import "../instrumentation-CFIspF8-.mjs";
5
5
  import { z } from "zod";
@@ -1,9 +1,9 @@
1
1
  import "../app-context-LF4QmPUC.mjs";
2
- import { a as loadWorkflows, h as loadEvents } from "../send-email-Bgcdjy-e.mjs";
3
- import { a as DATABASES_DIR, c as FIXTURES_DIR, h as WEB_DIR, i as COMMANDS_DIR, m as TEST_EXTENSIONS, n as BUILD_DIR, s as FILE_EXT, t as APPOS_DIR, u as MAIN_ENTRY } from "../constants-BePPc_yF.mjs";
4
- import { _ as defineMigrationOpts } from "../openapi-crG3j4xx.mjs";
2
+ import { a as loadWorkflows, h as loadEvents } from "../send-email-CXxlkfFL.mjs";
3
+ import { a as DATABASES_DIR, c as FILE_EXT, d as MAIN_ENTRY, g as WEB_DIR, h as TEST_EXTENSIONS, i as COMMANDS_DIR, l as FIXTURES_DIR, n as BUILD_DIR, t as APPOS_DIR } from "../constants-BicCnEiJ.mjs";
4
+ import { _ as defineMigrationOpts } from "../openapi-uisUTLq7.mjs";
5
5
  import "../instrumentation-DkoLNAtz.mjs";
6
- import { t as defineServer } from "../server-BlNxgHUc.mjs";
6
+ import { t as defineServer } from "../server-CA4aI0U6.mjs";
7
7
  import "../ssr-BsfNjYlJ.mjs";
8
8
  import { createRequire } from "node:module";
9
9
  import { z } from "zod";
@@ -431,14 +431,33 @@ var build_default = defineCommand({
431
431
  } catch {
432
432
  hasWebDir = false;
433
433
  }
434
- if (hasWebDir) try {
435
- await ctx.spinner("Building React Router app", async () => {
436
- const viteBin = await findBin("vite");
437
- await ctx.exec(viteBin, ["build"]);
438
- });
439
- ctx.success("Built React Router app successfully");
440
- } catch (error) {
441
- ctx.fail(error instanceof Error ? error.message : String(error));
434
+ if (hasWebDir) {
435
+ try {
436
+ await ctx.spinner("Building React Router app", async () => {
437
+ const viteBin = await findBin("vite");
438
+ await ctx.exec(viteBin, ["build"]);
439
+ });
440
+ ctx.success("Built React Router app successfully");
441
+ } catch (error) {
442
+ ctx.fail(error instanceof Error ? error.message : String(error));
443
+ }
444
+ const configDir = join(dirname(createRequire(import.meta.url).resolve("appos/package.json")), "src/storybook/.storybook");
445
+ if (existsSync(configDir)) try {
446
+ await ctx.spinner("Building design system", async () => {
447
+ const storybookBin = await findBin("storybook");
448
+ await ctx.exec(storybookBin, [
449
+ "build",
450
+ "-o",
451
+ `${BUILD_DIR}/storybook`,
452
+ "--config-dir",
453
+ configDir,
454
+ "--quiet"
455
+ ]);
456
+ });
457
+ ctx.success("Built design system successfully");
458
+ } catch (error) {
459
+ ctx.warn(`Storybook build failed: ${error instanceof Error ? error.message : String(error)}`);
460
+ }
442
461
  }
443
462
  const entryPoints = await collectEntryPoints();
444
463
  const outdir = `./${BUILD_DIR}`;
@@ -1404,7 +1423,7 @@ var preview_default = defineCommand({
1404
1423
 
1405
1424
  //#endregion
1406
1425
  //#region package.json
1407
- var version = "0.4.3-0";
1426
+ var version = "0.5.0-0";
1408
1427
 
1409
1428
  //#endregion
1410
1429
  //#region src/cli/commands/repl.ts
@@ -1526,6 +1545,7 @@ var start_default = defineCommand({
1526
1545
  const startWorker = !opts.service || opts.service === "worker";
1527
1546
  let server = null;
1528
1547
  let worker = null;
1548
+ let storybookProc = null;
1529
1549
  let isShuttingDown = false;
1530
1550
  /**
1531
1551
  * Graceful shutdown handler.
@@ -1535,6 +1555,10 @@ var start_default = defineCommand({
1535
1555
  isShuttingDown = true;
1536
1556
  logger.info(`Shutdown initiated (${signal})`);
1537
1557
  try {
1558
+ if (storybookProc && !storybookProc.killed) {
1559
+ storybookProc.kill("SIGKILL");
1560
+ logger.info("Design system stopped");
1561
+ }
1538
1562
  if (server) {
1539
1563
  await server.stop();
1540
1564
  logger.info("HTTP server stopped");
@@ -1560,6 +1584,56 @@ var start_default = defineCommand({
1560
1584
  server = await defineServer({ container });
1561
1585
  await server.start();
1562
1586
  logger.info(`HTTP server ready at http://${server.host}:${server.port} ${runtimeInfo}`);
1587
+ if (process.env.NODE_ENV !== "production") {
1588
+ const configDir = join(dirname(createRequire(import.meta.url).resolve("appos/package.json")), "src/storybook/.storybook");
1589
+ let binPath = "";
1590
+ let dir = process.cwd();
1591
+ while (dir !== "/") {
1592
+ const candidate = join(dir, "node_modules", ".bin");
1593
+ if (existsSync(candidate)) {
1594
+ binPath = candidate;
1595
+ break;
1596
+ }
1597
+ dir = dirname(dir);
1598
+ }
1599
+ const { spawn: spawn$1 } = await import("node:child_process");
1600
+ storybookProc = spawn$1("storybook", [
1601
+ "dev",
1602
+ "-p",
1603
+ "6006",
1604
+ "--no-open",
1605
+ "--config-dir",
1606
+ configDir
1607
+ ], {
1608
+ stdio: "ignore",
1609
+ cwd: process.cwd(),
1610
+ env: {
1611
+ ...process.env,
1612
+ PATH: binPath ? `${binPath}:${process.env.PATH}` : process.env.PATH
1613
+ }
1614
+ });
1615
+ storybookProc.on("exit", (code) => {
1616
+ if (code !== 0 && code !== null && !isShuttingDown) logger.error(`Design system exited with code ${code}`);
1617
+ storybookProc = null;
1618
+ });
1619
+ storybookProc.on("error", (err) => {
1620
+ if (!isShuttingDown) logger.error(`Design system spawn error: ${err.message}`);
1621
+ });
1622
+ /**
1623
+ * Waits for a port to become available by polling.
1624
+ */
1625
+ const waitForPort = async (port, timeout) => {
1626
+ const start = Date.now();
1627
+ while (Date.now() - start < timeout) try {
1628
+ await fetch(`http://localhost:${port}`);
1629
+ return true;
1630
+ } catch {
1631
+ await new Promise((r) => setTimeout(r, 200));
1632
+ }
1633
+ return false;
1634
+ };
1635
+ if (!await waitForPort(6006, 3e4) && storybookProc && !storybookProc.killed) logger.warn("Design system slow to start, /design may not be ready yet");
1636
+ }
1563
1637
  }
1564
1638
  }
1565
1639
  });
@@ -163,6 +163,12 @@ const FIXTURES_DIR = "__fixtures__";
163
163
  * @default [".test.ts", ".spec.ts"]
164
164
  */
165
165
  const TEST_EXTENSIONS = [".test.ts", ".spec.ts"];
166
+ /**
167
+ * URL path for Storybook design system.
168
+ *
169
+ * @default "/design"
170
+ */
171
+ const DESIGN_SYSTEM_PATH = "/design";
166
172
 
167
173
  //#endregion
168
- export { DATABASES_DIR as a, FIXTURES_DIR as c, MIDDLEWARE_DIR as d, PUBLIC_DIR as f, WORKFLOWS_DIR as g, WEB_DIR as h, COMMANDS_DIR as i, LOCALES_DIR as l, TEST_EXTENSIONS as m, BUILD_DIR as n, EVENTS_DIR as o, ROUTES_DIR as p, BUILD_OUTPUT_DIR as r, FILE_EXT as s, APPOS_DIR as t, MAIN_ENTRY as u };
174
+ export { WORKFLOWS_DIR as _, DATABASES_DIR as a, FILE_EXT as c, MAIN_ENTRY as d, MIDDLEWARE_DIR as f, WEB_DIR as g, TEST_EXTENSIONS as h, COMMANDS_DIR as i, FIXTURES_DIR as l, ROUTES_DIR as m, BUILD_DIR as n, DESIGN_SYSTEM_PATH as o, PUBLIC_DIR as p, BUILD_OUTPUT_DIR as r, EVENTS_DIR as s, APPOS_DIR as t, LOCALES_DIR as u };