1.0.2 • Published 9 months ago

@ikonintegration/ikapi-docs-gen v1.0.2

Weekly downloads
-
License
ISC
Repository
-
Last release
9 months ago

IKApi-docs-gen

A tool to generate OpenAPI specifications from IKApi Routes in TypeScript files.

Installation

You don't need to install the package globally. You can use npx to run the command directly.

Usage

To generate OpenAPI specifications, run:

npx @ikonintegration/ikapi-docs-gen

This command will:

  1. Recursively find all router.ts files in the src directory.
  2. Extract IKApi Routes from these files.
  3. Generate OpenAPI components and save them to ./docs/api.yaml.

Requirements

Ensure your project meets the following requirements:

  1. TypeScript files IKApi exported Router, named router.ts.
  2. A base.json file in the docs folder.

Configuration

The base.json file should contain your OpenAPI base configuration. Here is an example:

{
    "contact": {
        "email": "someone@domain.com",
        "name": "Company Inc",
        "url": "http://domain.com"
    },
    "servers": [
        {
            "url": "http://localhost:8080",
            "description": "Local server"
        },
        {
            "url": "https://example.dev.domain.com",
            "description": "Dev server"
        }
    ],
    "security": {
        "UserAuth": {
            "bearerFormat": "JWT",
            "description": "User custom JSON web token.",
            "scheme": "bearer",
            "type": "http"
        },
        "APIKey": {
            "description": "API Key",
            "type": "apiKey",
            "in": "header",
            "name": "apiKey"
        }
    }
}

Examples

Route

import { Route, HttpMethod, Response } from '@ikonintegration/ikapi'

import {
  NotesListInputType,
  NotesListInputSchema,
  NotesResponseType,
  NotesResponseSchema,
} from './types.js'
import Module from '../../core/Module.js'

interface PostRouteType extends Route<NotesListInputType, NotesResponseType> {}
export default class Post implements PostRouteType {
  public path: string = '/notes'
  public method: HttpMethod = HttpMethod.POST
  public inputSchema = NotesListInputSchema
  public openApi = {
    summary: 'List Notes',
    description: 'Paginated Notes Listing',
    outputSchema: NotesResponseSchema,
    tags: ['Notes'],
    security: [{ UserAuth: [] }],
  }
  public handler: PostRouteType['handler'] = async transaction => {
    return await new Module.Core(transaction, Module.Globals.AccessLevel.ADMIN).authenticate(
      async core => {
        const b = transaction.request.getBody()
        const resp = await core.notesService.note.list(b.nextToken || undefined)
        if (resp instanceof Response) return resp
        return Response.SuccessResponse(resp)
      }
    )
  }
}

Input Body Example

// Input Body Example
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi'
import { z } from 'zod'

extendZodWithOpenApi(z)

/* Post */
export const NotesListInputSchema = z
  .object({
    nextToken: z.string().nullish().openapi({
      description: 'Optional next token',
    }),
  })
  .openapi({
    description: 'Notes list input body',
    name: 'NotesListInput',
  })

export type NotesListInputType = z.infer<typeof NotesListInputSchema>

Output Body Example

// Output Body Example
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi'
import { z } from 'zod'

extendZodWithOpenApi(z)

/* Post */
export const NotesResponseSchema = z
  .object({
    notes: z.array(.....).openapi({
      description: 'List of notes',
    }),
    nextToken: z.string().optional().openapi({
      description: 'Next token for pagination',
    }),
  })
  .openapi({
    description: 'Notes list response body',
    name: 'NotesResponse',
  })

export type NotesResponseType = z.infer<typeof NotesResponseSchema>

Path Parameter Example

// Path Parameter Example
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi'
import { z } from 'zod'

extendZodWithOpenApi(z)

/* Path */
export const NotePathSchema = z
  .object({
    noteId: z.string().openapi({
      param: {
        name: 'noteId',
        in: 'path',
      },
      example: 'Note Id',
    }),
  })
  .openapi({
    description: 'Note authorized route path parameters',
  })

export type NotePathType = z.infer<typeof NotePathSchema>