@lokalise/api-contracts
Version:
123 lines (122 loc) • 9.46 kB
TypeScript
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>;