Generate TypeScript API clients from OpenAPI/Swagger specifications with support for Fetch and Axios HTTP clients
—
Comprehensive configuration options for customizing the API generation process, including input/output settings, type generation options, naming conventions, and advanced customization hooks.
// Local file input
interface GenerateApiParamsFromPath {
/** Path to local OpenAPI schema file */
input: string;
// ... other config options
}
// Remote URL input
interface GenerateApiParamsFromUrl {
/** URL to remote OpenAPI schema */
url: string;
/** Optional authorization token for private schemas */
authorizationToken?: string;
/** Request options for schema fetching */
requestOptions?: Partial<RequestInit>;
// ... other config options
}
// Direct spec object input
interface GenerateApiParamsFromSpecLiteral {
/** OpenAPI specification object */
spec: import("swagger-schema-official").Spec;
// ... other config options
}interface OutputConfig {
/** Output directory path or false to skip file writing */
output: string | false;
/** Generated file name (default: "Api.ts") */
fileName: string;
/** Clean output directory before generation */
cleanOutput: boolean;
/** Generate JavaScript with declaration files */
toJS: boolean;
/** Generate separate files for different components */
modular: boolean;
}Usage Examples:
// Write to disk
const result = await generateApi({
input: "./openapi.json",
output: "./src/generated",
fileName: "ApiClient.ts",
cleanOutput: true
});
// Keep in memory only
const result = await generateApi({
input: "./openapi.json",
output: false // Files available in result.files
});
// Generate JavaScript
const result = await generateApi({
input: "./openapi.json",
output: "./dist",
toJS: true,
fileName: "ApiClient.js"
});interface HttpClientConfig {
/** HTTP client type: "fetch" | "axios" */
httpClientType: "fetch" | "axios";
/** Allow HttpClient instance in API constructor */
singleHttpClient: boolean;
/** Don't throw errors on non-successful responses */
disableThrowOnError: boolean;
/** Unwrap data item from response */
unwrapResponseData: boolean;
}Usage Examples:
// Fetch client with custom error handling
const result = await generateApi({
input: "./openapi.json",
httpClientType: "fetch",
disableThrowOnError: true,
unwrapResponseData: true
});
// Axios client with single instance support
const result = await generateApi({
input: "./openapi.json",
httpClientType: "axios",
singleHttpClient: true
});interface GenerationFlags {
/** Generate API client class */
generateClient: boolean;
/** Generate response type definitions */
generateResponses: boolean;
/** Generate route type definitions */
generateRouteTypes: boolean;
/** Use "default" response as success response */
defaultResponseAsSuccess: boolean;
/** Default type for empty response schemas */
defaultResponseType: string;
}interface TypeGenerationConfig {
/** Generate readonly properties */
addReadonly: boolean;
/** Use Array<Type> instead of Type[] */
anotherArrayType: boolean;
/** Generate union enums (T1 | T2) instead of enum construct */
generateUnionEnums: boolean;
/** Use x-enumNames as enum values */
enumNamesAsValues: boolean;
}interface ExtractionConfig {
/** Extract request body types to data contracts */
extractRequestBody: boolean;
/** Extract response body types to data contracts */
extractResponseBody: boolean;
/** Extract response error types to data contracts */
extractResponseError: boolean;
/** Extract request parameters to data contracts */
extractRequestParams: boolean;
/** Extract all enums to TypeScript enum construction */
extractEnums: boolean;
/** Extract all responses from /components/responses */
extractResponses: boolean;
}Usage Examples:
// Full type extraction
const result = await generateApi({
input: "./openapi.json",
extractRequestBody: true,
extractResponseBody: true,
extractResponseError: true,
extractEnums: true,
addReadonly: true
});
// Union types instead of enums
const result = await generateApi({
input: "./openapi.json",
generateUnionEnums: true,
enumNamesAsValues: true
});interface NamingConfig {
/** Name of the main API class */
apiClassName: string;
/** Prefix for generated type names */
typePrefix: string;
/** Suffix for generated type names */
typeSuffix: string;
/** Prefix for enum keys */
enumKeyPrefix: string;
/** Suffix for enum keys */
enumKeySuffix: string;
/** Prefix for invalid type names */
fixInvalidTypeNamePrefix: string;
/** Prefix for invalid enum keys */
fixInvalidEnumKeyPrefix: string;
}interface OrganizationConfig {
/** Path index for route module separation */
moduleNameIndex: number;
/** Use first tag for module names */
moduleNameFirstTag: boolean;
/** Sort data contracts alphabetically */
sortTypes: boolean;
/** Sort routes alphabetically */
sortRoutes: boolean;
}Usage Examples:
// Custom naming
const result = await generateApi({
input: "./openapi.json",
apiClassName: "MyApiClient",
typePrefix: "API",
typeSuffix: "DTO",
sortTypes: true,
sortRoutes: true
});
// Module organization
const result = await generateApi({
input: "./openapi.json",
moduleNameFirstTag: true,
moduleNameIndex: 1,
modular: true
});interface TemplateConfig {
/** Path to custom templates directory */
templates: string;
/** Template file paths */
templatePaths: {
base: string;
default: string;
modular: string;
original: string;
custom: string | null;
};
}interface GenerateTemplatesParams {
/** Clean output folder before generation */
cleanOutput?: boolean;
/** Output directory for templates */
output?: string;
/** HTTP client type for templates */
httpClientType?: HttpClientType;
/** Generate modular template structure */
modular?: boolean;
/** Overwrite existing templates */
rewrite?: boolean;
/** Suppress output messages */
silent?: boolean;
/** Enable debug output */
debug?: boolean;
}Usage Examples:
// Custom templates
const result = await generateApi({
input: "./openapi.json",
templates: "./my-custom-templates"
});
// Generate custom templates
const templates = await generateTemplates({
output: "./templates",
httpClientType: "axios",
modular: true,
cleanOutput: true
});Hooks provide powerful customization points throughout the generation process:
const result = await generateApi({
input: "./openapi.json",
hooks: {
// Customize initialization
onInit: (config, codeGenProcess) => {
console.log("Starting generation with config:", config.fileName);
return config;
},
// Customize route processing
onCreateRoute: (routeData) => {
// Skip certain routes
if (routeData.raw.tags?.includes("internal")) {
return false; // Skip this route
}
// Modify route names
routeData.routeName.usage = routeData.routeName.usage.replace(/Api$/, "Service");
return routeData;
},
// Customize type names
onFormatTypeName: (typeName, rawTypeName, schemaType) => {
if (schemaType === "type-name") {
return typeName.endsWith("DTO") ? typeName : `${typeName}DTO`;
}
return typeName;
},
// Customize route names
onFormatRouteName: (routeInfo, templateRouteName) => {
return `${routeInfo.method.toLowerCase()}${templateRouteName}`;
},
// Customize schema parsing
onParseSchema: (originalSchema, parsedSchema) => {
// Add custom properties or modify parsed result
return parsedSchema;
},
// Customize components
onCreateComponent: (component) => {
// Modify component before processing
return component;
}
}
});const result = await generateApi({
input: "./openapi.json",
// Customize primitive type mappings
primitiveTypeConstructs: (struct) => ({
...struct,
string: {
...struct.string,
'date-time': () => 'Date', // Map date-time to Date instead of string
'uuid': () => 'string',
'email': () => 'string'
},
integer: () => 'number',
number: () => 'number'
}),
// Customize code generation constructs
codeGenConstructs: (struct) => ({
...struct,
Keyword: {
...struct.Keyword,
Any: 'unknown' // Use unknown instead of any
},
ArrayType: (content) => `ReadonlyArray<${content}>` // Make arrays readonly
})
});const result = await generateApi({
input: "./openapi.json",
schemaParsers: {
// Custom enum parser
enum: (schemaParserInput) => {
// Custom enum parsing logic
return customEnumParser(schemaParserInput);
},
// Custom object parser
object: (schemaParserInput) => {
// Custom object parsing logic
return customObjectParser(schemaParserInput);
}
}
});const result = await generateApi({
input: "./openapi.json",
extractingOptions: {
// Custom suffixes for extracted types
requestBodySuffix: ["Request", "Input", "Payload"],
responseBodySuffix: ["Response", "Output", "Result"],
responseErrorSuffix: ["Error", "ErrorResponse"],
enumSuffix: ["Enum", "Type"],
// Custom name resolvers
requestBodyNameResolver: (name, reservedNames) => {
return `${name}RequestBody`;
},
responseBodyNameResolver: (name, reservedNames) => {
return `${name}ResponseBody`;
},
enumNameResolver: (name, reservedNames) => {
return `${name}Enum`;
}
}
});interface DebugConfig {
/** Enable debug output */
debug: boolean;
/** Suppress all output except errors */
silent: boolean;
/** Fix small errors in swagger schema */
patch: boolean;
}Usage Examples:
// Debug mode
const result = await generateApi({
input: "./openapi.json",
debug: true,
patch: true
});
// Silent mode
const result = await generateApi({
input: "./openapi.json",
silent: true
});For complex configurations, create a dedicated configuration file:
// swagger-typescript-api.config.js
export default {
httpClientType: "axios",
generateResponses: true,
generateRouteTypes: true,
extractEnums: true,
sortTypes: true,
apiClassName: "ApiClient",
typePrefix: "API",
hooks: {
onFormatTypeName: (typeName) => {
return typeName.replace(/^API/, '').replace(/DTO$/, '');
},
onCreateRoute: (routeData) => {
// Skip deprecated routes
if (routeData.raw.deprecated) {
return false;
}
return routeData;
}
},
primitiveTypeConstructs: (struct) => ({
...struct,
string: {
...struct.string,
'date-time': () => 'Date',
'date': () => 'Date'
}
})
};Then use it in your generation:
import config from "./swagger-typescript-api.config.js";
const result = await generateApi({
input: "./openapi.json",
...config
});const DEFAULT_CONFIG = {
// Output
fileName: "Api.ts",
output: "./",
cleanOutput: false,
// Generation
generateClient: true,
generateResponses: false,
generateRouteTypes: false,
generateUnionEnums: false,
// HTTP Client
httpClientType: "fetch",
singleHttpClient: false,
disableThrowOnError: false,
// Types
addReadonly: false,
anotherArrayType: false,
extractEnums: false,
// Naming
apiClassName: "Api",
typePrefix: "",
typeSuffix: "",
// Processing
defaultResponseAsSuccess: false,
defaultResponseType: "void",
patch: false,
// Organization
moduleNameIndex: 0,
moduleNameFirstTag: false,
sortTypes: false,
sortRoutes: false,
// Debug
debug: false,
silent: false
};Install with Tessl CLI
npx tessl i tessl/npm-swagger-typescript-api