New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@xm-fe/create-api

Package Overview
Dependencies
Maintainers
7
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@xm-fe/create-api - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

.vscode/launch.json

26

bin/capi.js
#!/usr/bin/env node
// // import inquirer from "inquirer";
// const inquirer = require('inquirer')
// inquirer
// .prompt([
// {
// type: "rawlist", // 交互类型 -- 有序单选
// message: "请选择一种水果:", // 引导词
// name: "projectId", // 自定义的字段名
// choices: ["潜艇SAAS/",
// "summerfarm-manage(鲜沐后台)",
// "pms-service(采购)/1164725",
// "summerfarm-crm(CRM)/1295278",
// "TMS(配送)/1409074",
// "summerfarm-wms(WMS)/1965722",
// "OFC(履约)/2020406",
// "saas-manage (帆台后台)/2437205",
// "saas-oms (帆台大后台)/2437206",
// "saas-mall (帆台商城)/2437207"
// ], // 选项列表
// },
// ])
// .then((answers) => {
// console.log(answers);
// });
const main = require('../src/index')
main()

10

package.json
{
"name": "@xm-fe/create-api",
"version": "0.0.1",
"version": "0.0.2",
"description": "API快速导入",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"capi": "node bin/capi.js"
},

@@ -12,3 +12,2 @@ "bin": {

},
"files":["bin", "src"],
"repository": {

@@ -24,5 +23,8 @@ "type": "git",

"dependencies": {
"@xm-fe/xm-base": "0.0.10",
"axios": "^1.3.4",
"lodash": "^4.17.21"
"inquirer": "^8.0.0",
"lodash": "^4.17.21",
"log4js": "^6.9.1"
}
}

35

src/common.js

@@ -5,2 +5,5 @@ const fs = require('fs')

const _ = require('lodash')
const log4js = require('log4js')
const logger = log4js.getLogger()
var typeEnmu = {

@@ -101,15 +104,25 @@ 'integer[]': 'number[]',

const getCurrentInterfaceTpl = obj => {
return `
/**${obj.description} */
export interface ${_.upperFirst(obj._name)} {
const interfaceName = _.upperFirst(obj._name)
try {
return `
/**${obj.description} */
export interface ${interfaceName} {
${Object.entries(obj.type === 'array' ? obj.items.properties : obj.properties)
.map(([key, val]) => {
return ` /**${val.description} */
` + (key.indexOf('.') > -1 || key.indexOf('[') > -1 ? `"${key}"` : key) + `${val._required ? '' : '?'}: ${toFeType(val._type)}`
})
.join('\n')}
}
`
} catch (error) {
console.log('类型创建异常:', interfaceName, '使用any代替')
${Object.entries(obj.type === 'array' ? obj.items.properties : obj.properties)
.map(([key, val]) => {
return ` /**${val.description} */
${key}${val._required ? '' : '?'}: ${toFeType(val._type)}`
})
.join('\n')}
return `
export type ${interfaceName} = any`
}
}
`
}
const mkdir = dirname => {

@@ -116,0 +129,0 @@ // 循环创建目录

@@ -5,13 +5,14 @@ const path = require('path')

let useConfig = {}
const defaultConfig = {
// 生成目录
targetPath: `/src/apx`,
truePath: `apis`,
targetPath: `/src/apix`,
truePath: `apix`,
// targetTypePath: `/src/api-typess`,
// 读本地文件生成
useLocal: false,
runtimeProjectId: '', // 当前的工程id
// 本地文件地址
localPath: `./test3.0.1.json`,
remotePath: `http://127.0.0.1:4523/export/openapi/6?projectId=2517920&version=3.0`,
remotePath: `http://127.0.0.1:4523/export/openapi?projectId=1164722&version=3.0`,
language: 'ts', // 生成的项目语言类型
// 暂时搞不定的接口

@@ -27,7 +28,23 @@ ignorePath: [

appNameMap: {
'1164722': 'summerfarm-manage',
'1409074': 'tms',
'954456': 'cosfo',
'2517920': 'rs'
954456: 'SAAS',
1164722: 'summerfarm-manage',
1164725: 'pms-service',
1295278: 'summerfarm-crm',
1409074: 'tms',
1965722: 'summerfarm-wms',
2020406: 'OFC',
2437205: 'saas-manage',
2437206: 'saas-oms',
2437207: 'saas-mall',
2517920: 'summerfarm-wnc',
2546551: 'saas-pms',
2546569: 'SCP',
2546585: 'SRM',
2546600: 'bms-service'
},
/**
* 接口项目前缀
* saas项目中访问
*/
apiPrefix: ['/summerfarm-manage', '/summerfarm-wms', '/summerfarm-wnc', '/pms-service', '/xianmu-manage', '/bms-service'], // 目前已经有的前缀
// 路径参数别名

@@ -127,3 +144,3 @@ paramsNumName: {

*/
export function ${api.name}(
export function ${api.fileName || api.name}(
${pathParams ? pathParams : ''}

@@ -146,3 +163,32 @@ ${api.queryParams ? `params?: ${api.queryParams._name},` : ''}

`
},
getApiCodeTplJs(api) {
const pathParams = api.pathParams
.map((param) => `${param.name}${param.required ? '' : '?'}: ${param._type},`)
.join('\r\n')
return `
import net from '@/utils/net'
import { NetConfig } from '@/interface/IAxiosConfig'
/**
* ${api.summary}
*/
export function ${api.fileName || api.name}(
${pathParams ? pathParams : ''}
${api.queryParams ? `params,` : ''}
${api.bodyParams ? `data,` : ''}
config
) {
return net(
{
url: \`${api.url}\`,
method: '${api.method}',
${api.isDownload ? `_download: true,` : ''}
${api.queryParams ? `params,` : ''}
${api.bodyParams ? ` data,` : ''}
},
config
)
}
`
}
}

@@ -152,4 +198,19 @@

const useConfigPath = path.join(process.cwd(), 'capi.config.js') // 上一层路径
const config = { ...defaultConfig }
try {
useConfig = require(useConfigPath)
const { getApiCodeTpl, remotePath, language } = useConfig
if(getApiCodeTpl) {
config.getApiCodeTpl = getApiCodeTpl
}
if(remotePath) {
config.remotePath = remotePath
}
if(language) {
config.language = language
}
} catch (error) {

@@ -159,3 +220,2 @@ console.log(`用户本地配置文件${useConfigPath} 解析失败,将使用默认配置`)

const config = { ...defaultConfig, ...useConfig }

@@ -188,2 +248,5 @@ if(!config.remotePath) {

const URLparams = queryURLparams(config.remotePath)
config.runtimeProjectId = URLparams.projectId
module.exports = config
const _ = require('lodash')
const config = require('./config')
const common = require('./common')
const log4js = require('log4js')
const logger = log4js.getLogger()

@@ -91,6 +93,6 @@ const apiType = ['export', 'query', 'upsert', 'import']

apiPathList[apiPathList.length - 2] +
'_' +
apiPathList[apiPathList.length - 1] +
config.paramsNumName[pathParamsCount] +
'Net'
'_' +
apiPathList[apiPathList.length - 1] +
config.paramsNumName[pathParamsCount] +
'Net'
)

@@ -149,3 +151,3 @@ } else {

if (
shouldAddListModel &&
shouldAddListModel && responseSchema.properties &&
!responseSchema.properties.msg &&

@@ -251,3 +253,3 @@ !responseSchema.properties.data &&

} catch (e) {
console.log('接口解析异常:', apiPath)
console.error('接口解析异常:', apiPath)
}

@@ -257,9 +259,23 @@ }

function generateApiCode(api) {
const api_ = JSON.parse(JSON.stringify(api))
if(api_.resType === 'Data') {
api_.resType = 'any'
}
switch (api_.resType) {
case 'Data':
api_.resType = 'any'
break;
case 'integer':
api_.resType = 'number'
break;
}
return `
${common.generateRefType(api.bodyParams)}
${common.generateRefType(api.resSchema)}
${config.getApiCodeTpl(api)}
${api.queryParams ? common.getInterfaceTpl(api.queryParams) : ''}
${api.hasbodyParamsType ? common.getInterfaceTpl(api.bodyParams) : ''}
${api.hasResType ? common.getInterfaceTpl(api.resSchema) : ''}
${config.getApiCodeTpl(api_)}
${api_.queryParams ? common.getInterfaceTpl(api_.queryParams) : ''}
${api_.hasbodyParamsType ? common.getInterfaceTpl(api_.bodyParams) : ''}
${api_.hasResType ? common.getInterfaceTpl(api_.resSchema) : ''}
`

@@ -266,0 +282,0 @@ }

const common = require('./common')
const log4js = require('log4js')
const logger = log4js.getLogger()

@@ -34,7 +36,7 @@ const handleType = components => {

// }
const generateTypeCode = typeData => common.generateRefType(typeData) + common.getInterfaceTpl(typeData)
// const generateTypeCode = typeData => common.getInterfaceTpl(typeData)
module.exports = {
handleType,
generateTypeCode,
// generateTypeCode,
}

@@ -10,4 +10,17 @@ const fs = require('fs')

const { queryURLparams } = require('./utils')
const { isNumber } = require('@xm-fe/xm-base')
require('./log')
const log4js = require('log4js')
const logger = log4js.getLogger()
let appName = 'main'
const typeMode = {}
const apiTypeListMap = {}
// 接口命名不符合规范的url
const abnormalApi = []
// 当前api已经创建过的 接口类型 防止重复创建和循环引用
let createdType = []
async function main() {

@@ -18,3 +31,16 @@ let apiData

const re = await axios.get(config.remotePath)
Object.keys(re.data.paths).forEach(api => {
let newUrl = api
const defaultPrefix = config.apiPrefix.find(prefix => api.indexOf(prefix) > -1)
if (defaultPrefix) {
newUrl = api.replace(defaultPrefix, '')
re.data.paths[newUrl] = JSON.parse(JSON.stringify(re.data.paths[api]))
delete re.data.paths[api]
}
})
apiData = re.data
console.log(`请求成功!`)

@@ -38,3 +64,5 @@ } else {

} else {
console.log(`warning:未检测到appName,生成至${config.targetPath}/main文件夹`)
console.error('!!! projectId没有对应的文件名,请联系我', URLparams.projectId)
console.error('!!! projectId没有对应的文件名,请联系我', URLparams.projectId)
process.exit()
}

@@ -44,2 +72,7 @@ config.appName = appName

cApi(apiData)
// if (abnormalApi.length > 0) {
// abnormalApi.forEach(item => {
// console.warn('不符合规范的URL:', item)
// })
// }
console.log('创建成功!', config.targetPath)

@@ -49,3 +82,3 @@ }

const cApi = apiData => {
const targetPath = path.join(process.cwd(), config.targetPath, appName, 'api')
const targetPath = path.join(process.cwd(), config.targetPath, appName)
common.mkdir(targetPath)

@@ -55,14 +88,49 @@ const apiModuleMap = createApi.handlePaths(apiData.paths, apiData.components.schemas)

Object.entries(apiModuleMap).forEach(([moduleName, apiList]) => {
const modulePath = path.join(targetPath, moduleName)
if (!fs.existsSync(modulePath)) {
fs.mkdirSync(modulePath)
}
// 遍历模块内api
apiList.forEach((api, idx) => {
const filePath = path.resolve(modulePath, api.name + '.ts')
// 清空
createdType = []
// 处理 -
let name = api.url.split('-').map((item, index) => (index > 0 ? _.upperFirst(item) : item)).join('')
// 处理 /
name = name.split('/').map((item, index) => (index > 1 ? _.upperFirst(item) : item)).join('')
// 如果以数字开头的不生成
if (isNumber(name[0]) || /^.*?(http|localhost|_|\,).*?$/.test(name)) {
abnormalApi.push(api.url)
return
}
name = name.replace(/\$\{.*?\}/g, '')
// 会生成 .ts 文件
if (!name) {
return
}
const fileName = name + (api.method === 'post' ? '' : _.upperFirst(api.method)) + 'Net'
const filePath = path.resolve(targetPath, fileName + '.' + config.language)
api.fileName = fileName
try {
// createApi.generateApiCode(api)
fs.writeFileSync(filePath, createApi.generateApiCode(api))
let content = ''
// 接口生成
content += createApi.generateApiCode(api)
if (config.language === 'ts') {
// 请求参数
if (api.bodyParams?._ref) {
content += handleTypeLink(api.bodyParams._ref)
}
// 响应参数
content += handleTypeLink(api.resSchema._ref)
}
fs.writeFileSync(filePath, content)
} catch (e) {
console.log('接口创建异常:', api.url)
console.error('接口创建异常:', api.url)
}

@@ -72,13 +140,16 @@ })

}
const cType = apiData => {
const apiTypeList = createType.handleType(apiData.components.schemas)
const targetPath = path.join(process.cwd(), config.targetPath, appName, 'types')
common.mkdir(targetPath)
apiTypeList.forEach((item) => {
apiTypeListMap[item._name] = item
})
// 生成type
apiTypeList.forEach(type => {
const typePath = path.resolve(targetPath, type._name + '.ts')
try {
fs.writeFileSync(typePath, createType.generateTypeCode(type))
typeMode[type._name] = common.getInterfaceTpl(type)
} catch (e) {
console.log('类型创建异常:', type._name)
console.error('类型创建异常:', type._name)
console.error(e)
}

@@ -88,2 +159,26 @@ })

/**
* 处理type间的引用关系, 根据type生成该type 中所以引用的type模板
* @param {*} apiData
*/
const handleTypeLink = (resType) => {
let typeStr = ''
const creatType_ = (type) => {
if (type !== 'null' && type && !createdType.includes(type)) {
createdType.push(type)
if(typeMode[type]) {
typeStr += typeMode[type]
}
apiTypeListMap[type]?._refList?.forEach((item) => {
creatType_(item)
})
}
}
creatType_(resType)
return typeStr
}
module.exports = main
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc