mirror of
https://gitee.com/eolink_admin/postcat.git
synced 2024-11-29 18:28:09 +08:00
merge feat/import
This commit is contained in:
parent
af64099769
commit
d230860670
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "eoapi",
|
||||
"souceLocale": "zh-Hans",
|
||||
"version": "1.5.1",
|
||||
"version": "1.6.0",
|
||||
"main": "out/app/electron-main/main.js",
|
||||
"description": "A lightweight, extensible API tool",
|
||||
"homepage": "https://github.com/eolinker/eoapi.git",
|
||||
|
@ -53,7 +53,6 @@ window.eo.loadFeatureModule = (moduleID) => {
|
||||
if (!featureModules.has(moduleID)) {
|
||||
try {
|
||||
const module = window.eo.getModule(moduleID);
|
||||
console.log('featureModules module', module);
|
||||
window.eo._currentExtensionID = moduleID;
|
||||
const _module = require(module.baseDir);
|
||||
featureModules.set(moduleID, _module);
|
||||
|
@ -33,12 +33,13 @@
|
||||
"@ant-design/icons-angular": "13.1.0",
|
||||
"@babel/runtime": "7.18.3",
|
||||
"@ngxs/store": "3.7.4",
|
||||
"ajv": "8.11.0",
|
||||
"angular": "1.8.2",
|
||||
"brace": "0.11.1",
|
||||
"js-beautify": "1.14.4",
|
||||
"markdown-it": "13.0.1",
|
||||
"monaco-editor": "0.33.0",
|
||||
"ng-zorro-antd": "13.3.2",
|
||||
"ng-zorro-antd": "13.4.0",
|
||||
"ngx-ace-wrapper": "12.0.0",
|
||||
"qs": "6.11.0",
|
||||
"rxjs": "7.5.5",
|
||||
@ -93,4 +94,4 @@
|
||||
"chrome 98"
|
||||
],
|
||||
"__npminstall_done": false
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,12 @@ export class LanguageService {
|
||||
languages = LANGUAGES;
|
||||
//If the user does not set it, the system default language is used
|
||||
// Web from nginx setting and App from computer system setting
|
||||
systemLanguage =
|
||||
systemLanguage =this.setting.getSettings()?.['eoapi-language']||
|
||||
this.languages.find((val) => window.location.href.includes(`/${val.path}`))?.value ||
|
||||
(navigator.language.includes('zh') ? 'zh-Hans' : 'en-US');
|
||||
|
||||
constructor(private remote: RemoteService, private electron: ElectronService,private setting:SettingService) {}
|
||||
constructor(private remote: RemoteService, private electron: ElectronService,private setting: SettingService) {
|
||||
}
|
||||
|
||||
init() {
|
||||
this.changeLanguage(this.setting.getSettings()?.['eoapi-language']);
|
||||
|
@ -43,6 +43,10 @@ import { ApiTabStorageService } from 'eo/workbench/browser/src/app/pages/api/tab
|
||||
import { ApiTabOperateService } from 'eo/workbench/browser/src/app/pages/api/tab/api-tab-operate.service';
|
||||
import { ApiTabService } from 'eo/workbench/browser/src/app/pages/api/api-tab.service';
|
||||
import { NzSpinModule } from 'ng-zorro-antd/spin';
|
||||
|
||||
import { ImportOutline, ExportOutline, SyncOutline,PlusOutline } from '@ant-design/icons-angular/icons';
|
||||
import { IconDefinition } from '@ant-design/icons-angular';
|
||||
const icons: IconDefinition[] = [ ImportOutline, ExportOutline, SyncOutline,PlusOutline ];
|
||||
const COMPONENTS = [
|
||||
ApiComponent,
|
||||
ApiGroupEditComponent,
|
||||
@ -59,11 +63,11 @@ const COMPONENTS = [
|
||||
imports: [
|
||||
HttpClientModule,
|
||||
FormsModule,
|
||||
NzIconModule.forRoot(icons),
|
||||
ReactiveFormsModule,
|
||||
CommonModule,
|
||||
ApiRoutingModule,
|
||||
NzButtonModule,
|
||||
NzIconModule,
|
||||
NzTabsModule,
|
||||
NzLayoutModule,
|
||||
NzTreeModule,
|
||||
|
@ -12,6 +12,7 @@ import { StorageService } from '../../../shared/services/storage';
|
||||
|
||||
import {
|
||||
Group,
|
||||
ApiEditViewData,
|
||||
ApiData,
|
||||
RequestProtocol,
|
||||
RequestMethod,
|
||||
@ -30,15 +31,15 @@ import { ApiEditUtilService } from './api-edit-util.service';
|
||||
styleUrls: ['./api-edit.component.scss'],
|
||||
})
|
||||
export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
@Input() model: ApiData;
|
||||
@Input() model: ApiEditViewData;
|
||||
/**
|
||||
* Intial model from outside,check form is change
|
||||
* * Usually restored from tab
|
||||
*/
|
||||
@Input() initialModel: ApiData;
|
||||
@Output() modelChange = new EventEmitter<ApiData>();
|
||||
@Output() afterInit = new EventEmitter<ApiData>();
|
||||
@Output() afterSaved = new EventEmitter<ApiData>();
|
||||
@Input() initialModel: ApiEditViewData;
|
||||
@Output() modelChange = new EventEmitter<ApiEditViewData>();
|
||||
@Output() afterInit = new EventEmitter<ApiEditViewData>();
|
||||
@Output() afterSaved = new EventEmitter<ApiEditViewData>();
|
||||
@ViewChild('apiGroup') apiGroup: NzTreeSelectComponent;
|
||||
validateForm: FormGroup;
|
||||
groups: any[];
|
||||
@ -72,7 +73,7 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
const id = Number(this.route.snapshot.queryParams.uuid);
|
||||
const groupID = Number(this.route.snapshot.queryParams.groupID || 0);
|
||||
if (!this.model || isEmptyObj(this.model)) {
|
||||
this.model = {} as ApiData;
|
||||
this.model = {} as ApiEditViewData;
|
||||
const initTimes = this.initTimes;
|
||||
const result = await this.apiEdit.getApi({
|
||||
id,
|
||||
@ -213,7 +214,7 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
* Resolve the problem that groupID change but view not change
|
||||
*/
|
||||
private resetGroupID() {
|
||||
let groupID: number | string = '-1';
|
||||
let groupID = '-1';
|
||||
if (this.model && this.model.groupID) {
|
||||
groupID = this.model.groupID;
|
||||
this.model.groupID = '';
|
||||
@ -229,7 +230,7 @@ export class ApiEditComponent implements OnInit, OnDestroy {
|
||||
private initBasicForm() {
|
||||
//Prevent init error
|
||||
if (!this.model) {
|
||||
this.model = {} as ApiData;
|
||||
this.model = {} as ApiEditViewData;
|
||||
}
|
||||
const controls = {};
|
||||
['protocol', 'method', 'uri', 'groupID', 'name'].forEach((name) => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ApiService } from 'eo/workbench/browser/src/app/pages/api/api.service';
|
||||
import { StorageService } from 'eo/workbench/browser/src/app/shared/services/storage';
|
||||
import { ApiData, StorageRes } from 'eo/workbench/browser/src/app/shared/services/storage/index.model';
|
||||
import { ApiBodyType, ApiData, ApiEditViewData, JsonRootType, StorageRes } from 'eo/workbench/browser/src/app/shared/services/storage/index.model';
|
||||
import { RequestMethod, RequestProtocol } from '../../../shared/services/storage/index.model';
|
||||
import { ApiEditUtilService } from './api-edit-util.service';
|
||||
@Injectable()
|
||||
@ -22,21 +22,21 @@ export class ApiEditService {
|
||||
method: RequestMethod.POST,
|
||||
},
|
||||
{
|
||||
requestBodyType: 'json',
|
||||
requestBodyJsonType: 'object',
|
||||
requestBodyType: ApiBodyType.JSON,
|
||||
requestBodyJsonType: JsonRootType.Object,
|
||||
requestBody: [],
|
||||
queryParams: [],
|
||||
restParams: [],
|
||||
requestHeaders: [],
|
||||
responseHeaders: [],
|
||||
responseBodyType: 'json',
|
||||
responseBodyJsonType: 'object',
|
||||
responseBodyType: ApiBodyType.JSON,
|
||||
responseBodyJsonType: JsonRootType.Object,
|
||||
responseBody: [],
|
||||
}
|
||||
);
|
||||
}
|
||||
async getApi({ id, groupID }): Promise<ApiData> {
|
||||
let result: ApiData = {} as ApiData;
|
||||
async getApi({ id, groupID }): Promise<ApiEditViewData> {
|
||||
let result= {} as ApiData;
|
||||
if (!id) {
|
||||
// From test page/copy api data;
|
||||
let tmpApiData = window.sessionStorage.getItem('apiDataWillbeSave');
|
||||
@ -55,7 +55,7 @@ export class ApiEditService {
|
||||
result = pureApi;
|
||||
}
|
||||
} else {
|
||||
result = (await this.apiService.get(id)) as ApiData;
|
||||
result = (await this.apiService.get(id));
|
||||
}
|
||||
return this.apiEditUtil.getFormdataFromApiData(result);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import { NzTreeComponent } from 'ng-zorro-antd/tree';
|
||||
import { ModalService } from '../../../../shared/services/modal.service';
|
||||
import { StorageService } from '../../../../shared/services/storage';
|
||||
import { ElectronService } from '../../../../core/services';
|
||||
import { createMockObj, IndexedDBStorage } from 'eo/workbench/browser/src/app/shared/services/storage/IndexedDB/lib/';
|
||||
import { ApiService } from 'eo/workbench/browser/src/app/pages/api/api.service';
|
||||
@Component({
|
||||
selector: 'eo-api-group-tree',
|
||||
@ -69,7 +68,6 @@ export class ApiGroupTreeComponent implements OnInit, OnDestroy {
|
||||
private messageService: MessageService,
|
||||
private storage: StorageService,
|
||||
public electron: ElectronService,
|
||||
public storageInstance: IndexedDBStorage,
|
||||
private apiService: ApiService,
|
||||
private nzModalService: NzModalService
|
||||
) {}
|
||||
@ -163,17 +161,6 @@ export class ApiGroupTreeComponent implements OnInit, OnDestroy {
|
||||
...(getExpandGroupByKey(this.apiGroup, this.route.snapshot.queryParams.uuid) || []),
|
||||
];
|
||||
}
|
||||
async createGroup({ name, projectID, content }) {
|
||||
const groupID = await this.storageInstance.group.add({ name: name.replace(/\.json$/, ''), projectID });
|
||||
const result = content.apiData.map(({ uuid, ...it }, index) => ({ ...it, groupID }));
|
||||
const apiDataKeys = await this.storageInstance.apiData.bulkAdd(result, { allKeys: true });
|
||||
const apiData = result.map((n, i) =>
|
||||
createMockObj(n, { name: $localize`Default Mock`, createWay: 'system', apiDataID: apiDataKeys.at(i) })
|
||||
);
|
||||
this.storageInstance.mock.bulkAdd(apiData);
|
||||
this.buildGroupTreeData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch apiData change event.
|
||||
*/
|
||||
@ -187,13 +174,11 @@ export class ApiGroupTreeComponent implements OnInit, OnDestroy {
|
||||
case 'editApiSuccess':
|
||||
case 'copyApiSuccess':
|
||||
case 'deleteApiSuccess':
|
||||
case 'importSuccess':
|
||||
case 'updateGroupSuccess': {
|
||||
this.buildGroupTreeData();
|
||||
break;
|
||||
}
|
||||
case 'importSuccess': {
|
||||
this.createGroup({ projectID: 1, ...inArg.data });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -240,7 +240,9 @@ export class ApiTestUtilService {
|
||||
result[keyName] = this.testTableData2ApiBody(result[keyName]);
|
||||
});
|
||||
if (inData.history.response.responseType === 'text') {
|
||||
console.log('inData.history.response.body', inData.history.response.body);
|
||||
const bodyInfo = text2UiData(inData.history.response.body);
|
||||
console.log('bodyInfo', bodyInfo);
|
||||
result.responseBody = listToTreeHasLevel(bodyInfo.data);
|
||||
result.responseBodyType = bodyInfo.textType;
|
||||
result.responseBodyJsonType = bodyInfo.rootType;
|
||||
|
@ -5,7 +5,7 @@
|
||||
class="bd_all w-full min-h-[140px] p-5 flex flex-col flex-wrap items-center plugin-block hover:border-green-700 hover:shadow-lg transition-shadow duration-300"
|
||||
*ngFor="let it of renderList" (click)="clickExtension(it)">
|
||||
<div class="flex w-full">
|
||||
<div class="shrink-0 block w-[40px] h-[40px] rounded-lg bg-cover bg-center bg-no-repeat mr-[20px]"
|
||||
<div class="shrink-0 block w-[40px] h-[40px] rounded-lg bg-[length:90%] bg-center bg-no-repeat mr-[20px]"
|
||||
[ngClass]="{ 'bg-gray-100': it.logo }" [ngStyle]="{ 'background-image': 'url(' + (it.logo || '') + ')' }">
|
||||
</div>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
<i nz-icon nzType="inbox"></i>
|
||||
</p>
|
||||
<p class="ant-upload-text" i18n>Tap or drag files directly to this area</p>
|
||||
<p class="ant-upload-hint" i18n>Only individual files in Json format are supported</p>
|
||||
<p class="ant-upload-hint" i18n>Only supports importing a single file</p>
|
||||
</nz-upload>
|
||||
<div class="text h-4 my-2">{{ filename }}</div>
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@
|
||||
transition: all 0.3s ease;
|
||||
.logobg {
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-size: 45px;
|
||||
background-position: center center;
|
||||
}
|
||||
&.active {
|
||||
|
@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { FeatureType } from '../../types';
|
||||
import { EoMessageService } from 'eo/workbench/browser/src/app/eoui/message/eo-message.service';
|
||||
import { MessageService } from 'eo/workbench/browser/src/app/shared/services/message/message.service';
|
||||
import { StorageService } from 'eo/workbench/browser/src/app/shared/services/storage';
|
||||
import { StorageRes, StorageResStatus } from 'eo/workbench/browser/src/app/shared/services/storage/index.model';
|
||||
|
||||
// const optionList = [
|
||||
// {
|
||||
@ -48,7 +50,11 @@ export class ImportApiComponent implements OnInit {
|
||||
currentExtension = '';
|
||||
uploadData = null;
|
||||
featureMap = window.eo.getFeature('apimanage.import');
|
||||
constructor(private messageService: MessageService, private eoMessage: EoMessageService) {}
|
||||
constructor(
|
||||
private messageService: MessageService,
|
||||
private storage: StorageService,
|
||||
private eoMessage: EoMessageService
|
||||
) {}
|
||||
ngOnInit(): void {
|
||||
this.featureMap?.forEach((data: FeatureType, key: string) => {
|
||||
this.supportList.push({
|
||||
@ -65,6 +71,10 @@ export class ImportApiComponent implements OnInit {
|
||||
this.uploadData = data;
|
||||
}
|
||||
async submit(callback) {
|
||||
if(!this.uploadData){
|
||||
this.eoMessage.error($localize `Please import the file first`);
|
||||
return;
|
||||
}
|
||||
// * this.currentExtension is extension's key, like 'eoapi-import-openapi'
|
||||
const feature = this.featureMap.get(this.currentExtension);
|
||||
const action = feature.action || null;
|
||||
@ -76,10 +86,14 @@ export class ImportApiComponent implements OnInit {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
// console.log(JSON.stringify(data, null, 2));
|
||||
this.messageService.send({
|
||||
type: 'importSuccess',
|
||||
data: { name, content: data },
|
||||
console.log(data);
|
||||
this.storage.run('projectImport', [1, data], (result: StorageRes) => {
|
||||
if (result.status === StorageResStatus.success) {
|
||||
this.messageService.send({
|
||||
type: 'importSuccess',
|
||||
data: { },
|
||||
});
|
||||
}
|
||||
});
|
||||
callback(true);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ApiData } from '../../index.model';
|
||||
import { JsonRootType, RequestProtocol, RequestMethod, ApiBodyType } from '../../index.model';
|
||||
|
||||
export const sampleApiData: ApiData[] = [
|
||||
{
|
||||
@ -6,10 +7,10 @@ export const sampleApiData: ApiData[] = [
|
||||
projectID: 1,
|
||||
uri: 'http://www.weather.com.cn/data/cityinfo/{cityCode}.html',
|
||||
groupID: 0,
|
||||
protocol: 'http',
|
||||
method: 'GET',
|
||||
requestBodyType: 'raw',
|
||||
requestBodyJsonType: 'object',
|
||||
protocol: RequestProtocol.HTTP,
|
||||
method: RequestMethod.GET,
|
||||
requestBodyType: ApiBodyType.Raw,
|
||||
requestBodyJsonType: JsonRootType.Object,
|
||||
requestBody: '',
|
||||
queryParams: [],
|
||||
restParams: [
|
||||
@ -27,8 +28,8 @@ export const sampleApiData: ApiData[] = [
|
||||
],
|
||||
requestHeaders: [],
|
||||
responseHeaders: [],
|
||||
responseBodyType: 'json',
|
||||
responseBodyJsonType: 'object',
|
||||
responseBodyType: ApiBodyType.JSON,
|
||||
responseBodyJsonType: JsonRootType.Object,
|
||||
responseBody: [
|
||||
{
|
||||
name: 'weatherinfo',
|
||||
@ -39,8 +40,20 @@ export const sampleApiData: ApiData[] = [
|
||||
children: [
|
||||
{ name: 'city', description: '', type: 'string', required: true, example: '北京' },
|
||||
{ name: 'cityid', description: '', type: 'string', required: true, example: '101010100' },
|
||||
{ name: 'temp1', description: $localize`minimum temperature`, type: 'string', required: true, example: '18℃' },
|
||||
{ name: 'temp2', description: $localize`maximun temperature`, type: 'string', required: true, example: '31℃' },
|
||||
{
|
||||
name: 'temp1',
|
||||
description: $localize`minimum temperature`,
|
||||
type: 'string',
|
||||
required: true,
|
||||
example: '18℃',
|
||||
},
|
||||
{
|
||||
name: 'temp2',
|
||||
description: $localize`maximun temperature`,
|
||||
type: 'string',
|
||||
required: true,
|
||||
example: '31℃',
|
||||
},
|
||||
{ name: 'weather', description: '', type: 'string', required: true, example: '多云转阴' },
|
||||
{ name: 'img1', description: '', type: 'string', required: true, example: 'n1.gif' },
|
||||
{ name: 'img2', description: '', type: 'string', required: true, example: 'd2.gif' },
|
||||
@ -55,12 +68,12 @@ export const sampleApiData: ApiData[] = [
|
||||
projectID: 1,
|
||||
uri: 'https://view.inews.qq.com/g2/getOnsInfo',
|
||||
groupID: 0,
|
||||
protocol: 'http',
|
||||
method: 'GET',
|
||||
requestBodyType: 'raw',
|
||||
requestBodyJsonType: 'object',
|
||||
protocol: RequestProtocol.HTTP,
|
||||
method: RequestMethod.GET,
|
||||
requestBodyType: ApiBodyType.Raw,
|
||||
requestBodyJsonType: JsonRootType.Object,
|
||||
requestBody: '',
|
||||
queryParams: [{ name: 'name', required: true, example: 'disease_h5',description:'' }],
|
||||
queryParams: [{ name: 'name', required: true, example: 'disease_h5', description: '' }],
|
||||
restParams: [],
|
||||
requestHeaders: [],
|
||||
responseHeaders: [
|
||||
@ -73,8 +86,8 @@ export const sampleApiData: ApiData[] = [
|
||||
{ name: 'x-client-ip', required: true, description: '', example: '120.26.198.150' },
|
||||
{ name: 'x-server-ip', required: true, description: '', example: '58.250.137.40' },
|
||||
],
|
||||
responseBodyType: 'json',
|
||||
responseBodyJsonType: 'object',
|
||||
responseBodyType: ApiBodyType.JSON,
|
||||
responseBodyJsonType: JsonRootType.Object,
|
||||
responseBody: [
|
||||
{ name: 'ret', description: '', type: 'number', required: true, example: '' },
|
||||
{
|
@ -1,10 +1,9 @@
|
||||
import Dexie, { Table } from 'dexie';
|
||||
import { getSettings } from 'eo/workbench/browser/src/app/core/services/settings/settings.service';
|
||||
import { messageService } from 'eo/workbench/browser/src/app/shared/services/message/message.service';
|
||||
import { DataSourceType } from 'eo/workbench/browser/src/app/shared/services/storage/storage.service';
|
||||
import { uniqueSlash } from 'eo/workbench/browser/src/app/utils/api';
|
||||
import { tree2obj } from 'eo/workbench/browser/src/app/utils/tree/tree.utils';
|
||||
import { Observable } from 'rxjs';
|
||||
import { firstValueFrom, Observable } from 'rxjs';
|
||||
import {
|
||||
Project,
|
||||
Environment,
|
||||
@ -16,7 +15,9 @@ import {
|
||||
StorageItem,
|
||||
StorageResStatus,
|
||||
} from '../../index.model';
|
||||
import { sampleApiData } from '../sample';
|
||||
|
||||
import { parseAndCheckApiData, parseAndCheckEnv, parseAndCheckGroup } from './validate';
|
||||
import { sampleApiData } from './index.constant';
|
||||
|
||||
export type ResultType<T = any> = {
|
||||
status: StorageResStatus.success;
|
||||
@ -94,11 +95,6 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
status: StorageResStatus.success,
|
||||
data,
|
||||
};
|
||||
// if (isNotEmpty(data)) {
|
||||
// result.status = StorageResStatus.success;
|
||||
// } else {
|
||||
// result.status = StorageResStatus.empty;
|
||||
// }
|
||||
return result as ResultType;
|
||||
}
|
||||
/**
|
||||
@ -107,7 +103,7 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
* @param table
|
||||
* @param item
|
||||
*/
|
||||
private create(table: Table, item: StorageItem): Observable<object> {
|
||||
private create(table: Table, item: StorageItem): Observable<any> {
|
||||
if (!item.createdAt) {
|
||||
item.createdAt = new Date();
|
||||
}
|
||||
@ -134,6 +130,7 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
*/
|
||||
private bulkCreate(table: Table, items: Array<StorageItem>): Observable<object> {
|
||||
items = items.map((item: StorageItem) => {
|
||||
delete item.uuid;
|
||||
if (!item.createdAt) {
|
||||
item.createdAt = new Date();
|
||||
}
|
||||
@ -470,9 +467,7 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
apiTestHistoryLoad = (uuid: number | string): Observable<object> => {
|
||||
return this.load(this.apiTestHistory, uuid);
|
||||
};
|
||||
apiTestHistoryLoad = (uuid: number | string): Observable<object> => this.load(this.apiTestHistory, uuid);
|
||||
|
||||
/**
|
||||
* Load all apiTestHistory items by apiDataID.
|
||||
@ -643,7 +638,7 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
groupCreate(item: Group): Observable<object> {
|
||||
groupCreate(item: Group): Observable<ResultType<Group>> {
|
||||
return this.create(this.group, item);
|
||||
}
|
||||
|
||||
@ -678,12 +673,66 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
groupUpdate(item: Group, uuid: number | string): Observable<object> {
|
||||
return this.update(this.group, item, uuid);
|
||||
}
|
||||
|
||||
projectImport(uuid: number, data): Observable<object> {
|
||||
return new Observable((obs) => {
|
||||
const errors = {
|
||||
apiData: [],
|
||||
};
|
||||
//Add api and group
|
||||
const deepFn = (collections, parentID) =>
|
||||
new Promise((resolve) => {
|
||||
collections.forEach(async (item) => {
|
||||
item.projectID = uuid;
|
||||
//Judge item is api or group
|
||||
if (item.uri || item.method || item.protocol) {
|
||||
delete item.uuid;
|
||||
item.groupID = parentID;
|
||||
const result = parseAndCheckApiData(item);
|
||||
if (!result.validate) {
|
||||
errors.apiData.push(item.name || item.uri);
|
||||
return;
|
||||
}
|
||||
this.apiDataCreate(result.data);
|
||||
} else {
|
||||
item.parentID = parentID;
|
||||
const result = parseAndCheckGroup(item);
|
||||
if (!result.validate) {
|
||||
return;
|
||||
}
|
||||
item.uuid = (await firstValueFrom(this.groupCreate(result.data))).data.uuid;
|
||||
}
|
||||
if (item.children?.length) {
|
||||
await deepFn(item.children, item.uuid);
|
||||
}
|
||||
resolve('');
|
||||
});
|
||||
});
|
||||
deepFn(data.collections, 0);
|
||||
//Add env
|
||||
if (data.enviroments && data.enviroments.length) {
|
||||
data.enviroments.forEach((item) => {
|
||||
item.projectID = uuid;
|
||||
const result = parseAndCheckEnv(item);
|
||||
if (!result.validate) {
|
||||
return;
|
||||
}
|
||||
this.environmentCreate(result.data);
|
||||
});
|
||||
}
|
||||
obs.next(
|
||||
this.resProxy({
|
||||
errors,
|
||||
})
|
||||
);
|
||||
obs.complete();
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Bulk create project items.
|
||||
*
|
||||
* @param items
|
||||
*/
|
||||
|
||||
projectBulkCreate(items: Array<Project>): Observable<object> {
|
||||
return this.bulkCreate(this.project, items);
|
||||
}
|
||||
@ -691,9 +740,8 @@ export class IndexedDBStorage extends Dexie implements StorageInterface {
|
||||
return new Observable((obs) => {
|
||||
const fun = async () => {
|
||||
const result = {};
|
||||
const tables = ['environment', 'group', 'project', 'apiData'];
|
||||
for (let i = 0; i < tables.length; i++) {
|
||||
const tableName = tables[i];
|
||||
const tables = ['environment', 'group', 'project', 'apiData', 'mock'];
|
||||
for (const tableName of tables) {
|
||||
if (tableName === 'project') {
|
||||
result[tableName] = (await this[tableName].toArray())[0];
|
||||
} else {
|
||||
|
@ -0,0 +1,70 @@
|
||||
import Ajv, { JSONSchemaType } from 'ajv';
|
||||
import { ApiData, Environment, Group } from '../../index.model';
|
||||
import { whatType } from 'eo/workbench/browser/src/app/utils';
|
||||
import apiDataSchema from '../schema/apiData.json';
|
||||
import { ApiBodyType } from '../../index.model';
|
||||
import envSchema from '../schema/env.json';
|
||||
export const parseAndCheckApiData = (apiData): { validate: boolean; data?: ApiData; error?: any } => {
|
||||
const ajv = new Ajv({
|
||||
useDefaults: true,
|
||||
removeAdditional: true,
|
||||
});
|
||||
const validate = ajv.compile<ApiData>(apiDataSchema);
|
||||
if (validate(apiData)) {
|
||||
['requestBody', 'responseBody'].forEach((keyName) => {
|
||||
if (
|
||||
[ApiBodyType['Form-data'], ApiBodyType.JSON, ApiBodyType.XML].includes(apiData[`${keyName}Type`]) &&
|
||||
whatType(apiData[keyName]) !== 'array'
|
||||
) {
|
||||
//Handle xml\formdata\json data
|
||||
apiData[keyName] = [];
|
||||
} else if (
|
||||
[ApiBodyType.Raw, ApiBodyType.Binary].includes(apiData[`${keyName}Type`]) &&
|
||||
whatType(apiData[keyName]) !== 'string'
|
||||
) {
|
||||
//Handle raw\binary data
|
||||
apiData[keyName] = '';
|
||||
}
|
||||
});
|
||||
return { validate: true, data: apiData };
|
||||
} else {
|
||||
console.error(validate.errors);
|
||||
return { validate: false, error: validate.errors };
|
||||
}
|
||||
};
|
||||
|
||||
export const parseAndCheckGroup = (group): { validate: boolean; data?: Group } => {
|
||||
if (group.name) {
|
||||
return {
|
||||
validate: true,
|
||||
data: {
|
||||
projectID: group.projectID,
|
||||
parentID: group.parentID,
|
||||
name: group.name,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return { validate: false };
|
||||
}
|
||||
};
|
||||
export const parseAndCheckEnv = (env): { validate: boolean; data?: Environment; error?: any } => {
|
||||
const ajv = new Ajv({
|
||||
useDefaults: true,
|
||||
removeAdditional: true,
|
||||
});
|
||||
const validate = ajv.compile<Environment>(envSchema);
|
||||
if (validate(env)) {
|
||||
return {
|
||||
validate: true,
|
||||
data: {
|
||||
projectID: env.projectID,
|
||||
name: env.name,
|
||||
hostUri: env.hostUri,
|
||||
parameters: env.parameters,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
console.error(validate.errors);
|
||||
return { validate: false, error: validate.errors };
|
||||
}
|
||||
};
|
@ -0,0 +1,38 @@
|
||||
# JSON schema
|
||||
|
||||
Check data Valide
|
||||
|
||||
# Genreate JSON schema from Typescript interface
|
||||
|
||||
1. install
|
||||
|
||||
```
|
||||
npm install typescript-json-schema -g
|
||||
```
|
||||
|
||||
2. genreate
|
||||
|
||||
```
|
||||
cd src/workbench/browser/src/app/shared/services/storage
|
||||
//genrate apidata
|
||||
typescript-json-schema "index.model.ts" 'ApiData' -o "./indexedDB/schema/apiData.json"
|
||||
//genrate env
|
||||
typescript-json-schema "index.model.ts" 'Environment' -o "./indexedDB/schema/env.json"
|
||||
```
|
||||
|
||||
3. compare and merge
|
||||
The generated rule verification is not strict enough and needs to be merged manually
|
||||
|
||||
# Check
|
||||
|
||||
```javascript
|
||||
const ajv = new Ajv({
|
||||
useDefaults: true,
|
||||
});
|
||||
const validate = ajv.compile < ApiData > apiDataSchema;
|
||||
if (validate(apiData)) {
|
||||
return { validate: true, data: apiData };
|
||||
} else {
|
||||
return { validate: false, error: validate.errors };
|
||||
}
|
||||
```
|
@ -0,0 +1,260 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"ApiBodyType": {
|
||||
"nullable": true,
|
||||
"enum": ["binary", "formData", "json", "raw", "xml"],
|
||||
"type": "string"
|
||||
},
|
||||
"ApiEditBody": {
|
||||
"properties": {
|
||||
"attribute": {
|
||||
"description": "XML attribute",
|
||||
"type": "string"
|
||||
},
|
||||
"children": {
|
||||
"description": "子参数",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ApiEditBody"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"description": {
|
||||
"description": "说明",
|
||||
"type": "string"
|
||||
},
|
||||
"enum": {
|
||||
"description": "值可能性",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ParamsEnum"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"example": {
|
||||
"description": "param example",
|
||||
"type": "string"
|
||||
},
|
||||
"maxLength": {
|
||||
"description": "最大长度",
|
||||
"type": "number"
|
||||
},
|
||||
"maximum": {
|
||||
"description": "最大值",
|
||||
"type": "number"
|
||||
},
|
||||
"minLength": {
|
||||
"description": "最小长度",
|
||||
"type": "number"
|
||||
},
|
||||
"minimum": {
|
||||
"description": "最小值",
|
||||
"type": "number"
|
||||
},
|
||||
"name": {
|
||||
"description": "参数名",
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"description": "is response/request must contain param",
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"description": "参数类型",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BasiApiEditParams": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "说明",
|
||||
"type": "string"
|
||||
},
|
||||
"enum": {
|
||||
"description": "值可能性",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ParamsEnum"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"example": {
|
||||
"description": "param example",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "参数名",
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"description": "is response/request must contain param",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"JsonRootType": {
|
||||
"description": "body type is json,set root type of object/array",
|
||||
"enum": ["array", "object"],
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"ParamsEnum": {
|
||||
"properties": {
|
||||
"default": {
|
||||
"description": "is default param value",
|
||||
"type": "boolean"
|
||||
},
|
||||
"description": {
|
||||
"description": "param value description",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"description": "param value",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": "ParamsEnum",
|
||||
"type": "object"
|
||||
},
|
||||
"RequestMethod": {
|
||||
"enum": ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"],
|
||||
"type": "string"
|
||||
},
|
||||
"RequestProtocol": {
|
||||
"enum": ["http", "https"],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"createdAt": {
|
||||
"description": "创建时间,可为空",
|
||||
"type": "string"
|
||||
},
|
||||
"groupID": {
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"method": {
|
||||
"$ref": "#/definitions/RequestMethod",
|
||||
"default":"POST",
|
||||
"description": "Request method [POST, GET, PUT, ...]"
|
||||
},
|
||||
"name": {
|
||||
"description": "name",
|
||||
"type": "string"
|
||||
},
|
||||
"projectID": {
|
||||
"description": "Belongs to which project",
|
||||
"type": "number"
|
||||
},
|
||||
"protocol": {
|
||||
"$ref": "#/definitions/RequestProtocol",
|
||||
"description": "API protocol [http, https, ...]"
|
||||
},
|
||||
"queryParams": {
|
||||
"description": "get请求参数,数据用json存储",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/BasiApiEditParams"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"requestBody": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {
|
||||
"$ref": "#/definitions/ApiEditBody"
|
||||
},
|
||||
"type": "array",
|
||||
"default":[]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"default":""
|
||||
}
|
||||
],
|
||||
"default": "",
|
||||
"description": "请求参数(多层结构),数据用json存储"
|
||||
},
|
||||
"requestBodyJsonType": {
|
||||
"$ref": "#/definitions/JsonRootType",
|
||||
"description": "请求的json参数根类型",
|
||||
"default": "object"
|
||||
},
|
||||
"requestBodyType": {
|
||||
"$ref": "#/definitions/ApiBodyType",
|
||||
"description": "请求的参数类型",
|
||||
"default": "raw"
|
||||
},
|
||||
"requestHeaders": {
|
||||
"description": "请求头数据,数据用json存储",
|
||||
"items": {
|
||||
"$ref": "#/definitions/BasiApiEditParams"
|
||||
},
|
||||
"type": "array",
|
||||
"default": []
|
||||
},
|
||||
"responseBody": {
|
||||
"anyOf": [
|
||||
{
|
||||
"items": {
|
||||
"$ref": "#/definitions/ApiEditBody"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "Response(多层结构),数据用json存储",
|
||||
"default": ""
|
||||
},
|
||||
"responseBodyJsonType": {
|
||||
"$ref": "#/definitions/JsonRootType",
|
||||
"description": "Responsejson根类型",
|
||||
"default": "object"
|
||||
},
|
||||
"responseBodyType": {
|
||||
"$ref": "#/definitions/ApiBodyType",
|
||||
"description": "返回的参数类型",
|
||||
"default": "raw"
|
||||
},
|
||||
"responseHeaders": {
|
||||
"description": "返回头数据,数据用json存储",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/BasiApiEditParams"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"restParams": {
|
||||
"description": "rest请求参数,数据用json存储",
|
||||
"items": {
|
||||
"$ref": "#/definitions/BasiApiEditParams"
|
||||
},
|
||||
"type": "array",
|
||||
"default": []
|
||||
},
|
||||
"updatedAt": {
|
||||
"description": "更新时间,可为空",
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"description": "Request url,Usually value is path",
|
||||
"type": "string"
|
||||
},
|
||||
"uuid": {
|
||||
"description": "主键UUID,字符串UUID或数值型",
|
||||
"type": "number"
|
||||
},
|
||||
"weight": {
|
||||
"description": "api show order",
|
||||
"type": "number",
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"required": ["method", "name", "uri", "protocol"],
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "环境对象接口",
|
||||
"definitions": {
|
||||
"BasicParams": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "参数名",
|
||||
"type": "string",
|
||||
"default":""
|
||||
},
|
||||
"value": {
|
||||
"description": "param value",
|
||||
"type": "string",
|
||||
"default":""
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"createdAt": {
|
||||
"description": "创建时间,可为空",
|
||||
"type": "string"
|
||||
},
|
||||
"hostUri": {
|
||||
"description": "前置url",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"name": {
|
||||
"description": "名称",
|
||||
"type": "string"
|
||||
},
|
||||
"parameters": {
|
||||
"description": "环境变量(可选)",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/BasicParams"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"projectID": {
|
||||
"description": "项目主键ID",
|
||||
"type": "number"
|
||||
},
|
||||
"updatedAt": {
|
||||
"description": "更新时间,可为空",
|
||||
"type": "string"
|
||||
},
|
||||
"uuid": {
|
||||
"description": "主键UUID,字符串UUID或数值型",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["name"],
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
}
|
@ -20,6 +20,9 @@ export class HttpStorage implements StorageInterface {
|
||||
return this.http.get('/system/status') as Observable<object>;
|
||||
}
|
||||
// Project
|
||||
projectImport(uuid: number, item: Project) {
|
||||
return this.http.put(`/project/${uuid}/import`, item) as Observable<object>;
|
||||
}
|
||||
projectCreate(item: Project) {
|
||||
return this.http.post(`/project`, item) as Observable<object>;
|
||||
}
|
||||
|
@ -1,9 +1,4 @@
|
||||
import {
|
||||
ApiTestBody,
|
||||
ApiTestBodyType,
|
||||
ApiTestHeaders,
|
||||
ApiTestQuery,
|
||||
} from 'eo/workbench/browser/src/app/shared/services/api-test/api-test.model';
|
||||
import { ApiTestBody, ApiTestBodyType, ApiTestHeaders } from './../api-test/api-test.model';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
@ -13,9 +8,9 @@ interface StorageModel {
|
||||
/**
|
||||
* 主键UUID,字符串UUID或数值型
|
||||
*
|
||||
* @type {string|number}
|
||||
* @type {number}
|
||||
*/
|
||||
uuid?: string | number;
|
||||
uuid?: number;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
@ -24,13 +19,6 @@ interface StorageModel {
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* 备注信息
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* 创建时间,可为空
|
||||
*
|
||||
@ -51,32 +39,30 @@ interface StorageModel {
|
||||
*/
|
||||
export interface Environment extends StorageModel {
|
||||
/**
|
||||
* 名称
|
||||
* Env name
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* 项目主键ID
|
||||
* Project primary ID
|
||||
*
|
||||
* @type {string|number}
|
||||
* @type {number}
|
||||
*/
|
||||
projectID: string | number;
|
||||
projectID: number;
|
||||
|
||||
/**
|
||||
* 前置url
|
||||
* Host uri
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
hostUri: string;
|
||||
hostUri?: string;
|
||||
|
||||
/**
|
||||
* 环境变量(可选)
|
||||
*
|
||||
* @type {object}
|
||||
* Env parameters
|
||||
*/
|
||||
parameters?: object;
|
||||
parameters?: { name: string; value: string }[];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -327,7 +313,7 @@ export enum RequestProtocol {
|
||||
/**
|
||||
* API Data
|
||||
*/
|
||||
export interface ApiData extends StorageModel {
|
||||
interface BasicApiData extends StorageModel {
|
||||
/**
|
||||
* name
|
||||
*
|
||||
@ -335,39 +321,23 @@ export interface ApiData extends StorageModel {
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Belongs to which project
|
||||
*
|
||||
* @type {string|number}
|
||||
*/
|
||||
projectID?: string | number;
|
||||
|
||||
/**
|
||||
* Belongs to which group
|
||||
*
|
||||
* @type {string|number}
|
||||
*/
|
||||
groupID: string | number;
|
||||
|
||||
/**
|
||||
* Request url,Usually value is path
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
uri: string;
|
||||
|
||||
/**
|
||||
* API protocol [http, https, ...]
|
||||
*
|
||||
* @type {RequestProtocol|string}
|
||||
*/
|
||||
protocol: RequestProtocol | string;
|
||||
protocol: RequestProtocol;
|
||||
|
||||
/**
|
||||
* Request method [POST, GET, PUT, ...]
|
||||
*
|
||||
* @type {RequestMethod|string}
|
||||
*/
|
||||
method: RequestMethod | string;
|
||||
method: RequestMethod;
|
||||
|
||||
/**
|
||||
* api show order
|
||||
@ -379,28 +349,23 @@ export interface ApiData extends StorageModel {
|
||||
/**
|
||||
* 请求的参数类型
|
||||
*
|
||||
* @type {ApiBodyType|string}
|
||||
*/
|
||||
requestBodyType?: ApiBodyType | string;
|
||||
requestBodyType?: ApiBodyType;
|
||||
|
||||
/**
|
||||
* 请求头数据,数据用json存储
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
requestHeaders?: ApiEditHeaders[];
|
||||
|
||||
/**
|
||||
* 请求的json参数根类型
|
||||
*
|
||||
* @type {JsonRootType|string}
|
||||
*/
|
||||
requestBodyJsonType?: JsonRootType | string;
|
||||
requestBodyJsonType?: JsonRootType;
|
||||
|
||||
/**
|
||||
* 请求参数(多层结构),数据用json存储
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
requestBody?: ApiEditBody[] | string;
|
||||
|
||||
@ -421,30 +386,37 @@ export interface ApiData extends StorageModel {
|
||||
/**
|
||||
* 返回头数据,数据用json存储
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
responseHeaders?: ApiEditHeaders[];
|
||||
|
||||
/**
|
||||
* Response(多层结构),数据用json存储
|
||||
*
|
||||
* @type {ApiEditBody[] | string}
|
||||
*/
|
||||
responseBody?: ApiEditBody[] | string;
|
||||
|
||||
/**
|
||||
* 返回的参数类型
|
||||
*
|
||||
* @type {ApiBodyType|string}
|
||||
*/
|
||||
responseBodyType?: ApiBodyType | string;
|
||||
responseBodyType?: ApiBodyType;
|
||||
|
||||
/**
|
||||
* Responsejson根类型
|
||||
*
|
||||
* @type {JsonRootType|string}
|
||||
*/
|
||||
responseBodyJsonType?: JsonRootType | string;
|
||||
responseBodyJsonType?: JsonRootType;
|
||||
}
|
||||
export interface ApiData extends BasicApiData {
|
||||
/**
|
||||
* Belongs to which project
|
||||
*
|
||||
*/
|
||||
projectID: number;
|
||||
groupID: number;
|
||||
}
|
||||
/**
|
||||
* API data view model
|
||||
*/
|
||||
export interface ApiEditViewData extends BasicApiData {
|
||||
groupID: string;
|
||||
}
|
||||
/**
|
||||
* API Test Data
|
||||
@ -524,11 +496,11 @@ export interface ApiTestData {
|
||||
/**
|
||||
* Javascript code before test
|
||||
*/
|
||||
beforeScript: string;
|
||||
beforeScript?: string;
|
||||
/**
|
||||
* Javascript code after api response
|
||||
*/
|
||||
afterScript: string;
|
||||
afterScript?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -666,6 +638,7 @@ export interface StorageInterface {
|
||||
*/
|
||||
systemCheck?: () => Observable<object>;
|
||||
// Project
|
||||
projectImport: (uuid: number, item: any) => Observable<object>;
|
||||
projectCreate: (item: Project) => Observable<object>;
|
||||
projectUpdate: (item: Project, uuid: number | string) => Observable<object>;
|
||||
projectBulkUpdate: (items: Array<Project>) => Observable<object>;
|
||||
|
@ -96,12 +96,12 @@ export const xml2json = (tmpl) => {
|
||||
let index = null;
|
||||
while (xml) {
|
||||
// * handle end tags
|
||||
if (xml.substring(0, 2) === '</') {
|
||||
if (xml.trim().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');
|
||||
throw new Error(`Parse error 101. [${last.tagName}] is not eq [${label}]`);
|
||||
}
|
||||
if (stack.length === 0) {
|
||||
result.push(last);
|
||||
@ -110,12 +110,25 @@ export const xml2json = (tmpl) => {
|
||||
parent.children.push(last);
|
||||
stack.push(parent);
|
||||
}
|
||||
xml = xml.substring(str.length);
|
||||
xml = xml.trim().substring(str.length);
|
||||
continue;
|
||||
}
|
||||
// * handle start tags
|
||||
if ((start = xml.match(startTag))) {
|
||||
const [str, label, attr] = start;
|
||||
if (str.slice(-2) === '/>') {
|
||||
// * single tag
|
||||
const parent = stack.pop();
|
||||
parent.children.push({
|
||||
tagName: label.trim(),
|
||||
attr: attr.trim(),
|
||||
content: '',
|
||||
children: [],
|
||||
});
|
||||
stack.push(parent);
|
||||
xml = xml.trim().substring(str.length);
|
||||
continue;
|
||||
}
|
||||
stack.push({
|
||||
tagName: label.trim(),
|
||||
attr: attr.trim(),
|
||||
@ -139,6 +152,7 @@ export const xml2json = (tmpl) => {
|
||||
if (stack.length) {
|
||||
throw new Error('Parse error 102');
|
||||
}
|
||||
// console.log(JSON.stringify(result, null, 2));
|
||||
return result;
|
||||
};
|
||||
|
||||
@ -147,6 +161,7 @@ type uiData = {
|
||||
rootType: JsonRootType | string;
|
||||
data: ApiEditBody | any;
|
||||
};
|
||||
|
||||
export const xml2UiData = (text) => {
|
||||
const data: any[] = xml2json(text);
|
||||
const deep = (list = []) =>
|
||||
@ -265,7 +280,7 @@ export const uiData2Json = function (eoapiArr: ApiEditBody[], inputOptions) {
|
||||
if (inputOptions.checkXmlAttr) {
|
||||
inputObject['@eo_attr'] = inputObject['@eo_attr'] || {};
|
||||
}
|
||||
for (const val of inputArr) {
|
||||
for (const val of inputArr || []) {
|
||||
if (!val.name) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"PAGES": {
|
||||
"HOME": {
|
||||
"TITLE": "App works !",
|
||||
"GO_TO_DETAIL": "Go to Detail1"
|
||||
},
|
||||
"DETAIL": {
|
||||
"TITLE": "Detail page !",
|
||||
"BACK_TO_HOME": "Back to Home"
|
||||
}
|
||||
}
|
||||
}
|
@ -95,15 +95,15 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/detail/mock/api-detail-mock.component.ts</context>
|
||||
<context context-type="linenumber">134</context>
|
||||
<context context-type="linenumber">133</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">261</context>
|
||||
<context context-type="linenumber">260</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/monaco-editor/monaco-editor.component.ts</context>
|
||||
<context context-type="linenumber">290</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/utils/index.ts</context>
|
||||
@ -143,7 +143,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">54</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/overview/api-overview.component.html</context>
|
||||
@ -238,7 +238,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">14</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/body/api-test-body.component.ts</context>
|
||||
@ -265,7 +265,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7045123878111147511" datatype="html">
|
||||
@ -368,11 +368,11 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">97</context>
|
||||
<context context-type="linenumber">98</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">100</context>
|
||||
<context context-type="linenumber">101</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/api-script/constant.ts</context>
|
||||
@ -395,7 +395,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
<context context-type="linenumber">106</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3170454287339201082" datatype="html">
|
||||
@ -711,11 +711,11 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">56</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">137</context>
|
||||
<context context-type="linenumber">138</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3098390606978669021" datatype="html">
|
||||
@ -740,7 +740,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">132</context>
|
||||
<context context-type="linenumber">133</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="52c9a103b812f258bcddc3d90a6e3f46871d25fe" datatype="html">
|
||||
@ -797,11 +797,11 @@
|
||||
<source>Edited successfully</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">127</context>
|
||||
<context context-type="linenumber">128</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">235</context>
|
||||
<context context-type="linenumber">234</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/env/env.component.ts</context>
|
||||
@ -812,11 +812,11 @@
|
||||
<source>Added successfully</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">127</context>
|
||||
<context context-type="linenumber">128</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">240</context>
|
||||
<context context-type="linenumber">239</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/env/env.component.ts</context>
|
||||
@ -827,14 +827,14 @@
|
||||
<source>Failed Operation</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4926605800185679045" datatype="html">
|
||||
<source>Root directory</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">185</context>
|
||||
<context context-type="linenumber">186</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="bc0fd905b5fa45043121b5607fa0f2e91201ff98" datatype="html">
|
||||
@ -988,57 +988,46 @@
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7245969617352349881" datatype="html">
|
||||
<source>Default Mock</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">171</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.ts</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1623775429516238560" datatype="html">
|
||||
<source>Deletion Confirmation?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
<context context-type="linenumber">217</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9142685431369791033" datatype="html">
|
||||
<source>Are you sure you want to delete the data <strong title="<x id="PH" equiv-text="apiInfo.name"/>"><x id="PH_1" equiv-text="apiInfo.name.length > 50 ? apiInfo.name.slice(0, 50) + '...' : apiInfo.name"/></strong> ? You cannot restore it once deleted!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">233,235</context>
|
||||
<context context-type="linenumber">218,220</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="9124347207158517893" datatype="html">
|
||||
<source>Add Group</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">291</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6661660398413994526" datatype="html">
|
||||
<source>Add Subgroup</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">300</context>
|
||||
<context context-type="linenumber">285</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="5908762969513689727" datatype="html">
|
||||
<source>Edit Group</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
<context context-type="linenumber">294</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3596210590059423029" datatype="html">
|
||||
<source>Delete Group</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">318</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="c6b146602288a87386004d591558477a97497e60" datatype="html">
|
||||
@ -1102,7 +1091,7 @@
|
||||
<source>Delete Succeeded</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">224</context>
|
||||
<context context-type="linenumber">223</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="1071721880474488785" datatype="html">
|
||||
@ -1239,18 +1228,18 @@
|
||||
<source><x id="PH" equiv-text="opts.title"/> Value</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
<context context-type="linenumber">17</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6555318547274416232" datatype="html">
|
||||
<source>Value</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">118</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">123</context>
|
||||
<context context-type="linenumber">124</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/header/api-test-header.component.ts</context>
|
||||
@ -2749,8 +2738,8 @@
|
||||
<context context-type="linenumber">24,26</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="48337f1cc97660a13f3327ba705a66f31faec719" datatype="html">
|
||||
<source>Only individual files in Json format are supported</source>
|
||||
<trans-unit id="15c7e4510fb38a7b8ca73e1af4fa3a199f2d1a44" datatype="html">
|
||||
<source>Only supports importing a single file</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/extension-select/extension-select.component.html</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
@ -2763,6 +2752,13 @@
|
||||
<context context-type="linenumber">44</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7946321398772270161" datatype="html">
|
||||
<source>Please import the file first</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/import-api/import-api.component.ts</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36" datatype="html">
|
||||
<source>Import</source>
|
||||
<context-group purpose="location">
|
||||
@ -2926,25 +2922,25 @@
|
||||
<source>Only the client can connect to the remote server. You need to download the client first.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">110</context>
|
||||
<context context-type="linenumber">112</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">156</context>
|
||||
<context context-type="linenumber">159</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8244321085825115351" datatype="html">
|
||||
<source>Remote server connection failed!!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">144</context>
|
||||
<context context-type="linenumber">146</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2875796658938124573" datatype="html">
|
||||
<source>The remote data source connection is successful!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">169</context>
|
||||
<context context-type="linenumber">172</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="0feab442129ba239106e55cf029069d3d4adeadc" datatype="html">
|
||||
@ -3076,43 +3072,50 @@
|
||||
<trans-unit id="3618702844543429787" datatype="html">
|
||||
<source>Get City Weather Today</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">6</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="2290605059653855867" datatype="html">
|
||||
<source>City Code : http://www.mca.gov.cn/article/sj/xzqh/2020/20201201.html</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7782559081118681676" datatype="html">
|
||||
<source>minimum temperature</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">42</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">45</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="4661147653025473439" datatype="html">
|
||||
<source>maximun temperature</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8259972015663673459" datatype="html">
|
||||
<source>COVID-19 national epidemic</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">54</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="3950552443739162649" datatype="html">
|
||||
<source>The actual parameter is string, in order to show the document expansion display</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">82</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">95</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="7245969617352349881" datatype="html">
|
||||
<source>Default Mock</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.ts</context>
|
||||
<context context-type="linenumber">88</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
</body>
|
||||
|
@ -103,15 +103,15 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/detail/mock/api-detail-mock.component.ts</context>
|
||||
<context context-type="linenumber">134</context>
|
||||
<context context-type="linenumber">133</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">261</context>
|
||||
<context context-type="linenumber">260</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/monaco-editor/monaco-editor.component.ts</context>
|
||||
<context context-type="linenumber">290</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/utils/index.ts</context>
|
||||
@ -155,7 +155,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">54</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/overview/api-overview.component.html</context>
|
||||
@ -260,7 +260,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">14</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/body/api-test-body.component.ts</context>
|
||||
@ -288,7 +288,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">15</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
</context-group>
|
||||
<target state="translated"><x id="PH" equiv-text="opts.title"/>名</target>
|
||||
</trans-unit>
|
||||
@ -396,11 +396,11 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">97</context>
|
||||
<context context-type="linenumber">98</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">100</context>
|
||||
<context context-type="linenumber">101</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/api-script/constant.ts</context>
|
||||
@ -424,7 +424,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">105</context>
|
||||
<context context-type="linenumber">106</context>
|
||||
</context-group>
|
||||
<target state="translated">类型</target>
|
||||
</trans-unit>
|
||||
@ -768,11 +768,11 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">55</context>
|
||||
<context context-type="linenumber">56</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">137</context>
|
||||
<context context-type="linenumber">138</context>
|
||||
</context-group>
|
||||
<target state="translated">删除</target>
|
||||
</trans-unit>
|
||||
@ -800,7 +800,7 @@
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">132</context>
|
||||
<context context-type="linenumber">133</context>
|
||||
</context-group>
|
||||
<target state="translated">添加子字段</target>
|
||||
</trans-unit>
|
||||
@ -864,11 +864,11 @@
|
||||
<source>Edited successfully</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">127</context>
|
||||
<context context-type="linenumber">128</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">235</context>
|
||||
<context context-type="linenumber">234</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/env/env.component.ts</context>
|
||||
@ -880,11 +880,11 @@
|
||||
<source>Added successfully</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">127</context>
|
||||
<context context-type="linenumber">128</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">240</context>
|
||||
<context context-type="linenumber">239</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/env/env.component.ts</context>
|
||||
@ -896,7 +896,7 @@
|
||||
<source>Failed Operation</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">141</context>
|
||||
<context context-type="linenumber">142</context>
|
||||
</context-group>
|
||||
<target state="translated">操作失败</target>
|
||||
</trans-unit>
|
||||
@ -904,7 +904,7 @@
|
||||
<source>Root directory</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/edit/api-edit.component.ts</context>
|
||||
<context context-type="linenumber">185</context>
|
||||
<context context-type="linenumber">186</context>
|
||||
</context-group>
|
||||
<target state="translated">根目录</target>
|
||||
</trans-unit>
|
||||
@ -1078,23 +1078,11 @@
|
||||
</context-group>
|
||||
<target state="translated">编辑</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="7245969617352349881" datatype="html">
|
||||
<source>Default Mock</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">171</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.ts</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
<target state="translated">默认 Mock</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="1623775429516238560" datatype="html">
|
||||
<source>Deletion Confirmation?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">232</context>
|
||||
<context context-type="linenumber">217</context>
|
||||
</context-group>
|
||||
<target state="translated">确认删除?</target>
|
||||
</trans-unit>
|
||||
@ -1102,7 +1090,7 @@
|
||||
<source>Are you sure you want to delete the data <strong title="<x id="PH" equiv-text="apiInfo.name"/>"><x id="PH_1" equiv-text="apiInfo.name.length > 50 ? apiInfo.name.slice(0, 50) + '...' : apiInfo.name"/></strong> ? You cannot restore it once deleted!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">233,235</context>
|
||||
<context context-type="linenumber">218,220</context>
|
||||
</context-group>
|
||||
<target state="translated">确认要删除数据 <strong title="<x id="PH" equiv-text="apiInfo.name"/>"><x id="PH_1" equiv-text="apiInfo.name.length > 50 ? apiInfo.name.slice(0, 50) + '...' : apiInfo.name"/></strong> 吗?删除后不可恢复!</target>
|
||||
</trans-unit>
|
||||
@ -1110,7 +1098,7 @@
|
||||
<source>Add Group</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">291</context>
|
||||
<context context-type="linenumber">276</context>
|
||||
</context-group>
|
||||
<target state="translated">添加分组</target>
|
||||
</trans-unit>
|
||||
@ -1118,7 +1106,7 @@
|
||||
<source>Add Subgroup</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">300</context>
|
||||
<context context-type="linenumber">285</context>
|
||||
</context-group>
|
||||
<target state="translated">添加子分组</target>
|
||||
</trans-unit>
|
||||
@ -1126,7 +1114,7 @@
|
||||
<source>Edit Group</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
<context context-type="linenumber">294</context>
|
||||
</context-group>
|
||||
<target state="translated">编辑分组</target>
|
||||
</trans-unit>
|
||||
@ -1134,7 +1122,7 @@
|
||||
<source>Delete Group</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/group/tree/api-group-tree.component.ts</context>
|
||||
<context context-type="linenumber">318</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
</context-group>
|
||||
<target state="translated">删除分组</target>
|
||||
</trans-unit>
|
||||
@ -1208,7 +1196,7 @@
|
||||
<source>Delete Succeeded</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/mock/api-mock.component.ts</context>
|
||||
<context context-type="linenumber">224</context>
|
||||
<context context-type="linenumber">223</context>
|
||||
</context-group>
|
||||
<target state="translated">删除成功</target>
|
||||
</trans-unit>
|
||||
@ -1364,7 +1352,7 @@
|
||||
<source><x id="PH" equiv-text="opts.title"/> Value</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">16</context>
|
||||
<context context-type="linenumber">17</context>
|
||||
</context-group>
|
||||
<target state="translated"><x id="PH" equiv-text="opts.title"/>值</target>
|
||||
</trans-unit>
|
||||
@ -1372,11 +1360,11 @@
|
||||
<source>Value</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">118</context>
|
||||
<context context-type="linenumber">119</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/api-test-util.service.ts</context>
|
||||
<context context-type="linenumber">123</context>
|
||||
<context context-type="linenumber">124</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/pages/api/test/header/api-test-header.component.ts</context>
|
||||
@ -3036,13 +3024,13 @@
|
||||
</context-group>
|
||||
<target state="translated"> 该功能需要插件支持,请移步至<x id="START_LINK" ctype="x-a" equiv-text="<a class="eo_link" routerLink="/home/extension/list">"/>插件广场<x id="CLOSE_LINK" ctype="x-a" equiv-text="</a>"/>下载 </target>
|
||||
</trans-unit>
|
||||
<trans-unit id="48337f1cc97660a13f3327ba705a66f31faec719" datatype="html">
|
||||
<source>Only individual files in Json format are supported</source>
|
||||
<trans-unit id="15c7e4510fb38a7b8ca73e1af4fa3a199f2d1a44" datatype="html">
|
||||
<source>Only supports importing a single file</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/extension-select/extension-select.component.html</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
</context-group>
|
||||
<target state="translated">仅支持JSON格式的单个文件导入</target>
|
||||
<target state="translated">仅支持导入单个文件</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="4141575162728577645" datatype="html">
|
||||
<source>Only files in JSON format are supported</source>
|
||||
@ -3052,6 +3040,14 @@
|
||||
</context-group>
|
||||
<target state="translated">仅支持上传 JSON 格式的文件</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="7946321398772270161" datatype="html">
|
||||
<source>Please import the file first</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/import-api/import-api.component.ts</context>
|
||||
<context context-type="linenumber">75</context>
|
||||
</context-group>
|
||||
<target state="translated">请先导入文件</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="a059709f71aa4c0ac219e160e78a738682ca6a36" datatype="html">
|
||||
<source>Import</source>
|
||||
<context-group purpose="location">
|
||||
@ -3236,11 +3232,11 @@
|
||||
<source>Only the client can connect to the remote server. You need to download the client first.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">110</context>
|
||||
<context context-type="linenumber">112</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">156</context>
|
||||
<context context-type="linenumber">159</context>
|
||||
</context-group>
|
||||
<target state="translated">仅客户端支持连接远程服务器,需要先下载客户端。</target>
|
||||
</trans-unit>
|
||||
@ -3248,7 +3244,7 @@
|
||||
<source>Remote server connection failed!!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">144</context>
|
||||
<context context-type="linenumber">146</context>
|
||||
</context-group>
|
||||
<target state="translated">远程服务器连接失败</target>
|
||||
</trans-unit>
|
||||
@ -3256,7 +3252,7 @@
|
||||
<source>The remote data source connection is successful!</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/components/setting/common/data-storage.component.ts</context>
|
||||
<context context-type="linenumber">169</context>
|
||||
<context context-type="linenumber">172</context>
|
||||
</context-group>
|
||||
<target state="translated">远程数据源连接成功!</target>
|
||||
</trans-unit>
|
||||
@ -3405,51 +3401,59 @@
|
||||
<trans-unit id="3618702844543429787" datatype="html">
|
||||
<source>Get City Weather Today</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">5</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">6</context>
|
||||
</context-group>
|
||||
<target state="translated">获取城市今日天气</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="2290605059653855867" datatype="html">
|
||||
<source>City Code : http://www.mca.gov.cn/article/sj/xzqh/2020/20201201.html</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
<target state="translated">城市代码 : http://www.mca.gov.cn/article/sj/xzqh/2020/20201201.html</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="7782559081118681676" datatype="html">
|
||||
<source>minimum temperature</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">42</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">45</context>
|
||||
</context-group>
|
||||
<target state="translated">最低温度</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="4661147653025473439" datatype="html">
|
||||
<source>maximun temperature</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">43</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">52</context>
|
||||
</context-group>
|
||||
<target state="translated">最高温度</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="8259972015663673459" datatype="html">
|
||||
<source>COVID-19 national epidemic</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">54</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">67</context>
|
||||
</context-group>
|
||||
<target state="translated">新冠全国疫情</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="3950552443739162649" datatype="html">
|
||||
<source>The actual parameter is string, in order to show the document expansion display</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/sample/index.ts</context>
|
||||
<context context-type="linenumber">82</context>
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.constant.ts</context>
|
||||
<context context-type="linenumber">95</context>
|
||||
</context-group>
|
||||
<target state="translated">实际参数是 string,以便显示文档扩展显示</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="7245969617352349881" datatype="html">
|
||||
<source>Default Mock</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/services/storage/IndexedDB/lib/index.ts</context>
|
||||
<context context-type="linenumber">88</context>
|
||||
</context-group>
|
||||
<target state="translated">默认 Mock</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -5,7 +5,7 @@
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"emitDecoratorMetadata": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
|
@ -9204,10 +9204,10 @@ neo-async@^2.6.0, neo-async@^2.6.2:
|
||||
resolved "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||
|
||||
ng-zorro-antd@13.3.2:
|
||||
version "13.3.2"
|
||||
resolved "https://registry.npmmirror.com/ng-zorro-antd/-/ng-zorro-antd-13.3.2.tgz#04d79f884231afdfdb5759919c0fa202f431cc8f"
|
||||
integrity sha512-bmpolaSevoZSVlP2nVpvi/CrFFu7hdaK/vz1k0R84db4AYOYFHcRwlAUBaWVKjWGaCHek+k1atC/pckXZqEgIA==
|
||||
ng-zorro-antd@13.4.0:
|
||||
version "13.4.0"
|
||||
resolved "https://registry.yarnpkg.com/ng-zorro-antd/-/ng-zorro-antd-13.4.0.tgz#a62a9df914d7241a6f5baabe1f4740ddd724b737"
|
||||
integrity sha512-ZIXeeXtTUNg3mdXNg2A3gJGh0aqN/pM3Ii61FiUhwkVwmVzIIDwYfGZZNNOl+cURL5HGzrwQ10nrYgdfFfZ20g==
|
||||
dependencies:
|
||||
"@angular/cdk" "^13.0.1"
|
||||
"@ant-design/icons-angular" "^13.0.1"
|
||||
|
Loading…
Reference in New Issue
Block a user