@lokalise/api-contracts
Version:
147 lines (146 loc) • 11.3 kB
TypeScript
import type { ZodSchema, z } from 'zod/v4';
import type { HttpStatusCode } from './HttpStatusCodes.ts';
import type { MayOmit } from './typeUtils.ts';
export type InferSchemaInput<T extends ZodSchema | undefined> = T extends ZodSchema ? z.input<T> : T extends undefined ? undefined : never;
export type InferSchemaOutput<T extends ZodSchema | undefined> = T extends ZodSchema ? z.infer<T> : T extends undefined ? undefined : never;
export type RoutePathResolver<PathParams> = (pathParams: PathParams) => string;
export interface CommonRouteDefinitionMetadata extends Record<string, unknown> {
}
/**
* Who a route is intended for.
*
* 'internal' marks routes (e.g. backend-for-frontend endpoints) that must not be part of
* the published API surface: OpenAPI generators exclude them from the generated document.
* It has no effect on runtime behavior — the route is registered and served as usual.
*/
export type RouteVisibility = 'public' | 'internal';
export type CommonRouteDefinition<ResponseBodySchema 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> = {
isNonJSONResponseExpected: IsNonJSONResponseExpected;
isEmptyResponseExpected: IsEmptyResponseExpected;
successResponseBodySchema: ResponseBodySchema;
requestQuerySchema?: RequestQuerySchema;
/**
* Schema for validating request headers.
* Used to define and validate headers that the client must send with the request.
*
* @example
* ```ts
* requestHeaderSchema: z.object({
* 'authorization': z.string(),
* 'x-api-key': z.string()
* })
* ```
*/
requestHeaderSchema?: RequestHeaderSchema;
/**
* Schema for validating response headers.
* Used to define and validate headers that the server will send in the response.
* This is useful for documenting expected response headers (e.g., rate limit headers,
* pagination headers, cache control headers) and can be used by clients to validate
* the response they receive.
*
* @example
* ```ts
* responseHeaderSchema: z.object({
* 'x-ratelimit-limit': z.string(),
* 'x-ratelimit-remaining': z.string(),
* 'x-ratelimit-reset': z.string()
* })
* ```
*/
responseHeaderSchema?: ResponseHeaderSchema;
pathResolver: RoutePathResolver<InferSchemaOutput<PathParamsSchema>>;
requestPathParamsSchema?: PathParamsSchema;
visibility: RouteVisibility;
responseSchemasByStatusCode?: ResponseSchemasByStatusCode;
metadata?: CommonRouteDefinitionMetadata;
description?: string;
summary?: string;
tags?: readonly string[];
};
export type PayloadRouteDefinition<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;
};
export type GetRouteDefinition<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: 'get';
};
export type DeleteRouteDefinition<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> = CommonRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode> & {
method: 'delete';
};
/**
* @deprecated Use `defineApiContract` instead. This function will be removed in a future version.
* @example
* ```typescript
* // Before (deprecated):
* const route = buildPayloadRoute({
* visibility: 'public',
* method: 'post',
* requestBodySchema: bodySchema,
* successResponseBodySchema: responseSchema,
* pathResolver: () => '/api/users',
* })
*
* // After (recommended):
* const route = defineApiContract({
* visibility: 'public',
* method: 'post',
* requestBodySchema: bodySchema,
* pathResolver: () => '/api/users',
* responsesByStatusCode: { 201: responseSchema },
* })
* ```
*/
export declare function buildPayloadRoute<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>(params: MayOmit<PayloadRouteDefinition<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'isEmptyResponseExpected' | 'isNonJSONResponseExpected'>): PayloadRouteDefinition<RequestBodySchema, SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
/**
* @deprecated Use `defineApiContract` instead. This function will be removed in a future version.
* @example
* ```typescript
* // Before (deprecated):
* const route = buildGetRoute({
* visibility: 'public',
* successResponseBodySchema: responseSchema,
* pathResolver: () => '/api/users',
* })
*
* // After (recommended):
* const route = defineApiContract({
* visibility: 'public',
* method: 'get',
* pathResolver: () => '/api/users',
* responsesByStatusCode: { 200: responseSchema },
* })
* ```
*/
export declare function buildGetRoute<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>(params: MayOmit<Omit<GetRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'>, 'isEmptyResponseExpected' | 'isNonJSONResponseExpected'>): GetRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
/**
* @deprecated Use `defineApiContract` instead. This function will be removed in a future version.
* @example
* ```typescript
* // Before (deprecated):
* const route = buildDeleteRoute({
* visibility: 'public',
* requestPathParamsSchema: z.object({ userId: z.string() }),
* pathResolver: (params) => `/api/users/${params.userId}`,
* })
*
* // After (recommended):
* const route = defineApiContract({
* visibility: 'public',
* method: 'delete',
* requestPathParamsSchema: z.object({ userId: z.string() }),
* pathResolver: ({ userId }) => `/api/users/${userId}`,
* responsesByStatusCode: { 204: noBodyResponse() },
* })
* ```
*/
export declare function buildDeleteRoute<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>(params: MayOmit<Omit<DeleteRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>, 'method'>, 'isEmptyResponseExpected' | 'isNonJSONResponseExpected'>): DeleteRouteDefinition<SuccessResponseBodySchema, PathParamsSchema, RequestQuerySchema, RequestHeaderSchema, ResponseHeaderSchema, IsNonJSONResponseExpected, IsEmptyResponseExpected, ResponseSchemasByStatusCode>;
/**
* @deprecated Use `mapApiContractToPath` instead.
* Maps a route definition to a path string of the format '/static-path-part/:path-param-value'.
*/
export declare function mapRouteToPath(routeDefinition: CommonRouteDefinition<any, any, any, any, any, any, any, any>): string;
/**
* @deprecated Use `describeApiContract` instead.
*/
export declare function describeContract(contract: PayloadRouteDefinition<any, any, any, any, any, any, any, any, any> | GetRouteDefinition<any, any, any, any, any, any, any, any> | DeleteRouteDefinition<any, any, any, any, any, any, any, any>): string;