/** * Core type definitions for the Superblocks SDK. * * This module provides the public types used to define TypeScript-based APIs. */ import type { z } from "zod"; import type { IntegrationRef, AnyIntegrationRef, IntegrationsMap } from "./integrations/declarations.js"; /** * Configuration for defining a TypeScript-based API. * * @template TInput - Zod schema type for input validation * @template TOutput - Zod schema type for output validation * @template TIntegrations - Record of integration declarations * * @example * ```typescript * import { api, z, postgres, slack } from '@superblocksteam/sdk-api'; * * const UserSchema = z.object({ * id: z.string(), * name: z.string(), * }); * * export default api({ * integrations: { * db: postgres('Production Postgres'), * notifier: slack('Ops Slack'), * }, * input: z.object({ userId: z.string() }), * output: z.object({ user: UserSchema }), * async run(ctx, { userId }) { * const users = await ctx.integrations.db.query( * 'SELECT * FROM users WHERE id = $1', * UserSchema, // Schema is REQUIRED * [userId] * ); * if (users.length === 0) { * throw new Error('User not found'); * } * const notifyResult = await ctx.integrations.notifier.apiRequest( * { method: 'POST', path: '/chat.postMessage', body: { channel: '#alerts', text: `Fetched user ${users[0].name}` } }, * { response: z.object({ channel: z.string(), ts: z.string() }) } * ); * if (!notifyResult.ok) { * throw new Error(`Slack API error: ${notifyResult.error}`); * } * return { user: users[0] }; * }, * }); * ``` */ export interface ApiConfig = Record> { /** * Name for this API. * * Used for identification in execution logs and debugging. */ name: string; /** * Plain-language summary of what this API does and which integrations it uses, * written for a non-technical audience. * * This field is auto-generated by the AI agent when creating or editing an API. */ description?: string; /** * Integration declarations for this API. * * Declare integrations upfront to enable type-safe access via `ctx.integrations` * and to allow the runtime to authenticate integrations before execution. * * @example * ```typescript * integrations: { * db: postgres('Production Postgres'), * cache: mongodb('Cache MongoDB'), * } * ``` */ integrations?: TIntegrations; /** Zod schema for input validation */ input: TInput; /** Zod schema for output validation */ output: TOutput; /** * The API implementation function. * * @param ctx - Execution context with access to integrations, logging, and environment * @param input - Validated input parameters (can be destructured) * @returns Promise resolving to the validated output */ run: (ctx: ApiContext, input: z.infer) => Promise>; } /** * User information extracted from the Superblocks JWT. * * This information is passed to the API context and is available * as `ctx.user` in API implementations. */ export interface ApiUser { /** Unique user identifier from JWT */ readonly userId: string; /** User's email address (if available) */ readonly email?: string; /** User's display name (if available) */ readonly name?: string; /** User's group memberships from JWT */ readonly groups: readonly string[]; /** Custom claims from JWT */ readonly customClaims: Readonly>; } /** * Execution context passed to the API run function. * * Provides access to integration clients, logging, environment variables, * and user information. * * @template TIntegrations - Record of integration declarations */ export interface ApiContext = Record> { /** * Typed integration clients declared in the API config. * * Access each integration by the name (key) you declared: `ctx.integrations.`. * Each client is fully typed based on the declaration function used. * * @example * ```typescript * // Given: integrations: { db: postgres('My Postgres'), notifier: slack('My Slack') } * * // ctx.integrations.db is PostgresClient * const users = await ctx.integrations.db.query('SELECT * FROM users', UserSchema); * * // ctx.integrations.notifier is SlackClient * const notifyResult = await ctx.integrations.notifier.apiRequest( * { method: 'POST', path: '/chat.postMessage', body: { channel: '#alerts', text: 'Hello!' } }, * { response: z.object({ channel: z.string(), ts: z.string() }) } * ); * if (!notifyResult.ok) { * throw new Error(`Slack API error: ${notifyResult.error}`); * } * ``` */ readonly integrations: IntegrationsMap; /** Logger for structured logging */ readonly log: Logger; /** Access to environment variables */ readonly env: Readonly>; /** * Canonical key of the requested data tag validated for this execution. * * This identifies the integration configuration in use, not a user's * environment entitlement. It is supplied by the Superblocks runtime and * cannot be selected through API input. It is undefined when no data tag was * resolved or on runtimes that predate data-tag context support; * authorization checks must deny access in those cases. */ readonly dataTag?: string; /** User information from the Superblocks JWT */ readonly user: ApiUser; } /** * Logger interface for API execution. * * All log methods accept an optional data object for structured logging. */ export interface Logger { /** Log an info message */ info(message: string, data?: Record): void; /** Log a warning message */ warn(message: string, data?: Record): void; /** Log an error message */ error(message: string, data?: Record): void; /** Log a debug message */ debug(message: string, data?: Record): void; } /** * Base interface for all integration clients. */ export interface BaseIntegrationClient { /** The integration name */ readonly name: string; /** The plugin type ID (e.g., 'postgres', 'slack') */ readonly pluginId: string; } export type { IntegrationRef, AnyIntegrationRef, IntegrationsMap }; //# sourceMappingURL=types.d.ts.map