Configuration
Config file
Create hono-takibi.config.ts and run the CLI with no arguments:
ts
import { defineConfig } from 'hono-takibi'
export default defineConfig({
input: 'openapi.yaml',
output: './src/routes.ts',
})input is a local document named by its extension (.yaml, .yml, .json, or .tsp for TypeSpec), or an http(s) URL with or without one: a remote document is read by its content.
sh
npx hono-takibish
yarn hono-takibish
pnpm hono-takibish
bunx hono-takibiEvery generator is opted in by adding its section to the config. See the full reference below.
To run a config file from another location, pass --config. Paths inside it still resolve against the current directory:
sh
npx hono-takibi --config config/api.config.tsWatch mode
sh
npx hono-takibi --watchReruns the config whenever the input documents or the config itself change, and keeps watching when a run fails. The whole directory of the input document is watched, so TypeSpec imports and external $ref files trigger a rerun too.
Prefer a Vite dev server? Use the Vite plugin instead.
Rules
- Every generator needs its own
output. Two generators writing to one file is an error. output(single file) androutes(split) are mutually exclusive. Same forcomponents.outputand the per-typecomponents.*sections.outputinlines the components its routes refer to.routesandwebhooksimport them instead, so every component kind the operations refer to needs an output that holds it:components.output, orcomponents.<kind>. Without one, generation fails naming the kind, rather than writing an import of a file that does not exist.- A
splitdirectory belongs to the generator: its.tsfiles are removed before each run. Keep hand-written code elsewhere. basePathmust start with/.client.importand everypackagemust be module specifiers.- Generated files import one another relatively, under
pathAliaswhen the target is in the directory of the app entry, and by the target'spackagefrom another package. A target in another package without apackageis an error. - The
clientblock needstemplate. rpcand the hooks need theclientblock: they import the generated client, relatively or byclient.packagefrom another package.
Full reference
ts
import { defineConfig } from 'hono-takibi'
export default defineConfig({
input: 'openapi.yaml',
output: './src/routes.ts', // single-file mode; with template.define, the app entry (an index.ts path, default ./src/index.ts)
basePath: '/api',
readonly: true,
// Import prefix the generated files of this package use for one another, `@/routes` instead
// of `../routes`. Map it in tsconfig (`"@/*": ["./src/*"]`). Files written into another
// package never use it.
pathAlias: '@/',
// format: {}, // oxfmt FormatConfig
template: {
routeHandler: false, // true: RouteHandler exports
define: false, // true: defineOpenAPIRoute output
split: false, // true: one exported group per first path segment
},
exportSchemas: true,
exportSchemasTypes: true,
exportResponses: true,
exportParameters: true,
exportParametersTypes: true,
exportExamples: true,
exportRequestBodies: true,
exportHeaders: true,
exportHeadersTypes: true,
exportSecuritySchemes: true,
exportLinks: true,
exportCallbacks: true,
exportPathItems: true,
exportMediaTypes: true,
exportMediaTypesTypes: true,
// How generated files import one another: relatively inside a package, under `pathAlias`
// when the target is in the directory of the app entry, and by `package` from another
// package (the nearest package.json above an output delimits its package).
routes: {
output: './src/routes',
split: true,
// package: '@packages/routes', // the name other packages import these routes by
},
webhooks: {
output: './src/webhooks',
split: true,
// package: '@packages/webhooks',
},
// `output` (single file) and the per-type fields below (split) are mutually exclusive.
// `exportTypes` applies only to schemas / parameters / headers / mediaTypes.
// `package` names the package an output is written into, for the files of other packages
// that import it; leave it out while everything is in one package.
components: {
output: './src/components/index.ts',
// package: '@packages/components', // when src/components is a package of its own
schemas: {
output: './src/schemas',
exportTypes: true,
split: true,
// package: '@packages/schemas',
},
responses: {
output: './src/responses',
split: true,
// package: '@packages/responses',
},
parameters: {
output: './src/parameters',
exportTypes: true,
split: true,
// package: '@packages/parameters',
},
examples: {
output: './src/examples',
split: true,
// package: '@packages/examples',
},
requestBodies: {
output: './src/requestBodies',
split: true,
// package: '@packages/requestBodies',
},
headers: {
output: './src/headers',
exportTypes: true,
split: true,
// package: '@packages/headers',
},
securitySchemes: {
output: './src/securitySchemes',
split: true,
// package: '@packages/securitySchemes',
},
links: {
output: './src/links',
split: true,
// package: '@packages/links',
},
callbacks: {
output: './src/callbacks',
split: true,
// package: '@packages/callbacks',
},
pathItems: {
output: './src/pathItems',
split: true,
// package: '@packages/pathItems',
},
mediaTypes: {
output: './src/mediaTypes',
exportTypes: true,
split: true,
// package: '@packages/mediaTypes',
},
},
type: {
output: './src/types.ts',
readonly: true,
},
// Hono client of the scaffolded app (needs `template`); `rpc` and the hooks import it.
client: {
output: './src/lib/client.ts',
baseUrl: '/', // same origin (default); from the environment: { env: 'VITE_API_URL' }, { env: 'API_URL', source: 'process.env' }, { env: 'API_URL', import: '@/env' }
// credentials: 'include', // send cookies to any origin: hc('/', { init: { credentials: 'include' } })
// import: '@packages/server', // monorepo: where the app's type comes from
// package: '@packages/client', // monorepo: what other packages import the client by
},
rpc: {
output: './src/rpc.ts',
parseResponse: true,
docs: false, // operation summary/description as JSDoc
},
swr: { output: './src/swr.ts' },
'tanstack-query': { output: './src/tanstack-query.ts' },
'preact-query': { output: './src/preact-query.ts' },
'solid-query': { output: './src/solid-query.ts' },
'vue-query': { output: './src/vue-query.ts' },
'svelte-query': { output: './src/svelte-query.ts' },
'angular-query': { output: './src/angular-query.ts' },
mock: {
output: './src/mock.ts',
useExamples: true, // true: response examples | 'all': also schema/property examples | false
locale: 'en',
seed: 42, // optional: same body per route on every request (snapshot-friendly)
delay: false,
arrayMin: 1,
arrayMax: 10,
},
docs: {
output: './docs/api.md',
entry: 'src/index.ts',
curl: false, // true: curl commands (requires baseUrl); false: hono request
baseUrl: 'http://localhost:3000',
},
})