@opensumi/ide-core-node 2.21.8-rc-1670567192.0 → 2.21.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -6
- package/src/bootstrap/app.ts +0 -252
- package/src/bootstrap/index.ts +0 -2
- package/src/bootstrap/inner-providers.ts +0 -42
- package/src/bootstrap/shell-path.ts +0 -116
- package/src/common-module/common.server.ts +0 -9
- package/src/common-module/credential.server.ts +0 -90
- package/src/common-module/crypto.server.ts +0 -50
- package/src/common-module/index.ts +0 -49
- package/src/connection.ts +0 -147
- package/src/hash-calculate/hash-calculate.contribution.ts +0 -19
- package/src/index.ts +0 -12
- package/src/logger/node-logger.ts +0 -68
- package/src/node-module.ts +0 -3
- package/src/types.ts +0 -143
package/package.json
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opensumi/ide-core-node",
|
|
3
|
-
"version": "2.21.8
|
|
3
|
+
"version": "2.21.8",
|
|
4
4
|
"description": "@opensumi/ide-core-node",
|
|
5
5
|
"files": [
|
|
6
|
-
"lib"
|
|
7
|
-
"src"
|
|
6
|
+
"lib"
|
|
8
7
|
],
|
|
9
8
|
"license": "MIT",
|
|
10
9
|
"main": "lib/index.js",
|
|
@@ -18,12 +17,12 @@
|
|
|
18
17
|
"url": "git@github.com:opensumi/core.git"
|
|
19
18
|
},
|
|
20
19
|
"dependencies": {
|
|
21
|
-
"@opensumi/ide-connection": "2.21.8
|
|
22
|
-
"@opensumi/ide-core-common": "2.21.8
|
|
20
|
+
"@opensumi/ide-connection": "2.21.8",
|
|
21
|
+
"@opensumi/ide-core-common": "2.21.8",
|
|
23
22
|
"keytar": "^7.7.0"
|
|
24
23
|
},
|
|
25
24
|
"devDependencies": {
|
|
26
25
|
"@opensumi/ide-dev-tool": "^1.3.1"
|
|
27
26
|
},
|
|
28
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "603eaa81756ee0e8a58871fb67cfb01c8499593a"
|
|
29
28
|
}
|
package/src/bootstrap/app.ts
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import http from 'http';
|
|
2
|
-
import https from 'https';
|
|
3
|
-
import net from 'net';
|
|
4
|
-
import os from 'os';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
|
|
7
|
-
import Koa from 'koa';
|
|
8
|
-
|
|
9
|
-
import { Injector } from '@opensumi/di';
|
|
10
|
-
import { WebSocketHandler } from '@opensumi/ide-connection/lib/node';
|
|
11
|
-
import { ContributionProvider, createContributionProvider, isWindows } from '@opensumi/ide-core-common';
|
|
12
|
-
import { ILogServiceManager, ILogService, SupportLogNamespace, StoragePaths } from '@opensumi/ide-core-common';
|
|
13
|
-
import { DEFAULT_OPENVSX_REGISTRY } from '@opensumi/ide-core-common/lib/const';
|
|
14
|
-
|
|
15
|
-
import { createServerConnection2, createNetServerConnection, RPCServiceCenter } from '../connection';
|
|
16
|
-
import { NodeModule } from '../node-module';
|
|
17
|
-
import { AppConfig, IServerApp, IServerAppOpts, ModuleConstructor, ServerAppContribution } from '../types';
|
|
18
|
-
|
|
19
|
-
import { injectInnerProviders } from './inner-providers';
|
|
20
|
-
|
|
21
|
-
export class ServerApp implements IServerApp {
|
|
22
|
-
private _injector: Injector;
|
|
23
|
-
|
|
24
|
-
private config: IServerAppOpts;
|
|
25
|
-
|
|
26
|
-
private logger: ILogService;
|
|
27
|
-
|
|
28
|
-
private webSocketHandler: WebSocketHandler[];
|
|
29
|
-
|
|
30
|
-
private modulesInstances: NodeModule[];
|
|
31
|
-
|
|
32
|
-
use: (middleware: Koa.Middleware<Koa.ParameterizedContext<any, any>>) => void;
|
|
33
|
-
|
|
34
|
-
protected contributionsProvider: ContributionProvider<ServerAppContribution>;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 启动初始化
|
|
38
|
-
* 1. 绑定 process 报错处理
|
|
39
|
-
* 2. 初始化内置的 Provider
|
|
40
|
-
* 3. 获取 Modules 的实例
|
|
41
|
-
* 4. 设置默认的实例
|
|
42
|
-
* @param opts
|
|
43
|
-
*/
|
|
44
|
-
constructor(private opts: IServerAppOpts) {
|
|
45
|
-
this._injector = opts.injector || new Injector();
|
|
46
|
-
this.webSocketHandler = opts.webSocketHandler || [];
|
|
47
|
-
// 使用外部传入的中间件
|
|
48
|
-
this.use = opts.use || ((middleware) => null);
|
|
49
|
-
this.config = {
|
|
50
|
-
injector: this.injector,
|
|
51
|
-
logDir: opts.logDir,
|
|
52
|
-
logLevel: opts.logLevel,
|
|
53
|
-
LogServiceClass: opts.LogServiceClass,
|
|
54
|
-
marketplace: Object.assign(
|
|
55
|
-
{
|
|
56
|
-
endpoint: DEFAULT_OPENVSX_REGISTRY,
|
|
57
|
-
extensionDir: path.join(
|
|
58
|
-
os.homedir(),
|
|
59
|
-
...(isWindows ? [StoragePaths.WINDOWS_APP_DATA_DIR, StoragePaths.WINDOWS_ROAMING_DIR] : ['']),
|
|
60
|
-
StoragePaths.DEFAULT_STORAGE_DIR_NAME,
|
|
61
|
-
StoragePaths.MARKETPLACE_DIR,
|
|
62
|
-
),
|
|
63
|
-
showBuiltinExtensions: false,
|
|
64
|
-
accountId: '',
|
|
65
|
-
masterKey: '',
|
|
66
|
-
ignoreId: [],
|
|
67
|
-
},
|
|
68
|
-
opts.marketplace,
|
|
69
|
-
),
|
|
70
|
-
processCloseExitThreshold: opts.processCloseExitThreshold,
|
|
71
|
-
terminalPtyCloseThreshold: opts.terminalPtyCloseThreshold,
|
|
72
|
-
staticAllowOrigin: opts.staticAllowOrigin,
|
|
73
|
-
staticAllowPath: opts.staticAllowPath,
|
|
74
|
-
extLogServiceClassPath: opts.extLogServiceClassPath,
|
|
75
|
-
maxExtProcessCount: opts.maxExtProcessCount,
|
|
76
|
-
onDidCreateExtensionHostProcess: opts.onDidCreateExtensionHostProcess,
|
|
77
|
-
extHost: process.env.EXTENSION_HOST_ENTRY || opts.extHost,
|
|
78
|
-
blockPatterns: opts.blockPatterns,
|
|
79
|
-
extHostIPCSockPath: opts.extHostIPCSockPath,
|
|
80
|
-
extHostForkOptions: opts.extHostForkOptions,
|
|
81
|
-
};
|
|
82
|
-
this.bindProcessHandler();
|
|
83
|
-
this.initBaseProvider();
|
|
84
|
-
this.createNodeModules(opts.modules, opts.modulesInstances);
|
|
85
|
-
this.logger = this.injector.get(ILogServiceManager).getLogger(SupportLogNamespace.App);
|
|
86
|
-
this.contributionsProvider = this.injector.get(ServerAppContribution);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
get injector() {
|
|
90
|
-
return this._injector;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* 将被依赖但未被加入modules的模块加入到待加载模块最后
|
|
95
|
-
*/
|
|
96
|
-
public resolveModuleDeps(moduleConstructor: ModuleConstructor, modules: any[]) {
|
|
97
|
-
const dependencies = Reflect.getMetadata('dependencies', moduleConstructor) as [];
|
|
98
|
-
if (dependencies) {
|
|
99
|
-
dependencies.forEach((dep) => {
|
|
100
|
-
if (modules.indexOf(dep) === -1) {
|
|
101
|
-
modules.push(dep);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private get contributions(): ServerAppContribution[] {
|
|
108
|
-
return this.contributionsProvider.getContributions();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
private initBaseProvider() {
|
|
112
|
-
// 创建 contributionsProvider
|
|
113
|
-
createContributionProvider(this.injector, ServerAppContribution);
|
|
114
|
-
|
|
115
|
-
this.injector.addProviders({
|
|
116
|
-
token: AppConfig,
|
|
117
|
-
useValue: this.config,
|
|
118
|
-
});
|
|
119
|
-
injectInnerProviders(this.injector);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private async initializeContribution() {
|
|
123
|
-
for (const contribution of this.contributions) {
|
|
124
|
-
if (contribution.initialize) {
|
|
125
|
-
try {
|
|
126
|
-
await contribution.initialize(this);
|
|
127
|
-
} catch (error) {
|
|
128
|
-
this.logger.error('Could not initialize contribution', error);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
private async startContribution() {
|
|
135
|
-
for (const contrib of this.contributions) {
|
|
136
|
-
if (contrib.onStart) {
|
|
137
|
-
try {
|
|
138
|
-
await contrib.onStart(this);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
this.logger.error('Could not start contribution', error);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async start(
|
|
147
|
-
server: http.Server | https.Server | net.Server,
|
|
148
|
-
serviceHandler?: (serviceCenter: RPCServiceCenter) => void,
|
|
149
|
-
) {
|
|
150
|
-
await this.initializeContribution();
|
|
151
|
-
|
|
152
|
-
let serviceCenter;
|
|
153
|
-
|
|
154
|
-
if (serviceHandler) {
|
|
155
|
-
serviceCenter = new RPCServiceCenter();
|
|
156
|
-
serviceHandler(serviceCenter);
|
|
157
|
-
} else {
|
|
158
|
-
if (server instanceof http.Server || server instanceof https.Server) {
|
|
159
|
-
// 创建 websocket 通道
|
|
160
|
-
serviceCenter = createServerConnection2(
|
|
161
|
-
server,
|
|
162
|
-
this.injector,
|
|
163
|
-
this.modulesInstances,
|
|
164
|
-
this.webSocketHandler,
|
|
165
|
-
this.opts,
|
|
166
|
-
);
|
|
167
|
-
} else if (server instanceof net.Server) {
|
|
168
|
-
serviceCenter = createNetServerConnection(server, this.injector, this.modulesInstances);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// TODO: 每次链接来的时候绑定一次,或者是服务获取的时候多实例化出来
|
|
173
|
-
// bindModuleBackService(this.injector, this.modulesInstances, serviceCenter);
|
|
174
|
-
|
|
175
|
-
await this.startContribution();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private async onStop() {
|
|
179
|
-
for (const contrib of this.contributions) {
|
|
180
|
-
if (contrib.onStop) {
|
|
181
|
-
try {
|
|
182
|
-
await contrib.onStop(this);
|
|
183
|
-
} catch (error) {
|
|
184
|
-
this.logger.error('Could not stop contribution', error);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* 绑定 process 退出逻辑
|
|
192
|
-
*/
|
|
193
|
-
private bindProcessHandler() {
|
|
194
|
-
process.on('uncaughtException', (error) => {
|
|
195
|
-
if (error) {
|
|
196
|
-
this.logger.error('Uncaught Exception: ', error.toString());
|
|
197
|
-
if (error.stack) {
|
|
198
|
-
this.logger.error(error.stack);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
// Handles normal process termination.
|
|
203
|
-
process.on('exit', () => {
|
|
204
|
-
this.logger.log('process exit');
|
|
205
|
-
});
|
|
206
|
-
// Handles `Ctrl+C`.
|
|
207
|
-
process.on('SIGINT', async () => {
|
|
208
|
-
this.logger.log('process SIGINT');
|
|
209
|
-
await this.onStop();
|
|
210
|
-
this.logger.log('process SIGINT DONE');
|
|
211
|
-
process.exit(0);
|
|
212
|
-
});
|
|
213
|
-
// Handles `kill pid`.
|
|
214
|
-
process.on('SIGTERM', async () => {
|
|
215
|
-
this.logger.log('process SIGTERM');
|
|
216
|
-
await this.onStop();
|
|
217
|
-
this.logger.log('process SIGTERM DONE');
|
|
218
|
-
process.exit(0);
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 收集 module 实例
|
|
224
|
-
* @param Constructors
|
|
225
|
-
* @param modules
|
|
226
|
-
*/
|
|
227
|
-
private createNodeModules(Constructors: ModuleConstructor[] = [], modules: NodeModule[] = []) {
|
|
228
|
-
const allModules = [...modules];
|
|
229
|
-
Constructors.forEach((c) => {
|
|
230
|
-
this.resolveModuleDeps(c, Constructors);
|
|
231
|
-
});
|
|
232
|
-
for (const Constructor of Constructors) {
|
|
233
|
-
allModules.push(this.injector.get(Constructor));
|
|
234
|
-
}
|
|
235
|
-
for (const instance of allModules) {
|
|
236
|
-
if (instance.providers) {
|
|
237
|
-
this.injector.addProviders(...instance.providers);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (instance.contributionProvider) {
|
|
241
|
-
if (Array.isArray(instance.contributionProvider)) {
|
|
242
|
-
for (const contributionProvider of instance.contributionProvider) {
|
|
243
|
-
createContributionProvider(this.injector, contributionProvider);
|
|
244
|
-
}
|
|
245
|
-
} else {
|
|
246
|
-
createContributionProvider(this.injector, instance.contributionProvider);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
this.modulesInstances = allModules;
|
|
251
|
-
}
|
|
252
|
-
}
|
package/src/bootstrap/index.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Injector } from '@opensumi/di';
|
|
2
|
-
import {
|
|
3
|
-
IReporter,
|
|
4
|
-
DefaultReporter,
|
|
5
|
-
IReporterService,
|
|
6
|
-
ReporterService,
|
|
7
|
-
ReporterMetadata,
|
|
8
|
-
REPORT_HOST,
|
|
9
|
-
} from '@opensumi/ide-core-common';
|
|
10
|
-
import {
|
|
11
|
-
HashCalculateServiceImpl,
|
|
12
|
-
IHashCalculateService,
|
|
13
|
-
} from '@opensumi/ide-core-common/lib/hash-calculate/hash-calculate';
|
|
14
|
-
|
|
15
|
-
import { INodeLogger, NodeLogger } from '../logger/node-logger';
|
|
16
|
-
|
|
17
|
-
export function injectInnerProviders(injector: Injector) {
|
|
18
|
-
injector.addProviders(
|
|
19
|
-
{
|
|
20
|
-
token: INodeLogger,
|
|
21
|
-
useClass: NodeLogger,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
token: IReporter,
|
|
25
|
-
useClass: DefaultReporter,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
token: IReporterService,
|
|
29
|
-
useClass: ReporterService,
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
token: ReporterMetadata,
|
|
33
|
-
useValue: {
|
|
34
|
-
host: REPORT_HOST.NODE,
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
token: IHashCalculateService,
|
|
39
|
-
useClass: HashCalculateServiceImpl,
|
|
40
|
-
},
|
|
41
|
-
);
|
|
42
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'child_process';
|
|
2
|
-
|
|
3
|
-
import { isWindows, stripAnsi } from '@opensumi/ide-core-common';
|
|
4
|
-
|
|
5
|
-
// 成功过一次后,取 PATH 的超时时间
|
|
6
|
-
const MAX_WAIT_AFTER_SUCCESS = 3 * 1000;
|
|
7
|
-
|
|
8
|
-
// Shell 执行的最大超时时间
|
|
9
|
-
// 即使 getShellPath 已经返回,在这个时间之内执行成功后还是会更新缓存,供下一次调用使用
|
|
10
|
-
const SHELL_TIMEOUT = 30 * 1000;
|
|
11
|
-
|
|
12
|
-
let shellPath = process.env.PATH;
|
|
13
|
-
const isJestTest = process.env.IS_JEST_TEST;
|
|
14
|
-
let updating: Promise<void> | undefined;
|
|
15
|
-
|
|
16
|
-
// 至少成功过一次
|
|
17
|
-
let hasSuccess = false;
|
|
18
|
-
|
|
19
|
-
// 某些用户的配置初始化时间较长,提前开始
|
|
20
|
-
// 测试环境下不执行,让测试快一点
|
|
21
|
-
if (!isJestTest) {
|
|
22
|
-
updateShellPath();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function parseEnv(env: string) {
|
|
26
|
-
env = env.split('_SHELL_ENV_DELIMITER_')[1];
|
|
27
|
-
const ret: { [key: string]: string } = {};
|
|
28
|
-
const lines = stripAnsi(env).split('\n').filter(Boolean);
|
|
29
|
-
for (const line of lines) {
|
|
30
|
-
const [key, ...values] = line.split('=');
|
|
31
|
-
ret[key] = values.join('=');
|
|
32
|
-
}
|
|
33
|
-
return ret;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function createUpdateShellPathPromise(): Promise<void> {
|
|
37
|
-
let pid: number;
|
|
38
|
-
const timer = setTimeout(() => {
|
|
39
|
-
if (pid) {
|
|
40
|
-
try {
|
|
41
|
-
process.kill(pid);
|
|
42
|
-
} catch (error) {
|
|
43
|
-
// ignore
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}, SHELL_TIMEOUT);
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
shellPath = await new Promise((resolve, reject) => {
|
|
50
|
-
const buf: Buffer[] = [];
|
|
51
|
-
const proc = spawn(
|
|
52
|
-
process.env.SHELL || '/bin/bash',
|
|
53
|
-
['-ilc', 'echo -n "_SHELL_ENV_DELIMITER_"; env; echo -n "_SHELL_ENV_DELIMITER_"; exit;'],
|
|
54
|
-
{
|
|
55
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
56
|
-
detached: true, // 在有些场景 zsh 会卡住, detached 后正常
|
|
57
|
-
},
|
|
58
|
-
);
|
|
59
|
-
proc.on('error', (err) => {
|
|
60
|
-
reject(err);
|
|
61
|
-
});
|
|
62
|
-
proc.stdout.on('data', (chunk) => {
|
|
63
|
-
buf.push(chunk);
|
|
64
|
-
});
|
|
65
|
-
proc.stderr.on('data', (chunk) => {
|
|
66
|
-
// reject(chunk.toString());
|
|
67
|
-
});
|
|
68
|
-
proc.on('close', () => {
|
|
69
|
-
clearTimeout(timer);
|
|
70
|
-
|
|
71
|
-
if (buf.length) {
|
|
72
|
-
resolve(parseEnv(Buffer.concat(buf).toString()).PATH);
|
|
73
|
-
} else {
|
|
74
|
-
reject(new Error('Fail to get env.'));
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
proc.unref();
|
|
78
|
-
pid = proc.pid;
|
|
79
|
-
});
|
|
80
|
-
hasSuccess = true;
|
|
81
|
-
} catch (err) {
|
|
82
|
-
// console.error('shell path error:', err);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function updateShellPath(): Promise<void> {
|
|
87
|
-
// 确保每次只有一个进程运行
|
|
88
|
-
// macOS 实测多个进程同时运行时,耗时成倍增加 <1s -> 6-10s
|
|
89
|
-
if (!updating) {
|
|
90
|
-
updating = createUpdateShellPathPromise().finally(() => {
|
|
91
|
-
updating = undefined;
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return updating;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export async function getShellPath(): Promise<string | undefined> {
|
|
98
|
-
if (isWindows) {
|
|
99
|
-
return process.env['PATH'];
|
|
100
|
-
}
|
|
101
|
-
// 触发一次更新
|
|
102
|
-
await Promise.race([
|
|
103
|
-
updateShellPath(),
|
|
104
|
-
new Promise<void>((resolve) => {
|
|
105
|
-
// 第一次等待时间长一些,尽量拿到正确的 PATH
|
|
106
|
-
setTimeout(
|
|
107
|
-
() => {
|
|
108
|
-
resolve(undefined);
|
|
109
|
-
},
|
|
110
|
-
hasSuccess ? MAX_WAIT_AFTER_SUCCESS : SHELL_TIMEOUT,
|
|
111
|
-
);
|
|
112
|
-
}),
|
|
113
|
-
]);
|
|
114
|
-
// 不管有没有更新成功,都返回当前的最新结果
|
|
115
|
-
return shellPath;
|
|
116
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@opensumi/di';
|
|
2
|
-
import { ICommonServer, OS, OperatingSystem } from '@opensumi/ide-core-common';
|
|
3
|
-
|
|
4
|
-
@Injectable()
|
|
5
|
-
export class CommonServer implements ICommonServer {
|
|
6
|
-
async getBackendOS(): Promise<OperatingSystem> {
|
|
7
|
-
return OS.type();
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { Injectable, Autowired } from '@opensumi/di';
|
|
2
|
-
import { IChunkedPassword, INativeCredentialService, isWindows } from '@opensumi/ide-core-common';
|
|
3
|
-
|
|
4
|
-
import { AppConfig } from '../types';
|
|
5
|
-
|
|
6
|
-
@Injectable()
|
|
7
|
-
export class CredentialService implements INativeCredentialService {
|
|
8
|
-
private static readonly MAX_PASSWORD_LENGTH = 2500;
|
|
9
|
-
private static readonly PASSWORD_CHUNK_SIZE = CredentialService.MAX_PASSWORD_LENGTH - 100;
|
|
10
|
-
|
|
11
|
-
@Autowired(AppConfig)
|
|
12
|
-
private readonly appConfig: AppConfig;
|
|
13
|
-
|
|
14
|
-
async setPassword(service: string, account: string, password: string): Promise<void> {
|
|
15
|
-
const keytar = await this.withKeytar();
|
|
16
|
-
if (isWindows && password.length > CredentialService.MAX_PASSWORD_LENGTH) {
|
|
17
|
-
let index = 0;
|
|
18
|
-
let chunk = 0;
|
|
19
|
-
let hasNextChunk = true;
|
|
20
|
-
while (hasNextChunk) {
|
|
21
|
-
const passwordChunk = password.substring(index, index + CredentialService.PASSWORD_CHUNK_SIZE);
|
|
22
|
-
index += CredentialService.PASSWORD_CHUNK_SIZE;
|
|
23
|
-
hasNextChunk = password.length - index > 0;
|
|
24
|
-
|
|
25
|
-
const content: IChunkedPassword = {
|
|
26
|
-
content: passwordChunk,
|
|
27
|
-
hasNextChunk,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
await keytar.setPassword(service, chunk ? `${account}-${chunk}` : account, JSON.stringify(content));
|
|
31
|
-
chunk++;
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
await keytar.setPassword(service, account, password);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async deletePassword(service: string, account: string) {
|
|
39
|
-
const keytar = await this.withKeytar();
|
|
40
|
-
const didDelete = await keytar.deletePassword(service, account);
|
|
41
|
-
return didDelete;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async getPassword(service: string, account: string) {
|
|
45
|
-
const keytar = await this.withKeytar();
|
|
46
|
-
const password = await keytar.getPassword(service, account);
|
|
47
|
-
if (password) {
|
|
48
|
-
try {
|
|
49
|
-
let { content, hasNextChunk }: IChunkedPassword = JSON.parse(password);
|
|
50
|
-
if (!content || !hasNextChunk) {
|
|
51
|
-
return password;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let index = 1;
|
|
55
|
-
while (hasNextChunk) {
|
|
56
|
-
const nextChunk = await keytar.getPassword(service, `${account}-${index++}`);
|
|
57
|
-
const result: IChunkedPassword = JSON.parse(nextChunk!);
|
|
58
|
-
content += result.content;
|
|
59
|
-
hasNextChunk = result.hasNextChunk;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return content;
|
|
63
|
-
} catch (_e) {
|
|
64
|
-
return password;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async findPassword(service: string) {
|
|
71
|
-
const keytar = await this.withKeytar();
|
|
72
|
-
const password = await keytar.findPassword(service);
|
|
73
|
-
if (password) {
|
|
74
|
-
return password;
|
|
75
|
-
}
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async findCredentials(service: string): Promise<Array<{ account: string; password: string }>> {
|
|
80
|
-
const keytar = await this.withKeytar();
|
|
81
|
-
return keytar.findCredentials(service);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private async withKeytar(): Promise<typeof import('keytar')> {
|
|
85
|
-
if (this.appConfig.disableKeytar) {
|
|
86
|
-
throw new Error('keytar has been disabled via --disable-keytar option');
|
|
87
|
-
}
|
|
88
|
-
return await import('keytar');
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
import { Injectable } from '@opensumi/di';
|
|
4
|
-
import { INativeCryptoService } from '@opensumi/ide-core-common';
|
|
5
|
-
|
|
6
|
-
@Injectable()
|
|
7
|
-
export class CryptoService implements INativeCryptoService {
|
|
8
|
-
private static SECRET_KEY = 'CryptoService';
|
|
9
|
-
private static IV_LENGTH = 16;
|
|
10
|
-
private static SALT_LENGTH = 64;
|
|
11
|
-
private static TAG_LENGTH = 16;
|
|
12
|
-
private static ALGORITHM = 'aes-256-gcm';
|
|
13
|
-
private static TAG_POSITION: number = CryptoService.SALT_LENGTH + CryptoService.IV_LENGTH;
|
|
14
|
-
private static ENCRYPTED_POSITION: number = CryptoService.TAG_POSITION + CryptoService.TAG_LENGTH;
|
|
15
|
-
|
|
16
|
-
private getKey(salt: string | Buffer) {
|
|
17
|
-
return crypto.pbkdf2Sync(CryptoService.SECRET_KEY, salt, 100000, 32, 'sha512');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async encrypt(password: string) {
|
|
21
|
-
const iv = crypto.randomBytes(CryptoService.IV_LENGTH);
|
|
22
|
-
const salt = crypto.randomBytes(CryptoService.SALT_LENGTH);
|
|
23
|
-
|
|
24
|
-
const key = this.getKey(salt);
|
|
25
|
-
|
|
26
|
-
const cipher = crypto.createCipheriv(CryptoService.ALGORITHM, key, iv);
|
|
27
|
-
const encrypted = Buffer.concat([cipher.update(password, 'utf8'), cipher.final()]);
|
|
28
|
-
|
|
29
|
-
const tag = (cipher as any).getAuthTag();
|
|
30
|
-
|
|
31
|
-
return Buffer.concat([salt, iv, tag, encrypted]).toString('hex');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async decrypt(hash: string) {
|
|
35
|
-
const stringValue = Buffer.from(String(hash), 'hex');
|
|
36
|
-
|
|
37
|
-
const salt = stringValue.slice(0, CryptoService.SALT_LENGTH);
|
|
38
|
-
const iv = stringValue.slice(CryptoService.SALT_LENGTH, CryptoService.TAG_POSITION);
|
|
39
|
-
const tag = stringValue.slice(CryptoService.TAG_POSITION, CryptoService.ENCRYPTED_POSITION);
|
|
40
|
-
const encrypted = stringValue.slice(CryptoService.ENCRYPTED_POSITION);
|
|
41
|
-
|
|
42
|
-
const key = this.getKey(salt);
|
|
43
|
-
|
|
44
|
-
const decipher = crypto.createDecipheriv(CryptoService.ALGORITHM, key, iv);
|
|
45
|
-
|
|
46
|
-
(decipher as any).setAuthTag(tag);
|
|
47
|
-
|
|
48
|
-
return decipher.update(encrypted) + decipher.final('utf8');
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@opensumi/di';
|
|
2
|
-
import {
|
|
3
|
-
ICommonServer,
|
|
4
|
-
CommonServerPath,
|
|
5
|
-
INativeCredentialService,
|
|
6
|
-
KeytarServicePath,
|
|
7
|
-
INativeCryptoService,
|
|
8
|
-
CryptoServicePath,
|
|
9
|
-
} from '@opensumi/ide-core-common';
|
|
10
|
-
|
|
11
|
-
import { HashCalculateContribution } from '../hash-calculate/hash-calculate.contribution';
|
|
12
|
-
import { NodeModule } from '../node-module';
|
|
13
|
-
|
|
14
|
-
import { CommonServer } from './common.server';
|
|
15
|
-
import { CredentialService } from './credential.server';
|
|
16
|
-
import { CryptoService } from './crypto.server';
|
|
17
|
-
|
|
18
|
-
@Injectable()
|
|
19
|
-
export class ServerCommonModule extends NodeModule {
|
|
20
|
-
providers = [
|
|
21
|
-
HashCalculateContribution,
|
|
22
|
-
{
|
|
23
|
-
token: ICommonServer,
|
|
24
|
-
useClass: CommonServer,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
token: INativeCredentialService,
|
|
28
|
-
useClass: CredentialService,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
token: INativeCryptoService,
|
|
32
|
-
useClass: CryptoService,
|
|
33
|
-
},
|
|
34
|
-
];
|
|
35
|
-
backServices = [
|
|
36
|
-
{
|
|
37
|
-
servicePath: CommonServerPath,
|
|
38
|
-
token: ICommonServer,
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
servicePath: KeytarServicePath,
|
|
42
|
-
token: INativeCredentialService,
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
servicePath: CryptoServicePath,
|
|
46
|
-
token: INativeCryptoService,
|
|
47
|
-
},
|
|
48
|
-
];
|
|
49
|
-
}
|
package/src/connection.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import http from 'http';
|
|
2
|
-
import net from 'net';
|
|
3
|
-
|
|
4
|
-
import ws from 'ws';
|
|
5
|
-
|
|
6
|
-
import { Injector, InstanceCreator, ClassCreator, FactoryCreator } from '@opensumi/di';
|
|
7
|
-
import { WSChannel, initRPCService, RPCServiceCenter } from '@opensumi/ide-connection';
|
|
8
|
-
import { createWebSocketConnection } from '@opensumi/ide-connection/lib/common/message';
|
|
9
|
-
import {
|
|
10
|
-
WebSocketServerRoute,
|
|
11
|
-
WebSocketHandler,
|
|
12
|
-
CommonChannelHandler,
|
|
13
|
-
commonChannelPathHandler,
|
|
14
|
-
createSocketConnection,
|
|
15
|
-
} from '@opensumi/ide-connection/lib/node';
|
|
16
|
-
|
|
17
|
-
import { INodeLogger } from './logger/node-logger';
|
|
18
|
-
import { NodeModule } from './node-module';
|
|
19
|
-
import { IServerAppOpts } from './types';
|
|
20
|
-
|
|
21
|
-
export { RPCServiceCenter };
|
|
22
|
-
|
|
23
|
-
export function createServerConnection2(
|
|
24
|
-
server: http.Server,
|
|
25
|
-
injector,
|
|
26
|
-
modulesInstances,
|
|
27
|
-
handlerArr: WebSocketHandler[],
|
|
28
|
-
serverAppOpts: IServerAppOpts,
|
|
29
|
-
) {
|
|
30
|
-
const logger = injector.get(INodeLogger);
|
|
31
|
-
const socketRoute = new WebSocketServerRoute(server, logger);
|
|
32
|
-
const channelHandler = new CommonChannelHandler('/service', logger, {
|
|
33
|
-
pathMatchOptions: serverAppOpts.pathMatchOptions,
|
|
34
|
-
wsServerOptions: serverAppOpts.wsServerOptions,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// 事件由 connection 的时机来触发
|
|
38
|
-
commonChannelPathHandler.register('RPCService', {
|
|
39
|
-
handler: (connection: WSChannel, clientId: string) => {
|
|
40
|
-
logger.log(`set rpc connection ${clientId}`);
|
|
41
|
-
|
|
42
|
-
const serviceCenter = new RPCServiceCenter(undefined, logger);
|
|
43
|
-
const serviceChildInjector = bindModuleBackService(injector, modulesInstances, serviceCenter, clientId);
|
|
44
|
-
|
|
45
|
-
const serverConnection = createWebSocketConnection(connection);
|
|
46
|
-
connection.messageConnection = serverConnection;
|
|
47
|
-
serviceCenter.setConnection(serverConnection);
|
|
48
|
-
|
|
49
|
-
connection.onClose(() => {
|
|
50
|
-
serviceCenter.removeConnection(serverConnection);
|
|
51
|
-
serviceChildInjector.disposeAll();
|
|
52
|
-
|
|
53
|
-
logger.log(`remove rpc connection ${clientId} `);
|
|
54
|
-
});
|
|
55
|
-
},
|
|
56
|
-
dispose: (connection: ws, connectionClientId: string) => {},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
socketRoute.registerHandler(channelHandler);
|
|
60
|
-
if (handlerArr) {
|
|
61
|
-
for (const handler of handlerArr) {
|
|
62
|
-
socketRoute.registerHandler(handler);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
socketRoute.init();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export function createNetServerConnection(server: net.Server, injector, modulesInstances) {
|
|
69
|
-
const logger = injector.get(INodeLogger);
|
|
70
|
-
const serviceCenter = new RPCServiceCenter(undefined, logger);
|
|
71
|
-
const serviceChildInjector = bindModuleBackService(
|
|
72
|
-
injector,
|
|
73
|
-
modulesInstances,
|
|
74
|
-
serviceCenter,
|
|
75
|
-
process.env.CODE_WINDOW_CLIENT_ID as string,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
server.on('connection', (connection) => {
|
|
79
|
-
logger.log('set net rpc connection');
|
|
80
|
-
const serverConnection = createSocketConnection(connection);
|
|
81
|
-
serviceCenter.setConnection(serverConnection);
|
|
82
|
-
|
|
83
|
-
connection.on('close', () => {
|
|
84
|
-
serviceCenter.removeConnection(serverConnection);
|
|
85
|
-
serviceChildInjector.disposeAll();
|
|
86
|
-
|
|
87
|
-
logger.log('remove net rpc connection');
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
return serviceCenter;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function bindModuleBackService(
|
|
95
|
-
injector: Injector,
|
|
96
|
-
modules: NodeModule[],
|
|
97
|
-
serviceCenter: RPCServiceCenter,
|
|
98
|
-
clientId?: string,
|
|
99
|
-
) {
|
|
100
|
-
const logger = injector.get(INodeLogger);
|
|
101
|
-
const { createRPCService } = initRPCService(serviceCenter);
|
|
102
|
-
|
|
103
|
-
const childInjector = injector.createChild();
|
|
104
|
-
for (const module of modules) {
|
|
105
|
-
if (module.backServices) {
|
|
106
|
-
for (const service of module.backServices) {
|
|
107
|
-
if (service.token) {
|
|
108
|
-
logger.log('back service', service.token);
|
|
109
|
-
const serviceToken = service.token;
|
|
110
|
-
|
|
111
|
-
if (!injector.creatorMap.has(serviceToken)) {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const creator = injector.creatorMap.get(serviceToken) as InstanceCreator;
|
|
116
|
-
|
|
117
|
-
if ((creator as FactoryCreator).useFactory) {
|
|
118
|
-
const serviceFactory = (creator as FactoryCreator).useFactory;
|
|
119
|
-
childInjector.addProviders({
|
|
120
|
-
token: serviceToken,
|
|
121
|
-
useValue: serviceFactory(childInjector),
|
|
122
|
-
});
|
|
123
|
-
} else {
|
|
124
|
-
const serviceClass = (creator as ClassCreator).useClass;
|
|
125
|
-
childInjector.addProviders({
|
|
126
|
-
token: serviceToken,
|
|
127
|
-
useClass: serviceClass,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
const serviceInstance = childInjector.get(serviceToken);
|
|
131
|
-
|
|
132
|
-
if (serviceInstance.setConnectionClientId && clientId) {
|
|
133
|
-
serviceInstance.setConnectionClientId(clientId);
|
|
134
|
-
}
|
|
135
|
-
const servicePath = service.servicePath;
|
|
136
|
-
const createService = createRPCService(servicePath, serviceInstance);
|
|
137
|
-
|
|
138
|
-
if (!serviceInstance.rpcClient) {
|
|
139
|
-
serviceInstance.rpcClient = [createService];
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return childInjector;
|
|
147
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Autowired } from '@opensumi/di';
|
|
2
|
-
import { Domain } from '@opensumi/ide-core-common/lib/di-helper';
|
|
3
|
-
import { IHashCalculateService } from '@opensumi/ide-core-common/lib/hash-calculate/hash-calculate';
|
|
4
|
-
|
|
5
|
-
import { ServerAppContribution } from '../types';
|
|
6
|
-
|
|
7
|
-
@Domain(ServerAppContribution)
|
|
8
|
-
export class HashCalculateContribution implements ServerAppContribution {
|
|
9
|
-
@Autowired(IHashCalculateService)
|
|
10
|
-
private readonly hashCalculateService: IHashCalculateService;
|
|
11
|
-
|
|
12
|
-
async initialize() {
|
|
13
|
-
try {
|
|
14
|
-
await this.hashCalculateService.initialize();
|
|
15
|
-
} catch (err) {
|
|
16
|
-
throw new Error(`hashCalculateService init fail: \n ${err.message}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { Injectable, Autowired } from '@opensumi/di';
|
|
2
|
-
import { ILogServiceManager, SupportLogNamespace, ILogService, LogLevel } from '@opensumi/ide-core-common';
|
|
3
|
-
|
|
4
|
-
export type INodeLogger = ILogService;
|
|
5
|
-
export const INodeLogger = Symbol('INodeLogger');
|
|
6
|
-
|
|
7
|
-
@Injectable()
|
|
8
|
-
export class NodeLogger implements INodeLogger {
|
|
9
|
-
@Autowired(ILogServiceManager)
|
|
10
|
-
private loggerManger: ILogServiceManager;
|
|
11
|
-
|
|
12
|
-
private logger: ILogService;
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
this.logger = this.loggerManger.getLogger(SupportLogNamespace.Node);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
error(...args) {
|
|
19
|
-
return this.logger.error(...args);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
warn(...args) {
|
|
23
|
-
return this.logger.warn(...args);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
log(...args) {
|
|
27
|
-
return this.logger.log(...args);
|
|
28
|
-
}
|
|
29
|
-
debug(...args) {
|
|
30
|
-
return this.logger.debug(...args);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
verbose(...args) {
|
|
34
|
-
return this.logger.verbose(...args);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
critical(...args) {
|
|
38
|
-
return this.logger.critical(...args);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
dispose() {
|
|
42
|
-
return this.logger.dispose();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
setOptions(options) {
|
|
46
|
-
return this.logger.setOptions(options);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
sendLog(level: LogLevel, message: string) {
|
|
50
|
-
return this.logger.sendLog(level, message);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
drop() {
|
|
54
|
-
return this.logger.drop();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
flush() {
|
|
58
|
-
return this.logger.flush();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
getLevel() {
|
|
62
|
-
return this.logger.getLevel();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
setLevel(level: LogLevel) {
|
|
66
|
-
return this.logger.setLevel(level);
|
|
67
|
-
}
|
|
68
|
-
}
|
package/src/node-module.ts
DELETED
package/src/types.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import type cp from 'child_process';
|
|
2
|
-
import type http from 'http';
|
|
3
|
-
import type https from 'https';
|
|
4
|
-
|
|
5
|
-
import type Koa from 'koa';
|
|
6
|
-
import type ws from 'ws';
|
|
7
|
-
|
|
8
|
-
import type { Injector } from '@opensumi/di';
|
|
9
|
-
import type { WebSocketHandler } from '@opensumi/ide-connection/lib/node';
|
|
10
|
-
import type { ConstructorOf, ILogService, LogLevel, MaybePromise } from '@opensumi/ide-core-common';
|
|
11
|
-
import { BasicModule } from '@opensumi/ide-core-common';
|
|
12
|
-
|
|
13
|
-
export abstract class NodeModule extends BasicModule {}
|
|
14
|
-
|
|
15
|
-
export type ModuleConstructor = ConstructorOf<NodeModule>;
|
|
16
|
-
export type ContributionConstructor = ConstructorOf<ServerAppContribution>;
|
|
17
|
-
|
|
18
|
-
export const AppConfig = Symbol('AppConfig');
|
|
19
|
-
|
|
20
|
-
export interface MarketplaceRequest {
|
|
21
|
-
path?: string;
|
|
22
|
-
headers?: {
|
|
23
|
-
[header: string]: string | string[] | undefined;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface MarketplaceConfig {
|
|
28
|
-
endpoint: string;
|
|
29
|
-
// 插件市场下载到本地的位置,默认 ~/.sumi/extensions
|
|
30
|
-
extensionDir: string;
|
|
31
|
-
// 是否显示内置插件,默认隐藏
|
|
32
|
-
showBuiltinExtensions: boolean;
|
|
33
|
-
// 插件市场中申请到的客户端的 accountId
|
|
34
|
-
accountId: string;
|
|
35
|
-
// 插件市场中申请到的客户端的 masterKey
|
|
36
|
-
masterKey: string;
|
|
37
|
-
// 插件市场参数转换函数
|
|
38
|
-
transformRequest?: (request: MarketplaceRequest) => MarketplaceRequest;
|
|
39
|
-
// 在热门插件、搜索插件时忽略的插件 id
|
|
40
|
-
ignoreId: string[];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
interface Config {
|
|
44
|
-
/**
|
|
45
|
-
* 初始化的 DI 实例,一般可在外部进行 DI 初始化之后传入,便于提前进行一些依赖的初始化
|
|
46
|
-
*/
|
|
47
|
-
injector: Injector;
|
|
48
|
-
/**
|
|
49
|
-
* 设置落盘日志级别,默认为 Info 级别的log落盘
|
|
50
|
-
*/
|
|
51
|
-
logLevel?: LogLevel;
|
|
52
|
-
/**
|
|
53
|
-
* 设置日志的目录,默认:~/.sumi/logs
|
|
54
|
-
*/
|
|
55
|
-
logDir?: string;
|
|
56
|
-
/**
|
|
57
|
-
* @deprecated 可通过在传入的 `injector` 初始化 `ILogService` 进行实现替换
|
|
58
|
-
* 外部设置的 ILogService,替换默认的 logService
|
|
59
|
-
*/
|
|
60
|
-
LogServiceClass?: ConstructorOf<ILogService>;
|
|
61
|
-
/**
|
|
62
|
-
* 启用插件进程的最大个数
|
|
63
|
-
*/
|
|
64
|
-
maxExtProcessCount?: number;
|
|
65
|
-
/**
|
|
66
|
-
* 插件日志自定义实现路径
|
|
67
|
-
*/
|
|
68
|
-
extLogServiceClassPath?: string;
|
|
69
|
-
/**
|
|
70
|
-
* 插件进程关闭时间
|
|
71
|
-
*/
|
|
72
|
-
processCloseExitThreshold?: number;
|
|
73
|
-
/**
|
|
74
|
-
* 终端 pty 进程退出时间
|
|
75
|
-
*/
|
|
76
|
-
terminalPtyCloseThreshold?: number;
|
|
77
|
-
/**
|
|
78
|
-
* 访问静态资源允许的 origin
|
|
79
|
-
*/
|
|
80
|
-
staticAllowOrigin?: string;
|
|
81
|
-
/**
|
|
82
|
-
* 访问静态资源允许的路径,用于配置静态资源的白名单规则
|
|
83
|
-
*/
|
|
84
|
-
staticAllowPath?: string[];
|
|
85
|
-
/**
|
|
86
|
-
* 文件服务禁止访问的路径,使用 glob 匹配
|
|
87
|
-
*/
|
|
88
|
-
blockPatterns?: string[];
|
|
89
|
-
/**
|
|
90
|
-
* 获取插件进程句柄方法
|
|
91
|
-
* @deprecated 自测 1.30.0 后,不在提供给 IDE 后端发送插件进程的方法
|
|
92
|
-
*/
|
|
93
|
-
onDidCreateExtensionHostProcess?: (cp: cp.ChildProcess) => void;
|
|
94
|
-
/**
|
|
95
|
-
* 插件 Node 进程入口文件
|
|
96
|
-
*/
|
|
97
|
-
extHost?: string;
|
|
98
|
-
/**
|
|
99
|
-
* 插件进程存放用于通信的 sock 地址
|
|
100
|
-
* 默认为 /tmp
|
|
101
|
-
*/
|
|
102
|
-
extHostIPCSockPath?: string;
|
|
103
|
-
/**
|
|
104
|
-
* 插件进程 fork 配置
|
|
105
|
-
*/
|
|
106
|
-
extHostForkOptions?: Partial<cp.ForkOptions>;
|
|
107
|
-
/**
|
|
108
|
-
* 配置关闭 keytar 校验能力,默认开启
|
|
109
|
-
*/
|
|
110
|
-
disableKeytar?: boolean;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface AppConfig extends Partial<Config> {
|
|
114
|
-
marketplace: MarketplaceConfig;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export interface IServerAppOpts extends Partial<Config> {
|
|
118
|
-
modules?: ModuleConstructor[];
|
|
119
|
-
contributions?: ContributionConstructor[];
|
|
120
|
-
modulesInstances?: NodeModule[];
|
|
121
|
-
webSocketHandler?: WebSocketHandler[];
|
|
122
|
-
wsServerOptions?: ws.ServerOptions;
|
|
123
|
-
pathMatchOptions?: {
|
|
124
|
-
// When true the regexp will match to the end of the string.
|
|
125
|
-
end?: boolean;
|
|
126
|
-
};
|
|
127
|
-
marketplace?: Partial<MarketplaceConfig>;
|
|
128
|
-
use?(middleware: Koa.Middleware<Koa.ParameterizedContext<any, any>>): void;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export const ServerAppContribution = Symbol('ServerAppContribution');
|
|
132
|
-
|
|
133
|
-
export interface ServerAppContribution {
|
|
134
|
-
initialize?(app: IServerApp): MaybePromise<void>;
|
|
135
|
-
onStart?(app: IServerApp): MaybePromise<void>;
|
|
136
|
-
onStop?(app: IServerApp): MaybePromise<void>;
|
|
137
|
-
onWillUseElectronMain?(): void;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export interface IServerApp {
|
|
141
|
-
use(middleware: Koa.Middleware<Koa.ParameterizedContext<any, any>>): void;
|
|
142
|
-
start(server: http.Server | https.Server): Promise<void>;
|
|
143
|
-
}
|