Skip to content

Commit

Permalink
feat: bug fix pack
Browse files Browse the repository at this point in the history
  • Loading branch information
Bosn committed Jul 21, 2020
1 parent 7af8fee commit 7177b2e
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 92 deletions.
2 changes: 2 additions & 0 deletions database/v2020_07_21_body_option_save.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `interfaces`
ADD COLUMN `bodyOption` VARCHAR(255) NULL;
3 changes: 3 additions & 0 deletions database/v2020_07_21_merge_PR.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE `RAP2_DELOS_APP`.`Properties`
MODIFY COLUMN `scope` enum('request','response','script') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
DEFAULT 'response' COMMENT 'property owner' AFTER `id`;
4 changes: 4 additions & 0 deletions src/models/bo/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Table, Column, Model, HasMany, AutoIncrement, PrimaryKey, AllowNull, Da
import { User, Module, Repository, Property } from '../'
import RedisService, { CACHE_KEY } from '../../service/redis'
import * as Sequelize from 'sequelize'
import { BODY_OPTION } from '../../routes/utils/const'

const Op = Sequelize.Op

Expand Down Expand Up @@ -68,6 +69,9 @@ export default class Interface extends Model<Interface> {
@Column({ comment: 'API method' })
method: string

@Column({ type: DataType.STRING(255) })
bodyOption?: BODY_OPTION

@Column(DataType.TEXT)
description: string

Expand Down
24 changes: 14 additions & 10 deletions src/models/bo/property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ import { User, Interface, Module, Repository } from '../'
export enum SCOPES { REQUEST = 'request', RESPONSE = 'response', SCRIPT = 'script' }
export enum TYPES { STRING = 'String', NUMBER = 'Number', BOOLEAN = 'Boolean', OBJECT = 'Object', ARRAY = 'Array', FUNCTION = 'Function', REGEXP = 'RegExp', Null = 'Null' }

export enum REQUEST_PARAMS_TYPE {
HEADERS = 1,
QUERY_PARAMS = 2,
BODY_PARAMS = 3,
PRE_REQUEST_SCRIPT = 4,
TESTS = 5
}

@Table({ paranoid: true, freezeTableName: false, timestamps: true })
export default class Property extends Model<Property> {
public static TYPES = TYPES
Expand Down Expand Up @@ -43,9 +35,9 @@ export default class Property extends Model<Property> {

@AllowNull(false)
@Default(2)
@Column
@Column({ type: DataType.INTEGER }) // for better extension
/** request params type (position) */
pos: number
pos: POS_TYPE

@AllowNull(false)
@Column(DataType.STRING(256))
Expand Down Expand Up @@ -102,4 +94,16 @@ export default class Property extends Model<Property> {
/** 是否为必填选项 */
required: boolean

}


/**
* 参数类型
*/
export enum POS_TYPE {
QUERY = 2,
HEADER = 1,
BODY = 3,
PRE_REQUEST_SCRIPT = 4,
TEST = 5,
}
9 changes: 7 additions & 2 deletions src/routes/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ router.post('/repository/defaultVal/update/:id', async (ctx) => {
ctx.body = Consts.COMMON_ERROR_RES.ACCESS_DENY
return
}
const list = ctx.request.body.list
const list = ctx.request.body.list.map(x => { const { id, ...y } = x; return y })
if (!(repositoryId > 0) || !list) {
ctx.body = Consts.COMMON_ERROR_RES.ERROR_PARAMS
return
Expand Down Expand Up @@ -964,7 +964,7 @@ router.post('/property/update', isLoggedIn, async (ctx) => {

router.post('/properties/update', isLoggedIn, async (ctx, next) => {
const itfId = +ctx.query.itf
let { properties } = ctx.request.body as { properties: Property[], summary: Interface }
let { properties, summary } = ctx.request.body as { properties: Property[], summary: Interface }
properties = Array.isArray(properties) ? properties : [properties]

let itf = await Interface.findByPk(itfId)
Expand All @@ -973,6 +973,11 @@ router.post('/properties/update', isLoggedIn, async (ctx, next) => {
return
}

if (summary.bodyOption) {
itf.bodyOption = summary.bodyOption
await itf.save()
}


const itfPropertiesChangeLog: string[] = []

Expand Down
7 changes: 7 additions & 0 deletions src/routes/utils/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,11 @@ export enum THEME_TEMPLATE_KEY {
ORANGE = 'ORANGE',
PURPLE = 'PURPLE',
CYAN = 'CYAN',
}

export enum BODY_OPTION {
FORM_DATA = 'FORM_DATA',
FORM_URLENCODED = 'FORM_URLENCODED',
RAW = 'RAW',
BINARY = 'BINARY',
}
160 changes: 80 additions & 80 deletions src/service/export/postman.ts
Original file line number Diff line number Diff line change
@@ -1,106 +1,106 @@
import { PostmanCollection, Folder, Item } from "../../types/postman"
import { Repository, Interface, Module, Property } from "../../models"
import * as url from 'url'
import { REQUEST_PARAMS_TYPE } from "../../models/bo/property"
import { POS_TYPE } from "../../models/bo/property"
import UrlUtils from "../../routes/utils/url"

const SCHEMA_V_2_1_0 = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'

export default class PostmanService {
public static async export(repositoryId: number): Promise<PostmanCollection> {
const repo = await Repository.findByPk(repositoryId, {
include: [{
model: Module,
as: 'modules',
include: [{
model: Interface,
as: 'interfaces',
include: [{
model: Property,
as: 'properties',
}]
}]
}]
})
const result: PostmanCollection = {
info: {
name: `RAP2 Pack ${repo.name}`,
schema: SCHEMA_V_2_1_0,
},
item: []
}
public static async export(repositoryId: number): Promise<PostmanCollection> {
const repo = await Repository.findByPk(repositoryId, {
include: [{
model: Module,
as: 'modules',
include: [{
model: Interface,
as: 'interfaces',
include: [{
model: Property,
as: 'properties',
}]
}]
}]
})
const result: PostmanCollection = {
info: {
name: `RAP2 Pack ${repo.name}`,
schema: SCHEMA_V_2_1_0,
},
item: []
}

for (const mod of repo.modules) {
const modItem: Folder = {
name: mod.name,
item: [],
}
for (const mod of repo.modules) {
const modItem: Folder = {
name: mod.name,
item: [],
}

for (const itf of mod.interfaces) {
const interfaceId = itf.id
const requestParams = await Property.findAll({
where: {interfaceId, scope: 'request'}
})
const responseParams = await Property.findAll({
where: {interfaceId, scope: 'response'}
})
const eventScript = await Property.findAll({
where: {interfaceId, scope: 'script'}
})
for (const itf of mod.interfaces) {
const interfaceId = itf.id
const requestParams = await Property.findAll({
where: { interfaceId, scope: 'request' }
})
const responseParams = await Property.findAll({
where: { interfaceId, scope: 'response' }
})
const eventScript = await Property.findAll({
where: { interfaceId, scope: 'script' }
})

const relativeUrl = UrlUtils.getRelative(itf.url)
const parseResult = url.parse(itf.url)
const itfItem: Item = {
name: itf.name,
request: {
method: itf.method as any,
header: getHeader(requestParams),
body: getBody(requestParams),
url: {
raw: `{{url}}${relativeUrl}`,
host: '{{url}}',
port: parseResult.port || '',
hash: parseResult.hash,
path: [parseResult.path],
query: getQuery(requestParams),
},
description: itf.description,
},
response: responseParams.map(x => ({key: x.name, value: x.value})),
event: getEvent(eventScript)
}
modItem.item.push(itfItem)
}
result.item.push(modItem)
const relativeUrl = UrlUtils.getRelative(itf.url)
const parseResult = url.parse(itf.url)
const itfItem: Item = {
name: itf.name,
request: {
method: itf.method as any,
header: getHeader(requestParams),
body: getBody(requestParams),
url: {
raw: `{{url}}${relativeUrl}`,
host: '{{url}}',
port: parseResult.port || '',
hash: parseResult.hash,
path: [parseResult.path],
query: getQuery(requestParams),
},
description: itf.description,
},
response: responseParams.map(x => ({ key: x.name, value: x.value })),
event: getEvent(eventScript)
}
return result
modItem.item.push(itfItem)
}
result.item.push(modItem)
}
return result
}
}

function getBody(pList: Property[]) {
return {
"mode": "formdata" as "formdata",
"formdata": pList.filter(x => x.pos === REQUEST_PARAMS_TYPE.BODY_PARAMS)
.map(x => ({key: x.name, value: x.value, description: x.description, type: "text" as "text"})),
}
return {
"mode": "formdata" as "formdata",
"formdata": pList.filter(x => x.pos === POS_TYPE.BODY)
.map(x => ({ key: x.name, value: x.value, description: x.description, type: "text" as "text" })),
}
}

function getQuery(pList: Property[]) {
return pList.filter(x => x.pos === null || x.pos === REQUEST_PARAMS_TYPE.QUERY_PARAMS)
.map(x => ({key: x.name, value: x.value, description: x.description}))
return pList.filter(x => x.pos === null || x.pos === POS_TYPE.QUERY)
.map(x => ({ key: x.name, value: x.value, description: x.description }))
}

function getHeader(pList: Property[]) {
return pList.filter(x => x.pos === REQUEST_PARAMS_TYPE.HEADERS)
.map(x => ({key: x.name, value: x.value, description: x.description}))
return pList.filter(x => x.pos === POS_TYPE.HEADER)
.map(x => ({ key: x.name, value: x.value, description: x.description }))
}

function getEvent(pList: Property[]) {
return pList.filter(x => (x.pos === REQUEST_PARAMS_TYPE.PRE_REQUEST_SCRIPT || x.pos === REQUEST_PARAMS_TYPE.TESTS))
.map(x => ({
key: x.name,
script: {key: x.name, type: 'text/javascript', exec: x.value},
disabled: false,
listen: x.pos === REQUEST_PARAMS_TYPE.PRE_REQUEST_SCRIPT ? 'prerequest' : 'test'
}))
return pList.filter(x => (x.pos === POS_TYPE.PRE_REQUEST_SCRIPT || x.pos === POS_TYPE.TEST))
.map(x => ({
key: x.name,
script: { key: x.name, type: 'text/javascript', exec: x.value },
disabled: false,
listen: x.pos === POS_TYPE.PRE_REQUEST_SCRIPT ? 'prerequest' : 'test'
}))
}

0 comments on commit 7177b2e

Please sign in to comment.