# free-swagger-core

> ![Travis (.com)](https://img.shields.io/travis/com/yeyan1996/free-swagger-core)![](https://img.shields.io/npm/v/free-swagger-core)

Latest version **5.5.0-beta.1** (published 2024-04-29) · MIT license · 0 weekly downloads

## Install

```sh
npm install free-swagger-core
pnpm add free-swagger-core
yarn add free-swagger-core
bun add free-swagger-core
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 5.5.0-beta.1 |
| Published | 2024-04-29 |
| First published | 2021-09-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 9 |
| Unpacked size | 63.2 KB |
| Known vulnerabilities | 0 (+23 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 68 |
| Author | yeyan1996 |
| Maintainers | yeyan1996 |
| Keywords | swagger, typescript |

## Links

- npm: https://www.npmjs.com/package/free-swagger-core
- Repository: https://github.com/yeyan1996/free-swagger
- Homepage: https://github.com/yeyan1996/free-swagger#readme
- Issues: https://github.com/yeyan1996/free-swagger/issues
- npm.io page: https://npm.io/package/free-swagger-core

## Dependencies (9)

- [axios](https://npm.io/package/axios.md) ^0.21.1
- [chalk](https://npm.io/package/chalk.md) ^3.0.0
- [dayjs](https://npm.io/package/dayjs.md) ^1.10.7
- [lodash](https://npm.io/package/lodash.md) ^4.17.15
- [js-yaml](https://npm.io/package/js-yaml.md) ^3.13.1
- [prettier](https://npm.io/package/prettier.md) ^2.0.5
- [camelcase](https://npm.io/package/camelcase.md) ^5.3.1
- [openapi-types](https://npm.io/package/openapi-types.md) ^1.3.5
- [api-spec-converter](https://npm.io/package/api-spec-converter.md) ^2.12.0

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 5.5.0-beta.1 (latest) — 2024-04-29
- 6.0.0-beta.3 (beta) — 2024-04-30
- 6.0.0-beta.2 — 2024-04-30
- 5.5.0-beta.0 — 2024-04-26
- 5.4.2 — 2023-04-18
- 5.4.1 — 2023-04-06
- 5.4.0 — 2022-12-16
- 5.3.2 — 2021-11-20
- 5.3.1 — 2021-11-20
- 5.3.0 — 2021-09-21
- 5.2.0 — 2021-09-14
- 5.1.5 — 2021-09-14
- 5.1.3 — 2021-09-13
- 5.1.2 — 2021-09-12
- 5.1.1 — 2021-09-12
- … 3 more at https://npm.io/package/free-swagger-core/versions

## README

# free-swagger-core

![Travis (.com)](https://img.shields.io/travis/com/yeyan1996/free-swagger-core)![](https://img.shields.io/npm/v/free-swagger-core)

输入 swagger 文档，返回接口代码片段

# 快速上手

```javascript
import freeSwaggerCore from "free-swagger-core";

freeSwaggerCore(config, url, method).then(code => console.log(code))

`
// 增加属性
export const addUsingPOST = params =>
  axios.request({
    url: "/attribute/add",
    method: "post",
    responseType: "json",
    params: {},
    data: params
  });
`;
```

# API

| 参数   | 说明   | 类型   | 可选值 | 默认值 |
| ------ | ------ | ------ | ------ | ------ |
| config | 配置项 | Config | -      | -      |
| url    | -      | string | -      | -      |
| method | -      | string | -      | -      |

- Config

| 参数             | 说明                        | 类型                     | 可选值      | 默认值                               |
| ---------------- | --------------------------- | ------------------------ | ----------- | ------------------------------------ |
| source           | 必选，swagger 源            | json                     | -           | -                                    |
| lang             | 可选，生成 api 语言         | string                   | "js" / "ts" | "js"                                 |
| templateFunction | 可选，模版函数              | Function(TemplateConfig) | -           | 返回一个模版，用于生成自定义代码片段 |
| jsDoc         | 可选，代码块附加 jsdoc 注释   | boolean                  |  -           | true                                |
| typedef | 可选，代码块附加 js doc typedef | boolean |  | false |
| interface     | 可选，代码块附加 interface | boolean                 |  -          | false                                |
| recursive | 可选，递归解析 jsDoc/interface 的依赖 | boolean | - | false |

- TemplateConfig

| 参数         | 说明                                 | 类型     | 可选值   | 默认值 |
| ------------ | ------------------------------------ | -------- | -------- | ------ |
| url          | 路径                                 | string   | -        | -      |
| summary      | 注释，对应 swagger 源 summary 字段      | string   | -        | -      |
| method       | 接口请求方法                                 | string   | -        | -      |
| name         | 名称，对应 swagger 源 operationId 字段   | string   | -        | -      |
| responseType | 返回值类型                           | string   | 同 axios responseType | -      |
| pathParams   | 路径参数                             | string[] | -        |
| IResponse    | 返回值接口类型                       | string   | -        | -      |
| IQueryParams      | 请求值接口类型（请求参数）                      | string   | -        | -      |
| IBodyParams      | 请求值接口类型（请求体）                      | string   | -        | -      |
| IPathParams  | 路径参数接口类型                     | string   | -        | -      |

# 默认模版

free-swagger-core 基于模版函数来生成最终的 api 代码

用户可以自定义模版函数，来满足不同需求，例如修改请求库名，修改参数位置，修改接口命名等等

以下为 free-swagger-core 提供的默认模版

`之所以模版比较复杂，是因为要考虑不同情况，例如 url 中包含路径参数，入参的数量和结构等，但用户不需要关心具体实现，只需自由组合返回的字符串`

https://github.com/yeyan1996/free-swagger/blob/master/packages/core/src/default/template.ts

## js 代码模版

```javascript
({
     url,            // 完整路径 {string}
     summary,        // 注释 {string}
     method,         // 请求方法 {string}
     name,           // api 函数名 {string}
     responseType,   // 响应值种类，同 axios responseType {string}
     pathParams,     // 路径参数 {Array<string>}
     IQueryParams,   // 请求查询参数 ts 类型
     IBodyParams,    // 请求体参数 ts 类型
     IPathParams     // 请求路径参数 ts 类型
 }) => {
    /**
      * js 代码模版
    **/ 
      
    // debugger
    // 可通过 debugger 调试模版

    // 处理路径参数 `/pet/{id}` => `/pet/${id}`
    const parsedUrl = url.replace(/{(.*?)}/g, '${$1}');

    // 有 query 和 body 参数
    const multipleParamsCondition = ({ IQueryParams, IBodyParams }) =>
        IQueryParams && IBodyParams

  const firstParamCodeMap = new Map()
      // 只有 query 参数，可能有 path 参数
      .set(
        ({ IQueryParams, IBodyParams }) => IQueryParams && !IBodyParams,
         `params,`
      )
      // 只有 body 参数，可能有 path 参数
      .set(
        ({ IQueryParams, IBodyParams }) => IBodyParams && !IQueryParams,
         `params,`
      )
      // 有 query 和 body 参数，可能有 path 参数
      .set(
        multipleParamsCondition,
        () => `queryParams,`
      )
       // 没有 query body 参数，有 path 参数
      .set(
        ({ IQueryParams,pathParams,IBodyParams }) => !IBodyParams && !IQueryParams && pathParams.length,
        '_NOOP,'
      )  
      // 只有 path 参数
      .set(
        ({ pathParams }) => pathParams.length,
        ({ pathParams }) =>
          `{${pathParams.join(',')}},`
      )

    const secondParamCodeMap = new Map()
        // 有 path 参数
        .set(
          ({ pathParams }) => pathParams.length,
          ({ pathParams }) =>
            `{${pathParams.join(',')}},`
        )
        // 有 query 和 body 参数，有 path 参数
        .set(multipleParamsCondition, `_NOOP,`)
        
      const thirdParamCodeMap = new Map()
        // 有 query 和 body 参数，有 path 参数
        .set(
          multipleParamsCondition,
          `bodyParams,`
        )
        
      const paramCodeMap = new Map()
        .set(multipleParamsCondition, 'queryParams,')
        .set(({ IQueryParams }) => !!IQueryParams, 'params,')
        
      const dataCodeMap = new Map()
        .set(multipleParamsCondition, 'bodyParams,')
        .set(({ IBodyParams }) => !!IBodyParams, 'params,')
    
      const createParamCode = (conditionMap, defaultCode = '') => {
        let code = defaultCode
        for (const [condition, codeFunction] of conditionMap.entries()) {
          const res = condition({
            IQueryParams,
            IBodyParams,
            pathParams,
          })
          if (res) {
            code =
              typeof codeFunction === 'string'
                ? codeFunction
                : codeFunction({
                    IQueryParams,
                    IBodyParams,
                    IPathParams,
                    pathParams,
                  })
            break
          }
        }
        return code
      }
     
    return `
  ${summary ? `// ${summary}` : ""}
  export const ${name} = (
    ${createParamCode(firstParamCodeMap) /* query | body | NOOP */}
    ${createParamCode(secondParamCodeMap) /* path | null */}
    ${createParamCode(thirdParamCodeMap) /* body | null */}
) => axios.request({
     url: \`${parsedUrl}\`,
     method: "${method}",
     params: ${createParamCode(paramCodeMap, '{},')}
     data: ${createParamCode(dataCodeMap, '{},')}
     ${responseType === "json" ? "" : `responseType: ${responseType},`}
 })`
}
```

## ts 代码模版

```javascript
({
     url,            // 完整路径 {string}
     summary,        // 注释 {string}
     method,         // 请求方法 {string}
     name,           // api 函数名 {string}
     responseType,   // 响应值种类，同 axios responseType {string}
     pathParams,     // 路径参数 {Array<string>}
     IQueryParams,   // 请求查询参数 ts 类型
     IBodyParams,    // 请求体参数 ts 类型
     IPathParams,    // 请求路径参数 ts 类型
     IResponse,      // 响应参数 ts 类型
 }) => {
    /**
      * ts 代码模版
    **/ 
      
    // debugger
    // 可通过 debugger 调试模版

    // 处理路径参数 `/pet/{id}` => `/pet/${id}`
      const parsedUrl = url.replace(/{(.*?)}/g, '${$1}'); 
     
      // 有 query 和 body 参数
      const multipleParamsCondition = ({ IQueryParams, IBodyParams }) =>
        IQueryParams && IBodyParams
        
      const firstParamCodeMap = new Map()
        // 只有 query 参数，可能有 path 参数
        .set(
          ({ IQueryParams, IBodyParams }) => IQueryParams && !IBodyParams,
          ({ IQueryParams }) => `params: ${IQueryParams},`
        )
        // 只有 body 参数，可能有 path 参数
        .set(
          ({ IQueryParams, IBodyParams }) => IBodyParams && !IQueryParams,
          ({ IBodyParams }) => `params: ${IBodyParams},`
        )
        // 有 query 和 body 参数，可能有 path 参数
        .set(
          multipleParamsCondition,
          ({ IQueryParams }) => `queryParams: ${IQueryParams},`
        )
        // 没有 query body 参数，有 path 参数
        .set(
          ({ IQueryParams,pathParams,IBodyParams }) => !IBodyParams && !IQueryParams && pathParams.length,
          '_NOOP: Record<string,never>,'
        )
         // 只有 path 参数
        .set(
          ({ pathParams }) => pathParams.length,
          ({ pathParams, IPathParams }) =>
            `{${pathParams.join(',')}}: ${IPathParams},`
        )
        
      const secondParamCodeMap = new Map()
        // 有 path 参数
        .set(
          ({ pathParams }) => pathParams.length,
          ({ pathParams, IPathParams }) =>
            `{${pathParams.join(',')}}: ${IPathParams},`
        )
        // 有 query 和 body 参数，有 path 参数
        .set(multipleParamsCondition, `_NOOP:{[key:string]: never},`)
        
      const thirdParamCodeMap = new Map()
        // 有 query 和 body 参数，有 path 参数
        .set(
          multipleParamsCondition,
          ({ IBodyParams }) => `bodyParams: ${IBodyParams},`
        )
        
      const paramCodeMap = new Map()
        .set(multipleParamsCondition, 'queryParams,')
        .set(({ IQueryParams }) => !!IQueryParams, 'params,')
        
      const dataCodeMap = new Map()
        .set(multipleParamsCondition, 'bodyParams,')
        .set(({ IBodyParams }) => !!IBodyParams, 'params,')
    
      const createParamCode = (conditionMap, defaultCode = '') => {
        let code = defaultCode
        for (const [condition, codeFunction] of conditionMap.entries()) {
          const res = condition({
            IQueryParams,
            IBodyParams,
            pathParams,
          })
          if (res) {
            code =
              typeof codeFunction === 'string'
                ? codeFunction
                : codeFunction({
                    IQueryParams,
                    IBodyParams,
                    IPathParams,
                    pathParams,
                  })
            break
          }
        }
        return code
      }

    return `
  ${summary ? `// ${summary}` : ""}  
  export const ${name} = (
    ${createParamCode(firstParamCodeMap) /* query | body | NOOP */}
    ${createParamCode(secondParamCodeMap) /* path | null */}
    ${createParamCode(thirdParamCodeMap) /* body | null */}
) => axios.request<${IResponse || "any"}>({
     url: \`${parsedUrl}\`,
     method: "${method}",
     params: ${createParamCode(paramCodeMap, '{},')}
     data: ${createParamCode(dataCodeMap, '{},')}
     ${responseType === "json" ? "" : `responseType: ${responseType},`}
 })`
}
```

---
_Source: https://npm.io/package/free-swagger-core · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
