@rebasepro/server-core 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +62 -25
  2. package/dist/{server-core/src/api → api}/errors.d.ts +20 -2
  3. package/dist/{server-core/src/api → api}/rest/api-generator.d.ts +8 -2
  4. package/dist/{server-core/src/api → api}/types.d.ts +2 -0
  5. package/dist/auth/admin-user-ops.d.ts +79 -0
  6. package/dist/{server-core/src/auth → auth}/api-keys/index.d.ts +2 -2
  7. package/dist/{server-core/src/auth → auth}/auth-hooks.d.ts +37 -9
  8. package/dist/{server-core/src/auth → auth}/builtin-auth-adapter.d.ts +4 -4
  9. package/dist/{server-core/src/auth → auth}/index.d.ts +5 -2
  10. package/dist/{server-core/src/auth → auth}/jwt.d.ts +10 -0
  11. package/dist/auth/mfa-routes.d.ts +6 -0
  12. package/dist/auth/reset-password-admin.d.ts +29 -0
  13. package/dist/auth/session-routes.d.ts +25 -0
  14. package/dist/backend-CIxN4FVm.js +15 -0
  15. package/dist/backend-CIxN4FVm.js.map +1 -0
  16. package/dist/chunk-Dze3rakg.js +42 -0
  17. package/dist/{server-core/src/cron → cron}/cron-scheduler.d.ts +1 -1
  18. package/dist/dist-CZKP-Xz4.js +832 -0
  19. package/dist/dist-CZKP-Xz4.js.map +1 -0
  20. package/dist/env.d.ts +102 -0
  21. package/dist/from-VbwD7xRf.js +3849 -0
  22. package/dist/from-VbwD7xRf.js.map +1 -0
  23. package/dist/{server-core/src/index.d.ts → index.d.ts} +1 -0
  24. package/dist/index.es.js +60871 -50424
  25. package/dist/index.es.js.map +1 -1
  26. package/dist/index.umd.js +73151 -51256
  27. package/dist/index.umd.js.map +1 -1
  28. package/dist/init/docs.d.ts +4 -0
  29. package/dist/init/health.d.ts +2 -0
  30. package/dist/init/middlewares.d.ts +10 -0
  31. package/dist/init/shutdown.d.ts +11 -0
  32. package/dist/init/storage.d.ts +5 -0
  33. package/dist/{server-core/src/init.d.ts → init.d.ts} +4 -4
  34. package/dist/jwt-DHcQRGC3.js +4168 -0
  35. package/dist/jwt-DHcQRGC3.js.map +1 -0
  36. package/dist/logger-BYU66ENZ.js +94 -0
  37. package/dist/logger-BYU66ENZ.js.map +1 -0
  38. package/dist/ms-BeBSuOXN.js +125 -0
  39. package/dist/ms-BeBSuOXN.js.map +1 -0
  40. package/dist/multipart-parser-CedBDOeC.js +299 -0
  41. package/dist/multipart-parser-CedBDOeC.js.map +1 -0
  42. package/dist/src-COaj0G3P.js +1182 -0
  43. package/dist/src-COaj0G3P.js.map +1 -0
  44. package/dist/{server-core/src/storage → storage}/image-transform.d.ts +3 -1
  45. package/dist/utils/request-id.d.ts +4 -0
  46. package/package.json +29 -29
  47. package/src/api/collections_for_test/callbacks_test_collection.ts +7 -6
  48. package/src/api/errors.ts +95 -20
  49. package/src/api/graphql/graphql-schema-generator.ts +15 -10
  50. package/src/api/logs-routes.ts +5 -2
  51. package/src/api/openapi-generator.ts +1 -1
  52. package/src/api/rest/api-generator-count.test.ts +21 -10
  53. package/src/api/rest/api-generator.ts +151 -36
  54. package/src/api/rest/query-parser.ts +18 -12
  55. package/src/api/server.ts +13 -2
  56. package/src/api/types.ts +2 -0
  57. package/src/auth/adapter-middleware.ts +17 -10
  58. package/src/auth/admin-user-ops.ts +236 -0
  59. package/src/auth/api-keys/api-key-middleware.ts +15 -9
  60. package/src/auth/api-keys/api-key-permission-guard.ts +1 -1
  61. package/src/auth/api-keys/api-key-routes.ts +3 -3
  62. package/src/auth/api-keys/api-key-store.ts +14 -8
  63. package/src/auth/api-keys/index.ts +2 -2
  64. package/src/auth/apple-oauth.ts +4 -3
  65. package/src/auth/auth-hooks.ts +50 -10
  66. package/src/auth/bitbucket-oauth.ts +5 -4
  67. package/src/auth/builtin-auth-adapter.ts +64 -54
  68. package/src/auth/custom-auth-adapter.ts +4 -5
  69. package/src/auth/discord-oauth.ts +5 -4
  70. package/src/auth/facebook-oauth.ts +5 -4
  71. package/src/auth/github-oauth.ts +6 -5
  72. package/src/auth/gitlab-oauth.ts +5 -4
  73. package/src/auth/google-oauth.ts +2 -1
  74. package/src/auth/index.ts +6 -2
  75. package/src/auth/jwt.ts +15 -4
  76. package/src/auth/linkedin-oauth.ts +4 -3
  77. package/src/auth/mfa-routes.ts +299 -0
  78. package/src/auth/mfa.ts +2 -1
  79. package/src/auth/microsoft-oauth.ts +5 -4
  80. package/src/auth/middleware.ts +5 -4
  81. package/src/auth/rate-limiter.ts +1 -1
  82. package/src/auth/reset-password-admin.ts +144 -0
  83. package/src/auth/rls-scope.ts +1 -1
  84. package/src/auth/routes.ts +52 -600
  85. package/src/auth/session-routes.ts +341 -0
  86. package/src/auth/slack-oauth.ts +6 -5
  87. package/src/auth/spotify-oauth.ts +5 -4
  88. package/src/auth/twitter-oauth.ts +4 -3
  89. package/src/collections/loader.ts +5 -4
  90. package/src/cron/cron-scheduler.test.ts +23 -11
  91. package/src/cron/cron-scheduler.ts +14 -8
  92. package/src/cron/cron-store.ts +1 -1
  93. package/src/email/smtp-email-service.ts +3 -2
  94. package/src/env.ts +11 -10
  95. package/src/index.ts +1 -0
  96. package/src/init/docs.ts +47 -0
  97. package/src/init/health.ts +37 -0
  98. package/src/init/middlewares.ts +61 -0
  99. package/src/init/shutdown.ts +56 -0
  100. package/src/init/storage.ts +57 -0
  101. package/src/init.ts +93 -295
  102. package/src/serve-spa.ts +12 -5
  103. package/src/services/driver-registry.ts +4 -3
  104. package/src/storage/S3StorageController.ts +1 -2
  105. package/src/storage/image-transform.ts +25 -10
  106. package/src/storage/routes.ts +30 -11
  107. package/src/storage/storage-registry.ts +4 -3
  108. package/src/storage/tus-handler.ts +12 -12
  109. package/src/utils/request-id.ts +40 -0
  110. package/src/utils/request-logger.ts +6 -0
  111. package/test/api-generator.test.ts +90 -2
  112. package/test/api-key-permission-guard.test.ts +24 -12
  113. package/test/auth-routes.test.ts +5 -3
  114. package/test/backend-hooks-data.test.ts +99 -30
  115. package/test/custom-auth-adapter.test.ts +16 -15
  116. package/test/email-templates.test.ts +10 -5
  117. package/test/env.test.ts +10 -10
  118. package/test/function-loader.test.ts +7 -4
  119. package/test/graphql-schema-generator.test.ts +554 -0
  120. package/test/jwt-security.test.ts +1 -1
  121. package/test/query-parser.test.ts +0 -1
  122. package/test/reset-password-admin.test.ts +113 -0
  123. package/test/singleton.test.ts +5 -5
  124. package/test/smtp-email-service.test.ts +21 -21
  125. package/test/webhook-service.test.ts +22 -11
  126. package/tsconfig.json +2 -0
  127. package/tsconfig.prod.json +3 -0
  128. package/vite.config.ts +5 -5
  129. package/dist/common/src/collections/CollectionRegistry.d.ts +0 -56
  130. package/dist/common/src/collections/default-collections.d.ts +0 -9
  131. package/dist/common/src/collections/index.d.ts +0 -2
  132. package/dist/common/src/data/buildRebaseData.d.ts +0 -14
  133. package/dist/common/src/data/query_builder.d.ts +0 -55
  134. package/dist/common/src/index.d.ts +0 -4
  135. package/dist/common/src/util/builders.d.ts +0 -57
  136. package/dist/common/src/util/callbacks.d.ts +0 -6
  137. package/dist/common/src/util/collections.d.ts +0 -11
  138. package/dist/common/src/util/common.d.ts +0 -2
  139. package/dist/common/src/util/conditions.d.ts +0 -26
  140. package/dist/common/src/util/entities.d.ts +0 -58
  141. package/dist/common/src/util/enums.d.ts +0 -3
  142. package/dist/common/src/util/index.d.ts +0 -16
  143. package/dist/common/src/util/navigation_from_path.d.ts +0 -34
  144. package/dist/common/src/util/navigation_utils.d.ts +0 -20
  145. package/dist/common/src/util/parent_references_from_path.d.ts +0 -6
  146. package/dist/common/src/util/paths.d.ts +0 -14
  147. package/dist/common/src/util/permissions.d.ts +0 -6
  148. package/dist/common/src/util/references.d.ts +0 -2
  149. package/dist/common/src/util/relations.d.ts +0 -22
  150. package/dist/common/src/util/resolutions.d.ts +0 -72
  151. package/dist/common/src/util/storage.d.ts +0 -24
  152. package/dist/index-Cr1D21av.js +0 -49
  153. package/dist/index-Cr1D21av.js.map +0 -1
  154. package/dist/server-core/src/auth/admin-routes.d.ts +0 -27
  155. package/dist/server-core/src/env.d.ts +0 -137
  156. package/dist/types/src/controllers/analytics_controller.d.ts +0 -7
  157. package/dist/types/src/controllers/auth.d.ts +0 -104
  158. package/dist/types/src/controllers/client.d.ts +0 -168
  159. package/dist/types/src/controllers/collection_registry.d.ts +0 -46
  160. package/dist/types/src/controllers/customization_controller.d.ts +0 -60
  161. package/dist/types/src/controllers/data.d.ts +0 -207
  162. package/dist/types/src/controllers/data_driver.d.ts +0 -218
  163. package/dist/types/src/controllers/database_admin.d.ts +0 -11
  164. package/dist/types/src/controllers/dialogs_controller.d.ts +0 -36
  165. package/dist/types/src/controllers/effective_role.d.ts +0 -4
  166. package/dist/types/src/controllers/email.d.ts +0 -36
  167. package/dist/types/src/controllers/index.d.ts +0 -18
  168. package/dist/types/src/controllers/local_config_persistence.d.ts +0 -20
  169. package/dist/types/src/controllers/navigation.d.ts +0 -225
  170. package/dist/types/src/controllers/registry.d.ts +0 -63
  171. package/dist/types/src/controllers/side_dialogs_controller.d.ts +0 -67
  172. package/dist/types/src/controllers/side_entity_controller.d.ts +0 -97
  173. package/dist/types/src/controllers/snackbar.d.ts +0 -24
  174. package/dist/types/src/controllers/storage.d.ts +0 -171
  175. package/dist/types/src/index.d.ts +0 -4
  176. package/dist/types/src/rebase_context.d.ts +0 -122
  177. package/dist/types/src/types/auth_adapter.d.ts +0 -301
  178. package/dist/types/src/types/backend.d.ts +0 -536
  179. package/dist/types/src/types/backend_hooks.d.ts +0 -172
  180. package/dist/types/src/types/builders.d.ts +0 -15
  181. package/dist/types/src/types/chips.d.ts +0 -5
  182. package/dist/types/src/types/collections.d.ts +0 -941
  183. package/dist/types/src/types/component_ref.d.ts +0 -47
  184. package/dist/types/src/types/cron.d.ts +0 -102
  185. package/dist/types/src/types/data_source.d.ts +0 -64
  186. package/dist/types/src/types/database_adapter.d.ts +0 -94
  187. package/dist/types/src/types/entities.d.ts +0 -145
  188. package/dist/types/src/types/entity_actions.d.ts +0 -104
  189. package/dist/types/src/types/entity_callbacks.d.ts +0 -173
  190. package/dist/types/src/types/entity_link_builder.d.ts +0 -7
  191. package/dist/types/src/types/entity_overrides.d.ts +0 -10
  192. package/dist/types/src/types/entity_views.d.ts +0 -87
  193. package/dist/types/src/types/export_import.d.ts +0 -21
  194. package/dist/types/src/types/formex.d.ts +0 -40
  195. package/dist/types/src/types/index.d.ts +0 -28
  196. package/dist/types/src/types/locales.d.ts +0 -4
  197. package/dist/types/src/types/modify_collections.d.ts +0 -5
  198. package/dist/types/src/types/plugins.d.ts +0 -282
  199. package/dist/types/src/types/properties.d.ts +0 -1181
  200. package/dist/types/src/types/property_config.d.ts +0 -74
  201. package/dist/types/src/types/relations.d.ts +0 -336
  202. package/dist/types/src/types/slots.d.ts +0 -262
  203. package/dist/types/src/types/translations.d.ts +0 -900
  204. package/dist/types/src/types/user_management_delegate.d.ts +0 -86
  205. package/dist/types/src/types/websockets.d.ts +0 -78
  206. package/dist/types/src/users/index.d.ts +0 -1
  207. package/dist/types/src/users/user.d.ts +0 -50
  208. package/src/auth/admin-routes.ts +0 -534
  209. package/test/admin-routes.test.ts +0 -544
  210. package/test/backend-hooks-admin.test.ts +0 -388
  211. package/test.ts +0 -6
  212. /package/dist/{server-core/src/api → api}/ast-schema-editor.d.ts +0 -0
  213. /package/dist/{server-core/src/api → api}/collections_for_test/callbacks_test_collection.d.ts +0 -0
  214. /package/dist/{server-core/src/api → api}/graphql/graphql-schema-generator.d.ts +0 -0
  215. /package/dist/{server-core/src/api → api}/graphql/index.d.ts +0 -0
  216. /package/dist/{server-core/src/api → api}/index.d.ts +0 -0
  217. /package/dist/{server-core/src/api → api}/logs-routes.d.ts +0 -0
  218. /package/dist/{server-core/src/api → api}/openapi-generator.d.ts +0 -0
  219. /package/dist/{server-core/src/api → api}/rest/index.d.ts +0 -0
  220. /package/dist/{server-core/src/api → api}/rest/query-parser.d.ts +0 -0
  221. /package/dist/{server-core/src/api → api}/schema-editor-routes.d.ts +0 -0
  222. /package/dist/{server-core/src/api → api}/server.d.ts +0 -0
  223. /package/dist/{server-core/src/auth → auth}/adapter-middleware.d.ts +0 -0
  224. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-middleware.d.ts +0 -0
  225. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-permission-guard.d.ts +0 -0
  226. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-routes.d.ts +0 -0
  227. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-store.d.ts +0 -0
  228. /package/dist/{server-core/src/auth → auth}/api-keys/api-key-types.d.ts +0 -0
  229. /package/dist/{server-core/src/auth → auth}/apple-oauth.d.ts +0 -0
  230. /package/dist/{server-core/src/auth → auth}/bitbucket-oauth.d.ts +0 -0
  231. /package/dist/{server-core/src/auth → auth}/crypto-utils.d.ts +0 -0
  232. /package/dist/{server-core/src/auth → auth}/custom-auth-adapter.d.ts +0 -0
  233. /package/dist/{server-core/src/auth → auth}/discord-oauth.d.ts +0 -0
  234. /package/dist/{server-core/src/auth → auth}/facebook-oauth.d.ts +0 -0
  235. /package/dist/{server-core/src/auth → auth}/github-oauth.d.ts +0 -0
  236. /package/dist/{server-core/src/auth → auth}/gitlab-oauth.d.ts +0 -0
  237. /package/dist/{server-core/src/auth → auth}/google-oauth.d.ts +0 -0
  238. /package/dist/{server-core/src/auth → auth}/interfaces.d.ts +0 -0
  239. /package/dist/{server-core/src/auth → auth}/linkedin-oauth.d.ts +0 -0
  240. /package/dist/{server-core/src/auth → auth}/mfa.d.ts +0 -0
  241. /package/dist/{server-core/src/auth → auth}/microsoft-oauth.d.ts +0 -0
  242. /package/dist/{server-core/src/auth → auth}/middleware.d.ts +0 -0
  243. /package/dist/{server-core/src/auth → auth}/password.d.ts +0 -0
  244. /package/dist/{server-core/src/auth → auth}/rate-limiter.d.ts +0 -0
  245. /package/dist/{server-core/src/auth → auth}/rls-scope.d.ts +0 -0
  246. /package/dist/{server-core/src/auth → auth}/routes.d.ts +0 -0
  247. /package/dist/{server-core/src/auth → auth}/slack-oauth.d.ts +0 -0
  248. /package/dist/{server-core/src/auth → auth}/spotify-oauth.d.ts +0 -0
  249. /package/dist/{server-core/src/auth → auth}/twitter-oauth.d.ts +0 -0
  250. /package/dist/{server-core/src/collections → collections}/BackendCollectionRegistry.d.ts +0 -0
  251. /package/dist/{server-core/src/collections → collections}/loader.d.ts +0 -0
  252. /package/dist/{server-core/src/cron → cron}/cron-loader.d.ts +0 -0
  253. /package/dist/{server-core/src/cron → cron}/cron-routes.d.ts +0 -0
  254. /package/dist/{server-core/src/cron → cron}/cron-store.d.ts +0 -0
  255. /package/dist/{server-core/src/cron → cron}/index.d.ts +0 -0
  256. /package/dist/{server-core/src/db → db}/interfaces.d.ts +0 -0
  257. /package/dist/{server-core/src/email → email}/index.d.ts +0 -0
  258. /package/dist/{server-core/src/email → email}/smtp-email-service.d.ts +0 -0
  259. /package/dist/{server-core/src/email → email}/templates.d.ts +0 -0
  260. /package/dist/{server-core/src/email → email}/types.d.ts +0 -0
  261. /package/dist/{server-core/src/functions → functions}/function-loader.d.ts +0 -0
  262. /package/dist/{server-core/src/functions → functions}/function-routes.d.ts +0 -0
  263. /package/dist/{server-core/src/functions → functions}/index.d.ts +0 -0
  264. /package/dist/{server-core/src/history → history}/history-routes.d.ts +0 -0
  265. /package/dist/{server-core/src/history → history}/index.d.ts +0 -0
  266. /package/dist/{server-core/src/serve-spa.d.ts → serve-spa.d.ts} +0 -0
  267. /package/dist/{server-core/src/services → services}/driver-registry.d.ts +0 -0
  268. /package/dist/{server-core/src/services → services}/webhook-service.d.ts +0 -0
  269. /package/dist/{server-core/src/singleton.d.ts → singleton.d.ts} +0 -0
  270. /package/dist/{server-core/src/storage → storage}/LocalStorageController.d.ts +0 -0
  271. /package/dist/{server-core/src/storage → storage}/S3StorageController.d.ts +0 -0
  272. /package/dist/{server-core/src/storage → storage}/index.d.ts +0 -0
  273. /package/dist/{server-core/src/storage → storage}/routes.d.ts +0 -0
  274. /package/dist/{server-core/src/storage → storage}/storage-registry.d.ts +0 -0
  275. /package/dist/{server-core/src/storage → storage}/tus-handler.d.ts +0 -0
  276. /package/dist/{server-core/src/storage → storage}/types.d.ts +0 -0
  277. /package/dist/{server-core/src/types → types}/index.d.ts +0 -0
  278. /package/dist/{server-core/src/utils → utils}/dev-port.d.ts +0 -0
  279. /package/dist/{server-core/src/utils → utils}/logger.d.ts +0 -0
  280. /package/dist/{server-core/src/utils → utils}/logging.d.ts +0 -0
  281. /package/dist/{server-core/src/utils → utils}/request-logger.d.ts +0 -0
  282. /package/dist/{server-core/src/utils → utils}/sql.d.ts +0 -0
package/README.md CHANGED
@@ -1,40 +1,77 @@
1
- # @rebasepro/backend
1
+ # @rebasepro/server-core
2
2
 
3
- PostgreSQL and Drizzle ORM backend implementation for Rebase.
4
-
5
- This package provides a complete backend solution for Rebase applications using PostgreSQL as the database and Drizzle ORM for type-safe database operations.
3
+ Database-agnostic backend core for Rebase.
6
4
 
7
5
  ## Installation
8
6
 
9
7
  ```bash
10
- npm install @rebasepro/backend @rebasepro/core
8
+ pnpm add @rebasepro/server-core
11
9
  ```
12
10
 
13
- ## Usage
11
+ ## What This Package Does
14
12
 
15
- ```typescript
16
- import { createBackend } from "@rebasepro/backend";
13
+ This is the central orchestrator for any Rebase backend. It provides the framework-level plumbing — HTTP routing (Hono), authentication middleware, storage, email, cron jobs, custom functions, and the REST/GraphQL API generator — without being coupled to any specific database. Database implementations are plugged in via driver packages like `@rebasepro/server-postgresql` or `@rebasepro/server-mongodb`.
17
14
 
18
- const backend = createBackend({
19
- connectionString: "postgresql://user:password@localhost:5432/database",
20
- schema: "public",
21
- debug: true
22
- });
23
- ```
15
+ ## Key Exports
16
+
17
+ | Export | Description |
18
+ |--------|-------------|
19
+ | `initializeRebaseBackend(config)` | Main entry point. Wires up drivers, auth, storage, API routes, cron, and custom functions. Returns a `RebaseBackendInstance`. |
20
+ | `rebase` | Server-side singleton (`RebaseClient`). Available after init. Admin-level access to data, auth, email, and storage. |
21
+ | `loadEnv()` | Validates `process.env` against the Rebase env schema (Zod). Auto-generates dev secrets. Supports `extend` for custom vars. |
22
+ | `serveSPA(app, config)` | Mounts SPA static-file serving + index.html fallback on a Hono app. |
23
+ | `RebaseBackendConfig` | Config type for `initializeRebaseBackend`. |
24
+ | `RebaseAuthConfig` | Auth config type (JWT, OAuth providers, hooks, service key). |
25
+ | `RebaseBackendInstance` | Return type — includes `driver`, `healthCheck()`, `shutdown()`, `cronScheduler`, `storageController`, etc. |
26
+ | `RebaseEnv` | Zod-inferred type of validated environment variables. |
27
+ | `z` | Re-exported Zod instance for extending `loadEnv`. |
28
+ | `_setRebaseMock` / `_resetRebaseMock` | Test helpers to mock the `rebase` singleton (NODE_ENV=test only). |
24
29
 
25
- ## Features
30
+ Also re-exports all abstract interfaces (`DatabaseAdapter`, `AuthAdapter`, `DataDriver`, etc.), API types (`HonoEnv`, `ApiConfig`), auth module, email module, storage module, history module, cron module, custom functions, logging utilities, and driver registry.
26
31
 
27
- - PostgreSQL database support
28
- - Drizzle ORM integration
29
- - Type-safe database operations
30
- - Full Rebase compatibility
31
- - Migration support
32
- - Connection pooling
32
+ ## Quick Start
33
33
 
34
- ## Development
34
+ ```typescript
35
+ import { serve } from "@hono/node-server";
36
+ import { Hono } from "hono";
37
+ import { initializeRebaseBackend, loadEnv, serveSPA } from "@rebasepro/server-core";
38
+ import { createPostgresAdapter } from "@rebasepro/server-postgresql";
35
39
 
36
- This package is part of the Rebase monorepo. For development instructions, see the main repository README.
40
+ // 1. Load and validate environment
41
+ const env = loadEnv();
42
+
43
+ // 2. Create Hono app + HTTP server
44
+ const app = new Hono();
45
+ const server = serve({ fetch: app.fetch, port: env.PORT });
46
+
47
+ // 3. Initialize Rebase
48
+ const backend = await initializeRebaseBackend({
49
+ app,
50
+ server,
51
+ database: createPostgresAdapter({ connection: db, schema }),
52
+ collections: myCollections,
53
+ auth: {
54
+ collection: defaultUsersCollection,
55
+ jwtSecret: env.JWT_SECRET,
56
+ allowRegistration: env.ALLOW_REGISTRATION,
57
+ serviceKey: env.REBASE_SERVICE_KEY,
58
+ google: { clientId: env.GOOGLE_CLIENT_ID },
59
+ },
60
+ storage: { type: "s3", bucket: env.S3_BUCKET },
61
+ functionsDir: "./functions",
62
+ cronsDir: "./crons",
63
+ });
64
+
65
+ // 4. Optionally serve a frontend SPA
66
+ serveSPA(app, { frontendPath: "./frontend/dist" });
67
+ ```
37
68
 
38
- ## License
69
+ ## Related Packages
39
70
 
40
- MIT
71
+ | Package | Role |
72
+ |---------|------|
73
+ | `@rebasepro/server-postgresql` | PostgreSQL database driver (Drizzle ORM) |
74
+ | `@rebasepro/server-mongodb` | MongoDB database driver |
75
+ | `@rebasepro/types` | Shared type definitions (`DataDriver`, `EntityCollection`, etc.) |
76
+ | `@rebasepro/client` | Client SDK used internally by the `rebase` singleton |
77
+ | `@rebasepro/common` | Shared utilities and default collections |
@@ -1,4 +1,5 @@
1
- import { ErrorHandler } from "hono";
1
+ import type { ErrorHandler } from "hono";
2
+ import type { HonoEnv } from "./types";
2
3
  /**
3
4
  * Standardized API error class.
4
5
  * Throw this from any route handler — the errorHandler middleware
@@ -26,10 +27,27 @@ export interface ErrorResponse {
26
27
  message: string;
27
28
  code: string;
28
29
  details?: unknown;
30
+ /** Request correlation ID for tracing (echoes X-Request-ID). */
31
+ requestId?: string;
29
32
  };
30
33
  }
34
+ /**
35
+ * General shape of errors that flow through the API error handler.
36
+ * Extends Error with optional HTTP status, error code, and details.
37
+ */
38
+ export interface RebaseApiError extends Error {
39
+ statusCode?: number;
40
+ code?: string;
41
+ details?: unknown;
42
+ }
43
+ /**
44
+ * Type guard for errors that carry optional API metadata (statusCode, code, details).
45
+ * Returns true for any Error instance — the optional properties are then
46
+ * checked via normal property access.
47
+ */
48
+ export declare function isRebaseApiError(error: unknown): error is RebaseApiError;
31
49
  /**
32
50
  * Hono error-handling middleware (`app.onError`).
33
51
  * Converts any error into the canonical `{ error: { message, code } }` shape.
34
52
  */
35
- export declare const errorHandler: ErrorHandler;
53
+ export declare const errorHandler: ErrorHandler<HonoEnv>;
@@ -1,5 +1,5 @@
1
1
  import { Hono } from "hono";
2
- import { DataDriver, EntityCollection, DataHooks } from "@rebasepro/types";
2
+ import { AuthAdapter, DataDriver, EntityCollection, DataHooks } from "@rebasepro/types";
3
3
  import { HonoEnv } from "../types";
4
4
  /**
5
5
  * Lightweight REST API generator that leverages existing Rebase DataDriver.
@@ -10,7 +10,8 @@ export declare class RestApiGenerator {
10
10
  private router;
11
11
  private driver;
12
12
  private dataHooks?;
13
- constructor(collections: EntityCollection[], driver: DataDriver, dataHooks?: DataHooks);
13
+ private authAdapter?;
14
+ constructor(collections: EntityCollection[], driver: DataDriver, dataHooks?: DataHooks, authAdapter?: AuthAdapter);
14
15
  /** Build a BackendHookContext from a Hono context */
15
16
  private buildHookContext;
16
17
  /**
@@ -23,6 +24,11 @@ export declare class RestApiGenerator {
23
24
  * No-ops if the request is not authenticated via an API key.
24
25
  */
25
26
  private enforceApiKeyPermission;
27
+ /**
28
+ * Get the request-scoped driver. Throws if none is set — never falls
29
+ * back to the unscoped `this.driver` to avoid bypassing RLS/auth.
30
+ */
31
+ private getScopedDriver;
26
32
  /**
27
33
  * Get the typed RestFetchService from a driver if it exposes one (for include support).
28
34
  */
@@ -16,6 +16,8 @@ export type HonoEnv = {
16
16
  driver?: DataDriver;
17
17
  /** Set when the request is authenticated via a Service API Key. */
18
18
  apiKey?: ApiKeyMasked;
19
+ /** Unique request correlation ID (generated or propagated from X-Request-ID header). */
20
+ requestId?: string;
19
21
  };
20
22
  };
21
23
  /**
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Admin User Operations
3
+ *
4
+ * Shared utilities and orchestration for admin-initiated user management
5
+ * (user creation via REST API, password reset via admin panel).
6
+ *
7
+ * Hook resolution order:
8
+ * 1. Collection-level hook (`auth.onCreateUser` on the collection) — closest to the data
9
+ * 2. Backend-level hook (`AuthHooks.onAdminCreateUser`) — global override
10
+ * 3. Built-in default — framework fallback
11
+ */
12
+ import type { AuthRepository } from "./interfaces";
13
+ import type { EmailService, EmailConfig } from "../email";
14
+ import type { ResolvedAuthHooks } from "./auth-hooks";
15
+ import type { AuthCollectionConfig } from "@rebasepro/types";
16
+ /**
17
+ * Generate a cryptographically secure random password that meets strength requirements.
18
+ *
19
+ * 16 characters, guaranteed at least one uppercase, one lowercase, one digit.
20
+ * Ambiguous characters (0, O, 1, l, I) are excluded.
21
+ */
22
+ export declare function generateSecurePassword(): string;
23
+ /**
24
+ * Generate a cryptographically secure random token (80 hex characters).
25
+ */
26
+ export declare function generateSecureToken(): string;
27
+ /**
28
+ * Hash a token for database storage using SHA-256.
29
+ */
30
+ export declare function hashToken(token: string): string;
31
+ /**
32
+ * Context needed by admin user creation / password reset operations.
33
+ */
34
+ export interface AdminUserContext {
35
+ authRepo: AuthRepository;
36
+ emailService?: EmailService;
37
+ emailConfig?: EmailConfig;
38
+ resolvedHooks: ResolvedAuthHooks;
39
+ /** The parsed auth config from the collection (if `auth` is an object, not just `true`). */
40
+ collectionAuthConfig?: AuthCollectionConfig;
41
+ }
42
+ /**
43
+ * Result of preparing user values for admin-initiated creation.
44
+ */
45
+ export interface AdminUserPrepareResult {
46
+ /** Values ready for `driver.saveEntity()`. */
47
+ values: Record<string, unknown>;
48
+ /** The cleartext password (for returning to admin or sending via email). */
49
+ clearPassword?: string;
50
+ /** Whether the hook already handled the invitation email. */
51
+ hookHandledEmail: boolean;
52
+ /** Whether an invitation was sent (only relevant when hookHandledEmail is true). */
53
+ invitationSent: boolean;
54
+ }
55
+ /**
56
+ * Prepare user values for an admin-initiated user creation.
57
+ *
58
+ * Resolution order:
59
+ * 1. Collection-level `auth.onCreateUser` — closest to the data
60
+ * 2. Backend-level `AuthHooks.onAdminCreateUser` — global override
61
+ * 3. Built-in default — generate password → hash → normalize email
62
+ *
63
+ * The caller is responsible for persisting (via `driver.saveEntity()`).
64
+ */
65
+ export declare function prepareAdminUserValues(body: Record<string, unknown>, ctx: AdminUserContext): Promise<AdminUserPrepareResult>;
66
+ /**
67
+ * Handle post-creation work for admin-created users.
68
+ *
69
+ * Sends an invitation email (password-reset link) if email is configured
70
+ * and no explicit password was provided. Falls back to returning the
71
+ * temporary password if email fails or is not configured.
72
+ */
73
+ export declare function finalizeAdminUserCreation(entity: {
74
+ id: string;
75
+ values: Record<string, unknown>;
76
+ }, clearPassword: string | undefined, ctx: AdminUserContext): Promise<{
77
+ temporaryPassword?: string;
78
+ invitationSent: boolean;
79
+ }>;
@@ -6,12 +6,12 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- export type { ApiKey, ApiKeyMasked, ApiKeyPermission, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest, } from "./api-key-types";
9
+ export type { ApiKey, ApiKeyMasked, ApiKeyPermission, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest } from "./api-key-types";
10
10
  export { createApiKeyStore } from "./api-key-store";
11
11
  export type { ApiKeyStore } from "./api-key-store";
12
12
  export { isApiKeyToken, validateApiKey } from "./api-key-middleware";
13
13
  export type { ApiKeyAuthOptions } from "./api-key-middleware";
14
- export { httpMethodToOperation, isOperationAllowed, } from "./api-key-permission-guard";
14
+ export { httpMethodToOperation, isOperationAllowed } from "./api-key-permission-guard";
15
15
  export type { ApiKeyOperation } from "./api-key-permission-guard";
16
16
  export { createApiKeyRoutes } from "./api-key-routes";
17
17
  export type { ApiKeyRouteOptions } from "./api-key-routes";
@@ -38,6 +38,7 @@
38
38
  */
39
39
  import type { PasswordValidationResult } from "./password";
40
40
  import type { AuthRepository, UserData, CreateUserData } from "./interfaces";
41
+ import type { EmailService, EmailConfig } from "../email";
41
42
  /**
42
43
  * Authentication method identifier for lifecycle hooks.
43
44
  */
@@ -176,22 +177,49 @@ export interface AuthHooks {
176
177
  * This is fire-and-forget — errors are logged but do not fail the request.
177
178
  */
178
179
  afterUserDelete?(userId: string): Promise<void>;
180
+ /**
181
+ * Optional hook to customize or override the default user creation flow via the admin panel/REST API.
182
+ * When provided, this replaces the built-in password generation, hashing, and invitation email logic.
183
+ */
184
+ onAdminCreateUser?(values: Record<string, unknown>, ctx: {
185
+ authRepo: AuthRepository;
186
+ emailService?: EmailService;
187
+ emailConfig?: EmailConfig;
188
+ hashPassword: (password: string) => Promise<string>;
189
+ }): Promise<{
190
+ values: Record<string, unknown>;
191
+ temporaryPassword?: string;
192
+ invitationSent?: boolean;
193
+ }>;
194
+ /**
195
+ * Optional hook to customize or override the default password reset flow via the admin panel.
196
+ * When provided, this replaces the built-in password reset token generation, hashing, and email logic.
197
+ */
198
+ onAdminResetPassword?(userId: string, ctx: {
199
+ authRepo: AuthRepository;
200
+ emailService?: EmailService;
201
+ emailConfig?: EmailConfig;
202
+ }): Promise<{
203
+ temporaryPassword?: string;
204
+ invitationSent?: boolean;
205
+ }>;
179
206
  }
180
207
  /**
181
- * Resolved auth operationsevery method is guaranteed to exist.
208
+ * Resolved auth hookspassword operations are guaranteed to exist,
209
+ * all other hooks are passed through as-is (optional).
210
+ *
182
211
  * Created by `resolveAuthHooks()` which merges user hooks
183
212
  * with built-in defaults.
213
+ *
214
+ * Consumers should use the resolved object exclusively —
215
+ * never access the raw `AuthHooks` directly.
184
216
  */
185
- export interface ResolvedAuthOperations {
186
- hashPassword(password: string): Promise<string>;
187
- verifyPassword(password: string, storedHash: string): Promise<boolean>;
188
- validatePasswordStrength(password: string): PasswordValidationResult;
189
- }
217
+ export type ResolvedAuthHooks = Required<Pick<AuthHooks, "hashPassword" | "verifyPassword" | "validatePasswordStrength">> & Omit<AuthHooks, "hashPassword" | "verifyPassword" | "validatePasswordStrength">;
190
218
  /**
191
219
  * Merge user-provided hooks with the built-in defaults to produce
192
- * a complete set of resolved operations.
220
+ * a complete set of resolved hooks.
193
221
  *
194
222
  * This is the single point where defaults are applied — all consumers
195
- * call this once and use the resolved operations throughout.
223
+ * call this once and use the resolved hooks throughout.
196
224
  */
197
- export declare function resolveAuthHooks(hooks?: AuthHooks): ResolvedAuthOperations;
225
+ export declare function resolveAuthHooks(hooks?: AuthHooks): ResolvedAuthHooks;
@@ -6,10 +6,10 @@
6
6
  * when the user passes a plain `RebaseAuthConfig` object.
7
7
  *
8
8
  * This is NOT a rewrite — it delegates to the existing `createAuthRoutes()`,
9
- * `createAdminRoutes()`, and `verifyAccessToken()` functions. The goal is to
9
+ * `createResetPasswordRoute()`, and `verifyAccessToken()` functions. The goal is to
10
10
  * present the same functionality through the pluggable `AuthAdapter` contract.
11
11
  */
12
- import type { AuthAdapter, BackendHooks } from "@rebasepro/types";
12
+ import type { AuthAdapter } from "@rebasepro/types";
13
13
  import type { AuthRepository, OAuthProvider } from "./interfaces";
14
14
  import type { AuthHooks } from "./auth-hooks";
15
15
  import type { EmailService, EmailConfig } from "../email";
@@ -34,10 +34,10 @@ export interface BuiltinAuthAdapterConfig {
34
34
  oauthProviders?: OAuthProvider<any>[];
35
35
  /** Static service key for server-to-server auth. */
36
36
  serviceKey?: string;
37
- /** Backend hooks for intercepting admin data. */
38
- hooks?: BackendHooks;
39
37
  /** Auth hooks for customizing password, credentials, lifecycle, etc. */
40
38
  authHooks?: AuthHooks;
39
+ /** The parsed auth config from the collection (if `auth` is an object, not just `true`). */
40
+ collectionAuthConfig?: import("@rebasepro/types").AuthCollectionConfig;
41
41
  }
42
42
  /**
43
43
  * Create the built-in Rebase auth adapter.
@@ -3,8 +3,10 @@ export { configureJwt, generateAccessToken, verifyAccessToken, generateRefreshTo
3
3
  export type { JwtConfig, AccessTokenPayload } from "./jwt";
4
4
  export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
5
5
  export type { PasswordValidationResult } from "./password";
6
- export type { AuthHooks, AuthMethod, ResolvedAuthOperations } from "./auth-hooks";
6
+ export type { AuthHooks, AuthMethod, ResolvedAuthHooks } from "./auth-hooks";
7
7
  export { resolveAuthHooks } from "./auth-hooks";
8
+ export { generateSecurePassword, generateSecureToken, hashToken, prepareAdminUserValues, finalizeAdminUserCreation } from "./admin-user-ops";
9
+ export type { AdminUserContext, AdminUserPrepareResult } from "./admin-user-ops";
8
10
  export { createGoogleProvider } from "./google-oauth";
9
11
  export type { GoogleProviderConfig } from "./google-oauth";
10
12
  export { createLinkedinProvider } from "./linkedin-oauth";
@@ -22,7 +24,8 @@ export { requireAuth, requireAdmin, optionalAuth, extractUserFromToken, createAu
22
24
  export type { AuthMiddlewareOptions, AuthResult } from "./middleware";
23
25
  export { createAuthRoutes } from "./routes";
24
26
  export type { AuthModuleConfig } from "./routes";
25
- export { createAdminRoutes } from "./admin-routes";
27
+ export { createResetPasswordRoute } from "./reset-password-admin";
28
+ export type { ResetPasswordRouteConfig } from "./reset-password-admin";
26
29
  export { createRateLimiter, defaultAuthLimiter, strictAuthLimiter, createApiKeyRateLimiter, apiKeyKeyGenerator } from "./rate-limiter";
27
30
  export { createApiKeyStore, createApiKeyRoutes, isApiKeyToken, validateApiKey, httpMethodToOperation, isOperationAllowed } from "./api-keys";
28
31
  export type { ApiKey, ApiKeyMasked, ApiKeyPermission, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest, ApiKeyStore, ApiKeyOperation } from "./api-keys";
@@ -9,6 +9,16 @@ export interface AccessTokenPayload {
9
9
  uid?: string;
10
10
  /** Authentication Assurance Level: aal1 = password/oauth, aal2 = MFA verified */
11
11
  aal?: "aal1" | "aal2";
12
+ /** Email claim from the JWT, if present */
13
+ email?: string;
14
+ /** Display name claim from the JWT, if present */
15
+ displayName?: string;
16
+ /** Photo URL claim from the JWT, if present */
17
+ photoURL?: string;
18
+ /** Whether MFA has been verified for this session */
19
+ mfa_verified?: boolean;
20
+ /** Authentication Methods Reference — list of methods used (e.g. 'pwd', 'otp') */
21
+ amr?: string[];
12
22
  }
13
23
  /**
14
24
  * Configure JWT settings - call this during initialization.
@@ -0,0 +1,6 @@
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
+ export declare function mountMfaRoutes(router: Hono<HonoEnv>, config: AuthModuleConfig, ops: ReturnType<typeof resolveAuthHooks>, parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T): void;
@@ -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,25 @@
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
+ interface SessionRoutesConfig {
7
+ router: Hono<HonoEnv>;
8
+ config: AuthModuleConfig;
9
+ ops: ReturnType<typeof resolveAuthHooks>;
10
+ parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T;
11
+ buildAuthResponse: (user: {
12
+ id: string;
13
+ email: string;
14
+ displayName?: string | null;
15
+ photoUrl?: string | null;
16
+ metadata?: Record<string, unknown> | null;
17
+ }, roleIds: string[], accessToken: string, refreshToken: string) => unknown;
18
+ createSessionAndTokens: (userId: string, userAgent: string, ipAddress: string) => Promise<{
19
+ roleIds: string[];
20
+ accessToken: string;
21
+ refreshToken: string;
22
+ }>;
23
+ }
24
+ export declare function mountSessionRoutes(opts: SessionRoutesConfig): void;
25
+ export {};
@@ -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// =============================================================================\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 }): 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":";;;;;;;;AA2dA,SAAgB,WAAW,OAAqD;CAC5E,OAAO,CAAC,CAAC,SAAS,OAAQ,MAAmB,eAAe;AAChE"}
@@ -0,0 +1,42 @@
1
+ import { createRequire as __createRequire } from "module";
2
+ import "process";
3
+ const require = __createRequire(import.meta.url);
4
+ //#region \0rolldown/runtime.js
5
+ var __create = Object.create;
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
+ var __getOwnPropNames = Object.getOwnPropertyNames;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
13
+ var __exportAll = (all, no_symbols) => {
14
+ let target = {};
15
+ for (var name in all) __defProp(target, name, {
16
+ get: all[name],
17
+ enumerable: true
18
+ });
19
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
20
+ return target;
21
+ };
22
+ var __copyProps = (to, from, except, desc) => {
23
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
24
+ key = keys[i];
25
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
26
+ get: ((k) => from[k]).bind(null, key),
27
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
28
+ });
29
+ }
30
+ return to;
31
+ };
32
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
33
+ value: mod,
34
+ enumerable: true
35
+ }) : target, mod));
36
+ var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
38
+ if (typeof require !== "undefined") return require.apply(this, arguments);
39
+ throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
40
+ });
41
+ //#endregion
42
+ export { __toCommonJS as a, __require as i, __esmMin as n, __toESM as o, __exportAll as r, __commonJSMin as t };
@@ -1,5 +1,5 @@
1
1
  import type { CronJobStatus, CronJobLogEntry } from "@rebasepro/types";
2
- import type { RebaseClient } from "@rebasepro/client";
2
+ import type { RebaseClient } from "@rebasepro/types";
3
3
  import type { LoadedCronJob } from "./cron-loader";
4
4
  import type { CronStore } from "./cron-store";
5
5
  /**