bunderstack 0.23.4 → 0.24.1

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 (159) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +7 -4
  3. package/dist/api/builder.d.ts +13 -11
  4. package/dist/api/builder.d.ts.map +1 -1
  5. package/dist/api/builder.js.map +1 -1
  6. package/dist/api/context.d.ts +6 -6
  7. package/dist/api/context.d.ts.map +1 -1
  8. package/dist/api/context.js +1 -1
  9. package/dist/api/context.js.map +1 -1
  10. package/dist/api/crud-router.d.ts +6 -6
  11. package/dist/api/realtime-router.d.ts +1 -1
  12. package/dist/api/storage-router.d.ts +5 -5
  13. package/dist/auth.d.ts +20 -9
  14. package/dist/auth.d.ts.map +1 -1
  15. package/dist/auth.js +3 -8
  16. package/dist/auth.js.map +1 -1
  17. package/dist/backend-internals.d.ts +5 -13
  18. package/dist/backend-internals.d.ts.map +1 -1
  19. package/dist/backend-internals.js.map +1 -1
  20. package/dist/backend.d.ts +39 -5
  21. package/dist/backend.d.ts.map +1 -1
  22. package/dist/backend.js +37 -46
  23. package/dist/backend.js.map +1 -1
  24. package/dist/blueprint-generator.d.ts +1 -0
  25. package/dist/blueprint-generator.d.ts.map +1 -1
  26. package/dist/blueprint-generator.js +29 -1
  27. package/dist/blueprint-generator.js.map +1 -1
  28. package/dist/blueprint.d.ts +2 -1
  29. package/dist/blueprint.d.ts.map +1 -1
  30. package/dist/blueprint.js +9 -2
  31. package/dist/blueprint.js.map +1 -1
  32. package/dist/cli.d.ts.map +1 -1
  33. package/dist/cli.js +14 -2
  34. package/dist/cli.js.map +1 -1
  35. package/dist/config.d.ts +23 -25
  36. package/dist/config.d.ts.map +1 -1
  37. package/dist/config.js +1 -1
  38. package/dist/config.js.map +1 -1
  39. package/dist/email/smtp.d.ts +7 -1
  40. package/dist/email/smtp.d.ts.map +1 -1
  41. package/dist/email/smtp.js +5 -1
  42. package/dist/email/smtp.js.map +1 -1
  43. package/dist/email.d.ts +3 -29
  44. package/dist/email.d.ts.map +1 -1
  45. package/dist/email.js +1 -194
  46. package/dist/email.js.map +1 -1
  47. package/dist/env-probe.d.ts +9 -0
  48. package/dist/env-probe.d.ts.map +1 -0
  49. package/dist/env-probe.js +73 -0
  50. package/dist/env-probe.js.map +1 -0
  51. package/dist/env.d.ts +2 -5
  52. package/dist/env.d.ts.map +1 -1
  53. package/dist/env.js +2 -9
  54. package/dist/env.js.map +1 -1
  55. package/dist/hosted-contract.d.ts +11 -0
  56. package/dist/hosted-contract.d.ts.map +1 -0
  57. package/dist/hosted-contract.js +46 -0
  58. package/dist/hosted-contract.js.map +1 -0
  59. package/dist/index.d.ts +3 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1 -1
  62. package/dist/index.js.map +1 -1
  63. package/dist/inspect.d.ts +15 -0
  64. package/dist/inspect.d.ts.map +1 -0
  65. package/dist/inspect.js +43 -0
  66. package/dist/inspect.js.map +1 -0
  67. package/dist/internal-tables-pg.d.ts +43 -94
  68. package/dist/internal-tables-pg.d.ts.map +1 -1
  69. package/dist/internal-tables-pg.js +14 -17
  70. package/dist/internal-tables-pg.js.map +1 -1
  71. package/dist/internal-tables.d.ts +213 -488
  72. package/dist/internal-tables.d.ts.map +1 -1
  73. package/dist/internal-tables.js +33 -33
  74. package/dist/internal-tables.js.map +1 -1
  75. package/dist/jobs/define.d.ts +20 -20
  76. package/dist/jobs/define.d.ts.map +1 -1
  77. package/dist/jobs/define.js.map +1 -1
  78. package/dist/manifest-diff.d.ts +6 -0
  79. package/dist/manifest-diff.d.ts.map +1 -0
  80. package/dist/manifest-diff.js +42 -0
  81. package/dist/manifest-diff.js.map +1 -0
  82. package/dist/manifest.d.ts +10 -2
  83. package/dist/manifest.d.ts.map +1 -1
  84. package/dist/manifest.js +27 -29
  85. package/dist/manifest.js.map +1 -1
  86. package/dist/messaging/email.d.ts +16 -0
  87. package/dist/messaging/email.d.ts.map +1 -0
  88. package/dist/messaging/email.js +8 -0
  89. package/dist/messaging/email.js.map +1 -0
  90. package/dist/messaging/index.d.ts +8 -0
  91. package/dist/messaging/index.d.ts.map +1 -0
  92. package/dist/messaging/index.js +4 -0
  93. package/dist/messaging/index.js.map +1 -0
  94. package/dist/messaging/journal.d.ts +4 -0
  95. package/dist/messaging/journal.d.ts.map +1 -0
  96. package/dist/messaging/journal.js +19 -0
  97. package/dist/messaging/journal.js.map +1 -0
  98. package/dist/messaging/runtime.d.ts +16 -0
  99. package/dist/messaging/runtime.d.ts.map +1 -0
  100. package/dist/messaging/runtime.js +213 -0
  101. package/dist/messaging/runtime.js.map +1 -0
  102. package/dist/messaging/standalone.d.ts +27 -0
  103. package/dist/messaging/standalone.d.ts.map +1 -0
  104. package/dist/messaging/standalone.js +18 -0
  105. package/dist/messaging/standalone.js.map +1 -0
  106. package/dist/messaging/telegram.d.ts +16 -0
  107. package/dist/messaging/telegram.d.ts.map +1 -0
  108. package/dist/messaging/telegram.js +5 -0
  109. package/dist/messaging/telegram.js.map +1 -0
  110. package/dist/messaging/types.d.ts +22 -0
  111. package/dist/messaging/types.d.ts.map +1 -0
  112. package/dist/messaging/types.js +17 -0
  113. package/dist/messaging/types.js.map +1 -0
  114. package/dist/provision-internals.d.ts +1 -1
  115. package/dist/provision-internals.js +1 -1
  116. package/dist/provision-internals.js.map +1 -1
  117. package/dist/provision-runtime.d.ts +7 -0
  118. package/dist/provision-runtime.d.ts.map +1 -0
  119. package/dist/provision-runtime.js +50 -0
  120. package/dist/provision-runtime.js.map +1 -0
  121. package/dist/provision-schema.d.ts +16 -0
  122. package/dist/provision-schema.d.ts.map +1 -0
  123. package/dist/provision-schema.js +63 -0
  124. package/dist/provision-schema.js.map +1 -0
  125. package/dist/provision.d.ts +4 -21
  126. package/dist/provision.d.ts.map +1 -1
  127. package/dist/provision.js +10 -111
  128. package/dist/provision.js.map +1 -1
  129. package/dist/runtime.d.ts +17 -14
  130. package/dist/runtime.d.ts.map +1 -1
  131. package/dist/runtime.js +20 -33
  132. package/dist/runtime.js.map +1 -1
  133. package/dist/schema-export-pg.d.ts +1 -1
  134. package/dist/schema-export-pg.d.ts.map +1 -1
  135. package/dist/schema-export-pg.js +1 -1
  136. package/dist/schema-export-pg.js.map +1 -1
  137. package/dist/schema-export.d.ts +1 -1
  138. package/dist/schema-export.d.ts.map +1 -1
  139. package/dist/schema-export.js +1 -1
  140. package/dist/schema-export.js.map +1 -1
  141. package/dist/testing/fixture.d.ts +3 -3
  142. package/dist/testing/fixture.d.ts.map +1 -1
  143. package/dist/testing/fixture.js +12 -10
  144. package/dist/testing/fixture.js.map +1 -1
  145. package/dist/testing/messaging.d.ts +21 -0
  146. package/dist/testing/messaging.d.ts.map +1 -0
  147. package/dist/testing/messaging.js +34 -0
  148. package/dist/testing/messaging.js.map +1 -0
  149. package/dist/testing.d.ts +1 -0
  150. package/dist/testing.d.ts.map +1 -1
  151. package/dist/testing.js.map +1 -1
  152. package/llms-full.txt +416 -226
  153. package/llms.txt +4 -3
  154. package/package.json +10 -2
  155. package/skills/creating-bunderstack-apps/references/application-structure.md +16 -7
  156. package/skills/creating-bunderstack-apps/references/verification.md +7 -6
  157. package/skills/migrating-to-bunderstack/SKILL.md +75 -51
  158. package/skills/migrating-to-bunderstack/references/audit-checklist.md +2 -2
  159. package/skills/migrating-to-bunderstack/references/runtime-replacements.md +20 -15
package/CHANGELOG.md CHANGED
@@ -2,6 +2,73 @@
2
2
 
3
3
  All notable changes to `bunderstack` will be documented in this file.
4
4
 
5
+ ## [0.24.1] — 2026-09-14
6
+
7
+ ### Fixed
8
+
9
+ - Preserve the exact Better Auth configuration through `defineAuth()`,
10
+ `bunderstack()`, and `BunderstackApp`, so plugin APIs and session fields
11
+ remain available on `app.auth`.
12
+ - Keep `drizzle-kit` out of the production `bunderstack/provision` bundle.
13
+ Production provisioning now requires committed migrations; development
14
+ schema push lives in `bunderstack/provision-schema`.
15
+
16
+ ## [0.24.0] - 2026-09-05
17
+
18
+ ### Changed
19
+
20
+ - **Env-first declarations.** The declaration stays one object, and the slots
21
+ that hold credentials — `database`, `storage`, `messaging`, and `realtime` —
22
+ now also accept a function of the validated environment; `auth` has taken a
23
+ `{ db, env }` builder since 0.22. A slot function is resolved once per
24
+ `inspect()`, `start()`, and test fixture, and it supplies values, never
25
+ shapes.
26
+ - **`backend.manifest` becomes `backend.inspect({ env })`.** A manifest depends
27
+ on the environment, so it is a call. Inspection validates the environment,
28
+ resolves the declaration, and builds the manifest without opening a database,
29
+ a bucket, a provider connection, or a worker.
30
+ - **`email` becomes `messaging`.** Channels are named, each names one provider,
31
+ and each provider carries its own message type. `app.email.send()` becomes
32
+ `app.messaging.<channel>.send()`, `ctx.email` becomes `ctx.messaging`, and
33
+ `t.email.sent` becomes `t.messaging.<channel>.sent`. Providers are declared
34
+ with `resend()`, `smtp()`, `customEmail()`, and `telegram()`.
35
+ - **Capture replaces the console provider.** A channel whose required
36
+ configuration is absent or empty writes the message to the journal instead of
37
+ sending, and prints it locally. On a host the body stays out of the logs. A
38
+ wrong key and a rejected request still raise.
39
+ - **The message journal replaces the email log.** `_bunderstack_messages` and
40
+ `_bunderstack_message_events` replace `_bunderstack_emails` and
41
+ `_bunderstack_email_events`, and record the channel, provider, credential
42
+ source, status, recipients, content, and error. Applications with committed
43
+ migrations must run their `db:generate` command and apply the generated
44
+ migration after upgrading.
45
+ - Manifest version 4 adds `messaging.channels`; the blueprint gains
46
+ `resources.messaging`. Neither carries a key, a token, or a sender address.
47
+
48
+ ### Added
49
+
50
+ - **Managed messaging credentials.** `BUNDERSTACK_MESSAGING_CONFIG` supplies
51
+ provider-keyed defaults that every channel of that provider shares. A field
52
+ the channel declares itself wins field by field, and each journal row records
53
+ whether its credentials were `explicit`, `managed`, or `capture`.
54
+ - **Blueprint shape probes.** Blueprint generation resolves the declaration
55
+ against two accepted environments and rejects a declaration whose shape
56
+ depends on a value, naming the differing paths and never a value.
57
+ - **Hosted contract checking.** `bunderstack blueprint --hosted-check` compares
58
+ an inspected declaration with the committed blueprint. At runtime,
59
+ `BUNDERSTACK_BLUEPRINT_PATH` makes `start()` verify that contract before it
60
+ connects to anything.
61
+ - `defineApi({ schema, env, messaging })` types `context.messaging` exactly for
62
+ a router declared in its own module.
63
+ - `createMessaging(channels, { env, db })` builds the same channel facades
64
+ outside a started app, for a Better Auth builder or a script. It replaces
65
+ `createEmail`.
66
+
67
+ ### Removed
68
+
69
+ - The eager `backend.manifest` property, the `email` configuration key,
70
+ `app.email`, `ctx.email`, and `t.email`. See `docs/MIGRATION-0.24.md`.
71
+
5
72
  ## [0.23.4] - 2026-09-01
6
73
 
7
74
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # bunderstack
2
2
 
3
- The complete backend & full-stack framework for Bun: type-safe oRPC APIs, auth, storage, realtime, jobs, email, live views, and client bindings from one single file declaration.
3
+ The complete backend & full-stack framework for Bun: type-safe oRPC APIs, auth, storage, realtime, jobs, messaging, live views, and client bindings from one single file declaration.
4
4
 
5
5
  ```sh
6
6
  bun add bunderstack better-auth drizzle-orm valibot @libsql/client
@@ -14,7 +14,7 @@ import * as schema from './schema'
14
14
 
15
15
  export const backend = bunderstack({
16
16
  schema,
17
- database: { adapter: libsql(), url: 'file:./data.db' },
17
+ database: { adapter: libsql() },
18
18
  access: { posts: { crud: true } },
19
19
  realtime: true,
20
20
  api: {
@@ -42,7 +42,7 @@ await context.realtime.publish(schema.posts, 'update', post)
42
42
  ```
43
43
 
44
44
  Use the in-memory Publisher for one process or configure
45
- `realtime: { redis: process.env.REDIS_URL! }` for multi-process delivery and
45
+ `realtime: (env) => ({ redis: env.REDIS_URL })` for multi-process delivery and
46
46
  replay. Deployment metadata is generated with `bunx bunderstack blueprint`.
47
47
 
48
48
  ## Package Subpaths (0.21+)
@@ -51,6 +51,7 @@ replay. Deployment metadata is generated with `bunx bunderstack blueprint`.
51
51
  - `bunderstack/testing` — Isolated lexical fixtures and reusable test factories
52
52
  (`backend.test()` / `backend.test.configure()`)
53
53
  - `bunderstack/provision` — Explicit production schema provisioning
54
+ - `bunderstack/provision-schema` — Development-only schema push via Drizzle Kit
54
55
  - `bunderstack/client` — Framework-neutral RPC & LiveView client (`createClient`, `createLiveView`)
55
56
  - `bunderstack/client-rest` — Type-safe REST client
56
57
  - `bunderstack/client-react`, `bunderstack/client-solid`, `bunderstack/client-vue`, `bunderstack/client-svelte` — LiveView UI bindings
@@ -59,7 +60,8 @@ replay. Deployment metadata is generated with `bunx bunderstack blueprint`.
59
60
  - `bunderstack/start` & `bunderstack/start-auth` — TanStack Start full-stack integration
60
61
  - `bunderstack/libsql`, `bunderstack/postgres-js`, `bunderstack/bun-sql`, `bunderstack/bun-sqlite`, `bunderstack/pglite` — Database adapters
61
62
  - `bunderstack/storage/*` — Storage adapters (`s3`, `disk`)
62
- - `bunderstack/email-smtp` — SMTP email adapter
63
+ - `bunderstack/messaging` — Messaging channel descriptors (`resend`, `customEmail`, `telegram`)
64
+ - `bunderstack/email-smtp` — SMTP email channel
63
65
  - `bunderstack/jobs/*` — Job queue adapters (`memory`, `redis`)
64
66
 
65
67
  See the [workspace documentation](https://github.com/kirill-dev-pro/bunderstack#readme) for webhooks, clients,
@@ -69,6 +71,7 @@ storage, collections, lifecycle, and complete examples.
69
71
 
70
72
  Every change is listed with before/after code in the migration guides, which live in full at:
71
73
 
74
+ - [Migrating to 0.24](https://github.com/kirill-dev-pro/bunderstack/blob/main/docs/MIGRATION-0.24.md)
72
75
  - [Migrating to 0.22](https://github.com/kirill-dev-pro/bunderstack/blob/main/docs/MIGRATION-0.22.md)
73
76
  - [Migrating to 0.21](https://github.com/kirill-dev-pro/bunderstack/blob/main/docs/MIGRATION-0.21.md)
74
77
  - [Migrating to 0.17](https://github.com/kirill-dev-pro/bunderstack/blob/main/docs/MIGRATION-0.17.md)
@@ -1,10 +1,11 @@
1
1
  import { type AnyMiddleware, type AnyRouter, type Context, type Middleware } from '@orpc/server';
2
2
  import type { EnvConfigInput, ValidatedEnv } from '../env.js';
3
+ import type { MessagingConfig } from '../messaging/index.js';
3
4
  import type { ApiContext } from './context.js';
4
5
  import { BUNDERSTACK_ERRORS } from '../errors.js';
5
6
  export type { ProtectedContextAdditions } from './types.js';
6
- export declare function createApiBuilder<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>>(): {
7
- public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv> & object, object, {
7
+ export declare function createApiBuilder<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig>(): {
8
+ public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging> & object, object, {
8
9
  readonly BAD_REQUEST: {
9
10
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
10
11
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -62,7 +63,7 @@ export declare function createApiBuilder<TSchema extends Record<string, unknown>
62
63
  }>;
63
64
  };
64
65
  }>;
65
- protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv> & object, Omit<object, "user" | "session"> & {
66
+ protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging> & object, Omit<object, "user" | "session"> & {
66
67
  user: import("..").AccessUser;
67
68
  session: {
68
69
  activeOrganizationId: string | null;
@@ -125,7 +126,7 @@ export declare function createApiBuilder<TSchema extends Record<string, unknown>
125
126
  }>;
126
127
  };
127
128
  }>;
128
- webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv> & object, object, {
129
+ webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging> & object, object, {
129
130
  readonly BAD_REQUEST: {
130
131
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
131
132
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -191,18 +192,19 @@ export declare function createApiBuilder<TSchema extends Record<string, unknown>
191
192
  * The annotation is explicit because the inferred `DecoratedMiddleware`
192
193
  * is internal to `@orpc/server` and cannot be named in the emitted types.
193
194
  */
194
- middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, TEnv>, TOutContext, unknown, unknown, typeof BUNDERSTACK_ERRORS>) => AnyMiddleware;
195
+ middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, TEnv, TMessaging>, TOutContext, unknown, unknown, typeof BUNDERSTACK_ERRORS>) => AnyMiddleware;
195
196
  };
196
197
  /**
197
198
  * Same builder as `createApiBuilder`, but the generics come from the values an
198
199
  * application already has. It reads nothing at runtime, so a module can call it
199
200
  * at import time and export the bases that its router modules import.
200
201
  */
201
- export declare function defineApi<TSchema extends Record<string, unknown>, TEnv extends EnvConfigInput | undefined = undefined>(_options: {
202
+ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv extends EnvConfigInput | undefined = undefined, TMessaging extends MessagingConfig = MessagingConfig>(_options: {
202
203
  schema: TSchema;
203
204
  env?: TEnv;
205
+ messaging?: TMessaging;
204
206
  }): {
205
- public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>> & object, object, {
207
+ public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging> & object, object, {
206
208
  readonly BAD_REQUEST: {
207
209
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
208
210
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -260,7 +262,7 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
260
262
  }>;
261
263
  };
262
264
  }>;
263
- protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>> & object, Omit<object, "user" | "session"> & {
265
+ protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging> & object, Omit<object, "user" | "session"> & {
264
266
  user: import("..").AccessUser;
265
267
  session: {
266
268
  activeOrganizationId: string | null;
@@ -323,7 +325,7 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
323
325
  }>;
324
326
  };
325
327
  }>;
326
- webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>> & object, object, {
328
+ webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging> & object, object, {
327
329
  readonly BAD_REQUEST: {
328
330
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
329
331
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -389,7 +391,7 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
389
391
  * The annotation is explicit because the inferred `DecoratedMiddleware`
390
392
  * is internal to `@orpc/server` and cannot be named in the emitted types.
391
393
  */
392
- middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, ValidatedEnv<TEnv>>, TOutContext, unknown, unknown, {
394
+ middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging>, TOutContext, unknown, unknown, {
393
395
  readonly BAD_REQUEST: {
394
396
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
395
397
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -448,6 +450,6 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
448
450
  };
449
451
  }>) => AnyMiddleware;
450
452
  };
451
- export type BunderstackApiBuilder<TSchema extends Record<string, unknown>, TEnv = Record<string, unknown>> = ReturnType<typeof createApiBuilder<TSchema, TEnv>>;
453
+ export type BunderstackApiBuilder<TSchema extends Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig> = ReturnType<typeof createApiBuilder<TSchema, TEnv, TMessaging>>;
452
454
  export type ApiFactory<TSchema extends Record<string, unknown>, TEnv, TCustomApiRouter extends AnyRouter> = (builder: BunderstackApiBuilder<TSchema, TEnv>) => TCustomApiRouter;
453
455
  //# sourceMappingURL=builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,OAAO,EACL,kBAAkB,EAGnB,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAExD,wBAAgB,gBAAgB,CAC9B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0B5B;;;;;;;OAOG;gBACuC,CAAC,WAAW,SAAS,OAAO,EACpE,UAAU,EAAE,UAAU,CACpB,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,EACzB,WAAW,EACX,OAAO,EACP,OAAO,EACP,OAAO,kBAAkB,CAC1B,KACE,aAAa;EAErB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,SAAS,cAAc,GAAG,SAAS,GAAG,SAAS,EACnD,QAAQ,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA5BvC;;;;;;;OAOG;iBACwC,WAAW,SAAS,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAQjE,aAAa;EAcrB;AAED,MAAM,MAAM,qBAAqB,CAC/B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC5B,UAAU,CAAC,OAAO,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;AAEtD,MAAM,MAAM,UAAU,CACpB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,EACJ,gBAAgB,SAAS,SAAS,IAChC,CAAC,OAAO,EAAE,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,gBAAgB,CAAA"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,UAAU,EAChB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,OAAO,EACL,kBAAkB,EAGnB,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAExD,wBAAgB,gBAAgB,CAC9B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,UAAU,SAAS,eAAe,GAAG,SAAS,GAAG,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0B9D;;;;;;;OAOG;gBACuC,CAAC,WAAW,SAAS,OAAO,EACpE,UAAU,EAAE,UAAU,CACpB,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,EACrC,WAAW,EACX,OAAO,EACP,OAAO,EACP,OAAO,kBAAkB,CAC1B,KACE,aAAa;EAErB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,SAAS,cAAc,GAAG,SAAS,GAAG,SAAS,EACnD,UAAU,SAAS,eAAe,GAAG,eAAe,EACpD,QAAQ,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,UAAU,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA7B/D;;;;;;;OAOG;iBACwC,WAAW,SAAS,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAQjE,aAAa;EAerB;AAED,MAAM,MAAM,qBAAqB,CAC/B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,UAAU,SAAS,eAAe,GAAG,SAAS,GAAG,eAAe,IAC9D,UAAU,CAAC,OAAO,gBAAgB,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAA;AAElE,MAAM,MAAM,UAAU,CACpB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,EACJ,gBAAgB,SAAS,SAAS,IAChC,CAAC,OAAO,EAAE,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,gBAAgB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,EAAE,GAKH,MAAM,cAAc,CAAA;AAKrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,WAAW,CAAA;AAGlB,MAAM,UAAU,gBAAgB;IAI9B,MAAM,IAAI,GAAG,EAAE;SACZ,QAAQ,EAA6B;SACrC,MAAM,CAAC,kBAAkB,CAAC;SAC1B,GAAG,CAAC,oBAAoB,CAAC,CAAA;IAE5B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACzD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAA;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,gBAAgB,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAA;QACvE,CAAC;QACD,OAAO,IAAI,CAAC;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE;oBACP,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;iBACnD;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,aAAa;QACxB,OAAO,EAAE,IAAI;QACb;;;;;;;WAOG;QACH,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAQnB;KACnB,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAGvB,QAAyC;IACzC,OAAO,gBAAgB,EAA+B,CAAA;AACxD,CAAC","sourcesContent":["import {\n os,\n type AnyMiddleware,\n type AnyRouter,\n type Context,\n type Middleware,\n} from '@orpc/server'\n\nimport type { EnvConfigInput, ValidatedEnv } from '../env'\nimport type { ApiContext } from './context'\n\nimport {\n BUNDERSTACK_ERRORS,\n BunderstackError,\n mapBunderstackErrors,\n} from '../errors'\nexport type { ProtectedContextAdditions } from './types'\n\nexport function createApiBuilder<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n>() {\n const base = os\n .$context<ApiContext<TSchema, TEnv>>()\n .errors(BUNDERSTACK_ERRORS)\n .use(mapBunderstackErrors)\n\n const protectedProc = base.use(async ({ context, next }) => {\n const session = await context.getSession()\n if (!session.user) {\n throw new BunderstackError('UNAUTHORIZED', 'Authentication required')\n }\n return next({\n context: {\n user: session.user,\n session: {\n activeOrganizationId: session.activeOrganizationId,\n },\n },\n })\n })\n\n return {\n public: base,\n protected: protectedProc,\n webhook: base,\n /**\n * Declares a standalone middleware over the base context. Use it for\n * `bunderstack({ middleware })`, which reaches every procedure in\n * the graph, and for `.use(...)` on any base declared here.\n *\n * The annotation is explicit because the inferred `DecoratedMiddleware`\n * is internal to `@orpc/server` and cannot be named in the emitted types.\n */\n middleware: base.middleware.bind(base) as <TOutContext extends Context>(\n middleware: Middleware<\n ApiContext<TSchema, TEnv>,\n TOutContext,\n unknown,\n unknown,\n typeof BUNDERSTACK_ERRORS\n >,\n ) => AnyMiddleware,\n }\n}\n\n/**\n * Same builder as `createApiBuilder`, but the generics come from the values an\n * application already has. It reads nothing at runtime, so a module can call it\n * at import time and export the bases that its router modules import.\n */\nexport function defineApi<\n TSchema extends Record<string, unknown>,\n TEnv extends EnvConfigInput | undefined = undefined,\n>(_options: { schema: TSchema; env?: TEnv }) {\n return createApiBuilder<TSchema, ValidatedEnv<TEnv>>()\n}\n\nexport type BunderstackApiBuilder<\n TSchema extends Record<string, unknown>,\n TEnv = Record<string, unknown>,\n> = ReturnType<typeof createApiBuilder<TSchema, TEnv>>\n\nexport type ApiFactory<\n TSchema extends Record<string, unknown>,\n TEnv,\n TCustomApiRouter extends AnyRouter,\n> = (builder: BunderstackApiBuilder<TSchema, TEnv>) => TCustomApiRouter\n"]}
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,EAAE,GAKH,MAAM,cAAc,CAAA;AAMrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,WAAW,CAAA;AAGlB,MAAM,UAAU,gBAAgB;IAK9B,MAAM,IAAI,GAAG,EAAE;SACZ,QAAQ,EAAyC;SACjD,MAAM,CAAC,kBAAkB,CAAC;SAC1B,GAAG,CAAC,oBAAoB,CAAC,CAAA;IAE5B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACzD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAA;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,gBAAgB,CAAC,cAAc,EAAE,yBAAyB,CAAC,CAAA;QACvE,CAAC;QACD,OAAO,IAAI,CAAC;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE;oBACP,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;iBACnD;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,aAAa;QACxB,OAAO,EAAE,IAAI;QACb;;;;;;;WAOG;QACH,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAQnB;KACnB,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAIvB,QAAiE;IACjE,OAAO,gBAAgB,EAA2C,CAAA;AACpE,CAAC","sourcesContent":["import {\n os,\n type AnyMiddleware,\n type AnyRouter,\n type Context,\n type Middleware,\n} from '@orpc/server'\n\nimport type { EnvConfigInput, ValidatedEnv } from '../env'\nimport type { MessagingConfig } from '../messaging'\nimport type { ApiContext } from './context'\n\nimport {\n BUNDERSTACK_ERRORS,\n BunderstackError,\n mapBunderstackErrors,\n} from '../errors'\nexport type { ProtectedContextAdditions } from './types'\n\nexport function createApiBuilder<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n>() {\n const base = os\n .$context<ApiContext<TSchema, TEnv, TMessaging>>()\n .errors(BUNDERSTACK_ERRORS)\n .use(mapBunderstackErrors)\n\n const protectedProc = base.use(async ({ context, next }) => {\n const session = await context.getSession()\n if (!session.user) {\n throw new BunderstackError('UNAUTHORIZED', 'Authentication required')\n }\n return next({\n context: {\n user: session.user,\n session: {\n activeOrganizationId: session.activeOrganizationId,\n },\n },\n })\n })\n\n return {\n public: base,\n protected: protectedProc,\n webhook: base,\n /**\n * Declares a standalone middleware over the base context. Use it for\n * `bunderstack({ middleware })`, which reaches every procedure in\n * the graph, and for `.use(...)` on any base declared here.\n *\n * The annotation is explicit because the inferred `DecoratedMiddleware`\n * is internal to `@orpc/server` and cannot be named in the emitted types.\n */\n middleware: base.middleware.bind(base) as <TOutContext extends Context>(\n middleware: Middleware<\n ApiContext<TSchema, TEnv, TMessaging>,\n TOutContext,\n unknown,\n unknown,\n typeof BUNDERSTACK_ERRORS\n >,\n ) => AnyMiddleware,\n }\n}\n\n/**\n * Same builder as `createApiBuilder`, but the generics come from the values an\n * application already has. It reads nothing at runtime, so a module can call it\n * at import time and export the bases that its router modules import.\n */\nexport function defineApi<\n TSchema extends Record<string, unknown>,\n TEnv extends EnvConfigInput | undefined = undefined,\n TMessaging extends MessagingConfig = MessagingConfig,\n>(_options: { schema: TSchema; env?: TEnv; messaging?: TMessaging }) {\n return createApiBuilder<TSchema, ValidatedEnv<TEnv>, TMessaging>()\n}\n\nexport type BunderstackApiBuilder<\n TSchema extends Record<string, unknown>,\n TEnv = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> = ReturnType<typeof createApiBuilder<TSchema, TEnv, TMessaging>>\n\nexport type ApiFactory<\n TSchema extends Record<string, unknown>,\n TEnv,\n TCustomApiRouter extends AnyRouter,\n> = (builder: BunderstackApiBuilder<TSchema, TEnv>) => TCustomApiRouter\n"]}
@@ -1,26 +1,26 @@
1
1
  import type { AccessUser, AuthSessionResolver } from '../access.js';
2
2
  import type { DbFor } from '../db.js';
3
- import type { EmailFacade } from '../email.js';
4
3
  import type { JobsRuntimeFacade } from '../jobs/define.js';
5
4
  import type { BunderstackLogger } from '../logging.js';
5
+ import type { MessagingConfig, MessagingFacadesFor } from '../messaging/index.js';
6
6
  import type { RealtimeFacade } from '../realtime/facade.js';
7
7
  import type { AuthInstance, StorageFacade } from '../runtime.js';
8
- export interface ApiContextDeps<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>> {
8
+ export interface ApiContextDeps<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig> {
9
9
  db: DbFor<TSchema>;
10
10
  env: TEnv;
11
11
  storage: StorageFacade;
12
- email: EmailFacade;
12
+ messaging: MessagingFacadesFor<TMessaging>;
13
13
  jobs: JobsRuntimeFacade;
14
14
  realtime: RealtimeFacade<TSchema>;
15
15
  auth: AuthInstance;
16
16
  authResolver?: AuthSessionResolver;
17
17
  logger?: BunderstackLogger;
18
18
  }
19
- export interface ApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>> {
19
+ export interface ApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig> {
20
20
  db: DbFor<TSchema>;
21
21
  env: TEnv;
22
22
  storage: StorageFacade;
23
- email: EmailFacade;
23
+ messaging: MessagingFacadesFor<TMessaging>;
24
24
  jobs: JobsRuntimeFacade;
25
25
  realtime: RealtimeFacade<TSchema>;
26
26
  auth: AuthInstance;
@@ -43,5 +43,5 @@ export interface ApiContext<TSchema extends Record<string, unknown> = Record<str
43
43
  activeOrganizationId: string | null;
44
44
  } | undefined;
45
45
  }
46
- export declare function createApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>>(deps: ApiContextDeps<TSchema, TEnv>, request: Request): ApiContext<TSchema, TEnv>;
46
+ export declare function createApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig>(deps: ApiContextDeps<TSchema, TEnv, TMessaging>, request: Request): ApiContext<TSchema, TEnv, TMessaging>;
47
47
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK7D,MAAM,WAAW,cAAc,CAC7B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE9B,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAClB,GAAG,EAAE,IAAI,CAAA;IACT,OAAO,EAAE,aAAa,CAAA;IACtB,KAAK,EAAE,WAAW,CAAA;IAClB,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,EAAE,YAAY,CAAA;IAClB,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AAED,MAAM,WAAW,UAAU,CACzB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAE9B,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAClB,GAAG,EAAE,IAAI,CAAA;IACT,OAAO,EAAE,aAAa,CAAA;IACtB,KAAK,EAAE,WAAW,CAAA;IAClB,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,iBAAiB,CAAA;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,OAAO,CAAC;QACxB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;QACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;KACpC,CAAC,CAAA;IACF;;;;;OAKG;IACH,WAAW,EAAE,MACT;QAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;QAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAChE,SAAS,CAAA;CACd;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAE9B,IAAI,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,EACnC,OAAO,EAAE,OAAO,GACf,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CA8C3B"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAClC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK7D,MAAM,WAAW,cAAc,CAC7B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,UAAU,SAAS,eAAe,GAAG,SAAS,GAAG,eAAe;IAEhE,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAClB,GAAG,EAAE,IAAI,CAAA;IACT,OAAO,EAAE,aAAa,CAAA;IACtB,SAAS,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAA;IAC1C,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,EAAE,YAAY,CAAA;IAClB,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AAED,MAAM,WAAW,UAAU,CACzB,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,UAAU,SAAS,eAAe,GAAG,SAAS,GAAG,eAAe;IAEhE,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAClB,GAAG,EAAE,IAAI,CAAA;IACT,OAAO,EAAE,aAAa,CAAA;IACtB,SAAS,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAA;IAC1C,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;IACjC,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,iBAAiB,CAAA;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;IACnB,UAAU,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,OAAO,CAAC;QACxB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;QACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;KACpC,CAAC,CAAA;IACF;;;;;OAKG;IACH,WAAW,EAAE,MACT;QAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;QAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAChE,SAAS,CAAA;CACd;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,UAAU,SAAS,eAAe,GAAG,SAAS,GAAG,eAAe,EAEhE,IAAI,EAAE,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,EAC/C,OAAO,EAAE,OAAO,GACf,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CA8CvC"}
@@ -25,7 +25,7 @@ export function createApiContext(deps, request) {
25
25
  db: deps.db,
26
26
  env: deps.env,
27
27
  storage: deps.storage,
28
- email: deps.email,
28
+ messaging: deps.messaging,
29
29
  jobs: deps.jobs,
30
30
  realtime: deps.realtime,
31
31
  auth: deps.auth,
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA+C1C,MAAM,UAAU,gBAAgB,CAI9B,IAAmC,EACnC,OAAgB;IAEhB,uEAAuE;IACvE,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;IACtC,IAAI,cAA2C,CAAA;IAC/C,IAAI,cAES,CAAA;IAEb,IAAI,cAES,CAAA;IAEb,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CACtE,CAAC,OAAO,EAAE,EAAE;gBACV,cAAc,GAAG,OAAO,CAAA;gBACxB,OAAO,OAAO,CAAA;YAChB,CAAC,CACF,CAAA;QACH,CAAC;QACD,OAAO,cAAc,CAAA;IACvB,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,cAAc,CAAA;IAExC,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,cAAc;YAAE,cAAc,GAAG,cAAc,CAAC,IAAI,EAAE,CAAA;QAC3D,OAAO,cAAc,CAAA;IACvB,CAAC,CAAA;IAED,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa;QACpC,OAAO;QACP,UAAU,EAAE,IAAI,OAAO,EAAE;QACzB,UAAU;QACV,UAAU;QACV,WAAW;KACZ,CAAA;AACH,CAAC","sourcesContent":["import type { AccessUser, AuthSessionResolver } from '../access'\nimport type { DbFor } from '../db'\nimport type { EmailFacade } from '../email'\nimport type { JobsRuntimeFacade } from '../jobs/define'\nimport type { BunderstackLogger } from '../logging'\nimport type { RealtimeFacade } from '../realtime/facade'\nimport type { AuthInstance, StorageFacade } from '../runtime'\n\nimport { resolveSession } from '../access'\nimport { consoleLogger } from '../logging'\n\nexport interface ApiContextDeps<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n> {\n db: DbFor<TSchema>\n env: TEnv\n storage: StorageFacade\n email: EmailFacade\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n auth: AuthInstance\n authResolver?: AuthSessionResolver\n logger?: BunderstackLogger\n}\n\nexport interface ApiContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n> {\n db: DbFor<TSchema>\n env: TEnv\n storage: StorageFacade\n email: EmailFacade\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n auth: AuthInstance\n logger: BunderstackLogger\n request: Request\n resHeaders: Headers\n getRawBody: () => Promise<string>\n getSession: () => Promise<{\n user: AccessUser | null\n activeOrganizationId: string | null\n }>\n /**\n * The session that some earlier code already resolved, or `undefined`.\n * Never starts a resolution, so a global middleware can log the caller\n * without removing the lazy session behavior that signed webhooks rely on.\n * Use it for observability only. Never use it for authorization.\n */\n peekSession: () =>\n | { user: AccessUser | null; activeOrganizationId: string | null }\n | undefined\n}\n\nexport function createApiContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n>(\n deps: ApiContextDeps<TSchema, TEnv>,\n request: Request,\n): ApiContext<TSchema, TEnv> {\n // Reserve the body stream before a transport codec consumes `request`.\n const rawBodyRequest = request.clone()\n let rawBodyPromise: Promise<string> | undefined\n let sessionPromise:\n | Promise<{ user: AccessUser | null; activeOrganizationId: string | null }>\n | undefined\n\n let settledSession:\n | { user: AccessUser | null; activeOrganizationId: string | null }\n | undefined\n\n const getSession = () => {\n if (!sessionPromise) {\n sessionPromise = resolveSession(deps.authResolver, request.headers).then(\n (session) => {\n settledSession = session\n return session\n },\n )\n }\n return sessionPromise\n }\n\n const peekSession = () => settledSession\n\n const getRawBody = () => {\n if (!rawBodyPromise) rawBodyPromise = rawBodyRequest.text()\n return rawBodyPromise\n }\n\n return {\n db: deps.db,\n env: deps.env,\n storage: deps.storage,\n email: deps.email,\n jobs: deps.jobs,\n realtime: deps.realtime,\n auth: deps.auth,\n logger: deps.logger ?? consoleLogger,\n request,\n resHeaders: new Headers(),\n getRawBody,\n getSession,\n peekSession,\n }\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAiD1C,MAAM,UAAU,gBAAgB,CAK9B,IAA+C,EAC/C,OAAgB;IAEhB,uEAAuE;IACvE,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;IACtC,IAAI,cAA2C,CAAA;IAC/C,IAAI,cAES,CAAA;IAEb,IAAI,cAES,CAAA;IAEb,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CACtE,CAAC,OAAO,EAAE,EAAE;gBACV,cAAc,GAAG,OAAO,CAAA;gBACxB,OAAO,OAAO,CAAA;YAChB,CAAC,CACF,CAAA;QACH,CAAC;QACD,OAAO,cAAc,CAAA;IACvB,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,cAAc,CAAA;IAExC,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,cAAc;YAAE,cAAc,GAAG,cAAc,CAAC,IAAI,EAAE,CAAA;QAC3D,OAAO,cAAc,CAAA;IACvB,CAAC,CAAA;IAED,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa;QACpC,OAAO;QACP,UAAU,EAAE,IAAI,OAAO,EAAE;QACzB,UAAU;QACV,UAAU;QACV,WAAW;KACZ,CAAA;AACH,CAAC","sourcesContent":["import type { AccessUser, AuthSessionResolver } from '../access'\nimport type { DbFor } from '../db'\nimport type { JobsRuntimeFacade } from '../jobs/define'\nimport type { BunderstackLogger } from '../logging'\nimport type { MessagingConfig, MessagingFacadesFor } from '../messaging'\nimport type { RealtimeFacade } from '../realtime/facade'\nimport type { AuthInstance, StorageFacade } from '../runtime'\n\nimport { resolveSession } from '../access'\nimport { consoleLogger } from '../logging'\n\nexport interface ApiContextDeps<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> {\n db: DbFor<TSchema>\n env: TEnv\n storage: StorageFacade\n messaging: MessagingFacadesFor<TMessaging>\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n auth: AuthInstance\n authResolver?: AuthSessionResolver\n logger?: BunderstackLogger\n}\n\nexport interface ApiContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n> {\n db: DbFor<TSchema>\n env: TEnv\n storage: StorageFacade\n messaging: MessagingFacadesFor<TMessaging>\n jobs: JobsRuntimeFacade\n realtime: RealtimeFacade<TSchema>\n auth: AuthInstance\n logger: BunderstackLogger\n request: Request\n resHeaders: Headers\n getRawBody: () => Promise<string>\n getSession: () => Promise<{\n user: AccessUser | null\n activeOrganizationId: string | null\n }>\n /**\n * The session that some earlier code already resolved, or `undefined`.\n * Never starts a resolution, so a global middleware can log the caller\n * without removing the lazy session behavior that signed webhooks rely on.\n * Use it for observability only. Never use it for authorization.\n */\n peekSession: () =>\n | { user: AccessUser | null; activeOrganizationId: string | null }\n | undefined\n}\n\nexport function createApiContext<\n TSchema extends Record<string, unknown> = Record<string, unknown>,\n TEnv = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n>(\n deps: ApiContextDeps<TSchema, TEnv, TMessaging>,\n request: Request,\n): ApiContext<TSchema, TEnv, TMessaging> {\n // Reserve the body stream before a transport codec consumes `request`.\n const rawBodyRequest = request.clone()\n let rawBodyPromise: Promise<string> | undefined\n let sessionPromise:\n | Promise<{ user: AccessUser | null; activeOrganizationId: string | null }>\n | undefined\n\n let settledSession:\n | { user: AccessUser | null; activeOrganizationId: string | null }\n | undefined\n\n const getSession = () => {\n if (!sessionPromise) {\n sessionPromise = resolveSession(deps.authResolver, request.headers).then(\n (session) => {\n settledSession = session\n return session\n },\n )\n }\n return sessionPromise\n }\n\n const peekSession = () => settledSession\n\n const getRawBody = () => {\n if (!rawBodyPromise) rawBodyPromise = rawBodyRequest.text()\n return rawBodyPromise\n }\n\n return {\n db: deps.db,\n env: deps.env,\n storage: deps.storage,\n messaging: deps.messaging,\n jobs: deps.jobs,\n realtime: deps.realtime,\n auth: deps.auth,\n logger: deps.logger ?? consoleLogger,\n request,\n resHeaders: new Headers(),\n getRawBody,\n getSession,\n peekSession,\n }\n}\n"]}
@@ -61,7 +61,7 @@ export type BuildTableCrudProceduresArgs<TSchema extends Record<string, unknown>
61
61
  livePublisher?: RealtimePublisher;
62
62
  };
63
63
  export declare function buildTableCrudProcedures<TSchema extends Record<string, unknown>, TTable extends Table, TFilterable extends string = string, TSortable extends string = string>(args: BuildTableCrudProceduresArgs<TSchema, TTable>): {
64
- list: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>> & object, object, v.GenericSchema<ListInputFor<TTable, TFilterable, TSortable>, ListInputFor<TTable, TFilterable, TSortable>>, v.StrictObjectSchema<{
64
+ list: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.GenericSchema<ListInputFor<TTable, TFilterable, TSortable>, ListInputFor<TTable, TFilterable, TSortable>>, v.StrictObjectSchema<{
65
65
  readonly items: v.ArraySchema<v.GenericSchema<TTable["$inferSelect"], TTable["$inferSelect"]>, undefined>;
66
66
  readonly nextCursor: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
67
67
  readonly hasMore: v.BooleanSchema<undefined>;
@@ -130,7 +130,7 @@ export declare function buildTableCrudProcedures<TSchema extends Record<string,
130
130
  }>;
131
131
  };
132
132
  }, never>;
133
- get: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
133
+ get: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
134
134
  readonly id: v.StringSchema<undefined>;
135
135
  }, undefined>, v.GenericSchema<TTable["$inferSelect"], TTable["$inferSelect"]>, {
136
136
  readonly BAD_REQUEST: {
@@ -190,7 +190,7 @@ export declare function buildTableCrudProcedures<TSchema extends Record<string,
190
190
  }>;
191
191
  };
192
192
  }, Extract<TTable["$inferSelect"], import("@orpc/client").AnyORPCError>>;
193
- create: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>> & object, object, v.GenericSchema<Partial<TTable["$inferInsert"]>, Partial<TTable["$inferInsert"]>>, v.GenericSchema<TTable["$inferSelect"], TTable["$inferSelect"]>, {
193
+ create: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.GenericSchema<Partial<TTable["$inferInsert"]>, Partial<TTable["$inferInsert"]>>, v.GenericSchema<TTable["$inferSelect"], TTable["$inferSelect"]>, {
194
194
  readonly BAD_REQUEST: {
195
195
  readonly data: v.OptionalSchema<v.StrictObjectSchema<{
196
196
  readonly code: v.OptionalSchema<v.LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -248,7 +248,7 @@ export declare function buildTableCrudProcedures<TSchema extends Record<string,
248
248
  }>;
249
249
  };
250
250
  }, Extract<TTable["$inferSelect"], import("@orpc/client").AnyORPCError>>;
251
- update: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>> & object, object, v.GenericSchema<{
251
+ update: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.GenericSchema<{
252
252
  id: string;
253
253
  } & Partial<Omit<TTable["$inferInsert"], "id">>, {
254
254
  id: string;
@@ -310,7 +310,7 @@ export declare function buildTableCrudProcedures<TSchema extends Record<string,
310
310
  }>;
311
311
  };
312
312
  }, Extract<TTable["$inferSelect"], import("@orpc/client").AnyORPCError>>;
313
- delete: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
313
+ delete: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
314
314
  readonly id: v.StringSchema<undefined>;
315
315
  }, undefined>, v.UndefinedSchema<undefined>, {
316
316
  readonly BAD_REQUEST: {
@@ -370,7 +370,7 @@ export declare function buildTableCrudProcedures<TSchema extends Record<string,
370
370
  }>;
371
371
  };
372
372
  }, never>;
373
- live: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>> & object, object, v.GenericSchema<LiveInputFor<TTable, TFilterable, TSortable>, LiveInputFor<TTable, TFilterable, TSortable>>, import("@orpc/contract").Schema<AsyncIteratorObject<{
373
+ live: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.GenericSchema<LiveInputFor<TTable, TFilterable, TSortable>, LiveInputFor<TTable, TFilterable, TSortable>>, import("@orpc/contract").Schema<AsyncIteratorObject<{
374
374
  type: "snapshot";
375
375
  items: TTable["$inferSelect"][];
376
376
  sort: string;
@@ -7,7 +7,7 @@ type RealtimeRouterOptions = {
7
7
  };
8
8
  export declare function buildRealtimeApiRouter(publisher: RealtimePublisher | undefined, access: ResolvedAccess, options?: RealtimeRouterOptions): {
9
9
  realtime: {
10
- changes: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<Record<string, unknown>, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
10
+ changes: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
11
11
  readonly tables: v.SchemaWithPipe<readonly [v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.StringSchema<undefined>, undefined>], undefined>, v.TransformAction<string | string[], string[]>]>;
12
12
  }, undefined>, import("@orpc/contract").Schema<AsyncIteratorObject<{
13
13
  table: string;
@@ -6,7 +6,7 @@ import type { ApiContext } from './context.js';
6
6
  export declare function buildStorageApiRouter(registry: BucketStorageRegistry, operations: StorageOperations): {
7
7
  files: {
8
8
  [k: string]: {
9
- prepareUpload: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
9
+ prepareUpload: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
10
10
  readonly filename: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
11
11
  readonly contentType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
12
12
  }, undefined>, v.VariantSchema<"mode", [v.StrictObjectSchema<{
@@ -76,7 +76,7 @@ export declare function buildStorageApiRouter(registry: BucketStorageRegistry, o
76
76
  }>;
77
77
  };
78
78
  }, never>;
79
- upload: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
79
+ upload: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
80
80
  readonly params: v.OptionalSchema<v.StrictObjectSchema<{}, undefined>, {}>;
81
81
  readonly query: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, {}>;
82
82
  readonly headers: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, {}>;
@@ -147,7 +147,7 @@ export declare function buildStorageApiRouter(registry: BucketStorageRegistry, o
147
147
  }>;
148
148
  };
149
149
  }, never>;
150
- confirmUpload: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
150
+ confirmUpload: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
151
151
  readonly id: v.StringSchema<undefined>;
152
152
  }, undefined>, v.StrictObjectSchema<{
153
153
  readonly fileId: v.StringSchema<undefined>;
@@ -210,7 +210,7 @@ export declare function buildStorageApiRouter(registry: BucketStorageRegistry, o
210
210
  }>;
211
211
  };
212
212
  }, never>;
213
- download: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
213
+ download: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
214
214
  readonly params: v.StrictObjectSchema<{
215
215
  readonly path: v.StringSchema<undefined>;
216
216
  }, undefined>;
@@ -283,7 +283,7 @@ export declare function buildStorageApiRouter(registry: BucketStorageRegistry, o
283
283
  }>;
284
284
  };
285
285
  }, never>;
286
- delete: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>> & object, object, v.StrictObjectSchema<{
286
+ delete: import("@orpc/server").DecoratedProcedure<ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
287
287
  readonly path: v.StringSchema<undefined>;
288
288
  }, undefined>, v.UndefinedSchema<undefined>, {
289
289
  readonly BAD_REQUEST: {
package/dist/auth.d.ts CHANGED
@@ -1,17 +1,27 @@
1
- import { type Auth } from 'better-auth';
1
+ import { type Auth, type BetterAuthPlugin } from 'better-auth';
2
+ import { openAPI } from 'better-auth/plugins';
2
3
  import type { AuthSessionResolver } from './access.js';
3
4
  import type { BetterAuthConfig } from './config.js';
4
5
  import type { AnyDb, Dialect } from './dialect.js';
5
6
  import type { EmailFacade } from './email.js';
7
+ type ConfiguredAuthPlugins<TConfig extends BetterAuthConfig> = TConfig extends {
8
+ plugins: infer TPlugins extends readonly BetterAuthPlugin[];
9
+ } ? TPlugins : [];
10
+ type WithBunderstackAuthDefaults<TConfig extends BetterAuthConfig> = Omit<BetterAuthConfig, 'plugins'> & Omit<TConfig, 'plugins'> & {
11
+ plugins: [...ConfiguredAuthPlugins<TConfig>, ReturnType<typeof openAPI>];
12
+ };
6
13
  /**
7
- * Returns better-auth's plain `Auth`, not the plugin-parameterised type its
8
- * builder infers: declaration emit would otherwise inline that whole inferred
9
- * options object into the published `.d.ts`, where it no longer satisfies
10
- * better-auth's own `BetterAuthOptions` constraint. Plugin-specific endpoints
11
- * are reached through runtime checks (see the OpenAPI schema lookup in
12
- * `index.ts`), so nothing depends on the wider type.
14
+ * The public Better Auth instance retains every endpoint and model field from
15
+ * the declared config. Bunderstack always installs OpenAPI at runtime, so its
16
+ * endpoints are part of the public type even when the app omitted the plugin.
13
17
  */
14
- export declare function createAuth(db: AnyDb, cfg: BetterAuthConfig, dialect: Dialect, userSchema?: Record<string, unknown>): Auth;
18
+ export type BunderstackAuth<TConfig extends BetterAuthConfig = BetterAuthConfig> = Auth<WithBunderstackAuthDefaults<TConfig>> & Auth;
19
+ /**
20
+ * Build Better Auth while exposing its named plugin-aware public type. The
21
+ * implementation accepts the resolved runtime config, while `TConfig` carries
22
+ * the declaration that produced it; their relationship is asserted once here.
23
+ */
24
+ export declare function createAuth<TConfig extends BetterAuthConfig = BetterAuthConfig>(db: AnyDb, cfg: BetterAuthConfig, dialect: Dialect, userSchema?: Record<string, unknown>): BunderstackAuth<TConfig>;
15
25
  /**
16
26
  * better-auth resolves its models out of the app's own schema, so an app that
17
27
  * declares none has no auth at all. Session resolution must then short-circuit
@@ -28,7 +38,7 @@ export declare function missingAuthModels(schema: Record<string, unknown>, cfg:
28
38
  * Keeping this adapter here means internal modules never depend on better-auth's
29
39
  * evolving types.
30
40
  */
31
- export declare function toAuthSessionResolver(auth: ReturnType<typeof createAuth>): AuthSessionResolver;
41
+ export declare function toAuthSessionResolver(auth: Auth): AuthSessionResolver;
32
42
  /**
33
43
  * Fill better-auth's email hooks from the bunderstack email facade. Only fills
34
44
  * gaps: user-supplied handlers always win, and nothing is injected when email
@@ -36,4 +46,5 @@ export declare function toAuthSessionResolver(auth: ReturnType<typeof createAuth
36
46
  * (injecting it unasked would enable the feature).
37
47
  */
38
48
  export declare function withEmailAuthDefaults(cfg: BetterAuthConfig, email: EmailFacade, emailConfigured: boolean): BetterAuthConfig;
49
+ export {};
39
50
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,aAAa,CAAA;AAInD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,EAAE,EAAE,KAAK,EACT,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAcN;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,GAAG,EAAE,gBAAgB,GACpB,MAAM,EAAE,CAMV;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAClC,mBAAmB,CA+BrB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,WAAW,EAClB,eAAe,EAAE,OAAO,GACvB,gBAAgB,CAkClB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,IAAI,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,KAAK,qBAAqB,CAAC,OAAO,SAAS,gBAAgB,IAAI,OAAO,SAAS;IAC7E,OAAO,EAAE,MAAM,QAAQ,SAAS,SAAS,gBAAgB,EAAE,CAAA;CAC5D,GACG,QAAQ,GACR,EAAE,CAAA;AAEN,KAAK,2BAA2B,CAAC,OAAO,SAAS,gBAAgB,IAAI,IAAI,CACvE,gBAAgB,EAChB,SAAS,CACV,GACC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG;IACzB,OAAO,EAAE,CAAC,GAAG,qBAAqB,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAAA;CACzE,CAAA;AAEH;;;;GAIG;AACH,MAAM,MAAM,eAAe,CACzB,OAAO,SAAS,gBAAgB,GAAG,gBAAgB,IACjD,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAA;AAErD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,SAAS,gBAAgB,GAAG,gBAAgB,EAC5E,EAAE,EAAE,KAAK,EACT,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,eAAe,CAAC,OAAO,CAAC,CAY1B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,GAAG,EAAE,gBAAgB,GACpB,MAAM,EAAE,CAMV;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,mBAAmB,CA+BrE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,WAAW,EAClB,eAAe,EAAE,OAAO,GACvB,gBAAgB,CAkClB"}
package/dist/auth.js CHANGED
@@ -3,18 +3,13 @@ import { betterAuth } from 'better-auth';
3
3
  import { drizzleAdapter } from 'better-auth/adapters/drizzle';
4
4
  import { openAPI } from 'better-auth/plugins';
5
5
  /**
6
- * Returns better-auth's plain `Auth`, not the plugin-parameterised type its
7
- * builder infers: declaration emit would otherwise inline that whole inferred
8
- * options object into the published `.d.ts`, where it no longer satisfies
9
- * better-auth's own `BetterAuthOptions` constraint. Plugin-specific endpoints
10
- * are reached through runtime checks (see the OpenAPI schema lookup in
11
- * `index.ts`), so nothing depends on the wider type.
6
+ * Build Better Auth while exposing its named plugin-aware public type. The
7
+ * implementation accepts the resolved runtime config, while `TConfig` carries
8
+ * the declaration that produced it; their relationship is asserted once here.
12
9
  */
13
10
  export function createAuth(db, cfg, dialect, userSchema) {
14
11
  const hasOpenApi = cfg.plugins?.some((p) => p.id === 'open-api');
15
12
  const plugins = hasOpenApi ? cfg.plugins : [...(cfg.plugins || []), openAPI()];
16
- // Type-only narrowing: the value is unchanged, but the published signature
17
- // stays a type better-auth itself can name.
18
13
  return betterAuth({
19
14
  ...cfg,
20
15
  plugins,
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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","sourcesContent":["// src/auth.ts\nimport { betterAuth, type Auth } from 'better-auth'\nimport { drizzleAdapter } from 'better-auth/adapters/drizzle'\nimport { openAPI } from 'better-auth/plugins'\n\nimport type { AuthSessionResolver } from './access'\nimport type { BetterAuthConfig } from './config'\nimport type { AnyDb, Dialect } from './dialect'\nimport type { EmailFacade } from './email'\n\n/**\n * Returns better-auth's plain `Auth`, not the plugin-parameterised type its\n * builder infers: declaration emit would otherwise inline that whole inferred\n * options object into the published `.d.ts`, where it no longer satisfies\n * better-auth's own `BetterAuthOptions` constraint. Plugin-specific endpoints\n * are reached through runtime checks (see the OpenAPI schema lookup in\n * `index.ts`), so nothing depends on the wider type.\n */\nexport function createAuth(\n db: AnyDb,\n cfg: BetterAuthConfig,\n dialect: Dialect,\n userSchema?: Record<string, unknown>,\n): Auth {\n const hasOpenApi = cfg.plugins?.some((p: any) => p.id === 'open-api')\n const plugins = hasOpenApi ? cfg.plugins : [...(cfg.plugins || []), openAPI()]\n\n // Type-only narrowing: the value is unchanged, but the published signature\n // stays a type better-auth itself can name.\n return betterAuth({\n ...cfg,\n plugins,\n database: drizzleAdapter(db as Parameters<typeof drizzleAdapter>[0], {\n provider: dialect === 'pg' ? 'pg' : 'sqlite',\n ...(userSchema ? { schema: userSchema } : {}),\n }),\n }) as unknown as Auth\n}\n\n/**\n * better-auth resolves its models out of the app's own schema, so an app that\n * declares none has no auth at all. Session resolution must then short-circuit\n * to null: the drizzle adapter throws on a missing model, and any session\n * cookie for the host — a browser keeps those per host, not per port, so one\n * minted by another local app arrives here too — would break every request.\n */\nexport function missingAuthModels(\n schema: Record<string, unknown>,\n cfg: BetterAuthConfig,\n): string[] {\n const models = [\n cfg.user?.modelName ?? 'user',\n cfg.session?.modelName ?? 'session',\n ]\n return models.filter((model) => !schema[model])\n}\n\n/**\n * Adapt the raw better-auth instance to our internal {@link AuthSessionResolver}\n * contract. better-auth's `getSession` has a union return (a bare session, or a\n * `{ headers, response }` wrapper when `returnHeaders` is set); we only ever\n * call the bare form, so we narrow on `'user' in result` and map to our shape.\n * Keeping this adapter here means internal modules never depend on better-auth's\n * evolving types.\n */\nexport function toAuthSessionResolver(\n auth: ReturnType<typeof createAuth>,\n): AuthSessionResolver {\n return {\n api: {\n async getSession({ headers }) {\n const result = await auth.api.getSession({ headers })\n if (result && 'user' in result && result.user) {\n const session = 'session' in result ? result.session : null\n const activeOrganizationId =\n session &&\n 'activeOrganizationId' in session &&\n typeof session.activeOrganizationId === 'string'\n ? session.activeOrganizationId\n : null\n const role =\n 'role' in result.user && typeof result.user.role === 'string'\n ? result.user.role\n : undefined\n return {\n user: {\n id: result.user.id,\n email: result.user.email,\n name: result.user.name,\n ...(role ? { role } : {}),\n },\n session: session ? { activeOrganizationId } : null,\n }\n }\n return null\n },\n },\n }\n}\n\n/**\n * Fill better-auth's email hooks from the bunderstack email facade. Only fills\n * gaps: user-supplied handlers always win, and nothing is injected when email\n * isn't configured. emailAndPassword is only touched when the user enabled it\n * (injecting it unasked would enable the feature).\n */\nexport function withEmailAuthDefaults(\n cfg: BetterAuthConfig,\n email: EmailFacade,\n emailConfigured: boolean,\n): BetterAuthConfig {\n if (!emailConfigured) return cfg\n const out: BetterAuthConfig = { ...cfg }\n\n if (\n cfg.emailAndPassword?.enabled &&\n !cfg.emailAndPassword.sendResetPassword\n ) {\n out.emailAndPassword = {\n ...cfg.emailAndPassword,\n sendResetPassword: async ({ user, url }) => {\n await email.send({\n to: user.email,\n subject: 'Reset your password',\n text: `Click the link to reset your password:\\n\\n${url}\\n\\nIf you didn't request this, you can ignore this email.`,\n })\n },\n }\n }\n\n if (!cfg.emailVerification?.sendVerificationEmail) {\n out.emailVerification = {\n ...cfg.emailVerification,\n sendVerificationEmail: async ({ user, url }) => {\n await email.send({\n to: user.email,\n subject: 'Verify your email',\n text: `Click the link to verify your email address:\\n\\n${url}`,\n })\n },\n }\n }\n\n return out\n}\n"]}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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","sourcesContent":["// src/auth.ts\nimport { betterAuth, type Auth, type BetterAuthPlugin } from 'better-auth'\nimport { drizzleAdapter } from 'better-auth/adapters/drizzle'\nimport { openAPI } from 'better-auth/plugins'\n\nimport type { AuthSessionResolver } from './access'\nimport type { BetterAuthConfig } from './config'\nimport type { AnyDb, Dialect } from './dialect'\nimport type { EmailFacade } from './email'\n\ntype ConfiguredAuthPlugins<TConfig extends BetterAuthConfig> = TConfig extends {\n plugins: infer TPlugins extends readonly BetterAuthPlugin[]\n}\n ? TPlugins\n : []\n\ntype WithBunderstackAuthDefaults<TConfig extends BetterAuthConfig> = Omit<\n BetterAuthConfig,\n 'plugins'\n> &\n Omit<TConfig, 'plugins'> & {\n plugins: [...ConfiguredAuthPlugins<TConfig>, ReturnType<typeof openAPI>]\n }\n\n/**\n * The public Better Auth instance retains every endpoint and model field from\n * the declared config. Bunderstack always installs OpenAPI at runtime, so its\n * endpoints are part of the public type even when the app omitted the plugin.\n */\nexport type BunderstackAuth<\n TConfig extends BetterAuthConfig = BetterAuthConfig,\n> = Auth<WithBunderstackAuthDefaults<TConfig>> & Auth\n\n/**\n * Build Better Auth while exposing its named plugin-aware public type. The\n * implementation accepts the resolved runtime config, while `TConfig` carries\n * the declaration that produced it; their relationship is asserted once here.\n */\nexport function createAuth<TConfig extends BetterAuthConfig = BetterAuthConfig>(\n db: AnyDb,\n cfg: BetterAuthConfig,\n dialect: Dialect,\n userSchema?: Record<string, unknown>,\n): BunderstackAuth<TConfig> {\n const hasOpenApi = cfg.plugins?.some((p: any) => p.id === 'open-api')\n const plugins = hasOpenApi ? cfg.plugins : [...(cfg.plugins || []), openAPI()]\n\n return betterAuth({\n ...cfg,\n plugins,\n database: drizzleAdapter(db as Parameters<typeof drizzleAdapter>[0], {\n provider: dialect === 'pg' ? 'pg' : 'sqlite',\n ...(userSchema ? { schema: userSchema } : {}),\n }),\n }) as unknown as BunderstackAuth<TConfig>\n}\n\n/**\n * better-auth resolves its models out of the app's own schema, so an app that\n * declares none has no auth at all. Session resolution must then short-circuit\n * to null: the drizzle adapter throws on a missing model, and any session\n * cookie for the host — a browser keeps those per host, not per port, so one\n * minted by another local app arrives here too — would break every request.\n */\nexport function missingAuthModels(\n schema: Record<string, unknown>,\n cfg: BetterAuthConfig,\n): string[] {\n const models = [\n cfg.user?.modelName ?? 'user',\n cfg.session?.modelName ?? 'session',\n ]\n return models.filter((model) => !schema[model])\n}\n\n/**\n * Adapt the raw better-auth instance to our internal {@link AuthSessionResolver}\n * contract. better-auth's `getSession` has a union return (a bare session, or a\n * `{ headers, response }` wrapper when `returnHeaders` is set); we only ever\n * call the bare form, so we narrow on `'user' in result` and map to our shape.\n * Keeping this adapter here means internal modules never depend on better-auth's\n * evolving types.\n */\nexport function toAuthSessionResolver(auth: Auth): AuthSessionResolver {\n return {\n api: {\n async getSession({ headers }) {\n const result = await auth.api.getSession({ headers })\n if (result && 'user' in result && result.user) {\n const session = 'session' in result ? result.session : null\n const activeOrganizationId =\n session &&\n 'activeOrganizationId' in session &&\n typeof session.activeOrganizationId === 'string'\n ? session.activeOrganizationId\n : null\n const role =\n 'role' in result.user && typeof result.user.role === 'string'\n ? result.user.role\n : undefined\n return {\n user: {\n id: result.user.id,\n email: result.user.email,\n name: result.user.name,\n ...(role ? { role } : {}),\n },\n session: session ? { activeOrganizationId } : null,\n }\n }\n return null\n },\n },\n }\n}\n\n/**\n * Fill better-auth's email hooks from the bunderstack email facade. Only fills\n * gaps: user-supplied handlers always win, and nothing is injected when email\n * isn't configured. emailAndPassword is only touched when the user enabled it\n * (injecting it unasked would enable the feature).\n */\nexport function withEmailAuthDefaults(\n cfg: BetterAuthConfig,\n email: EmailFacade,\n emailConfigured: boolean,\n): BetterAuthConfig {\n if (!emailConfigured) return cfg\n const out: BetterAuthConfig = { ...cfg }\n\n if (\n cfg.emailAndPassword?.enabled &&\n !cfg.emailAndPassword.sendResetPassword\n ) {\n out.emailAndPassword = {\n ...cfg.emailAndPassword,\n sendResetPassword: async ({ user, url }) => {\n await email.send({\n to: user.email,\n subject: 'Reset your password',\n text: `Click the link to reset your password:\\n\\n${url}\\n\\nIf you didn't request this, you can ignore this email.`,\n })\n },\n }\n }\n\n if (!cfg.emailVerification?.sendVerificationEmail) {\n out.emailVerification = {\n ...cfg.emailVerification,\n sendVerificationEmail: async ({ user, url }) => {\n await email.send({\n to: user.email,\n subject: 'Verify your email',\n text: `Click the link to verify your email address:\\n\\n${url}`,\n })\n },\n }\n }\n\n return out\n}\n"]}