Skip to content

Commit

Permalink
feat: save api from test add response body
Browse files Browse the repository at this point in the history
  • Loading branch information
scarqin committed Jan 21, 2022
1 parent 835a125 commit 686d851
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 151 deletions.
4 changes: 2 additions & 2 deletions src/app/eoui/editor/eo-editor/eo-editor.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, Input, Output, EventEmitter, OnChanges, AfterViewInit, ViewChild } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { AceConfigInterface, AceComponent, AceDirective } from 'ngx-ace-wrapper';
import { whatRootType } from '../../../utils';
import { whatTextType } from '../../../utils';
import beautifier from 'js-beautify';
import 'brace';
import 'brace/theme/tomorrow_night_eighties';
Expand Down Expand Up @@ -94,7 +94,7 @@ export class EoEditorComponent implements AfterViewInit, OnChanges {
ngOnChanges() {
// * update root type
if (this.eventList.includes('type') && !this.hiddenList.includes('type')) {
const type = whatRootType(this.code || '');
const type = whatTextType(this.code || '');
this.editorType = type;
if (this.autoFormat) {
this.code = this.formatCode(this.code, type);
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/api/api.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</div>
</div>
<div class="content_container {{ this.id ? 'has_tab_page' : '' }}">
<nz-tabset class="inside_page_tab" *ngIf="this.id" nzLinkRouter>
<nz-tabset class="inside_page_tab" *ngIf="this.id" nzLinkRouter>
<nz-tab>
<a *nzTabLink nz-tab-link [routerLink]="['detail']" queryParamsHandling="merge"> 文档 </a>
</nz-tab>
Expand Down
9 changes: 1 addition & 8 deletions src/app/pages/api/edit/api-edit.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ import { MessageService } from '../../../shared/services/message';
import { Group } from '../../../shared/services/group/group.model';
import { GroupService } from '../../../shared/services/group/group.service';

import { objectToArray } from '../../../utils';
import { objectToArray,getRest } from '../../../utils';
import { treeToListHasLevel, listToTree, listToTreeHasLevel } from '../../../utils/tree';
import { getRest } from '../../../utils/api';

@Component({
selector: 'eo-api-edit-edit',
Expand Down Expand Up @@ -130,12 +129,6 @@ export class ApiEditComponent implements OnInit, OnDestroy {
//Add From Test
Object.assign(
this.apiData,
{
responseHeaders: [],
responseBodyType: 'json',
responseBodyJsonType: 'object',
responseBody: [],
},
JSON.parse(testData)
);
} else {
Expand Down
20 changes: 16 additions & 4 deletions src/app/pages/api/test/api-test.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ApiTestQuery } from '../../../shared/services/api-test/api-test-params.
import { ApiTestHistory } from '../../../shared/services/api-test-history/api-test-history.model';

import { treeToListHasLevel } from '../../../utils/tree';
import { text2UiData } from '../../../utils/data-transfer';

@Injectable()
export class ApiTestService {
Expand Down Expand Up @@ -227,7 +228,7 @@ export class ApiTestService {
return HTTP_CODE_STATUS.find((val) => statusCode <= val.cap);
}
getTestDataFromHistory(inData: ApiTestHistory) {
console.log(inData)
console.log(inData);
let result = {
testData: {
uuid: inData.apiDataID,
Expand All @@ -251,6 +252,7 @@ export class ApiTestService {
* @returns {ApiData}
*/
getApiFromTestData(inData) {
console.log('getApiFromTestData=>', inData);
let testToEditParams = (arr) => {
let result = [];
arr.forEach((val) => {
Expand All @@ -263,12 +265,23 @@ export class ApiTestService {
};
let result = {
...inData.testData,
responseHeaders: [],
responseBodyType: 'json',
responseBodyJsonType: 'object',
responseBody: [],
};
delete result.uuid;
['requestHeaders', 'requestBody', 'restParams', 'queryParams'].forEach((keyName) => {
if (!result[keyName] || typeof result[keyName] !== 'object') return;
result[keyName] = testToEditParams(result[keyName]);
});
if(inData.history.response.responseType==='text'){
let bodyInfo=text2UiData(inData.history.response.body)
result.responseBody=bodyInfo.data;
result.responseBodyType=bodyInfo.textType;
result.responseBodyJsonType=bodyInfo.rootType;
}
console.log('getApiFromTestData=>', result);
return result;
}
getTestDataFromApi(inData) {
Expand Down Expand Up @@ -298,8 +311,7 @@ export class ApiTestService {
let typeSorts = [
{
type: 'string',
match: ['file',
'date', 'datetime', 'char', 'byte'],
match: ['file', 'date', 'datetime', 'char', 'byte'],
},
{
type: 'number',
Expand All @@ -325,7 +337,7 @@ export class ApiTestService {
case 'formData': {
inData.requestBody.forEach((val) => {
val.value = val.example;
val.type='string';
val.type = 'string';
delete val.example;
});
break;
Expand Down
27 changes: 4 additions & 23 deletions src/app/shared/components/params-import/params-import.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { whatType } from '../../../utils';
import { flatData, form2json, xml2json, parseTree } from '../../../utils/tree';
import { flatData } from '../../../utils/tree';
import { form2json, parseTree, xml2UiData } from '../../../utils/data-transfer';
@Component({
selector: 'params-import',
templateUrl: './params-import.component.html',
Expand All @@ -14,8 +15,7 @@ export class ParamsImportComponent {
@Output() baseDataChange = new EventEmitter<any>();
isVisible = false;
paramCode = '';

constructor(private message: NzMessageService) { }
constructor(private message: NzMessageService) {}

get contentTypeTitle() {
switch (this.contentType) {
Expand Down Expand Up @@ -66,19 +66,7 @@ export class ParamsImportComponent {
paramCode = JSON.parse(JSON.stringify(json));
}
if (this.contentType === 'xml') {
const data: any[] = xml2json(this.paramCode);
const res = {};
const mapAttr = (obj: any) => {
const { tagName, attr, children } = obj;
return {
[tagName]: children.length ? mapAttr(children[0]) : attr,
};
};
data.forEach((it) => {
const { tagName, attr, children } = it;
res[tagName] = children.length ? mapAttr(children[0]) : attr;
});
paramCode = JSON.parse(JSON.stringify(res));
paramCode = JSON.parse(JSON.stringify(xml2UiData(this.paramCode)));
}
if (this.contentType === 'raw') {
paramCode = this.paramCode;
Expand All @@ -100,13 +88,6 @@ export class ParamsImportComponent {
}
// * tree to array for table render
const cacheData = flatData(Object.keys(paramCode).map((it) => parseTree(it, paramCode[it])));
console.log(
JSON.stringify(
Object.keys(paramCode).map((it) => parseTree(it, paramCode[it])),
null,
2
)
);
// TODO delete useless attribute in cacheData
switch (type) {
case 'mixin': {
Expand Down
3 changes: 0 additions & 3 deletions src/app/utils/api.ts

This file was deleted.

167 changes: 167 additions & 0 deletions src/app/utils/data-transfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { whatType, whatTextType } from '.';
import { ApiBodyType, JsonRootType } from '../shared/services/api-data/api-data.model';
import { flatData } from './tree';

/**
* Parse item to table need row data
*/
export const parseTree = (key, value, level = 0) => {
if (whatType(value) === 'object') {
return {
name: key,
required: true,
example: '',
type: 'object',
description: '',
listDepth: level,
children: Object.keys(value).map((it) => parseTree(it, value[it], level + 1)),
};
}
if (whatType(value) === 'array') {
const [data] = value;
return {
name: key,
required: true,
example: '',
type: 'array',
description: '',
listDepth: level,
children: data ? Object.keys(data).map((it) => parseTree(it, data[it], level + 1)) : [],
};
}
return {
name: key,
value,
description: '',
type: whatType(value),
required: true,
example: value || '',
listDepth: level,
};
};
/**
* Parse item to table need row data
*/
export const form2json = (tmpl) =>
tmpl
.split('\n')
.filter((it) => it.trim())
.map((it) => it.split(':'))
.map((it) => {
const [key, value] = it;
return { key: key.trim(), value: value.trim() };
});

export const xml2json = (tmpl) => {
// * delete <?xml ... ?>
let xml = tmpl.replace(/<\?xml.+\?>/g, '').trim();
if (xml === '') {
return [];
}
const startTag = /^<([^>\s\/]+)((\s+[^=>\s]+(\s*=\s*((\"[^"]*\")|(\'[^']*\')|[^>\s]+))?)*)\s*\/?\s*>/m;
const endTag = /^<\/([^>\s]+)[^>]*>/m;
const stack = [];
const result = [];
let start = null;
let index = null;
while (xml) {
// * handle end tags
if (xml.substring(0, 2) === '</') {
const end = xml.match(endTag);
const [str, label] = end;
const last = stack.pop();
if (last.tagName !== label) {
throw new Error('Parse error 101');
}
if (stack.length === 0) {
result.push(last);
} else {
const parent = stack.pop();
parent.children.push(last);
stack.push(parent);
}
xml = xml.substring(str.length);
continue;
}
// * handle start tags
if ((start = xml.match(startTag))) {
const [str, label, attr] = start;
stack.push({
tagName: label.trim(),
attr: attr.trim(),
content: '',
children: [],
});
xml = xml.trim().substring(str.length);
continue;
}
// * handle text content
if ((index = xml.indexOf('<') > 0)) {
const content = xml.slice(0, index);
const last = stack.pop();
last.content += content;
stack.push(last);
xml = xml.substring(index);
index = null;
}
xml = xml.trim();
}
if (stack.length) {
throw new Error('Parse error 102');
}
return result;
};

interface uiData {
textType: ApiBodyType | string;
rootType: JsonRootType | string;
data: any;
}
export const xml2UiData = (text) => {
const data: any[] = xml2json(text);
const result = {};
const mapAttr = (obj: any) => {
const { tagName, attr, children } = obj;
return {
[tagName]: children.length ? mapAttr(children[0]) : attr,
};
};
data.forEach((it) => {
const { tagName, attr, children } = it;
result[tagName] = children.length ? mapAttr(children[0]) : attr;
});
return JSON.parse(JSON.stringify(result));
};
/**
* Transfer text to json/xml/raw ui data,such as request body/response body
* @returns {object} body info
*/
export const text2UiData: (text: string) => uiData = (text) => {
let result: uiData = {
textType: 'raw',
rootType: 'json',
data: text,
};
let textType = whatTextType(text);
result.textType = ['xml', 'json'].includes(textType) ? textType : 'raw';
switch (result.textType) {
case 'xml': {
result.data = xml2UiData(text);
result.data = flatData(Object.keys(result.data).map((it) => parseTree(it, result.data[it])));
break;
}
case 'json': {
try {
result.data = JSON.parse(result.data);
result.data = flatData(Object.keys(result.data).map((it) => parseTree(it, result.data[it])));
} catch (error) {
result.textType = 'raw';
}
break;
}
default: {
break;
}
}
return result;
};
16 changes: 13 additions & 3 deletions src/app/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
export const uuid = (): string => Math.random().toString(36).slice(-8);
/**
* get rest param from url,format like {restName}
* @param url
* @returns {Array[string]}
*/
export const getRest: (url: string) => string[] = (url) => {
return [...url.replace(/{{(.*?)}}/g, '').matchAll(/{(.*?)}/g)].map((val) => val[1]);
};

export const addEnvPrefix = (prefix, uri) => {
// * 需要先判断uri是否已经包含 http:// 前缀
Expand All @@ -17,7 +25,6 @@ export const addEnvPrefix = (prefix, uri) => {
// '(^((http|wss|ws|ftp|https)://))|(^(((http|wss|ws|ftp|https)://)|)(([\\w\\-_]+([\\w\\-\\.]*)?(\\.(' +
// DOMAIN_CONSTANT.join('|') +
// ')))|((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(localhost))((\\/)|(\\?)|(:)|($)))';

export const whatType = (data: any): string => {
if (data === undefined) {
return 'undefined';
Expand All @@ -42,8 +49,11 @@ export const whatType = (data: any): string => {
}
return 'unknown';
};

export const whatRootType = (tmpText) => {
/**
* judge text content type
* @returns textType - xml|json|html|text
*/
export const whatTextType = (tmpText) => {
// TODO it can be better
const tmpCompareText = tmpText.replace(/\s/g, '');
if (/^({|\[)(.*)(}|])$/.test(tmpCompareText) && JSON.parse(tmpCompareText)) {
Expand Down
Loading

0 comments on commit 686d851

Please sign in to comment.