diff --git a/Dockerfile b/Dockerfile index 8edcf25..23f7d3d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,4 +2,4 @@ FROM node:8.11.1-alpine WORKDIR /app ADD . /tmp -RUN /bin/sh -c 'cd /tmp && npm run build && mv ./dist/* /app/ && mv ./node_modules /app/ && rm -rf /tmp' \ No newline at end of file +RUN /bin/sh -c 'cd /tmp && npm install && npm install -g typescript && npm run build && mv ./dist/* /app/ && mv ./node_modules /app/ && rm -rf /tmp' \ No newline at end of file diff --git a/src/routes/migration.ts b/src/routes/migration.ts new file mode 100644 index 0000000..d4f483c --- /dev/null +++ b/src/routes/migration.ts @@ -0,0 +1,46 @@ +// import router from './router' +// import migration from '../scripts/migration/migration' + +// // TODO 2.3 迁移期间采用单 worker 机制,迁移后恢复 +// const TASKS: { [key: number]: number } = {} +// const doit = async (repositoryId: number) => { +// if (repositoryId in TASKS) return + +// let stage = await migration.stage(repositoryId) +// if (stage === 4) { +// TASKS[repositoryId] = 100 +// return +// } + +// await migration.repository(repositoryId) +// await migration.lock(repositoryId) + +// TASKS[repositoryId] = 0 +// for (let i = 0; i < 100; i++) { +// const percent = await new Promise((resolve) => { +// setTimeout(() => { +// resolve(i + 1) +// }, Math.random() * 500) +// }) +// TASKS[repositoryId] = percent +// } +// } + +// router.post('/app/migrate', async (ctx) => { +// let { repositoryId } = ctx.request.body +// if (!repositoryId) return +// doit(repositoryId) +// ctx.type = 'json' +// ctx.body = { +// percent: TASKS[repositoryId] || 0 +// } +// }) + +// router.get('/app/migrate/progress/:repositoryId', async (ctx) => { +// let { repositoryId } = ctx.params +// let stage = await migration.stage(repositoryId) +// let percent = stage === 4 ? 100 : TASKS[repositoryId] +// ctx.body = { +// percent +// } +// }) diff --git a/src/routes/mock.ts b/src/routes/mock.ts index 2f51676..faaf18a 100644 --- a/src/routes/mock.ts +++ b/src/routes/mock.ts @@ -4,10 +4,12 @@ import { QueryInclude } from '../models'; import Tree from './utils/tree' import urlUtils from './utils/url' import * as querystring from 'querystring' +import { Sequelize } from 'sequelize-typescript'; const attributes: any = { exclude: [] } const pt = require('node-print').pt const beautify = require('js-beautify').js_beautify +const Op = Sequelize.Op // 检测是否存在重复接口,会在返回的插件 JS 中提示。同时也会在编辑器中提示。 const parseDuplicatedInterfaces = (repository: Repository) => { @@ -121,9 +123,6 @@ router.all('/app/mock/:repositoryId(\\d+)/:url(.+)', async (ctx) => { REG_URL_METHOD.lastIndex = -1 url = url.replace(REG_URL_METHOD, '') } - // if(process.env.NODE_ENV === 'development') { - // console.log({repositoryId, url, method}) - // } let urlWithoutPrefixSlash = /(\/)?(.*)/.exec(url)[2] let urlWithoutSearch @@ -140,14 +139,17 @@ router.all('/app/mock/:repositoryId(\\d+)/:url(.+)', async (ctx) => { let repository = await Repository.findById(repositoryId) let collaborators: Repository[] = (await repository.$get('collaborators')) as Repository[] let itf + console.log([urlWithoutPrefixSlash, '/' + urlWithoutPrefixSlash, urlWithoutSearch]) itf = await Interface.findOne({ attributes, where: { repositoryId: [repositoryId, ...collaborators.map(item => item.id)], method, - url: [urlWithoutPrefixSlash, '/' + urlWithoutPrefixSlash, urlWithoutSearch], - }, + url: { + [Op.like]: `%${urlWithoutPrefixSlash}%`, + } + } }) if (!itf) { diff --git a/src/routes/utils/url.ts b/src/routes/utils/url.ts index d796e90..26dde21 100644 --- a/src/routes/utils/url.ts +++ b/src/routes/utils/url.ts @@ -19,13 +19,16 @@ export default class UrlUtils { if (url.indexOf('?') > -1) { url = url.substring(0, url.indexOf('?')) } + if (url[0] !== '/') url = '/' + url return url } public static urlMatchesPattern = (url: string, pattern: string) => { url = UrlUtils.getRelative(url) pattern = UrlUtils.getRelative(pattern) + console.log(`url=${url} pattern=${pattern}`) let re = pathToRegexp(pattern) + console.log(url, re) return re.test(url) } diff --git a/src/service/migrate.ts b/src/service/migrate.ts index b3efb04..f00e6be 100644 --- a/src/service/migrate.ts +++ b/src/service/migrate.ts @@ -1,9 +1,9 @@ import { Repository, Module, Interface, Property, User } from "../models"; -import { SCOPES, TYPES } from "../models/bo/property"; +import { SCOPES } from "../models/bo/property"; import * as md5 from 'md5' -const isMd5 = require('is-md5') import * as querystring from 'querystring' import * as rp from 'request-promise' +const isMd5 = require('is-md5') export default class MigrateService { public static async importRepoFromRAP1ProjectData(orgId: number, curUserId: number, projectData: any): Promise { @@ -45,11 +45,32 @@ export default class MigrateService { for (const p of action.responseParameterList) { await processParam(p, SCOPES.RESPONSE) } - async function processParam(p: any, scope: SCOPES, parentId?: number) { + async function processParam(p: OldParameter, scope: SCOPES, parentId?: number) { + const RE_REMARK_MOCK = /@mock=(.+)$/ + const ramarkMatchMock = RE_REMARK_MOCK.exec(p.remark) + const remarkWithoutMock = p.remark.replace(RE_REMARK_MOCK, '') + const name = p.identifier.split('|')[0] + let rule = p.identifier.split('|')[1] || '' + let type = (p.dataType || 'string').split('<')[0] // array => Array + type = type[0].toUpperCase() + type.slice(1) // foo => Foo + let value = (ramarkMatchMock && ramarkMatchMock[1]) || '' + if (/^function/.test(value)) type = 'Function' // @mock=function(){} => Function + if (/^\$order/.test(value)) { // $order => Array|+1 + type = 'Array' + rule = '+1' + let orderArgs = /\$order\((.+)\)/.exec(value) + if (orderArgs) value = `[${orderArgs[1]}]` + } + let description = [] + if (p.name) description.push(p.name) + if (p.remark && remarkWithoutMock) description.push(remarkWithoutMock) + const pCreated = await Property.create({ scope, - name: p.identifier, - type: getTypeFromRAP1DataType(p.dataType), + name, + rule, + value, + type, description: `${p.remark}${p.name ? ', ' + p.name : ''}`, priority: pCounter++, interfaceId: itf.id, @@ -88,6 +109,7 @@ export default class MigrateService { } } + /** RAP1 property */ public static async importRepoFromRAP1DocUrl(orgId: number, curUserId: number, docUrl: string): Promise { const { projectId } = querystring.parse(docUrl.substring(docUrl.indexOf('?') + 1)) let domain = docUrl @@ -122,21 +144,31 @@ function getMethodFromRAP1RequestType(type: number) { } } -function getTypeFromRAP1DataType(dataType: string) { - switch (dataType) { - case 'number': - return TYPES.NUMBER - case 'string': - return TYPES.STRING - case 'boolean': - return TYPES.BOOLEAN - case 'object': - return TYPES.OBJECT - default: - if (dataType && dataType.indexOf('array') > -1) { - return TYPES.ARRAY - } else { - return TYPES.STRING - } - } -} \ No newline at end of file +// function getTypeFromRAP1DataType(dataType: string) { +// switch (dataType) { +// case 'number': +// return TYPES.NUMBER +// case 'string': +// return TYPES.STRING +// case 'boolean': +// return TYPES.BOOLEAN +// case 'object': +// return TYPES.OBJECT +// default: +// if (dataType && dataType.indexOf('array') > -1) { +// return TYPES.ARRAY +// } else { +// return TYPES.STRING +// } +// } +// } + +interface OldParameter { + id: number + name: string + mockData: string + identifier: string + remark: string + dataType: string + parameterList: OldParameter[] +}