bunderstack 0.24.2 → 0.24.4

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  All notable changes to `bunderstack` will be documented in this file.
4
4
 
5
+ ## [0.24.4] — 2026-09-19
6
+
7
+ ### Fixed
8
+
9
+ - Preserve Better Auth's `emailVerified` value in `context.getSession()` and
10
+ normalize a missing or malformed value to `false`, so applications can
11
+ enforce verified-email access without patching Bunderstack.
12
+
13
+ ### Added
14
+
15
+ - Add `defineSessionUser({ mapUser })` and the `session` declaration option for
16
+ explicitly projecting application user fields into public and protected API
17
+ contexts with inferred TypeScript types. Framework-owned identity fields
18
+ cannot be overridden by the mapper.
19
+
20
+ ## [0.24.3] — 2026-09-16
21
+
22
+ ### Fixed
23
+
24
+ - Prefer the configured `APP_URL` when resolving relative API URLs during
25
+ server-side rendering. Internal HTTP reverse-proxy requests no longer
26
+ override the public HTTPS origin and cause unhandled redirects in RPC
27
+ clients. Browser requests and the request-origin fallback are unchanged.
28
+
5
29
  ## [0.24.2] — 2026-09-14
6
30
 
7
31
  ### Fixed
package/dist/access.d.ts CHANGED
@@ -1,10 +1,24 @@
1
1
  export declare const AUTH_TABLE_NAMES: Set<string>;
2
- export type AccessUser = {
2
+ export type AccessUserBase = {
3
3
  id: string;
4
4
  email: string;
5
+ emailVerified?: boolean;
5
6
  name?: string;
6
7
  role?: string;
7
8
  };
9
+ export type SessionUserSource = {
10
+ id: string;
11
+ email: string;
12
+ emailVerified?: boolean;
13
+ name?: string;
14
+ role?: string;
15
+ } & Record<string, unknown>;
16
+ export type SessionUserConfig<TExtra extends Record<string, unknown> = Record<never, never>> = {
17
+ mapUser: (user: SessionUserSource) => TExtra;
18
+ };
19
+ export type SessionUserExtraOf<TSession> = TSession extends SessionUserConfig<infer TExtra> ? TExtra : Record<never, never>;
20
+ export type AccessUser<TExtra extends Record<string, unknown> = Record<never, never>> = AccessUserBase & Omit<TExtra, keyof AccessUserBase>;
21
+ export declare function defineSessionUser<const TExtra extends Record<string, unknown>>(config: SessionUserConfig<TExtra>): SessionUserConfig<TExtra>;
8
22
  export type AccessContext = {
9
23
  user: AccessUser | null;
10
24
  request: Request;
@@ -91,26 +105,27 @@ export declare function checkAccess(rule: OperationRule, ctx: AccessContext, own
91
105
  status: 401 | 403;
92
106
  }>;
93
107
  export declare function sanitizeWriteBody(body: Record<string, unknown>, access: ResolvedTableAccess, mode: 'create' | 'update', userId: string | null): Record<string, unknown>;
94
- export type AuthSessionResolver = {
108
+ export type AuthSessionResolver<TExtra extends Record<string, unknown> = Record<never, never>> = {
95
109
  api: {
96
110
  getSession: (opts: {
97
111
  headers: Headers;
98
112
  }) => Promise<{
99
- user: {
113
+ user: ({
100
114
  id: string;
101
115
  email: string;
116
+ emailVerified?: boolean;
102
117
  name?: string;
103
118
  role?: string;
104
- } | null;
119
+ } & TExtra) | null;
105
120
  session?: {
106
121
  activeOrganizationId?: string | null;
107
122
  } | null;
108
123
  } | null>;
109
124
  };
110
125
  };
111
- export declare function resolveAccessUser(auth: AuthSessionResolver | undefined, headers: Headers): Promise<AccessUser | null>;
112
- export declare function resolveSession(auth: AuthSessionResolver | undefined, headers: Headers): Promise<{
113
- user: AccessUser | null;
126
+ export declare function resolveAccessUser<TExtra extends Record<string, unknown> = Record<never, never>>(auth: AuthSessionResolver<TExtra> | undefined, headers: Headers): Promise<AccessUser<TExtra> | null>;
127
+ export declare function resolveSession<TExtra extends Record<string, unknown> = Record<never, never>>(auth: AuthSessionResolver<TExtra> | undefined, headers: Headers): Promise<{
128
+ user: AccessUser<TExtra> | null;
114
129
  activeOrganizationId: string | null;
115
130
  }>;
116
131
  //# sourceMappingURL=access.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
package/dist/access.js CHANGED
@@ -7,6 +7,9 @@ export const AUTH_TABLE_NAMES = new Set([
7
7
  'verification',
8
8
  ]);
9
9
  const EXPOSEABLE_AUTH_TABLES = new Set(['user']);
10
+ export function defineSessionUser(config) {
11
+ return config;
12
+ }
10
13
  /**
11
14
  * Look up a table's resolved access by its physical table name.
12
15
  *
@@ -299,12 +302,15 @@ export async function resolveAccessUser(auth, headers) {
299
302
  const session = await auth.api.getSession({ headers });
300
303
  if (!session?.user)
301
304
  return null;
302
- return {
305
+ const user = {
306
+ ...session.user,
303
307
  id: session.user.id,
304
308
  email: session.user.email,
309
+ emailVerified: session.user.emailVerified === true,
305
310
  name: session.user.name,
306
311
  role: session.user.role,
307
312
  };
313
+ return user;
308
314
  }
309
315
  export async function resolveSession(auth, headers) {
310
316
  if (!auth)
@@ -314,8 +320,10 @@ export async function resolveSession(auth, headers) {
314
320
  return { user: null, activeOrganizationId: null };
315
321
  return {
316
322
  user: {
323
+ ...session.user,
317
324
  id: session.user.id,
318
325
  email: session.user.email,
326
+ emailVerified: session.user.emailVerified === true,
319
327
  name: session.user.name,
320
328
  role: session.user.role,
321
329
  },
@@ -1 +1 @@
1
- {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTableColumns, getTableName, isTable } from 'drizzle-orm'\n\nimport { INTERNAL_TABLE_NAMES } from './internal-tables'\n\nexport const AUTH_TABLE_NAMES = new Set([\n 'user',\n 'session',\n 'account',\n 'verification',\n])\n\nconst EXPOSEABLE_AUTH_TABLES = new Set(['user'])\n\nexport type AccessUser = {\n id: string\n email: string\n name?: string\n role?: string\n}\n\nexport type AccessContext = {\n user: AccessUser | null\n request: Request\n row?: Record<string, unknown>\n body?: Record<string, unknown>\n session?: { activeOrganizationId: string | null } | null\n}\n\nexport type OperationRule =\n | 'public'\n | 'authenticated'\n | 'owner'\n | 'deny'\n | ((ctx: AccessContext) => boolean | Promise<boolean>)\n\nexport type ScopeMap = Record<string, string | string[]>\nexport type ScopeResolver = (ctx: AccessContext) => ScopeMap\n\nexport type CrudOperation = 'list' | 'get' | 'create' | 'update' | 'delete'\n\nexport type SortOrder = 'asc' | 'desc'\n\nexport type DefaultSort = {\n column: string\n order: SortOrder\n}\n\nexport type TableAccessInput = {\n crud?: boolean\n /** Opt the BetterAuth `user` table into auto-CRUD (read profiles, owner-update image). */\n exposeAuthTable?: boolean\n ownerColumn?: string\n list?: OperationRule\n get?: OperationRule\n create?: OperationRule\n update?: OperationRule\n delete?: OperationRule\n /** Explicit write allowlist. Entries override matching system-readonly\n * defaults such as `updatedAt`; `id` remains immutable on update. */\n writableColumns?: string[]\n readonlyColumns?: string[]\n /** Columns matched by `?q=` on list — opt-in; omitted columns are never searched. */\n searchableColumns?: string[]\n /** Columns filterable via flat `?column=value` query params. */\n filterableColumns?: string[]\n /** Columns allowed in `?sort=`. Defaults to `['id']`. */\n sortableColumns?: string[]\n /** Default list ordering when `?sort` is omitted. Defaults to `{ column: 'id', order: 'desc' }`. */\n defaultSort?: DefaultSort\n scope?: {\n read?: ScopeResolver\n write?: ScopeResolver\n }\n}\n\nexport type ResolvedTableAccess = {\n tableKey: string\n tableName: string\n enabled: boolean\n ownerColumn?: string\n list: OperationRule\n get: OperationRule\n create: OperationRule\n update: OperationRule\n delete: OperationRule\n writableColumns?: string[]\n readonlyColumns: string[]\n searchableColumns?: string[]\n filterableColumns: string[]\n sortableColumns: string[]\n defaultSort: DefaultSort\n readScope?: ScopeResolver\n writeScope?: ScopeResolver\n}\n\nexport type ResolvedAccess = Map<string, ResolvedTableAccess>\n\n/**\n * Look up a table's resolved access by its physical table name.\n *\n * `ResolvedAccess` is keyed by schema export name, not table name, so every\n * consumer that starts from a physical name needs this scan. It lives here so\n * CRUD, realtime, and route validation cannot drift apart on which tables they\n * consider enabled.\n */\nexport function tableEntryForName(\n access: ResolvedAccess,\n tableName: string,\n): ResolvedTableAccess | undefined {\n for (const entry of access.values()) {\n if (entry.tableName === tableName) return entry\n }\n return undefined\n}\n\nconst DEFAULT_READONLY = [\n 'id',\n 'createdAt',\n 'updatedAt',\n 'created_at',\n 'updated_at',\n]\n\nfunction getSchemaTables<TSchema extends Record<string, unknown>>(\n schema: TSchema,\n) {\n const tables: {\n key: string\n table: Parameters<typeof getTableName>[0]\n name: string\n columns: string[]\n }[] = []\n for (const [key, value] of Object.entries(schema)) {\n if (!isTable(value)) continue\n const name = getTableName(value)\n const columns = Object.keys(getTableColumns(value))\n tables.push({ key, table: value, name, columns })\n }\n return tables\n}\n\nfunction resolveListAccess(\n input: TableAccessInput,\n columns: string[],\n): Pick<\n ResolvedTableAccess,\n 'filterableColumns' | 'sortableColumns' | 'defaultSort'\n> {\n const sortableColumns =\n input.sortableColumns ?? (columns.includes('id') ? ['id'] : [])\n const defaultSort: DefaultSort = input.defaultSort ?? {\n column: sortableColumns[0] ?? 'id',\n order: 'desc',\n }\n\n if (!columns.includes(defaultSort.column)) {\n throw new Error(\n `[bunderstack] defaultSort.column \"${defaultSort.column}\" is not a column on this table`,\n )\n }\n if (!sortableColumns.includes(defaultSort.column)) {\n throw new Error(\n `[bunderstack] defaultSort.column \"${defaultSort.column}\" must be listed in sortableColumns`,\n )\n }\n\n const filterableColumns = input.filterableColumns ?? []\n for (const col of filterableColumns) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] filterableColumns references unknown column \"${col}\"`,\n )\n }\n }\n\n for (const col of sortableColumns) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] sortableColumns references unknown column \"${col}\"`,\n )\n }\n }\n\n return { filterableColumns, sortableColumns, defaultSort }\n}\n\nfunction resolveDefaults(\n input: TableAccessInput,\n ownerColumn: string | undefined,\n columns: string[],\n): Omit<ResolvedTableAccess, 'tableKey' | 'tableName' | 'enabled'> {\n const listAccess = resolveListAccess(input, columns)\n const explicitlyWritable = new Set(input.writableColumns ?? [])\n return {\n ownerColumn,\n list: input.list ?? 'public',\n get: input.get ?? 'public',\n create: input.create ?? 'public',\n update: input.update ?? (ownerColumn ? 'owner' : 'deny'),\n delete: input.delete ?? (ownerColumn ? 'owner' : 'deny'),\n writableColumns: input.writableColumns,\n readonlyColumns: [\n ...DEFAULT_READONLY.filter(\n (column) => column === 'id' || !explicitlyWritable.has(column),\n ),\n ...(input.readonlyColumns ?? []),\n ...(ownerColumn ? [ownerColumn] : []),\n ],\n searchableColumns: input.searchableColumns,\n readScope: input.scope?.read,\n writeScope: input.scope?.write,\n ...listAccess,\n }\n}\n\nfunction detectOwnerColumn(\n columns: string[],\n input?: TableAccessInput,\n): string | undefined {\n if (input?.ownerColumn) return input.ownerColumn\n if (columns.includes('userId')) return 'userId'\n return undefined\n}\n\nexport function validateAndResolveAccess<\n TSchema extends Record<string, unknown>,\n>(\n schema: TSchema,\n accessInput?: Record<string, TableAccessInput>,\n): ResolvedAccess {\n const tables = getSchemaTables(schema)\n const tableByKey = new Map(tables.map((t) => [t.key, t]))\n const resolved: ResolvedAccess = new Map()\n\n if (accessInput) {\n for (const key of Object.keys(accessInput)) {\n if (!tableByKey.has(key)) {\n throw new Error(\n `[bunderstack] access.${key} does not match any table in schema`,\n )\n }\n const tableName = tableByKey.get(key)!.name\n const input = accessInput[key]\n if (AUTH_TABLE_NAMES.has(tableName)) {\n if (input?.crud === false) continue\n if (!EXPOSEABLE_AUTH_TABLES.has(tableName) || !input?.exposeAuthTable) {\n throw new Error(\n `[bunderstack] access.${key} cannot target auth table \"${tableName}\" — use { crud: false } to silence, or exposeAuthTable on user`,\n )\n }\n }\n }\n }\n\n for (const { key, name, columns } of tables) {\n const input = accessInput?.[key]\n if (input?.crud === false) continue\n if (INTERNAL_TABLE_NAMES.has(name)) continue\n\n if (AUTH_TABLE_NAMES.has(name)) {\n if (!input?.exposeAuthTable || !EXPOSEABLE_AUTH_TABLES.has(name)) continue\n\n const ownerColumn = input.ownerColumn ?? 'id'\n if (!columns.includes(ownerColumn)) {\n throw new Error(\n `[bunderstack] access.${key}.ownerColumn \"${ownerColumn}\" is not a column on table \"${name}\"`,\n )\n }\n\n const defaults = resolveDefaults(\n {\n ...input,\n create: input.create ?? 'deny',\n delete: input.delete ?? 'deny',\n },\n ownerColumn,\n columns,\n )\n\n const existingReadonly = defaults.readonlyColumns.filter((col) =>\n columns.includes(col),\n )\n const resolvedReadonly = [...new Set(existingReadonly)]\n\n for (const col of [\n ...(defaults.writableColumns ?? []),\n ...(defaults.searchableColumns ?? []),\n ...defaults.filterableColumns,\n ...defaults.sortableColumns,\n ...resolvedReadonly,\n ]) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] access.${key} references unknown column \"${col}\" on table \"${name}\"`,\n )\n }\n }\n\n resolved.set(key, {\n tableKey: key,\n tableName: name,\n enabled: true,\n ...defaults,\n readonlyColumns: resolvedReadonly,\n })\n continue\n }\n\n const ownerColumn = detectOwnerColumn(columns, input)\n const hasExplicitRules = input !== undefined\n const hasConventionOwner =\n ownerColumn !== undefined &&\n input?.ownerColumn === undefined &&\n columns.includes('userId')\n\n if (!hasExplicitRules && !hasConventionOwner) continue\n if (\n !ownerColumn &&\n input?.crud !== true &&\n !input?.scope?.read &&\n !input?.scope?.write\n )\n continue\n\n if (input?.ownerColumn && !columns.includes(input.ownerColumn)) {\n throw new Error(\n `[bunderstack] access.${key}.ownerColumn \"${input.ownerColumn}\" is not a column on table \"${name}\"`,\n )\n }\n\n const defaults = resolveDefaults(input ?? {}, ownerColumn, columns)\n const existingReadonly = defaults.readonlyColumns.filter((col) =>\n columns.includes(col),\n )\n const resolvedReadonly = [...new Set(existingReadonly)]\n\n for (const col of [\n ...(defaults.writableColumns ?? []),\n ...(defaults.searchableColumns ?? []),\n ...defaults.filterableColumns,\n ...defaults.sortableColumns,\n ...resolvedReadonly,\n ]) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] access.${key} references unknown column \"${col}\" on table \"${name}\"`,\n )\n }\n }\n\n const needsOwner = [defaults.update, defaults.delete].some(\n (r) => r === 'owner',\n )\n if (needsOwner && !ownerColumn) {\n throw new Error(\n `[bunderstack] access.${key} requires ownerColumn for owner-based update/delete rules`,\n )\n }\n\n resolved.set(key, {\n tableKey: key,\n tableName: name,\n enabled: true,\n ...defaults,\n readonlyColumns: resolvedReadonly,\n })\n }\n\n return resolved\n}\n\nexport function defineAccess<\n TSchema extends Record<string, unknown>,\n const TRules extends Record<string, TableAccessInput>,\n>(schema: TSchema, rules: TRules): TRules {\n validateAndResolveAccess(schema, rules)\n return rules\n}\n\nexport function rowMatchesScope(\n row: Record<string, unknown>,\n scope: ScopeMap,\n): boolean {\n for (const [col, expected] of Object.entries(scope)) {\n const actual = row[col]\n if (actual == null) return false\n if (Array.isArray(expected)) {\n if (!expected.map(String).includes(String(actual))) return false\n } else if (String(actual) !== String(expected)) {\n return false\n }\n }\n return true\n}\n\nexport function stampScope(\n values: Record<string, unknown>,\n scope: ScopeMap,\n): Record<string, unknown> {\n const out = { ...values }\n for (const [col, expected] of Object.entries(scope)) {\n if (!Array.isArray(expected)) out[col] = expected\n }\n return out\n}\n\nexport function checkAccessSync(\n rule: Exclude<\n OperationRule,\n (ctx: AccessContext) => boolean | Promise<boolean>\n >,\n ctx: AccessContext,\n ownerColumn?: string,\n): { allowed: boolean } {\n if (rule === 'deny') return { allowed: false }\n if (rule === 'public') return { allowed: true }\n if (!ctx.user) return { allowed: false }\n if (rule === 'authenticated') return { allowed: true }\n if (rule === 'owner') {\n if (!ownerColumn) return { allowed: false }\n const owner = ctx.row?.[ownerColumn]\n return { allowed: owner != null && String(owner) === ctx.user.id }\n }\n return { allowed: false }\n}\n\nexport async function checkAccess(\n rule: OperationRule,\n ctx: AccessContext,\n ownerColumn?: string,\n): Promise<{ allowed: boolean; status: 401 | 403 }> {\n if (rule === 'deny') return { allowed: false, status: 403 }\n\n if (typeof rule === 'function') {\n return (await rule(ctx))\n ? { allowed: true, status: 403 }\n : { allowed: false, status: 403 }\n }\n\n if (rule === 'public') return { allowed: true, status: 403 }\n\n if (!ctx.user) return { allowed: false, status: 401 }\n\n if (rule === 'authenticated') return { allowed: true, status: 403 }\n\n if (rule === 'owner') {\n if (!ownerColumn) return { allowed: false, status: 403 }\n const rowOwner = ctx.row?.[ownerColumn] ?? ctx.body?.[ownerColumn]\n if (rowOwner == null) return { allowed: false, status: 403 }\n if (String(rowOwner) !== ctx.user.id) return { allowed: false, status: 403 }\n return { allowed: true, status: 403 }\n }\n\n return { allowed: false, status: 403 }\n}\n\nexport function sanitizeWriteBody(\n body: Record<string, unknown>,\n access: ResolvedTableAccess,\n mode: 'create' | 'update',\n userId: string | null,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const readonly = new Set(access.readonlyColumns)\n\n for (const [key, value] of Object.entries(body)) {\n // On create, allow client-supplied `id` even if it appears in readonlyColumns,\n // but still respect an explicit writableColumns allowlist if provided.\n if (mode === 'create' && key === 'id') {\n if (access.writableColumns && !access.writableColumns.includes(key))\n continue\n out[key] = value\n continue\n }\n if (readonly.has(key)) continue\n if (access.writableColumns && !access.writableColumns.includes(key))\n continue\n out[key] = value\n }\n\n if (mode === 'create' && access.ownerColumn) {\n out[access.ownerColumn] = userId ?? null\n }\n\n if (mode === 'update' && access.ownerColumn) {\n delete out[access.ownerColumn]\n }\n\n return out\n}\n\nexport type AuthSessionResolver = {\n api: {\n getSession: (opts: { headers: Headers }) => Promise<{\n user: { id: string; email: string; name?: string; role?: string } | null\n session?: { activeOrganizationId?: string | null } | null\n } | null>\n }\n}\n\nexport async function resolveAccessUser(\n auth: AuthSessionResolver | undefined,\n headers: Headers,\n): Promise<AccessUser | null> {\n if (!auth) return null\n const session = await auth.api.getSession({ headers })\n if (!session?.user) return null\n return {\n id: session.user.id,\n email: session.user.email,\n name: session.user.name,\n role: session.user.role,\n }\n}\n\nexport async function resolveSession(\n auth: AuthSessionResolver | undefined,\n headers: Headers,\n): Promise<{ user: AccessUser | null; activeOrganizationId: string | null }> {\n if (!auth) return { user: null, activeOrganizationId: null }\n const session = await auth.api.getSession({ headers })\n if (!session?.user) return { user: null, activeOrganizationId: null }\n return {\n user: {\n id: session.user.id,\n email: session.user.email,\n name: session.user.name,\n role: session.user.role,\n },\n activeOrganizationId: session.session?.activeOrganizationId ?? null,\n }\n}\n"]}
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTableColumns, getTableName, isTable } from 'drizzle-orm'\n\nimport { INTERNAL_TABLE_NAMES } from './internal-tables'\n\nexport const AUTH_TABLE_NAMES = new Set([\n 'user',\n 'session',\n 'account',\n 'verification',\n])\n\nconst EXPOSEABLE_AUTH_TABLES = new Set(['user'])\n\nexport type AccessUserBase = {\n id: string\n email: string\n emailVerified?: boolean\n name?: string\n role?: string\n}\n\nexport type SessionUserSource = {\n id: string\n email: string\n emailVerified?: boolean\n name?: string\n role?: string\n} & Record<string, unknown>\n\nexport type SessionUserConfig<\n TExtra extends Record<string, unknown> = Record<never, never>,\n> = {\n mapUser: (user: SessionUserSource) => TExtra\n}\n\nexport type SessionUserExtraOf<TSession> =\n TSession extends SessionUserConfig<infer TExtra>\n ? TExtra\n : Record<never, never>\n\nexport type AccessUser<\n TExtra extends Record<string, unknown> = Record<never, never>,\n> = AccessUserBase & Omit<TExtra, keyof AccessUserBase>\n\nexport function defineSessionUser<const TExtra extends Record<string, unknown>>(\n config: SessionUserConfig<TExtra>,\n): SessionUserConfig<TExtra> {\n return config\n}\n\nexport type AccessContext = {\n user: AccessUser | null\n request: Request\n row?: Record<string, unknown>\n body?: Record<string, unknown>\n session?: { activeOrganizationId: string | null } | null\n}\n\nexport type OperationRule =\n | 'public'\n | 'authenticated'\n | 'owner'\n | 'deny'\n | ((ctx: AccessContext) => boolean | Promise<boolean>)\n\nexport type ScopeMap = Record<string, string | string[]>\nexport type ScopeResolver = (ctx: AccessContext) => ScopeMap\n\nexport type CrudOperation = 'list' | 'get' | 'create' | 'update' | 'delete'\n\nexport type SortOrder = 'asc' | 'desc'\n\nexport type DefaultSort = {\n column: string\n order: SortOrder\n}\n\nexport type TableAccessInput = {\n crud?: boolean\n /** Opt the BetterAuth `user` table into auto-CRUD (read profiles, owner-update image). */\n exposeAuthTable?: boolean\n ownerColumn?: string\n list?: OperationRule\n get?: OperationRule\n create?: OperationRule\n update?: OperationRule\n delete?: OperationRule\n /** Explicit write allowlist. Entries override matching system-readonly\n * defaults such as `updatedAt`; `id` remains immutable on update. */\n writableColumns?: string[]\n readonlyColumns?: string[]\n /** Columns matched by `?q=` on list — opt-in; omitted columns are never searched. */\n searchableColumns?: string[]\n /** Columns filterable via flat `?column=value` query params. */\n filterableColumns?: string[]\n /** Columns allowed in `?sort=`. Defaults to `['id']`. */\n sortableColumns?: string[]\n /** Default list ordering when `?sort` is omitted. Defaults to `{ column: 'id', order: 'desc' }`. */\n defaultSort?: DefaultSort\n scope?: {\n read?: ScopeResolver\n write?: ScopeResolver\n }\n}\n\nexport type ResolvedTableAccess = {\n tableKey: string\n tableName: string\n enabled: boolean\n ownerColumn?: string\n list: OperationRule\n get: OperationRule\n create: OperationRule\n update: OperationRule\n delete: OperationRule\n writableColumns?: string[]\n readonlyColumns: string[]\n searchableColumns?: string[]\n filterableColumns: string[]\n sortableColumns: string[]\n defaultSort: DefaultSort\n readScope?: ScopeResolver\n writeScope?: ScopeResolver\n}\n\nexport type ResolvedAccess = Map<string, ResolvedTableAccess>\n\n/**\n * Look up a table's resolved access by its physical table name.\n *\n * `ResolvedAccess` is keyed by schema export name, not table name, so every\n * consumer that starts from a physical name needs this scan. It lives here so\n * CRUD, realtime, and route validation cannot drift apart on which tables they\n * consider enabled.\n */\nexport function tableEntryForName(\n access: ResolvedAccess,\n tableName: string,\n): ResolvedTableAccess | undefined {\n for (const entry of access.values()) {\n if (entry.tableName === tableName) return entry\n }\n return undefined\n}\n\nconst DEFAULT_READONLY = [\n 'id',\n 'createdAt',\n 'updatedAt',\n 'created_at',\n 'updated_at',\n]\n\nfunction getSchemaTables<TSchema extends Record<string, unknown>>(\n schema: TSchema,\n) {\n const tables: {\n key: string\n table: Parameters<typeof getTableName>[0]\n name: string\n columns: string[]\n }[] = []\n for (const [key, value] of Object.entries(schema)) {\n if (!isTable(value)) continue\n const name = getTableName(value)\n const columns = Object.keys(getTableColumns(value))\n tables.push({ key, table: value, name, columns })\n }\n return tables\n}\n\nfunction resolveListAccess(\n input: TableAccessInput,\n columns: string[],\n): Pick<\n ResolvedTableAccess,\n 'filterableColumns' | 'sortableColumns' | 'defaultSort'\n> {\n const sortableColumns =\n input.sortableColumns ?? (columns.includes('id') ? ['id'] : [])\n const defaultSort: DefaultSort = input.defaultSort ?? {\n column: sortableColumns[0] ?? 'id',\n order: 'desc',\n }\n\n if (!columns.includes(defaultSort.column)) {\n throw new Error(\n `[bunderstack] defaultSort.column \"${defaultSort.column}\" is not a column on this table`,\n )\n }\n if (!sortableColumns.includes(defaultSort.column)) {\n throw new Error(\n `[bunderstack] defaultSort.column \"${defaultSort.column}\" must be listed in sortableColumns`,\n )\n }\n\n const filterableColumns = input.filterableColumns ?? []\n for (const col of filterableColumns) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] filterableColumns references unknown column \"${col}\"`,\n )\n }\n }\n\n for (const col of sortableColumns) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] sortableColumns references unknown column \"${col}\"`,\n )\n }\n }\n\n return { filterableColumns, sortableColumns, defaultSort }\n}\n\nfunction resolveDefaults(\n input: TableAccessInput,\n ownerColumn: string | undefined,\n columns: string[],\n): Omit<ResolvedTableAccess, 'tableKey' | 'tableName' | 'enabled'> {\n const listAccess = resolveListAccess(input, columns)\n const explicitlyWritable = new Set(input.writableColumns ?? [])\n return {\n ownerColumn,\n list: input.list ?? 'public',\n get: input.get ?? 'public',\n create: input.create ?? 'public',\n update: input.update ?? (ownerColumn ? 'owner' : 'deny'),\n delete: input.delete ?? (ownerColumn ? 'owner' : 'deny'),\n writableColumns: input.writableColumns,\n readonlyColumns: [\n ...DEFAULT_READONLY.filter(\n (column) => column === 'id' || !explicitlyWritable.has(column),\n ),\n ...(input.readonlyColumns ?? []),\n ...(ownerColumn ? [ownerColumn] : []),\n ],\n searchableColumns: input.searchableColumns,\n readScope: input.scope?.read,\n writeScope: input.scope?.write,\n ...listAccess,\n }\n}\n\nfunction detectOwnerColumn(\n columns: string[],\n input?: TableAccessInput,\n): string | undefined {\n if (input?.ownerColumn) return input.ownerColumn\n if (columns.includes('userId')) return 'userId'\n return undefined\n}\n\nexport function validateAndResolveAccess<\n TSchema extends Record<string, unknown>,\n>(\n schema: TSchema,\n accessInput?: Record<string, TableAccessInput>,\n): ResolvedAccess {\n const tables = getSchemaTables(schema)\n const tableByKey = new Map(tables.map((t) => [t.key, t]))\n const resolved: ResolvedAccess = new Map()\n\n if (accessInput) {\n for (const key of Object.keys(accessInput)) {\n if (!tableByKey.has(key)) {\n throw new Error(\n `[bunderstack] access.${key} does not match any table in schema`,\n )\n }\n const tableName = tableByKey.get(key)!.name\n const input = accessInput[key]\n if (AUTH_TABLE_NAMES.has(tableName)) {\n if (input?.crud === false) continue\n if (!EXPOSEABLE_AUTH_TABLES.has(tableName) || !input?.exposeAuthTable) {\n throw new Error(\n `[bunderstack] access.${key} cannot target auth table \"${tableName}\" — use { crud: false } to silence, or exposeAuthTable on user`,\n )\n }\n }\n }\n }\n\n for (const { key, name, columns } of tables) {\n const input = accessInput?.[key]\n if (input?.crud === false) continue\n if (INTERNAL_TABLE_NAMES.has(name)) continue\n\n if (AUTH_TABLE_NAMES.has(name)) {\n if (!input?.exposeAuthTable || !EXPOSEABLE_AUTH_TABLES.has(name)) continue\n\n const ownerColumn = input.ownerColumn ?? 'id'\n if (!columns.includes(ownerColumn)) {\n throw new Error(\n `[bunderstack] access.${key}.ownerColumn \"${ownerColumn}\" is not a column on table \"${name}\"`,\n )\n }\n\n const defaults = resolveDefaults(\n {\n ...input,\n create: input.create ?? 'deny',\n delete: input.delete ?? 'deny',\n },\n ownerColumn,\n columns,\n )\n\n const existingReadonly = defaults.readonlyColumns.filter((col) =>\n columns.includes(col),\n )\n const resolvedReadonly = [...new Set(existingReadonly)]\n\n for (const col of [\n ...(defaults.writableColumns ?? []),\n ...(defaults.searchableColumns ?? []),\n ...defaults.filterableColumns,\n ...defaults.sortableColumns,\n ...resolvedReadonly,\n ]) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] access.${key} references unknown column \"${col}\" on table \"${name}\"`,\n )\n }\n }\n\n resolved.set(key, {\n tableKey: key,\n tableName: name,\n enabled: true,\n ...defaults,\n readonlyColumns: resolvedReadonly,\n })\n continue\n }\n\n const ownerColumn = detectOwnerColumn(columns, input)\n const hasExplicitRules = input !== undefined\n const hasConventionOwner =\n ownerColumn !== undefined &&\n input?.ownerColumn === undefined &&\n columns.includes('userId')\n\n if (!hasExplicitRules && !hasConventionOwner) continue\n if (\n !ownerColumn &&\n input?.crud !== true &&\n !input?.scope?.read &&\n !input?.scope?.write\n )\n continue\n\n if (input?.ownerColumn && !columns.includes(input.ownerColumn)) {\n throw new Error(\n `[bunderstack] access.${key}.ownerColumn \"${input.ownerColumn}\" is not a column on table \"${name}\"`,\n )\n }\n\n const defaults = resolveDefaults(input ?? {}, ownerColumn, columns)\n const existingReadonly = defaults.readonlyColumns.filter((col) =>\n columns.includes(col),\n )\n const resolvedReadonly = [...new Set(existingReadonly)]\n\n for (const col of [\n ...(defaults.writableColumns ?? []),\n ...(defaults.searchableColumns ?? []),\n ...defaults.filterableColumns,\n ...defaults.sortableColumns,\n ...resolvedReadonly,\n ]) {\n if (!columns.includes(col)) {\n throw new Error(\n `[bunderstack] access.${key} references unknown column \"${col}\" on table \"${name}\"`,\n )\n }\n }\n\n const needsOwner = [defaults.update, defaults.delete].some(\n (r) => r === 'owner',\n )\n if (needsOwner && !ownerColumn) {\n throw new Error(\n `[bunderstack] access.${key} requires ownerColumn for owner-based update/delete rules`,\n )\n }\n\n resolved.set(key, {\n tableKey: key,\n tableName: name,\n enabled: true,\n ...defaults,\n readonlyColumns: resolvedReadonly,\n })\n }\n\n return resolved\n}\n\nexport function defineAccess<\n TSchema extends Record<string, unknown>,\n const TRules extends Record<string, TableAccessInput>,\n>(schema: TSchema, rules: TRules): TRules {\n validateAndResolveAccess(schema, rules)\n return rules\n}\n\nexport function rowMatchesScope(\n row: Record<string, unknown>,\n scope: ScopeMap,\n): boolean {\n for (const [col, expected] of Object.entries(scope)) {\n const actual = row[col]\n if (actual == null) return false\n if (Array.isArray(expected)) {\n if (!expected.map(String).includes(String(actual))) return false\n } else if (String(actual) !== String(expected)) {\n return false\n }\n }\n return true\n}\n\nexport function stampScope(\n values: Record<string, unknown>,\n scope: ScopeMap,\n): Record<string, unknown> {\n const out = { ...values }\n for (const [col, expected] of Object.entries(scope)) {\n if (!Array.isArray(expected)) out[col] = expected\n }\n return out\n}\n\nexport function checkAccessSync(\n rule: Exclude<\n OperationRule,\n (ctx: AccessContext) => boolean | Promise<boolean>\n >,\n ctx: AccessContext,\n ownerColumn?: string,\n): { allowed: boolean } {\n if (rule === 'deny') return { allowed: false }\n if (rule === 'public') return { allowed: true }\n if (!ctx.user) return { allowed: false }\n if (rule === 'authenticated') return { allowed: true }\n if (rule === 'owner') {\n if (!ownerColumn) return { allowed: false }\n const owner = ctx.row?.[ownerColumn]\n return { allowed: owner != null && String(owner) === ctx.user.id }\n }\n return { allowed: false }\n}\n\nexport async function checkAccess(\n rule: OperationRule,\n ctx: AccessContext,\n ownerColumn?: string,\n): Promise<{ allowed: boolean; status: 401 | 403 }> {\n if (rule === 'deny') return { allowed: false, status: 403 }\n\n if (typeof rule === 'function') {\n return (await rule(ctx))\n ? { allowed: true, status: 403 }\n : { allowed: false, status: 403 }\n }\n\n if (rule === 'public') return { allowed: true, status: 403 }\n\n if (!ctx.user) return { allowed: false, status: 401 }\n\n if (rule === 'authenticated') return { allowed: true, status: 403 }\n\n if (rule === 'owner') {\n if (!ownerColumn) return { allowed: false, status: 403 }\n const rowOwner = ctx.row?.[ownerColumn] ?? ctx.body?.[ownerColumn]\n if (rowOwner == null) return { allowed: false, status: 403 }\n if (String(rowOwner) !== ctx.user.id) return { allowed: false, status: 403 }\n return { allowed: true, status: 403 }\n }\n\n return { allowed: false, status: 403 }\n}\n\nexport function sanitizeWriteBody(\n body: Record<string, unknown>,\n access: ResolvedTableAccess,\n mode: 'create' | 'update',\n userId: string | null,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const readonly = new Set(access.readonlyColumns)\n\n for (const [key, value] of Object.entries(body)) {\n // On create, allow client-supplied `id` even if it appears in readonlyColumns,\n // but still respect an explicit writableColumns allowlist if provided.\n if (mode === 'create' && key === 'id') {\n if (access.writableColumns && !access.writableColumns.includes(key))\n continue\n out[key] = value\n continue\n }\n if (readonly.has(key)) continue\n if (access.writableColumns && !access.writableColumns.includes(key))\n continue\n out[key] = value\n }\n\n if (mode === 'create' && access.ownerColumn) {\n out[access.ownerColumn] = userId ?? null\n }\n\n if (mode === 'update' && access.ownerColumn) {\n delete out[access.ownerColumn]\n }\n\n return out\n}\n\nexport type AuthSessionResolver<\n TExtra extends Record<string, unknown> = Record<never, never>,\n> = {\n api: {\n getSession: (opts: { headers: Headers }) => Promise<{\n user:\n | ({\n id: string\n email: string\n emailVerified?: boolean\n name?: string\n role?: string\n } & TExtra)\n | null\n session?: { activeOrganizationId?: string | null } | null\n } | null>\n }\n}\n\nexport async function resolveAccessUser<\n TExtra extends Record<string, unknown> = Record<never, never>,\n>(\n auth: AuthSessionResolver<TExtra> | undefined,\n headers: Headers,\n): Promise<AccessUser<TExtra> | null> {\n if (!auth) return null\n const session = await auth.api.getSession({ headers })\n if (!session?.user) return null\n const user = {\n ...session.user,\n id: session.user.id,\n email: session.user.email,\n emailVerified: session.user.emailVerified === true,\n name: session.user.name,\n role: session.user.role,\n }\n return user as AccessUser<TExtra>\n}\n\nexport async function resolveSession<\n TExtra extends Record<string, unknown> = Record<never, never>,\n>(\n auth: AuthSessionResolver<TExtra> | undefined,\n headers: Headers,\n): Promise<{\n user: AccessUser<TExtra> | null\n activeOrganizationId: string | null\n}> {\n if (!auth) return { user: null, activeOrganizationId: null }\n const session = await auth.api.getSession({ headers })\n if (!session?.user) return { user: null, activeOrganizationId: null }\n return {\n user: {\n ...session.user,\n id: session.user.id,\n email: session.user.email,\n emailVerified: session.user.emailVerified === true,\n name: session.user.name,\n role: session.user.role,\n },\n activeOrganizationId: session.session?.activeOrganizationId ?? null,\n }\n}\n"]}
@@ -1,11 +1,12 @@
1
1
  import { type AnyMiddleware, type AnyRouter, type Context, type Middleware } from '@orpc/server';
2
+ import type { SessionUserConfig, SessionUserExtraOf } from '../access.js';
2
3
  import type { EnvConfigInput, ValidatedEnv } from '../env.js';
3
4
  import type { MessagingConfig } from '../messaging/index.js';
4
5
  import type { ApiContext } from './context.js';
5
6
  import { BUNDERSTACK_ERRORS } from '../errors.js';
6
7
  export type { ProtectedContextAdditions } from './types.js';
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
+ export declare function createApiBuilder<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig, TSessionUser extends Record<string, unknown> = Record<never, never>>(): {
9
+ public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging, TSessionUser> & object, object, {
9
10
  readonly BAD_REQUEST: {
10
11
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
11
12
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -63,8 +64,8 @@ export declare function createApiBuilder<TSchema extends Record<string, unknown>
63
64
  }>;
64
65
  };
65
66
  }>;
66
- protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging> & object, Omit<object, "user" | "session"> & {
67
- user: import("..").AccessUser;
67
+ protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging, TSessionUser> & object, Omit<object, "user" | "session"> & {
68
+ user: import("..").AccessUser<TSessionUser>;
68
69
  session: {
69
70
  activeOrganizationId: string | null;
70
71
  };
@@ -126,7 +127,7 @@ export declare function createApiBuilder<TSchema extends Record<string, unknown>
126
127
  }>;
127
128
  };
128
129
  }>;
129
- webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging> & object, object, {
130
+ webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, TEnv, TMessaging, TSessionUser> & object, object, {
130
131
  readonly BAD_REQUEST: {
131
132
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
132
133
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -192,19 +193,20 @@ export declare function createApiBuilder<TSchema extends Record<string, unknown>
192
193
  * The annotation is explicit because the inferred `DecoratedMiddleware`
193
194
  * is internal to `@orpc/server` and cannot be named in the emitted types.
194
195
  */
195
- middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, TEnv, TMessaging>, TOutContext, unknown, unknown, typeof BUNDERSTACK_ERRORS>) => AnyMiddleware;
196
+ middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, TEnv, TMessaging, TSessionUser>, TOutContext, unknown, unknown, typeof BUNDERSTACK_ERRORS>) => AnyMiddleware;
196
197
  };
197
198
  /**
198
199
  * Same builder as `createApiBuilder`, but the generics come from the values an
199
200
  * application already has. It reads nothing at runtime, so a module can call it
200
201
  * at import time and export the bases that its router modules import.
201
202
  */
202
- export declare function defineApi<TSchema extends Record<string, unknown>, TEnv extends EnvConfigInput | undefined = undefined, TMessaging extends MessagingConfig = MessagingConfig>(_options: {
203
+ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv extends EnvConfigInput | undefined = undefined, TMessaging extends MessagingConfig = MessagingConfig, const TSession extends SessionUserConfig<Record<string, unknown>> | undefined = undefined>(_options: {
203
204
  schema: TSchema;
204
205
  env?: TEnv;
205
206
  messaging?: TMessaging;
207
+ session?: TSession;
206
208
  }): {
207
- public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging> & object, object, {
209
+ public: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging, SessionUserExtraOf<TSession>> & object, object, {
208
210
  readonly BAD_REQUEST: {
209
211
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
210
212
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -262,8 +264,8 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
262
264
  }>;
263
265
  };
264
266
  }>;
265
- protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging> & object, Omit<object, "user" | "session"> & {
266
- user: import("..").AccessUser;
267
+ protected: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging, SessionUserExtraOf<TSession>> & object, Omit<object, "user" | "session"> & {
268
+ user: import("..").AccessUser<SessionUserExtraOf<TSession>>;
267
269
  session: {
268
270
  activeOrganizationId: string | null;
269
271
  };
@@ -325,7 +327,7 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
325
327
  }>;
326
328
  };
327
329
  }>;
328
- webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging> & object, object, {
330
+ webhook: import("@orpc/server").BuilderWithMiddlewares<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging, SessionUserExtraOf<TSession>> & object, object, {
329
331
  readonly BAD_REQUEST: {
330
332
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
331
333
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -391,7 +393,7 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
391
393
  * The annotation is explicit because the inferred `DecoratedMiddleware`
392
394
  * is internal to `@orpc/server` and cannot be named in the emitted types.
393
395
  */
394
- middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging>, TOutContext, unknown, unknown, {
396
+ middleware: <TOutContext extends Context>(middleware: Middleware<ApiContext<TSchema, ValidatedEnv<TEnv>, TMessaging, SessionUserExtraOf<TSession>>, TOutContext, unknown, unknown, {
395
397
  readonly BAD_REQUEST: {
396
398
  readonly data: import("valibot").OptionalSchema<import("valibot").StrictObjectSchema<{
397
399
  readonly code: import("valibot").OptionalSchema<import("valibot").LiteralSchema<"BAD_REQUEST", undefined>, "BAD_REQUEST">;
@@ -450,6 +452,6 @@ export declare function defineApi<TSchema extends Record<string, unknown>, TEnv
450
452
  };
451
453
  }>) => AnyMiddleware;
452
454
  };
453
- export type BunderstackApiBuilder<TSchema extends Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig> = ReturnType<typeof createApiBuilder<TSchema, TEnv, TMessaging>>;
455
+ export type BunderstackApiBuilder<TSchema extends Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig, TSessionUser extends Record<string, unknown> = Record<never, never>> = ReturnType<typeof createApiBuilder<TSchema, TEnv, TMessaging, TSessionUser>>;
454
456
  export type ApiFactory<TSchema extends Record<string, unknown>, TEnv, TCustomApiRouter extends AnyRouter> = (builder: BunderstackApiBuilder<TSchema, TEnv>) => TCustomApiRouter;
455
457
  //# 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,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
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
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
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/api/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,EAAE,GAKH,MAAM,cAAc,CAAA;AAOrB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,WAAW,CAAA;AAGlB,MAAM,UAAU,gBAAgB;IAM9B,MAAM,IAAI,GAAG,EAAE;SACZ,QAAQ,EAAuD;SAC/D,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,CAOvB,QAKD;IACC,OAAO,gBAAgB,EAKpB,CAAA;AACL,CAAC","sourcesContent":["import {\n os,\n type AnyMiddleware,\n type AnyRouter,\n type Context,\n type Middleware,\n} from '@orpc/server'\n\nimport type { SessionUserConfig, SessionUserExtraOf } from '../access'\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 TSessionUser extends Record<string, unknown> = Record<never, never>,\n>() {\n const base = os\n .$context<ApiContext<TSchema, TEnv, TMessaging, TSessionUser>>()\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, TSessionUser>,\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 const TSession extends\n | SessionUserConfig<Record<string, unknown>>\n | undefined = undefined,\n>(_options: {\n schema: TSchema\n env?: TEnv\n messaging?: TMessaging\n session?: TSession\n}) {\n return createApiBuilder<\n TSchema,\n ValidatedEnv<TEnv>,\n TMessaging,\n SessionUserExtraOf<TSession>\n >()\n}\n\nexport type BunderstackApiBuilder<\n TSchema extends Record<string, unknown>,\n TEnv = Record<string, unknown>,\n TMessaging extends MessagingConfig | undefined = MessagingConfig,\n TSessionUser extends Record<string, unknown> = Record<never, never>,\n> = ReturnType<typeof createApiBuilder<TSchema, TEnv, TMessaging, TSessionUser>>\n\nexport type ApiFactory<\n TSchema extends Record<string, unknown>,\n TEnv,\n TCustomApiRouter extends AnyRouter,\n> = (builder: BunderstackApiBuilder<TSchema, TEnv>) => TCustomApiRouter\n"]}
@@ -5,7 +5,7 @@ import type { BunderstackLogger } from '../logging.js';
5
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>, TMessaging extends MessagingConfig | undefined = MessagingConfig> {
8
+ export interface ApiContextDeps<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig, TSessionUser extends Record<string, unknown> = Record<never, never>> {
9
9
  db: DbFor<TSchema>;
10
10
  env: TEnv;
11
11
  storage: StorageFacade;
@@ -13,10 +13,10 @@ export interface ApiContextDeps<TSchema extends Record<string, unknown> = Record
13
13
  jobs: JobsRuntimeFacade;
14
14
  realtime: RealtimeFacade<TSchema>;
15
15
  auth: AuthInstance;
16
- authResolver?: AuthSessionResolver;
16
+ authResolver?: AuthSessionResolver<TSessionUser>;
17
17
  logger?: BunderstackLogger;
18
18
  }
19
- export interface ApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig> {
19
+ export interface ApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig, TSessionUser extends Record<string, unknown> = Record<never, never>> {
20
20
  db: DbFor<TSchema>;
21
21
  env: TEnv;
22
22
  storage: StorageFacade;
@@ -29,7 +29,7 @@ export interface ApiContext<TSchema extends Record<string, unknown> = Record<str
29
29
  resHeaders: Headers;
30
30
  getRawBody: () => Promise<string>;
31
31
  getSession: () => Promise<{
32
- user: AccessUser | null;
32
+ user: AccessUser<TSessionUser> | null;
33
33
  activeOrganizationId: string | null;
34
34
  }>;
35
35
  /**
@@ -39,9 +39,9 @@ export interface ApiContext<TSchema extends Record<string, unknown> = Record<str
39
39
  * Use it for observability only. Never use it for authorization.
40
40
  */
41
41
  peekSession: () => {
42
- user: AccessUser | null;
42
+ user: AccessUser<TSessionUser> | null;
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>, TMessaging extends MessagingConfig | undefined = MessagingConfig>(deps: ApiContextDeps<TSchema, TEnv, TMessaging>, request: Request): ApiContext<TSchema, TEnv, TMessaging>;
46
+ export declare function createApiContext<TSchema extends Record<string, unknown> = Record<string, unknown>, TEnv = Record<string, unknown>, TMessaging extends MessagingConfig | undefined = MessagingConfig, TSessionUser extends Record<string, unknown> = Record<never, never>>(deps: ApiContextDeps<TSchema, TEnv, TMessaging, TSessionUser>, request: Request): ApiContext<TSchema, TEnv, TMessaging, TSessionUser>;
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,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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"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"}
@@ -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;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"]}
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;AAsD1C,MAAM,UAAU,gBAAgB,CAM9B,IAA6D,EAC7D,OAAgB;IAEhB,uEAAuE;IACvE,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;IACtC,IAAI,cAA2C,CAAA;IAC/C,IAAI,cAKS,CAAA;IAEb,IAAI,cAKS,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 TSessionUser extends Record<string, unknown> = Record<never, never>,\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<TSessionUser>\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 TSessionUser extends Record<string, unknown> = Record<never, never>,\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<TSessionUser> | 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 | {\n user: AccessUser<TSessionUser> | null\n activeOrganizationId: string | null\n }\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 TSessionUser extends Record<string, unknown> = Record<never, never>,\n>(\n deps: ApiContextDeps<TSchema, TEnv, TMessaging, TSessionUser>,\n request: Request,\n): ApiContext<TSchema, TEnv, TMessaging, TSessionUser> {\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<{\n user: AccessUser<TSessionUser> | null\n activeOrganizationId: string | null\n }>\n | undefined\n\n let settledSession:\n | {\n user: AccessUser<TSessionUser> | null\n activeOrganizationId: string | null\n }\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>, import("..").MessagingConfig> & 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, Record<never, never>> & 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>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
133
+ get: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig, Record<never, never>> & 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>, import("..").MessagingConfig> & 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, Record<never, never>> & 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>, import("..").MessagingConfig> & object, object, v.GenericSchema<{
251
+ update: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig, Record<never, never>> & 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>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
313
+ delete: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<TSchema, Record<string, unknown>, import("..").MessagingConfig, Record<never, never>> & 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>, import("..").MessagingConfig> & 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, Record<never, never>> & 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>, import("..").MessagingConfig> & object, object, v.StrictObjectSchema<{
10
+ changes: import("@orpc/server").DecoratedProcedure<import("./context.js").ApiContext<Record<string, unknown>, Record<string, unknown>, import("..").MessagingConfig, Record<never, never>> & 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;