@rebasepro/server-core 0.7.0 → 0.8.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 (155) hide show
  1. package/build-errors.txt +52 -0
  2. package/dist/api/ast-schema-editor.d.ts +21 -0
  3. package/dist/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
  4. package/dist/api/errors.d.ts +53 -0
  5. package/dist/api/graphql/graphql-schema-generator.d.ts +44 -0
  6. package/dist/api/graphql/index.d.ts +1 -0
  7. package/dist/api/index.d.ts +9 -0
  8. package/dist/api/logs-routes.d.ts +37 -0
  9. package/dist/api/openapi-generator.d.ts +16 -0
  10. package/dist/api/rest/api-generator.d.ts +76 -0
  11. package/dist/api/rest/index.d.ts +1 -0
  12. package/dist/api/rest/query-parser.d.ts +8 -0
  13. package/dist/api/schema-editor-routes.d.ts +3 -0
  14. package/dist/api/server.d.ts +40 -0
  15. package/dist/api/types.d.ts +104 -0
  16. package/dist/auth/adapter-middleware.d.ts +43 -0
  17. package/dist/auth/admin-roles-route.d.ts +18 -0
  18. package/dist/auth/admin-user-ops.d.ts +79 -0
  19. package/dist/auth/admin-users-route.d.ts +28 -0
  20. package/dist/auth/api-keys/api-key-middleware.d.ts +39 -0
  21. package/dist/auth/api-keys/api-key-permission-guard.d.ts +32 -0
  22. package/dist/auth/api-keys/api-key-routes.d.ts +20 -0
  23. package/dist/auth/api-keys/api-key-store.d.ts +35 -0
  24. package/dist/auth/api-keys/api-key-types.d.ts +96 -0
  25. package/dist/auth/api-keys/index.d.ts +17 -0
  26. package/dist/auth/apple-oauth.d.ts +30 -0
  27. package/dist/auth/auth-hooks.d.ts +242 -0
  28. package/dist/auth/bitbucket-oauth.d.ts +11 -0
  29. package/dist/auth/builtin-auth-adapter.d.ts +51 -0
  30. package/dist/auth/crypto-utils.d.ts +16 -0
  31. package/dist/auth/custom-auth-adapter.d.ts +39 -0
  32. package/dist/auth/discord-oauth.d.ts +14 -0
  33. package/dist/auth/facebook-oauth.d.ts +14 -0
  34. package/dist/auth/github-oauth.d.ts +15 -0
  35. package/dist/auth/gitlab-oauth.d.ts +13 -0
  36. package/dist/auth/google-oauth.d.ts +47 -0
  37. package/dist/auth/index.d.ts +37 -0
  38. package/dist/auth/interfaces.d.ts +431 -0
  39. package/dist/auth/jwt.d.ts +55 -0
  40. package/dist/auth/linkedin-oauth.d.ts +18 -0
  41. package/dist/auth/magic-link-routes.d.ts +30 -0
  42. package/dist/auth/mfa-crypto.d.ts +23 -0
  43. package/dist/auth/mfa-routes.d.ts +7 -0
  44. package/dist/auth/mfa.d.ts +49 -0
  45. package/dist/auth/microsoft-oauth.d.ts +16 -0
  46. package/dist/auth/middleware.d.ts +113 -0
  47. package/dist/auth/password.d.ts +22 -0
  48. package/dist/auth/rate-limiter.d.ts +50 -0
  49. package/dist/auth/reset-password-admin.d.ts +29 -0
  50. package/dist/auth/rls-scope.d.ts +31 -0
  51. package/dist/auth/routes.d.ts +35 -0
  52. package/dist/auth/session-routes.d.ts +27 -0
  53. package/dist/auth/slack-oauth.d.ts +12 -0
  54. package/dist/auth/spotify-oauth.d.ts +12 -0
  55. package/dist/auth/twitter-oauth.d.ts +18 -0
  56. package/dist/backend-CIxN4FVm.js +15 -0
  57. package/dist/backend-CIxN4FVm.js.map +1 -0
  58. package/dist/base64-js-C_frYBkI.js +1687 -0
  59. package/dist/base64-js-C_frYBkI.js.map +1 -0
  60. package/dist/chunk-Dze3rakg.js +42 -0
  61. package/dist/collections/BackendCollectionRegistry.d.ts +13 -0
  62. package/dist/collections/loader.d.ts +5 -0
  63. package/dist/cron/cron-loader.d.ts +17 -0
  64. package/dist/cron/cron-routes.d.ts +14 -0
  65. package/dist/cron/cron-scheduler.d.ts +106 -0
  66. package/dist/cron/cron-store.d.ts +32 -0
  67. package/dist/cron/index.d.ts +6 -0
  68. package/dist/db/interfaces.d.ts +18 -0
  69. package/dist/dist-DMO-zF6D.js +832 -0
  70. package/dist/dist-DMO-zF6D.js.map +1 -0
  71. package/dist/email/index.d.ts +6 -0
  72. package/dist/email/smtp-email-service.d.ts +25 -0
  73. package/dist/email/templates.d.ts +50 -0
  74. package/dist/email/types.d.ts +126 -0
  75. package/dist/env.d.ts +102 -0
  76. package/dist/from-VbwD7xRf.js +3849 -0
  77. package/dist/from-VbwD7xRf.js.map +1 -0
  78. package/dist/functions/define-function.d.ts +50 -0
  79. package/dist/functions/function-loader.d.ts +17 -0
  80. package/dist/functions/function-routes.d.ts +10 -0
  81. package/dist/functions/index.d.ts +5 -0
  82. package/dist/history/history-routes.d.ts +23 -0
  83. package/dist/history/index.d.ts +1 -0
  84. package/dist/index.d.ts +31 -0
  85. package/dist/index.es.js +61322 -0
  86. package/dist/index.es.js.map +1 -0
  87. package/dist/index.umd.js +103633 -0
  88. package/dist/index.umd.js.map +1 -0
  89. package/dist/init/docs.d.ts +4 -0
  90. package/dist/init/health.d.ts +2 -0
  91. package/dist/init/middlewares.d.ts +10 -0
  92. package/dist/init/shutdown.d.ts +11 -0
  93. package/dist/init/storage.d.ts +5 -0
  94. package/dist/init.d.ts +314 -0
  95. package/dist/jws-BqRRaK11.js +616 -0
  96. package/dist/jws-BqRRaK11.js.map +1 -0
  97. package/dist/jwt-BETC8a1J.js +3560 -0
  98. package/dist/jwt-BETC8a1J.js.map +1 -0
  99. package/dist/logger-BYU66ENZ.js +94 -0
  100. package/dist/logger-BYU66ENZ.js.map +1 -0
  101. package/dist/ms-BeBSuOXN.js +125 -0
  102. package/dist/ms-BeBSuOXN.js.map +1 -0
  103. package/dist/multipart-parser-CedBDOeC.js +299 -0
  104. package/dist/multipart-parser-CedBDOeC.js.map +1 -0
  105. package/dist/serve-spa.d.ts +30 -0
  106. package/dist/services/driver-registry.d.ts +78 -0
  107. package/dist/services/routed-realtime-service.d.ts +43 -0
  108. package/dist/services/webhook-service.d.ts +29 -0
  109. package/dist/singleton.d.ts +35 -0
  110. package/dist/src-CB2PIpBe.js +1182 -0
  111. package/dist/src-CB2PIpBe.js.map +1 -0
  112. package/dist/src-DjzOT1kG.js +29746 -0
  113. package/dist/src-DjzOT1kG.js.map +1 -0
  114. package/dist/storage/GCSStorageController.d.ts +43 -0
  115. package/dist/storage/LocalStorageController.d.ts +46 -0
  116. package/dist/storage/S3StorageController.d.ts +36 -0
  117. package/dist/storage/image-transform.d.ts +50 -0
  118. package/dist/storage/index.d.ts +31 -0
  119. package/dist/storage/routes.d.ts +70 -0
  120. package/dist/storage/storage-registry.d.ts +78 -0
  121. package/dist/storage/tus-handler.d.ts +53 -0
  122. package/dist/storage/types.d.ts +128 -0
  123. package/dist/types/index.d.ts +11 -0
  124. package/dist/utils/dev-port.d.ts +37 -0
  125. package/dist/utils/logger.d.ts +31 -0
  126. package/dist/utils/logging.d.ts +9 -0
  127. package/dist/utils/request-id.d.ts +4 -0
  128. package/dist/utils/request-logger.d.ts +19 -0
  129. package/dist/utils/sql.d.ts +27 -0
  130. package/package.json +22 -14
  131. package/src/api/graphql/graphql-schema-generator.ts +5 -5
  132. package/src/api/openapi-generator.ts +2 -2
  133. package/src/api/rest/api-generator.ts +44 -123
  134. package/src/api/rest/query-parser.ts +6 -23
  135. package/src/api/types.ts +2 -2
  136. package/src/auth/auth-hooks.ts +1 -1
  137. package/src/auth/builtin-auth-adapter.ts +1 -2
  138. package/src/auth/interfaces.ts +11 -2
  139. package/src/auth/middleware.ts +4 -4
  140. package/src/auth/routes.ts +1 -2
  141. package/src/functions/define-function.ts +59 -0
  142. package/src/functions/function-loader.ts +16 -0
  143. package/src/functions/index.ts +2 -0
  144. package/src/index.ts +70 -37
  145. package/src/init.ts +78 -21
  146. package/src/storage/GCSStorageController.ts +334 -0
  147. package/src/storage/index.ts +9 -3
  148. package/src/storage/routes.ts +191 -23
  149. package/src/storage/tus-handler.ts +16 -4
  150. package/src/storage/types.ts +25 -3
  151. package/test/api-generator.test.ts +1 -1
  152. package/test/auth-config-types.test.ts +40 -0
  153. package/test/define-function.test.ts +45 -0
  154. package/test/storage-routes.test.ts +160 -0
  155. package/test/backend-hooks-data.test.ts +0 -477
@@ -0,0 +1,49 @@
1
+ /**
2
+ * TOTP (Time-based One-Time Password) implementation.
3
+ *
4
+ * Pure Node.js crypto implementation — no external dependencies required.
5
+ * Implements RFC 6238 (TOTP) and RFC 4226 (HOTP).
6
+ */
7
+ /**
8
+ * Encode a Buffer to Base32 string (RFC 4648)
9
+ */
10
+ export declare function base32Encode(buffer: Buffer): string;
11
+ /**
12
+ * Decode a Base32 string to Buffer
13
+ */
14
+ export declare function base32Decode(encoded: string): Buffer;
15
+ /**
16
+ * Generate a TOTP value for the current time step
17
+ */
18
+ export declare function generateTotp(secret: Buffer, timeStep?: number): string;
19
+ /**
20
+ * Verify a TOTP token with a configurable time window
21
+ *
22
+ * @param secret - The shared secret as a Buffer
23
+ * @param token - The 6-digit TOTP code to verify
24
+ * @param window - Number of time steps to check on each side (default: 1)
25
+ * @returns true if the token is valid within the window
26
+ */
27
+ export declare function verifyTotp(secret: Buffer, token: string, window?: number): boolean;
28
+ /**
29
+ * Generate a new TOTP secret and return the setup information
30
+ *
31
+ * @param issuer - The issuer name (app name) for the QR code
32
+ * @param accountName - The account identifier (usually email)
33
+ * @returns Object with base32 secret and otpauth URI
34
+ */
35
+ export declare function generateTotpSecret(issuer: string, accountName: string): {
36
+ secret: string;
37
+ uri: string;
38
+ };
39
+ /**
40
+ * Generate a set of one-time recovery codes
41
+ *
42
+ * @param count - Number of recovery codes to generate (default: 10)
43
+ * @returns Array of formatted recovery code strings (e.g. "A1B2C-D3E4F")
44
+ */
45
+ export declare function generateRecoveryCodes(count?: number): string[];
46
+ /**
47
+ * Hash a recovery code for storage
48
+ */
49
+ export declare function hashRecoveryCode(code: string): string;
@@ -0,0 +1,16 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Microsoft / Entra ID (Azure AD) OAuth Provider integration.
4
+ *
5
+ * Supports both personal Microsoft accounts and work/school (Azure AD) accounts
6
+ * via the "common" tenant endpoint. Uses the authorization code flow.
7
+ */
8
+ export declare function createMicrosoftProvider(config: {
9
+ clientId: string;
10
+ clientSecret: string;
11
+ /** Tenant ID. Defaults to "common" which allows both personal and organizational accounts. */
12
+ tenantId?: string;
13
+ }): OAuthProvider<{
14
+ code: string;
15
+ redirectUri: string;
16
+ }>;
@@ -0,0 +1,113 @@
1
+ import { MiddlewareHandler, Context } from "hono";
2
+ import { DataDriver } from "@rebasepro/types";
3
+ import { AccessTokenPayload } from "./jwt";
4
+ import { HonoEnv } from "../api/types";
5
+ import type { ApiKeyStore } from "./api-keys/api-key-store";
6
+ /**
7
+ * Result from a custom auth validator.
8
+ * - `false`/`null`/`undefined` = not authenticated
9
+ * - `true` = authenticated as default user
10
+ * - object with `userId` or `uid` = authenticated with user info
11
+ */
12
+ export type AuthResult = boolean | null | undefined | {
13
+ userId?: string;
14
+ uid?: string;
15
+ roles?: string[];
16
+ [key: string]: unknown;
17
+ };
18
+ /**
19
+ * Options for creating an auth middleware via createAuthMiddleware()
20
+ */
21
+ export interface AuthMiddlewareOptions {
22
+ /** DataDriver to scope via withAuth() for RLS */
23
+ driver: DataDriver;
24
+ /**
25
+ * Optional per-request driver resolver for multi-data-source backends.
26
+ * Given the request context, returns the unscoped delegate to use (e.g.
27
+ * Postgres vs Mongo, picked by the request's collection data source).
28
+ * When omitted, `driver` is used for every request.
29
+ */
30
+ resolveDriver?: (c: Context<HonoEnv>) => DataDriver;
31
+ /**
32
+ * If true, return 401 when no valid token is present.
33
+ *
34
+ * **Defaults to `true` (secure by default).** Set to `false` only for
35
+ * intentionally public endpoints where access control is fully delegated
36
+ * to Postgres Row-Level Security policies.
37
+ */
38
+ requireAuth?: boolean;
39
+ /** Optional custom validator (for non-JWT auth, e.g. external auth providers) */
40
+ validator?: (c: Context<HonoEnv>) => Promise<AuthResult>;
41
+ /**
42
+ * A static secret key for server-to-server / script authentication.
43
+ *
44
+ * When a request sends `Authorization: Bearer <key>` and the key matches
45
+ * this value, the request is granted admin-level access (uid: `service`,
46
+ * roles: `["admin"]`) **without** JWT verification. The driver is scoped
47
+ * via `withAuth()` with the service identity.
48
+ *
49
+ * This is the Rebase equivalent of a Service Account key.
50
+ * Set via `REBASE_SERVICE_KEY` in `.env` and pass through the backend config.
51
+ *
52
+ * **Security:** The comparison uses constant-time equality to prevent
53
+ * timing attacks. The key must be at least 32 characters.
54
+ */
55
+ serviceKey?: string;
56
+ /**
57
+ * API key store for authenticating `rk_` prefixed tokens.
58
+ * When set, tokens starting with `rk_` are validated against the
59
+ * database instead of being treated as JWTs.
60
+ */
61
+ apiKeyStore?: ApiKeyStore;
62
+ }
63
+ /**
64
+ * Hono middleware that requires a valid JWT token
65
+ * Returns 401 if token is missing or invalid
66
+ */
67
+ export declare const requireAuth: MiddlewareHandler<HonoEnv>;
68
+ /**
69
+ * Factory that creates a requireAuth middleware with optional service key support.
70
+ *
71
+ * When `serviceKey` is provided, the middleware will check if the Bearer token
72
+ * matches the service key using constant-time comparison. If it matches, the
73
+ * request is authenticated as a service user with admin privileges.
74
+ *
75
+ * This allows admin routes (which use standalone requireAuth + requireAdmin)
76
+ * to be accessed via service keys for scripts and server-to-server calls.
77
+ */
78
+ export declare function createRequireAuth(options?: {
79
+ serviceKey?: string;
80
+ }): MiddlewareHandler<HonoEnv>;
81
+ /**
82
+ * Middleware that requires the user to have an admin or schema-admin role.
83
+ * Must be used AFTER requireAuth or on a route where user is guaranteed.
84
+ */
85
+ export declare const requireAdmin: MiddlewareHandler<HonoEnv>;
86
+ /**
87
+ * Middleware that optionally extracts user from JWT
88
+ * Does not return 401 if token is missing - allows anonymous access
89
+ */
90
+ export declare const optionalAuth: MiddlewareHandler<HonoEnv>;
91
+ /**
92
+ * Extract user from token - for WebSocket authentication
93
+ */
94
+ export declare function extractUserFromToken(token: string): AccessTokenPayload | null;
95
+ /**
96
+ * Create a configurable auth middleware that handles:
97
+ * 1. Token extraction (via custom validator or JWT Bearer token)
98
+ * 2. RLS-scoped DataDriver via withAuth()
99
+ * 3. Enforcement (401 when requireAuth is true and no user)
100
+ *
101
+ * **Secure by default:** `requireAuth` defaults to `true`. Anonymous
102
+ * access is only allowed when the developer explicitly opts out by
103
+ * setting `requireAuth: false`, indicating that Postgres RLS policies
104
+ * fully control access.
105
+ *
106
+ * **Fail-closed:** The raw unscoped driver is never placed in the
107
+ * request context. Every code path either scopes via `withAuth()` or
108
+ * rejects the request. This prevents silent RLS bypass.
109
+ *
110
+ * This is the single source of truth for HTTP auth in Rebase.
111
+ * Use this instead of manually parsing tokens in route handlers.
112
+ */
113
+ export declare function createAuthMiddleware(options: AuthMiddlewareOptions): MiddlewareHandler<HonoEnv>;
@@ -0,0 +1,22 @@
1
+ export interface PasswordValidationResult {
2
+ valid: boolean;
3
+ errors: string[];
4
+ }
5
+ /**
6
+ * Password requirements:
7
+ * - Minimum 8 characters
8
+ * - At least 1 uppercase letter
9
+ * - At least 1 lowercase letter
10
+ * - At least 1 number
11
+ */
12
+ export declare function validatePasswordStrength(password: string): PasswordValidationResult;
13
+ /**
14
+ * Hash a password using Node's built-in scrypt
15
+ * Returns format: salt:hash (both hex encoded)
16
+ */
17
+ export declare function hashPassword(password: string): Promise<string>;
18
+ /**
19
+ * Verify a password against a scrypt hash
20
+ * Expects format: salt:hash (both hex encoded)
21
+ */
22
+ export declare function verifyPassword(password: string, storedHash: string): Promise<boolean>;
@@ -0,0 +1,50 @@
1
+ import { MiddlewareHandler } from "hono";
2
+ import { HonoEnv } from "../api/types";
3
+ interface RateLimiterOptions {
4
+ /** Time window in milliseconds (default: 15 minutes) */
5
+ windowMs?: number;
6
+ /** Maximum requests per window (default: 100) */
7
+ limit?: number;
8
+ /** Key generator function. Defaults to IP-based keying. */
9
+ keyGenerator?: (c: Parameters<MiddlewareHandler<HonoEnv>>[0]) => string;
10
+ /** Custom message for rate limit responses */
11
+ message?: string;
12
+ }
13
+ /**
14
+ * Create a rate-limiting middleware.
15
+ *
16
+ * Uses a sliding window algorithm: only timestamps within the last
17
+ * `windowMs` milliseconds are counted. Old entries are garbage-collected
18
+ * every `windowMs` to prevent unbounded memory growth.
19
+ */
20
+ export declare function createRateLimiter(options?: RateLimiterOptions): MiddlewareHandler<HonoEnv>;
21
+ /**
22
+ * Pre-configured rate limiter for general auth endpoints (login, register).
23
+ * 200 requests per 15 minutes per IP.
24
+ */
25
+ export declare const defaultAuthLimiter: MiddlewareHandler<HonoEnv>;
26
+ /**
27
+ * Pre-configured strict rate limiter for sensitive endpoints (password reset, verification).
28
+ * 50 requests per 15 minutes per IP.
29
+ */
30
+ export declare const strictAuthLimiter: MiddlewareHandler<HonoEnv>;
31
+ /**
32
+ * Key generator for API-key-based rate limiting.
33
+ *
34
+ * Uses the API key ID (from `c.get("apiKey")`) as the rate limit key.
35
+ * Falls back to IP-based keying when the request is not authenticated
36
+ * via an API key.
37
+ */
38
+ export declare function apiKeyKeyGenerator(c: Parameters<MiddlewareHandler<HonoEnv>>[0]): string;
39
+ /**
40
+ * Create a rate limiter specifically for API key requests.
41
+ *
42
+ * When a request is authenticated via an API key that has a `rate_limit`
43
+ * configured, this limiter enforces per-key limits using the key's ID
44
+ * as the rate limit bucket.
45
+ *
46
+ * @param defaultLimit - Fallback limit when the key has no `rate_limit` set.
47
+ * @param windowMs - Time window in milliseconds (default: 15 minutes).
48
+ */
49
+ export declare function createApiKeyRateLimiter(defaultLimit?: number, windowMs?: number): MiddlewareHandler<HonoEnv>;
50
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Standalone admin endpoint for resetting a user's password.
3
+ *
4
+ * Hook resolution order:
5
+ * 1. Collection-level hook (`auth.onResetPassword` on the collection)
6
+ * 2. Backend-level hook (`AuthHooks.onAdminResetPassword`)
7
+ * 3. Built-in default (send reset email, or generate temp password)
8
+ */
9
+ import { Hono } from "hono";
10
+ import type { AuthRepository } from "./interfaces";
11
+ import type { AuthHooks } from "./auth-hooks";
12
+ import type { EmailService, EmailConfig } from "../email";
13
+ import type { HonoEnv } from "../api/types";
14
+ import type { AuthCollectionConfig } from "@rebasepro/types";
15
+ export interface ResetPasswordRouteConfig {
16
+ authRepo: AuthRepository;
17
+ emailService?: EmailService;
18
+ emailConfig?: EmailConfig;
19
+ serviceKey?: string;
20
+ authHooks?: AuthHooks;
21
+ /** The parsed auth config from the collection, if available. */
22
+ collectionAuthConfig?: AuthCollectionConfig;
23
+ }
24
+ /**
25
+ * Create a standalone admin route for resetting user passwords.
26
+ *
27
+ * Mounts: POST /users/:userId/reset-password
28
+ */
29
+ export declare function createResetPasswordRoute(config: ResetPasswordRouteConfig): Hono<HonoEnv>;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared RLS (Row-Level Security) scoping helper.
3
+ *
4
+ * DataDrivers may implement a `withAuth()` method that returns a scoped
5
+ * clone of the driver with RLS policies applied for the given user.
6
+ * This is database-specific (e.g. Postgres SET LOCAL ROLE) and is not
7
+ * part of the core DataDriver interface.
8
+ *
9
+ * This module provides the shared duck-typing logic used by the
10
+ * adapter-aware middleware.
11
+ *
12
+ * @module
13
+ */
14
+ import type { DataDriver } from "@rebasepro/types";
15
+ /**
16
+ * Scope a DataDriver via `withAuth()` for RLS.
17
+ *
18
+ * SECURITY: If `withAuth()` is available but fails, the error is re-thrown
19
+ * so the request is **denied** rather than proceeding with unscoped access
20
+ * (fail-closed behavior).
21
+ *
22
+ * If the driver does not support RLS, the original driver is returned.
23
+ *
24
+ * @param driver - The DataDriver to scope.
25
+ * @param user - The authenticated user identity for RLS.
26
+ * @returns The RLS-scoped DataDriver (or the original if RLS is unsupported).
27
+ */
28
+ export declare function scopeDataDriver(driver: DataDriver, user: {
29
+ uid: string;
30
+ roles?: string[];
31
+ }): Promise<DataDriver>;
@@ -0,0 +1,35 @@
1
+ import { Hono } from "hono";
2
+ import type { AuthRepository, OAuthProvider } from "./interfaces";
3
+ import type { AuthHooks } from "./auth-hooks";
4
+ import { EmailService, EmailConfig } from "../email";
5
+ import { HonoEnv } from "../api/types";
6
+ /**
7
+ * Shared configuration for auth and admin route factories.
8
+ */
9
+ export interface AuthModuleConfig {
10
+ authRepo: AuthRepository;
11
+ emailService?: EmailService;
12
+ emailConfig?: EmailConfig;
13
+ /** Allow new user registration (default: false). */
14
+ allowRegistration?: boolean;
15
+ /** Default role ID to assign to new users (default: none). Must NOT be "admin". */
16
+ defaultRole?: string;
17
+ /** Optional array of OAuth providers */
18
+ oauthProviders?: OAuthProvider<unknown>[];
19
+ /** When true, blocks all self-registration regardless of `allowRegistration`. */
20
+ disableSelfRegistration?: boolean;
21
+ /**
22
+ * Auth hooks for customizing password hashing, credential
23
+ * verification, lifecycle hooks, etc.
24
+ */
25
+ authHooks?: AuthHooks;
26
+ /**
27
+ * Callback that checks if bootstrap has already been completed.
28
+ * Used by GET /auth/config to report `needsSetup` status.
29
+ * When not provided, falls back to checking if any users exist.
30
+ */
31
+ isBootstrapCompleted?: () => Promise<boolean>;
32
+ /** Enable magic link (passwordless email) login. Requires email service. */
33
+ enableMagicLink?: boolean;
34
+ }
35
+ export declare function createAuthRoutes(config: AuthModuleConfig): Hono<HonoEnv>;
@@ -0,0 +1,27 @@
1
+ import { Hono } from "hono";
2
+ import { z } from "zod";
3
+ import { HonoEnv } from "../api/types";
4
+ import type { AuthModuleConfig } from "./routes";
5
+ import { resolveAuthHooks } from "./auth-hooks";
6
+ import type { AuthResponsePayload, TransformAuthResponseContext } from "@rebasepro/types";
7
+ interface SessionRoutesConfig {
8
+ router: Hono<HonoEnv>;
9
+ config: AuthModuleConfig;
10
+ ops: ReturnType<typeof resolveAuthHooks>;
11
+ parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T;
12
+ buildAuthResponse: (user: {
13
+ id: string;
14
+ email: string;
15
+ displayName?: string | null;
16
+ photoUrl?: string | null;
17
+ metadata?: Record<string, unknown> | null;
18
+ }, roleIds: string[], accessToken: string, refreshToken: string) => unknown;
19
+ createSessionAndTokens: (userId: string, userAgent: string, ipAddress: string) => Promise<{
20
+ roleIds: string[];
21
+ accessToken: string;
22
+ refreshToken: string;
23
+ }>;
24
+ applyTransformHook: (response: AuthResponsePayload, method: TransformAuthResponseContext["method"], request: Request, userId: string) => Promise<AuthResponsePayload>;
25
+ }
26
+ export declare function mountSessionRoutes(opts: SessionRoutesConfig): void;
27
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Slack OAuth Provider integration (OAuth 2.0 / "Sign in with Slack").
4
+ * Uses the OpenID Connect flow with the "openid,email,profile" scopes.
5
+ */
6
+ export declare function createSlackProvider(config: {
7
+ clientId: string;
8
+ clientSecret: string;
9
+ }): OAuthProvider<{
10
+ code: string;
11
+ redirectUri: string;
12
+ }>;
@@ -0,0 +1,12 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Spotify OAuth Provider integration.
4
+ * Uses the authorization code flow with the "user-read-email" scope.
5
+ */
6
+ export declare function createSpotifyProvider(config: {
7
+ clientId: string;
8
+ clientSecret: string;
9
+ }): OAuthProvider<{
10
+ code: string;
11
+ redirectUri: string;
12
+ }>;
@@ -0,0 +1,18 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Twitter/X OAuth 2.0 Provider integration.
4
+ *
5
+ * Uses OAuth 2.0 with PKCE (authorization code flow). The frontend must include
6
+ * the PKCE `code_verifier` when sending the authorization code.
7
+ *
8
+ * Twitter API v2 requires the "tweet.read" and "users.read" scopes at minimum,
9
+ * plus "offline.access" if refresh tokens are needed on Twitter's side.
10
+ */
11
+ export declare function createTwitterProvider(config: {
12
+ clientId: string;
13
+ clientSecret: string;
14
+ }): OAuthProvider<{
15
+ code: string;
16
+ redirectUri: string;
17
+ codeVerifier: string;
18
+ }>;
@@ -0,0 +1,15 @@
1
+ import { createRequire as __createRequire } from "module";
2
+ import "process";
3
+ __createRequire(import.meta.url);
4
+ //#region ../types/src/types/backend.ts
5
+ /**
6
+ * Type guard: does this admin support SQL operations?
7
+ * @group Admin
8
+ */
9
+ function isSQLAdmin(admin) {
10
+ return !!admin && typeof admin.executeSql === "function";
11
+ }
12
+ //#endregion
13
+ export { isSQLAdmin as t };
14
+
15
+ //# sourceMappingURL=backend-CIxN4FVm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-CIxN4FVm.js","names":[],"sources":["../../types/src/types/backend.ts"],"sourcesContent":["import type { Entity } from \"./entities\";\nimport type { EntityCollection, FilterValues, WhereFilterOp } from \"./collections\";\nimport type { AuthAdapter } from \"./auth_adapter\";\n\n// =============================================================================\n// DATABASE CONNECTION INTERFACES\n// =============================================================================\n\n/**\n * Abstract database connection interface.\n * Represents a connection to any database system.\n */\nexport interface DatabaseConnection {\n /**\n * Type identifier for this database (e.g., 'postgres', 'mongodb', 'mysql')\n */\n readonly type: string;\n\n /**\n * Whether the connection is currently active\n */\n readonly isConnected?: boolean;\n\n /**\n * Close the database connection and release resources.\n */\n close?(): Promise<void>;\n}\n\n// =============================================================================\n// QUERY BUILDING INTERFACES\n// =============================================================================\n\n/**\n * A single filter condition for database queries\n */\nexport interface QueryFilter {\n field: string;\n operator: WhereFilterOp;\n value: unknown;\n}\n\n/**\n * Options for fetching a collection of entities\n */\nexport interface FetchCollectionOptions<M extends Record<string, unknown> = Record<string, unknown>> {\n filter?: FilterValues<Extract<keyof M, string>>;\n orderBy?: string;\n order?: \"desc\" | \"asc\";\n limit?: number;\n offset?: number;\n startAfter?: unknown;\n searchString?: string;\n databaseId?: string;\n collection?: EntityCollection;\n}\n\n/**\n * Options for searching entities\n */\nexport interface SearchOptions<M extends Record<string, unknown> = Record<string, unknown>> {\n filter?: FilterValues<Extract<keyof M, string>>;\n orderBy?: string;\n order?: \"desc\" | \"asc\";\n limit?: number;\n databaseId?: string;\n collection?: EntityCollection;\n}\n\n/**\n * Options for counting entities\n */\nexport interface CountOptions<M extends Record<string, unknown> = Record<string, unknown>> {\n filter?: FilterValues<Extract<keyof M, string>>;\n searchString?: string;\n databaseId?: string;\n}\n\n/**\n * Abstract condition builder interface.\n * Implementations translate Rebase filter conditions to database-specific queries.\n *\n * Note: This interface can be implemented as instance methods or as a class with static methods.\n * For static implementations (like DrizzleConditionBuilder), use the ConditionBuilderStatic type.\n *\n * @template T The type of condition returned by the builder (e.g., SQL for PostgreSQL, Filter<Document> for MongoDB)\n */\nexport interface ConditionBuilder<T = unknown> {\n /**\n * Build filter conditions from Rebase FilterValues\n */\n buildFilterConditions<M extends Record<string, unknown>>(\n filter: FilterValues<Extract<keyof M, string>>,\n collectionPath: string,\n ...args: unknown[]\n ): T[];\n\n /**\n * Build search conditions for text search\n */\n buildSearchConditions(\n searchString: string,\n properties: Record<string, unknown>,\n ...args: unknown[]\n ): T[];\n\n /**\n * Combine multiple conditions with AND operator\n */\n combineConditionsWithAnd(conditions: T[]): T | undefined;\n\n /**\n * Combine multiple conditions with OR operator\n */\n combineConditionsWithOr(conditions: T[]): T | undefined;\n}\n\n/**\n * Static condition builder type for implementations using static methods.\n * Use this type when the class provides static methods rather than instance methods.\n *\n * @example\n * // DrizzleConditionBuilder satisfies this type\n * const builder: ConditionBuilderStatic<SQL> = DrizzleConditionBuilder;\n */\nexport type ConditionBuilderStatic<T = unknown> = {\n buildFilterConditions<M extends Record<string, unknown>>(\n filter: FilterValues<Extract<keyof M, string>>,\n ...args: unknown[]\n ): T[];\n buildSearchConditions(\n searchString: string,\n properties: Record<string, unknown>,\n ...args: unknown[]\n ): T[];\n combineConditionsWithAnd(conditions: T[]): T | undefined;\n combineConditionsWithOr(conditions: T[]): T | undefined;\n};\n\n// =============================================================================\n// ENTITY REPOSITORY INTERFACES\n// =============================================================================\n\n/**\n * Abstract entity repository interface.\n * Handles all CRUD operations for entities in the database.\n *\n * Implementations should handle:\n * - Entity serialization/deserialization\n * - Relation resolution\n * - ID generation and conversion\n */\nexport interface EntityRepository {\n /**\n * Fetch a single entity by ID\n */\n fetchEntity<M extends Record<string, unknown>>(\n collectionPath: string,\n entityId: string | number,\n databaseId?: string\n ): Promise<Entity<M> | undefined>;\n\n /**\n * Fetch a collection of entities with optional filtering, ordering, and pagination\n */\n fetchCollection<M extends Record<string, unknown>>(\n collectionPath: string,\n options?: FetchCollectionOptions<M>\n ): Promise<Entity<M>[]>;\n\n /**\n * Search entities by text\n */\n searchEntities<M extends Record<string, unknown>>(\n collectionPath: string,\n searchString: string,\n options?: SearchOptions<M>\n ): Promise<Entity<M>[]>;\n\n /**\n * Count entities in a collection\n */\n countEntities<M extends Record<string, unknown>>(\n collectionPath: string,\n options?: CountOptions<M>\n ): Promise<number>;\n\n /**\n * Save an entity (create or update)\n */\n saveEntity<M extends Record<string, unknown>>(\n collectionPath: string,\n values: Partial<M>,\n entityId?: string | number,\n databaseId?: string\n ): Promise<Entity<M>>;\n\n /**\n * Delete an entity by ID\n */\n deleteEntity(\n collectionPath: string,\n entityId: string | number,\n databaseId?: string\n ): Promise<void>;\n\n /**\n * Check if a field value is unique in a collection\n */\n checkUniqueField(\n collectionPath: string,\n fieldName: string,\n value: unknown,\n excludeEntityId?: string,\n databaseId?: string\n ): Promise<boolean>;\n\n}\n\n// =============================================================================\n// REALTIME INTERFACES\n// =============================================================================\n\n/**\n * Configuration for subscribing to a collection\n */\nexport interface CollectionSubscriptionConfig {\n clientId: string;\n path: string;\n filter?: unknown;\n orderBy?: string;\n order?: \"desc\" | \"asc\";\n limit?: number;\n startAfter?: unknown;\n databaseId?: string;\n searchString?: string;\n}\n\n/**\n * Configuration for subscribing to a single entity\n */\nexport interface EntitySubscriptionConfig {\n clientId: string;\n path: string;\n entityId: string | number;\n}\n\n/**\n * Abstract realtime provider interface.\n * Handles real-time subscriptions and notifications for entity changes.\n */\nexport interface RealtimeProvider {\n /**\n * Subscribe to collection changes\n */\n subscribeToCollection(\n subscriptionId: string,\n config: CollectionSubscriptionConfig,\n callback?: (entities: Entity[]) => void\n ): void;\n\n /**\n * Subscribe to single entity changes\n */\n subscribeToEntity(\n subscriptionId: string,\n config: EntitySubscriptionConfig,\n callback?: (entity: Entity | null) => void\n ): void;\n\n /**\n * Unsubscribe from a subscription\n */\n unsubscribe(subscriptionId: string): void;\n\n /**\n * Notify all relevant subscribers of an entity update\n */\n notifyEntityUpdate(\n path: string,\n entityId: string,\n entity: Entity | null,\n databaseId?: string\n ): Promise<void>;\n\n /**\n * Called when the HTTP server is ready and listening.\n * Useful for providers that need the server address for callbacks.\n */\n onServerReady?(serverInfo: { port: number; hostname?: string }): void;\n\n /**\n * Gracefully shut down the realtime provider.\n * Called during server shutdown to clean up resources.\n */\n destroy?(): Promise<void>;\n\n /**\n * Stop the internal LISTEN client (e.g., PostgreSQL LISTEN/NOTIFY).\n * Called during graceful shutdown before closing database connections.\n */\n stopListening?(): Promise<void>;\n}\n\n// =============================================================================\n// COLLECTION REGISTRY INTERFACES\n// =============================================================================\n\n/**\n * Abstract collection registry interface.\n * Manages registration and lookup of entity collections.\n */\nexport interface CollectionRegistryInterface {\n /**\n * Register a collection\n */\n register(collection: EntityCollection): void;\n\n /**\n * Get a collection by its path\n */\n getCollectionByPath(path: string): EntityCollection | undefined;\n\n /**\n * Get all registered collections\n */\n getCollections(): EntityCollection[];\n\n /**\n * Get the currently registered global callbacks, if any.\n */\n getGlobalCallbacks(): any | undefined;\n}\n\n// =============================================================================\n// DATA TRANSFORMER INTERFACES\n// =============================================================================\n\n/**\n * Abstract data transformer interface.\n * Handles serialization/deserialization between frontend and database formats.\n */\nexport interface DataTransformer {\n /**\n * Transform entity data for storage in the database\n */\n serializeToDatabase<M extends Record<string, unknown>>(\n entity: M,\n collection: EntityCollection\n ): Record<string, unknown>;\n\n /**\n * Transform database data back to entity format\n */\n deserializeFromDatabase<M extends Record<string, unknown>>(\n data: Record<string, unknown>,\n collection: EntityCollection\n ): Promise<M>;\n}\n\n// =============================================================================\n// DATABASE ADMIN — CAPABILITY-SPECIFIC INTERFACES (1.3)\n// =============================================================================\n\n/**\n * Administrative operations for SQL-based databases (PostgreSQL, MySQL, etc.).\n * Used by the SQL Editor, RLS Editor, and schema browser.\n *\n * @group Admin\n */\nexport interface SQLAdmin {\n /**\n * Execute raw SQL against the database.\n */\n executeSql(sql: string, options?: { database?: string; role?: string; params?: unknown[] }): Promise<Record<string, unknown>[]>;\n\n /**\n * Fetch the available databases on the server.\n */\n fetchAvailableDatabases?(): Promise<string[]>;\n\n /**\n * Fetch the available database roles.\n */\n fetchAvailableRoles?(): Promise<string[]>;\n\n /**\n * Fetch the current database name.\n */\n fetchCurrentDatabase?(): Promise<string | undefined>;\n}\n\n/**\n * Administrative operations for document-based databases (MongoDB, Firestore, etc.).\n * Used by future document administration tools.\n *\n * @group Admin\n */\nexport interface DocumentAdmin {\n /**\n * Execute an aggregation pipeline or equivalent query.\n */\n executeAggregate?(pipeline: Record<string, unknown>[]): Promise<Record<string, unknown>[]>;\n\n /**\n * Fetch statistics for a collection (document count, size, etc.).\n */\n fetchCollectionStats?(collectionName: string): Promise<{ count: number; sizeBytes?: number }>;\n}\n\n/**\n * Administrative operations for schema management.\n * Shared across SQL and document databases.\n *\n * @group Admin\n */\nexport interface SchemaAdmin {\n /**\n * Fetch database tables/collections not yet mapped to a Rebase collection.\n */\n fetchUnmappedTables?(mappedPaths?: string[]): Promise<string[]>;\n\n /**\n * Fetch column/field metadata for a single table/collection.\n * The return type is generic — SQL backends return TableMetadata,\n * document backends may return a different shape.\n */\n fetchTableMetadata?(tableName: string): Promise<unknown>;\n}\n\n/**\n * Metadata for a database branch.\n * @group Admin\n */\nexport interface BranchInfo {\n /** Branch name (without prefix). */\n name: string;\n /** The database this branch was created from. */\n parentDatabase: string;\n /** When the branch was created. */\n createdAt: Date;\n /** Size in bytes, if available from the server. */\n sizeBytes?: number;\n}\n\n/**\n * Administrative operations for database branching.\n * Allows creating isolated database copies for development/preview workflows.\n *\n * @group Admin\n */\nexport interface BranchAdmin {\n /** Create a new branch (database copy) from the current or specified source database. */\n createBranch(name: string, options?: { source?: string }): Promise<BranchInfo>;\n\n /** Delete a branch database. Cannot delete the main/default database. */\n deleteBranch(name: string): Promise<void>;\n\n /** List all branches (databases that were created via branching). */\n listBranches(): Promise<BranchInfo[]>;\n\n /** Get info about a specific branch. */\n getBranchInfo(name: string): Promise<BranchInfo | undefined>;\n}\n\n/**\n * Union type for all admin capabilities.\n * A backend may implement any combination of these interfaces.\n *\n * Use type guards (`isSQLAdmin`, `isDocumentAdmin`, `isSchemaAdmin`, `isBranchAdmin`)\n * to safely narrow the type before calling methods.\n *\n * @group Admin\n */\nexport type DatabaseAdmin = Partial<SQLAdmin> & Partial<DocumentAdmin> & Partial<SchemaAdmin> & Partial<BranchAdmin>;\n\n/**\n * Type guard: does this admin support SQL operations?\n * @group Admin\n */\nexport function isSQLAdmin(admin: DatabaseAdmin | undefined): admin is SQLAdmin {\n return !!admin && typeof (admin as SQLAdmin).executeSql === \"function\";\n}\n\n/**\n * Type guard: does this admin support document operations?\n * @group Admin\n */\nexport function isDocumentAdmin(admin: DatabaseAdmin | undefined): admin is DocumentAdmin {\n return !!admin && (\n typeof (admin as DocumentAdmin).executeAggregate === \"function\" ||\n typeof (admin as DocumentAdmin).fetchCollectionStats === \"function\"\n );\n}\n\n/**\n * Type guard: does this admin support schema management?\n * @group Admin\n */\nexport function isSchemaAdmin(admin: DatabaseAdmin | undefined): admin is SchemaAdmin {\n return !!admin && (\n typeof (admin as SchemaAdmin).fetchUnmappedTables === \"function\" ||\n typeof (admin as SchemaAdmin).fetchTableMetadata === \"function\"\n );\n}\n\n/**\n * Type guard: does this admin support database branching?\n * @group Admin\n */\nexport function isBranchAdmin(admin: DatabaseAdmin | undefined): admin is BranchAdmin {\n return !!admin && typeof (admin as BranchAdmin).createBranch === \"function\";\n}\n\n// =============================================================================\n// LIFECYCLE INTERFACES (1.4)\n// =============================================================================\n\n/**\n * Health check result returned by `healthCheck()`.\n * @group Lifecycle\n */\nexport interface HealthCheckResult {\n /** Whether the backend is healthy and able to serve requests. */\n healthy: boolean;\n /** Round-trip latency to the database in milliseconds. */\n latencyMs: number;\n /** Optional details (e.g., pool stats, replication lag). */\n details?: Record<string, unknown>;\n}\n\n/**\n * Lifecycle contract for backend components that hold resources\n * (database connections, WebSocket pools, timers, etc.).\n *\n * All methods are optional — simple backends (e.g., in-memory) can skip them.\n * @group Lifecycle\n */\nexport interface BackendLifecycle {\n /**\n * Initialize the backend: open connections, run migrations, seed data.\n * Called once during startup. Idempotent.\n */\n initialize?(): Promise<void>;\n\n /**\n * Check whether the backend is healthy and reachable.\n * Should be fast (< 1 s) and safe to call frequently.\n */\n healthCheck?(): Promise<HealthCheckResult>;\n\n /**\n * Gracefully shut down: close connections, flush buffers, cancel timers.\n * After calling `destroy()`, no other methods should be called.\n */\n destroy?(): Promise<void>;\n}\n\n// =============================================================================\n// BACKEND FACTORY INTERFACES\n// =============================================================================\n\n/**\n * Configuration for creating a database backend\n */\nexport interface BackendConfig {\n /**\n * Type of database backend\n */\n type: string;\n\n /**\n * Database connection (implementation-specific)\n */\n connection: unknown;\n\n /**\n * Schema definition (implementation-specific, e.g., Drizzle schema for PostgreSQL)\n */\n schema?: unknown;\n}\n\n/**\n * A complete backend instance with all required services.\n *\n * Now includes optional lifecycle management and admin capabilities.\n */\nexport interface BackendInstance extends BackendLifecycle {\n /**\n * Entity repository for CRUD operations\n */\n entityRepository: EntityRepository;\n\n /**\n * Realtime provider for subscriptions\n */\n realtimeProvider: RealtimeProvider;\n\n /**\n * Collection registry\n */\n collectionRegistry: CollectionRegistryInterface;\n\n /**\n * The underlying database connection\n */\n connection: DatabaseConnection;\n\n /**\n * Administrative operations (SQL, schema, documents).\n * What's available depends on the backend type — use type guards\n * (`isSQLAdmin`, `isSchemaAdmin`, etc.) to narrow.\n */\n admin?: DatabaseAdmin;\n}\n\n/**\n * Factory function type for creating backend instances\n */\nexport type BackendFactory<TConfig extends BackendConfig = BackendConfig> =\n (config: TConfig) => BackendInstance;\n\n// =============================================================================\n// BACKEND BOOTSTRAPPER (1.2)\n// =============================================================================\n\n/**\n * A `BackendBootstrapper` encapsulates all driver-specific initialization logic.\n *\n * Instead of hard-coding Postgres setup into `initializeRebaseBackend()`,\n * each database backend provides its own bootstrapper that knows how to:\n * - Create the DataDriver from a config object\n * - Optionally initialize auth tables\n * - Optionally create a realtime service\n * - Mount driver-specific API routes\n *\n * The main `initializeRebaseBackend()` becomes a **coordinator** that iterates\n * registered bootstrappers, calls their hooks, and wires the results together.\n *\n * @group Backend\n *\n * @example\n * ```typescript\n * // Third-party MySQL bootstrapper\n * const mysqlBootstrapper: BackendBootstrapper = {\n * type: \"mysql\",\n * initializeDriver: async (config) => new MySQLDataDriver(config.connection),\n * initializeRealtime: async (config) => new MySQLChangeStreamRealtime(config.connection),\n * };\n *\n * initializeRebaseBackend({\n * ...config,\n * bootstrappers: [postgresBootstrapper, mysqlBootstrapper]\n * });\n * ```\n */\nexport interface BackendBootstrapper {\n /**\n * Which driver type this bootstrapper handles.\n * Must match the `type` field on the driver config object\n * (e.g., `\"postgres\"`, `\"mongodb\"`, `\"mysql\"`).\n */\n type: string;\n\n /**\n * Unique identifier for this bootstrapper instance.\n * Used to register the driver in the driver registry.\n * Defaults to `type` if not set.\n */\n id?: string;\n\n /**\n * Whether this bootstrapper provides the default driver.\n * When true, the coordinator uses this driver as the primary one.\n */\n isDefault?: boolean;\n\n /**\n * Run database migrations for this driver.\n * Called by the coordinator after all drivers are initialized.\n */\n runMigrations?(config: unknown, driverResult: InitializedDriver): Promise<void>;\n\n /**\n * Create a DataDriver from the given config.\n * This is the only **required** method.\n */\n initializeDriver(config: unknown): Promise<InitializedDriver>;\n\n /**\n * Initialize auth tables / services if this driver supports them.\n * Return undefined if auth is not supported by this backend.\n */\n initializeAuth?(config: unknown, driverResult: InitializedDriver): Promise<BootstrappedAuth | undefined>;\n\n /**\n * Initialize history tables / services if this driver supports them.\n * Return undefined if history is not supported by this backend.\n */\n initializeHistory?(config: unknown, driverResult: InitializedDriver): Promise<{ historyService: unknown } | undefined>;\n\n /**\n * Create a realtime provider for this driver.\n * Return undefined if the driver does not support realtime.\n */\n initializeRealtime?(config: unknown, driverResult: InitializedDriver): Promise<RealtimeProvider | undefined>;\n\n /**\n * Mount any driver-specific HTTP routes (e.g., custom admin endpoints).\n * Called after all drivers are initialized.\n */\n mountRoutes?(app: unknown, basePath: string, driverResult: InitializedDriver): void;\n\n /**\n * Return admin capabilities for this driver.\n */\n getAdmin?(driverResult: InitializedDriver): DatabaseAdmin | undefined;\n\n /**\n * Initialize WebSocket server for realtime operations.\n */\n initializeWebsockets?(server: unknown, realtimeService: RealtimeProvider, driver: import(\"../controllers/data_driver\").DataDriver, config?: unknown, authAdapter?: AuthAdapter): Promise<void> | void;\n}\n\n/**\n * Result of `BackendBootstrapper.initializeDriver()`.\n * @group Backend\n */\nexport interface InitializedDriver {\n /** The DataDriver instance, ready for use. */\n driver: import(\"../controllers/data_driver\").DataDriver;\n\n /** The realtime service, if the driver created one during init. */\n realtimeProvider?: RealtimeProvider;\n\n /** A collection registry to register schema / tables into. */\n collectionRegistry?: CollectionRegistryInterface;\n\n /** The underlying database connection (for lifecycle management). */\n connection?: DatabaseConnection;\n\n /**\n * Opaque handle that the bootstrapper can use in subsequent hooks\n * (e.g., `initializeAuth`, `mountRoutes`) to access driver internals.\n * Not used by the coordinator.\n */\n internals?: unknown;\n}\n\n/**\n * Result of `BackendBootstrapper.initializeAuth()`.\n * @group Backend\n */\nexport interface BootstrappedAuth {\n /** User management service. */\n userService: unknown;\n /** Role management service (optional, roles are now simple strings). */\n roleService?: unknown;\n /** Email service (optional). */\n emailService?: unknown;\n /** Combined Auth Repository for unified token and user management. */\n authRepository?: unknown;\n}\n"],"mappings":";;;;;;;;AAgeA,SAAgB,WAAW,OAAqD;CAC5E,OAAO,CAAC,CAAC,SAAS,OAAQ,MAAmB,eAAe;AAChE"}