@rebasepro/server-core 0.7.0 → 0.9.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 (300) hide show
  1. package/README.md +2 -2
  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/index.d.ts +7 -0
  6. package/dist/api/logs-routes.d.ts +37 -0
  7. package/dist/api/openapi-generator.d.ts +16 -0
  8. package/dist/api/rest/api-generator.d.ts +68 -0
  9. package/{src/api/rest/index.ts → dist/api/rest/index.d.ts} +0 -1
  10. package/dist/api/rest/query-parser.d.ts +6 -0
  11. package/dist/api/schema-editor-routes.d.ts +3 -0
  12. package/dist/api/types.d.ts +56 -0
  13. package/dist/auth/adapter-middleware.d.ts +43 -0
  14. package/dist/auth/admin-roles-route.d.ts +18 -0
  15. package/dist/auth/admin-user-ops.d.ts +79 -0
  16. package/dist/auth/admin-users-route.d.ts +28 -0
  17. package/dist/auth/api-keys/api-key-middleware.d.ts +39 -0
  18. package/{src/auth/api-keys/api-key-permission-guard.ts → dist/auth/api-keys/api-key-permission-guard.d.ts} +2 -34
  19. package/dist/auth/api-keys/api-key-routes.d.ts +20 -0
  20. package/dist/auth/api-keys/api-key-store.d.ts +35 -0
  21. package/{src/auth/api-keys/api-key-types.ts → dist/auth/api-keys/api-key-types.d.ts} +0 -6
  22. package/{src/auth/api-keys/index.ts → dist/auth/api-keys/index.d.ts} +2 -22
  23. package/dist/auth/apple-oauth.d.ts +30 -0
  24. package/{src/auth/auth-hooks.ts → dist/auth/auth-hooks.d.ts} +15 -73
  25. package/dist/auth/bitbucket-oauth.d.ts +11 -0
  26. package/dist/auth/builtin-auth-adapter.d.ts +55 -0
  27. package/dist/auth/cookie-utils.d.ts +32 -0
  28. package/{src/auth/crypto-utils.ts → dist/auth/crypto-utils.d.ts} +1 -16
  29. package/dist/auth/custom-auth-adapter.d.ts +39 -0
  30. package/dist/auth/discord-oauth.d.ts +14 -0
  31. package/dist/auth/facebook-oauth.d.ts +14 -0
  32. package/dist/auth/github-oauth.d.ts +15 -0
  33. package/dist/auth/gitlab-oauth.d.ts +13 -0
  34. package/dist/auth/google-oauth.d.ts +47 -0
  35. package/{src/auth/index.ts → dist/auth/index.d.ts} +4 -22
  36. package/{src/auth/interfaces.ts → dist/auth/interfaces.d.ts} +20 -89
  37. package/dist/auth/jwt.d.ts +67 -0
  38. package/dist/auth/linkedin-oauth.d.ts +18 -0
  39. package/dist/auth/magic-link-routes.d.ts +32 -0
  40. package/dist/auth/mfa-crypto.d.ts +23 -0
  41. package/dist/auth/mfa-routes.d.ts +7 -0
  42. package/dist/auth/mfa.d.ts +49 -0
  43. package/dist/auth/microsoft-oauth.d.ts +16 -0
  44. package/dist/auth/middleware.d.ts +158 -0
  45. package/dist/auth/password.d.ts +22 -0
  46. package/dist/auth/rate-limiter.d.ts +50 -0
  47. package/dist/auth/reset-password-admin.d.ts +29 -0
  48. package/dist/auth/rls-scope.d.ts +31 -0
  49. package/dist/auth/routes.d.ts +66 -0
  50. package/dist/auth/session-routes.d.ts +29 -0
  51. package/dist/auth/slack-oauth.d.ts +12 -0
  52. package/dist/auth/spotify-oauth.d.ts +12 -0
  53. package/dist/auth/twitter-oauth.d.ts +18 -0
  54. package/dist/collections/BackendCollectionRegistry.d.ts +13 -0
  55. package/dist/collections/loader.d.ts +5 -0
  56. package/dist/cron/cron-loader.d.ts +18 -0
  57. package/dist/cron/cron-routes.d.ts +14 -0
  58. package/dist/cron/cron-scheduler.d.ts +106 -0
  59. package/dist/cron/cron-store.d.ts +32 -0
  60. package/dist/cron/define-cron.d.ts +28 -0
  61. package/{src/cron/index.ts → dist/cron/index.d.ts} +1 -0
  62. package/dist/db/interfaces.d.ts +18 -0
  63. package/dist/dynamic-import-Dvh-K5fl.js +22 -0
  64. package/dist/dynamic-import-Dvh-K5fl.js.map +1 -0
  65. package/dist/email/index.d.ts +6 -0
  66. package/dist/email/smtp-email-service.d.ts +30 -0
  67. package/dist/email/templates.d.ts +50 -0
  68. package/{src/email/types.ts → dist/email/types.d.ts} +40 -36
  69. package/dist/env.d.ts +102 -0
  70. package/dist/functions/define-function.d.ts +55 -0
  71. package/dist/functions/function-loader.d.ts +18 -0
  72. package/dist/functions/function-routes.d.ts +10 -0
  73. package/{src/functions/index.ts → dist/functions/index.d.ts} +2 -0
  74. package/dist/history/history-routes.d.ts +23 -0
  75. package/{src/history/index.ts → dist/history/index.d.ts} +0 -1
  76. package/dist/index.d.ts +35 -0
  77. package/dist/index.es.js +18184 -0
  78. package/dist/index.es.js.map +1 -0
  79. package/dist/index.umd.js +48629 -0
  80. package/dist/index.umd.js.map +1 -0
  81. package/dist/init/docs.d.ts +4 -0
  82. package/dist/init/health.d.ts +2 -0
  83. package/dist/init/middlewares.d.ts +10 -0
  84. package/dist/init/shutdown.d.ts +65 -0
  85. package/dist/init/storage.d.ts +5 -0
  86. package/dist/init.d.ts +344 -0
  87. package/dist/jwt-BwIn8xmk.js +4200 -0
  88. package/dist/jwt-BwIn8xmk.js.map +1 -0
  89. package/dist/logger-BYU66ENZ.js +94 -0
  90. package/dist/logger-BYU66ENZ.js.map +1 -0
  91. package/dist/ms-DnYXB-Wd.js +162 -0
  92. package/dist/ms-DnYXB-Wd.js.map +1 -0
  93. package/dist/openapi-generator-Z9oYWLf_.js +586 -0
  94. package/dist/openapi-generator-Z9oYWLf_.js.map +1 -0
  95. package/dist/schema-editor-routes-D3ef8zu1.js +219 -0
  96. package/dist/schema-editor-routes-D3ef8zu1.js.map +1 -0
  97. package/dist/serve-spa.d.ts +36 -0
  98. package/dist/services/driver-registry.d.ts +78 -0
  99. package/dist/services/routed-realtime-service.d.ts +43 -0
  100. package/dist/services/webhook-service.d.ts +29 -0
  101. package/dist/singleton.d.ts +51 -0
  102. package/dist/src-B4OLmNVa.js +437 -0
  103. package/dist/src-B4OLmNVa.js.map +1 -0
  104. package/dist/src-B5WkP1Rv.js +24778 -0
  105. package/dist/src-B5WkP1Rv.js.map +1 -0
  106. package/dist/storage/GCSStorageController.d.ts +43 -0
  107. package/dist/storage/LocalStorageController.d.ts +46 -0
  108. package/dist/storage/S3StorageController.d.ts +40 -0
  109. package/dist/storage/image-transform.d.ts +50 -0
  110. package/{src/storage/index.ts → dist/storage/index.d.ts} +6 -21
  111. package/dist/storage/routes.d.ts +70 -0
  112. package/dist/storage/storage-registry.d.ts +78 -0
  113. package/dist/storage/tus-handler.d.ts +53 -0
  114. package/{src/storage/types.ts → dist/storage/types.d.ts} +32 -38
  115. package/dist/types/index.d.ts +11 -0
  116. package/dist/utils/dev-port.d.ts +45 -0
  117. package/dist/utils/dynamic-import.d.ts +25 -0
  118. package/dist/utils/logger.d.ts +31 -0
  119. package/dist/utils/logging.d.ts +9 -0
  120. package/dist/utils/request-id.d.ts +4 -0
  121. package/dist/utils/request-logger.d.ts +19 -0
  122. package/{src/utils/sql.ts → dist/utils/sql.d.ts} +5 -16
  123. package/package.json +49 -22
  124. package/coverage/clover.xml +0 -3739
  125. package/coverage/coverage-final.json +0 -31
  126. package/coverage/lcov-report/base.css +0 -224
  127. package/coverage/lcov-report/block-navigation.js +0 -87
  128. package/coverage/lcov-report/favicon.png +0 -0
  129. package/coverage/lcov-report/index.html +0 -266
  130. package/coverage/lcov-report/prettify.css +0 -1
  131. package/coverage/lcov-report/prettify.js +0 -2
  132. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  133. package/coverage/lcov-report/sorter.js +0 -210
  134. package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +0 -952
  135. package/coverage/lcov-report/src/api/errors.ts.html +0 -472
  136. package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +0 -1069
  137. package/coverage/lcov-report/src/api/graphql/index.html +0 -116
  138. package/coverage/lcov-report/src/api/index.html +0 -176
  139. package/coverage/lcov-report/src/api/openapi-generator.ts.html +0 -565
  140. package/coverage/lcov-report/src/api/rest/api-generator.ts.html +0 -994
  141. package/coverage/lcov-report/src/api/rest/index.html +0 -131
  142. package/coverage/lcov-report/src/api/rest/query-parser.ts.html +0 -550
  143. package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +0 -202
  144. package/coverage/lcov-report/src/api/server.ts.html +0 -823
  145. package/coverage/lcov-report/src/auth/admin-routes.ts.html +0 -973
  146. package/coverage/lcov-report/src/auth/index.html +0 -176
  147. package/coverage/lcov-report/src/auth/jwt.ts.html +0 -574
  148. package/coverage/lcov-report/src/auth/middleware.ts.html +0 -745
  149. package/coverage/lcov-report/src/auth/password.ts.html +0 -310
  150. package/coverage/lcov-report/src/auth/services.ts.html +0 -2074
  151. package/coverage/lcov-report/src/collections/index.html +0 -116
  152. package/coverage/lcov-report/src/collections/loader.ts.html +0 -232
  153. package/coverage/lcov-report/src/db/auth-schema.ts.html +0 -523
  154. package/coverage/lcov-report/src/db/data-transformer.ts.html +0 -1753
  155. package/coverage/lcov-report/src/db/entityService.ts.html +0 -700
  156. package/coverage/lcov-report/src/db/index.html +0 -146
  157. package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +0 -4048
  158. package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +0 -883
  159. package/coverage/lcov-report/src/db/services/RelationService.ts.html +0 -3121
  160. package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +0 -442
  161. package/coverage/lcov-report/src/db/services/index.html +0 -176
  162. package/coverage/lcov-report/src/db/services/index.ts.html +0 -124
  163. package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +0 -1960
  164. package/coverage/lcov-report/src/index.html +0 -116
  165. package/coverage/lcov-report/src/services/driver-registry.ts.html +0 -631
  166. package/coverage/lcov-report/src/services/index.html +0 -131
  167. package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +0 -3025
  168. package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +0 -1189
  169. package/coverage/lcov-report/src/storage/S3StorageController.ts.html +0 -970
  170. package/coverage/lcov-report/src/storage/index.html +0 -161
  171. package/coverage/lcov-report/src/storage/storage-registry.ts.html +0 -646
  172. package/coverage/lcov-report/src/storage/types.ts.html +0 -451
  173. package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +0 -3082
  174. package/coverage/lcov-report/src/utils/index.html +0 -116
  175. package/coverage/lcov.info +0 -7179
  176. package/jest.config.cjs +0 -19
  177. package/src/api/ast-schema-editor.ts +0 -289
  178. package/src/api/collections_for_test/callbacks_test_collection.ts +0 -61
  179. package/src/api/errors.ts +0 -278
  180. package/src/api/graphql/graphql-schema-generator.ts +0 -383
  181. package/src/api/graphql/index.ts +0 -2
  182. package/src/api/index.ts +0 -11
  183. package/src/api/logs-routes.ts +0 -132
  184. package/src/api/openapi-generator.ts +0 -727
  185. package/src/api/rest/api-generator-count.test.ts +0 -126
  186. package/src/api/rest/api-generator.ts +0 -747
  187. package/src/api/rest/query-parser.ts +0 -300
  188. package/src/api/schema-editor-routes.ts +0 -41
  189. package/src/api/server.ts +0 -271
  190. package/src/api/types.ts +0 -104
  191. package/src/auth/adapter-middleware.ts +0 -114
  192. package/src/auth/admin-roles-route.ts +0 -36
  193. package/src/auth/admin-user-ops.ts +0 -236
  194. package/src/auth/admin-users-route.ts +0 -302
  195. package/src/auth/api-keys/api-key-middleware.ts +0 -133
  196. package/src/auth/api-keys/api-key-routes.ts +0 -193
  197. package/src/auth/api-keys/api-key-store.ts +0 -340
  198. package/src/auth/apple-oauth.ts +0 -122
  199. package/src/auth/bitbucket-oauth.ts +0 -84
  200. package/src/auth/builtin-auth-adapter.ts +0 -380
  201. package/src/auth/custom-auth-adapter.ts +0 -86
  202. package/src/auth/discord-oauth.ts +0 -85
  203. package/src/auth/facebook-oauth.ts +0 -74
  204. package/src/auth/github-oauth.ts +0 -112
  205. package/src/auth/gitlab-oauth.ts +0 -72
  206. package/src/auth/google-oauth.ts +0 -223
  207. package/src/auth/jwt.ts +0 -208
  208. package/src/auth/linkedin-oauth.ts +0 -83
  209. package/src/auth/magic-link-routes.ts +0 -167
  210. package/src/auth/mfa-crypto.ts +0 -91
  211. package/src/auth/mfa-routes.ts +0 -323
  212. package/src/auth/mfa.ts +0 -161
  213. package/src/auth/microsoft-oauth.ts +0 -90
  214. package/src/auth/middleware.ts +0 -369
  215. package/src/auth/password.ts +0 -77
  216. package/src/auth/rate-limiter.ts +0 -225
  217. package/src/auth/reset-password-admin.ts +0 -160
  218. package/src/auth/rls-scope.ts +0 -58
  219. package/src/auth/routes.ts +0 -802
  220. package/src/auth/session-routes.ts +0 -353
  221. package/src/auth/slack-oauth.ts +0 -73
  222. package/src/auth/spotify-oauth.ts +0 -69
  223. package/src/auth/twitter-oauth.ts +0 -128
  224. package/src/collections/BackendCollectionRegistry.ts +0 -20
  225. package/src/collections/loader.ts +0 -50
  226. package/src/cron/cron-loader.ts +0 -84
  227. package/src/cron/cron-routes.test.ts +0 -265
  228. package/src/cron/cron-routes.ts +0 -85
  229. package/src/cron/cron-scheduler.test.ts +0 -559
  230. package/src/cron/cron-scheduler.ts +0 -581
  231. package/src/cron/cron-store.ts +0 -166
  232. package/src/db/interfaces.ts +0 -60
  233. package/src/email/index.ts +0 -19
  234. package/src/email/smtp-email-service.ts +0 -123
  235. package/src/email/templates.ts +0 -470
  236. package/src/env.ts +0 -227
  237. package/src/functions/function-loader.ts +0 -116
  238. package/src/functions/function-routes.ts +0 -31
  239. package/src/history/history-routes.ts +0 -129
  240. package/src/index.ts +0 -70
  241. package/src/init/docs.ts +0 -47
  242. package/src/init/health.ts +0 -37
  243. package/src/init/middlewares.ts +0 -61
  244. package/src/init/shutdown.ts +0 -56
  245. package/src/init/storage.ts +0 -57
  246. package/src/init.ts +0 -1041
  247. package/src/serve-spa.ts +0 -89
  248. package/src/services/driver-registry.ts +0 -183
  249. package/src/services/routed-realtime-service.ts +0 -113
  250. package/src/services/webhook-service.ts +0 -155
  251. package/src/singleton.ts +0 -70
  252. package/src/storage/LocalStorageController.ts +0 -389
  253. package/src/storage/S3StorageController.ts +0 -300
  254. package/src/storage/image-transform.ts +0 -218
  255. package/src/storage/routes.ts +0 -368
  256. package/src/storage/storage-registry.ts +0 -188
  257. package/src/storage/tus-handler.ts +0 -315
  258. package/src/types/index.ts +0 -27
  259. package/src/utils/dev-port.ts +0 -196
  260. package/src/utils/logger.ts +0 -143
  261. package/src/utils/logging.ts +0 -40
  262. package/src/utils/request-id.ts +0 -40
  263. package/src/utils/request-logger.ts +0 -72
  264. package/test/api-generator.test.ts +0 -588
  265. package/test/api-key-permission-guard.test.ts +0 -144
  266. package/test/ast-schema-editor.test.ts +0 -89
  267. package/test/auth-middleware-hono.test.ts +0 -556
  268. package/test/auth-routes.test.ts +0 -1098
  269. package/test/backend-hooks-data.test.ts +0 -477
  270. package/test/custom-auth-adapter.test.ts +0 -189
  271. package/test/driver-registry.test.ts +0 -282
  272. package/test/email-templates.test.ts +0 -174
  273. package/test/env.test.ts +0 -128
  274. package/test/error-propagation.test.ts +0 -226
  275. package/test/errors-hono.test.ts +0 -133
  276. package/test/errors.test.ts +0 -155
  277. package/test/function-loader.test.ts +0 -127
  278. package/test/graphql-schema-generator.test.ts +0 -554
  279. package/test/jwt-security.test.ts +0 -182
  280. package/test/jwt.test.ts +0 -326
  281. package/test/mfa.test.ts +0 -197
  282. package/test/middleware.test.ts +0 -305
  283. package/test/multi-datasource-routing.test.ts +0 -113
  284. package/test/password.test.ts +0 -165
  285. package/test/query-parser.test.ts +0 -233
  286. package/test/rate-limiter.test.ts +0 -102
  287. package/test/reset-password-admin.test.ts +0 -113
  288. package/test/routed-realtime-service.test.ts +0 -86
  289. package/test/safe-compare.test.ts +0 -66
  290. package/test/singleton.test.ts +0 -59
  291. package/test/smtp-email-service.test.ts +0 -169
  292. package/test/storage-local.test.ts +0 -271
  293. package/test/storage-registry.test.ts +0 -282
  294. package/test/storage-routes.test.ts +0 -222
  295. package/test/storage-s3.test.ts +0 -304
  296. package/test/transform-auth-response.test.ts +0 -305
  297. package/test/webhook-service.test.ts +0 -260
  298. package/tsconfig.json +0 -54
  299. package/tsconfig.prod.json +0 -23
  300. package/vite.config.ts +0 -86
package/README.md CHANGED
@@ -10,7 +10,7 @@ pnpm add @rebasepro/server-core
10
10
 
11
11
  ## What This Package Does
12
12
 
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`.
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 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`.
14
14
 
15
15
  ## Key Exports
16
16
 
@@ -72,6 +72,6 @@ serveSPA(app, { frontendPath: "./frontend/dist" });
72
72
  |---------|------|
73
73
  | `@rebasepro/server-postgresql` | PostgreSQL database driver (Drizzle ORM) |
74
74
  | `@rebasepro/server-mongodb` | MongoDB database driver |
75
- | `@rebasepro/types` | Shared type definitions (`DataDriver`, `EntityCollection`, etc.) |
75
+ | `@rebasepro/types` | Shared type definitions (`DataDriver`, `CollectionConfig`, etc.) |
76
76
  | `@rebasepro/client` | Client SDK used internally by the `rebase` singleton |
77
77
  | `@rebasepro/common` | Shared utilities and default collections |
@@ -0,0 +1,21 @@
1
+ export declare class AstSchemaEditor {
2
+ private project;
3
+ private collectionsDir;
4
+ constructor(collectionsDir: string);
5
+ /**
6
+ * Sanitize collectionId to prevent path traversal attacks.
7
+ * Only allows alphanumeric characters, underscores, and hyphens.
8
+ */
9
+ private sanitizeCollectionId;
10
+ /**
11
+ * Resolve a file path and ensure it falls within the collectionsDir.
12
+ */
13
+ private safePath;
14
+ private getCollectionFile;
15
+ private getCollectionObject;
16
+ private convertJsonToAstString;
17
+ saveProperty(collectionId: string, propertyKey: string, propertyConfig: Record<string, unknown>): Promise<void>;
18
+ deleteProperty(collectionId: string, propertyKey: string): Promise<void>;
19
+ saveCollection(collectionId: string, collectionData: Record<string, unknown>): Promise<void>;
20
+ deleteCollection(collectionId: string): Promise<void>;
21
+ }
@@ -0,0 +1,2 @@
1
+ import { PostgresCollectionConfig } from "@rebasepro/types";
2
+ export declare const callbacksTestCollection: PostgresCollectionConfig;
@@ -0,0 +1,53 @@
1
+ import type { ErrorHandler } from "hono";
2
+ import type { HonoEnv } from "./types";
3
+ /**
4
+ * Standardized API error class.
5
+ * Throw this from any route handler — the errorHandler middleware
6
+ * will format it into `{ error: { message, code, details? } }`.
7
+ */
8
+ export declare class ApiError extends Error {
9
+ readonly statusCode: number;
10
+ readonly code: string;
11
+ readonly details?: unknown;
12
+ constructor(statusCode: number, code: string, message: string, details?: unknown);
13
+ static badRequest(message: string, code?: string, details?: unknown): ApiError;
14
+ static unauthorized(message: string, code?: string): ApiError;
15
+ static forbidden(message: string, code?: string): ApiError;
16
+ static notFound(message: string, code?: string): ApiError;
17
+ static conflict(message: string, code?: string): ApiError;
18
+ static internal(message: string, code?: string): ApiError;
19
+ static serviceUnavailable(message: string, code?: string): ApiError;
20
+ }
21
+ /**
22
+ * Canonical error response shape:
23
+ * `{ error: { message: string, code: string, details?: unknown } }`
24
+ */
25
+ export interface ErrorResponse {
26
+ error: {
27
+ message: string;
28
+ code: string;
29
+ details?: unknown;
30
+ /** Request correlation ID for tracing (echoes X-Request-ID). */
31
+ requestId?: string;
32
+ };
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;
49
+ /**
50
+ * Hono error-handling middleware (`app.onError`).
51
+ * Converts any error into the canonical `{ error: { message, code } }` shape.
52
+ */
53
+ export declare const errorHandler: ErrorHandler<HonoEnv>;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * API generation infrastructure for Rebase
3
+ * Automatically generates REST APIs from CollectionConfig definitions
4
+ */
5
+ export * from "./rest";
6
+ export * from "./types";
7
+ export * from "./errors";
@@ -0,0 +1,37 @@
1
+ import { Hono } from "hono";
2
+ import type { MiddlewareHandler } from "hono";
3
+ import type { HonoEnv } from "./types";
4
+ export interface LogEntry {
5
+ id: string;
6
+ timestamp: string;
7
+ level: "debug" | "info" | "warn" | "error";
8
+ source: "api" | "auth" | "storage" | "realtime" | "system";
9
+ message: string;
10
+ metadata?: Record<string, unknown>;
11
+ }
12
+ declare class LogRingBuffer {
13
+ private buffer;
14
+ private maxSize;
15
+ private idCounter;
16
+ constructor(maxSize?: number);
17
+ push(entry: Omit<LogEntry, "id">): void;
18
+ query(options: {
19
+ level?: string;
20
+ source?: string;
21
+ search?: string;
22
+ limit?: number;
23
+ offset?: number;
24
+ since?: string;
25
+ }): {
26
+ entries: LogEntry[];
27
+ total: number;
28
+ };
29
+ getLatest(count?: number): LogEntry[];
30
+ }
31
+ export declare const logBuffer: LogRingBuffer;
32
+ /** Add a log entry */
33
+ export declare function addLog(level: LogEntry["level"], source: LogEntry["source"], message: string, metadata?: Record<string, unknown>): void;
34
+ /** Hono middleware to log API requests */
35
+ export declare function logMiddleware(): MiddlewareHandler<HonoEnv>;
36
+ declare const app: Hono<HonoEnv, import("hono/types").BlankSchema, "/">;
37
+ export default app;
@@ -0,0 +1,16 @@
1
+ import { CollectionConfig } from "@rebasepro/types";
2
+ /**
3
+ * OpenAPI 3.0.3 specification generator.
4
+ *
5
+ * Produces a spec that exactly mirrors the REST API consumed by the
6
+ * Rebase SDK client (`@rebasepro/client`).
7
+ *
8
+ * Routes are mounted at `{basePath}/data/{slug}` by `initializeRebaseBackend`.
9
+ */
10
+ export interface OpenApiGeneratorOptions {
11
+ /** Base path for the API (e.g. "/api"). Defaults to "/api". */
12
+ basePath?: string;
13
+ /** Whether auth is enabled on data routes. Defaults to true. */
14
+ requireAuth?: boolean;
15
+ }
16
+ export declare function generateOpenApiSpec(collections: CollectionConfig[], options?: OpenApiGeneratorOptions): Record<string, unknown>;
@@ -0,0 +1,68 @@
1
+ import { Hono } from "hono";
2
+ import { AuthAdapter, DataDriver, CollectionConfig } from "@rebasepro/types";
3
+ import { HonoEnv } from "../types";
4
+ /**
5
+ * Lightweight REST API generator that leverages existing Rebase DataDriver.
6
+ * Supports `include` query parameter for eager-loading relations via Drizzle.
7
+ */
8
+ export declare class RestApiGenerator {
9
+ private collections;
10
+ private router;
11
+ private driver;
12
+ private authAdapter?;
13
+ constructor(collections: CollectionConfig[], driver: DataDriver, authAdapter?: AuthAdapter);
14
+ /**
15
+ * Generate REST routes using existing DataDriver
16
+ */
17
+ generateRoutes(): Hono<HonoEnv>;
18
+ /**
19
+ * Check API key permissions for a collection operation.
20
+ * Throws 403 if the key doesn't have the required permission.
21
+ * No-ops if the request is not authenticated via an API key.
22
+ */
23
+ private enforceApiKeyPermission;
24
+ /**
25
+ * Get the request-scoped driver. Throws if none is set — never falls
26
+ * back to the unscoped `this.driver` to avoid bypassing RLS/auth.
27
+ */
28
+ private getScopedDriver;
29
+ /**
30
+ * Create REST routes for a collection using existing Rebase patterns
31
+ */
32
+ private createCollectionRoutes;
33
+ /**
34
+ * Catch-all routes for subcollection paths.
35
+ *
36
+ * Matches URL patterns like:
37
+ * GET /authors/111094/posts → list child collection
38
+ * GET /authors/111094/posts/43 → get child entity
39
+ * POST /authors/111094/posts → create child entity
40
+ * PUT /authors/111094/posts/43 → update child entity
41
+ * DELETE /authors/111094/posts/43 → delete child entity
42
+ *
43
+ * The `:rest{.+}` regex param captures the full remainder of the URL
44
+ * path (Hono v4 `*` wildcard does not populate `c.req.param("*")`).
45
+ * We split it into segments and reconstruct the `collectionPath`
46
+ * (e.g. "authors/111094/posts") and optional `id` (e.g. "43").
47
+ *
48
+ * The DataDriver.save / fetchCollection / etc. already know how to
49
+ * resolve multi-segment relation paths, so we just forward to them.
50
+ */
51
+ private createSubcollectionRoutes;
52
+ /**
53
+ * Format successful API response
54
+ */
55
+ private formatResponse;
56
+ /**
57
+ * Fetch raw collection data without Entity wrapper (fallback for non-Postgres)
58
+ */
59
+ private fetchRawCollection;
60
+ /**
61
+ * Count raw entities for a collection
62
+ */
63
+ private countRawEntities;
64
+ /**
65
+ * Fetch single entity raw data without Entity wrapper (fallback)
66
+ */
67
+ private fetchRawEntity;
68
+ }
@@ -1,2 +1 @@
1
1
  export * from "./api-generator";
2
-
@@ -0,0 +1,6 @@
1
+ import { QueryOptions } from "../types";
2
+ export declare const mapOperator: (op: string) => import("@rebasepro/types").WhereFilterOp | null;
3
+ /**
4
+ * Parse query parameters into QueryOptions
5
+ */
6
+ export declare function parseQueryOptions(query: Record<string, unknown>): QueryOptions;
@@ -0,0 +1,3 @@
1
+ import { Hono } from "hono";
2
+ import { HonoEnv } from "./types";
3
+ export declare function createSchemaEditorRoutes(collectionsDir: string): Hono<HonoEnv>;
@@ -0,0 +1,56 @@
1
+ import { VectorSearchParams, LogicalCondition, FilterValues } from "@rebasepro/types";
2
+ import { AuthResult } from "../auth/middleware";
3
+ import { DataDriver } from "@rebasepro/types";
4
+ import type { ApiKeyMasked } from "../auth/api-keys/api-key-types";
5
+ /**
6
+ * Hono Environment Variables
7
+ * Passed to generic Hono<HonoEnv> to type `c.get()`
8
+ */
9
+ export type HonoEnv = {
10
+ Variables: {
11
+ user?: AuthResult | {
12
+ userId?: string;
13
+ roles?: string[];
14
+ };
15
+ driver?: DataDriver;
16
+ /** Set when the request is authenticated via a Service API Key. */
17
+ apiKey?: ApiKeyMasked;
18
+ /** Unique request correlation ID (generated or propagated from X-Request-ID header). */
19
+ requestId?: string;
20
+ };
21
+ };
22
+ /**
23
+ * Standard API response format
24
+ */
25
+ export interface ApiResponse<T = unknown> {
26
+ data?: T;
27
+ error?: {
28
+ message: string;
29
+ code?: string;
30
+ details?: unknown;
31
+ };
32
+ meta?: {
33
+ total?: number;
34
+ page?: number;
35
+ limit?: number;
36
+ hasMore?: boolean;
37
+ };
38
+ }
39
+ /**
40
+ * Query options for API endpoints
41
+ */
42
+ export interface QueryOptions {
43
+ limit?: number;
44
+ offset?: number;
45
+ where?: FilterValues<string>;
46
+ logical?: LogicalCondition;
47
+ orderBy?: Array<{
48
+ field: string;
49
+ direction: "asc" | "desc";
50
+ }>;
51
+ include?: string[];
52
+ /** Columns to return in the response (field-level selection) */
53
+ fields?: string[];
54
+ /** Vector similarity search configuration */
55
+ vectorSearch?: VectorSearchParams;
56
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Adapter Auth Middleware
3
+ *
4
+ * Creates a Hono middleware that delegates authentication to an `AuthAdapter`
5
+ * instead of hardcoded JWT verification. This is used when the user passes
6
+ * an `AuthAdapter` to `initializeRebaseBackend()`.
7
+ *
8
+ * The middleware:
9
+ * 1. Checks for API key tokens (`rk_` prefix) first — these are Rebase-level
10
+ * 2. Falls back to `adapter.verifyRequest(request)` to resolve the user
11
+ * 3. Scopes the DataDriver via `withAuth()` for RLS
12
+ * 4. Enforces auth (401) when `requireAuth` is true and no user is found
13
+ *
14
+ * The behavior is identical to `createAuthMiddleware()` — only the
15
+ * token verification strategy is pluggable.
16
+ */
17
+ import type { MiddlewareHandler, Context } from "hono";
18
+ import type { DataDriver, AuthAdapter } from "@rebasepro/types";
19
+ import type { HonoEnv } from "../api/types";
20
+ import type { ApiKeyStore } from "./api-keys/api-key-store";
21
+ export interface AdapterAuthMiddlewareOptions {
22
+ /** The auth adapter to delegate verification to. */
23
+ adapter: AuthAdapter;
24
+ /** The DataDriver to scope via withAuth() for RLS. */
25
+ driver: DataDriver;
26
+ /**
27
+ * Optional per-request driver resolver for multi-data-source backends.
28
+ * Returns the unscoped delegate to use for this request (e.g. Postgres vs
29
+ * Mongo). When omitted, `driver` is used for every request.
30
+ */
31
+ resolveDriver?: (c: Context<HonoEnv>) => DataDriver;
32
+ /**
33
+ * If true, return 401 when no valid user is resolved.
34
+ * Defaults to `true` (secure by default).
35
+ */
36
+ requireAuth?: boolean;
37
+ /** Optional API key store — when provided, `rk_` bearer tokens are accepted. */
38
+ apiKeyStore?: ApiKeyStore;
39
+ }
40
+ /**
41
+ * Create a Hono middleware that uses an `AuthAdapter` for request verification.
42
+ */
43
+ export declare function createAdapterAuthMiddleware(options: AdapterAuthMiddlewareOptions): MiddlewareHandler<HonoEnv>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Admin endpoint for listing all roles.
3
+ *
4
+ * Mounts: GET /roles
5
+ */
6
+ import { Hono } from "hono";
7
+ import type { AuthRepository } from "./interfaces";
8
+ import type { HonoEnv } from "../api/types";
9
+ export interface AdminRolesRouteConfig {
10
+ authRepo: AuthRepository;
11
+ serviceKey?: string;
12
+ }
13
+ /**
14
+ * Create a standalone admin route for listing roles.
15
+ *
16
+ * Mounts: GET /roles
17
+ */
18
+ export declare function createAdminRolesRoute(config: AdminRolesRouteConfig): Hono<HonoEnv>;
@@ -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.save()`. */
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.save()`).
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
+ }>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Standalone admin endpoint for user management.
3
+ *
4
+ * Mounts:
5
+ * GET /users
6
+ * GET /users/:userId
7
+ * POST /users
8
+ * PUT /users/:userId
9
+ * DELETE /users/:userId
10
+ * POST /bootstrap
11
+ */
12
+ import { Hono } from "hono";
13
+ import type { AuthRepository } from "./interfaces";
14
+ import type { AuthHooks } from "./auth-hooks";
15
+ import type { EmailService, EmailConfig } from "../email";
16
+ import type { HonoEnv } from "../api/types";
17
+ import type { AuthCollectionConfig } from "@rebasepro/types";
18
+ export interface AdminUsersRouteConfig {
19
+ authRepo: AuthRepository;
20
+ emailService?: EmailService;
21
+ emailConfig?: EmailConfig;
22
+ serviceKey?: string;
23
+ authHooks?: AuthHooks;
24
+ collectionAuthConfig?: AuthCollectionConfig;
25
+ isBootstrapCompleted?: () => Promise<boolean>;
26
+ setBootstrapCompleted?: () => Promise<void>;
27
+ }
28
+ export declare function createAdminUsersRoute(config: AdminUsersRouteConfig): Hono<HonoEnv>;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Hono middleware for authenticating requests via Service API Keys.
3
+ *
4
+ * This middleware is integrated into `createAuthMiddleware()` and
5
+ * activates only when the bearer token starts with `rk_`. It:
6
+ *
7
+ * 1. Hashes the token with SHA-256
8
+ * 2. Looks up the hash in the `rebase.api_keys` table
9
+ * 3. Validates the key is not revoked and not expired
10
+ * 4. Sets `c.set("user", ...)` and `c.set("apiKey", ...)` for downstream use
11
+ * 5. Scopes the DataDriver via `withAuth()` using the API key's service identity
12
+ *
13
+ * @module
14
+ */
15
+ import type { Context } from "hono";
16
+ import type { DataDriver } from "@rebasepro/types";
17
+ import type { HonoEnv } from "../../api/types";
18
+ import type { ApiKeyStore } from "./api-key-store";
19
+ /**
20
+ * Check whether a token looks like a Rebase API key.
21
+ */
22
+ export declare function isApiKeyToken(token: string): boolean;
23
+ /**
24
+ * Options for the API key authentication handler.
25
+ */
26
+ export interface ApiKeyAuthOptions {
27
+ store: ApiKeyStore;
28
+ driver: DataDriver;
29
+ }
30
+ /**
31
+ * Validate an API key token and populate the Hono context.
32
+ *
33
+ * Returns `true` if the key is valid and context has been populated,
34
+ * or returns an error Response if the key is invalid.
35
+ *
36
+ * This is NOT a standalone middleware — it's called from within
37
+ * `createAuthMiddleware()` when a `rk_` prefixed token is detected.
38
+ */
39
+ export declare function validateApiKey(c: Context<HonoEnv>, token: string, options: ApiKeyAuthOptions): Promise<Response | true>;
@@ -7,12 +7,9 @@
7
7
  *
8
8
  * @module
9
9
  */
10
-
11
10
  import type { ApiKeyPermission } from "./api-key-types";
12
-
13
11
  /** Operations that map to HTTP methods. */
14
12
  export type ApiKeyOperation = "read" | "write" | "delete";
15
-
16
13
  /**
17
14
  * Map an HTTP method string to an `ApiKeyOperation`.
18
15
  *
@@ -20,24 +17,7 @@ export type ApiKeyOperation = "read" | "write" | "delete";
20
17
  * - `POST`, `PUT`, `PATCH` → `"write"`
21
18
  * - `DELETE` → `"delete"`
22
19
  */
23
- export function httpMethodToOperation(method: string): ApiKeyOperation {
24
- const upper = method.toUpperCase();
25
- switch (upper) {
26
- case "GET":
27
- case "HEAD":
28
- case "OPTIONS":
29
- return "read";
30
- case "POST":
31
- case "PUT":
32
- case "PATCH":
33
- return "write";
34
- case "DELETE":
35
- return "delete";
36
- default:
37
- return "read";
38
- }
39
- }
40
-
20
+ export declare function httpMethodToOperation(method: string): ApiKeyOperation;
41
21
  /**
42
22
  * Check whether the given permissions array allows `operation` on `collection`.
43
23
  *
@@ -49,16 +29,4 @@ export function httpMethodToOperation(method: string): ApiKeyOperation {
49
29
  * @param operation - The requested operation.
50
30
  * @returns `true` if the operation is permitted.
51
31
  */
52
- export function isOperationAllowed(
53
- permissions: ApiKeyPermission[],
54
- collection: string,
55
- operation: ApiKeyOperation
56
- ): boolean {
57
- for (const perm of permissions) {
58
- const collectionMatch = perm.collection === "*" || perm.collection === collection;
59
- if (collectionMatch && perm.operations.includes(operation)) {
60
- return true;
61
- }
62
- }
63
- return false;
64
- }
32
+ export declare function isOperationAllowed(permissions: ApiKeyPermission[], collection: string, operation: ApiKeyOperation): boolean;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Admin routes for managing Service API Keys.
3
+ *
4
+ * Mounted under `/api/admin/api-keys` with `requireAuth` + `requireAdmin`.
5
+ * All routes return masked keys (never the hash). The full plaintext key
6
+ * is returned exactly once in the POST response.
7
+ *
8
+ * @module
9
+ */
10
+ import { Hono } from "hono";
11
+ import type { HonoEnv } from "../../api/types";
12
+ import type { ApiKeyStore } from "./api-key-store";
13
+ export interface ApiKeyRouteOptions {
14
+ store: ApiKeyStore;
15
+ serviceKey?: string;
16
+ }
17
+ /**
18
+ * Create admin routes for API key management.
19
+ */
20
+ export declare function createApiKeyRoutes(options: ApiKeyRouteOptions): Hono<HonoEnv>;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Database operations for Service API Keys.
3
+ *
4
+ * Uses the DataDriver's `admin.executeSql` capability (same pattern as
5
+ * the cron-store and ensure-tables modules). All data lives in the
6
+ * `rebase.api_keys` table.
7
+ *
8
+ * @module
9
+ */
10
+ import type { DataDriver } from "@rebasepro/types";
11
+ import type { ApiKey, ApiKeyMasked, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest } from "./api-key-types";
12
+ export interface ApiKeyStore {
13
+ /** Ensure the `rebase.api_keys` table exists. Called once on startup. */
14
+ ensureTable(): Promise<void>;
15
+ /** Create a new API key. Returns the full plaintext key exactly once. */
16
+ createApiKey(request: CreateApiKeyRequest, createdBy: string): Promise<ApiKeyWithSecret>;
17
+ /** Look up an API key by its SHA-256 hash. Returns `null` if not found. */
18
+ findByKeyHash(hash: string): Promise<ApiKey | null>;
19
+ /** List all API keys (masked, never includes hash). */
20
+ listApiKeys(): Promise<ApiKeyMasked[]>;
21
+ /** Get a single API key by ID (masked). */
22
+ getApiKeyById(id: string): Promise<ApiKeyMasked | null>;
23
+ /** Update name, permissions, rate_limit, or expires_at. */
24
+ updateApiKey(id: string, updates: UpdateApiKeyRequest): Promise<ApiKeyMasked | null>;
25
+ /** Soft-delete: set `revoked_at` to now. */
26
+ revokeApiKey(id: string): Promise<boolean>;
27
+ /** Touch `last_used_at` to the current timestamp. */
28
+ updateLastUsed(id: string): Promise<void>;
29
+ }
30
+ /**
31
+ * Create an `ApiKeyStore` backed by the driver's SQL admin capability.
32
+ *
33
+ * Returns `undefined` if the driver does not support `executeSql`.
34
+ */
35
+ export declare function createApiKeyStore(driver: DataDriver): ApiKeyStore | undefined;