npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lhy-meta-web/open-api

v0.1.9

Published

> 根据open api规范文档生成typescript接口文件

Downloads

22

Readme

@lhy-meta-web/open-api

根据open api规范文档生成typescript接口文件

快速开始

安装

  npm install -g @lhy-meta-web/open-api

  // 或者
  yarn install -g @lhy-meta-web/open-api

  // 或者
  pnpm install -g @lhy-meta-web/open-api

使用

// typescript
import { GeneratorV2, GeneratorV3 } from '@lhy-meta-web/open-api'
// javascript
const { GeneratorV2, GeneratorV3 } = require('@lhy-meta-web/open-api')

const generator = new GeneratorV2({
  api: 'open api v2的访问地址,可在swagger文档的http请求中找到',
  template: {
    outputDir: './dist-api',
    clearOutputDir: true,
  },
})

generator.build()

配置

GeneratorConfig

| 属性 | 类型 | 描述 | | ---------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | api | string \| OpenAPI.Document \| string[] \| OpenAPI.Document[] | swagger.json的url地址或json | | template | TemplateConfig | 模板配置 | | commonUrl | string | 公共的url前缀,生成器会自动计算一个最长公共子路径,commonUrl必须是最长公共子路径的子集。通常不需要使用该配置 | | filterResourceDependencies | boolean | 是否对依赖做过滤处理,只会保留有存在依赖关系的模型和枚举,默认true | | formatter | GeneratorFormatter | 格式化配置 | | package | GeneratorPackage | 包路径配置 | | logger | GeneratorLogger | 日志配置 |

GeneratorV2Config extends GeneratorConfig

| 属性 | 类型 | 描述 | | ------------------ | ------------------------------- | ----------------------------------------------- | | makeEnum | (...) => ResourceEnum | 生成枚举,可用于自定义枚举解析,具体定义详见dts | | makeEnumProperty | (...) => ResourceEnumProperty | 生成枚举属性,具体定义详见dts | | pathFilter | (...) => boolean | 路径过滤,返回true才执行生成,具体定义详见dts |

GeneratorV3Config extends GeneratorConfig

| 属性 | 类型 | 描述 | | ------------------ | ------------------------------- | ----------------------------------------------- | | makeEnum | (...) => ResourceEnum | 生成枚举,可用于自定义枚举解析,具体定义详见dts | | makeEnumProperty | (...) => ResourceEnumProperty | 生成枚举属性,具体定义详见dts | | pathFilter | (...) => boolean | 路径过滤,返回true才执行生成,具体定义详见dts |

TemplateConfig 模板配置

| 属性 | 类型 | 描述 | | ---------------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | | groupName | string | 模板组名称,默认 default | | outputDir | string | 输出目录 | | outputFileName | (filename: string) => string | 输出文件名,默认:${filename}.ts | | outputFile | (outputDir: string, packagePath: string, fileName: string) => string | 输出文件绝对路径,默认:path.resolve(outputDir, packagePath, fileName) | | clearOutputDir | boolean | 重新编译前清空输出目录 | | buildModelContext | (model: ResourceModel, resource: Resource) => Record<string, unknown> | 生成Model编译上下文,可在模板中使用 | | buildEnumContext | (enumModel: ResourceEnum, resource: Resource) => Record<string, unknown> | 生成Enum编译上下文,可在模板中使用 | | buildParameterModelContext | (parameterModel: ResourceModel, resource: Resource) => Record<string, unknown> | 生成ParameterModel编译上下文,可在模板中使用 | | buildClassContext | (clazz: ResourceClass, resource: Resource) => Record<string, unknown> | 生成Class编译上下文,可在模板中使用 |

GeneratorFormatter 包路径配置

| 属性 | 类型 | 描述 | | ------------------- | ---------------------------- | --------------------- | | className | ResourceCodeNameFormatter | 类名,默认 pascal | | classPropertyName | ResourceCodeNameFormatter | 属性名,默认 hump | | fileName | ResourceFormatter | 文件名,默认 hyphen |

export const ResourceFormatter = {
  // 小驼峰
  Hump: 'hump',
  // 大驼峰
  Pascal: 'pascal',
  // 中划线
  Hyphen: 'hyphen',
  // 下划线
  Snake: 'snake',
} as const
export type ResourceFormatter = ConstType<typeof ResourceFormatter>
export type ResourceCodeNameFormatter = Exclude<ResourceFormatter, typeof ResourceFormatter.Hyphen>

GeneratorPackage 包路径配置

| 属性 | 类型 | 描述 | | ---------------- | --------- | ------------------------------------------------------------------------ | | model | string | Model包目录,默认 models | | enum | string | Enum包目录,默认 enums | | parameterModel | string | ParameterModel包目录,默认 parameter-models (取决于formatter.fileName) |

GeneratorLogger 日志配置

| 属性 | 类型 | 描述 | | ------- | -------------- | -------------------- | | level | LoggerLevel | 日志级别,默认warn |

export const LoggerLevel = {
  Info: 'info',
  Warn: 'warn',
  Error: 'error',
} as const
export type LoggerLevel = ConstType<typeof LoggerLevel>

执行流程

  • 从options.api读取Document json
  • 将Document json转换为Resource(v2、v3差异在此)
  • 根据配置从Template中获取模板组文件(可自定义扩展)
  • 根据模板组文件读取对应的模板编译器(可自定义扩展)
  • 根据配置项生成模板编译Context上下文(可配置扩展)
  • 执行编译器并将编译后的文本写入文件

Class拆分

@lhy-meta-web/open-api会自动根据Document json中的所有url计算出最长公共子路径,并与commonUrl做对比得出最终公共前缀,然后移除掉该公共路径后的下一级路径作为Class分类。

例:

  • v1/api/user/save
  • v1/api/user/update
  • v1/api/role/update
  • v1/api/menu/page

=> 最长公共子路径: v1/api/,得到Class分类

  • user
    • save
    • update
  • role
    • update
  • menu
    • page

当配置commonUrl时需要特别注意,commonUrl下一级的接口会全部合并成一个Class类,可能存在同名方法的情况。

=> commonUrl = 'v1',得到的Class分类为

  • api
    • save => user.save
    • update => user.update
    • update => role.update,同名了
    • page => menu.page

模板

@lhy-meta-web/open-api采用nunjucks作为模板编译引擎,并内置了一套默认模板组,包含

  • class.njk
  • enum.njk
  • model.njk

模板文件类型

  • TemplateFileType.Model (open api中定义好的模型)
  • TemplateFileType.Enum (枚举,v2中的枚举是每个Model或ParameterModel的属性中独立生成,v3中可使用重用枚举)
  • TemplateFileType.ParameterModel (针对Path、Query、FormData而新生成的参数模型)
  • TemplateFileType.Class (用于多个Api static挂载的Class)

自定义模板

// 注册模板组
Template.registryGroup('自定义模板组名称', {
  files: [
    {
      type: TemplateFileType.Model,
      path: './default/model.njk',
    },
    {
      type: TemplateFileType.Enum,
      path: './default/enum.njk',
    },
    {
      type: TemplateFileType.ParameterModel,
      path: './default/model.njk',
    },
    {
      type: TemplateFileType.Class,
      path: './default/class.njk',
    },
  ],
})

// 然后在配置中指定使用自己的模板组
const generator = new GeneratorV2({
  api: 'open api v2的访问地址,可在swagger文档的http请求中找到',
  template: {
    groupName: '自定义模板组名称',
    outputDir: './dist-api',
    clearOutputDir: true,
  },
})

模板编译器

模板编译器是针对模板文件类型的编译器

@lhy-meta-web/open-api内置了默认的模板编译器,可自定义覆盖默认编译器

import { Template } from '@lhy-meta-web/open-api'
import nunjucks from 'nunjucks'

Template.registryCompiler(
  TemplateFileType.Model,
  (templateContent: string, context: TemplateCompilerContext<typeof TemplateFileType.Model>, resource, config) => {
    return nunjucks.renderString(templateContent, context)
  }
)

自定义TS基础类型解析器

import { TSTypeResolverV2 } from '@lhy-meta-web/open-api'

// 注意TSTypeResolverV2.mapping是只读属性
console.log(TSTypeResolverV2.mapping)

// 以下是默认值
//   {
//     object: 'Record<string, unknown>',
//     string: 'string',
//     integer: 'number',
//     int: 'number',
//     long: 'number',
//     double: 'number',
//     boolean: 'boolean',
//     Map: 'Record',
//     List: 'Array',
//     Void: 'void',
//     file: ' File',
//   }

Object.assign(TSTypeResolverV2.mapping, {
  // ...编写自己的类型映射
})

移除统一目录前缀

const generator = new GeneratorV2({
  api: 'open api v2的访问地址,可在swagger文档的http请求中找到',
  template: {
    groupName: '自定义模板组名称',
    outputDir: './dist-api',
    outputFile(outputDir, packagePath, fileName) {
      // 注意移除url中的前缀时要同时移除尾巴的/,否则生成地址时会放置到根目录
      return path.resolve(__dirname, outputDir, packagePath.replace(/^api-prefix\/?/, ''), fileName)
    },
  },
})

注意事项

  • 接口文档中的泛型对象不能使用多泛型,只能是单泛型结构。如: User<Integer, String>是不允许的,User<Integer>是允许的
  • 所有的泛型必须明确的指定类型,否则会被解析成unknown
  • 应避免使用Object、JSON、Map等数据类型,尽可能使用明确的类型,此类均被解析成Record<string, unknown>
  • 文件上传接口指定@ApiImplicitParams({@ApiImplicitParam(name = "file", dataType = "MultipartFile")}),在swagger文档上能显示 consumes ["multipart/form-data"]即可
  • 返回文件流接口指定produces = MediaType.APPLICATION_OCTET_STREAM_VALUE,在swagger文档上能显示 produces ["application/octet-stream"]即可
  • 目前不支持allofoneofanyof,泛型的判断依据于名称中包含/«.*»/字符,主要适配于java的swagger生成

意见或建议

可发送邮件至邮箱[email protected],标题请明确包含@lhy-meta-web/open-api字样