Translators
Translators are the code generation strategy system of @keq-request/cli, used to define the style and pattern for generating TypeScript code from OpenAPI documents. Through different Translators, you can generate API client code adapted for different frameworks.
What is a Translator
A Translator is an interface for organizing and applying a set of plugins (Plugins) to control how code is generated:
interface Translator {
apply(): Plugin[]
}Each Translator returns a set of plugins through its apply() method. These plugins are executed during the compilation process, ultimately generating code in a specific style.
Built-in Translators
MicroFunctionTranslator
MicroFunctionTranslator is the default translator, generating function-style API calling code. This style is concise, easy to use, and suitable for most scenarios.
Generated code example:
import { KeqRequest } from 'keq'
export const request = new KeqRequest()import { request } from './request'
// Generated function-style API
export function getCats<STATUS extends keyof GetCatsResponseBodies>(
args?: GetCatsRequestParameters
): Keq<GetCatsOperation<STATUS>> {
const req = request.get<GetCatsResponseBodies[STATUS]>("/api/cats")
if (args && "breed" in args) {
req.query("breed", args["breed"], { arrayFormat: "repeat" })
}
return req
}
getCats.pathname = '/api/cats'
getCats.method = 'get'Using the generated code:
import { getCats } from './apis/cat-service'
// Call the function directly to make a request
const response = await getCats({ breed: 'persian' })
console.log(response.data)IsolatedTranslator
IsolatedTranslator generates standalone operation files, where each file contains complete type declarations and request functions without relying on shared schema files. Ideal for incremental API generation. Each file is fully isolated, unaffected by shared schema changes or naming conflicts.
Generated code characteristics:
- Each operation file contains inline schema type declarations
- Each module has its own independent
KeqRequestinstance - No cross-file schema dependencies, can be used independently
Generated directory structure:
outdir/
├── cat-service/
│ ├── request.ts # Module-independent KeqRequest instance
│ └── operations/
│ ├── get-cats.ts # Complete operation file (types + function)
│ └── create-cat.ts
Generated code example:
// cat-service/request.ts
import { KeqRequest } from "keq"
export const request = new KeqRequest()// cat-service/operations/get-cats.ts
import { Keq } from "keq"
import type { KeqOperation, KeqPathParameterInit, KeqQueryInit } from "keq"
import { request } from "../request"
// Inline type declarations (no external schema files needed)
export interface GetCatsResponseBodies {
200: { id: string; name: string; breed: string }[]
}
export interface GetCatsRequestBodies {}
export type GetCatsRequestQuery = {
breed?: string
}
// ...other type declarations
export function getCats<STATUS extends keyof GetCatsResponseBodies>(
args?: GetCatsRequestParameters
): Keq<GetCatsOperation<STATUS>> {
const req = request.get<GetCatsResponseBodies[STATUS]>("/api/cats")
if (args && "breed" in args) {
req.query("breed", args["breed"], { arrayFormat: "repeat" })
}
return req
}
getCats.pathname = "/api/cats"
getCats.method = "get"Configuration example:
// .keqrc.ts
import { defineKeqConfig, IsolatedTranslator } from "@keq-request/cli"
export default defineKeqConfig({
outdir: "./src/apis",
modules: {
catService: "./cat-service-swagger.json",
},
translators: [new IsolatedTranslator()],
})Using the generated code:
import { getCats } from './apis/cat-service/operations/get-cats'
const response = await getCats({ breed: 'persian' })NestjsTranslator
NestjsTranslator generates module code deeply integrated with the NestJS framework, suitable for use in NestJS projects.
Generated code characteristics:
- NestJS service module definitions
- Dependency injection support
- Seamless integration with the NestJS ecosystem
Configuration example:
// .keqrc.ts
import { defineKeqConfig, NestjsTranslator } from "@keq-request/cli"
export default defineKeqConfig({
outdir: "./src/apis",
modules: {
catService: "./cat-service-swagger.json",
},
translators: [new NestjsTranslator()],
})Using the generated code:
import { Module } from '@nestjs/common'
import { CatServiceModule } from './apis/cat-service'
@Module({
imports: [CatServiceModule],
})
export class AppModule {}Configuring Translators
Basic Configuration
Specify the translator to use via the translators field in the configuration file:
// .keqrc.ts
import { defineKeqConfig, MicroFunctionTranslator } from "@keq-request/cli"
export default defineKeqConfig({
outdir: "./src/apis",
modules: {
catService: "./cat-service-swagger.json",
},
// Specify MicroFunctionTranslator
translators: [new MicroFunctionTranslator()],
})Default Value
If the translators field is not configured, the CLI defaults to MicroFunctionTranslator:
// The following two configurations are equivalent
export default defineKeqConfig({
// ...
})
export default defineKeqConfig({
// ...
translators: [new MicroFunctionTranslator()],
})Using Multiple Translators
You can configure multiple translators simultaneously (though this is uncommon):
import { defineKeqConfig, MicroFunctionTranslator, NestjsTranslator } from "@keq-request/cli"
export default defineKeqConfig({
outdir: "./src/apis",
modules: {
catService: "./cat-service-swagger.json",
},
// Use multiple translators simultaneously
translators: [
new MicroFunctionTranslator(),
new NestjsTranslator(),
],
})How It Works
How Translators work in the compilation process:
Configuration file (.keqrc.ts)
↓
Parse config, read translators
↓
Call apply() on each translator
↓
Get Plugin[] arrays and flatten
↓
Apply all plugins to the compiler
↓
Execute compilation process
↓
Generate code
Relationship Between Translators and Plugins
A Translator is essentially an organizer for Plugins:
- Translator: Defines the code generation strategy, returns a set of related Plugins
- Plugin: Executes specific code generation logic
For example, MicroFunctionTranslator internally uses two plugins:
class MicroFunctionTranslator implements Translator {
apply(): Plugin[] {
return [
new GenerateDeclarationPlugin(), // Generate type declarations
new GenerateMicroFunctionPlugin(), // Generate function code
]
}
}Custom Translators
If the built-in translators don't meet your needs, you can implement a custom translator:
// custom-translator.ts
import type { Translator, Plugin } from '@keq-request/cli'
import { GenerateDeclarationPlugin } from '@keq-request/cli'
export class CustomTranslator implements Translator {
apply(): Plugin[] {
return [
new GenerateDeclarationPlugin(),
new MyCustomPlugin(),
]
}
}
class MyCustomPlugin implements Plugin {
apply(compiler: Compiler): void {
// Register to various compiler hooks
compiler.hooks.compile.tap('MyCustomPlugin', (context) => {
// Custom code generation logic
})
}
}Then use it in your configuration:
// .keqrc.ts
import { defineKeqConfig } from "@keq-request/cli"
import { CustomTranslator } from "./custom-translator"
export default defineKeqConfig({
outdir: "./src/apis",
modules: {
catService: "./cat-service-swagger.json",
},
translators: [new CustomTranslator()],
})Choosing the Right Translator
| Translator | Use Case | Features |
|---|---|---|
| MicroFunctionTranslator | General projects, React, Vue, and other frontend frameworks | Function-style calls, concise and easy to use, default option |
| IsolatedTranslator | Incremental generation, fully isolated files | Each operation file is self-contained with types, no shared schema dependencies |
| NestjsTranslator | NestJS backend projects | Generates NestJS modules, supports dependency injection |
| Custom Translator | Special frameworks or custom needs | Fully customizable generation logic |
Summary
- Translators define the strategy for generating code from OpenAPI documents
- Built-in MicroFunctionTranslator (default), IsolatedTranslator, and NestjsTranslator cover most needs
- Specify which translator to use via the
translatorsfield in the configuration file - Implement custom translators to generate code for specific frameworks
- Translators complete code generation by organizing and applying a set of Plugins