/** * SvelteKit Adapter for smrt-tenancy * * Provides a SvelteKit Handle that sets up tenant context for each request. * * @example * ```typescript * // hooks.server.ts * import { createSvelteKitHandle } from '@happyvertical/smrt-tenancy/adapters'; * * export const handle = createSvelteKitHandle({ * resolveTenantId: async (event) => { * // From subdomain * const host = event.request.headers.get('host'); * const subdomain = host?.split('.')[0]; * return subdomain; * * // Or from header * // return event.request.headers.get('x-tenant-id'); * * // Or from cookie * // return event.cookies.get('tenant_id'); * } * }); * ``` */ /** * SvelteKit RequestEvent (minimal interface to avoid direct dependency) */ interface SvelteKitEvent { request: Request; url: URL; cookies: { get(name: string): string | undefined; set(name: string, value: string, opts?: unknown): void; }; locals: Record; } /** * SvelteKit resolve function */ type SvelteKitResolve = (event: SvelteKitEvent) => Promise; /** * Configuration options for the SvelteKit tenancy handle created by * `createSvelteKitHandle()`. * * Only `resolveTenantId` is required; all other fields are optional callbacks * used to enrich the context or customise missing-tenant behaviour. * * @see createSvelteKitHandle */ export interface SvelteKitHandleOptions { /** * Resolve tenant ID from the request * * Return the tenant ID string, or null/undefined if no tenant context should be set. */ resolveTenantId: (event: SvelteKitEvent) => Promise | string | null | undefined; /** * Resolve user ID from the request (optional) */ resolveUserId?: (event: SvelteKitEvent) => Promise | string | null | undefined; /** * Resolve permissions for the user in this tenant (optional) */ resolvePermissions?: (event: SvelteKitEvent, tenantId: string, userId?: string) => Promise> | Set; /** * Check if user is a super admin (optional) * If true and super admin bypass is enabled on the class, tenant filtering is skipped. */ isSuperAdmin?: (event: SvelteKitEvent, tenantId: string, userId?: string) => Promise | boolean; /** * Called when no tenant ID could be resolved * Return a Response to short-circuit, or undefined to continue without tenant context. */ onNoTenant?: (event: SvelteKitEvent) => Promise | Response | undefined; /** * Paths to exclude from tenant context (e.g., public APIs, health checks) * Supports glob patterns. */ excludePaths?: string[]; } /** * Create a SvelteKit `Handle` function that establishes tenant context for * every server-side request. * * The returned handle wraps the `resolve` call in `withTenant()` so that all * server-side load functions, API routes, and `+server.ts` handlers within the * request share the same tenant context via `AsyncLocalStorage`. * * The resolved context is also stored in `event.locals` under two keys: * - `event.locals.tenantContext` — full `TenantContextData` * - `event.locals.tenantId` — string tenant ID shortcut * * When no tenant ID can be resolved (and no custom `onNoTenant` handler * returns a `Response`), the request continues without any tenant context. * * @param options - Configuration options including the required * `resolveTenantId` callback. * @returns A SvelteKit `Handle` function suitable for use in `hooks.server.ts`. * * @example * ```typescript * // src/hooks.server.ts * import { createSvelteKitHandle } from '@happyvertical/smrt-tenancy/adapters'; * * export const handle = createSvelteKitHandle({ * resolveTenantId: (event) => * event.request.headers.get('x-tenant-id'), * onNoTenant: () => * new Response('Tenant required', { status: 400 }), * }); * ``` * * @see SvelteKitHandleOptions * @see createExpressMiddleware */ export declare function createSvelteKitHandle(options: SvelteKitHandleOptions): ({ event, resolve, }: { event: SvelteKitEvent; resolve: SvelteKitResolve; }) => Promise; export {}; //# sourceMappingURL=sveltekit.d.ts.map