UNPKG

@lokalise/api-contracts

Version:
123 lines (122 loc) 9.46 kB
import type { z } from 'zod/v4'; import type { CommonRouteDefinition, DeleteRouteDefinition, GetRouteDefinition, PayloadRouteDefinition } from '../apiContracts.ts'; import type { HttpStatusCode } from '../HttpStatusCodes.ts'; /** * Configuration for building a GET route. * GET routes have no request body and require method: 'get'. */ export type GetContractConfig<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = Omit<CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'> & { method: 'get'; requestBodySchema?: never; /** Discriminator to distinguish from SSE contracts in buildContract */ serverSentEventSchemas?: never; }; /** * Configuration for building a DELETE route. * DELETE routes have no request body and default to empty response expected. */ export type DeleteContractConfig<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = true, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = Omit<CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'> & { method: 'delete'; requestBodySchema?: never; /** Discriminator to distinguish from SSE contracts in buildContract */ serverSentEventSchemas?: never; }; /** * Configuration for building a payload route (POST, PUT, PATCH). * Payload routes require a request body and an explicit method. */ export type PayloadContractConfig<RequestBodySchema extends z.Schema | undefined = undefined, SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined> = CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode> & { method: 'post' | 'put' | 'patch'; requestBodySchema: RequestBodySchema; /** Discriminator to distinguish from SSE contracts in buildContract */ serverSentEventSchemas?: never; }; /** * @deprecated Use `defineApiContract` instead. This function will be removed in a future version. * @example * ```typescript * // Before (deprecated): * const contract = buildRestContract({ * method: 'get', * pathResolver: (params) => `/users/${params.userId}`, * requestPathParamsSchema: z.object({ userId: z.string() }), * successResponseBodySchema: userSchema, * }) * * // After (recommended): * const contract = defineApiContract({ * method: 'get', * pathResolver: ({ userId }) => `/users/${userId}`, * requestPathParamsSchema: z.object({ userId: z.string() }), * responsesByStatusCode: { 200: userSchema }, * }) * ``` * * Builds REST API contracts with automatic type inference. * * This unified builder replaces the individual `buildGetRoute`, `buildPayloadRoute`, * and `buildDeleteRoute` functions, providing a single entry point for all REST contracts. * * The contract type is automatically determined based on the configuration: * * | `method` | `requestBodySchema` | Result | * |----------|---------------------|--------| * | `'get'` | ❌ | GET route | * | `'delete'` | ❌ | DELETE route | * | `'post'`/`'put'`/`'patch'` | ✅ | Payload route | * * @example * ```typescript * // GET route - method: 'get' is required * const getUsers = buildRestContract({ * method: 'get', * pathResolver: () => '/api/users', * successResponseBodySchema: z.array(userSchema), * }) * * // GET route with path params * const getUser = buildRestContract({ * method: 'get', * pathResolver: (params) => `/api/users/${params.userId}`, * requestPathParamsSchema: z.object({ userId: z.string() }), * successResponseBodySchema: userSchema, * }) * * // POST route - requires method and requestBodySchema * const createUser = buildRestContract({ * method: 'post', * pathResolver: () => '/api/users', * requestBodySchema: createUserSchema, * successResponseBodySchema: userSchema, * }) * * // PUT route * const updateUser = buildRestContract({ * method: 'put', * pathResolver: (params) => `/api/users/${params.userId}`, * requestPathParamsSchema: z.object({ userId: z.string() }), * requestBodySchema: updateUserSchema, * successResponseBodySchema: userSchema, * }) * * // PATCH route * const patchUser = buildRestContract({ * method: 'patch', * pathResolver: (params) => `/api/users/${params.userId}`, * requestPathParamsSchema: z.object({ userId: z.string() }), * requestBodySchema: patchUserSchema, * successResponseBodySchema: userSchema, * }) * * // DELETE route - method is 'delete', no body * const deleteUser = buildRestContract({ * method: 'delete', * pathResolver: (params) => `/api/users/${params.userId}`, * requestPathParamsSchema: z.object({ userId: z.string() }), * successResponseBodySchema: z.undefined(), * }) * ``` */ export declare function buildRestContract<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: GetContractConfig<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): GetRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>; export declare function buildRestContract<SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = true, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: DeleteContractConfig<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): DeleteRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>; export declare function buildRestContract<RequestBodySchema extends z.Schema | undefined = undefined, SuccessResponseBodySchema extends z.Schema | undefined = undefined, PathParamsSchema extends z.Schema | undefined = undefined, RequestQuerySchema extends z.Schema | undefined = undefined, RequestHeaderSchema extends z.Schema | undefined = undefined, ResponseHeaderSchema extends z.Schema | undefined = undefined, IsNonJSONResponseExpected extends boolean = false, IsEmptyResponseExpected extends boolean = false, ResponseSchemasByStatusCode extends Partial<Record<HttpStatusCode, z.Schema>> | undefined = undefined>(config: PayloadContractConfig<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>): PayloadRouteDefinition<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;