@@ -7,9 +7,16 @@ import { match } from "ts-pattern";
77import { type } from "arktype" ;
88import { wrapWithQuotesIfNeeded } from "./string-utils.ts" ;
99
10+ // Default success status codes (2xx and 3xx ranges)
11+ export const DEFAULT_SUCCESS_STATUS_CODES = [
12+ 200 , 201 , 202 , 203 , 204 , 205 , 206 , 207 , 208 , 226 ,
13+ 300 , 301 , 302 , 303 , 304 , 305 , 306 , 307 , 308
14+ ] as const ;
15+
1016type GeneratorOptions = ReturnType < typeof mapOpenApiEndpoints > & {
1117 runtime ?: "none" | keyof typeof runtimeValidationGenerator ;
1218 schemasOnly ?: boolean ;
19+ successStatusCodes ?: readonly number [ ] ;
1320} ;
1421type GeneratorContext = Required < GeneratorOptions > ;
1522
@@ -60,7 +67,11 @@ const replacerByRuntime = {
6067} ;
6168
6269export const generateFile = ( options : GeneratorOptions ) => {
63- const ctx = { ...options , runtime : options . runtime ?? "none" } as GeneratorContext ;
70+ const ctx = {
71+ ...options ,
72+ runtime : options . runtime ?? "none" ,
73+ successStatusCodes : options . successStatusCodes ?? DEFAULT_SUCCESS_STATUS_CODES
74+ } as GeneratorContext ;
6475
6576 const schemaList = generateSchemaList ( ctx ) ;
6677 const endpointSchemaList = options . schemasOnly ? "" : generateEndpointSchemaList ( ctx ) ;
@@ -276,6 +287,13 @@ const generateApiClient = (ctx: GeneratorContext) => {
276287 const byMethods = groupBy ( endpointList , "method" ) ;
277288 const endpointSchemaList = generateEndpointByMethod ( ctx ) ;
278289
290+ // Generate the StatusCode type from the configured success status codes
291+ const generateStatusCodeType = ( statusCodes : readonly number [ ] ) => {
292+ return statusCodes . join ( " | " ) ;
293+ } ;
294+
295+ const statusCodeType = generateStatusCodeType ( ctx . successStatusCodes ) ;
296+
279297 const apiClientTypes = `
280298// <ApiClientTypes>
281299export type EndpointParameters = {
@@ -315,6 +333,9 @@ export type Endpoint<TConfig extends DefaultEndpoint = DefaultEndpoint> = {
315333
316334export type Fetcher = (method: Method, url: string, parameters?: EndpointParameters | undefined) => Promise<Response>;
317335
336+ // Status code type for success responses
337+ export type StatusCode = ${ statusCodeType } ;
338+
318339// Error handling types
319340export type ApiResponse<TSuccess, TAllResponses extends Record<string | number, unknown> = {}> =
320341 (keyof TAllResponses extends never
@@ -325,21 +346,21 @@ export type ApiResponse<TSuccess, TAllResponses extends Record<string | number,
325346 }
326347 : {
327348 [K in keyof TAllResponses]: K extends string
328- ? K extends \`\${infer StatusCode extends number}\`
329- ? StatusCode extends 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308
349+ ? K extends \`\${infer TStatusCode extends number}\`
350+ ? TStatusCode extends StatusCode
330351 ? {
331352 ok: true;
332- status: StatusCode ;
353+ status: TStatusCode ;
333354 data: TAllResponses[K];
334355 }
335356 : {
336357 ok: false;
337- status: StatusCode ;
358+ status: TStatusCode ;
338359 error: TAllResponses[K];
339360 }
340361 : never
341362 : K extends number
342- ? K extends 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308
363+ ? K extends StatusCode
343364 ? {
344365 ok: true;
345366 status: K;
0 commit comments