@rebasepro/server 0.16.0 → 0.16.1-canary.g701140a

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 (148) hide show
  1. package/dist/api/contract-routes.d.ts +1 -1
  2. package/dist/api/errors.d.ts +1 -1
  3. package/dist/api/index.d.ts +3 -3
  4. package/dist/api/logs-routes.d.ts +1 -1
  5. package/dist/api/rest/api-generator.d.ts +2 -2
  6. package/dist/api/rest/index.d.ts +1 -1
  7. package/dist/api/rest/query-parser.d.ts +1 -1
  8. package/dist/api/schema-editor-routes.d.ts +1 -1
  9. package/dist/api/types.d.ts +3 -4
  10. package/dist/auth/adapter-middleware.d.ts +2 -2
  11. package/dist/auth/admin-roles-route.d.ts +2 -2
  12. package/dist/auth/admin-user-ops.d.ts +3 -3
  13. package/dist/auth/admin-users-route.d.ts +4 -4
  14. package/dist/auth/api-keys/api-key-middleware.d.ts +2 -2
  15. package/dist/auth/api-keys/api-key-permission-guard.d.ts +1 -1
  16. package/dist/auth/api-keys/api-key-routes.d.ts +2 -2
  17. package/dist/auth/api-keys/api-key-store.d.ts +1 -1
  18. package/dist/auth/api-keys/index.d.ts +9 -9
  19. package/dist/auth/apple-oauth.d.ts +2 -2
  20. package/dist/auth/auth-hooks.d.ts +3 -3
  21. package/dist/auth/bitbucket-oauth.d.ts +2 -2
  22. package/dist/auth/builtin-auth-adapter.d.ts +7 -4
  23. package/dist/auth/captcha.d.ts +86 -0
  24. package/dist/auth/cookie-utils.d.ts +2 -2
  25. package/dist/auth/discord-oauth.d.ts +2 -2
  26. package/dist/auth/facebook-oauth.d.ts +2 -2
  27. package/dist/auth/github-oauth.d.ts +2 -2
  28. package/dist/auth/gitlab-oauth.d.ts +2 -2
  29. package/dist/auth/google-oauth.d.ts +1 -1
  30. package/dist/auth/index.d.ts +56 -54
  31. package/dist/auth/jwks-routes.d.ts +1 -1
  32. package/dist/auth/jwt.d.ts +1 -1
  33. package/dist/auth/linkedin-oauth.d.ts +2 -2
  34. package/dist/auth/magic-link-routes.d.ts +10 -3
  35. package/dist/auth/mfa-gate.d.ts +1 -1
  36. package/dist/auth/mfa-routes.d.ts +3 -3
  37. package/dist/auth/microsoft-oauth.d.ts +2 -2
  38. package/dist/auth/middleware.d.ts +5 -5
  39. package/dist/auth/rate-limiter.d.ts +2 -2
  40. package/dist/auth/require-auth.d.ts +1 -1
  41. package/dist/auth/reset-password-admin.d.ts +4 -4
  42. package/dist/auth/routes.d.ts +13 -4
  43. package/dist/auth/session-routes.d.ts +3 -3
  44. package/dist/auth/slack-oauth.d.ts +2 -2
  45. package/dist/auth/spotify-oauth.d.ts +2 -2
  46. package/dist/auth/token-revocation.d.ts +2 -2
  47. package/dist/auth/twitter-oauth.d.ts +2 -2
  48. package/dist/{auth-5Et5mnUA.js → auth-B0IV-irB.js} +250 -15
  49. package/dist/auth-B0IV-irB.js.map +1 -0
  50. package/dist/backup/backup-common.d.ts +1 -1
  51. package/dist/backup/backup-routes.d.ts +3 -3
  52. package/dist/backup/index.d.ts +3 -3
  53. package/dist/{backup-C6ljYVTp.js → backup-BJ86ah4T.js} +2 -2
  54. package/dist/{backup-C6ljYVTp.js.map → backup-BJ86ah4T.js.map} +1 -1
  55. package/dist/boot/boot.d.ts +5 -5
  56. package/dist/boot/bundle.d.ts +1 -1
  57. package/dist/boot/driver.d.ts +1 -1
  58. package/dist/boot/env.d.ts +13 -1
  59. package/dist/boot/options.d.ts +30 -6
  60. package/dist/boot/role.d.ts +3 -2
  61. package/dist/boot/sources.d.ts +1 -1
  62. package/dist/collections/BackendCollectionRegistry.d.ts +1 -1
  63. package/dist/collections/loader.d.ts +1 -1
  64. package/dist/{contract-routes-DZ-LBpSL.js → contract-routes-BEq7euZg.js} +2 -2
  65. package/dist/contract-routes-BEq7euZg.js.map +1 -0
  66. package/dist/cron/cron-routes.d.ts +2 -2
  67. package/dist/cron/cron-scheduler.d.ts +2 -2
  68. package/dist/cron/index.d.ts +8 -8
  69. package/dist/{cron-loader-YhhQeVBM.js → cron-loader-BMvtW6-J.js} +2 -2
  70. package/dist/{cron-loader-YhhQeVBM.js.map → cron-loader-BMvtW6-J.js.map} +1 -1
  71. package/dist/{cron-routes-maM_RlUu.js → cron-routes-BvYk-Kmi.js} +2 -2
  72. package/dist/{cron-routes-maM_RlUu.js.map → cron-routes-BvYk-Kmi.js.map} +1 -1
  73. package/dist/{cron-scheduler-DIpYBmZP.js → cron-scheduler-Buf-uVam.js} +2 -2
  74. package/dist/{cron-scheduler-DIpYBmZP.js.map → cron-scheduler-Buf-uVam.js.map} +1 -1
  75. package/dist/{cron-store-DfH_4Cd9.js → cron-store-CpfttP4f.js} +3 -3
  76. package/dist/{cron-store-DfH_4Cd9.js.map → cron-store-CpfttP4f.js.map} +1 -1
  77. package/dist/{ddl-bootstrap-Cywoj8Ta.js → ddl-bootstrap-CFLhcvfQ.js} +2 -2
  78. package/dist/{ddl-bootstrap-Cywoj8Ta.js.map → ddl-bootstrap-CFLhcvfQ.js.map} +1 -1
  79. package/dist/dev-secrets.d.ts +52 -0
  80. package/dist/email/dev-sink.d.ts +67 -0
  81. package/dist/email/index.d.ts +9 -7
  82. package/dist/email/link-base.d.ts +1 -1
  83. package/dist/email/smtp-email-service.d.ts +1 -1
  84. package/dist/env.d.ts +1 -1
  85. package/dist/{errors-EBYiaJ2E.js → errors-D_LwNKRM.js} +5 -5
  86. package/dist/errors-D_LwNKRM.js.map +1 -0
  87. package/dist/{function-loader-DDS1v7YX.js → function-loader-BrLmC_-y.js} +3 -3
  88. package/dist/{function-loader-DDS1v7YX.js.map → function-loader-BrLmC_-y.js.map} +1 -1
  89. package/dist/functions/context.d.ts +141 -0
  90. package/dist/functions/define-function.d.ts +1 -1
  91. package/dist/functions/function-routes.d.ts +2 -2
  92. package/dist/functions/guards.d.ts +76 -0
  93. package/dist/functions/index.d.ts +96 -5
  94. package/dist/functions/index.js +919 -0
  95. package/dist/functions/index.js.map +1 -0
  96. package/dist/functions/internal.d.ts +26 -0
  97. package/dist/functions/proxy.d.ts +1 -1
  98. package/dist/functions/request-timeout.d.ts +9 -1
  99. package/dist/functions/runtime-env.d.ts +92 -0
  100. package/dist/functions/wait-until.d.ts +74 -0
  101. package/dist/history/history-routes.d.ts +2 -2
  102. package/dist/history/index.d.ts +1 -1
  103. package/dist/index.d.ts +63 -54
  104. package/dist/index.es.js +1126 -53
  105. package/dist/index.es.js.map +1 -1
  106. package/dist/init/docs.d.ts +1 -1
  107. package/dist/init/middlewares.d.ts +1 -1
  108. package/dist/init/shutdown.d.ts +4 -0
  109. package/dist/init/storage.d.ts +1 -1
  110. package/dist/init/surfaces.d.ts +10 -0
  111. package/dist/init.d.ts +72 -18
  112. package/dist/jobs/index.d.ts +5 -5
  113. package/dist/{jobs-CyOKXXlu.js → jobs-CSlBZ8dn.js} +3 -3
  114. package/dist/{jobs-CyOKXXlu.js.map → jobs-CSlBZ8dn.js.map} +1 -1
  115. package/dist/{jwt-DxH9fLPt.js → jwt-BbJi0TR0.js} +2 -2
  116. package/dist/{jwt-DxH9fLPt.js.map → jwt-BbJi0TR0.js.map} +1 -1
  117. package/dist/{logger-DfvF_8r-.js → logger-TdvXIGqR.js} +101 -8
  118. package/dist/logger-TdvXIGqR.js.map +1 -0
  119. package/dist/metrics/index.d.ts +1 -1
  120. package/dist/{proxy-Bj5DVllb.js → proxy-QJKSS-CV.js} +5 -3
  121. package/dist/{proxy-Bj5DVllb.js.map → proxy-QJKSS-CV.js.map} +1 -1
  122. package/dist/{request-timeout-BuFoEKwT.js → request-timeout-OofPCHQT.js} +17 -3
  123. package/dist/request-timeout-OofPCHQT.js.map +1 -0
  124. package/dist/rls-audit/index.d.ts +111 -0
  125. package/dist/{schema-editor-routes-CV9k0w3G.js → schema-editor-routes-Cax2XTRj.js} +2 -2
  126. package/dist/{schema-editor-routes-CV9k0w3G.js.map → schema-editor-routes-Cax2XTRj.js.map} +1 -1
  127. package/dist/services/webhook-service.d.ts +1 -1
  128. package/dist/singleton.d.ts +7 -0
  129. package/dist/storage/GCSStorageController.d.ts +1 -1
  130. package/dist/storage/LocalStorageController.d.ts +1 -1
  131. package/dist/storage/S3StorageController.d.ts +1 -1
  132. package/dist/storage/cache-headers.d.ts +87 -0
  133. package/dist/storage/index.d.ts +11 -11
  134. package/dist/storage/policies.d.ts +88 -0
  135. package/dist/storage/range.d.ts +63 -0
  136. package/dist/storage/routes.d.ts +3 -3
  137. package/dist/storage/storage-registry.d.ts +1 -1
  138. package/dist/storage/tus-handler.d.ts +2 -2
  139. package/dist/utils/host.d.ts +58 -0
  140. package/dist/utils/logger.d.ts +0 -15
  141. package/dist/utils/request-id.d.ts +1 -1
  142. package/functions/package.json +24 -0
  143. package/package.json +13 -7
  144. package/dist/auth-5Et5mnUA.js.map +0 -1
  145. package/dist/contract-routes-DZ-LBpSL.js.map +0 -1
  146. package/dist/errors-EBYiaJ2E.js.map +0 -1
  147. package/dist/logger-DfvF_8r-.js.map +0 -1
  148. package/dist/request-timeout-BuFoEKwT.js.map +0 -1
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Reading the request context from inside a custom function.
3
+ *
4
+ * The functions router resolves the caller's identity before any handler runs
5
+ * and leaves the result on the Hono context. Getting it back out used to be the
6
+ * user's problem, and the shape made that worse than it sounds: `HonoEnv`
7
+ * types `user` as `AuthResult`, a union that includes `boolean`, `null` and an
8
+ * index signature, because the same slot is filled by four different middlewares
9
+ * — JWT, service key, API key, and a user-supplied validator that may return
10
+ * `true`. Every example in the documentation therefore opened with
11
+ *
12
+ * const user = c.get("user") as { uid: string; roles?: string[] } | undefined;
13
+ *
14
+ * and an assertion in a security-relevant position is exactly the kind of line
15
+ * that gets copied once and then never re-examined. It is also wrong in one
16
+ * case that occurs in practice: a custom validator returning `true` stores
17
+ * `{ uid: "default", roles: [] }`, which the assertion above types as having a
18
+ * `uid` — true here, but nothing checks it.
19
+ *
20
+ * These accessors do the narrowing once, in the framework, where it can be
21
+ * tested. They are also **runtime-neutral by construction** — no crypto, no
22
+ * token parsing, no I/O, nothing but property reads on an object another
23
+ * middleware already populated. That is what lets them live in
24
+ * `@rebasepro/server/functions` and run unchanged on a host that has no Node
25
+ * built-ins.
26
+ *
27
+ * @module
28
+ */
29
+ import type { Context } from "hono";
30
+ import type { DataDriver } from "@rebasepro/types";
31
+ import type { HonoEnv } from "../api/types.js";
32
+ import type { ApiKeyMasked } from "../auth/api-keys/api-key-types.js";
33
+ /**
34
+ * The caller, as a custom function sees them.
35
+ *
36
+ * A narrowed view of whatever the auth middleware resolved: `uid` and `roles`
37
+ * are guaranteed, and the index signature keeps any extra claims the token or
38
+ * the adapter carried (`email`, `org_id`, anything a custom validator added)
39
+ * reachable without a cast.
40
+ */
41
+ export interface FunctionUser {
42
+ /** Stable id of the caller. `"service"` for service-key and API-key callers. */
43
+ uid: string;
44
+ /** Roles as resolved for this request. Never `undefined` — an empty array instead. */
45
+ roles: string[];
46
+ /** Present when the identity carried one. Not every auth method does. */
47
+ email?: string;
48
+ /** Any further claim the token, adapter or validator supplied. */
49
+ [claim: string]: unknown;
50
+ }
51
+ /** Anything with a Hono-style `.get`, so these work on any `Context` shape. */
52
+ type CtxLike = Context<HonoEnv> | Context;
53
+ /**
54
+ * The authenticated caller, or `undefined` for an anonymous request.
55
+ *
56
+ * **`undefined` is not a permission decision.** The functions router mounts its
57
+ * auth middleware with `requireAuth: false` on purpose — a webhook receiver has
58
+ * no token to send — so an anonymous caller reaches the handler and reads
59
+ * `undefined` here while the handler runs on regardless. Use {@link requireAuth}
60
+ * (or a `!user` branch that returns 401) to make it a decision.
61
+ *
62
+ * A caller who presented a *bad* token never gets this far: both auth
63
+ * middlewares reject an unverifiable token with 401 before the router is
64
+ * reached, precisely so an expired session cannot be silently downgraded to an
65
+ * anonymous one.
66
+ */
67
+ export declare function getUser(c: CtxLike): FunctionUser | undefined;
68
+ /** The caller's id, or `undefined` when nobody is signed in. */
69
+ export declare function getUserId(c: CtxLike): string | undefined;
70
+ /** The caller's roles. Empty for an anonymous request — never `undefined`. */
71
+ export declare function getRoles(c: CtxLike): string[];
72
+ /**
73
+ * Whether the caller holds **any** of the named roles.
74
+ *
75
+ * Any rather than all, because that is what a route guard means by a list of
76
+ * roles; require several by calling this more than once.
77
+ */
78
+ export declare function hasRole(c: CtxLike, ...roles: string[]): boolean;
79
+ /**
80
+ * Whether the caller holds an administrative role.
81
+ *
82
+ * Delegates to the single definition in `auth/admin-roles.ts` — which is
83
+ * `admin` **or** `schema-admin` — rather than comparing against `"admin"`.
84
+ * Those two lists disagreed once, and the gap made every public registrant an
85
+ * administrator; see that file.
86
+ */
87
+ export declare function isAdmin(c: CtxLike): boolean;
88
+ /** Whether the request carries an identity at all. */
89
+ export declare function isAuthenticated(c: CtxLike): boolean;
90
+ /**
91
+ * The request-scoped data driver: reads and writes run as **the caller**, with
92
+ * your row-level security policies evaluated against their identity.
93
+ *
94
+ * This is the accessor to reach for when a function serves user-facing data.
95
+ * `rebase.dataAsAdmin` is the other one, and it is not the same thing — it runs
96
+ * as `{ uid: "service", roles: ["admin"] }` for every caller alike, which is
97
+ * correct for trusted background work and wrong for a request.
98
+ *
99
+ * `undefined` only when no Rebase auth middleware ran (see
100
+ * {@link identityResolved}); inside a function mounted by the framework it is
101
+ * always present, anonymous requests included — they get an anon-scoped driver
102
+ * so policies still have an identity to evaluate.
103
+ */
104
+ export declare function getDriver(c: CtxLike): DataDriver | undefined;
105
+ /**
106
+ * {@link getDriver}, but throws instead of handing back `undefined`.
107
+ *
108
+ * For the common case where a handler cannot proceed without it and would
109
+ * otherwise write `c.get("driver")!` — an assertion that turns a wiring problem
110
+ * into `Cannot read properties of undefined (reading 'fetchCollection')` twenty
111
+ * lines away from the cause.
112
+ */
113
+ export declare function requireDriver(c: CtxLike): DataDriver;
114
+ /**
115
+ * The API key this request authenticated with, masked, or `undefined` when it
116
+ * did not use one.
117
+ *
118
+ * Useful for attribution and for per-key behaviour. The permission check itself
119
+ * has already happened — reaching a handler means the key was allowed to.
120
+ */
121
+ export declare function getApiKey(c: CtxLike): ApiKeyMasked | undefined;
122
+ /**
123
+ * The correlation id for this request — generated, or taken from an inbound
124
+ * `X-Request-ID`.
125
+ *
126
+ * Log it. It is the only thing that ties a line written inside a function to
127
+ * the framework's own lines for the same request.
128
+ */
129
+ export declare function getRequestId(c: CtxLike): string | undefined;
130
+ /**
131
+ * Whether a Rebase auth middleware has run on this request.
132
+ *
133
+ * Both middlewares populate `driver` for *every* outcome, anonymous included,
134
+ * and populate `user` whenever there is one. So "neither is set" does not mean
135
+ * "anonymous" — it means nothing resolved the identity, and treating that as
136
+ * anonymous is the dangerous reading. The guards use this to tell a genuinely
137
+ * anonymous caller (401) from a misconfigured mount (500), because answering
138
+ * 401 to the second sends whoever is debugging it to look at the token.
139
+ */
140
+ export declare function identityResolved(c: CtxLike): boolean;
141
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import type { RebaseServerClient } from "@rebasepro/types";
3
- import type { HonoEnv } from "../api/types";
3
+ import type { HonoEnv } from "../api/types.js";
4
4
  /**
5
5
  * Typed context injected into a function authored with {@link defineFunction}.
6
6
  *
@@ -1,6 +1,6 @@
1
1
  import { Hono } from "hono";
2
- import { HonoEnv } from "../api/types";
3
- import { LoadedFunction } from "./function-loader";
2
+ import { HonoEnv } from "../api/types.js";
3
+ import { LoadedFunction } from "./function-loader.js";
4
4
  /**
5
5
  * Mount all loaded function routes under a single Hono router.
6
6
  *
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Route guards for custom functions.
3
+ *
4
+ * These decide access from the identity the platform already resolved. They do
5
+ * **not** verify tokens, and that division is the point rather than a
6
+ * limitation:
7
+ *
8
+ * - Verifying a token needs a signing key, constant-time comparison and a
9
+ * revocation lookup. That is host work, it belongs to the process that holds
10
+ * the secret, and it is the part of the stack that cannot be made
11
+ * runtime-neutral without rewriting it against WebCrypto.
12
+ * - Deciding whether *this* caller may call *this* route is application work.
13
+ * It needs nothing but the resolved identity, so it costs nothing to make it
14
+ * portable — and it is the half that lives in user code.
15
+ *
16
+ * Splitting there is what lets a function file compile and run unchanged on a
17
+ * host with no Node built-ins, and it is why these live in
18
+ * `@rebasepro/server/functions` while `verifyAccessToken` does not.
19
+ *
20
+ * **Inside the functions router these are equivalent to the guards exported
21
+ * from the package root.** Both auth middlewares resolve the identity before
22
+ * any handler runs: a valid credential populates `user`, an invalid one is
23
+ * rejected with 401 by the middleware itself, and a missing one leaves `user`
24
+ * unset. So the root `requireAuth`'s token-parsing branch is unreachable from a
25
+ * function, and removing it changes no outcome. The one difference is a handler
26
+ * mounted **outside** the framework's router, where no middleware ran: the root
27
+ * guard would parse the `Authorization` header itself, and these refuse the
28
+ * request with a 500 that names the wiring problem. Fail-closed, and legible.
29
+ *
30
+ * @module
31
+ */
32
+ import type { MiddlewareHandler } from "hono";
33
+ import type { HonoEnv } from "../api/types.js";
34
+ /**
35
+ * Reject anonymous callers with 401.
36
+ *
37
+ * Put it in the route's own middleware slot rather than `app.use("/*", …)`:
38
+ * `use()` covers only the routes declared *below* it, so a route appended later
39
+ * — by you, months from now, at the bottom of the file — is silently
40
+ * unprotected. The per-route form cannot drift that way.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * app.post("/", requireAuth, async (c) => {
45
+ * const user = getUser(c)!; // guaranteed by the guard
46
+ * return c.json({ uid: user.uid });
47
+ * });
48
+ * ```
49
+ */
50
+ export declare const requireAuth: MiddlewareHandler<HonoEnv>;
51
+ /**
52
+ * Reject callers without an administrative role with 403.
53
+ *
54
+ * Must come **after** {@link requireAuth}: on its own it answers 401 for an
55
+ * anonymous caller, which is right, but pairing them keeps the two failures
56
+ * distinguishable — 401 "who are you", 403 "not you".
57
+ *
58
+ * Administrative means `admin` or `schema-admin`, from the single list in
59
+ * `auth/admin-roles.ts`. Do not compare against `"admin"` by hand; that is the
60
+ * divergence that list exists to prevent.
61
+ */
62
+ export declare const requireAdmin: MiddlewareHandler<HonoEnv>;
63
+ /**
64
+ * Reject callers holding none of the named roles with 403.
65
+ *
66
+ * Any of them, not all — require several by chaining the guard twice. Naming no
67
+ * role at all is a programming error and throws at module load rather than at
68
+ * request time, because `requireRole()` with an empty list would otherwise read
69
+ * as a guard while admitting everyone.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * app.post("/publish", requireAuth, requireRole("editor", "admin"), handler);
74
+ * ```
75
+ */
76
+ export declare function requireRole(...roles: string[]): MiddlewareHandler<HonoEnv>;
@@ -1,5 +1,96 @@
1
- export { loadFunctionsFromDirectory } from "./function-loader";
2
- export type { LoadedFunction } from "./function-loader";
3
- export { createFunctionRoutes } from "./function-routes";
4
- export { defineFunction } from "./define-function";
5
- export type { RebaseFunctionContext } from "./define-function";
1
+ /**
2
+ * `@rebasepro/server/functions` — the portable authoring surface.
3
+ *
4
+ * Everything a custom function needs, and nothing that ties it to one runtime.
5
+ * Import from here rather than from `@rebasepro/server`:
6
+ *
7
+ * ```ts
8
+ * import { defineFunction, requireAuth, getUser, rebase } from "@rebasepro/server/functions";
9
+ * ```
10
+ *
11
+ * ## Why this entry point exists
12
+ *
13
+ * `@rebasepro/server` is a single barrel over the whole framework: the boot
14
+ * sequence, the collection loader, the backup routes, the SPA server, the
15
+ * WebSocket layer. Importing one name from it pulls `@hono/node-server`, `ws`,
16
+ * `jsonwebtoken`, Drizzle and a dozen modules that open files. On Node that
17
+ * costs a little start-up time and nothing else, which is why it stood for as
18
+ * long as it did. On a host without Node built-ins it does not resolve at all —
19
+ * so with only that entry point, *no* custom function could ever run anywhere
20
+ * but Node, no matter how portable the function's own code was.
21
+ *
22
+ * That is not a limitation you can lift later. `import { defineFunction } from
23
+ * "@rebasepro/server"` is the line in every function file, every template and
24
+ * every documentation page; changing it afterwards is a breaking change for
25
+ * everyone who has written one. The entry point has to exist before the code
26
+ * that would depend on it does.
27
+ *
28
+ * ## What "portable" means here, precisely
29
+ *
30
+ * Every module reachable from this file:
31
+ *
32
+ * - imports no Node built-in, directly or transitively;
33
+ * - imports no package that needs one (`@hono/node-server`, `ws`,
34
+ * `jsonwebtoken`, `drizzle-orm`, `pg`, …);
35
+ * - touches no host global — `process`, `Buffer`, `__dirname` — at module
36
+ * scope, so the module *evaluates* on a runtime that has none.
37
+ *
38
+ * `portability.test.ts` walks this graph on every run and fails naming the
39
+ * import chain that broke it. The rule is not a convention; it is a test.
40
+ *
41
+ * ## What is deliberately not here
42
+ *
43
+ * - **`rebase.sql()`** — reachable through `rebase`, and Node-only in practice:
44
+ * it runs on the database owner connection over a TCP socket. It is left on
45
+ * the object rather than hidden because there is nothing wrong with using it
46
+ * on a Node deployment; see its docblock, and `runtimeKey()` if a function
47
+ * needs to degrade rather than fail.
48
+ * - **Token verification.** Deciding whether a caller is who they say needs the
49
+ * signing key and belongs to the host; deciding whether *this* caller may
50
+ * call *this* route needs only the resolved identity and belongs here. That
51
+ * is why `requireAuth` below carries no crypto — see `./guards.ts`.
52
+ * - **The loader, the router, the proxy, the timeout middleware.** Host
53
+ * machinery. It lives in `./internal.ts`.
54
+ *
55
+ * @module
56
+ */
57
+ export { defineFunction } from "./define-function.js";
58
+ export type { RebaseFunctionContext } from "./define-function.js";
59
+ /**
60
+ * The app-scoped Rebase client: `dataAsAdmin`, `auth`, `storage`, `email`,
61
+ * `sql`.
62
+ *
63
+ * Re-exported here — the same object the package root exports, not a copy —
64
+ * because it is the one piece of the framework a function reaches for at
65
+ * runtime, and requiring a second import from the Node-only barrel to get it
66
+ * would defeat the entry point.
67
+ *
68
+ * It is safe to hold at module scope, unlike a configuration value, because it
69
+ * is a lazy Proxy: nothing is resolved until a property is read, which happens
70
+ * inside a request. That indirection is also the whole of what a future
71
+ * isolate-based host has to hook — see `_setRebaseResolver` in
72
+ * `../singleton.ts`.
73
+ */
74
+ export { rebase } from "../singleton.js";
75
+ export { getUser, getUserId, getRoles, hasRole, isAdmin, isAuthenticated, getDriver, requireDriver, getApiKey, getRequestId, identityResolved } from "./context.js";
76
+ export type { FunctionUser } from "./context.js";
77
+ export { requireAuth, requireAdmin, requireRole } from "./guards.js";
78
+ export { getEnv, env, requireEnv, runtimeKey, isNodeRuntime, lazyResource } from "./runtime-env.js";
79
+ export { waitUntil } from "./wait-until.js";
80
+ /**
81
+ * The Hono environment a Rebase function runs in: `c.get("user")`,
82
+ * `c.get("driver")`, `c.get("apiKey")` and `c.get("requestId")` are typed
83
+ * through it.
84
+ *
85
+ * `defineFunction` applies it for you. Declare it explicitly only when building
86
+ * the Hono app by hand: `new Hono<HonoEnv>()`.
87
+ */
88
+ export type { HonoEnv, ApiResponse } from "../api/types.js";
89
+ /**
90
+ * Throw this to answer with a specific status.
91
+ *
92
+ * The functions router installs the framework's error handler, so an `ApiError`
93
+ * thrown anywhere inside a handler becomes the status and body it names,
94
+ * whereas any other throw becomes a 500 with its detail withheld.
95
+ */
96
+ export { ApiError } from "../api/errors.js";