openapi-typescript 生成枚举

问题描述 投票:0回答:1

鉴于此输入:

openapi: 3.0.1
info:
  title: test enums
  description: test enums
  version: "1.00"

components:
  schemas:
    VideoProcessingStateDto:
      type: string
      enum:
        - IN_PROGRESS
        - FAILED
        - FINISHED

我希望生成以下打字稿枚举

export enum VideoProcessingStateDto {
  IN_PROGRESS = 'IN_PROGRESS',
  FAILED = 'FAILED',
  FINISHED = 'FINISHED',
}

但是,openapi-typescript 继续给我一个字符串联合:

/** @enum {string} */
VideoProcessingStateDto: "IN_PROGRESS" | "FAILED" | "FINISHED";

在这种情况下是否可以配置 openapi-typescript 来生成枚举?

基于对 源代码 的非常肤浅的一瞥,我没有看到任何配置选项

也许我没有在输入中正确定义枚举?

任何指导将不胜感激,谢谢!

typescript enums swagger-codegen openapi-generator
1个回答
0
投票

好的,所以我决定使用 API 上的

transform
选项,它允许用户根据需要重塑输出。在这种情况下,我用枚举的name替换值,从联合中的值生成枚举,并将它们添加到缓存中。

当需要将结果输出到文件时,我会将枚举附加到文件的末尾,以便在模式组件中引用它们时它们存在。

这是非常粗糙的代码,您可能需要修改它以满足您的需要,但这里是所有代码。

import openapiTS, { SchemaObject } from 'openapi-typescript';
import * as fs from 'node:fs';

// Utility function to get the name of the schema from the path
function getSchemaName(str: string) {
  const arr = str.split('/');
  const schemaName = arr[arr.length - 1];
  return schemaName;
}

/** trasform the sting union of "IN_PROGRESS" | "FAILED" | "FINISHED"
 * to a typescript enum like:
 * enum Status {
 * IN_PROGRESS = "IN_PROGRESS",
 * FAILED = "FAILED",
 * FINISHED = "FINISHED"
 * }
 */
function unionToEnum(enumValues: string[], enumName: string) {
  const enumString = enumValues
    .map((value) => `${value} = "${value}"`)
    .join(',\n');
  const enumType = `enum ${enumName} {
    ${enumString}
  }`;
  return enumType;
}

async function generateTypesFromSchema(): Promise<string> {
  const localPath = new URL('api.yml', import.meta.url);
  const output = await openapiTS(localPath, {
    transform: collectAndTransformEnums,
  });
  if (output) {
    return output;
  }
  return '';
}

const enumCache = new Map();

function collectAndTransformEnums(
  schemaObject: SchemaObject,
  metadata: any
): string {
  if ('enum' in schemaObject) {
    const enumName = getSchemaName(metadata.path);
    const enumValues = schemaObject.enum as string[];
    enumCache.set(getSchemaName(enumName), unionToEnum(enumValues, enumName));
    return enumName;
  }
  return '';
}

/**
 * 1. generate the types from the schema
 * 2. iterate over the enumCache and add the enums to the types
 * 3. write the types to a file
 */
generateTypesFromSchema().then((types) => {
  enumCache.forEach((enumType) => {
    types += enumType;
  });

  // write the types to a file
  return fs.writeFile('defs/types.ts', types, (err) => {
    if (err) {
      console.error(err);
      return;
    }
  });
});

使用上面的脚本,给定这个输入:

openapi: 3.0.1

info:
  title: Sample Video API
  description: Sample Video API
  version: '1.0'

paths:
  /api/v1/video-process:
    get:
      tags:
        - video
      summary: Process a video input
      operationId: VideoProcess
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoProcessingStateDto'

components:
  schemas:
    VideoProcessingStateDto:
      type: string
      enum:
        - IN_PROGRESS
        - FAILED
        - FINISHED

输出将是:

/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */

export interface paths {
  '/api/v1/video-process': {
    /** Process a video input */
    get: operations['VideoProcess'];
  };
}

export type webhooks = Record<string, never>;

export interface components {
  schemas: {
    /** @enum {string} */
    VideoProcessingStateDto: VideoProcessingStateDto;
  };
  responses: never;
  parameters: never;
  requestBodies: never;
  headers: never;
  pathItems: never;
}

export type external = Record<string, never>;

export interface operations {
  /** Process a video input */
  VideoProcess: {
    responses: {
      /** @description Successful operation */
      200: {
        content: {
          'application/json': components['schemas']['VideoProcessingStateDto'];
        };
      };
    };
  };
}
enum VideoProcessingStateDto {
  IN_PROGRESS = 'IN_PROGRESS',
  FAILED = 'FAILED',
  FINISHED = 'FINISHED',
}
© www.soinside.com 2019 - 2024. All rights reserved.