Skip to content

Generators @kubb/plugin-oas

In Kubb, generators are functions that allow developers to hook into the framework’s file generation process to create, modify, or extend code automatically. Generators are central to Kubb’s workflow, enabling the automated generation of code such as API clients, React-Query hooks, TypeScript types, or other files based on specific input(Swagger and OpenAPI specifications).

To add extra code after a generated client with @kubb/plugin-client, you can either:

  • Use the footer option
  • Override the default generator of @kubb/plugin-client

TIP

Every plugin has the generators option but for the most basic generation you can use plugin-oas.

Generators can be used with the React renderer or you can define your own renderer and return an array of KubbFiles.

createGenerator

TIP

  • operations, operation and schema are all promises where you need to return an array of KubbFiles.
  • You can utilize this to access the name or any other property that is part of the generator.
typescript
export function createGenerator(parseOptions: GeneratorOptions): Generator {
  return parseOptions
}
typescript
export type Generator = GeneratorOptions
typescript
export type Generator = {
  name: string
  operations?: (this: GeneratorOptions, props: OperationsProps) => Promise<KubbFile.File[]>
  operation?: (this: GeneratorOptions, props: OperationProps) => Promise<KubbFile.File[]>
  schema?: (this: GeneratorOptions, props: SchemaProps) => Promise<KubbFile.File[]>
}

name

Define a name that could be used to identify your generator.

Type:string
Required:true

operations

This function will be called with all operations that are available in your Swagger/OpenAPI file.

Type:(this: GeneratorOptions, props: OperationsProps) => Promise<KubbFile.File[]>
Required:false

The following properties will be accessible when operations is being called:

PropertyDescriptionType
instanceThe OperationsGenerator instance, this class can be used to have full control over the Oas instance. Omit<OperationGenerator, 'build'>
optionsThe resolved options from a specific plugin.object
operationsAll Oas operations.Array<Operation>
operationsByMethodAn object that is grouped by HttpMethod and an object with value as { operation, schemas }.OperationsByMethod

operation

This function is called with one operation from your OpenAPI file. operation is almost the same as operations, with one difference: operation is called x times based on the operations array.

Type:(this: GeneratorOptions, props: OperationProps) => Promise<KubbFile.File[]>
Required:false

The following properties will be accessible when operation is being called:

PropertyDescriptionType
instanceThe OperationsGenerator instance, this class can be used to have full control over the Oas instance. Omit<OperationGenerator, 'build'>
optionsThe resolved options from a specific plugin.object
operationOne Oas operation.Operation

schema

This function is called with one schema, executed x times based on your OpenAPI file.

Type:(this: GeneratorOptions, props: SchemaProps) => Promise<KubbFile.File[]>
Required:false

The following properties will be accessible when schema is being called:

PropertyDescriptionType
instanceThe SchemaGenerator instance, this class can be used to have full control over the Oas instance. Omit<SchemaGenerator, 'build'>
optionsThe resolved options from a specific plugin.object
schemaOne Oas schema object{ name: string; tree: Array<Schema>; value: SchemaObject }

TIP

  • schema.name contains the name, see #components/schemas/Pet where name will be Pet.
  • schema.tree contains the AST code that is generated based on the provided Swagger/OpenAPI file.
  • schema.value contains the value of the schema, this is the original object without any transformations.

createReactGenerator

TIP

createGenerator is being used behind the scenes where we render the component and then search for all files and return that back to createGenerator.

typescript
export function createReactGenerator(parseOptions: ReactGeneratorOptions): Generator {
  return parseOptions
}
typescript
export type Generator = GeneratorOptions
typescript
export type Generator = {
  name: string
  Operations?: (this: ReactGeneratorOptions, props: OperationsProps) => FabricReactNode
  Operation?: (this: ReactGeneratorOptions, props: OperationProps) => FabricReactNode
  Schema?: (this: ReactGeneratorOptions, props: SchemaProps) => FabricReactNode
}

Operations

Same as operations with one difference is that the return type is a FabricReactNode instead of Promise<KubbFile.File>.

Operation

Same as operation, with one difference: the return type is a FabricReactNode instead of Promise<KubbFile.File>.

Schema

Same as schema, with one difference: the return type is a FabricReactNode instead of Promise<KubbFile.File>.

Examples

Create a file for every operationId with createGenerator

Expected result:

typescript
export const createPets = {
  method: 'get',
  url: '/pets'
}

Create your generator:

tsx
import { URLPath } from '@kubb/core'
import type { PluginClient } from '@kubb/plugin-client'
import { createGenerator } from '@kubb/plugin-oas/generators'

export const clientOperationGenerator = createGenerator<PluginClient>({
  name: 'client-operation',
  async operation({ operation, generator }) {
    const pluginKey = generator.context.plugin.key
    const name = generator.context.pluginManager.resolveName({
      name: operation.getOperationId(),
      pluginKey,
      type: 'function',
    })

    const client = {
      name,
      file: generator.context.pluginManager.getFile({
        name,
        extname: '.ts',
        pluginKey,
        options: { type: 'file', pluginKey },
      }),
    }

    return [
      {
        baseName: client.file.baseName,
        path: client.file.path,
        meta: client.file.meta,
        sources: [
          {
            value: `
          export const ${operation.getOperationId()} = {
            method: '${operation.method}',
            url: '${new URLPath(operation.path).URL}'
          }
        `,
          },
        ],
      },
    ]
  },
})

Use of the generator:

kubb.config.ts
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas({
      generators: [clientOperationGenerator] 
    }),
  ],
})

Create a file for every operationId with createReactGenerator

Expected result:

typescript
export const createPets = {
  method: 'get',
  url: '/pets'
}

Create your generator with @kubb/react-fabric:

tsx
import { URLPath } from '@kubb/core'
import { createReactGenerator } from '@kubb/plugin-oas/generators'
import { useOperationManager } from '@kubb/plugin-oas/hooks'
import { File } from '@kubb/react-fabric'
import React from 'react'

export const clientOperationGenerator = createReactGenerator({
  name: 'client-operation',
  Operation({ operation, generator }) {
    const { getName, getFile } = useOperationManager(generator)

    const client = {
      name: getName(operation, { type: 'function' }),
      file: getFile(operation),
    }

    return (
      <File baseName={client.file.baseName} path={client.file.path} meta={client.file.meta}>
        <File.Source>
          {`
          export const ${operation.getOperationId()} = {
            method: '${operation.method}',
            url: '${new URLPath(operation.path).URL}'
          }
        `}
        </File.Source>
      </File>
    )
  },
})

Use of the generator:

kubb.config.ts
typescript
import { defineConfig } from "@kubb/core"
import { pluginOas } from "@kubb/plugin-oas"

export default defineConfig({
  root: '.',
  input: {
    path: './petStore.yaml',
  },
  output: {
    path: './src/gen',
  },
  plugins: [
    pluginOas({
      generators: [clientOperationGenerator] 
    }),
  ],
})

More examples can be found as part of examples/generators.

Released under the MIT License.