@theia/core 1.73.0-next.2 → 1.73.0-next.24
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/lib/browser/authentication-service.d.ts +2 -0
- package/lib/browser/authentication-service.d.ts.map +1 -1
- package/lib/browser/authentication-service.js +8 -2
- package/lib/browser/authentication-service.js.map +1 -1
- package/lib/browser/catalog.json +204 -73
- package/lib/browser/frontend-application.d.ts +2 -0
- package/lib/browser/frontend-application.d.ts.map +1 -1
- package/lib/browser/frontend-application.js +15 -9
- package/lib/browser/frontend-application.js.map +1 -1
- package/lib/browser/json-schema-store.d.ts +2 -0
- package/lib/browser/json-schema-store.d.ts.map +1 -1
- package/lib/browser/json-schema-store.js +8 -2
- package/lib/browser/json-schema-store.js.map +1 -1
- package/lib/browser/keybinding.js +2 -1
- package/lib/browser/keybinding.js.map +1 -1
- package/lib/browser/preferences/frontend-config-preference-contributions.d.ts +2 -0
- package/lib/browser/preferences/frontend-config-preference-contributions.d.ts.map +1 -1
- package/lib/browser/preferences/frontend-config-preference-contributions.js +7 -1
- package/lib/browser/preferences/frontend-config-preference-contributions.js.map +1 -1
- package/lib/browser/preferences/preference-schema-provider.spec.js +3 -0
- package/lib/browser/preferences/preference-schema-provider.spec.js.map +1 -1
- package/lib/browser/preferences/preference-validation-service.d.ts +2 -0
- package/lib/browser/preferences/preference-validation-service.d.ts.map +1 -1
- package/lib/browser/preferences/preference-validation-service.js +11 -5
- package/lib/browser/preferences/preference-validation-service.js.map +1 -1
- package/lib/browser/preferences/preference-validation-service.spec.js +2 -0
- package/lib/browser/preferences/preference-validation-service.spec.js.map +1 -1
- package/lib/browser/quick-input/quick-view-service.d.ts +1 -0
- package/lib/browser/quick-input/quick-view-service.d.ts.map +1 -1
- package/lib/browser/quick-input/quick-view-service.js +6 -1
- package/lib/browser/quick-input/quick-view-service.js.map +1 -1
- package/lib/browser/quick-input/quick-view-service.spec.d.ts +2 -0
- package/lib/browser/quick-input/quick-view-service.spec.d.ts.map +1 -0
- package/lib/browser/quick-input/quick-view-service.spec.js +41 -0
- package/lib/browser/quick-input/quick-view-service.spec.js.map +1 -0
- package/lib/browser/secondary-window-handler.d.ts +2 -0
- package/lib/browser/secondary-window-handler.d.ts.map +1 -1
- package/lib/browser/secondary-window-handler.js +12 -6
- package/lib/browser/secondary-window-handler.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts +2 -0
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +9 -3
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/tree/tree-container.spec.js +4 -0
- package/lib/browser/tree/tree-container.spec.js.map +1 -1
- package/lib/browser/tree/tree.d.ts +2 -0
- package/lib/browser/tree/tree.d.ts.map +1 -1
- package/lib/browser/tree/tree.js +7 -1
- package/lib/browser/tree/tree.js.map +1 -1
- package/lib/browser/window/default-window-service.d.ts +2 -1
- package/lib/browser/window/default-window-service.d.ts.map +1 -1
- package/lib/browser/window/default-window-service.js +10 -5
- package/lib/browser/window/default-window-service.js.map +1 -1
- package/lib/browser/window/default-window-service.spec.js +2 -0
- package/lib/browser/window/default-window-service.spec.js.map +1 -1
- package/lib/browser-only/messaging/frontend-only-service-connection-provider.d.ts +2 -0
- package/lib/browser-only/messaging/frontend-only-service-connection-provider.d.ts.map +1 -1
- package/lib/browser-only/messaging/frontend-only-service-connection-provider.js +8 -2
- package/lib/browser-only/messaging/frontend-only-service-connection-provider.js.map +1 -1
- package/lib/common/command.d.ts +2 -0
- package/lib/common/command.d.ts.map +1 -1
- package/lib/common/command.js +10 -4
- package/lib/common/command.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +2 -0
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +17 -9
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts +2 -0
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.js +9 -3
- package/lib/electron-main/messaging/electron-messaging-contribution.js.map +1 -1
- package/lib/electron-node/request/electron-backend-request-service.d.ts +2 -0
- package/lib/electron-node/request/electron-backend-request-service.d.ts.map +1 -1
- package/lib/electron-node/request/electron-backend-request-service.js +7 -1
- package/lib/electron-node/request/electron-backend-request-service.js.map +1 -1
- package/lib/electron-node/token/electron-token-backend-contribution.d.ts +2 -0
- package/lib/electron-node/token/electron-token-backend-contribution.d.ts.map +1 -1
- package/lib/electron-node/token/electron-token-backend-contribution.js +7 -1
- package/lib/electron-node/token/electron-token-backend-contribution.js.map +1 -1
- package/lib/electron-node/token/electron-token-validator.d.ts +2 -0
- package/lib/electron-node/token/electron-token-validator.d.ts.map +1 -1
- package/lib/electron-node/token/electron-token-validator.js +7 -1
- package/lib/electron-node/token/electron-token-validator.js.map +1 -1
- package/lib/node/backend-application.d.ts +2 -0
- package/lib/node/backend-application.d.ts.map +1 -1
- package/lib/node/backend-application.js +17 -11
- package/lib/node/backend-application.js.map +1 -1
- package/lib/node/backend-application.spec.js +3 -2
- package/lib/node/backend-application.spec.js.map +1 -1
- package/lib/node/messaging/default-messaging-service.d.ts +2 -0
- package/lib/node/messaging/default-messaging-service.d.ts.map +1 -1
- package/lib/node/messaging/default-messaging-service.js +8 -2
- package/lib/node/messaging/default-messaging-service.js.map +1 -1
- package/lib/node/messaging/test/default-messaging-service.spec.js +2 -0
- package/lib/node/messaging/test/default-messaging-service.spec.js.map +1 -1
- package/lib/node/messaging/websocket-endpoint.d.ts +2 -0
- package/lib/node/messaging/websocket-endpoint.d.ts.map +1 -1
- package/lib/node/messaging/websocket-endpoint.js +7 -1
- package/lib/node/messaging/websocket-endpoint.js.map +1 -1
- package/lib/node/process-utils.d.ts +2 -0
- package/lib/node/process-utils.d.ts.map +1 -1
- package/lib/node/process-utils.js +8 -2
- package/lib/node/process-utils.js.map +1 -1
- package/lib/node/process-utils.spec.js +11 -9
- package/lib/node/process-utils.spec.js.map +1 -1
- package/package.json +4 -4
- package/src/browser/authentication-service.ts +6 -3
- package/src/browser/frontend-application.ts +13 -9
- package/src/browser/json-schema-store.ts +6 -2
- package/src/browser/keybinding.ts +2 -2
- package/src/browser/preferences/frontend-config-preference-contributions.ts +7 -2
- package/src/browser/preferences/preference-schema-provider.spec.ts +5 -0
- package/src/browser/preferences/preference-validation-service.spec.ts +3 -1
- package/src/browser/preferences/preference-validation-service.ts +9 -6
- package/src/browser/quick-input/quick-view-service.spec.ts +50 -0
- package/src/browser/quick-input/quick-view-service.ts +5 -0
- package/src/browser/secondary-window-handler.ts +11 -7
- package/src/browser/shell/application-shell.ts +8 -4
- package/src/browser/tree/tree-container.spec.ts +6 -0
- package/src/browser/tree/tree.ts +6 -2
- package/src/browser/window/default-window-service.spec.ts +3 -1
- package/src/browser/window/default-window-service.ts +9 -6
- package/src/browser-only/messaging/frontend-only-service-connection-provider.ts +8 -3
- package/src/common/command.ts +8 -4
- package/src/electron-main/electron-main-application.ts +15 -9
- package/src/electron-main/messaging/electron-messaging-contribution.ts +7 -3
- package/src/electron-node/request/electron-backend-request-service.ts +6 -2
- package/src/electron-node/token/electron-token-backend-contribution.ts +6 -2
- package/src/electron-node/token/electron-token-validator.ts +6 -2
- package/src/node/backend-application.spec.ts +3 -3
- package/src/node/backend-application.ts +15 -11
- package/src/node/messaging/default-messaging-service.ts +6 -2
- package/src/node/messaging/test/default-messaging-service.spec.ts +3 -1
- package/src/node/messaging/websocket-endpoint.ts +6 -2
- package/src/node/process-utils.spec.ts +12 -9
- package/src/node/process-utils.ts +7 -3
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { injectable, inject, optional, postConstruct } from 'inversify';
|
|
17
|
+
import { injectable, inject, optional, postConstruct, named } from 'inversify';
|
|
18
18
|
import { ArrayExt, find, toArray, each } from '@lumino/algorithm';
|
|
19
19
|
import {
|
|
20
20
|
BoxLayout, BoxPanel, DockLayout, DockPanel, FocusTracker, Layout, Panel, SplitLayout,
|
|
@@ -46,6 +46,7 @@ import { OpenerService } from '../opener-service';
|
|
|
46
46
|
import { PreviewableWidget } from '../widgets/previewable-widget';
|
|
47
47
|
import { WindowService } from '../window/window-service';
|
|
48
48
|
import { TheiaSplitPanel } from './theia-split-panel';
|
|
49
|
+
import { ILogger } from '../../common/logger';
|
|
49
50
|
|
|
50
51
|
/** The class name added to ApplicationShell instances. */
|
|
51
52
|
export const APPLICATION_SHELL_CLASS = 'theia-ApplicationShell';
|
|
@@ -242,6 +243,9 @@ export class ApplicationShell extends Widget {
|
|
|
242
243
|
@inject(UntitledResourceResolver)
|
|
243
244
|
protected readonly untitledResourceResolver: UntitledResourceResolver;
|
|
244
245
|
|
|
246
|
+
@inject(ILogger) @named('core:ApplicationShell')
|
|
247
|
+
protected readonly logger: ILogger;
|
|
248
|
+
|
|
245
249
|
protected readonly onDidAddWidgetEmitter = new Emitter<Widget>();
|
|
246
250
|
readonly onDidAddWidget = this.onDidAddWidgetEmitter.event;
|
|
247
251
|
protected fireDidAddWidget(widget: Widget): void {
|
|
@@ -595,7 +599,7 @@ export class ApplicationShell extends Widget {
|
|
|
595
599
|
const opener = await this.openerService.getOpener(fileUri);
|
|
596
600
|
opener.open(fileUri);
|
|
597
601
|
} catch (e) {
|
|
598
|
-
|
|
602
|
+
this.logger.info(`no opener found for '${fileUri}'`);
|
|
599
603
|
}
|
|
600
604
|
};
|
|
601
605
|
|
|
@@ -975,7 +979,7 @@ export class ApplicationShell extends Widget {
|
|
|
975
979
|
*/
|
|
976
980
|
async addWidget(widget: Widget, options?: Readonly<ApplicationShell.WidgetOptions>): Promise<void> {
|
|
977
981
|
if (!widget.id) {
|
|
978
|
-
|
|
982
|
+
this.logger.error('Widgets added to the application shell must have a unique id property.');
|
|
979
983
|
return;
|
|
980
984
|
}
|
|
981
985
|
const { area, addOptions } = this.getInsertionOptions(options);
|
|
@@ -1430,7 +1434,7 @@ export class ApplicationShell extends Widget {
|
|
|
1430
1434
|
if (delta < this.activationTimeout) {
|
|
1431
1435
|
request = setTimeout(step, 0);
|
|
1432
1436
|
} else {
|
|
1433
|
-
|
|
1437
|
+
this.logger.warn(`Widget was activated, but did not accept focus after ${this.activationTimeout}ms: ${widget.id}`);
|
|
1434
1438
|
}
|
|
1435
1439
|
};
|
|
1436
1440
|
let request = setTimeout(step, 0);
|
|
@@ -19,6 +19,8 @@ import { Container } from 'inversify';
|
|
|
19
19
|
import { createTreeContainer, isTreeServices } from './tree-container';
|
|
20
20
|
import { TreeSearch } from './tree-search';
|
|
21
21
|
import { defaultTreeProps, TreeProps } from './tree-widget';
|
|
22
|
+
import { ILogger } from '../../common/logger';
|
|
23
|
+
import { MockLogger } from '../../common/test/mock-logger';
|
|
22
24
|
|
|
23
25
|
describe('TreeContainer', () => {
|
|
24
26
|
describe('IsTreeServices should accurately distinguish TreeProps from TreeContainerProps', () => {
|
|
@@ -33,11 +35,15 @@ describe('TreeContainer', () => {
|
|
|
33
35
|
const nonDefault = { search: !defaultTreeProps.search, contextMenu: ['no-default-for-this'] };
|
|
34
36
|
it('should use props passed in as just props', () => {
|
|
35
37
|
const parent = new Container();
|
|
38
|
+
parent.bind(ILogger).to(MockLogger).inSingletonScope();
|
|
39
|
+
|
|
36
40
|
const child = createTreeContainer(parent, nonDefault);
|
|
37
41
|
assert.deepStrictEqual(child.get(TreeProps), { ...defaultTreeProps, ...nonDefault });
|
|
38
42
|
});
|
|
39
43
|
it('should use props passed in as part of TreeContainerProps', () => {
|
|
40
44
|
const parent = new Container();
|
|
45
|
+
parent.bind(ILogger).to(MockLogger).inSingletonScope();
|
|
46
|
+
|
|
41
47
|
const child = createTreeContainer(parent, { props: nonDefault });
|
|
42
48
|
assert.deepStrictEqual(child.get(TreeProps), { ...defaultTreeProps, ...nonDefault });
|
|
43
49
|
});
|
package/src/browser/tree/tree.ts
CHANGED
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { injectable } from 'inversify';
|
|
17
|
+
import { injectable, inject, named } from 'inversify';
|
|
18
18
|
import { Event, Emitter, WaitUntilEvent } from '../../common/event';
|
|
19
19
|
import { Disposable, DisposableCollection } from '../../common/disposable';
|
|
20
20
|
import { CancellationToken, CancellationTokenSource } from '../../common/cancellation';
|
|
21
21
|
import { timeout } from '../../common/promise-util';
|
|
22
22
|
import { isObject, Mutable } from '../../common';
|
|
23
23
|
import { AccessibilityInformation } from '../../common/accessibility';
|
|
24
|
+
import { ILogger } from '../../common/logger';
|
|
24
25
|
|
|
25
26
|
export const Tree = Symbol('Tree');
|
|
26
27
|
|
|
@@ -250,6 +251,9 @@ export namespace CompositeTreeNode {
|
|
|
250
251
|
@injectable()
|
|
251
252
|
export class TreeImpl implements Tree {
|
|
252
253
|
|
|
254
|
+
@inject(ILogger) @named('core:TreeImpl')
|
|
255
|
+
protected readonly logger: ILogger;
|
|
256
|
+
|
|
253
257
|
protected _root: TreeNode | undefined;
|
|
254
258
|
protected readonly onChangedEmitter = new Emitter<void>();
|
|
255
259
|
protected readonly onNodeRefreshedEmitter = new Emitter<CompositeTreeNode & WaitUntilEvent>();
|
|
@@ -344,7 +348,7 @@ export class TreeImpl implements Tree {
|
|
|
344
348
|
protected async setChildren(parent: CompositeTreeNode, children: TreeNode[]): Promise<CompositeTreeNode | undefined> {
|
|
345
349
|
const root = this.getRootNode(parent);
|
|
346
350
|
if (this.nodes[root.id] && this.nodes[root.id] !== root) {
|
|
347
|
-
|
|
351
|
+
this.logger.error(`Child node '${parent.id}' does not belong to this '${root.id}' tree.`);
|
|
348
352
|
return undefined;
|
|
349
353
|
}
|
|
350
354
|
this.removeNode(parent);
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { Container } from 'inversify';
|
|
18
|
-
import { ContributionProvider } from '../../common';
|
|
18
|
+
import { ContributionProvider, ILogger } from '../../common';
|
|
19
19
|
import { CorePreferences } from '../../common/core-preferences';
|
|
20
20
|
import { FrontendApplicationContribution } from '../frontend-application-contribution';
|
|
21
21
|
import { DefaultWindowService } from './default-window-service';
|
|
22
22
|
import assert = require('assert');
|
|
23
|
+
import { MockLogger } from '../../common/test/mock-logger';
|
|
23
24
|
|
|
24
25
|
describe('DefaultWindowService', () => {
|
|
25
26
|
class TestFrontendApplicationContribution implements FrontendApplicationContribution {
|
|
@@ -42,6 +43,7 @@ describe('DefaultWindowService', () => {
|
|
|
42
43
|
.toConstantValue({
|
|
43
44
|
'application.confirmExit': confirmExit,
|
|
44
45
|
});
|
|
46
|
+
container.bind(ILogger).to(MockLogger).inSingletonScope();
|
|
45
47
|
return container.get(DefaultWindowService);
|
|
46
48
|
}
|
|
47
49
|
it('onWillStop should be called on every contribution (never)', () => {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { inject, injectable, named } from 'inversify';
|
|
18
|
-
import { Event, Emitter } from '../../common';
|
|
18
|
+
import { Event, Emitter, ILogger } from '../../common';
|
|
19
19
|
import { CorePreferences } from '../../common/core-preferences';
|
|
20
20
|
import { ContributionProvider } from '../../common/contribution-provider';
|
|
21
21
|
import { FrontendApplicationContribution, OnWillStopAction } from '../frontend-application-contribution';
|
|
@@ -43,6 +43,9 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
43
43
|
@named(FrontendApplicationContribution)
|
|
44
44
|
protected readonly contributions: ContributionProvider<FrontendApplicationContribution>;
|
|
45
45
|
|
|
46
|
+
@inject(ILogger) @named('core:DefaultWindowService')
|
|
47
|
+
protected readonly logger: ILogger;
|
|
48
|
+
|
|
46
49
|
onStart(app: FrontendApplication): void {
|
|
47
50
|
this.frontendApplication = app;
|
|
48
51
|
this.registerUnloadListeners();
|
|
@@ -114,7 +117,7 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
114
117
|
return true;
|
|
115
118
|
}
|
|
116
119
|
const preparedValues = await Promise.all(vetoes.map(e => e.prepare?.(stopReason)));
|
|
117
|
-
|
|
120
|
+
this.logger.debug('Shutdown prevented by', vetoes.map(({ reason }) => reason).join(', '));
|
|
118
121
|
for (let i = 0; i < vetoes.length; i++) {
|
|
119
122
|
try {
|
|
120
123
|
const result = await vetoes[i].action(preparedValues[i], stopReason);
|
|
@@ -122,10 +125,10 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
122
125
|
return false;
|
|
123
126
|
}
|
|
124
127
|
} catch (e) {
|
|
125
|
-
|
|
128
|
+
this.logger.error(e);
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
|
-
|
|
131
|
+
this.logger.debug('OnWillStop actions resolved; allowing shutdown');
|
|
129
132
|
this.allowVetoes = false;
|
|
130
133
|
return true;
|
|
131
134
|
}
|
|
@@ -145,10 +148,10 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
145
148
|
const vetoes = this.collectContributionUnloadVetoes();
|
|
146
149
|
if (vetoes.length) {
|
|
147
150
|
// In the browser, we don't call the functions because this has to finish in a single tick, so we treat any desired action as a veto.
|
|
148
|
-
|
|
151
|
+
this.logger.debug('Shutdown prevented by', vetoes.map(({ reason }) => reason).join(', '));
|
|
149
152
|
return this.preventUnload(event);
|
|
150
153
|
}
|
|
151
|
-
|
|
154
|
+
this.logger.debug('Shutdown will proceed.');
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
/**
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
import { Event, RpcProxy, Channel, RpcProxyFactory, Emitter } from '../../common';
|
|
17
|
-
import { injectable } from 'inversify';
|
|
17
|
+
import { injectable, inject, named } from 'inversify';
|
|
18
18
|
import { ServiceConnectionProvider } from '../../browser/messaging/service-connection-provider';
|
|
19
|
+
import { ILogger } from '../../common/logger';
|
|
19
20
|
import { ConnectionSource } from '../../browser/messaging/connection-source';
|
|
20
21
|
|
|
21
22
|
@injectable()
|
|
@@ -25,15 +26,19 @@ export class FrontendOnlyConnectionSource implements ConnectionSource {
|
|
|
25
26
|
|
|
26
27
|
@injectable()
|
|
27
28
|
export class FrontendOnlyServiceConnectionProvider extends ServiceConnectionProvider {
|
|
29
|
+
|
|
30
|
+
@inject(ILogger) @named('core:FrontendOnlyServiceConnectionProvider')
|
|
31
|
+
protected readonly logger: ILogger;
|
|
32
|
+
|
|
28
33
|
onSocketDidOpen = Event.None;
|
|
29
34
|
onSocketDidClose = Event.None;
|
|
30
35
|
onIncomingMessageActivity = Event.None;
|
|
31
36
|
override createProxy<T extends object>(path: unknown, target?: unknown): RpcProxy<T> {
|
|
32
|
-
|
|
37
|
+
this.logger.debug(`[Frontend-Only Fallback] Created proxy connection for ${path}`);
|
|
33
38
|
const factory = target instanceof RpcProxyFactory ? target : new RpcProxyFactory<T>(target);
|
|
34
39
|
return factory.createProxy();
|
|
35
40
|
}
|
|
36
41
|
override listen(path: string, handler: ServiceConnectionProvider.ConnectionHandler, reconnect: boolean): void {
|
|
37
|
-
|
|
42
|
+
this.logger.debug('[Frontend-Only Fallback] Listen to websocket connection requested');
|
|
38
43
|
}
|
|
39
44
|
}
|
package/src/common/command.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { ContributionProvider } from './contribution-provider';
|
|
|
21
21
|
import { nls } from './nls';
|
|
22
22
|
import debounce = require('p-debounce');
|
|
23
23
|
import { isObject } from './types';
|
|
24
|
+
import { ILogger } from './logger';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* A command is a unique identifier of a function
|
|
@@ -190,6 +191,9 @@ export interface CommandService {
|
|
|
190
191
|
@injectable()
|
|
191
192
|
export class CommandRegistry implements CommandService {
|
|
192
193
|
|
|
194
|
+
@inject(ILogger) @named('core:CommandRegistry')
|
|
195
|
+
protected readonly logger: ILogger;
|
|
196
|
+
|
|
193
197
|
protected readonly _commands: { [id: string]: Command } = {};
|
|
194
198
|
protected readonly _handlers: { [id: string]: CommandHandler[] } = {};
|
|
195
199
|
|
|
@@ -232,7 +236,7 @@ export class CommandRegistry implements CommandService {
|
|
|
232
236
|
*/
|
|
233
237
|
registerCommand(command: Command, handler?: CommandHandler): Disposable {
|
|
234
238
|
if (this._commands[command.id]) {
|
|
235
|
-
|
|
239
|
+
this.logger.warn(`A command ${command.id} is already registered.`);
|
|
236
240
|
return Disposable.NULL;
|
|
237
241
|
}
|
|
238
242
|
const toDispose = new DisposableCollection(this.doRegisterCommand(command));
|
|
@@ -363,7 +367,7 @@ export class CommandRegistry implements CommandService {
|
|
|
363
367
|
return handler;
|
|
364
368
|
}
|
|
365
369
|
} catch (error) {
|
|
366
|
-
|
|
370
|
+
this.logger.error(error);
|
|
367
371
|
}
|
|
368
372
|
}
|
|
369
373
|
}
|
|
@@ -383,7 +387,7 @@ export class CommandRegistry implements CommandService {
|
|
|
383
387
|
return handler;
|
|
384
388
|
}
|
|
385
389
|
} catch (error) {
|
|
386
|
-
|
|
390
|
+
this.logger.error(error);
|
|
387
391
|
}
|
|
388
392
|
}
|
|
389
393
|
}
|
|
@@ -403,7 +407,7 @@ export class CommandRegistry implements CommandService {
|
|
|
403
407
|
return handler;
|
|
404
408
|
}
|
|
405
409
|
} catch (error) {
|
|
406
|
-
|
|
410
|
+
this.logger.error(error);
|
|
407
411
|
}
|
|
408
412
|
}
|
|
409
413
|
}
|
|
@@ -45,6 +45,7 @@ import { StopReason } from '../common/frontend-application-state';
|
|
|
45
45
|
import { dynamicRequire } from '../node/dynamic-require';
|
|
46
46
|
import { ThemeMode } from '../common/theme';
|
|
47
47
|
import { backendGlobal } from '../node/backend-global';
|
|
48
|
+
import { ILogger } from '../common/logger';
|
|
48
49
|
|
|
49
50
|
export { ElectronMainApplicationGlobals };
|
|
50
51
|
|
|
@@ -174,6 +175,9 @@ export class ElectronMainApplication {
|
|
|
174
175
|
@inject(TheiaElectronWindowFactory)
|
|
175
176
|
protected readonly windowFactory: TheiaElectronWindowFactory;
|
|
176
177
|
|
|
178
|
+
@inject(ILogger) @named('core:ElectronMainApplication')
|
|
179
|
+
protected readonly logger: ILogger;
|
|
180
|
+
|
|
177
181
|
@inject(Stopwatch)
|
|
178
182
|
protected readonly stopwatch: Stopwatch;
|
|
179
183
|
|
|
@@ -231,7 +235,7 @@ export class ElectronMainApplication {
|
|
|
231
235
|
.positional('file', { type: 'string' }),
|
|
232
236
|
async args => {
|
|
233
237
|
if (args.electronUserData) {
|
|
234
|
-
|
|
238
|
+
this.logger.info(`using electron user data area : '${args.electronUserData}'`);
|
|
235
239
|
await fs.mkdir(args.electronUserData, { recursive: true });
|
|
236
240
|
app.setPath('userData', args.electronUserData);
|
|
237
241
|
}
|
|
@@ -298,7 +302,7 @@ export class ElectronMainApplication {
|
|
|
298
302
|
if (browserWindow) {
|
|
299
303
|
this.saveWindowState(browserWindow);
|
|
300
304
|
} else {
|
|
301
|
-
|
|
305
|
+
this.logger.warn(`no BrowserWindow with id: ${webContents.id}`);
|
|
302
306
|
}
|
|
303
307
|
}
|
|
304
308
|
|
|
@@ -365,7 +369,7 @@ export class ElectronMainApplication {
|
|
|
365
369
|
|
|
366
370
|
protected async configureAndShowSplashScreen(mainWindow: BrowserWindow): Promise<BrowserWindow> {
|
|
367
371
|
const splashScreenOptions = this.getSplashScreenOptions()!;
|
|
368
|
-
|
|
372
|
+
this.logger.debug('SplashScreen options', splashScreenOptions);
|
|
369
373
|
|
|
370
374
|
const splashScreenBounds = await this.determineSplashScreenBounds(mainWindow.getBounds());
|
|
371
375
|
const splashScreenWindow = new BrowserWindow({
|
|
@@ -394,6 +398,8 @@ export class ElectronMainApplication {
|
|
|
394
398
|
const cancelTokenSource = new CancellationTokenSource();
|
|
395
399
|
const minTime = timeout(splashScreenOptions.minDuration ?? 0, cancelTokenSource.token);
|
|
396
400
|
const maxTime = timeout(splashScreenOptions.maxDuration ?? 30000, cancelTokenSource.token);
|
|
401
|
+
// Swallow rejections that occur when the cancellation token is cancelled after one of the timers wins.
|
|
402
|
+
const ignoreCancellation = () => { /* timer was cancelled, intentionally ignored */ };
|
|
397
403
|
|
|
398
404
|
const showWindowAndCloseSplashScreen = () => {
|
|
399
405
|
cancelTokenSource.cancel();
|
|
@@ -404,10 +410,10 @@ export class ElectronMainApplication {
|
|
|
404
410
|
};
|
|
405
411
|
TheiaRendererAPI.onApplicationStateChanged(mainWindow.webContents, state => {
|
|
406
412
|
if (state === 'ready') {
|
|
407
|
-
minTime.then(() => showWindowAndCloseSplashScreen());
|
|
413
|
+
minTime.then(() => showWindowAndCloseSplashScreen(), ignoreCancellation);
|
|
408
414
|
}
|
|
409
415
|
});
|
|
410
|
-
maxTime.then(() => showWindowAndCloseSplashScreen());
|
|
416
|
+
maxTime.then(() => showWindowAndCloseSplashScreen(), ignoreCancellation);
|
|
411
417
|
return splashScreenWindow;
|
|
412
418
|
}
|
|
413
419
|
|
|
@@ -556,7 +562,7 @@ export class ElectronMainApplication {
|
|
|
556
562
|
try {
|
|
557
563
|
workspacePath = await fs.realpath(path.resolve(options.cwd, options.file));
|
|
558
564
|
} catch {
|
|
559
|
-
|
|
565
|
+
this.logger.error(`Could not resolve the workspace path. "${options.file}" is not a valid 'file' option. Falling back to the default workspace location.`);
|
|
560
566
|
}
|
|
561
567
|
}
|
|
562
568
|
if (workspacePath !== undefined) {
|
|
@@ -634,13 +640,13 @@ export class ElectronMainApplication {
|
|
|
634
640
|
// On Wayland, screen.getCursorScreenPoint() causes a native crash (SIGSEGV)
|
|
635
641
|
// before any window is opened. Detect Wayland and use primary display instead.
|
|
636
642
|
if (this.isWaylandSession()) {
|
|
637
|
-
|
|
643
|
+
this.logger.debug('Running under Wayland, using primary display for new window.');
|
|
638
644
|
return screen.getPrimaryDisplay();
|
|
639
645
|
}
|
|
640
646
|
try {
|
|
641
647
|
return screen.getDisplayNearestPoint(screen.getCursorScreenPoint());
|
|
642
648
|
} catch (error) {
|
|
643
|
-
|
|
649
|
+
this.logger.warn('Failed to get cursor screen point, falling back to primary display.', error);
|
|
644
650
|
return screen.getPrimaryDisplay();
|
|
645
651
|
}
|
|
646
652
|
}
|
|
@@ -711,7 +717,7 @@ export class ElectronMainApplication {
|
|
|
711
717
|
};
|
|
712
718
|
this.electronStore.set('windowstate', options);
|
|
713
719
|
} catch (e) {
|
|
714
|
-
|
|
720
|
+
this.logger.error('Error while saving window state:', e);
|
|
715
721
|
}
|
|
716
722
|
}
|
|
717
723
|
|
|
@@ -25,6 +25,7 @@ import { MessagingService } from '../../node';
|
|
|
25
25
|
import { ElectronMessagingService } from './electron-messaging-service';
|
|
26
26
|
import { ElectronConnectionHandler } from './electron-connection-handler';
|
|
27
27
|
import { ElectronMainApplicationContribution } from '../electron-main-application';
|
|
28
|
+
import { ILogger } from '../../common/logger';
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* This component replicates the role filled by `MessagingContribution` but for Electron.
|
|
@@ -42,6 +43,9 @@ export class ElectronMessagingContribution implements ElectronMainApplicationCon
|
|
|
42
43
|
@inject(ContributionProvider) @named(ElectronConnectionHandler)
|
|
43
44
|
protected readonly connectionHandlers: ContributionProvider<ConnectionHandler>;
|
|
44
45
|
|
|
46
|
+
@inject(ILogger) @named('core:ElectronMessagingContribution')
|
|
47
|
+
protected readonly logger: ILogger;
|
|
48
|
+
|
|
45
49
|
protected readonly channelHandlers = new ConnectionHandlers<Channel>();
|
|
46
50
|
|
|
47
51
|
/**
|
|
@@ -76,7 +80,7 @@ export class ElectronMessagingContribution implements ElectronMainApplicationCon
|
|
|
76
80
|
const windowChannel = this.openChannels.get(sender.id) ?? this.createWindowChannel(sender);
|
|
77
81
|
windowChannel.onMessageEmitter.fire(() => new Uint8ArrayReadBuffer(data));
|
|
78
82
|
} catch (error) {
|
|
79
|
-
|
|
83
|
+
this.logger.error('IPC: Failed to handle message', { error, data });
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
|
|
@@ -88,8 +92,8 @@ export class ElectronMessagingContribution implements ElectronMainApplicationCon
|
|
|
88
92
|
multiplexer.onDidOpenChannel(openEvent => {
|
|
89
93
|
const { channel, id } = openEvent;
|
|
90
94
|
if (this.channelHandlers.route(id, channel)) {
|
|
91
|
-
|
|
92
|
-
channel.onClose(() =>
|
|
95
|
+
this.logger.debug(`Opening channel for service path '${id}'.`);
|
|
96
|
+
channel.onClose(() => this.logger.debug(`Closing channel on service path '${id}'.`));
|
|
93
97
|
}
|
|
94
98
|
});
|
|
95
99
|
sender.once('did-navigate', () => this.deleteChannel(sender.id, 'Window was refreshed'));
|
|
@@ -14,15 +14,19 @@
|
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
|
-
import { decorate, injectable } from 'inversify';
|
|
17
|
+
import { decorate, injectable, inject, named } from 'inversify';
|
|
18
18
|
import { NodeRequestOptions, NodeRequestService } from '@theia/request/lib/node-request-service';
|
|
19
19
|
import { ElectronSecurityToken } from '../../electron-common/electron-token';
|
|
20
|
+
import { ILogger } from '../../common';
|
|
20
21
|
|
|
21
22
|
decorate(injectable(), NodeRequestService);
|
|
22
23
|
|
|
23
24
|
@injectable()
|
|
24
25
|
export class ElectronBackendRequestService extends NodeRequestService {
|
|
25
26
|
|
|
27
|
+
@inject(ILogger) @named('core:ElectronBackendRequestService')
|
|
28
|
+
protected readonly logger: ILogger;
|
|
29
|
+
|
|
26
30
|
override async getProxyUrl(url: string): Promise<string | undefined> {
|
|
27
31
|
if (this.proxyUrl) {
|
|
28
32
|
return this.proxyUrl;
|
|
@@ -34,7 +38,7 @@ export class ElectronBackendRequestService extends NodeRequestService {
|
|
|
34
38
|
return this.buildProxyUrl(url, proxyHost);
|
|
35
39
|
}
|
|
36
40
|
} catch (e) {
|
|
37
|
-
|
|
41
|
+
this.logger.error('Could not resolve electron proxy.', e);
|
|
38
42
|
}
|
|
39
43
|
return super.getProxyUrl(url);
|
|
40
44
|
}
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import express = require('express');
|
|
18
|
-
import { injectable, inject } from 'inversify';
|
|
18
|
+
import { injectable, inject, named } from 'inversify';
|
|
19
19
|
import { BackendApplicationContribution } from '../../node';
|
|
20
20
|
import { ElectronTokenValidator } from './electron-token-validator';
|
|
21
|
+
import { ILogger } from '../../common/logger';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* This component contributes an Express middleware that will refuse all
|
|
@@ -26,6 +27,9 @@ import { ElectronTokenValidator } from './electron-token-validator';
|
|
|
26
27
|
@injectable()
|
|
27
28
|
export class ElectronTokenBackendContribution implements BackendApplicationContribution {
|
|
28
29
|
|
|
30
|
+
@inject(ILogger) @named('core:ElectronTokenBackendContribution')
|
|
31
|
+
protected readonly logger: ILogger;
|
|
32
|
+
|
|
29
33
|
@inject(ElectronTokenValidator)
|
|
30
34
|
protected readonly tokenValidator: ElectronTokenValidator;
|
|
31
35
|
|
|
@@ -40,7 +44,7 @@ export class ElectronTokenBackendContribution implements BackendApplicationContr
|
|
|
40
44
|
if (this.tokenValidator.allowRequest(req)) {
|
|
41
45
|
next();
|
|
42
46
|
} else {
|
|
43
|
-
|
|
47
|
+
this.logger.error(`refused an http request: ${req.connection.remoteAddress}`);
|
|
44
48
|
res.sendStatus(403);
|
|
45
49
|
}
|
|
46
50
|
}
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
import * as http from 'http';
|
|
18
18
|
import * as cookie from 'cookie';
|
|
19
19
|
import * as crypto from 'crypto';
|
|
20
|
-
import { injectable, postConstruct } from 'inversify';
|
|
20
|
+
import { injectable, postConstruct, inject, named } from 'inversify';
|
|
21
21
|
import { isObject, isString, MaybePromise } from '../../common';
|
|
22
22
|
import { ElectronSecurityToken } from '../../electron-common/electron-token';
|
|
23
23
|
import { WsRequestValidatorContribution } from '../../node/ws-request-validators';
|
|
24
|
+
import { ILogger } from '../../common/logger';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* On Electron, we want to make sure that only Electron's browser-windows access the backend services.
|
|
@@ -28,6 +29,9 @@ import { WsRequestValidatorContribution } from '../../node/ws-request-validators
|
|
|
28
29
|
@injectable()
|
|
29
30
|
export class ElectronTokenValidator implements WsRequestValidatorContribution {
|
|
30
31
|
|
|
32
|
+
@inject(ILogger) @named('core:ElectronTokenValidator')
|
|
33
|
+
protected readonly logger: ILogger;
|
|
34
|
+
|
|
31
35
|
protected electronSecurityToken?: ElectronSecurityToken;
|
|
32
36
|
|
|
33
37
|
@postConstruct()
|
|
@@ -70,7 +74,7 @@ export class ElectronTokenValidator implements WsRequestValidatorContribution {
|
|
|
70
74
|
const expected = Buffer.from(this.electronSecurityToken!.value, 'utf8');
|
|
71
75
|
return received.byteLength === expected.byteLength && crypto.timingSafeEqual(received, expected);
|
|
72
76
|
} catch (error) {
|
|
73
|
-
|
|
77
|
+
this.logger.error(error);
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
80
|
return false;
|
|
@@ -19,7 +19,6 @@ import * as sinon from 'sinon';
|
|
|
19
19
|
import { Container, ContainerModule, injectable, preDestroy } from 'inversify';
|
|
20
20
|
import { bindContributionProvider, ILogger, Stopwatch } from '../common';
|
|
21
21
|
import { Deferred } from '../common/promise-util';
|
|
22
|
-
import { MockLogger } from '../common/test/mock-logger';
|
|
23
22
|
import { NodeStopwatch } from './performance/node-stopwatch';
|
|
24
23
|
import { ProcessUtils } from './process-utils';
|
|
25
24
|
import {
|
|
@@ -29,6 +28,7 @@ import {
|
|
|
29
28
|
RootContainer
|
|
30
29
|
} from './backend-application';
|
|
31
30
|
import { CliContribution } from './cli';
|
|
31
|
+
import { MockLogger } from '../common/test/mock-logger';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Test subclass that exposes the protected `gracefulShutdown` for direct testing.
|
|
@@ -82,7 +82,6 @@ describe('BackendApplication', () => {
|
|
|
82
82
|
const container = new Container();
|
|
83
83
|
|
|
84
84
|
container.bind(RootContainer).toConstantValue(container);
|
|
85
|
-
|
|
86
85
|
container.bind(ILogger).to(MockLogger).inSingletonScope();
|
|
87
86
|
container.bind(Stopwatch).to(NodeStopwatch).inSingletonScope();
|
|
88
87
|
container.bind(ProcessUtils).toSelf().inSingletonScope();
|
|
@@ -242,7 +241,8 @@ describe('BackendApplication', () => {
|
|
|
242
241
|
container.bind(BackendApplicationContribution).toConstantValue({
|
|
243
242
|
onStop: () => { secondRan = true; }
|
|
244
243
|
});
|
|
245
|
-
const
|
|
244
|
+
const mockLogger = container.get(ILogger) as ILogger;
|
|
245
|
+
const errorStub = sandbox.stub(mockLogger, 'error');
|
|
246
246
|
|
|
247
247
|
const app = container.get(TestBackendApplication);
|
|
248
248
|
await app.invokeGracefulShutdown();
|
|
@@ -28,6 +28,7 @@ import { Deferred, timeoutReject } from '../common/promise-util';
|
|
|
28
28
|
import { environment } from '../common/index';
|
|
29
29
|
import { AddressInfo } from 'net';
|
|
30
30
|
import { ProcessUtils } from './process-utils';
|
|
31
|
+
import { ILogger } from '../common/logger';
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* The path to the application project directory. This is the directory where the application code is located.
|
|
@@ -180,6 +181,9 @@ export class BackendApplication {
|
|
|
180
181
|
@inject(Stopwatch)
|
|
181
182
|
protected readonly stopwatch: Stopwatch;
|
|
182
183
|
|
|
184
|
+
@inject(ILogger) @named('core:BackendApplication')
|
|
185
|
+
protected readonly logger: ILogger;
|
|
186
|
+
|
|
183
187
|
@inject(RootContainer)
|
|
184
188
|
protected readonly rootContainer: interfaces.Container;
|
|
185
189
|
|
|
@@ -201,7 +205,7 @@ export class BackendApplication {
|
|
|
201
205
|
// Workaround for Electron not installing a handler to ignore SIGPIPE error
|
|
202
206
|
// (https://github.com/electron/electron/issues/13254)
|
|
203
207
|
process.on('SIGPIPE', () => {
|
|
204
|
-
|
|
208
|
+
this.logger.error(new Error('Unexpected SIGPIPE'));
|
|
205
209
|
});
|
|
206
210
|
|
|
207
211
|
// Handles normal process termination.
|
|
@@ -221,7 +225,7 @@ export class BackendApplication {
|
|
|
221
225
|
await this.measureContribution(contribution, 'initialize',
|
|
222
226
|
() => contribution.initialize!());
|
|
223
227
|
} catch (error) {
|
|
224
|
-
|
|
228
|
+
this.logger.error('Could not initialize contribution', error);
|
|
225
229
|
}
|
|
226
230
|
}
|
|
227
231
|
}));
|
|
@@ -258,11 +262,11 @@ export class BackendApplication {
|
|
|
258
262
|
await this.measureContribution(contribution, 'configure',
|
|
259
263
|
() => contribution.configure!(this.app));
|
|
260
264
|
} catch (error) {
|
|
261
|
-
|
|
265
|
+
this.logger.error('Could not configure contribution', error);
|
|
262
266
|
}
|
|
263
267
|
}
|
|
264
268
|
}));
|
|
265
|
-
|
|
269
|
+
this.logger.info('configured all backend app contributions');
|
|
266
270
|
}
|
|
267
271
|
|
|
268
272
|
use(...handlers: express.Handler[]): void {
|
|
@@ -297,14 +301,14 @@ export class BackendApplication {
|
|
|
297
301
|
try {
|
|
298
302
|
key = await fs.readFile(this.cliParams.certkey as string);
|
|
299
303
|
} catch (err) {
|
|
300
|
-
|
|
304
|
+
this.logger.error("Can't read certificate key");
|
|
301
305
|
throw err;
|
|
302
306
|
}
|
|
303
307
|
|
|
304
308
|
try {
|
|
305
309
|
cert = await fs.readFile(this.cliParams.cert as string);
|
|
306
310
|
} catch (err) {
|
|
307
|
-
|
|
311
|
+
this.logger.error("Can't read certificate");
|
|
308
312
|
throw err;
|
|
309
313
|
}
|
|
310
314
|
server = https.createServer({ key, cert }, this.app);
|
|
@@ -323,7 +327,7 @@ export class BackendApplication {
|
|
|
323
327
|
// address should be defined at this point
|
|
324
328
|
const address = server.address()!;
|
|
325
329
|
const url = typeof address === 'string' ? address : this.getHttpUrl(address, this.cliParams.ssl);
|
|
326
|
-
|
|
330
|
+
this.logger.info(`Theia app listening on ${url}.`);
|
|
327
331
|
deferred.resolve(server);
|
|
328
332
|
});
|
|
329
333
|
|
|
@@ -336,7 +340,7 @@ export class BackendApplication {
|
|
|
336
340
|
await this.measureContribution(contribution, 'onStart',
|
|
337
341
|
() => contribution.onStart!(server));
|
|
338
342
|
} catch (error) {
|
|
339
|
-
|
|
343
|
+
this.logger.error('Could not start contribution', error);
|
|
340
344
|
}
|
|
341
345
|
}
|
|
342
346
|
}
|
|
@@ -415,7 +419,7 @@ export class BackendApplication {
|
|
|
415
419
|
try {
|
|
416
420
|
await contrib.onStop(this.app);
|
|
417
421
|
} catch (error) {
|
|
418
|
-
|
|
422
|
+
this.logger.error('Could not stop contribution', error);
|
|
419
423
|
}
|
|
420
424
|
}
|
|
421
425
|
}));
|
|
@@ -466,9 +470,9 @@ export class BackendApplication {
|
|
|
466
470
|
|
|
467
471
|
protected handleUncaughtError(error: Error): void {
|
|
468
472
|
if (error) {
|
|
469
|
-
|
|
473
|
+
this.logger.error('Uncaught Exception: ', error.toString());
|
|
470
474
|
if (error.stack) {
|
|
471
|
-
|
|
475
|
+
this.logger.error(error.stack);
|
|
472
476
|
}
|
|
473
477
|
}
|
|
474
478
|
}
|