@theia/core 1.74.0-next.10 → 1.74.0-next.17

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.
Files changed (38) hide show
  1. package/lib/browser/catalog.json +27 -0
  2. package/lib/browser/preferences/preference-contribution.d.ts.map +1 -1
  3. package/lib/browser/preferences/preference-contribution.js +9 -1
  4. package/lib/browser/preferences/preference-contribution.js.map +1 -1
  5. package/lib/browser/preferences/preference-service.spec.js +63 -0
  6. package/lib/browser/preferences/preference-service.spec.js.map +1 -1
  7. package/lib/common/preferences/index.d.ts +1 -0
  8. package/lib/common/preferences/index.d.ts.map +1 -1
  9. package/lib/common/preferences/index.js +1 -0
  10. package/lib/common/preferences/index.js.map +1 -1
  11. package/lib/common/preferences/preference-scope.d.ts +6 -1
  12. package/lib/common/preferences/preference-scope.d.ts.map +1 -1
  13. package/lib/common/preferences/preference-scope.js +5 -0
  14. package/lib/common/preferences/preference-scope.js.map +1 -1
  15. package/lib/common/preferences/preference-scope.spec.js +5 -3
  16. package/lib/common/preferences/preference-scope.spec.js.map +1 -1
  17. package/lib/common/preferences/preference-service.d.ts +19 -0
  18. package/lib/common/preferences/preference-service.d.ts.map +1 -1
  19. package/lib/common/preferences/preference-service.js +34 -5
  20. package/lib/common/preferences/preference-service.js.map +1 -1
  21. package/lib/common/preferences/session-preference-provider.d.ts +17 -0
  22. package/lib/common/preferences/session-preference-provider.d.ts.map +1 -0
  23. package/lib/common/preferences/session-preference-provider.js +77 -0
  24. package/lib/common/preferences/session-preference-provider.js.map +1 -0
  25. package/lib/common/preferences/session-preference-provider.spec.d.ts +2 -0
  26. package/lib/common/preferences/session-preference-provider.spec.d.ts.map +1 -0
  27. package/lib/common/preferences/session-preference-provider.spec.js +71 -0
  28. package/lib/common/preferences/session-preference-provider.spec.js.map +1 -0
  29. package/package.json +4 -4
  30. package/src/browser/preferences/preference-contribution.ts +9 -1
  31. package/src/browser/preferences/preference-service.spec.ts +72 -0
  32. package/src/browser/style/status-bar.css +1 -1
  33. package/src/common/preferences/index.ts +1 -0
  34. package/src/common/preferences/preference-scope.spec.ts +5 -3
  35. package/src/common/preferences/preference-scope.ts +6 -1
  36. package/src/common/preferences/preference-service.ts +39 -5
  37. package/src/common/preferences/session-preference-provider.spec.ts +78 -0
  38. package/src/common/preferences/session-preference-provider.ts +69 -0
@@ -0,0 +1,17 @@
1
+ import { JSONObject, JSONValue } from '@lumino/coreutils';
2
+ import { PreferenceProvider } from './preference-provider';
3
+ import { PreferenceProviderImpl } from './preference-provider-impl';
4
+ import { PreferenceScope } from './preference-scope';
5
+ /**
6
+ * In-memory preference provider used for process-lifetime overrides such as those
7
+ * supplied via the `--session-preference` CLI option. Values live in memory only
8
+ * and are dropped when the process exits.
9
+ */
10
+ export declare class SessionPreferenceProvider extends PreferenceProviderImpl implements PreferenceProvider {
11
+ protected readonly preferences: Map<string, JSONValue>;
12
+ protected init(): void;
13
+ canHandleScope(scope: PreferenceScope): boolean;
14
+ getPreferences(): JSONObject;
15
+ setPreference(key: string, value: JSONValue | undefined): Promise<boolean>;
16
+ }
17
+ //# sourceMappingURL=session-preference-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-preference-provider.d.ts","sourceRoot":"","sources":["../../../src/common/preferences/session-preference-provider.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAgC,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;GAIG;AACH,qBACa,yBAA0B,SAAQ,sBAAuB,YAAW,kBAAkB;IAE/F,SAAS,CAAC,QAAQ,CAAC,WAAW,yBAAgC;IAG9D,SAAS,CAAC,IAAI,IAAI,IAAI;IAIb,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAIxD,cAAc,IAAI,UAAU;IAQtB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;CAmBnF"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.SessionPreferenceProvider = void 0;
19
+ const tslib_1 = require("tslib");
20
+ const inversify_1 = require("inversify");
21
+ const preference_provider_impl_1 = require("./preference-provider-impl");
22
+ const preference_scope_1 = require("./preference-scope");
23
+ /**
24
+ * In-memory preference provider used for process-lifetime overrides such as those
25
+ * supplied via the `--session-preference` CLI option. Values live in memory only
26
+ * and are dropped when the process exits.
27
+ */
28
+ let SessionPreferenceProvider = class SessionPreferenceProvider extends preference_provider_impl_1.PreferenceProviderImpl {
29
+ constructor() {
30
+ super(...arguments);
31
+ this.preferences = new Map();
32
+ }
33
+ init() {
34
+ this._ready.resolve();
35
+ }
36
+ canHandleScope(scope) {
37
+ return scope === preference_scope_1.PreferenceScope.Session;
38
+ }
39
+ getPreferences() {
40
+ const result = {};
41
+ for (const [name, value] of this.preferences) {
42
+ result[name] = value;
43
+ }
44
+ return result;
45
+ }
46
+ async setPreference(key, value) {
47
+ const oldValue = this.preferences.get(key);
48
+ if (value === undefined) {
49
+ if (!this.preferences.has(key)) {
50
+ return false;
51
+ }
52
+ this.preferences.delete(key);
53
+ }
54
+ else {
55
+ this.preferences.set(key, value);
56
+ }
57
+ const change = {
58
+ preferenceName: key,
59
+ newValue: value,
60
+ oldValue,
61
+ scope: preference_scope_1.PreferenceScope.Session
62
+ };
63
+ await this.emitPreferencesChangedEvent([change]);
64
+ return true;
65
+ }
66
+ };
67
+ exports.SessionPreferenceProvider = SessionPreferenceProvider;
68
+ tslib_1.__decorate([
69
+ (0, inversify_1.postConstruct)(),
70
+ tslib_1.__metadata("design:type", Function),
71
+ tslib_1.__metadata("design:paramtypes", []),
72
+ tslib_1.__metadata("design:returntype", void 0)
73
+ ], SessionPreferenceProvider.prototype, "init", null);
74
+ exports.SessionPreferenceProvider = SessionPreferenceProvider = tslib_1.__decorate([
75
+ (0, inversify_1.injectable)()
76
+ ], SessionPreferenceProvider);
77
+ //# sourceMappingURL=session-preference-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-preference-provider.js","sourceRoot":"","sources":["../../../src/common/preferences/session-preference-provider.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAGhF,yCAAsD;AAEtD,yEAAoE;AACpE,yDAAqD;AAErD;;;;GAIG;AAEI,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,iDAAsB;IAA9D;;QAEgB,gBAAW,GAAG,IAAI,GAAG,EAAqB,CAAC;IAsClE,CAAC;IAnCa,IAAI;QACV,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAEQ,cAAc,CAAC,KAAsB;QAC1C,OAAO,KAAK,KAAK,kCAAe,CAAC,OAAO,CAAC;IAC7C,CAAC;IAED,cAAc;QACV,MAAM,MAAM,GAAe,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAW,EAAE,KAA4B;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,MAAM,GAAiC;YACzC,cAAc,EAAE,GAAG;YACnB,QAAQ,EAAE,KAAK;YACf,QAAQ;YACR,KAAK,EAAE,kCAAe,CAAC,OAAO;SACjC,CAAC;QACF,MAAM,IAAI,CAAC,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ,CAAA;AAxCY,8DAAyB;AAKxB;IADT,IAAA,yBAAa,GAAE;;;;qDAGf;oCAPQ,yBAAyB;IADrC,IAAA,sBAAU,GAAE;GACA,yBAAyB,CAwCrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-preference-provider.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-preference-provider.spec.d.ts","sourceRoot":"","sources":["../../../src/common/preferences/session-preference-provider.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const chai_1 = require("chai");
19
+ const session_preference_provider_1 = require("./session-preference-provider");
20
+ const preference_scope_1 = require("./preference-scope");
21
+ describe('SessionPreferenceProvider', () => {
22
+ let provider;
23
+ beforeEach(() => {
24
+ provider = new session_preference_provider_1.SessionPreferenceProvider();
25
+ // PostConstruct emulation
26
+ provider.init();
27
+ });
28
+ it('claims only the Session scope', () => {
29
+ (0, chai_1.expect)(provider.canHandleScope(preference_scope_1.PreferenceScope.Session)).to.be.true;
30
+ (0, chai_1.expect)(provider.canHandleScope(preference_scope_1.PreferenceScope.User)).to.be.false;
31
+ (0, chai_1.expect)(provider.canHandleScope(preference_scope_1.PreferenceScope.Workspace)).to.be.false;
32
+ (0, chai_1.expect)(provider.canHandleScope(preference_scope_1.PreferenceScope.Folder)).to.be.false;
33
+ (0, chai_1.expect)(provider.canHandleScope(preference_scope_1.PreferenceScope.Default)).to.be.false;
34
+ });
35
+ it('starts empty', () => {
36
+ (0, chai_1.expect)(provider.getPreferences()).to.deep.equal({});
37
+ });
38
+ it('stores set values in memory and exposes them via get/resolve', async () => {
39
+ const ok = await provider.setPreference('editor.fontSize', 18);
40
+ (0, chai_1.expect)(ok).to.be.true;
41
+ (0, chai_1.expect)(provider.get('editor.fontSize')).to.equal(18);
42
+ (0, chai_1.expect)(provider.resolve('editor.fontSize').value).to.equal(18);
43
+ (0, chai_1.expect)(provider.getPreferences()).to.deep.equal({ 'editor.fontSize': 18 });
44
+ });
45
+ it('emits a change event on set', async () => {
46
+ let received;
47
+ provider.onDidPreferencesChanged(changes => {
48
+ const key = Object.keys(changes)[0];
49
+ received = {
50
+ name: changes[key].preferenceName,
51
+ newValue: changes[key].newValue,
52
+ oldValue: changes[key].oldValue,
53
+ scope: changes[key].scope
54
+ };
55
+ });
56
+ await provider.setPreference('foo', 'bar');
57
+ (0, chai_1.expect)(received).to.deep.equal({ name: 'foo', newValue: 'bar', oldValue: undefined, scope: preference_scope_1.PreferenceScope.Session });
58
+ });
59
+ it('removes a value when set to undefined', async () => {
60
+ await provider.setPreference('foo', 'bar');
61
+ const removed = await provider.setPreference('foo', undefined);
62
+ (0, chai_1.expect)(removed).to.be.true;
63
+ (0, chai_1.expect)(provider.get('foo')).to.equal(undefined);
64
+ (0, chai_1.expect)(provider.getPreferences()).to.deep.equal({});
65
+ });
66
+ it('returns false when removing a key that was never set', async () => {
67
+ const removed = await provider.setPreference('missing', undefined);
68
+ (0, chai_1.expect)(removed).to.be.false;
69
+ });
70
+ });
71
+ //# sourceMappingURL=session-preference-provider.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-preference-provider.spec.js","sourceRoot":"","sources":["../../../src/common/preferences/session-preference-provider.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,+BAA8B;AAC9B,+EAA0E;AAC1E,yDAAqD;AAErD,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IAEvC,IAAI,QAAmC,CAAC;IAExC,UAAU,CAAC,GAAG,EAAE;QACZ,QAAQ,GAAG,IAAI,uDAAyB,EAAE,CAAC;QAC3C,0BAA0B;QACzB,QAAwC,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACrC,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,CAAC,kCAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACpE,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,CAAC,kCAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAClE,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,CAAC,kCAAe,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACvE,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,CAAC,kCAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACpE,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,CAAC,kCAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QACpB,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAC/D,IAAA,aAAM,EAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACtB,IAAA,aAAM,EAAC,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrD,IAAA,aAAM,EAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/D,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QACzC,IAAI,QAAoG,CAAC;QACzG,QAAQ,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE;YACvC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACpC,QAAQ,GAAG;gBACP,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,cAAc;gBACjC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ;gBAC/B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ;gBAC/B,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK;aAC5B,CAAC;QACN,CAAC,CAAC,CAAC;QACH,MAAM,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,IAAA,aAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,kCAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1H,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,SAAkB,CAAC,CAAC;QACxE,IAAA,aAAM,EAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC3B,IAAA,aAAM,EAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChD,IAAA,aAAM,EAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,SAAkB,CAAC,CAAC;QAC5E,IAAA,aAAM,EAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAChC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theia/core",
3
- "version": "1.74.0-next.10+a3326786b",
3
+ "version": "1.74.0-next.17+3351cf136",
4
4
  "description": "Theia is a cloud & desktop IDE framework implemented in TypeScript.",
5
5
  "main": "lib/common/index.js",
6
6
  "typings": "lib/common/index.d.ts",
@@ -17,8 +17,8 @@
17
17
  "@lumino/virtualdom": "^2.0.4",
18
18
  "@lumino/widgets": "2.7.5",
19
19
  "@parcel/watcher": "^2.5.6",
20
- "@theia/application-package": "1.74.0-next.10+a3326786b",
21
- "@theia/request": "1.74.0-next.10+a3326786b",
20
+ "@theia/application-package": "1.74.0-next.17+3351cf136",
21
+ "@theia/request": "1.74.0-next.17+3351cf136",
22
22
  "@types/body-parser": "^1.19.6",
23
23
  "@types/express": "^4.17.25",
24
24
  "@types/fs-extra": "^4.0.15",
@@ -230,5 +230,5 @@
230
230
  "nyc": {
231
231
  "extends": "../../configs/nyc.json"
232
232
  },
233
- "gitHead": "a3326786bf47e6e12172815eba3578ca4234bb23"
233
+ "gitHead": "3351cf1363eb15fad7088cfc9e6857377baf0acc"
234
234
  }
@@ -22,16 +22,24 @@ import { isObject } from '../../common/types';
22
22
  import { PreferenceSchemaServiceImpl } from '../../common/preferences/preference-schema-service';
23
23
  import { PreferenceContribution, PreferenceSchemaService } from '../../common/preferences/preference-schema';
24
24
  import { DefaultsPreferenceProvider } from '../../common/preferences/defaults-preference-provider';
25
+ import { SessionPreferenceProvider } from '../../common/preferences/session-preference-provider';
25
26
  import { PreferenceLanguageOverrideService } from '../../common/preferences/preference-language-override-service';
26
27
  import { FrontendConfigPreferenceContribution } from './frontend-config-preference-contributions';
27
28
  import { bindPreferenceConfigurations } from '../../common/preferences/preference-configurations';
28
29
 
29
30
  export function bindPreferenceSchemaProvider(bind: interfaces.Bind): void {
30
31
  bindPreferenceConfigurations(bind);
31
- bind(ValidPreferenceScopes).toConstantValue([PreferenceScope.Default, PreferenceScope.User, PreferenceScope.Workspace, PreferenceScope.Folder]);
32
+ bind(ValidPreferenceScopes).toConstantValue([
33
+ PreferenceScope.Default,
34
+ PreferenceScope.User,
35
+ PreferenceScope.Workspace,
36
+ PreferenceScope.Folder,
37
+ PreferenceScope.Session
38
+ ]);
32
39
  bind(PreferenceSchemaServiceImpl).toSelf().inSingletonScope();
33
40
  bind(PreferenceSchemaService).toService(PreferenceSchemaServiceImpl);
34
41
  bind(PreferenceProvider).to(DefaultsPreferenceProvider).inSingletonScope().whenTargetNamed(PreferenceScope.Default);
42
+ bind(PreferenceProvider).to(SessionPreferenceProvider).inSingletonScope().whenTargetNamed(PreferenceScope.Session);
35
43
  bind(PreferenceLanguageOverrideService).toSelf().inSingletonScope();
36
44
  bindRootContributionProvider(bind, PreferenceContribution);
37
45
  bind(PreferenceContribution).to(FrontendConfigPreferenceContribution).inSingletonScope();
@@ -262,6 +262,7 @@ describe('Preference Service', () => {
262
262
  globalValue,
263
263
  workspaceValue,
264
264
  workspaceFolderValue,
265
+ sessionValue: undefined,
265
266
  value,
266
267
  };
267
268
  const inspection = preferences.inspect(TAB_SIZE, DUMMY_URI);
@@ -374,6 +375,7 @@ describe('Preference Service', () => {
374
375
  globalValue: undefined,
375
376
  workspaceValue: undefined,
376
377
  workspaceFolderValue: undefined,
378
+ sessionValue: undefined,
377
379
  value: 4,
378
380
  };
379
381
  assert.deepStrictEqual(expected, preferences.inspect('editor.tabSize'));
@@ -397,6 +399,7 @@ describe('Preference Service', () => {
397
399
  globalValue: 2,
398
400
  workspaceValue: undefined,
399
401
  workspaceFolderValue: undefined,
402
+ sessionValue: undefined,
400
403
  value: 2
401
404
  };
402
405
  preferences.set('editor.tabSize', 2, PreferenceScope.User);
@@ -422,6 +425,7 @@ describe('Preference Service', () => {
422
425
  globalValue: undefined,
423
426
  workspaceValue: undefined,
424
427
  workspaceFolderValue: undefined,
428
+ sessionValue: undefined,
425
429
  value: 4
426
430
  };
427
431
  assert.deepStrictEqual(expected, preferences.inspect('editor.tabSize'));
@@ -537,4 +541,72 @@ describe('Preference Service', () => {
537
541
  });
538
542
  });
539
543
 
544
+ describe('session-scope overrides', () => {
545
+ function getSessionProvider(): PreferenceProvider {
546
+ return testContainer.getNamed<PreferenceProvider>(PreferenceProvider, PreferenceScope.Session);
547
+ }
548
+
549
+ beforeEach(() => {
550
+ prefSchema.addSchema({
551
+ scope: PreferenceScope.Folder,
552
+ properties: {
553
+ 'test.session': { type: 'number' }
554
+ }
555
+ });
556
+ });
557
+
558
+ it('takes precedence over the user scope', async () => {
559
+ getProvider(PreferenceScope.User).setPreference('test.session', 1);
560
+ await prefService.set('test.session', 99, PreferenceScope.Session);
561
+ expect(prefService.get('test.session')).equals(99);
562
+ });
563
+
564
+ it('is dropped when the same key is written to a persistent scope', async () => {
565
+ const sessionProvider = getSessionProvider();
566
+ getProvider(PreferenceScope.User).setPreference('test.session', 1);
567
+ await prefService.set('test.session', 99, PreferenceScope.Session);
568
+ expect(prefService.get('test.session')).equals(99);
569
+
570
+ // An explicit user edit must win over the session override and clear it.
571
+ await prefService.set('test.session', 2, PreferenceScope.User);
572
+ expect(sessionProvider.get('test.session')).to.equal(undefined);
573
+ expect(prefService.get('test.session')).equals(2);
574
+ });
575
+
576
+ it('is reported via inspect().sessionValue', async () => {
577
+ await prefService.set('test.session', 42, PreferenceScope.Session);
578
+ expect(prefService.inspect('test.session')?.sessionValue).equals(42);
579
+ });
580
+
581
+ it('emits a Session-scope change event when evicted by a persistent write', async () => {
582
+ // Status bar listeners rely on this: an eviction must surface as an
583
+ // onPreferenceChanged event whose `scope` is Session, otherwise the
584
+ // status bar would never clear after the override is dropped.
585
+ await prefService.set('test.session', 99, PreferenceScope.Session);
586
+
587
+ const sessionScopeEvents: PreferenceScope[] = [];
588
+ const listener = prefService.onPreferenceChanged(e => {
589
+ if (e.preferenceName === 'test.session') {
590
+ sessionScopeEvents.push(e.scope);
591
+ }
592
+ });
593
+ try {
594
+ await prefService.set('test.session', 2, PreferenceScope.User);
595
+ } finally {
596
+ listener.dispose();
597
+ }
598
+
599
+ expect(sessionScopeEvents).to.include(PreferenceScope.Session);
600
+ });
601
+
602
+ it('is left alone when writing to the Session scope itself', async () => {
603
+ const sessionProvider = getSessionProvider();
604
+ await prefService.set('test.session', 7, PreferenceScope.Session);
605
+ expect(sessionProvider.get('test.session')).to.equal(7);
606
+ // A second write to Session must not trigger eviction of itself.
607
+ await prefService.set('test.session', 8, PreferenceScope.Session);
608
+ expect(sessionProvider.get('test.session')).to.equal(8);
609
+ });
610
+ });
611
+
540
612
  });
@@ -63,7 +63,7 @@ body.theia-no-open-workspace #theia-statusBar {
63
63
  padding-inline: var(--theia-ui-padding);
64
64
  }
65
65
 
66
- #theia-statusBar .area.left .element.has-background {
66
+ #theia-statusBar .area.left .element.has-background:not(#session-preference-status) {
67
67
  margin-left: calc(-1 * var(--theia-ui-padding));
68
68
  }
69
69
 
@@ -16,6 +16,7 @@
16
16
 
17
17
  export * from './defaults-preference-provider';
18
18
  export * from './preference-language-override-service';
19
+ export * from './session-preference-provider';
19
20
  export * from './preference-provider-impl';
20
21
  export * from './preference-provider';
21
22
  export * from './preference-schema-service';
@@ -20,11 +20,11 @@ import { PreferenceScope } from './preference-scope';
20
20
  describe('PreferenceScope', () => {
21
21
 
22
22
  it('getScopes() should return numbers from broadest to narrowest', () => {
23
- expect(PreferenceScope.getScopes()).deep.equal([0, 1, 2, 3]);
23
+ expect(PreferenceScope.getScopes()).deep.equal([0, 1, 2, 3, 4]);
24
24
  });
25
25
 
26
26
  it('getReversedScopes() should return numbers from narrowest to broadest', () => {
27
- expect(PreferenceScope.getReversedScopes()).deep.equal([3, 2, 1, 0]);
27
+ expect(PreferenceScope.getReversedScopes()).deep.equal([4, 3, 2, 1, 0]);
28
28
  });
29
29
 
30
30
  it('getScopeNames() should return the names of scopes broader than the current one', () => {
@@ -36,11 +36,13 @@ describe('PreferenceScope', () => {
36
36
  expect(PreferenceScope.is(PreferenceScope.User)).to.be.true;
37
37
  expect(PreferenceScope.is(PreferenceScope.Workspace)).to.be.true;
38
38
  expect(PreferenceScope.is(PreferenceScope.Folder)).to.be.true;
39
+ expect(PreferenceScope.is(PreferenceScope.Session)).to.be.true;
39
40
  expect(PreferenceScope.is(0)).to.be.true;
40
41
  expect(PreferenceScope.is(1)).to.be.true;
41
42
  expect(PreferenceScope.is(2)).to.be.true;
42
43
  expect(PreferenceScope.is(3)).to.be.true;
43
- expect(PreferenceScope.is(4)).to.be.false;
44
+ expect(PreferenceScope.is(4)).to.be.true;
45
+ expect(PreferenceScope.is(5)).to.be.false;
44
46
  expect(PreferenceScope.is(-1)).to.be.false;
45
47
  expect(PreferenceScope.is({})).to.be.false;
46
48
  expect(PreferenceScope.is('Default')).to.be.false;
@@ -23,7 +23,12 @@ export enum PreferenceScope {
23
23
  Default,
24
24
  User,
25
25
  Workspace,
26
- Folder
26
+ Folder,
27
+ /**
28
+ * Process-lifetime, in-memory scope used by `--session-preference` CLI overrides.
29
+ * Has the highest precedence and is never persisted to disk.
30
+ */
31
+ Session
27
32
  }
28
33
 
29
34
  export namespace PreferenceScope {
@@ -254,6 +254,10 @@ export interface PreferenceInspection<T = JSONValue> {
254
254
  * Value in folder scope.
255
255
  */
256
256
  workspaceFolderValue: T | undefined,
257
+ /**
258
+ * Value in session scope (in-memory, set via `--session-preference`).
259
+ */
260
+ sessionValue?: T | undefined,
257
261
  /**
258
262
  * The value that is active, i.e. the value set in the lowest scope available.
259
263
  */
@@ -453,11 +457,37 @@ export class PreferenceServiceImpl implements PreferenceService {
453
457
  }
454
458
  const provider = this.getProvider(resolvedScope);
455
459
  if (provider && await provider.setPreference(preferenceName, value, resourceUri)) {
460
+ await this.evictSessionOverride(preferenceName, resolvedScope);
456
461
  return;
457
462
  }
458
463
  throw new Error(`Unable to write to ${PreferenceScope[resolvedScope]} Settings.`);
459
464
  }
460
465
 
466
+ /**
467
+ * When a preference is written to a persistent scope, drop any in-memory session
468
+ * override (set via `--session-preference`) for the same key so that the explicit
469
+ * change takes effect for the remainder of the session. Without this, the session
470
+ * scope would keep shadowing the user's change because it has higher precedence.
471
+ *
472
+ * Note: this fires for any write to a persistent scope, including programmatic
473
+ * writes from extensions. Extensions that race with startup CLI overrides will
474
+ * therefore clear them. This is intentional: a programmatic write is "explicit"
475
+ * from the preference system's point of view, but consumers should be aware.
476
+ *
477
+ * Session preferences are global (no per-resource scoping), so `resourceUri` is
478
+ * not threaded through.
479
+ */
480
+ protected async evictSessionOverride(preferenceName: string, writtenScope: PreferenceScope): Promise<void> {
481
+ if (writtenScope === PreferenceScope.Session || writtenScope === PreferenceScope.Default) {
482
+ return;
483
+ }
484
+ const sessionProvider = this.getProvider(PreferenceScope.Session);
485
+ if (sessionProvider && sessionProvider.get(preferenceName) !== undefined) {
486
+ // Passing `undefined` clears the value in the session provider.
487
+ await sessionProvider.setPreference(preferenceName, undefined as unknown as JSONValue);
488
+ }
489
+ }
490
+
461
491
  getBoolean(preferenceName: string): boolean | undefined;
462
492
  getBoolean(preferenceName: string, defaultValue: boolean): boolean;
463
493
  getBoolean(preferenceName: string, defaultValue: boolean, resourceUri: string): boolean;
@@ -499,10 +529,11 @@ export class PreferenceServiceImpl implements PreferenceService {
499
529
  const globalValue = this.inspectInScope<T>(preferenceName, PreferenceScope.User, resourceUri, forceLanguageOverride);
500
530
  const workspaceValue = this.inspectInScope<T>(preferenceName, PreferenceScope.Workspace, resourceUri, forceLanguageOverride);
501
531
  const workspaceFolderValue = this.inspectInScope<T>(preferenceName, PreferenceScope.Folder, resourceUri, forceLanguageOverride);
532
+ const sessionValue = this.inspectInScope<T>(preferenceName, PreferenceScope.Session, resourceUri, forceLanguageOverride);
502
533
 
503
- const valueApplied = workspaceFolderValue ?? workspaceValue ?? globalValue ?? defaultValue;
534
+ const valueApplied = sessionValue ?? workspaceFolderValue ?? workspaceValue ?? globalValue ?? defaultValue;
504
535
 
505
- return { preferenceName, defaultValue, globalValue, workspaceValue, workspaceFolderValue, value: valueApplied };
536
+ return { preferenceName, defaultValue, globalValue, workspaceValue, workspaceFolderValue, sessionValue, value: valueApplied };
506
537
  }
507
538
 
508
539
  inspectInScope<T extends JSONValue>(preferenceName: string, scope: PreferenceScope, resourceUri?: string, forceLanguageOverride?: boolean): T | undefined {
@@ -526,6 +557,8 @@ export class PreferenceServiceImpl implements PreferenceService {
526
557
  return inspection.workspaceValue;
527
558
  case PreferenceScope.Folder:
528
559
  return inspection.workspaceFolderValue;
560
+ case PreferenceScope.Session:
561
+ return inspection.sessionValue;
529
562
  }
530
563
  unreachable(scope, 'Not all PreferenceScope enum variants handled.');
531
564
  }
@@ -551,9 +584,10 @@ export class PreferenceServiceImpl implements PreferenceService {
551
584
  }
552
585
 
553
586
  // Scopes in ascending order of scope breadth.
554
- const allScopes = [...this.schemaService.validScopes].reverse();
555
- // Get rid of Default scope. We can't set anything there.
556
- allScopes.pop();
587
+ const allScopes = [...this.schemaService.validScopes].reverse()
588
+ // Default is read-only, and Session is populated only by `--session-preference`,
589
+ // so neither is a valid target for a regular user edit.
590
+ .filter(scope => scope !== PreferenceScope.Default && scope !== PreferenceScope.Session);
557
591
 
558
592
  const isScopeDefined = (scope: PreferenceScope) => this.getScopedValueFromInspection(inspection, scope) !== undefined;
559
593
 
@@ -0,0 +1,78 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource 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 { expect } from 'chai';
18
+ import { SessionPreferenceProvider } from './session-preference-provider';
19
+ import { PreferenceScope } from './preference-scope';
20
+
21
+ describe('SessionPreferenceProvider', () => {
22
+
23
+ let provider: SessionPreferenceProvider;
24
+
25
+ beforeEach(() => {
26
+ provider = new SessionPreferenceProvider();
27
+ // PostConstruct emulation
28
+ (provider as unknown as { init(): void }).init();
29
+ });
30
+
31
+ it('claims only the Session scope', () => {
32
+ expect(provider.canHandleScope(PreferenceScope.Session)).to.be.true;
33
+ expect(provider.canHandleScope(PreferenceScope.User)).to.be.false;
34
+ expect(provider.canHandleScope(PreferenceScope.Workspace)).to.be.false;
35
+ expect(provider.canHandleScope(PreferenceScope.Folder)).to.be.false;
36
+ expect(provider.canHandleScope(PreferenceScope.Default)).to.be.false;
37
+ });
38
+
39
+ it('starts empty', () => {
40
+ expect(provider.getPreferences()).to.deep.equal({});
41
+ });
42
+
43
+ it('stores set values in memory and exposes them via get/resolve', async () => {
44
+ const ok = await provider.setPreference('editor.fontSize', 18);
45
+ expect(ok).to.be.true;
46
+ expect(provider.get('editor.fontSize')).to.equal(18);
47
+ expect(provider.resolve('editor.fontSize').value).to.equal(18);
48
+ expect(provider.getPreferences()).to.deep.equal({ 'editor.fontSize': 18 });
49
+ });
50
+
51
+ it('emits a change event on set', async () => {
52
+ let received: { name: string; newValue: unknown; oldValue: unknown; scope: PreferenceScope } | undefined;
53
+ provider.onDidPreferencesChanged(changes => {
54
+ const key = Object.keys(changes)[0];
55
+ received = {
56
+ name: changes[key].preferenceName,
57
+ newValue: changes[key].newValue,
58
+ oldValue: changes[key].oldValue,
59
+ scope: changes[key].scope
60
+ };
61
+ });
62
+ await provider.setPreference('foo', 'bar');
63
+ expect(received).to.deep.equal({ name: 'foo', newValue: 'bar', oldValue: undefined, scope: PreferenceScope.Session });
64
+ });
65
+
66
+ it('removes a value when set to undefined', async () => {
67
+ await provider.setPreference('foo', 'bar');
68
+ const removed = await provider.setPreference('foo', undefined as never);
69
+ expect(removed).to.be.true;
70
+ expect(provider.get('foo')).to.equal(undefined);
71
+ expect(provider.getPreferences()).to.deep.equal({});
72
+ });
73
+
74
+ it('returns false when removing a key that was never set', async () => {
75
+ const removed = await provider.setPreference('missing', undefined as never);
76
+ expect(removed).to.be.false;
77
+ });
78
+ });
@@ -0,0 +1,69 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource 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 { JSONObject, JSONValue } from '@lumino/coreutils';
18
+ import { injectable, postConstruct } from 'inversify';
19
+ import { PreferenceProvider, PreferenceProviderDataChange } from './preference-provider';
20
+ import { PreferenceProviderImpl } from './preference-provider-impl';
21
+ import { PreferenceScope } from './preference-scope';
22
+
23
+ /**
24
+ * In-memory preference provider used for process-lifetime overrides such as those
25
+ * supplied via the `--session-preference` CLI option. Values live in memory only
26
+ * and are dropped when the process exits.
27
+ */
28
+ @injectable()
29
+ export class SessionPreferenceProvider extends PreferenceProviderImpl implements PreferenceProvider {
30
+
31
+ protected readonly preferences = new Map<string, JSONValue>();
32
+
33
+ @postConstruct()
34
+ protected init(): void {
35
+ this._ready.resolve();
36
+ }
37
+
38
+ override canHandleScope(scope: PreferenceScope): boolean {
39
+ return scope === PreferenceScope.Session;
40
+ }
41
+
42
+ getPreferences(): JSONObject {
43
+ const result: JSONObject = {};
44
+ for (const [name, value] of this.preferences) {
45
+ result[name] = value;
46
+ }
47
+ return result;
48
+ }
49
+
50
+ async setPreference(key: string, value: JSONValue | undefined): Promise<boolean> {
51
+ const oldValue = this.preferences.get(key);
52
+ if (value === undefined) {
53
+ if (!this.preferences.has(key)) {
54
+ return false;
55
+ }
56
+ this.preferences.delete(key);
57
+ } else {
58
+ this.preferences.set(key, value);
59
+ }
60
+ const change: PreferenceProviderDataChange = {
61
+ preferenceName: key,
62
+ newValue: value,
63
+ oldValue,
64
+ scope: PreferenceScope.Session
65
+ };
66
+ await this.emitPreferencesChangedEvent([change]);
67
+ return true;
68
+ }
69
+ }