Skip to content

CLI

The command line tool provided by Keq can compile the swagger document into typescript code. So that HTTP requests can be sent like calling functions.

Install

bash
npm install keq-cli
bash
pnpm install keq-cli
bash
yarn install keq-cli

IMPORTANT

It is recommended to lock the version of keq-cli in package.json. Minor version of keq-cli may modify code template to fix bugs. This may cause code incompatibility.

Usage

Add a swagger file and .keqrc.ts file to project:

typescript
import { defineKeqConfig, FileNamingStyle } from "keq-cli"

export default defineKeqConfig({
  outdir: "./src/api",
  fileNamingStyle: FileNamingStyle.snakeCase,
  modules: {
    catService: "./cat-service-swagger.json",
    // can also get the swagger document from internet, for example:
    // dogService: "http://dog.example.com/swagger.json"
  },
})
json
{
  "openapi": "3.0.0",
  "info": {
    "title": "Cat Service",
    "version": "0.0.1"
  },
  "paths": {
    "/cat": {
      "get": {
        "operationId": "getCat",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Cat"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Cat": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "age": { "type": "number" }
        }
      }
    }
  }
}

Run npx keq-cli build in the project directory to generate typescript code. The results are as follows:

typescript
import { Keq } from "keq"
import { request } from "keq"
import type {
  RequestParameters,
  ResponseMap,
  Operation,
} from "./types/get_cat"

export function getCat<STATUS extends keyof ResponseMap>(
  arg?: RequestParameters
): Keq<ResponseMap[STATUS], Operation<STATUS>> {
  const req = request.get<ResponseMap[STATUS]>("/cat").option("module", {
    name: "catService",
    pathname: "/cat",
  })

  return req as unknown as Keq<ResponseMap[STATUS], Operation<STATUS>>
}
typescript
/**
 * @interface Cat
 * @export
 */
export interface Cat {
  "name"?: string
  "age"?: number
}
typescript
import type { KeqOperation } from 'keq'
import type { Cat } from "../components/schemas/cat"


export interface ResponseMap {
  "200": Cat
}


export type QueryParameters = {
}

export type RouteParameters = {
}

export type HeaderParameters = {
}

export type BodyParameters ={}
export type RequestParameters = QueryParameters & RouteParameters & HeaderParameters & BodyParameters


export interface Operation<STATUS extends keyof ResponseMap> extends KeqOperation {
  requestParams: RouteParameters
  requestQuery: QueryParameters
  requestHeaders: HeaderParameters
  requestBody: BodyParameters
  responseBody: ResponseMap[STATUS]
}

Use the generated function to send an HTTP request:

typescript
import { getCat } from "./src/api/cat_service/get_cat"

const cat = await getCat()
  .retry(3, 1000)
  .timeout(1000)

console.log(`Cat name is ${cat.name}`)

And we can add error handler to the requests of catService module:

typescript
import { request } from 'keq'
import { throwException, RequestException } from 'keq-exception'


request
  .useRouter()
  .module('catService', throwException(context => {
    if (context.response) {
      if (context.response.status >= 400 && context.response.status < 500) {
        throw new RequestException(context.response.status, context.response.statusText, false)
      } else if (context.response.status >= 500) {
        throw new RequestException(context.response.status, context.response.statusText)
      }
    }
  }))

TIP

Thanks to the chain call and middleware, we can adjust the behavior of request without modifying code generated by keq-cli.

Configuration

keq-cli will look for files named .keqrc.yml.keqrc.json.keqrc.js.keqrc.ts. And you can set the config file path using -c --config <config_file_path>.

PropertiesRequiredDefaultDescription
outdirtrue-Output directory of results
fileNamingStylefalse-The file naming style.
modulestrue-Swagger file location and module name
operationIdFactoryfalse({ operation }) => operation.operationIdDefines how to generate function name. Default, the operationId in the swagger file is used.
strictfalsefalseClear outdir before generate.
esmfalsefalseWhether to generate ESM style code.

FileNamingStyle

EnumExample
FileNamingStyle.camelCase"twoWords"
FileNamingStyle.capitalCase"Two Words"
FileNamingStyle.constantCase"TWO_WORDS"
FileNamingStyle.dotCase"two.words"
FileNamingStyle.headerCase"Tow-Words"
FileNamingStyle.noCase"two words"
FileNamingStyle.paramCase"two-words"
FileNamingStyle.pascalCase"TwoWords"
FileNamingStyle.pathCase"two/words"
FileNamingStyle.sentenceCase"Two words"
FileNamingStyle.snakeCase"two_words"

Command Line Options

OptionsDescription
[moduleName]Only generate the specified module.
-c --config <config_file_path>Configuration file address.
-i --interactiveInteractively specify the HTTP interface to be generated.
--method <method>Only generate function matching method ('get' | 'post' | 'put' | 'patch' | 'head' | 'options' | 'delete').
--pathname <pathname>Only generate function matching pathname.
--no-appendDo not generate newly added functions (compared with the last generation).
--no-updateDo not update the last generated functions.