mirror of
https://gitee.com/eolink_admin/postcat.git
synced 2024-11-30 02:37:57 +08:00
i18n (#90)
* fix: can not navigate to extensions page * feat: add iconpark * feat: sidebar done * feat: update style * fix: theme components show in bottom * feat: homepage almost done * feat: extension detail readme * feat: ignore eo-setting * feat: ignore eo-setting * feat: extension detail support text * fix: build error * feat: mock extension preview in web * update css style * feat: extension detail support web preview * pref: update css style * feat: update setting component * feat: update style * feat: ignore * remove diver * feat: add link in github logo * fix: build ts error * fix: search extension * feat: change bind event of click * fix: setting button can not click * feat: system setting support web * fix: flex style issue * feat: icon button width * chore: switch data source btn move to setting modal * feat: i18n * fix: module inject error * fix: some css style * feat: hide cloud icon * add logo to settingModal * feat: update settingModal UI * chore: serve support i18n * feat: base env * fix: some error message * fix: build error * feat: history done * feat: done env * feat: settings logic * fix: env modal auto open while page load * pref: api-tabs css style * fix: api-tabs css style issus * pref: update settingsModal css style * fix: set default language * feat: update env * feat: add goto env callback * fix: remote source for web * fix: remote source for web * fix: rename API to REST * feat: fix tips text * feat: fix icon size * fix: make api-tabs space evenly * fix: about component descritions issues * fix: style of env select position * fix: settings modal navigate to extension page faile * feat: modal footer left * fix: mock some logic * feat: history icon style * fix: extension list css style * update extension css style * fix: env save failed * chore: build i18n destop app * fix: rename event name * feat: change language * chore * test vercel * test vercel * delete vercel.json * fix: lose baseHref * chore: change angular.json beforeBuild * fix: 2 bug about env * perf: extension detail scrollbar style * feat: add ts.code-snippets * feat: initial i18n * fix: open test history * feat: add uuid in history tab * fix: custom iconpark component * test merge * fix: center plus icon * fix: setttings should auto save * translate: en * feat: change lang * feat: translate en * translate en * translate en * translate en * delete package.lock * fix: root directory run error * vercel.json * vercel redirects * vercel.json * change * change * route by accept-language * vercel.json * feat:redirect * vercel rewrites * vercel * chore: translate chinese comment to english * translate: cn * push zh.xlf * fix: manage environment * translate zh * fix: some css style issues * feat: changeLanuage * delete vercel * fix: language storage none * feat: app reload * fix: initial lanugae * feat:debug success * feat: node-server * feat:web node server * stash ProxySandbox * feat: extension i18n * feat: extension i18n logic Co-authored-by: buqiyuan <1743369777@qq.com> Co-authored-by: 夜鹰 <17kungfuboy@gmail.com>
This commit is contained in:
parent
84c5d65f94
commit
c2757a4487
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,6 +11,7 @@ out/
|
||||
*.js.map
|
||||
*.webpack.js
|
||||
!src/workbench/node/request/**/*.js
|
||||
!src/workbench/node/server/**/*.js
|
||||
!/api/*.js
|
||||
!/build/*.js
|
||||
!*.config.js
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -13,7 +13,8 @@
|
||||
// }
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/bower_components": true,
|
||||
"**/dist":true,
|
||||
"**/.angular":true,
|
||||
"**/*.code-search": true,
|
||||
"**/*.lock": true,
|
||||
}
|
||||
|
17
api/unit.js
17
api/unit.js
@ -4,20 +4,19 @@ let _LibsCommon = require('../src/workbench/node/request/libs/common.js');
|
||||
module.exports = (req, res) => {
|
||||
console.log('unit.js', req.body);
|
||||
try {
|
||||
let data = req.body.data;
|
||||
data.env = _LibsCommon.parseEnv(data.env);
|
||||
new _LibsFlowCommon.core().main(data, (tmpInputReport, tmpInputHistory) => {
|
||||
let reqJSON = req.body.data;
|
||||
reqJSON.env = _LibsCommon.parseEnv(reqJSON.env);
|
||||
new _LibsFlowCommon.core().main(reqJSON).then(({ report, history }) => {
|
||||
['general', 'requestInfo', 'resultInfo'].forEach((keyName) => {
|
||||
if (typeof tmpInputHistory[keyName] === 'string')
|
||||
tmpInputHistory[keyName] = JSON.parse(tmpInputHistory[keyName]);
|
||||
if (typeof history[keyName] === 'string') history[keyName] = JSON.parse(history[keyName]);
|
||||
});
|
||||
res.send(
|
||||
JSON.stringify({
|
||||
action: 'finish',
|
||||
data: {
|
||||
id: req.body.id,
|
||||
report: tmpInputReport,
|
||||
history: tmpInputHistory,
|
||||
id: ctx.request.body.id,
|
||||
report: report,
|
||||
history: history,
|
||||
},
|
||||
})
|
||||
);
|
||||
@ -25,4 +24,4 @@ module.exports = (req, res) => {
|
||||
} catch (e) {
|
||||
console.error('unit.js', e, req.body);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -10,7 +10,8 @@
|
||||
"out/shared/**/*.js*",
|
||||
"**/*/browser/dist/**/*",
|
||||
"**/*/node/dist/**/*",
|
||||
"out/workbench/node/",
|
||||
"out/workbench/browser/src/**/*.js*",
|
||||
"out/workbench/node/**/*.js*",
|
||||
"out/core/**/package.json",
|
||||
"out/app/common/**/*",
|
||||
"!**/*.ts"
|
||||
|
17
package.json
17
package.json
@ -1,15 +1,14 @@
|
||||
{
|
||||
"name": "eoapi",
|
||||
"souceLocale": "zh-Hans",
|
||||
"version": "1.2.4",
|
||||
"version": "1.3.0",
|
||||
"main": "out/app/electron-main/main.js",
|
||||
"description": "A lightweight, extensible API tool",
|
||||
"homepage": "https://github.com/eolinker/eoapi.git",
|
||||
"author": "eoapi",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"src/workbench/browser",
|
||||
"src/app/electron-browser/IndexedDB"
|
||||
"src/workbench/browser"
|
||||
],
|
||||
"scripts": {
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
@ -21,11 +20,12 @@
|
||||
"electron:serve": "wait-on tcp:4200 && npm run electron:dev",
|
||||
"electron:dev:static": "npm run electron:tsc && electron .",
|
||||
"electron:dev": "npm run electron:tsc && electron . --development",
|
||||
"build": "npm-run-all -s build:workbench electron:tsc && electron-builder build",
|
||||
"build:static": "npm-run-all -s build:workbench electron:tsc && electron-builder build",
|
||||
"release": "npm-run-all -s build:workbench electron:tsc && electron-builder --publish=always && node upload.js",
|
||||
"build": "npm-run-all -s build:workbench clear:electron:tsc electron:tsc && electron-builder build",
|
||||
"build:static": "npm run clear:electron:tsc&&npm run electron:tsc && electron-builder build",
|
||||
"release": "npm-run-all -s build:workbench electron:tsc && electron-builder --publish=always",
|
||||
"release:m1": "npm-run-all -s build:workbench electron:tsc && electron-builder -m=dmg --arm64 -p onTagOrDraft",
|
||||
"test": "npm-run-all --serial test:*",
|
||||
"clear:electron:tsc": "tsc --build --clean",
|
||||
"electron:tsc": "tsc -p tsconfig.json",
|
||||
"copyfile:out": "copyfiles -u 1 src/**/*.json src/app/common/images/** out"
|
||||
},
|
||||
@ -36,6 +36,7 @@
|
||||
"copyfiles": "2.4.1",
|
||||
"crypto-js": "^4.1.1",
|
||||
"electron-log": "^4.4.8",
|
||||
"electron-store": "8.0.2",
|
||||
"electron-updater": "^5.0.5",
|
||||
"express": "4.18.1",
|
||||
"fix-path": "3.0.0",
|
||||
@ -44,7 +45,6 @@
|
||||
"iconv-lite": "^0.6.3",
|
||||
"npm": "6.14.17",
|
||||
"portfinder": "1.0.28",
|
||||
"qiniu": "^6.1.13",
|
||||
"resolve": "^1.22.1",
|
||||
"rxjs": "7.5.5",
|
||||
"xml2js": "^0.4.23"
|
||||
@ -65,8 +65,7 @@
|
||||
"npm-run-all": "4.1.5",
|
||||
"ts-node": "10.8.1",
|
||||
"typescript": "~4.7.4",
|
||||
"wait-on": "6.0.1",
|
||||
"yaml": "2.1.1"
|
||||
"wait-on": "6.0.1"
|
||||
},
|
||||
"__npminstall_done": false,
|
||||
"node-module-alias": {
|
||||
|
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script type="application/javascript" src="./dist/index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "eoapi",
|
||||
"version": "1.0.0",
|
||||
"description": "A storage load service.",
|
||||
"scripts": {
|
||||
"build": "rimraf ./dist && rollup -c rollup.config",
|
||||
"dev": "rollup -c rollup.config.js -w"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^21.0.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-replace": "^3.0.0",
|
||||
"@types/rimraf": "^3.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.58.0",
|
||||
"rollup-plugin-node-polyfills": "^0.2.1",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-string": "^3.0.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-typescript2": "^0.30.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import typescript from 'rollup-plugin-typescript2';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import json from '@rollup/plugin-json';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import nodePolyfills from 'rollup-plugin-node-polyfills';
|
||||
|
||||
const sourcemap = 'inline';
|
||||
const input = './src/index.ts';
|
||||
|
||||
const commonOptions = {
|
||||
external: ['dexie', 'rxjs'],
|
||||
plugins: [
|
||||
typescript({
|
||||
tsconfigOverride: {
|
||||
compilerOptions: {
|
||||
target: 'ES2017',
|
||||
module: 'ES2015'
|
||||
}
|
||||
}
|
||||
}),
|
||||
terser(),
|
||||
resolve(),
|
||||
nodePolyfills(),
|
||||
commonjs(),
|
||||
json(),
|
||||
replace({
|
||||
preventAssignment: true
|
||||
})
|
||||
],
|
||||
input
|
||||
};
|
||||
|
||||
/** @type import('rollup').RollupOptions */
|
||||
const nodeCjs = {
|
||||
output: [{
|
||||
file: 'dist/index.js',
|
||||
format: 'cjs',
|
||||
sourcemap
|
||||
}],
|
||||
...commonOptions
|
||||
};
|
||||
|
||||
const bundles = [nodeCjs];
|
||||
|
||||
export default bundles;
|
@ -1,69 +0,0 @@
|
||||
import { BrowserView, BrowserWindow, ipcMain } from 'electron';
|
||||
import { BrowserViewInstance } from 'eo/platform/electron-main/browserView/browserView';
|
||||
import * as path from 'path';
|
||||
import { processEnv } from 'eo/platform/node/constant';
|
||||
export class CoreViews {
|
||||
moduleID: string;
|
||||
view: BrowserView;
|
||||
constructor(private win: BrowserWindow) {
|
||||
this.triggleEvent = this.triggleEvent.bind(this);
|
||||
}
|
||||
|
||||
rebuildBounds() {
|
||||
if (!this.view) {
|
||||
return;
|
||||
}
|
||||
const _bounds = this.win.getContentBounds();
|
||||
_bounds.x = 0;
|
||||
_bounds.y = 0;
|
||||
this.view.setBounds(_bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* create core module browserview with sidebar/navbar/toolbar
|
||||
*/
|
||||
create() {
|
||||
const _bounds = this.win.getContentBounds();
|
||||
_bounds.x = 0;
|
||||
_bounds.y = 0;
|
||||
this.view = new BrowserViewInstance({
|
||||
bounds: _bounds,
|
||||
partition: '<core-module>',
|
||||
preloadPath: path.join(__dirname, '../../', 'platform', 'electron-browser', 'preload.js'),
|
||||
viewPath:
|
||||
processEnv === 'development'
|
||||
? 'http://localhost:4201'
|
||||
: `file://${path.join(__dirname, '../../', 'workbench', 'browser', 'dist', 'index.html')}`,
|
||||
}).init(this.win);
|
||||
this.view.webContents.openDevTools();
|
||||
this.view.webContents.once('dom-ready', () => {
|
||||
require('@electron/remote/main').enable(this.view.webContents);
|
||||
});
|
||||
this.watch();
|
||||
}
|
||||
watch() {
|
||||
// ipcMain.on('message', this.triggleEvent);
|
||||
}
|
||||
triggleEvent(event, arg) {
|
||||
console.log(`core view ${event.frameId}: recieve render msg=>`, arg, arg.action);
|
||||
if (event.frameId !== 1) return;
|
||||
switch (arg.action) {
|
||||
case 'setBounds': {
|
||||
//sidebar shrink or expand
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 删除视图
|
||||
* @param view
|
||||
* @param window
|
||||
*/
|
||||
remove() {
|
||||
if (!this.view) return;
|
||||
this.win.removeBrowserView(this.view);
|
||||
this.view.webContents.closeDevTools();
|
||||
ipcMain.removeListener('message', this.triggleEvent);
|
||||
this.view = undefined;
|
||||
}
|
||||
}
|
23
src/app/electron-main/language.service.ts
Normal file
23
src/app/electron-main/language.service.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { app } from 'electron';
|
||||
import { LANGUAGES } from '../../workbench/browser/src/app/core/services/language/language.model';
|
||||
import Store from 'electron-store';
|
||||
const store = new Store();
|
||||
class LanguageInstance {
|
||||
private static _instance: LanguageInstance;
|
||||
constructor() {}
|
||||
public static get Instance(): LanguageInstance {
|
||||
return this._instance || (this._instance = new this());
|
||||
}
|
||||
get(): string {
|
||||
let lang = store.get('language') || (app.getLocale().includes('zh') ? 'zh-Hans' : 'en-US');
|
||||
return lang as string;
|
||||
}
|
||||
getPath() {
|
||||
const systemLanguage = this.get();
|
||||
return LANGUAGES.find((val) => val.value === systemLanguage).path;
|
||||
}
|
||||
set(localeID) {
|
||||
store.set('language', localeID);
|
||||
}
|
||||
}
|
||||
export const LanguageService = LanguageInstance.Instance;
|
@ -3,97 +3,100 @@ import { app, BrowserWindow, ipcMain, screen } from 'electron';
|
||||
import { EoUpdater } from './updater';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import ModuleManager from '../../platform/node/extension-manager/lib/manager';
|
||||
import {ModuleManager} from '../../platform/node/extension-manager/lib/manager';
|
||||
import { ModuleManagerInterface } from '../../platform/node/extension-manager';
|
||||
// TODO 引入问题
|
||||
// import {
|
||||
// StorageResStatus,
|
||||
// StorageProcessType,
|
||||
// } from '../../workbench/browser/src/app/shared/services/storage/index.model';
|
||||
import { processEnv } from '../../platform/node/constant';
|
||||
import { proxyOpenExternal } from '../../shared/common/browserView';
|
||||
import { deleteFile, readJson } from '../../shared/node/file';
|
||||
import { STORAGE_TEMP as storageTemp } from '../../shared/common/constant';
|
||||
import { UnitWorkerModule } from '../../workbench/node/unitWorker';
|
||||
import { STORAGE_TEMP as storageTemp } from '../../shared/electron-main/constant';
|
||||
import { UnitWorkerModule } from '../../workbench/node/electron/main';
|
||||
import Configuration from '../../platform/node/configuration/lib';
|
||||
import { ConfigurationInterface } from 'src/platform/node/configuration';
|
||||
import { MockServer } from 'eo/platform/node/mock-server';
|
||||
import { LanguageService } from 'eo/app/electron-main/language.service';
|
||||
|
||||
let win: BrowserWindow = null;
|
||||
export const subView = {
|
||||
appView: null,
|
||||
mainView: null,
|
||||
};
|
||||
const eoUpdater = new EoUpdater();
|
||||
const mockServer = new MockServer();
|
||||
const moduleManager: ModuleManagerInterface = ModuleManager();
|
||||
const moduleManager: ModuleManagerInterface = new ModuleManager();
|
||||
const configuration: ConfigurationInterface = Configuration();
|
||||
// Remote
|
||||
const mainRemote = require('@electron/remote/main');
|
||||
mainRemote.initialize();
|
||||
global.shareObject = {
|
||||
storageResult: null,
|
||||
};
|
||||
|
||||
function createWindow(): BrowserWindow {
|
||||
const electronScreen = screen;
|
||||
const size = electronScreen.getPrimaryDisplay().workAreaSize;
|
||||
// Create the browser window.
|
||||
win = new BrowserWindow({
|
||||
width: Math.round(size.width * 0.85),
|
||||
height: Math.round(size.height * 0.85),
|
||||
minWidth: 1280,
|
||||
minHeight: 720,
|
||||
useContentSize: true, // 这个要设置,不然计算显示区域尺寸不准
|
||||
frame: os.type() === 'Darwin' ? true : false, //mac use default frame
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
preload: path.join(__dirname, '../../', 'platform', 'electron-browser', 'preload.js'),
|
||||
nodeIntegration: true,
|
||||
allowRunningInsecureContent: processEnv === 'development' ? true : false,
|
||||
contextIsolation: false, // false if you want to run e2e test with Spectron
|
||||
},
|
||||
});
|
||||
// 启动mock服务
|
||||
mockServer.start(win as any);
|
||||
proxyOpenExternal(win);
|
||||
let loadPage = async () => {
|
||||
let currentUrl = win.webContents.getURL();
|
||||
let locale = ['zh', 'en'].find((val) => currentUrl.includes(val));
|
||||
let eoBrowserWindow: EoBrowserWindow = null;
|
||||
class EoBrowserWindow {
|
||||
// Start mock server when app inital
|
||||
win: BrowserWindow;
|
||||
constructor() {
|
||||
this.create();
|
||||
}
|
||||
private startMock() {
|
||||
mockServer.start(this.win as any);
|
||||
}
|
||||
// Start unit test function
|
||||
private startUnitTest() {
|
||||
UnitWorkerModule.setup({
|
||||
view: this.win,
|
||||
});
|
||||
}
|
||||
//Watch win event
|
||||
private watch() {
|
||||
// Reload page when load page url error
|
||||
this.win.webContents.on('did-fail-load', (event, errorCode) => {
|
||||
console.error('did-fail-load', errorCode);
|
||||
this.loadURL();
|
||||
});
|
||||
this.win.on('closed', () => {
|
||||
// Dereference the window object, usually you would store window
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
this.win = null;
|
||||
});
|
||||
}
|
||||
public loadURL() {
|
||||
console.log('loadURL')
|
||||
const file: string =
|
||||
processEnv === 'development'
|
||||
? 'http://localhost:4200'
|
||||
: `file://${path.join(
|
||||
__dirname,
|
||||
`../../../src/workbench/browser/dist/${locale || app.getLocale()}/index.html`
|
||||
`../../../src/workbench/browser/dist/${LanguageService.getPath()}/index.html`
|
||||
)}`;
|
||||
win.loadURL(file);
|
||||
this.win.loadURL(file);
|
||||
if (['development'].includes(processEnv)) {
|
||||
win.webContents.openDevTools({
|
||||
this.win.webContents.openDevTools({
|
||||
mode: 'undocked',
|
||||
});
|
||||
}
|
||||
UnitWorkerModule.setup({
|
||||
view: win,
|
||||
}
|
||||
public create(): BrowserWindow {
|
||||
const size = screen.getPrimaryDisplay().workAreaSize;
|
||||
// Create the browser window.
|
||||
this.win = new BrowserWindow({
|
||||
width: Math.round(size.width * 0.85),
|
||||
height: Math.round(size.height * 0.85),
|
||||
minWidth: 1280,
|
||||
minHeight: 720,
|
||||
useContentSize: true, // 这个要设置,不然计算显示区域尺寸不准
|
||||
frame: os.type() === 'Darwin' ? true : false, //mac use default frame
|
||||
webPreferences: {
|
||||
webSecurity: false,
|
||||
preload: path.join(__dirname, '../../', 'platform', 'electron-browser', 'preload.js'),
|
||||
nodeIntegration: true,
|
||||
allowRunningInsecureContent: processEnv === 'development' ? true : false,
|
||||
contextIsolation: false, // false if you want to run e2e test with Spectron
|
||||
},
|
||||
});
|
||||
};
|
||||
win.webContents.on('did-fail-load', (event, errorCode) => {
|
||||
console.error('did-fail-load', errorCode);
|
||||
loadPage();
|
||||
});
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
mainRemote.enable(win.webContents);
|
||||
});
|
||||
loadPage();
|
||||
|
||||
// Emitted when the window is closed.
|
||||
win.on('closed', () => {
|
||||
// Dereference the window object, usually you would store window
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
win = null;
|
||||
});
|
||||
return win;
|
||||
proxyOpenExternal(this.win);
|
||||
this.loadURL();
|
||||
this.startMock();
|
||||
this.startUnitTest();
|
||||
this.watch();
|
||||
return this.win;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@ -102,7 +105,9 @@ try {
|
||||
// Some APIs can only be used after this event occurs.
|
||||
// Added 400 ms to fix the black background issue while using transparent window. More detais at https://github.com/electron/electron/issues/15947
|
||||
app.on('ready', async () => {
|
||||
setTimeout(createWindow, 400);
|
||||
setTimeout(() => {
|
||||
eoBrowserWindow = new EoBrowserWindow();
|
||||
}, 400);
|
||||
eoUpdater.check();
|
||||
});
|
||||
//!TODO only api manage app need this
|
||||
@ -121,8 +126,8 @@ try {
|
||||
app.on('activate', () => {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (win === null) {
|
||||
createWindow();
|
||||
if (eoBrowserWindow.win === null) {
|
||||
eoBrowserWindow.create();
|
||||
}
|
||||
});
|
||||
ipcMain.on('message', function (event, arg) {
|
||||
@ -131,32 +136,37 @@ try {
|
||||
// if (event.frameId !== 1) return;
|
||||
switch (arg.action) {
|
||||
case 'minimize': {
|
||||
win.minimize();
|
||||
eoBrowserWindow.win.minimize();
|
||||
break;
|
||||
}
|
||||
case 'restore': {
|
||||
win.restore();
|
||||
eoBrowserWindow.win.restore();
|
||||
break;
|
||||
}
|
||||
case 'maximize': {
|
||||
win.maximize();
|
||||
eoBrowserWindow.win.maximize();
|
||||
break;
|
||||
}
|
||||
case 'close': {
|
||||
win.close();
|
||||
eoBrowserWindow.win.close();
|
||||
break;
|
||||
}
|
||||
case 'changeLanguage': {
|
||||
LanguageService.set(arg.data);
|
||||
eoBrowserWindow.loadURL();
|
||||
moduleManager.refreshAll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('eo-storage', (event, args) => {
|
||||
let returnValue: any;
|
||||
if (args.type === 'default' || args.type === 'remote') {
|
||||
win.webContents.send('eo-storage', args);
|
||||
eoBrowserWindow.win.webContents.send('eo-storage', args);
|
||||
returnValue = null;
|
||||
} else if (args.type === 'sync') {
|
||||
deleteFile(storageTemp);
|
||||
win.webContents.send('eo-storage', args);
|
||||
eoBrowserWindow.win.webContents.send('eo-storage', args);
|
||||
let data = readJson(storageTemp);
|
||||
let count: number = 0;
|
||||
while (data === null) {
|
||||
@ -174,7 +184,7 @@ try {
|
||||
deleteFile(storageTemp);
|
||||
returnValue = data;
|
||||
} else if (args.type === 'result') {
|
||||
let view = subView.appView ? subView.appView?.view.webContents : win.webContents;
|
||||
let view = subView.appView ? subView.appView?.view.webContents : eoBrowserWindow.win.webContents;
|
||||
view.send('storageCallback', args.result);
|
||||
}
|
||||
});
|
||||
|
40
src/platform/common/i18n.ts
Normal file
40
src/platform/common/i18n.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { ModuleInfo } from 'eo/platform/node/extension-manager';
|
||||
/**
|
||||
* Single extension i18 service,chain call
|
||||
*/
|
||||
export class TranslateService {
|
||||
// Default key in package.json translate replace directly
|
||||
defaultKeys = ['moduleName', 'description', 'author', 'logo'];
|
||||
constructor(private module: ModuleInfo, private locale) {}
|
||||
translate() {
|
||||
return this.translateDefaultKey().translateVariableKey().get();
|
||||
}
|
||||
get() {
|
||||
return this.module;
|
||||
}
|
||||
translateDefaultKey() {
|
||||
this.defaultKeys.forEach((defaultKey) => {
|
||||
if (!this.module[defaultKey] || !this.locale[defaultKey]) return;
|
||||
this.module[defaultKey] = this.locale[defaultKey];
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Transalte package.json variable ${} to locale text
|
||||
*/
|
||||
translateVariableKey() {
|
||||
let that = this;
|
||||
Object.keys(this.module.features).forEach((name) => {
|
||||
let feature = that.module.features[name];
|
||||
Object.keys(feature).forEach((childName) => {
|
||||
if (typeof feature[childName] !== 'string') return;
|
||||
that.module.features[name][childName] = feature[childName].replace(/\$\{(.+)\}/g, (match, rest) => {
|
||||
let replacement = match;
|
||||
replacement = that.locale[rest] || replacement;
|
||||
return replacement;
|
||||
});
|
||||
});
|
||||
});
|
||||
return this;
|
||||
}
|
||||
}
|
30
src/platform/electron-browser/i18n.ts
Normal file
30
src/platform/electron-browser/i18n.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { getLocaleData } from '../node/i18n';
|
||||
import { LANGUAGES } from '../../workbench/browser/src/app/core/services/language/language.model';
|
||||
export class I18N {
|
||||
constructor() {
|
||||
}
|
||||
getSystemLanguage() {
|
||||
let deafultLanguage =
|
||||
LANGUAGES.find((val) => window.location.href.includes(`/${val.path}`))?.value ||
|
||||
(navigator.language.includes('zh') ? 'zh-Hans' : 'en-US');
|
||||
return window.eo.getSettings()['eoapi-language'] || deafultLanguage;
|
||||
}
|
||||
localize(id: string, originText: string, ...args) {
|
||||
let result = originText;
|
||||
const locale: Object = getLocaleData(window.eo.getModule(window.eo._currentExtensionID), this.getSystemLanguage());
|
||||
if (!locale) return result;
|
||||
result ??= locale[id];
|
||||
result = result.replace(/\{(\d+)\}/g, (match, rest) => {
|
||||
let index = rest[0];
|
||||
let arg = args[index];
|
||||
let replacement = match;
|
||||
if (typeof arg === 'string') {
|
||||
replacement = arg;
|
||||
} else if (typeof arg === 'number' || typeof arg === 'boolean' || arg === void 0 || arg === null) {
|
||||
replacement = String(arg);
|
||||
}
|
||||
return replacement;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { I18N } from './i18n';
|
||||
const { ipcRenderer } = require('electron');
|
||||
console.log('eoapi public api load');
|
||||
// 可以加上条件判断,根据不同模块id哪些允许放出
|
||||
const apiAccessRules = ipcRenderer.sendSync('eo-sync', { action: 'getApiAccessRules' }) || [];
|
||||
|
||||
@ -53,6 +53,7 @@ window.eo.loadFeatureModule = (moduleID) => {
|
||||
if (!featureModules.has(moduleID)) {
|
||||
try {
|
||||
const module = window.eo.getModule(moduleID);
|
||||
window.eo._currentExtensionID=moduleID;
|
||||
const _module = window.require(module.baseDir);
|
||||
featureModules.set(moduleID, _module);
|
||||
} catch (e) {
|
||||
@ -102,28 +103,28 @@ window.eo.storageSync = (args) => {
|
||||
args.type = 'sync';
|
||||
return ipcRenderer.sendSync('eo-storage', args);
|
||||
};
|
||||
window.eo.storageRemote = (args) => {
|
||||
console.log('run preload storageRemote');
|
||||
args.type = 'remote';
|
||||
const shareObject = window.require('@electron/remote').getGlobal('shareObject');
|
||||
shareObject.storageResult = null;
|
||||
ipcRenderer.send('eo-storage', args);
|
||||
let output: any = shareObject.storageResult;
|
||||
let count: number = 0;
|
||||
while (output === null) {
|
||||
if (count > 1500) {
|
||||
output = {
|
||||
status: 'error',
|
||||
data: 'storage remote load error',
|
||||
};
|
||||
break;
|
||||
}
|
||||
output = shareObject.storageResult;
|
||||
++count;
|
||||
}
|
||||
shareObject.storageResult = null;
|
||||
return output;
|
||||
};
|
||||
// window.eo.storageRemote = (args) => {
|
||||
// console.log('run preload storageRemote');
|
||||
// args.type = 'remote';
|
||||
// const shareObject = window.require('@electron/remote').getGlobal('shareObject');
|
||||
// shareObject.storageResult = null;
|
||||
// ipcRenderer.send('eo-storage', args);
|
||||
// let output: any = shareObject.storageResult;
|
||||
// let count: number = 0;
|
||||
// while (output === null) {
|
||||
// if (count > 1500) {
|
||||
// output = {
|
||||
// status: 'error',
|
||||
// data: 'storage remote load error',
|
||||
// };
|
||||
// break;
|
||||
// }
|
||||
// output = shareObject.storageResult;
|
||||
// ++count;
|
||||
// }
|
||||
// shareObject.storageResult = null;
|
||||
// return output;
|
||||
// };
|
||||
|
||||
window.eo.saveSettings = (settings) => {
|
||||
// console.log('window.eo.saveSettings', settings);
|
||||
@ -141,14 +142,18 @@ window.eo.deleteModuleSettings = (moduleID) => {
|
||||
return ipcRenderer.sendSync('eo-sync', { action: 'deleteModuleSettings', data: { moduleID: moduleID } });
|
||||
};
|
||||
|
||||
window.eo.getSettings = (settings) => {
|
||||
return ipcRenderer.sendSync('eo-sync', { action: 'getSettings' });
|
||||
window.eo.getSettings = () => {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('localSettings') || '{}');
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
window.eo.i18n = new I18N();
|
||||
|
||||
window.eo.getModuleSettings = (moduleID) => {
|
||||
return ipcRenderer.sendSync('eo-sync', { action: 'getModuleSettings', data: { moduleID: moduleID } });
|
||||
};
|
||||
|
||||
// 注册单个mock路由
|
||||
window.eo.registerMockRoute = ({ method, path, data }) => {
|
||||
return ipcRenderer.send('eo-sync', { action: 'registerMockRoute', data: { method, path, data } });
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DATA_DIR as dataDir } from 'eo/shared/common/constant';
|
||||
import { DATA_DIR as dataDir } from 'eo/shared/electron-main/constant';
|
||||
import { ConfigurationInterface, ConfigurationValueInterface } from '../types';
|
||||
import * as path from 'path';
|
||||
import { fileExists, readJson, writeJson } from 'eo/shared/node/file';
|
||||
|
@ -1,8 +1,10 @@
|
||||
import * as path from 'path';
|
||||
import { ModuleHandlerOptions, ModuleInfo } from '../types';
|
||||
import { fileExists, readJson } from 'eo/shared/node/file';
|
||||
import { fileExists, readFile, readJson } from 'eo/shared/node/file';
|
||||
import { isNotEmpty } from 'eo/shared/common/common';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { getLocaleData } from 'eo/platform/node/i18n';
|
||||
import { LanguageService } from 'eo/app/electron-main/language.service';
|
||||
import { TranslateService } from 'eo/platform/common/i18n';
|
||||
/**
|
||||
* 核心模块管理器
|
||||
* @class CoreHandler
|
||||
@ -37,8 +39,20 @@ export class CoreHandler {
|
||||
try {
|
||||
const baseDir: string = this.getModuleDir(name);
|
||||
moduleInfo = readJson(path.join(baseDir, 'package.json')) as ModuleInfo;
|
||||
moduleInfo.introduction = readFileSync(path.join(baseDir, 'README.md')).toString();
|
||||
moduleInfo.baseDir = baseDir;
|
||||
// Get language locale
|
||||
//!Warn:baseDir must be set before get locale file
|
||||
const lang = LanguageService.get();
|
||||
if (moduleInfo.features?.i18n) {
|
||||
const locale = getLocaleData(moduleInfo, lang);
|
||||
if (locale) {
|
||||
let translateService = new TranslateService(moduleInfo, locale);
|
||||
moduleInfo = translateService.translate();
|
||||
}
|
||||
}
|
||||
// Check that the file exists locally
|
||||
moduleInfo.introduction =
|
||||
readFile(path.join(baseDir, `README.${lang}.md`)) || readFile(path.join(baseDir, `README.md`));
|
||||
moduleInfo.main = 'file://' + path.join(moduleInfo.baseDir, moduleInfo.main);
|
||||
if (moduleInfo.preload?.length > 0) {
|
||||
moduleInfo.preload = path.join(moduleInfo.baseDir, moduleInfo.preload);
|
||||
@ -56,9 +70,9 @@ export class CoreHandler {
|
||||
moduleInfo.author = moduleInfo.author['name'] || '';
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(`get module ${moduleInfo.moduleID} error:${e}`);
|
||||
moduleInfo = {} as ModuleInfo;
|
||||
}
|
||||
|
||||
return moduleInfo;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ import { ModuleHandlerOptions, ModuleHandlerResult } from '../types';
|
||||
import { fileExists, writeJson } from 'eo/shared/node/file';
|
||||
import { CoreHandler } from './core';
|
||||
import * as fs from 'fs';
|
||||
import { spawn } from 'child_process';
|
||||
type Action = 'uninstall' | 'install' | 'update';
|
||||
// import npmCli from 'npm';
|
||||
const npmCli = require('npm');
|
||||
/**
|
||||
@ -60,7 +62,6 @@ export class ModuleHandler extends CoreHandler {
|
||||
async install(modules: string[], isLocal: boolean): Promise<ModuleHandlerResult> {
|
||||
return await this.execCommand(isLocal ? 'link' : 'install', modules);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新模块
|
||||
* @param {...string[]} modules 模块名称数组
|
||||
@ -83,7 +84,7 @@ export class ModuleHandler extends CoreHandler {
|
||||
* @param result npm install安装成功回调的结果
|
||||
* @param moduleList 所有的模块列表
|
||||
*/
|
||||
private operatePackage(result: any[], moduleList: string[], action: 'uninstall' | 'install' | 'update') {
|
||||
private operatePackage(result: any[], moduleList: string[], action: Action) {
|
||||
if (Array.isArray(result)) {
|
||||
const moduleNames = moduleList.map((n) => n.split('@')[0]);
|
||||
const packagePath = path.join(this.baseDir, 'package.json');
|
||||
@ -105,7 +106,55 @@ export class ModuleHandler extends CoreHandler {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private executeByAppNpm(command: string, modules: string[], resolve, reject) {
|
||||
// https://www.npmjs.com/package/bin-links
|
||||
npmCli.load({ 'bin-links': false, verbose: true, prefix: this.baseDir }, (loaderr) => {
|
||||
const moduleList = modules.map((it) => it + '@latest');
|
||||
console.log('moduleList',command, moduleList);
|
||||
let executeCommand = ['update', 'install', 'uninstall'];
|
||||
if (!executeCommand.includes(command)) return;
|
||||
npmCli.commands[command](moduleList, (err, data) => {
|
||||
process.chdir(this.baseDir);
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
this.operatePackage(data, moduleList, command as Action);
|
||||
return resolve({ code: 0, data });
|
||||
});
|
||||
});
|
||||
}
|
||||
private executeBySystemNpm(command: string, modules: string[], resolve) {
|
||||
let args = [command].concat(modules).concat('--color=always', '--save');
|
||||
if (!['link', 'unlink', 'uninstall', 'update'].includes(command)) {
|
||||
if (this.registry) {
|
||||
args = args.concat(`--registry=${this.registry}`);
|
||||
}
|
||||
if (this.proxy) {
|
||||
args = args.concat(`--proxy=${this.proxy}`);
|
||||
}
|
||||
}
|
||||
console.log(args)
|
||||
const npm = spawn('npm', args, { cwd: this.baseDir });
|
||||
// console.log('2==>', npm);
|
||||
let output = '';
|
||||
npm.stdout
|
||||
.on('data', (data: string) => {
|
||||
output += data;
|
||||
})
|
||||
.pipe(process.stdout);
|
||||
npm.stderr
|
||||
.on('data', (data: string) => {
|
||||
output += data;
|
||||
})
|
||||
.pipe(process.stderr);
|
||||
npm.on('close', (code: number) => {
|
||||
if (!code) {
|
||||
resolve({ code: 0, data: output });
|
||||
} else {
|
||||
resolve({ code: code, data: output });
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 运行模块管理器
|
||||
* @param command
|
||||
@ -113,71 +162,8 @@ export class ModuleHandler extends CoreHandler {
|
||||
*/
|
||||
private async execCommand(command: string, modules: string[]): Promise<ModuleHandlerResult> {
|
||||
return await new Promise((resolve: any, reject: any): void => {
|
||||
let args = [command].concat(modules).concat('--color=always', '--save');
|
||||
if (!['link', 'unlink', 'uninstall', 'update'].includes(command)) {
|
||||
if (this.registry) {
|
||||
args = args.concat(`--registry=${this.registry}`);
|
||||
}
|
||||
if (this.proxy) {
|
||||
args = args.concat(`--proxy=${this.proxy}`);
|
||||
}
|
||||
}
|
||||
// console.log(npmCli.commands.run('version'));
|
||||
// console.log('command', [command].concat(modules), this.baseDir);
|
||||
npmCli.load({ 'bin-links': false, verbose: true, prefix: this.baseDir }, (loaderr) => {
|
||||
const moduleList = modules.map((it) => it + '@latest');
|
||||
if (command === 'update') {
|
||||
npmCli.commands.update(moduleList, (err, data) => {
|
||||
process.chdir(this.baseDir);
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
this.operatePackage(data, moduleList, 'update');
|
||||
return resolve({ code: 0, data });
|
||||
});
|
||||
}
|
||||
if (command === 'install') {
|
||||
npmCli.commands.install(moduleList, (err, data) => {
|
||||
process.chdir(this.baseDir);
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
this.operatePackage(data, moduleList, 'install');
|
||||
return resolve({ code: 0, data });
|
||||
});
|
||||
}
|
||||
if (command === 'uninstall') {
|
||||
npmCli.commands.uninstall(moduleList, (err, data) => {
|
||||
process.chdir(this.baseDir);
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
this.operatePackage(data, moduleList, 'uninstall');
|
||||
return resolve({ code: 0, data });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// const npm = spawn('npm', args, { cwd: this.baseDir });
|
||||
// // console.log('2==>', npm);
|
||||
// let output = '';
|
||||
// npm.stdout
|
||||
// .on('data', (data: string) => {
|
||||
// output += data;
|
||||
// })
|
||||
// .pipe(process.stdout);
|
||||
// npm.stderr
|
||||
// .on('data', (data: string) => {
|
||||
// output += data;
|
||||
// })
|
||||
// .pipe(process.stderr);
|
||||
// npm.on('close', (code: number) => {
|
||||
// if (!code) {
|
||||
// resolve({ code: 0, data: output });
|
||||
// } else {
|
||||
// resolve({ code: code, data: output });
|
||||
// }
|
||||
// });
|
||||
// this.executeBySystemNpm(command, modules, resolve)
|
||||
this.executeByAppNpm(command, modules, resolve, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ export class ModuleLoader implements ModuleLoaderInterface {
|
||||
* @param module ModuleInfo
|
||||
*/
|
||||
loadModule(module: ModuleInfo): void {
|
||||
console.log(module);
|
||||
if ((this.runtime === ModuleRuntime.main && ![ModuleType.system, ModuleType.app].indexOf(module.moduleType))
|
||||
|| (this.runtime === ModuleRuntime.render && ![ModuleType.feature].indexOf(module.moduleType))
|
||||
|| (this.runtime === ModuleRuntime.web && !module.web)) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MODULE_DIR as baseDir } from 'eo/shared/common/constant';
|
||||
import { MODULE_DIR as baseDir } from 'eo/shared/electron-main/constant';
|
||||
import { ModuleHandler } from './handler';
|
||||
import { ModuleHandlerResult, ModuleInfo, ModuleManagerInfo, ModuleManagerInterface, ModuleType } from '../types';
|
||||
import { isNotEmpty } from 'eo/shared/common/common';
|
||||
@ -6,7 +6,6 @@ import { processEnv } from '../../constant';
|
||||
|
||||
// * npm pkg name
|
||||
const installExtension = [{ name: 'eoapi-export-openapi' }, { name: 'eoapi-import-openapi' }];
|
||||
|
||||
export class ModuleManager implements ModuleManagerInterface {
|
||||
/**
|
||||
* 模块管理器
|
||||
@ -33,20 +32,7 @@ export class ModuleManager implements ModuleManagerInterface {
|
||||
this.modules = new Map();
|
||||
this.features = new Map();
|
||||
this.init();
|
||||
// * ModuleManager will be new only one while app run start, so it should be here upgrade & install extension
|
||||
// * upgrade
|
||||
const list = Array.from(this.getModules().keys());
|
||||
list.forEach((item) => {
|
||||
this.update({ name: item });
|
||||
});
|
||||
// * install
|
||||
// console.log('install');
|
||||
this.installExtension.forEach((item) => {
|
||||
// * If the extension already in local extension list, then do not repeat installation
|
||||
if (!list.includes(item.name)) {
|
||||
this.install(item);
|
||||
}
|
||||
});
|
||||
this.updateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,7 +59,22 @@ export class ModuleManager implements ModuleManagerInterface {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
updateAll() {
|
||||
// * ModuleManager will be new only one while app run start, so it should be here upgrade & install extension
|
||||
// * Upgrade
|
||||
const list = Array.from(this.getModules().values()).map((val) => val.name);
|
||||
list.forEach((item) => {
|
||||
//!Warn this is bug,it did't work @kungfuboy
|
||||
this.update({ name: item });
|
||||
});
|
||||
// * Install default extension
|
||||
this.installExtension.forEach((item) => {
|
||||
// * If the extension already in local extension list, then do not repeat installation
|
||||
if (list.includes(item.name)) return;
|
||||
//!TODO this will reinstall all package, npm link(debug) package will be remove after npm install command,
|
||||
// this.install(item);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 删除模块,调用npm uninstall | unlink
|
||||
* @param module
|
||||
@ -95,7 +96,16 @@ export class ModuleManager implements ModuleManagerInterface {
|
||||
const moduleInfo: ModuleInfo = this.moduleHandler.info(module.name);
|
||||
this.set(moduleInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取本地package.json更新模块信息
|
||||
* @param module
|
||||
*/
|
||||
refreshAll(): void {
|
||||
const list = Array.from(this.getModules().values());
|
||||
list.forEach((module) => {
|
||||
this.refresh(module);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 获取应用级app列表
|
||||
*/
|
||||
@ -281,5 +291,3 @@ export class ModuleManager implements ModuleManagerInterface {
|
||||
return newModules;
|
||||
}
|
||||
}
|
||||
|
||||
export default () => new ModuleManager();
|
||||
|
@ -13,36 +13,38 @@ export enum ModuleType {
|
||||
app = 'app',
|
||||
feature = 'feature',
|
||||
}
|
||||
|
||||
export interface I18nLocale{
|
||||
locale: string; package: any
|
||||
}
|
||||
/**
|
||||
* 模块信息接口
|
||||
*/
|
||||
export interface ModuleInfo {
|
||||
// 模块名称, npm包名
|
||||
// npm package name
|
||||
name: string;
|
||||
// 作者
|
||||
// author
|
||||
author: string;
|
||||
// 版本
|
||||
// extension version
|
||||
version: string;
|
||||
// 模块描述
|
||||
// extension description
|
||||
description: string;
|
||||
// 详细说明
|
||||
// extension intro,from README.md
|
||||
introduction: string;
|
||||
// 模块ID,用于关联
|
||||
// extension ID
|
||||
moduleID: string;
|
||||
// 模块名称,用于显示
|
||||
// extension name
|
||||
moduleName: string;
|
||||
// 模块类型
|
||||
// extension type
|
||||
moduleType: ModuleType;
|
||||
// 模块Logo
|
||||
// extension logo
|
||||
logo: string;
|
||||
// 入口文件
|
||||
// manifest code file
|
||||
main: string;
|
||||
// main端运行脚本
|
||||
// main node script
|
||||
main_node?: string;
|
||||
// 入口开发调试
|
||||
main_debug?: string;
|
||||
// 预加载js文件
|
||||
// inject script before start app
|
||||
preload?: string;
|
||||
// 判断是不是顶层App
|
||||
isApp?: boolean;
|
||||
@ -64,8 +66,9 @@ export interface ModuleInfo {
|
||||
contributes: ModuleContributes;
|
||||
// 功能点配置
|
||||
features?: {
|
||||
[index: string]: object;
|
||||
[index: string]: any;
|
||||
};
|
||||
i18n?:I18nLocale[]
|
||||
}
|
||||
/**
|
||||
* 贡献点
|
||||
@ -118,6 +121,7 @@ export interface ModuleManagerInterface {
|
||||
update: (module: ModuleManagerInfo) => Promise<ModuleHandlerResult>;
|
||||
uninstall: (module: ModuleManagerInfo) => Promise<ModuleHandlerResult>;
|
||||
refresh: (module: ModuleManagerInfo) => void;
|
||||
refreshAll:()=>void;
|
||||
getModule: (moduleID: string, belongs?: boolean) => ModuleInfo;
|
||||
getModules: (belongs?: boolean) => Map<string, ModuleInfo>;
|
||||
getAppModuleList: () => Array<ModuleInfo>;
|
||||
|
37
src/platform/node/i18n.ts
Normal file
37
src/platform/node/i18n.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { I18nLocale, ModuleInfo } from 'eo/platform/node/extension-manager';
|
||||
|
||||
interface LooseObject {
|
||||
[key: string]: any;
|
||||
}
|
||||
const localeStorage: LooseObject = {};
|
||||
/**
|
||||
* Get locale file from extension i18 file dir
|
||||
* @param moduleID
|
||||
* @returns json
|
||||
*/
|
||||
function getLocaleFile(module: ModuleInfo, lang): Object {
|
||||
let result = {};
|
||||
try {
|
||||
result = require(`${module.baseDir}/i18n/${lang}.json`);
|
||||
} catch (e) {}
|
||||
return result;
|
||||
}
|
||||
function getSupportLang(module: ModuleInfo) {
|
||||
return [module.features.i18n.sourceLocale, ...module.features.i18n.locales].filter((val) => val);
|
||||
}
|
||||
/**
|
||||
* Get locale data from storage or file
|
||||
* @returns json
|
||||
*/
|
||||
export function getLocaleData(module: ModuleInfo, lang): Object | null {
|
||||
let supportLang = getSupportLang(module);
|
||||
if (!supportLang.includes(lang)) {
|
||||
console.log(`Error: extenaion ${module.moduleID} can't find the i18n package ${lang}`);
|
||||
return null;
|
||||
}
|
||||
localeStorage[module.moduleID] = localeStorage[module.moduleID] || {};
|
||||
if (!localeStorage[module.moduleID][lang]) {
|
||||
localeStorage[module.moduleID][lang] = getLocaleFile(module, lang);
|
||||
}
|
||||
return localeStorage[module.moduleID][lang];
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { shell } from 'electron';
|
||||
//open link through default browser not electron
|
||||
//Open link through system default browser not Electron browserwin
|
||||
export function proxyOpenExternal(view) {
|
||||
view.webContents.setWindowOpenHandler(({ url }) => {
|
||||
setImmediate(() => {
|
||||
|
@ -17,6 +17,3 @@ export const isNotEmpty = (value: any) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const isElectron = () => {
|
||||
return !!(window && window.process && window.process.type);
|
||||
};
|
||||
|
@ -5,4 +5,4 @@ export const home: string = app.getPath('home');
|
||||
export const HOME_DIR = path.join(home, '.eo');
|
||||
export const DATA_DIR = path.join(HOME_DIR, 'data');
|
||||
export const MODULE_DIR = HOME_DIR;
|
||||
export const STORAGE_TEMP = path.join(HOME_DIR, 'tmp.storage');
|
||||
export const STORAGE_TEMP = path.join(HOME_DIR, 'tmp.storage');
|
@ -1,7 +1,5 @@
|
||||
//change angular.json
|
||||
const fs = require('fs');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
class webPlatformBuilder {
|
||||
resetBuildConfig(json) {
|
||||
delete json.projects.eoapi.i18n.sourceLocale.baseHref;
|
||||
@ -23,7 +21,7 @@ class appPlatformBuilder {
|
||||
return json;
|
||||
}
|
||||
executeBuild() {
|
||||
execSync('ng build --base-href ./', { stdio: 'inherit' });
|
||||
execSync('ng build -c production --base-href ./', { stdio: 'inherit' });
|
||||
}
|
||||
}
|
||||
class PlatformBuilder {
|
||||
@ -40,9 +38,10 @@ class PlatformBuilder {
|
||||
}
|
||||
}
|
||||
build() {
|
||||
let buildConfigJson = require( '../angular.json');
|
||||
//Because of i18n,we should change angular.json for generate different base-href html tag
|
||||
let buildConfigJson = require('../angular.json');
|
||||
buildConfigJson = this.instance.resetBuildConfig(buildConfigJson);
|
||||
let that=this;
|
||||
let that = this;
|
||||
fs.writeFile('./angular.json', JSON.stringify(buildConfigJson), function (err) {
|
||||
if (err) {
|
||||
console.error('build/beforeBuild.js:', err);
|
||||
@ -51,6 +50,7 @@ class PlatformBuilder {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let platform = process.argv[2] || 'app';
|
||||
let platformBuilder = new PlatformBuilder(platform);
|
||||
platformBuilder.build();
|
||||
|
@ -24,6 +24,8 @@ import { NzMessageService } from 'ng-zorro-antd/message';
|
||||
import { NzModalService } from 'ng-zorro-antd/modal';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { BaseUrlInterceptor } from 'eo/workbench/browser/src/app/shared/services/storage/http/lib/baseUrl.service';
|
||||
import { LanguageService } from 'eo/workbench/browser/src/app/core/services/language/language.service';
|
||||
import { APP_CONFIG } from 'eo/workbench/browser/src/environments/environment';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
@ -58,7 +60,10 @@ import { BaseUrlInterceptor } from 'eo/workbench/browser/src/app/shared/services
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {
|
||||
constructor(private upgrade: UpgradeModule) {
|
||||
constructor(private upgrade: UpgradeModule, private lang: LanguageService) {
|
||||
if (APP_CONFIG.production) {
|
||||
this.lang.init();
|
||||
}
|
||||
this.upgrade.bootstrap(document.body, ['eolinker']);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
export const LANGUAGES = [
|
||||
{
|
||||
name: 'English',
|
||||
value: 'en-US',
|
||||
path: 'en',
|
||||
},
|
||||
{
|
||||
name: '简体中文',
|
||||
value: 'zh-Hans',
|
||||
path: 'zh',
|
||||
},
|
||||
];
|
@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LanguageService } from './language.service';
|
||||
|
||||
describe('LanguageService', () => {
|
||||
let service: LanguageService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(LanguageService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,39 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ElectronService } from 'eo/workbench/browser/src/app/core/services/electron/electron.service';
|
||||
import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service';
|
||||
import { LANGUAGES } from 'eo/workbench/browser/src/app/core/services/language/language.model';
|
||||
import { SettingService } from 'eo/workbench/browser/src/app/core/services/settings/settings.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
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 =
|
||||
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) {}
|
||||
|
||||
init() {
|
||||
this.changeLanguage(this.setting.getSettings()?.['eoapi-language']);
|
||||
}
|
||||
changeLanguage(localeID) {
|
||||
if (!localeID || localeID === this.systemLanguage) {
|
||||
console.warn(`current language has already ${localeID}`);
|
||||
return;
|
||||
}
|
||||
this.systemLanguage = localeID;
|
||||
const localePath = (this.languages.find((val) => val.value === localeID) || this.languages[0]).path;
|
||||
if (this.electron.isElectron) {
|
||||
this.electron.ipcRenderer.send('message', {
|
||||
action: 'changeLanguage',
|
||||
data: this.systemLanguage,
|
||||
});
|
||||
} else {
|
||||
window.location.href = `/${localePath}`;
|
||||
}
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import { ApiParamsNumPipe } from '../../../shared/pipes/api-param-num.pipe';
|
||||
import { StorageService } from '../../../shared/services/storage';
|
||||
import { TestServerLocalNodeService } from '../../../shared/services/api-test/local-node/test-connect.service';
|
||||
import { TestServerServerlessService } from '../../../shared/services/api-test/serverless-node/test-connect.service';
|
||||
import { TestServerRemoteService } from 'eo/workbench/browser/src/app/shared/services/api-test/remote-node/test-connect.service';
|
||||
|
||||
@Component({
|
||||
selector: 'eo-api-test',
|
||||
@ -48,7 +49,7 @@ export class ApiTestComponent implements OnInit, OnDestroy {
|
||||
response: {},
|
||||
request: {},
|
||||
};
|
||||
testServer: TestServerLocalNodeService | TestServerServerlessService;
|
||||
testServer: TestServerLocalNodeService | TestServerServerlessService | TestServerRemoteService;
|
||||
REQUEST_METHOD = objectToArray(RequestMethod);
|
||||
REQUEST_PROTOCOL = objectToArray(RequestProtocol);
|
||||
|
||||
|
@ -40,6 +40,7 @@ import { ApiTestResultHeaderComponent } from './result-header/api-test-result-he
|
||||
import { ApiTestResultResponseComponent } from './result-response/api-test-result-response.component';
|
||||
import { ApiTestHistoryComponent } from './history/api-test-history.component';
|
||||
import { ApiTestResultRequestBodyComponent } from './result-request-body/api-test-result-request-body.component';
|
||||
import { TestServerRemoteService } from 'eo/workbench/browser/src/app/shared/services/api-test/remote-node/test-connect.service';
|
||||
const NZ_COMPONETS = [
|
||||
NzDropDownModule,
|
||||
NzModalModule,
|
||||
@ -81,6 +82,6 @@ const COMPONENTS = [
|
||||
SharedModule,
|
||||
ParamsImportModule
|
||||
],
|
||||
providers: [ApiTestService, TestServerService, TestServerLocalNodeService,TestServerServerlessService],
|
||||
providers: [ApiTestService, TestServerService, TestServerLocalNodeService,TestServerServerlessService,TestServerRemoteService],
|
||||
})
|
||||
export class ApiTestModule {}
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
<h2 class="text-lg font-bold mt-[30px]" i18n>Support</h2>
|
||||
<nz-descriptions [nzColumn]="1" nzTitle="">
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Author">{{ extensionDetail?.author }}</nz-descriptions-item>
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Author">{{ extensionDetail?.author}}</nz-descriptions-item>
|
||||
<nz-descriptions-item i18n-nzTitle nzTitle="Version">{{ extensionDetail?.version }}
|
||||
</nz-descriptions-item>
|
||||
</nz-descriptions>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ModuleInfo } from "../../utils/module-loader";
|
||||
import { ModuleInfo } from 'eo/platform/node/extension-manager/types/index';
|
||||
|
||||
export enum ExtensionGroupType {
|
||||
all = 'all',
|
||||
|
@ -1,30 +1,54 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { isElectron } from 'eo/shared/common/common';
|
||||
import { ElectronService } from 'eo/workbench/browser/src/app/core/services';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { ModuleInfo } from '../../utils/module-loader';
|
||||
import { EoExtensionInfo } from './extension.model';
|
||||
import { ModuleInfo } from 'eo/platform/node/extension-manager/types/index';
|
||||
import { TranslateService } from 'eo/platform/common/i18n';
|
||||
import { LanguageService } from 'eo/workbench/browser/src/app/core/services/language/language.service';
|
||||
|
||||
const HOST = 'http://106.12.149.147';
|
||||
@Injectable()
|
||||
export class ExtensionService {
|
||||
ignoreList = ['default'];
|
||||
extensionIDs: Array<string> = [];
|
||||
localModules: Map<string, ModuleInfo>;
|
||||
constructor(private http: HttpClient) {
|
||||
this.getInstalledList();
|
||||
HOST = '';
|
||||
localExtensions: Map<string, ModuleInfo>;
|
||||
constructor(private http: HttpClient, private electron: ElectronService, private language: LanguageService) {
|
||||
this.localExtensions = this.getExtensions();
|
||||
this.extensionIDs = this.updateExtensionIDs();
|
||||
this.HOST = this.electron.isElectron
|
||||
? 'http://106.12.149.147'
|
||||
: 'https://mockapi.eolink.com/ztBFKai20ee60c12871881565b5a6ddd718337df0e30979';
|
||||
}
|
||||
private getExtensions() {
|
||||
// Local extension
|
||||
return window.eo?.getModules() || new Map();
|
||||
}
|
||||
getInstalledList() {
|
||||
this.localModules = window.eo?.getModules() || new Map();
|
||||
this.updateExtensionIDs();
|
||||
// Local extension exception for ignore list
|
||||
return Array.from(this.localExtensions.values()).filter((it) => this.extensionIDs.includes(it.moduleID));
|
||||
}
|
||||
private translateModule(module: ModuleInfo) {
|
||||
const lang = this.language.systemLanguage;
|
||||
const locale = module.i18n?.find((val) => val.locale === lang)?.package;
|
||||
console.log(locale, module);
|
||||
if (!locale) return module;
|
||||
module = new TranslateService(module, locale).translate();
|
||||
return module;
|
||||
}
|
||||
public async requestList() {
|
||||
return await lastValueFrom(this.http.get(`${HOST}/list`));
|
||||
let result: any = await lastValueFrom(this.http.get(`${this.HOST}/list?locale=${this.language.systemLanguage}`));
|
||||
result.data = [
|
||||
...result.data,
|
||||
//Local debug package
|
||||
...this.getInstalledList().filter((val) => result.data.every((childVal) => childVal.name !== val.name)),
|
||||
];
|
||||
result.data = result.data.map((module) => this.translateModule(module));
|
||||
return result;
|
||||
}
|
||||
async getDetail(id, name): Promise<any> {
|
||||
let result = {};
|
||||
if (this.localModules.has(id)) {
|
||||
Object.assign(result, this.localModules.get(id), { installed: true });
|
||||
if (this.localExtensions.has(id)) {
|
||||
Object.assign(result, this.localExtensions.get(id), { installed: true });
|
||||
}
|
||||
let { code, data }: any = await this.requestDetail(name);
|
||||
Object.assign(result, data);
|
||||
@ -39,7 +63,7 @@ export class ExtensionService {
|
||||
console.log('Install module:', id);
|
||||
const { code, data, modules } = window.eo.installModule(id);
|
||||
if (code === 0) {
|
||||
this.localModules = modules;
|
||||
this.localExtensions = modules;
|
||||
this.updateExtensionIDs();
|
||||
return true;
|
||||
}
|
||||
@ -50,7 +74,7 @@ export class ExtensionService {
|
||||
console.log('Install module:', id);
|
||||
const { code, data, modules } = window.eo.uninstallModule(id);
|
||||
if (code === 0) {
|
||||
this.localModules = modules;
|
||||
this.localExtensions = modules;
|
||||
this.updateExtensionIDs();
|
||||
return true;
|
||||
}
|
||||
@ -58,10 +82,12 @@ export class ExtensionService {
|
||||
return false;
|
||||
}
|
||||
private async requestDetail(id) {
|
||||
return await lastValueFrom(this.http.get(`${HOST}/detail/${id}`));
|
||||
return await lastValueFrom(this.http.get(`${this.HOST}/detail/${id}?locale=${this.language.systemLanguage}`)).catch(
|
||||
(err) => [0, err]
|
||||
);
|
||||
}
|
||||
private updateExtensionIDs() {
|
||||
this.extensionIDs = Array.from(this.localModules.keys())
|
||||
return Array.from(this.localExtensions.keys())
|
||||
.filter((it) => it)
|
||||
.filter((it) => !this.ignoreList.includes(it));
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
<span class="my-1 text-gray-500 desc">{{ it.description }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span *ngIf="isElectron ? extensionService.localModules.has(it.moduleID) : it.installed"
|
||||
class="p-1 text-xs text-green-700 border-green-700 rounded-sm bd_all" i18n>Installed</span>
|
||||
<span *ngIf="electron.isElectron ? extensionService.localExtensions.has(it.moduleID) : it.installed"
|
||||
class="p-1 text-xs text-green-700 border-green-700 rounded-sm bd_all whitespace-nowrap" i18n>Installed</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { isElectron } from 'eo/shared/common/common';
|
||||
import { ElectronService } from 'eo/workbench/browser/src/app/core/services';
|
||||
import { Message, MessageService } from 'eo/workbench/browser/src/app/shared/services/message';
|
||||
import { debounceTime, distinctUntilChanged, takeUntil, Subject } from 'rxjs';
|
||||
import { ExtensionGroupType } from '../extension.model';
|
||||
@ -25,12 +25,12 @@ export class ExtensionListComponent implements OnInit {
|
||||
type: ExtensionGroupType = ExtensionGroupType.all;
|
||||
keyword = '';
|
||||
renderList = [];
|
||||
isElectron = isElectron();
|
||||
seachChanged$: Subject<string> = new Subject<string>();
|
||||
private destroy$: Subject<void> = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
public extensionService: ExtensionService,
|
||||
public electron:ElectronService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private messageService: MessageService
|
||||
@ -46,11 +46,7 @@ export class ExtensionListComponent implements OnInit {
|
||||
}
|
||||
async searchPlugin(keyword = '') {
|
||||
if (this.type === 'installed') {
|
||||
const installedList = new ExtensionList(
|
||||
[...window.eo.getModules()]
|
||||
.map((it) => it[1])
|
||||
.filter((it) => this.extensionService.extensionIDs.includes(it.moduleID))
|
||||
);
|
||||
const installedList = new ExtensionList(this.extensionService.getInstalledList());
|
||||
return installedList.search(keyword);
|
||||
}
|
||||
const res: any = await this.extensionService.requestList();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<eo-navbar></eo-navbar>
|
||||
<div [style.--remote-notification-height]="isShowNotification && isElectron ? '50px' : '0px'">
|
||||
<div *ngIf="isShowNotification && isElectron" class="remote-notification">
|
||||
<div [style.--remote-notification-height]="isShowNotification && electron.isElectron ? '50px' : '0px'">
|
||||
<div *ngIf="isShowNotification && electron.isElectron" class="remote-notification">
|
||||
<i nz-icon [nzType]="isRemote ? 'cloud' : 'exclamation-circle'" nzTheme="outline" class="text-[13px] mr-[2px]"></i>
|
||||
<span i18n>Current data storage exists{{ dataSourceText }},please switch if you want to collaborate</span>
|
||||
<a class="eo-blod" (click)="switchDataSource()" i18n>{{ isRemote ? 'Remote Server' : 'Localhost' }} Data Storage</a>
|
||||
|
@ -4,9 +4,9 @@ import { SidebarService } from 'eo/workbench/browser/src/app/shared/components/s
|
||||
import { Message } from 'eo/workbench/browser/src/app/shared/services/message/message.model';
|
||||
import { MessageService } from 'eo/workbench/browser/src/app/shared/services/message/message.service';
|
||||
import { Subject, takeUntil, debounceTime } from 'rxjs';
|
||||
import { isElectron } from 'eo/shared/common/common';
|
||||
import { RemoteService } from 'eo/workbench/browser/src/app/shared/services/remote/remote.service';
|
||||
import { IS_SHOW_REMOTE_SERVER_NOTIFICATION } from 'eo/workbench/browser/src/app/shared/services/storage/storage.service';
|
||||
import { ElectronService } from 'eo/workbench/browser/src/app/core/services';
|
||||
|
||||
@Component({
|
||||
selector: 'eo-pages',
|
||||
@ -19,7 +19,6 @@ export class PagesComponent implements OnInit {
|
||||
get isRemote() {
|
||||
return this.remoteService.isRemote;
|
||||
}
|
||||
isElectron = isElectron();
|
||||
isShow = localStorage.getItem(IS_SHOW_REMOTE_SERVER_NOTIFICATION) === 'true';
|
||||
get dataSourceText() {
|
||||
return this.remoteService.dataSourceText;
|
||||
@ -34,7 +33,8 @@ export class PagesComponent implements OnInit {
|
||||
private cdRef: ChangeDetectorRef,
|
||||
public sidebar: SidebarService,
|
||||
private messageService: MessageService,
|
||||
private remoteService: RemoteService
|
||||
private remoteService: RemoteService,
|
||||
public electron:ElectronService
|
||||
) {
|
||||
this.rawChange$.pipe(debounceTime(500), takeUntil(this.destroy$)).subscribe(() => {
|
||||
this.updateState();
|
||||
|
@ -3,6 +3,7 @@ import { StorageService } from '../../../shared/services/storage';
|
||||
import { StorageRes, StorageResStatus } from '../../services/storage/index.model';
|
||||
import packageJson from '../../../../../../../../package.json';
|
||||
import { FeatureType } from '../../types';
|
||||
import { ModuleInfo } from 'eo/platform/node/extension-manager';
|
||||
|
||||
@Component({
|
||||
selector: 'eo-export-api',
|
||||
@ -67,19 +68,14 @@ export class ExportApiComponent implements OnInit {
|
||||
const feature = this.featureMap.get(this.currentExtension);
|
||||
const action = feature.action || null;
|
||||
const filename = feature.filename || null;
|
||||
const module = window.eo.loadFeatureModule(this.currentExtension);
|
||||
const module: ModuleInfo = window.eo.loadFeatureModule(this.currentExtension);
|
||||
if (action && filename && module && module[action] && typeof module[action] === 'function') {
|
||||
this.storage.run('projectExport', [], (result: StorageRes) => {
|
||||
if (result.status === StorageResStatus.success) {
|
||||
result.data.version = packageJson.version;
|
||||
try {
|
||||
const output = module[action](result || {});
|
||||
this.transferTextToFile(filename, output);
|
||||
callback(true);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
callback(false);
|
||||
}
|
||||
const output = module[action](result || {});
|
||||
this.transferTextToFile(filename, output);
|
||||
callback(true);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core';
|
||||
import { ElectronService } from 'eo/workbench/browser/src/app/core/services';
|
||||
import { NzModalService } from 'ng-zorro-antd/modal';
|
||||
import { LanguageService } from 'eo/workbench/browser/src/app/core/services/language/language.service';
|
||||
|
||||
@Component({
|
||||
selector: 'eo-language-switcher',
|
||||
@ -13,7 +12,12 @@ import { NzModalService } from 'ng-zorro-antd/modal';
|
||||
(ngModelChange)="handleChange($event)"
|
||||
[nzCustomTemplate]="defaultTemplate"
|
||||
>
|
||||
<nz-option *ngFor="let item of languages" nzCustomContent [nzValue]="item.value" [nzLabel]="item.name">
|
||||
<nz-option
|
||||
*ngFor="let item of languageService.languages"
|
||||
nzCustomContent
|
||||
[nzValue]="item.value"
|
||||
[nzLabel]="item.name"
|
||||
>
|
||||
<eo-iconpark-icon name="language"></eo-iconpark-icon>
|
||||
{{ item.name }}
|
||||
</nz-option>
|
||||
@ -34,40 +38,15 @@ import { NzModalService } from 'ng-zorro-antd/modal';
|
||||
export class LanguageSwticherComponent implements OnInit {
|
||||
@Input() model: object = {};
|
||||
@Output() modelChange: EventEmitter<any> = new EventEmitter();
|
||||
languages = [
|
||||
{
|
||||
name: 'English',
|
||||
value: 'en-US',
|
||||
path: 'en',
|
||||
},
|
||||
{
|
||||
name: '简体中文',
|
||||
value: 'zh-Hans',
|
||||
path: 'zh',
|
||||
},
|
||||
];
|
||||
constructor(private modal: NzModalService, private electron: ElectronService) {}
|
||||
constructor(public languageService: LanguageService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.model['eoapi-language'] ??= navigator.language.includes('zh') ? 'zh-Hans' : 'en-US';
|
||||
this.model['eoapi-language'] = this.languageService.systemLanguage;
|
||||
}
|
||||
|
||||
handleChange(inputLocaleID) {
|
||||
let changeCallback = (localeID) => {
|
||||
this.model['eoapi-language'] = localeID;
|
||||
this.modelChange.emit(this.model);
|
||||
window.location.href = `/${(this.languages.find((val) => val.value === localeID) || this.languages[0]).path}`;
|
||||
};
|
||||
// if (this.electron.isElectron) {
|
||||
// this.modal.warning({
|
||||
// nzTitle: ``,
|
||||
// nzContent:`Eoapi will need to restart after you switch the app language to ${this.languages.find(val=>val.value===inputLocaleID).name}`,
|
||||
// nzOnOk: () => {
|
||||
// changeCallback(inputLocaleID);
|
||||
// },
|
||||
// });
|
||||
// } else {
|
||||
changeCallback(inputLocaleID);
|
||||
// }
|
||||
handleChange(localeID) {
|
||||
this.model['eoapi-language'] = localeID;
|
||||
this.modelChange.emit(this.model);
|
||||
this.languageService.changeLanguage(localeID);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ModuleInfo } from '../../../utils/module-loader';
|
||||
import { ModuleInfo } from 'eo/platform/node/extension-manager/types/index';
|
||||
import { SidebarModuleInfo } from './sidebar.model';
|
||||
|
||||
@Injectable({
|
||||
|
@ -0,0 +1,90 @@
|
||||
import { Injectable, Inject, LOCALE_ID } from '@angular/core';
|
||||
|
||||
import { TestServer } from '../test-server.model';
|
||||
import { eoFormatRequestData, eoFormatResponseData } from '../api-test.utils';
|
||||
@Injectable()
|
||||
export class TestServerRemoteService implements TestServer {
|
||||
receiveMessage: (message) => void;
|
||||
xhrByTabID = {};
|
||||
constructor(@Inject(LOCALE_ID) private locale: string) {}
|
||||
init(receiveMessage: (message) => void) {
|
||||
this.receiveMessage = receiveMessage;
|
||||
}
|
||||
send(module, message) {
|
||||
switch (message.action) {
|
||||
case 'ajax': {
|
||||
this.xhrByTabID[message.id] = this.ajax(message);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
this.xhrByTabID[message.id].abort();
|
||||
}
|
||||
}
|
||||
if (message.action !== 'ajax') return;
|
||||
}
|
||||
ajax(message) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const url = `${window.location.protocol}//${window.location.hostname}:4201/api/unit`;
|
||||
console.log(url)
|
||||
xhr.open('POST', url);
|
||||
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
|
||||
xhr.onreadystatechange = (e) => {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
if (xhr.status === 200) {
|
||||
this.receiveMessage(this.formatResponseData(JSON.parse(xhr.responseText).data));
|
||||
} else {
|
||||
this.receiveMessage({
|
||||
id: message.id,
|
||||
general: { redirectTimes: 0, downloadSize: 0, downloadRate: 0, time: '0.00ms' },
|
||||
response: {
|
||||
statusCode: 0,
|
||||
headers: [],
|
||||
testDeny: '0.00',
|
||||
responseLength: 0,
|
||||
responseType: 'text',
|
||||
reportList: [],
|
||||
body: $localize`Test service connection failed, please submit Issue contact community`,
|
||||
},
|
||||
report: {
|
||||
request: {
|
||||
requestHeaders: [{ name: 'Content-Type', value: 'application/json' }],
|
||||
requestBodyType: 'raw',
|
||||
requestBody: '{}',
|
||||
},
|
||||
},
|
||||
history: {
|
||||
request: {
|
||||
uri: 'http:///',
|
||||
method: 'POST',
|
||||
protocol: 'http',
|
||||
requestHeaders: [{ name: 'Content-Type', value: 'application/json' }],
|
||||
requestBodyJsonType: 'object',
|
||||
requestBodyType: 'raw',
|
||||
requestBody: '{}',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(JSON.stringify(message));
|
||||
return xhr;
|
||||
}
|
||||
close() {}
|
||||
/**
|
||||
* Format UI Request Data To Server Request Data
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
formatRequestData(data, opts = { env: {} }) {
|
||||
return eoFormatRequestData(data, opts, this.locale);
|
||||
}
|
||||
/**
|
||||
* Format TestResult to TestData
|
||||
* @param {object} report test result after test finish
|
||||
* @param {object} history storage test history
|
||||
*/
|
||||
formatResponseData(data) {
|
||||
return eoFormatResponseData(data);
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ import { Injectable, Inject, LOCALE_ID } from '@angular/core';
|
||||
import { TestServer } from '../test-server.model';
|
||||
import { eoFormatRequestData, eoFormatResponseData } from '../api-test.utils';
|
||||
@Injectable()
|
||||
/**
|
||||
* Vercel serverless api
|
||||
*/
|
||||
export class TestServerServerlessService implements TestServer {
|
||||
receiveMessage: (message) => void;
|
||||
xhrByTabID = {};
|
||||
|
@ -2,17 +2,26 @@ import { Injectable } from '@angular/core';
|
||||
import { TestServerLocalNodeService } from './local-node/test-connect.service';
|
||||
import { TestServerServerlessService } from './serverless-node/test-connect.service';
|
||||
import { ElectronService } from '../../../core/services';
|
||||
import { TestServerRemoteService } from 'eo/workbench/browser/src/app/shared/services/api-test/remote-node/test-connect.service';
|
||||
@Injectable()
|
||||
export class TestServerService {
|
||||
isElectron = true;
|
||||
constructor(private electron: ElectronService, private localNode: TestServerLocalNodeService,private sassNode:TestServerServerlessService) {
|
||||
constructor(
|
||||
private electron: ElectronService,
|
||||
private remoteNode: TestServerRemoteService,
|
||||
private localNode: TestServerLocalNodeService,
|
||||
private serverlessNode: TestServerServerlessService
|
||||
) {
|
||||
this.isElectron = this.electron.isElectron;
|
||||
}
|
||||
get instance() {
|
||||
let isVercel = window.location.href.includes('vercel');
|
||||
if (this.isElectron) {
|
||||
return this.localNode;
|
||||
} else if (!isVercel) {
|
||||
return this.remoteNode;
|
||||
} else {
|
||||
return this.sassNode;
|
||||
return this.serverlessNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,43 @@ export class RemoteService {
|
||||
this.storageService.toggleDataSource({ dataSourceType: 'http' });
|
||||
}
|
||||
|
||||
getSettings() {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('localSettings') || '{}');
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the corresponding configuration according to the key path
|
||||
*
|
||||
* @param key
|
||||
* @returns
|
||||
*/
|
||||
getConfiguration = (keyPath: string) => {
|
||||
const localSettings = this.getSettings();
|
||||
if (Reflect.has(localSettings, keyPath)) {
|
||||
return Reflect.get(localSettings, keyPath);
|
||||
}
|
||||
|
||||
const keys = Object.keys(localSettings);
|
||||
const filterKeys = keys.filter((n) => n.startsWith(keyPath));
|
||||
if (filterKeys.length) {
|
||||
return filterKeys.reduce((pb, ck) => {
|
||||
const keyArr = ck.replace(`${keyPath}.`, '').split('.');
|
||||
const targetKey = keyArr.pop();
|
||||
const target = keyArr.reduce((p, v) => {
|
||||
p[v] ??= {};
|
||||
return p[v];
|
||||
}, pb);
|
||||
target[targetKey] = localSettings[ck];
|
||||
return pb;
|
||||
}, {});
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* switch data
|
||||
*/
|
||||
|
@ -23,7 +23,6 @@ export type ResultType<T = any> = {
|
||||
};
|
||||
|
||||
let isFirstLoad = true;
|
||||
|
||||
const getApiUrl = (apiData: ApiData) => {
|
||||
const dataSourceType: DataSourceType = getSettings()?.['eoapi-common.dataStorage'] ?? 'local';
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
export * from './loader';
|
||||
export * from './type';
|
@ -1,63 +0,0 @@
|
||||
import { ModuleRuntime, ModuleType, ModuleInfo, ModuleLoaderInterface } from './type';
|
||||
|
||||
/**
|
||||
* 模块加载类
|
||||
* 根据运行环境加载模块
|
||||
*/
|
||||
export class ModuleLoader implements ModuleLoaderInterface {
|
||||
/**
|
||||
* 模块运行时环境
|
||||
*/
|
||||
private readonly runtime: ModuleRuntime;
|
||||
|
||||
/**
|
||||
* 模块加载方法
|
||||
*/
|
||||
private readonly moduleRequire: any;
|
||||
|
||||
constructor(_runtime: ModuleRuntime, _moduleRequire?: any) {
|
||||
this.runtime = _runtime;
|
||||
this.moduleRequire = _moduleRequire || require;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量加载模块
|
||||
* @param modules
|
||||
*/
|
||||
loadModules(modules: Array<ModuleInfo>): void {
|
||||
modules.forEach((module: ModuleInfo) => {
|
||||
this.loadModule(module);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 实际加载模块并运行
|
||||
* 需要检查模块的类型与运行环境匹配
|
||||
* main运行环境只能加载system和app模块
|
||||
* render运行环境只能加载ui和feature模块
|
||||
* web运行环境只能加载web支持的模块
|
||||
* @param module ModuleInfo
|
||||
*/
|
||||
loadModule(module: ModuleInfo): void {
|
||||
console.log(module);
|
||||
if ((this.runtime === ModuleRuntime.main && ![ModuleType.system, ModuleType.app].indexOf(module.type))
|
||||
|| (this.runtime === ModuleRuntime.render && ![ModuleType.ui, ModuleType.feature].indexOf(module.type))
|
||||
|| (this.runtime === ModuleRuntime.web && !module.web)) {
|
||||
console.log(`The [${module.type}] module [${module.name}] can not run in runtime [${this.runtime}].`);
|
||||
return;
|
||||
}
|
||||
if (this.runtime === ModuleRuntime.main) {
|
||||
console.log('load from main');
|
||||
const _module = this.moduleRequire(module.baseDir)();
|
||||
console.log(_module);
|
||||
} else if (this.runtime === ModuleRuntime.render) {
|
||||
console.log('load from render');
|
||||
const _module = this.moduleRequire(module.baseDir)();
|
||||
console.log(_module);
|
||||
} else if (this.runtime === ModuleRuntime.web) {
|
||||
console.log('load from web');
|
||||
// todo with script src
|
||||
}
|
||||
// 加入hooks列表
|
||||
}
|
||||
}
|
@ -1365,7 +1365,7 @@
|
||||
<context context-type="sourcefile">src/app/pages/extension/detail/extension-detail.component.html</context>
|
||||
<context context-type="linenumber">64</context>
|
||||
</context-group>
|
||||
<target state="translated">帮助</target>
|
||||
<target state="translated">支持</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="d7293b61e9088c66421df2e367e0ccc00346cf9f" datatype="html">
|
||||
<source>Author</source>
|
||||
|
@ -7,7 +7,6 @@ import { APP_CONFIG } from './environments/environment';
|
||||
if (APP_CONFIG.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule, {})
|
||||
.catch((err) => console.error(err));
|
||||
|
1
src/workbench/node/README.md
Normal file
1
src/workbench/node/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Node Test server
|
27
src/workbench/node/electron/main.ts
Normal file
27
src/workbench/node/electron/main.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import { UnitWorker } from 'eo/workbench/node/electron/unitWorker';
|
||||
/**
|
||||
* Electron Test use Ipc to communicate
|
||||
*/
|
||||
export const UnitWorkerModule = {
|
||||
works: {},
|
||||
setup(eo: any) {
|
||||
ipcMain.removeAllListeners('unitTest');
|
||||
ipcMain.on('unitTest', function (event, message) {
|
||||
const id = message.id;
|
||||
switch (message.action) {
|
||||
case 'ajax': {
|
||||
UnitWorkerModule.works[id] = new UnitWorker(eo.view);
|
||||
UnitWorkerModule.works[id].start(message);
|
||||
break;
|
||||
}
|
||||
case 'abort': {
|
||||
UnitWorkerModule.works[id].kill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
25
src/workbench/node/electron/unitWorker.ts
Normal file
25
src/workbench/node/electron/unitWorker.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { BrowserView } from 'electron';
|
||||
import _LibsFlowCommon from '../request/unit';
|
||||
import _LibsCommon from '../request/libs/common';
|
||||
export class UnitWorker {
|
||||
view: BrowserView;
|
||||
constructor(view: BrowserView) {
|
||||
this.view = view;
|
||||
}
|
||||
async start(message: any) {
|
||||
message.data.env = _LibsCommon.parseEnv(message.data.env);
|
||||
await new _LibsFlowCommon.core().main(message.data).then(({ report, history }) => {
|
||||
['general', 'requestInfo', 'resultInfo'].forEach((keyName) => {
|
||||
if (typeof history[keyName] === 'string') history[keyName] = JSON.parse(history[keyName]);
|
||||
});
|
||||
this.finish({
|
||||
id: message.id,
|
||||
report: report,
|
||||
history: history,
|
||||
});
|
||||
});
|
||||
}
|
||||
finish(message: any) {
|
||||
this.view.webContents.send('unitTest', message);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
let _LibsFlowCommon = require('./unit.js');
|
||||
let _LibsCommon = require('./libs/common.js');
|
||||
process.on('message', (message) => {
|
||||
switch (message.action) {
|
||||
case 'ajax': {
|
||||
message.data.env = _LibsCommon.parseEnv(message.data.env);
|
||||
new _LibsFlowCommon.core().main(message.data, (tmpInputReport, tmpInputHistory) => {
|
||||
['general', 'requestInfo', 'resultInfo'].forEach((keyName) => {
|
||||
if (typeof tmpInputHistory[keyName] === 'string')
|
||||
tmpInputHistory[keyName] = JSON.parse(tmpInputHistory[keyName]);
|
||||
});
|
||||
process.send({
|
||||
action: 'finish',
|
||||
data: {
|
||||
id: message.id,
|
||||
report: tmpInputReport,
|
||||
history: tmpInputHistory,
|
||||
},
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
@ -1,3 +1,5 @@
|
||||
const { resolve } = require('path');
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
var url = require('url'),
|
||||
@ -680,146 +682,150 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
main(inputTestData, callback) {
|
||||
main(inputTestData) {
|
||||
let unitCommonClass = this;
|
||||
async function main() {
|
||||
let template = {
|
||||
ajax: {},
|
||||
status: 'finish',
|
||||
},
|
||||
tmpDecorateObj,
|
||||
tmpReportData = {
|
||||
afterInject: inputTestData.afterInject,
|
||||
beforeInject: inputTestData.beforeInject,
|
||||
};
|
||||
try {
|
||||
inputTestData.globalHeader = inputTestData.globalHeader || {};
|
||||
await privateFun.parseTestData(inputTestData, inputTestData.env || {}).then((tmpInputData) => {
|
||||
tmpDecorateObj = tmpInputData;
|
||||
});
|
||||
switch (tmpDecorateObj.status) {
|
||||
case 'preCode error': {
|
||||
template.ajax = {
|
||||
status: 'error',
|
||||
errorReason: tmpDecorateObj.content,
|
||||
reportList: tmpDecorateObj.reportList,
|
||||
general: {
|
||||
time: '0.00ms',
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
tmpReportData.requestInfo = {
|
||||
messageSeparatorSetting: inputTestData.messageSeparatorSetting,
|
||||
params: [],
|
||||
apiProtocol: '0',
|
||||
URL: tmpDecorateObj.history.uri,
|
||||
headers: [],
|
||||
methodType: inputTestData.methodType,
|
||||
method: inputTestData.method,
|
||||
};
|
||||
if (tmpDecorateObj.requestType === '4') {
|
||||
tmpReportData.requestInfo.requestType = '2';
|
||||
delete tmpReportData.requestInfo.params;
|
||||
} else {
|
||||
switch (typeof tmpDecorateObj.history.body) {
|
||||
case 'object': {
|
||||
tmpReportData.requestInfo.requestType = '0';
|
||||
for (let key in tmpDecorateObj.history.body) {
|
||||
switch (typeof tmpDecorateObj.history.body[key]) {
|
||||
case 'object': {
|
||||
for (let childKey in tmpDecorateObj.history.body[key]) {
|
||||
return new Promise((resolve, reject) => {
|
||||
async function main() {
|
||||
let template = {
|
||||
ajax: {},
|
||||
status: 'finish',
|
||||
},
|
||||
tmpDecorateObj,
|
||||
tmpReportData = {
|
||||
afterInject: inputTestData.afterInject,
|
||||
beforeInject: inputTestData.beforeInject,
|
||||
};
|
||||
try {
|
||||
inputTestData.globalHeader = inputTestData.globalHeader || {};
|
||||
await privateFun.parseTestData(inputTestData, inputTestData.env || {}).then((tmpInputData) => {
|
||||
tmpDecorateObj = tmpInputData;
|
||||
});
|
||||
switch (tmpDecorateObj.status) {
|
||||
case 'preCode error': {
|
||||
template.ajax = {
|
||||
status: 'error',
|
||||
errorReason: tmpDecorateObj.content,
|
||||
reportList: tmpDecorateObj.reportList,
|
||||
general: {
|
||||
time: '0.00ms',
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
tmpReportData.requestInfo = {
|
||||
messageSeparatorSetting: inputTestData.messageSeparatorSetting,
|
||||
params: [],
|
||||
apiProtocol: '0',
|
||||
URL: tmpDecorateObj.history.uri,
|
||||
headers: [],
|
||||
methodType: inputTestData.methodType,
|
||||
method: inputTestData.method,
|
||||
};
|
||||
if (tmpDecorateObj.requestType === '4') {
|
||||
tmpReportData.requestInfo.requestType = '2';
|
||||
delete tmpReportData.requestInfo.params;
|
||||
} else {
|
||||
switch (typeof tmpDecorateObj.history.body) {
|
||||
case 'object': {
|
||||
tmpReportData.requestInfo.requestType = '0';
|
||||
for (let key in tmpDecorateObj.history.body) {
|
||||
switch (typeof tmpDecorateObj.history.body[key]) {
|
||||
case 'object': {
|
||||
for (let childKey in tmpDecorateObj.history.body[key]) {
|
||||
tmpReportData.requestInfo.params.push({
|
||||
key: key,
|
||||
value:
|
||||
typeof tmpDecorateObj.history.body[key][childKey] == 'string'
|
||||
? tmpDecorateObj.history.body[key][childKey]
|
||||
: '[file]',
|
||||
});
|
||||
if (typeof tmpDecorateObj.history.body[key][childKey] != 'string') break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
tmpReportData.requestInfo.params.push({
|
||||
key: key,
|
||||
value:
|
||||
typeof tmpDecorateObj.history.body[key][childKey] == 'string'
|
||||
? tmpDecorateObj.history.body[key][childKey]
|
||||
: '[file]',
|
||||
value: tmpDecorateObj.history.body[key],
|
||||
});
|
||||
if (typeof tmpDecorateObj.history.body[key][childKey] != 'string') break;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
tmpReportData.requestInfo.params.push({
|
||||
key: key,
|
||||
value: tmpDecorateObj.history.body[key],
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
tmpReportData.requestInfo.requestType = '1';
|
||||
tmpReportData.requestInfo.params = tmpDecorateObj.history.body;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let key in tmpDecorateObj.history.headers) {
|
||||
tmpReportData.requestInfo.headers.push({
|
||||
name: key,
|
||||
value: tmpDecorateObj.history.headers[key],
|
||||
});
|
||||
}
|
||||
let tmpIsOversized,
|
||||
tmpRequestBodyStr =
|
||||
typeof tmpReportData.requestInfo.params === 'object'
|
||||
? JSON.stringify(tmpReportData.requestInfo.params)
|
||||
: tmpReportData.requestInfo.params;
|
||||
if ((tmpRequestBodyStr || '').length > CONFIG.REQUEST_BODY_LIMIT_STORAGE_LENGTH) {
|
||||
tmpReportData.requestInfo.requestType = 'oversized';
|
||||
tmpReportData.requestInfo.params = '';
|
||||
tmpIsOversized = true;
|
||||
}
|
||||
tmpReportData.requestInfo = JSON.stringify(tmpReportData.requestInfo);
|
||||
await unitCommonClass.ajax(
|
||||
tmpDecorateObj,
|
||||
{
|
||||
requestData: _LibsCommon.parseRequestDataToObj(tmpDecorateObj),
|
||||
globalHeader: inputTestData.globalHeader,
|
||||
pckSplitByHeader: inputTestData.messageSeparatorSetting === 'spliceLength',
|
||||
messageEncoding: inputTestData.messageEncoding,
|
||||
},
|
||||
function (res) {
|
||||
template.ajax = res;
|
||||
if (res.status != 'abort') {
|
||||
let tmpHistoryResponse = Object.assign({}, res.response);
|
||||
tmpHistoryResponse.reportList = res.reportList;
|
||||
// if (tmpHistoryResponse.responseType !== 'text') delete tmpHistoryResponse.body;
|
||||
tmpReportData.general = JSON.stringify(res.general);
|
||||
tmpReportData.resultInfo = JSON.stringify(tmpHistoryResponse);
|
||||
template.ajax.request.body = tmpDecorateObj.binaryFileName || tmpDecorateObj.requestBody.body;
|
||||
if (tmpIsOversized) {
|
||||
template.ajax.request.requestType = 'oversized';
|
||||
} else {
|
||||
template.ajax.request.requestType =
|
||||
tmpDecorateObj.requestType === '4'
|
||||
? '1'
|
||||
: typeof tmpDecorateObj.requestBody.body == 'object'
|
||||
? '0'
|
||||
: '1';
|
||||
default: {
|
||||
tmpReportData.requestInfo.requestType = '1';
|
||||
tmpReportData.requestInfo.params = tmpDecorateObj.history.body;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
for (let key in tmpDecorateObj.history.headers) {
|
||||
tmpReportData.requestInfo.headers.push({
|
||||
name: key,
|
||||
value: tmpDecorateObj.history.headers[key],
|
||||
});
|
||||
}
|
||||
let tmpIsOversized,
|
||||
tmpRequestBodyStr =
|
||||
typeof tmpReportData.requestInfo.params === 'object'
|
||||
? JSON.stringify(tmpReportData.requestInfo.params)
|
||||
: tmpReportData.requestInfo.params;
|
||||
if ((tmpRequestBodyStr || '').length > CONFIG.REQUEST_BODY_LIMIT_STORAGE_LENGTH) {
|
||||
tmpReportData.requestInfo.requestType = 'oversized';
|
||||
tmpReportData.requestInfo.params = '';
|
||||
tmpIsOversized = true;
|
||||
}
|
||||
tmpReportData.requestInfo = JSON.stringify(tmpReportData.requestInfo);
|
||||
await unitCommonClass.ajax(
|
||||
tmpDecorateObj,
|
||||
{
|
||||
requestData: _LibsCommon.parseRequestDataToObj(tmpDecorateObj),
|
||||
globalHeader: inputTestData.globalHeader,
|
||||
pckSplitByHeader: inputTestData.messageSeparatorSetting === 'spliceLength',
|
||||
messageEncoding: inputTestData.messageEncoding,
|
||||
},
|
||||
function (res) {
|
||||
template.ajax = res;
|
||||
if (res.status != 'abort') {
|
||||
let tmpHistoryResponse = Object.assign({}, res.response);
|
||||
tmpHistoryResponse.reportList = res.reportList;
|
||||
// if (tmpHistoryResponse.responseType !== 'text') delete tmpHistoryResponse.body;
|
||||
tmpReportData.general = JSON.stringify(res.general);
|
||||
tmpReportData.resultInfo = JSON.stringify(tmpHistoryResponse);
|
||||
template.ajax.request.body = tmpDecorateObj.binaryFileName || tmpDecorateObj.requestBody.body;
|
||||
if (tmpIsOversized) {
|
||||
template.ajax.request.requestType = 'oversized';
|
||||
} else {
|
||||
template.ajax.request.requestType =
|
||||
tmpDecorateObj.requestType === '4'
|
||||
? '1'
|
||||
: typeof tmpDecorateObj.requestBody.body == 'object'
|
||||
? '0'
|
||||
: '1';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
resolve({
|
||||
report: template.ajax,
|
||||
history: tmpReportData,
|
||||
});
|
||||
} catch (e) {
|
||||
resolve({
|
||||
report: template.ajax,
|
||||
history: tmpReportData,
|
||||
});
|
||||
console.error(new Date() + ':unit/common.js 336:', e);
|
||||
}
|
||||
if (callback) {
|
||||
callback(template.ajax, tmpReportData);
|
||||
}
|
||||
} catch (e) {
|
||||
if (callback) {
|
||||
callback(template.ajax, tmpReportData);
|
||||
}
|
||||
console.error(new Date() + ':unit/common.js 336:', e);
|
||||
}
|
||||
}
|
||||
main();
|
||||
main();
|
||||
});
|
||||
}
|
||||
abort() {
|
||||
this.areadyAbortXhr = true;
|
||||
|
12
src/workbench/node/server/README.md
Normal file
12
src/workbench/node/server/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# eo-test-server
|
||||
|
||||
Recieve eoapi tes config and response http result
|
||||
|
||||
> This service does not automatically install dependencies,please install it manually
|
||||
|
||||
# Command
|
||||
|
||||
dev/star
|
||||
```
|
||||
yarn start
|
||||
```
|
46
src/workbench/node/server/main.js
Normal file
46
src/workbench/node/server/main.js
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Web Test use Ipc to communicate
|
||||
*/
|
||||
|
||||
const _LibsFlowCommon = require('../request/unit.js');
|
||||
const _LibsCommon = require('../request/libs/common.js');
|
||||
// Koa reliance
|
||||
const koaBody = require('koa-body');
|
||||
const Koa = require('koa');
|
||||
const cors = require('@koa/cors');
|
||||
|
||||
const app = new Koa();
|
||||
const port = 4201;
|
||||
|
||||
app.use(cors());
|
||||
app.use(koaBody());
|
||||
|
||||
app.use(async (ctx, next) => {
|
||||
if (ctx.method !== 'POST') {
|
||||
ctx.body = 'Hello World';
|
||||
return;
|
||||
}
|
||||
switch (ctx.url) {
|
||||
case '/api/unit': {
|
||||
let reqJSON = ctx.request.body.data;
|
||||
reqJSON.env = _LibsCommon.parseEnv(reqJSON.env);
|
||||
await new _LibsFlowCommon.core().main(reqJSON).then(({ report, history }) => {
|
||||
['general', 'requestInfo', 'resultInfo'].forEach((keyName) => {
|
||||
if (typeof history[keyName] === 'string') history[keyName] = JSON.parse(history[keyName]);
|
||||
});
|
||||
ctx.body = JSON.stringify({
|
||||
action: 'finish',
|
||||
data: {
|
||||
id: ctx.request.body.id,
|
||||
report: report,
|
||||
history: history,
|
||||
},
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
app.listen(port);
|
17
src/workbench/node/server/package.json
Normal file
17
src/workbench/node/server/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "eo-test-server",
|
||||
"version": "1.0.0",
|
||||
"description": "Recieve eoapi tes config and response http result",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "node main",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "eoapi",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@koa/cors": "3.3.0",
|
||||
"koa": "2.13.4",
|
||||
"koa-body": "5.0.0"
|
||||
}
|
||||
}
|
461
src/workbench/node/server/yarn.lock
Normal file
461
src/workbench/node/server/yarn.lock
Normal file
@ -0,0 +1,461 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@koa/cors@3.3.0":
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.3.0.tgz#b4c1c7ee303b7c968c8727f2a638a74675b50bb2"
|
||||
integrity sha512-lzlkqLlL5Ond8jb6JLnVVDmD2OPym0r5kvZlMgAWiS9xle+Q5ulw1T358oW+RVguxUkANquZQz82i/STIRmsqQ==
|
||||
dependencies:
|
||||
vary "^1.1.2"
|
||||
|
||||
"@types/formidable@^2.0.4":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/formidable/-/formidable-2.0.5.tgz#e54e31d242ef750ac2d05aa163fa0274c8e6ef9c"
|
||||
integrity sha512-uvMcdn/KK3maPOaVUAc3HEYbCEhjaGFwww4EsX6IJfWIJ1tzHtDHczuImH3GKdusPnAAmzB07St90uabZeCKPA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "18.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.3.tgz#463fc47f13ec0688a33aec75d078a0541a447199"
|
||||
integrity sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==
|
||||
|
||||
accepts@^1.3.5:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
|
||||
dependencies:
|
||||
mime-types "~2.1.34"
|
||||
negotiator "0.6.3"
|
||||
|
||||
asap@^2.0.0:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
|
||||
|
||||
bytes@3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
|
||||
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
|
||||
|
||||
cache-content-type@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c"
|
||||
integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==
|
||||
dependencies:
|
||||
mime-types "^2.1.18"
|
||||
ylru "^1.2.0"
|
||||
|
||||
call-bind@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||
integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.2"
|
||||
|
||||
co-body@^5.1.1:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124"
|
||||
integrity sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ==
|
||||
dependencies:
|
||||
inflation "^2.0.0"
|
||||
qs "^6.4.0"
|
||||
raw-body "^2.2.0"
|
||||
type-is "^1.6.14"
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
|
||||
|
||||
content-disposition@~0.5.2:
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
|
||||
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
|
||||
dependencies:
|
||||
safe-buffer "5.2.1"
|
||||
|
||||
content-type@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
cookies@~0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90"
|
||||
integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==
|
||||
dependencies:
|
||||
depd "~2.0.0"
|
||||
keygrip "~1.1.0"
|
||||
|
||||
debug@^4.3.2:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
deep-equal@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
|
||||
integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
||||
|
||||
depd@2.0.0, depd@^2.0.0, depd@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
|
||||
|
||||
destroy@^1.0.4:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
|
||||
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
|
||||
|
||||
dezalgo@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
|
||||
integrity sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==
|
||||
dependencies:
|
||||
asap "^2.0.0"
|
||||
wrappy "1"
|
||||
|
||||
ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
|
||||
|
||||
encodeurl@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
|
||||
|
||||
escape-html@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
|
||||
|
||||
formidable@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-2.0.1.tgz#4310bc7965d185536f9565184dee74fbb75557ff"
|
||||
integrity sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==
|
||||
dependencies:
|
||||
dezalgo "1.0.3"
|
||||
hexoid "1.0.0"
|
||||
once "1.4.0"
|
||||
qs "6.9.3"
|
||||
|
||||
fresh@~0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
get-intrinsic@^1.0.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
|
||||
integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.3"
|
||||
|
||||
has-symbols@^1.0.2, has-symbols@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
|
||||
has-tostringtag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
|
||||
integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
|
||||
dependencies:
|
||||
has-symbols "^1.0.2"
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hexoid@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18"
|
||||
integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==
|
||||
|
||||
http-assert@^1.3.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
|
||||
integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==
|
||||
dependencies:
|
||||
deep-equal "~1.0.1"
|
||||
http-errors "~1.8.0"
|
||||
|
||||
http-errors@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
|
||||
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
|
||||
dependencies:
|
||||
depd "2.0.0"
|
||||
inherits "2.0.4"
|
||||
setprototypeof "1.2.0"
|
||||
statuses "2.0.1"
|
||||
toidentifier "1.0.1"
|
||||
|
||||
http-errors@^1.6.3, http-errors@~1.8.0:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
|
||||
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
|
||||
dependencies:
|
||||
depd "~1.1.2"
|
||||
inherits "2.0.4"
|
||||
setprototypeof "1.2.0"
|
||||
statuses ">= 1.5.0 < 2"
|
||||
toidentifier "1.0.1"
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
inflation@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f"
|
||||
integrity sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw==
|
||||
|
||||
inherits@2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-generator-function@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
|
||||
integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
|
||||
dependencies:
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
keygrip@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
|
||||
integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==
|
||||
dependencies:
|
||||
tsscmp "1.0.6"
|
||||
|
||||
koa-body@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/koa-body/-/koa-body-5.0.0.tgz#d310372bea09a24ccc450c76ca142ee55395dda6"
|
||||
integrity sha512-nHwEODrQGiyKBILCWO8QSS40C87cKr2cp3y/Cw8u9Z8w5t0CdSkGm3+y9WK5BIAlPpo9tTw5RtSbxpVyG79vmw==
|
||||
dependencies:
|
||||
"@types/formidable" "^2.0.4"
|
||||
co-body "^5.1.1"
|
||||
formidable "^2.0.1"
|
||||
|
||||
koa-compose@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877"
|
||||
integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==
|
||||
|
||||
koa-convert@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5"
|
||||
integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
koa-compose "^4.1.0"
|
||||
|
||||
koa@2.13.4:
|
||||
version "2.13.4"
|
||||
resolved "https://registry.yarnpkg.com/koa/-/koa-2.13.4.tgz#ee5b0cb39e0b8069c38d115139c774833d32462e"
|
||||
integrity sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==
|
||||
dependencies:
|
||||
accepts "^1.3.5"
|
||||
cache-content-type "^1.0.0"
|
||||
content-disposition "~0.5.2"
|
||||
content-type "^1.0.4"
|
||||
cookies "~0.8.0"
|
||||
debug "^4.3.2"
|
||||
delegates "^1.0.0"
|
||||
depd "^2.0.0"
|
||||
destroy "^1.0.4"
|
||||
encodeurl "^1.0.2"
|
||||
escape-html "^1.0.3"
|
||||
fresh "~0.5.2"
|
||||
http-assert "^1.3.0"
|
||||
http-errors "^1.6.3"
|
||||
is-generator-function "^1.0.7"
|
||||
koa-compose "^4.1.0"
|
||||
koa-convert "^2.0.0"
|
||||
on-finished "^2.3.0"
|
||||
only "~0.0.2"
|
||||
parseurl "^1.3.2"
|
||||
statuses "^1.5.0"
|
||||
type-is "^1.6.16"
|
||||
vary "^1.1.2"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@^2.1.18, mime-types@~2.1.24, mime-types@~2.1.34:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
negotiator@0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
||||
|
||||
object-inspect@^1.9.0:
|
||||
version "1.12.2"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
|
||||
integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
|
||||
|
||||
on-finished@^2.3.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
||||
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
|
||||
dependencies:
|
||||
ee-first "1.1.1"
|
||||
|
||||
once@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
only@~0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
|
||||
integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==
|
||||
|
||||
parseurl@^1.3.2:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
|
||||
|
||||
qs@6.9.3:
|
||||
version "6.9.3"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e"
|
||||
integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==
|
||||
|
||||
qs@^6.4.0:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
|
||||
dependencies:
|
||||
side-channel "^1.0.4"
|
||||
|
||||
raw-body@^2.2.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
|
||||
integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
|
||||
dependencies:
|
||||
bytes "3.1.2"
|
||||
http-errors "2.0.0"
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
|
||||
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
|
||||
|
||||
side-channel@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
|
||||
dependencies:
|
||||
call-bind "^1.0.0"
|
||||
get-intrinsic "^1.0.2"
|
||||
object-inspect "^1.9.0"
|
||||
|
||||
statuses@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
"statuses@>= 1.5.0 < 2", statuses@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
|
||||
|
||||
toidentifier@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
|
||||
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
|
||||
|
||||
tsscmp@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
|
||||
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
|
||||
|
||||
type-is@^1.6.14, type-is@^1.6.16:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
|
||||
dependencies:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
unpipe@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
|
||||
|
||||
vary@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
|
||||
ylru@^1.2.0:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.3.2.tgz#0de48017473275a4cbdfc83a1eaf67c01af8a785"
|
||||
integrity sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==
|
@ -1,53 +0,0 @@
|
||||
import * as child_process from 'child_process';
|
||||
import { BrowserView, ipcMain } from 'electron';
|
||||
|
||||
class UnitWorker {
|
||||
instance: child_process.ChildProcess;
|
||||
view: BrowserView;
|
||||
constructor(view: BrowserView) {
|
||||
this.view = view;
|
||||
}
|
||||
start(message: any) {
|
||||
this.instance = child_process.fork(`${__dirname}/request/main.js`);
|
||||
this.watch();
|
||||
this.instance.send(message);
|
||||
}
|
||||
finish(message: any) {
|
||||
this.view.webContents.send('unitTest', message);
|
||||
this.kill();
|
||||
}
|
||||
kill() {
|
||||
this.instance.kill();
|
||||
}
|
||||
private watch() {
|
||||
this.instance.on('message', (message: any) => {
|
||||
switch (message.action) {
|
||||
case 'finish': {
|
||||
this.finish(message.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const UnitWorkerModule = {
|
||||
works: {},
|
||||
setup(eo: any) {
|
||||
ipcMain.removeAllListeners('unitTest');
|
||||
ipcMain.on('unitTest', function (event, message) {
|
||||
const id = message.id;
|
||||
switch (message.action) {
|
||||
case 'ajax': {
|
||||
UnitWorkerModule.works[id] = new UnitWorker(eo.view);
|
||||
UnitWorkerModule.works[id].start(message);
|
||||
break;
|
||||
}
|
||||
case 'abort': {
|
||||
UnitWorkerModule.works[id].kill();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
99
upload.js
99
upload.js
@ -1,99 +0,0 @@
|
||||
const qiniu = require('qiniu');
|
||||
const YAML = require('yaml');
|
||||
const fs = require('fs');
|
||||
const { AK, SK, bucket } = require('./qiniu_env.js');
|
||||
const package = require('./package.json');
|
||||
|
||||
qiniu.conf.ACCESS_KEY = AK;
|
||||
qiniu.conf.SECRET_KEY = SK;
|
||||
|
||||
// * 构建上传策略函数
|
||||
const uptoken = (bucket, key) => new qiniu.rs.PutPolicy(bucket + ':' + key).token();
|
||||
|
||||
const toLatest = (name) => name.replace(/\d+\.\d+\.\d+/, 'latest');
|
||||
const onlyName = (name) => name.replace(/release\//, '');
|
||||
|
||||
// * 构建客户端实例
|
||||
const client = new qiniu.rs.Client();
|
||||
|
||||
// * 上传单个文件
|
||||
const uploadFile = (token, file, localFile) =>
|
||||
new Promise((resolve) => {
|
||||
const extra = new qiniu.io.PutExtra();
|
||||
qiniu.io.putFile(token, file, localFile, extra, (err) => {
|
||||
console.log(err ? err : 'success');
|
||||
return err ? resolve(false) : resolve(true);
|
||||
});
|
||||
});
|
||||
|
||||
// * 删除单个文件
|
||||
const removeFile = (spaceName, file) =>
|
||||
new Promise((resolve) => {
|
||||
client.remove(spaceName, file, (err, ret) => {
|
||||
return err ? resolve(false) : resolve(true);
|
||||
});
|
||||
});
|
||||
|
||||
// * 拷贝单个文件
|
||||
const cpFile = (fromFile, toFile) =>
|
||||
new Promise((resolve) => {
|
||||
client.copy(bucket, fromFile, bucket, toFile, (err) => {
|
||||
return err ? resolve(false) : resolve(true);
|
||||
});
|
||||
});
|
||||
|
||||
const version = package.version;
|
||||
const fileList = [
|
||||
'release/eoapi Setup ?.exe',
|
||||
'release/eoapi-?.dmg',
|
||||
'release/eoapi-?-arm64.dmg',
|
||||
'release/eoapi-?-mac.zip',
|
||||
'release/latest.yml',
|
||||
'release/latest-mac.yml',
|
||||
].map((it) => it.replace(/\?/, `${version}`));
|
||||
// const fileList = ['releass/eoapi-Setup-?.png', 'releass/eoapi-?.png', 'releass/eoapi-?-arm64.png'].map((it) =>
|
||||
// it.replace(/\?/, `${version}`)
|
||||
// );
|
||||
|
||||
const app = async () => {
|
||||
const uploadResult = await Promise.all(
|
||||
fileList.map(async (it) => {
|
||||
let isOK;
|
||||
// * 生成上传 Token
|
||||
try {
|
||||
if (it.endsWith('.yml')) {
|
||||
const ymlObj = YAML.parse(fs.readFileSync(it, 'utf8'));
|
||||
ymlObj.files.forEach((n) => (n.url = `${ymlObj.version}/${n.url}`));
|
||||
ymlObj.path = `${ymlObj.version}/${ymlObj.path}`;
|
||||
fs.writeFileSync(it, YAML.stringify(ymlObj));
|
||||
await removeFile(bucket, onlyName(it));
|
||||
const token = uptoken(bucket, onlyName(it));
|
||||
isOK = await uploadFile(token, onlyName(it), it);
|
||||
} else {
|
||||
const token = uptoken(bucket, `${version}/${it.replace(/release\//, '')}`);
|
||||
isOK = await uploadFile(token, `${version}/${it.replace(/release\//, '')}`, it);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('error', error);
|
||||
}
|
||||
return Promise.resolve(isOK || false);
|
||||
})
|
||||
);
|
||||
console.log('上传结果:', uploadResult);
|
||||
const deleteResult = await Promise.all(
|
||||
fileList.map(async (it) => {
|
||||
const isOK = await removeFile(bucket, `latest/${toLatest(onlyName(it))}`);
|
||||
Promise.resolve(isOK || false);
|
||||
})
|
||||
);
|
||||
console.log('删除结果:', deleteResult);
|
||||
const copyResult = await Promise.all(
|
||||
fileList.map(async (it) => {
|
||||
const isOK = await cpFile(`${version}/${onlyName(it)}`, `latest/${toLatest(onlyName(it))}`);
|
||||
Promise.resolve(isOK || false);
|
||||
})
|
||||
);
|
||||
console.log('拷贝结果', copyResult);
|
||||
};
|
||||
|
||||
app();
|
23
vercel.json
23
vercel.json
@ -1,12 +1,13 @@
|
||||
{
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/:path((?!en/).*)",
|
||||
"destination": "/en/:path*"
|
||||
},
|
||||
{
|
||||
"source": "/:path((?!zh/).*)",
|
||||
"destination": "/zh/:path*"
|
||||
}
|
||||
]
|
||||
}
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/:path((?!en/).*)",
|
||||
"destination": "/en/:path*"
|
||||
},
|
||||
{
|
||||
"source": "/:path((?!zh/).*)",
|
||||
"destination": "/zh/:path*"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
102
yarn.lock
102
yarn.lock
@ -2275,6 +2275,7 @@
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.29.0.tgz#775046effd5019667bd086bcf326acbe32cd0082"
|
||||
integrity sha512-3Eos6uP1nyLOBayc/VUdKZikV90HahXE5Dx9L5YlSd/7ylQPXhLk1BYb29SDgnBnTp+jmSZUU0QxUiyHgW4p7A==
|
||||
<<<<<<< HEAD
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.29.0"
|
||||
@ -2288,6 +2289,21 @@
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz#7a4749fa7ef5160c44a451bf060ac1dc6dfb77ee"
|
||||
integrity sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==
|
||||
dependencies:
|
||||
=======
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@typescript-eslint/scope-manager" "5.29.0"
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
"@typescript-eslint/typescript-estree" "5.29.0"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.29.0":
|
||||
version "5.29.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.29.0.tgz#7a4749fa7ef5160c44a451bf060ac1dc6dfb77ee"
|
||||
integrity sha512-Hpb/mCWsjILvikMQoZIE3voc9wtQcS0A9FUw3h8bhr9UxBdtI/tw1ZDZUOXHXLOVMedKCH5NxyzATwnU78bWCQ==
|
||||
dependencies:
|
||||
>>>>>>> main
|
||||
"@typescript-eslint/types" "5.29.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
@ -2581,7 +2597,11 @@ ajv-keywords@^5.0.0:
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
|
||||
<<<<<<< HEAD
|
||||
ajv@8.11.0, ajv@^8.0.0, ajv@^8.6.3, ajv@^8.8.0:
|
||||
=======
|
||||
ajv@8.11.0, ajv@^8.0.0, ajv@^8.8.0:
|
||||
>>>>>>> main
|
||||
version "8.11.0"
|
||||
resolved "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
|
||||
integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
|
||||
@ -2969,6 +2989,14 @@ atob@^2.1.2:
|
||||
resolved "https://registry.npmmirror.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
<<<<<<< HEAD
|
||||
atomically@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.7.0.tgz#c07a0458432ea6dbc9a3506fffa424b48bccaafe"
|
||||
integrity sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==
|
||||
|
||||
=======
|
||||
>>>>>>> main
|
||||
autoprefixer@10.4.7, autoprefixer@^10.4.6:
|
||||
version "10.4.7"
|
||||
resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.7.tgz#1db8d195f41a52ca5069b7593be167618edbbedf"
|
||||
@ -3989,6 +4017,22 @@ concat-stream@^1.4.6, concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
conf@^10.1.2:
|
||||
version "10.1.2"
|
||||
resolved "https://registry.yarnpkg.com/conf/-/conf-10.1.2.tgz#50132158f388756fa9dea3048f6b47935315c14e"
|
||||
integrity sha512-o9Fv1Mv+6A0JpoayQ8JleNp3hhkbOJP/Re/Q+QqxMPHPkABVsRjQGWZn9A5GcqLiTNC6d89p2PB5ZhHVDSMwyg==
|
||||
dependencies:
|
||||
ajv "^8.6.3"
|
||||
ajv-formats "^2.1.1"
|
||||
atomically "^1.7.0"
|
||||
debounce-fn "^4.0.0"
|
||||
dot-prop "^6.0.1"
|
||||
env-paths "^2.2.1"
|
||||
json-schema-typed "^7.0.3"
|
||||
onetime "^5.1.2"
|
||||
pkg-up "^3.1.0"
|
||||
semver "^7.3.5"
|
||||
|
||||
config-chain@^1.1.11, config-chain@^1.1.12, config-chain@^1.1.13:
|
||||
version "1.1.13"
|
||||
resolved "https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
|
||||
@ -4570,10 +4614,19 @@ dateformat@^3.0.0:
|
||||
resolved "https://registry.npmmirror.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
|
||||
|
||||
<<<<<<< HEAD
|
||||
debounce-fn@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/debounce-fn/-/debounce-fn-4.0.0.tgz#ed76d206d8a50e60de0dd66d494d82835ffe61c7"
|
||||
integrity sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==
|
||||
dependencies:
|
||||
mimic-fn "^3.0.0"
|
||||
=======
|
||||
debug@0.7.2:
|
||||
version "0.7.2"
|
||||
resolved "https://registry.npmjs.org/debug/-/debug-0.7.2.tgz#056692c86670977f115de82917918b8e8b9a10f0"
|
||||
integrity sha512-Ch0X6QrHzrNiWwLsBJj9KgXL5IK67pfDyTsXXVPyrdObVyKuj/rPdCtZg761nHZM1GQ7wW/o9cAZf5JeTN/vRg==
|
||||
>>>>>>> main
|
||||
|
||||
debug@2.6.9, debug@^2.6.8, debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
@ -4933,6 +4986,13 @@ dot-prop@^5.1.0, dot-prop@^5.2.0:
|
||||
dependencies:
|
||||
is-obj "^2.0.0"
|
||||
|
||||
dot-prop@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083"
|
||||
integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==
|
||||
dependencies:
|
||||
is-obj "^2.0.0"
|
||||
|
||||
dotenv-expand@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
|
||||
@ -5066,6 +5126,14 @@ electron-reload@1.5.0:
|
||||
dependencies:
|
||||
chokidar "^3.0.2"
|
||||
|
||||
electron-store@8.0.2:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-8.0.2.tgz#95c8cf81c1e1cf48b24f3ceeea24b921c1ff62d7"
|
||||
integrity sha512-9GwUMv51w8ydbkaG7X0HrPlElXLApg63zYy1/VZ/a08ndl0gfm4iCoD3f0E1JvP3V16a+7KxqriCI0c122stiA==
|
||||
dependencies:
|
||||
conf "^10.1.2"
|
||||
type-fest "^2.12.2"
|
||||
|
||||
electron-to-chromium@^1.4.147:
|
||||
version "1.4.154"
|
||||
resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.154.tgz#d69c60499fc467a6c59591d29183e520afbc78a1"
|
||||
@ -5198,7 +5266,7 @@ entities@~3.0.1:
|
||||
resolved "https://registry.npmmirror.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
|
||||
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
|
||||
|
||||
env-paths@^2.2.0:
|
||||
env-paths@^2.2.0, env-paths@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npmmirror.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
|
||||
@ -7600,6 +7668,11 @@ json-schema-traverse@^1.0.0:
|
||||
resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||
|
||||
json-schema-typed@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9"
|
||||
integrity sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==
|
||||
|
||||
json-schema@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
|
||||
@ -8450,6 +8523,11 @@ mimic-fn@^2.1.0:
|
||||
resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
mimic-fn@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74"
|
||||
integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==
|
||||
|
||||
mimic-response@^1.0.0, mimic-response@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
|
||||
@ -9889,6 +9967,13 @@ pkg-dir@^4.1.0:
|
||||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
pkg-up@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
|
||||
integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==
|
||||
dependencies:
|
||||
find-up "^3.0.0"
|
||||
|
||||
plist@^3.0.1, plist@^3.0.4:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmmirror.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987"
|
||||
@ -10434,7 +10519,11 @@ qs@6.10.3:
|
||||
dependencies:
|
||||
side-channel "^1.0.4"
|
||||
|
||||
<<<<<<< HEAD
|
||||
qs@6.11.0:
|
||||
=======
|
||||
qs@6.11.0, qs@^6.1.0:
|
||||
>>>>>>> main
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
|
||||
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
|
||||
@ -11980,6 +12069,8 @@ symbol-observable@4.0.0:
|
||||
resolved "https://registry.npmmirror.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"
|
||||
integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
sync-request@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/sync-request/-/sync-request-3.0.1.tgz#caa1235aaf889ba501076a1834c436830a82fb73"
|
||||
@ -11989,6 +12080,7 @@ sync-request@3.0.1:
|
||||
http-response-object "^1.0.1"
|
||||
then-request "^2.0.1"
|
||||
|
||||
>>>>>>> main
|
||||
tailwindcss@3.1.4:
|
||||
version "3.1.4"
|
||||
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.4.tgz#64b09059805505902139fa805d97046080bd90b9"
|
||||
@ -12375,6 +12467,14 @@ type-fest@^0.8.1:
|
||||
resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
<<<<<<< HEAD
|
||||
type-fest@^2.12.2:
|
||||
version "2.16.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.16.0.tgz#1250fbd64dafaf4c8e405e393ef3fb16d9651db2"
|
||||
integrity sha512-qpaThT2HQkFb83gMOrdKVsfCN7LKxP26Yq+smPzY1FqoHRjqmjqHXA7n5Gkxi8efirtbeEUxzfEdePthQWCuHw==
|
||||
|
||||
=======
|
||||
>>>>>>> main
|
||||
type-fest@^2.14.0:
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.14.0.tgz#f990e19169517d689c98e16d128b231022b27e12"
|
||||
|
Loading…
Reference in New Issue
Block a user