@theia/core 1.61.0-next.8 → 1.61.1
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/README.md +7 -7
- package/i18n/nls.cs.json +34 -5
- package/i18n/nls.de.json +34 -5
- package/i18n/nls.es.json +34 -5
- package/i18n/nls.fr.json +34 -5
- package/i18n/nls.hu.json +34 -5
- package/i18n/nls.it.json +34 -5
- package/i18n/nls.ja.json +34 -5
- package/i18n/nls.json +35 -6
- package/i18n/nls.ko.json +34 -5
- package/i18n/nls.pl.json +34 -5
- package/i18n/nls.pt-br.json +34 -5
- package/i18n/nls.ru.json +34 -5
- package/i18n/nls.tr.json +34 -5
- package/i18n/nls.zh-cn.json +34 -5
- package/i18n/nls.zh-tw.json +34 -5
- package/lib/browser/catalog.json +322 -45
- package/lib/browser/dialogs.d.ts +8 -1
- package/lib/browser/dialogs.d.ts.map +1 -1
- package/lib/browser/dialogs.js +11 -4
- package/lib/browser/dialogs.js.map +1 -1
- package/lib/browser/frontend-application-module.js +1 -1
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/preload/i18n-preload-contribution.js +1 -1
- package/lib/browser/preload/i18n-preload-contribution.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts +17 -5
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +94 -40
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/shell/index.d.ts +1 -0
- package/lib/browser/shell/index.d.ts.map +1 -1
- package/lib/browser/shell/index.js +1 -0
- package/lib/browser/shell/index.js.map +1 -1
- package/lib/browser/shell/tab-bars.d.ts.map +1 -1
- package/lib/browser/shell/tab-bars.js +3 -2
- package/lib/browser/shell/tab-bars.js.map +1 -1
- package/lib/browser/shell/theia-dock-panel.d.ts +4 -10
- package/lib/browser/shell/theia-dock-panel.d.ts.map +1 -1
- package/lib/browser/shell/theia-dock-panel.js +7 -84
- package/lib/browser/shell/theia-dock-panel.js.map +1 -1
- package/lib/browser/shell/theia-split-panel.d.ts +6 -0
- package/lib/browser/shell/theia-split-panel.d.ts.map +1 -0
- package/lib/browser/shell/theia-split-panel.js +56 -0
- package/lib/browser/shell/theia-split-panel.js.map +1 -0
- package/lib/browser/tree/tree-widget.d.ts +1 -0
- package/lib/browser/tree/tree-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-widget.js +6 -0
- package/lib/browser/tree/tree-widget.js.map +1 -1
- package/lib/browser/view-container.d.ts.map +1 -1
- package/lib/browser/view-container.js +2 -1
- package/lib/browser/view-container.js.map +1 -1
- package/lib/browser/widgets/widget.d.ts.map +1 -1
- package/lib/browser/widgets/widget.js.map +1 -1
- package/lib/common/content-replacer.d.ts.map +1 -1
- package/lib/common/content-replacer.js +2 -1
- package/lib/common/content-replacer.js.map +1 -1
- package/lib/common/content-replacer.spec.js +2 -2
- package/lib/common/content-replacer.spec.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +15 -13
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.js +1 -4
- package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +1 -1
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +7 -5
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/node/backend-application-module.d.ts.map +1 -1
- package/lib/node/backend-application-module.js +3 -0
- package/lib/node/backend-application-module.js.map +1 -1
- package/lib/node/index.d.ts +1 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +1 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/setting-service.d.ts +20 -0
- package/lib/node/setting-service.d.ts.map +1 -0
- package/lib/node/setting-service.js +80 -0
- package/lib/node/setting-service.js.map +1 -0
- package/package.json +7 -9
- package/src/browser/dialogs.ts +11 -4
- package/src/browser/frontend-application-module.ts +1 -1
- package/src/browser/preload/i18n-preload-contribution.ts +1 -1
- package/src/browser/shell/application-shell.ts +96 -34
- package/src/browser/shell/index.ts +1 -0
- package/src/browser/shell/tab-bars.ts +3 -2
- package/src/browser/shell/theia-dock-panel.ts +10 -91
- package/src/browser/shell/theia-split-panel.ts +56 -0
- package/src/browser/style/index.css +3 -11
- package/src/browser/style/sidepanel.css +2 -4
- package/src/browser/tree/tree-widget.tsx +7 -0
- package/src/browser/view-container.ts +2 -1
- package/src/browser/widgets/widget.ts +1 -0
- package/src/common/content-replacer.spec.ts +2 -2
- package/src/common/content-replacer.ts +2 -1
- package/src/electron-browser/menu/electron-main-menu-factory.ts +15 -14
- package/src/electron-browser/menu/electron-menu-contribution.ts +1 -4
- package/src/electron-main/electron-main-application.ts +8 -5
- package/src/node/backend-application-module.ts +4 -0
- package/src/node/index.ts +1 -0
- package/src/node/setting-service.ts +78 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 STMicroelectronics and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { SplitLayout, SplitPanel } from '@lumino/widgets';
|
|
18
|
+
|
|
19
|
+
export class TheiaSplitPanel extends SplitPanel {
|
|
20
|
+
constructor(options?: SplitPanel.IOptions) {
|
|
21
|
+
super(options);
|
|
22
|
+
|
|
23
|
+
let oldCursor: string | undefined;
|
|
24
|
+
let pointerId: number | undefined;
|
|
25
|
+
|
|
26
|
+
this['_evtPointerDown'] = (event: PointerEvent) => {
|
|
27
|
+
super['_evtPointerDown'](event);
|
|
28
|
+
if (this['_pressData']) { // indicating that the drag has started
|
|
29
|
+
this.node.setPointerCapture(event.pointerId);
|
|
30
|
+
pointerId = event.pointerId;
|
|
31
|
+
const layout = this.layout as SplitLayout;
|
|
32
|
+
const handle = layout.handles.find(h => h.contains(event.target as HTMLElement));
|
|
33
|
+
if (handle) {
|
|
34
|
+
const style = window.getComputedStyle(handle);
|
|
35
|
+
oldCursor = this.node.style.cursor;
|
|
36
|
+
this.node.style.cursor = style.cursor;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this['_releaseMouse'] = () => {
|
|
41
|
+
super['_releaseMouse']();
|
|
42
|
+
if (oldCursor !== undefined) {
|
|
43
|
+
this.node.style.cursor = oldCursor;
|
|
44
|
+
oldCursor = undefined;
|
|
45
|
+
}
|
|
46
|
+
if (pointerId) {
|
|
47
|
+
this.node.releasePointerCapture(pointerId);
|
|
48
|
+
pointerId = undefined;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override handleEvent(event: Event): void {
|
|
54
|
+
super.handleEvent(event);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -90,6 +90,7 @@ body {
|
|
|
90
90
|
color: var(--theia-foreground);
|
|
91
91
|
border: 1px solid var(--theia-window-activeBorder);
|
|
92
92
|
}
|
|
93
|
+
|
|
93
94
|
body:window-inactive,
|
|
94
95
|
body:-moz-window-inactive {
|
|
95
96
|
border-color: var(--theia-window-inactiveBorder);
|
|
@@ -139,19 +140,10 @@ blockquote {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
.theia-maximized {
|
|
142
|
-
position: fixed !important;
|
|
143
143
|
top: 0 !important;
|
|
144
|
-
bottom: 0 !important;
|
|
145
144
|
left: 0 !important;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
height: auto !important;
|
|
149
|
-
z-index: 255 !important;
|
|
150
|
-
background: var(--theia-editor-background);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.theia-visible-menu-maximized {
|
|
154
|
-
top: var(--theia-private-menubar-height) !important;
|
|
145
|
+
width: 100% !important;
|
|
146
|
+
height: 100% !important;
|
|
155
147
|
}
|
|
156
148
|
|
|
157
149
|
.theia-ApplicationShell {
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
.lm-Widget .theia-sidebar-menu-item {
|
|
191
|
-
|
|
191
|
+
cursor: pointer;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
.lm-Widget.theia-sidebar-menu i {
|
|
@@ -334,6 +334,7 @@
|
|
|
334
334
|
padding-left: 5px;
|
|
335
335
|
align-items: center;
|
|
336
336
|
background-color: var(--theia-sideBar-background);
|
|
337
|
+
overflow: hidden;
|
|
337
338
|
}
|
|
338
339
|
|
|
339
340
|
.theia-sidepanel-toolbar .theia-sidepanel-title {
|
|
@@ -366,6 +367,3 @@
|
|
|
366
367
|
overflow: hidden;
|
|
367
368
|
text-overflow: ellipsis;
|
|
368
369
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
@@ -445,6 +445,13 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
|
|
|
445
445
|
super.onUpdateRequest(msg);
|
|
446
446
|
}
|
|
447
447
|
|
|
448
|
+
protected override handleVisiblityChanged(isNowVisible: boolean): void {
|
|
449
|
+
super.handleVisiblityChanged(isNowVisible);
|
|
450
|
+
if (isNowVisible) {
|
|
451
|
+
this.update();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
448
455
|
protected override onResize(msg: Widget.ResizeMessage): void {
|
|
449
456
|
super.onResize(msg);
|
|
450
457
|
this.update();
|
|
@@ -38,6 +38,7 @@ import { Drag } from '@lumino/dragdrop';
|
|
|
38
38
|
import { MimeData } from '@lumino/coreutils';
|
|
39
39
|
import { ElementExt } from '@lumino/domutils';
|
|
40
40
|
import { TabBarDecoratorService } from './shell/tab-bar-decorator';
|
|
41
|
+
import { TheiaSplitPanel } from './shell/theia-split-panel';
|
|
41
42
|
|
|
42
43
|
export interface ViewContainerTitleOptions {
|
|
43
44
|
label: string;
|
|
@@ -152,7 +153,7 @@ export class ViewContainer extends BaseWidget implements StatefulWidget, Applica
|
|
|
152
153
|
this.addClass('theia-view-container');
|
|
153
154
|
const layout = new PanelLayout();
|
|
154
155
|
this.layout = layout;
|
|
155
|
-
this.panel = new
|
|
156
|
+
this.panel = new TheiaSplitPanel({
|
|
156
157
|
layout: new ViewContainerLayout({
|
|
157
158
|
renderer: SplitPanel.defaultRenderer,
|
|
158
159
|
orientation: this.orientation,
|
|
@@ -295,6 +295,7 @@ export function addKeyListener<K extends keyof HTMLElementEventMap = never>(
|
|
|
295
295
|
return (actual: KeyCode) => KeysOrKeyCodes.toKeyCodes(keysOrKeyCodes).some(k => k.equals(actual));
|
|
296
296
|
}
|
|
297
297
|
})();
|
|
298
|
+
|
|
298
299
|
toDispose.push(addEventListener(element, 'keydown', e => {
|
|
299
300
|
const kc = KeyCode.createKeyCode(e);
|
|
300
301
|
if (keyCodePredicate(kc)) {
|
|
@@ -63,7 +63,7 @@ describe('ContentReplacer', () => {
|
|
|
63
63
|
];
|
|
64
64
|
const result = contentReplacer.applyReplacements(originalContent, replacements);
|
|
65
65
|
expect(result.updatedContent).to.equal(originalContent);
|
|
66
|
-
expect(result.errors
|
|
66
|
+
expect(result.errors.some(candidate => candidate.startsWith('Multiple occurrences found for: "Repeat"'))).to.be.true;
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
it('should prepend newContent when oldContent is an empty string', () => {
|
|
@@ -108,7 +108,7 @@ describe('ContentReplacer', () => {
|
|
|
108
108
|
];
|
|
109
109
|
const result = contentReplacer.applyReplacements(originalContent, replacements);
|
|
110
110
|
expect(result.updatedContent).to.equal(originalContent);
|
|
111
|
-
expect(result.errors
|
|
111
|
+
expect(result.errors.some(candidate => candidate.startsWith('Multiple occurrences found for: "Repeat"'))).to.be.true;
|
|
112
112
|
});
|
|
113
113
|
|
|
114
114
|
it('should return an error when conflicting replacements for the same oldContent are provided', () => {
|
|
@@ -60,7 +60,8 @@ export class ContentReplacer {
|
|
|
60
60
|
if (multiple) {
|
|
61
61
|
updatedContent = this.replaceContentAll(updatedContent, oldContent, newContent);
|
|
62
62
|
} else {
|
|
63
|
-
errorMessages.push(`Multiple occurrences found for: "${oldContent}"
|
|
63
|
+
errorMessages.push(`Multiple occurrences found for: "${oldContent}". Set 'multiple' to true if multiple occurrences of the oldContent are expected to be\
|
|
64
|
+
replaced at once.`);
|
|
64
65
|
}
|
|
65
66
|
} else {
|
|
66
67
|
updatedContent = this.replaceContentOnce(updatedContent, oldContent, newContent);
|
|
@@ -21,7 +21,6 @@ import { isOSX, MAIN_MENU_BAR, MenuPath, MenuNode, CommandMenuNode, CompoundMenu
|
|
|
21
21
|
import { Keybinding } from '../../common/keybinding';
|
|
22
22
|
import { PreferenceService, CommonCommands } from '../../browser';
|
|
23
23
|
import debounce = require('lodash.debounce');
|
|
24
|
-
import { MAXIMIZED_CLASS } from '../../browser/shell/theia-dock-panel';
|
|
25
24
|
import { BrowserMainMenuFactory } from '../../browser/menu/browser-menu-plugin';
|
|
26
25
|
import { ContextMatcher } from '../../browser/context-key-service';
|
|
27
26
|
import { MenuDto, MenuRole } from '../../electron-common/electron-api';
|
|
@@ -111,22 +110,24 @@ export class ElectronMainMenuFactory extends BrowserMainMenuFactory {
|
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
doSetMenuBar(): void {
|
|
114
|
-
|
|
115
|
-
window.electronTheiaCore.
|
|
113
|
+
const preference = this.preferencesService.get<string>('window.menuBarVisibility') || 'classic';
|
|
114
|
+
const shouldShowTop = !window.electronTheiaCore.isFullScreen() || preference === 'visible';
|
|
115
|
+
if (shouldShowTop) {
|
|
116
|
+
this.menu = this.createElectronMenuBar();
|
|
117
|
+
window.electronTheiaCore.setMenu(this.menu);
|
|
118
|
+
window.electronTheiaCore.setMenuBarVisible(true);
|
|
119
|
+
} else {
|
|
120
|
+
window.electronTheiaCore.setMenuBarVisible(false);
|
|
121
|
+
}
|
|
116
122
|
}
|
|
117
123
|
|
|
118
|
-
createElectronMenuBar(): MenuDto[]
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
const menu = this.fillMenuTemplate([], menuModel, [], { honorDisabled: false, rootMenuPath: MAIN_MENU_BAR }, false);
|
|
124
|
-
if (isOSX) {
|
|
125
|
-
menu.unshift(this.createOSXMenu());
|
|
126
|
-
}
|
|
127
|
-
return menu;
|
|
124
|
+
createElectronMenuBar(): MenuDto[] {
|
|
125
|
+
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR)!;
|
|
126
|
+
const menu = this.fillMenuTemplate([], menuModel, [], { honorDisabled: false, rootMenuPath: MAIN_MENU_BAR }, false);
|
|
127
|
+
if (isOSX) {
|
|
128
|
+
menu.unshift(this.createOSXMenu());
|
|
128
129
|
}
|
|
129
|
-
return
|
|
130
|
+
return menu;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
createElectronContextMenu(menuPath: MenuPath, args?: any[], context?: HTMLElement, contextKeyService?: ContextMatcher, skipSingleRootNode?: boolean): MenuDto[] {
|
|
@@ -120,10 +120,7 @@ export class ElectronMenuContribution extends BrowserMenuBarContribution impleme
|
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
122
|
onStateChange = this.stateService.onStateChanged(stateServiceListener);
|
|
123
|
-
this.shell.
|
|
124
|
-
this.handleToggleMaximized();
|
|
125
|
-
});
|
|
126
|
-
this.shell.bottomPanel.onDidToggleMaximized(() => {
|
|
123
|
+
this.shell.onDidToggleMaximized(() => {
|
|
127
124
|
this.handleToggleMaximized();
|
|
128
125
|
});
|
|
129
126
|
this.attachMenuBarVisibilityListener();
|
|
@@ -746,11 +746,14 @@ export class ElectronMainApplication {
|
|
|
746
746
|
this.stopContributions();
|
|
747
747
|
}
|
|
748
748
|
|
|
749
|
-
protected async onSecondInstance(event: ElectronEvent,
|
|
750
|
-
|
|
751
|
-
|
|
749
|
+
protected async onSecondInstance(event: ElectronEvent, _: string[], cwd: string, originalArgv: string[]): Promise<void> {
|
|
750
|
+
// the second instance passes it's original argument array as the fourth argument to this method
|
|
751
|
+
// The `argv` second parameter is not usable for us since it is mangled by electron before being passed here
|
|
752
|
+
|
|
753
|
+
if (originalArgv.includes('--open-url')) {
|
|
754
|
+
this.openUrl(originalArgv[originalArgv.length - 1]);
|
|
752
755
|
} else {
|
|
753
|
-
createYargs(this.processArgv.getProcessArgvWithoutBin(
|
|
756
|
+
createYargs(this.processArgv.getProcessArgvWithoutBin(originalArgv), cwd)
|
|
754
757
|
.help(false)
|
|
755
758
|
.command('$0 [file]', false,
|
|
756
759
|
cmd => cmd
|
|
@@ -758,7 +761,7 @@ export class ElectronMainApplication {
|
|
|
758
761
|
async args => {
|
|
759
762
|
await this.handleMainCommand({
|
|
760
763
|
file: args.file,
|
|
761
|
-
cwd:
|
|
764
|
+
cwd: cwd,
|
|
762
765
|
secondInstance: true
|
|
763
766
|
});
|
|
764
767
|
},
|
|
@@ -43,6 +43,7 @@ import { BackendRequestFacade } from './request/backend-request-facade';
|
|
|
43
43
|
import { FileSystemLocking, FileSystemLockingImpl } from './filesystem-locking';
|
|
44
44
|
import { BackendRemoteService } from './remote/backend-remote-service';
|
|
45
45
|
import { RemoteCliContribution } from './remote/remote-cli-contribution';
|
|
46
|
+
import { SettingService, SettingServiceImpl } from './setting-service';
|
|
46
47
|
|
|
47
48
|
decorate(injectable(), ApplicationPackage);
|
|
48
49
|
|
|
@@ -136,4 +137,7 @@ export const backendApplicationModule = new ContainerModule(bind => {
|
|
|
136
137
|
bindBackendStopwatchServer(bind);
|
|
137
138
|
|
|
138
139
|
bind(FileSystemLocking).to(FileSystemLockingImpl).inSingletonScope();
|
|
140
|
+
|
|
141
|
+
bind(SettingServiceImpl).toSelf().inSingletonScope();
|
|
142
|
+
bind(SettingService).toService(SettingServiceImpl);
|
|
139
143
|
});
|
package/src/node/index.ts
CHANGED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 STMicroelectronics and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { inject, injectable, postConstruct } from 'inversify';
|
|
18
|
+
import { EnvVariablesServer } from '../common/env-variables';
|
|
19
|
+
import { Deferred } from '../common/promise-util';
|
|
20
|
+
import { promises as fs } from 'fs';
|
|
21
|
+
import { URI } from '../common';
|
|
22
|
+
|
|
23
|
+
export const SettingService = Symbol('SettingService');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A service providing a simple user-level, persistent key-value store on the back end
|
|
27
|
+
*/
|
|
28
|
+
export interface SettingService {
|
|
29
|
+
set(key: string, value: string): Promise<void>;
|
|
30
|
+
get(key: string): Promise<string | undefined>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@injectable()
|
|
34
|
+
export class SettingServiceImpl implements SettingService {
|
|
35
|
+
|
|
36
|
+
@inject(EnvVariablesServer)
|
|
37
|
+
protected readonly envVarServer: EnvVariablesServer;
|
|
38
|
+
|
|
39
|
+
protected readonly ready = new Deferred<void>();
|
|
40
|
+
protected values: Record<string, string> = {};
|
|
41
|
+
|
|
42
|
+
@postConstruct()
|
|
43
|
+
protected init(): void {
|
|
44
|
+
const asyncInit = async () => {
|
|
45
|
+
const configDir = new URI(await this.envVarServer.getConfigDirUri());
|
|
46
|
+
const path: string = configDir.resolve('backend-settings.json').path.fsPath();
|
|
47
|
+
try {
|
|
48
|
+
const contents = await fs.readFile(path, {
|
|
49
|
+
encoding: 'utf-8'
|
|
50
|
+
});
|
|
51
|
+
this.values = JSON.parse(contents);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.log(e);
|
|
54
|
+
} finally {
|
|
55
|
+
this.ready.resolve();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
asyncInit();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async set(key: string, value: string): Promise<void> {
|
|
62
|
+
await this.ready.promise;
|
|
63
|
+
this.values[key] = value;
|
|
64
|
+
await this.writeFile();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async writeFile(): Promise<void> {
|
|
68
|
+
const configDir = new URI(await this.envVarServer.getConfigDirUri());
|
|
69
|
+
const path: string = configDir.resolve('backend-settings.json').path.fsPath();
|
|
70
|
+
const values = JSON.stringify(this.values);
|
|
71
|
+
await fs.writeFile(path, values);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async get(key: string): Promise<string | undefined> {
|
|
75
|
+
await this.ready.promise;
|
|
76
|
+
return this.values[key];
|
|
77
|
+
}
|
|
78
|
+
}
|