Custom Pipeline

Pipeline is the core of genapi. You can create custom pipelines to fully control the API generation process.

Pipeline System

genapi's pipeline system consists of multiple stages:

config - Read and transform configuration

original - Get original data source

parser - Parse data source into data graph

compiler - Compile data into abstract syntax tree (AST)

generate - Generate code string

dest - Output files

Creating Custom Pipeline

import { defineConfig } from '@genapi/core'
import pipeline, { compiler, dest, generate, original } from '@genapi/pipeline'
import { axios } from '@genapi/presets'

export default defineConfig({
  preset: pipeline(
    // read config, convert to internal config, and provide default values
    config => axios.ts.config(config),
    // get data source
    configRead => original(configRead),
    // parse the data source as data graphs
    configRead => axios.ts.parser(configRead),
    // compile data and convert it into abstract syntax tree (AST)
    configRead => compiler(configRead),
    // generate code string
    configRead => generate(configRead),
    // use outputs to output files
    configRead => dest(configRead),
  ),
})

Custom Parser

You can replace any stage. For the parser stage, use a preset's parser (e.g. axios.ts.parser) or build your own with createParser from @genapi/parser:

import { defineConfig } from '@genapi/core'
import pipeline, { compiler, dest, generate, original } from '@genapi/pipeline'
import { axios } from '@genapi/presets'

export default defineConfig({
  preset: pipeline(
    config => axios.ts.config(config),
    configRead => original(configRead),
    configRead => axios.ts.parser(configRead), // or your custom parser
    configRead => compiler(configRead),
    configRead => generate(configRead),
    configRead => dest(configRead),
  ),
})

Custom Generator

You can wrap or replace the generate stage:

import { defineConfig } from '@genapi/core'
import pipeline, { compiler, dest, generate, original } from '@genapi/pipeline'
import { axios } from '@genapi/presets'

function customGenerate(configRead) {
  // Customize then call default generate
  return generate(configRead)
}

export default defineConfig({
  preset: pipeline(
    config => axios.ts.config(config),
    configRead => original(configRead),
    configRead => axios.ts.parser(configRead),
    configRead => compiler(configRead),
    configRead => customGenerate(configRead),
    configRead => dest(configRead),
  ),
})

Pipeline Composition

Each stage receives the previous result; combine them to implement custom logic:

import { defineConfig } from '@genapi/core'
import pipeline, { compiler, dest, generate, original } from '@genapi/pipeline'
import { axios } from '@genapi/presets'

export default defineConfig({
  preset: pipeline(
    config => axios.ts.config(config),
    configRead => original(configRead),
    configRead => axios.ts.parser(configRead),
    configRead => compiler(configRead),
    configRead => generate(configRead),
    configRead => dest(configRead),
  ),
})

Best Practices

Reuse existing presets: Try to extend based on existing presets

Keep stages independent: Each stage should only be responsible for one responsibility

Error handling: Add error handling logic at critical stages

Type safety: Use TypeScript to ensure type safety