/** * Core Public Endpoints Framework * DO NOT MODIFY THIS FILE - You may break the project functionality * * This module provides the infrastructure for exposing public API endpoints * that external systems can consume with API key authentication or public access. */ import { type Env } from './core-utils'; import { z } from 'zod'; import type { Hono } from 'hono'; type ZodSchema = z.ZodType; /** * Authentication requirement declared by an endpoint definition. */ export type EndpointAuthType = 'apiKey' | 'public'; /** * Caller principal type resolved by the platform and passed via the * `X-Public-Endpoint-Auth-Type` header. `user`, `workspace_key` and `app` are * authenticated principals the platform has already authorized; `api_key` * additionally carries a validated key id; `none` is unauthenticated. * * `app` means a sibling app in the same workspace called this endpoint through * the platform (see `callAppEndpoint`). The platform records which app made the * call, but does not forward that id here: it is self-asserted by the caller and * must not be used for authorization until app identity is verifiable. */ export type EndpointPrincipalType = 'none' | 'api_key' | 'workspace_key' | 'user' | 'app'; /** * HTTP methods supported by endpoints */ export type EndpointMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; /** * Schema definition for endpoint validation */ export interface EndpointSchema { /** Query parameters schema */ query?: ZodSchema; /** Request body schema (for POST/PUT/PATCH) */ body?: ZodSchema; /** Response schema for documentation */ response?: ZodSchema; } /** * Context provided to endpoint handlers */ export interface EndpointContext, TBody = unknown> { /** Environment bindings */ env: Env; /** Original request object */ request: Request; /** Validated query parameters */ query: TQuery; /** Validated request body (null for GET/DELETE) */ body: TBody | null; /** Path parameters extracted from URL */ params: Record; /** Authentication information */ auth: EndpointAuthInfo; /** Request headers */ headers: Headers; /** Logger for endpoint operations */ logger: EndpointLogger; } /** * Authentication information passed to handlers */ export interface EndpointAuthInfo { /** Authentication requirement declared by the endpoint */ type: EndpointAuthType; /** Resolved caller principal type (api_key, workspace_key, user, app, none) */ principalType?: EndpointPrincipalType; /** API key ID (if authenticated with an API key) */ apiKeyId?: string; /** User ID (if authenticated as a workspace member) */ userId?: string; /** Scopes granted to the API key */ scopes?: string[]; /** Whether request is authenticated */ authenticated: boolean; } /** * Logger for endpoint operations */ export interface EndpointLogger { info(message: string, data?: Record): void; warn(message: string, data?: Record): void; error(message: string, data?: Record): void; } /** * Metadata for endpoint documentation */ export interface EndpointMeta { /** Human-readable description */ description?: string; /** Tags for grouping in documentation */ tags?: string[]; /** Deprecated flag */ deprecated?: boolean; /** Deprecation message */ deprecationMessage?: string; } /** * Public endpoint definition */ export interface EndpointDefinition, TBody = unknown, TResponse = unknown> { /** URL path (e.g., '/v1/todos', '/users/:id') */ path: string; /** HTTP method */ method: EndpointMethod; /** Authentication requirement */ auth: EndpointAuthType; /** Validation schemas */ schema?: EndpointSchema; /** Request handler */ handler: EndpointHandler; /** Endpoint metadata for documentation */ meta?: EndpointMeta; } /** * Endpoint handler function type */ export type EndpointHandler, TBody = unknown, TResponse = unknown> = (ctx: EndpointContext) => Promise; /** Type guard to distinguish EndpointDefinition from function-based route registrars */ export declare function isEndpointDefinition(entry: unknown): entry is EndpointDefinition; /** * Internal: Parsed endpoint info from request headers */ export interface ParsedEndpointRequest { endpointId: string; appId: string; authType: EndpointPrincipalType; apiKeyId?: string; userId?: string; scopes?: string[]; } /** * Create a JSON response */ export declare function jsonResponse(data: T, status?: number): Response; /** * Create an error response */ export declare function errorResponse(message: string, status?: number, code?: string): Response; /** * Convert Zod schema to JSON Schema for documentation * This is a simplified conversion that handles common cases */ export declare function zodToJsonSchema(schema: ZodSchema | undefined): Record | undefined; /** * Endpoint router that matches requests to handlers */ export declare class EndpointRouter { private endpoints; /** * Register endpoints */ register(endpoints: EndpointDefinition[]): void; /** * Find endpoint matching the request */ findEndpoint(method: string, path: string): { endpoint: EndpointDefinition; params: Record; } | null; /** * Get all registered endpoints for documentation */ getAllEndpoints(): EndpointDefinition[]; } /** * Mount an EndpointDefinition as a native Hono route. * * Registers the endpoint at its natural path using the correct HTTP method, * with Zod validation for query/body schemas and full EndpointContext support. * This allows EndpointDefinition entries in APP_ROUTES to work as first-class * Hono routes with middleware, streaming, and WebSocket support intact. */ export declare function mountEndpointAsHonoRoute(app: Hono<{ Bindings: Env; }>, endpoint: EndpointDefinition): void; /** * Handle an incoming public endpoint request. * Called by the platform when routing requests to the app. */ export declare function handleEndpointRequest(request: Request, env: Env, endpoints: EndpointDefinition[]): Promise; /** * Custom error for endpoint handlers * Use this to return specific HTTP status codes */ export declare class EndpointError extends Error { status: number; code?: string | undefined; constructor(message: string, status?: number, code?: string | undefined); static badRequest(message: string): EndpointError; static unauthorized(message?: string): EndpointError; static forbidden(message?: string): EndpointError; static notFound(message?: string): EndpointError; static conflict(message: string): EndpointError; } /** * Convert endpoint definition to registration data for workspace */ export declare function endpointToRegistration(endpoint: EndpointDefinition): { path: string; method: EndpointMethod; auth: EndpointAuthType; description?: string; tags?: string[]; schema?: { query?: Record; body?: Record; response?: Record; }; }; export {};