@theia/plugin-ext 1.76.0-next.7 → 1.77.0-next.0
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/common/paths-util.d.ts.map +1 -1
- package/lib/common/paths-util.js +9 -2
- package/lib/common/paths-util.js.map +1 -1
- package/lib/common/paths-util.spec.d.ts +2 -0
- package/lib/common/paths-util.spec.d.ts.map +1 -0
- package/lib/common/paths-util.spec.js +42 -0
- package/lib/common/paths-util.spec.js.map +1 -0
- package/lib/common/plugin-api-rpc.d.ts +14 -0
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +1 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +2 -2
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js +2 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +9 -3
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/worker-main.js +22 -12
- package/lib/hosted/browser/worker/worker-main.js.map +1 -1
- package/lib/hosted/browser/worker/worker-plugin-module.d.ts.map +1 -1
- package/lib/hosted/browser/worker/worker-plugin-module.js +2 -0
- package/lib/hosted/browser/worker/worker-plugin-module.js.map +1 -1
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.d.ts +37 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.js +107 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.js +106 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.d.ts +38 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.js +124 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.js +137 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.d.ts +43 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.js +145 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.js +165 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.d.ts +54 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.js +155 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.js +190 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.js.map +1 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.d.ts +24 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.d.ts.map +1 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.js +46 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.js.map +1 -0
- package/lib/hosted/common/hosted-plugin.d.ts +2 -2
- package/lib/hosted/common/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/common/hosted-plugin.js +2 -2
- package/lib/hosted/common/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/plugin-host-module.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-module.js +2 -0
- package/lib/hosted/node/plugin-host-module.js.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.d.ts +3 -0
- package/lib/hosted/node/plugin-host-rpc.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.js +9 -3
- package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.d.ts +7 -0
- package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
- package/lib/main/browser/editors-and-documents-main.js +19 -9
- package/lib/main/browser/editors-and-documents-main.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.spec.d.ts +2 -0
- package/lib/main/browser/editors-and-documents-main.spec.d.ts.map +1 -0
- package/lib/main/browser/editors-and-documents-main.spec.js +117 -0
- package/lib/main/browser/editors-and-documents-main.spec.js.map +1 -0
- package/lib/main/browser/languages-main.d.ts +7 -0
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +31 -9
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/languages-main.spec.d.ts +2 -0
- package/lib/main/browser/languages-main.spec.d.ts.map +1 -0
- package/lib/main/browser/languages-main.spec.js +82 -0
- package/lib/main/browser/languages-main.spec.js.map +1 -0
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +3 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +5 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +5 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +1 -0
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/plugin-icon-service.d.ts +6 -0
- package/lib/main/browser/plugin-icon-service.d.ts.map +1 -1
- package/lib/main/browser/plugin-icon-service.js +14 -2
- package/lib/main/browser/plugin-icon-service.js.map +1 -1
- package/lib/main/browser/plugin-icon-service.spec.d.ts +2 -0
- package/lib/main/browser/plugin-icon-service.spec.d.ts.map +1 -0
- package/lib/main/browser/plugin-icon-service.spec.js +83 -0
- package/lib/main/browser/plugin-icon-service.spec.js.map +1 -0
- package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
- package/lib/main/browser/plugin-icon-theme-service.js +2 -1
- package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
- package/lib/main/browser/plugin-icon-theme-service.spec.d.ts +2 -0
- package/lib/main/browser/plugin-icon-theme-service.spec.d.ts.map +1 -0
- package/lib/main/browser/plugin-icon-theme-service.spec.js +91 -0
- package/lib/main/browser/plugin-icon-theme-service.spec.js.map +1 -0
- package/lib/main/browser/telemetry-main.d.ts +20 -0
- package/lib/main/browser/telemetry-main.d.ts.map +1 -0
- package/lib/main/browser/telemetry-main.js +43 -0
- package/lib/main/browser/telemetry-main.js.map +1 -0
- package/lib/main/browser/telemetry-main.spec.d.ts +2 -0
- package/lib/main/browser/telemetry-main.spec.d.ts.map +1 -0
- package/lib/main/browser/telemetry-main.spec.js +66 -0
- package/lib/main/browser/telemetry-main.spec.js.map +1 -0
- package/lib/main/browser/webview/webview-context-keys.d.ts +3 -2
- package/lib/main/browser/webview/webview-context-keys.d.ts.map +1 -1
- package/lib/main/browser/webview/webview-context-keys.js +16 -2
- package/lib/main/browser/webview/webview-context-keys.js.map +1 -1
- package/lib/main/browser/webview/webview-environment.d.ts.map +1 -1
- package/lib/main/browser/webview/webview-environment.js +2 -1
- package/lib/main/browser/webview/webview-environment.js.map +1 -1
- package/lib/main/common/paths/const.d.ts +13 -0
- package/lib/main/common/paths/const.d.ts.map +1 -0
- package/lib/main/common/paths/const.js +32 -0
- package/lib/main/common/paths/const.js.map +1 -0
- package/lib/main/node/paths/const.d.ts +5 -5
- package/lib/main/node/paths/const.d.ts.map +1 -1
- package/lib/main/node/paths/const.js +6 -6
- package/lib/main/node/paths/const.js.map +1 -1
- package/lib/main/node/paths/plugin-paths-service.js +1 -1
- package/lib/main/node/paths/plugin-paths-service.js.map +1 -1
- package/lib/main/node/plugin-cli-contribution.d.ts +2 -2
- package/lib/main/node/plugin-cli-contribution.d.ts.map +1 -1
- package/lib/main/node/plugin-cli-contribution.js +4 -3
- package/lib/main/node/plugin-cli-contribution.js.map +1 -1
- package/lib/main/node/plugins-key-value-storage.js +1 -1
- package/lib/main/node/plugins-key-value-storage.js.map +1 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.d.ts +5 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.d.ts.map +1 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.js +12 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.js.map +1 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.d.ts +2 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.d.ts.map +1 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.js +54 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.js.map +1 -0
- package/lib/plugin/plugin-context.d.ts +2 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +2 -3
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts +2 -0
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +12 -1
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/relative-pattern.spec.d.ts +2 -0
- package/lib/plugin/relative-pattern.spec.d.ts.map +1 -0
- package/lib/plugin/relative-pattern.spec.js +51 -0
- package/lib/plugin/relative-pattern.spec.js.map +1 -0
- package/lib/plugin/telemetry-ext.d.ts +23 -7
- package/lib/plugin/telemetry-ext.d.ts.map +1 -1
- package/lib/plugin/telemetry-ext.js +60 -33
- package/lib/plugin/telemetry-ext.js.map +1 -1
- package/lib/plugin/telemetry-ext.spec.js +121 -16
- package/lib/plugin/telemetry-ext.spec.js.map +1 -1
- package/lib/plugin-ext-frontend-only-module.d.ts +4 -0
- package/lib/plugin-ext-frontend-only-module.d.ts.map +1 -0
- package/lib/plugin-ext-frontend-only-module.js +34 -0
- package/lib/plugin-ext-frontend-only-module.js.map +1 -0
- package/package.json +36 -32
- package/src/common/paths-util.spec.ts +47 -0
- package/src/common/paths-util.ts +11 -2
- package/src/common/plugin-api-rpc.ts +15 -1
- package/src/common/plugin-protocol.ts +2 -0
- package/src/hosted/browser/hosted-plugin.ts +9 -4
- package/src/hosted/browser/worker/worker-main.ts +23 -12
- package/src/hosted/browser/worker/worker-plugin-module.ts +2 -0
- package/src/hosted/browser-only/browser-only-hosted-plugin-server.spec.ts +133 -0
- package/src/hosted/browser-only/browser-only-hosted-plugin-server.ts +122 -0
- package/src/hosted/browser-only/browser-only-plugin-file-system-provider.spec.ts +178 -0
- package/src/hosted/browser-only/browser-only-plugin-file-system-provider.ts +129 -0
- package/src/hosted/browser-only/browser-only-plugin-paths-service.spec.ts +199 -0
- package/src/hosted/browser-only/browser-only-plugin-paths-service.ts +145 -0
- package/src/hosted/browser-only/browser-only-plugin-server.spec.ts +228 -0
- package/src/hosted/browser-only/browser-only-plugin-server.ts +165 -0
- package/src/hosted/browser-only/test/navigator-locks-test-util.ts +54 -0
- package/src/hosted/common/hosted-plugin.ts +4 -4
- package/src/hosted/node/plugin-host-module.ts +2 -0
- package/src/hosted/node/plugin-host-rpc.ts +10 -4
- package/src/main/browser/editors-and-documents-main.spec.ts +140 -0
- package/src/main/browser/editors-and-documents-main.ts +19 -7
- package/src/main/browser/languages-main.spec.ts +101 -0
- package/src/main/browser/languages-main.ts +31 -9
- package/src/main/browser/main-context.ts +4 -0
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +5 -0
- package/src/main/browser/plugin-ext-frontend-module.ts +2 -1
- package/src/main/browser/plugin-icon-service.spec.ts +101 -0
- package/src/main/browser/plugin-icon-service.ts +16 -3
- package/src/main/browser/plugin-icon-theme-service.spec.ts +103 -0
- package/src/main/browser/plugin-icon-theme-service.ts +2 -1
- package/src/main/browser/telemetry-main.spec.ts +77 -0
- package/src/main/browser/telemetry-main.ts +46 -0
- package/src/main/browser/webview/webview-context-keys.ts +20 -4
- package/src/main/browser/webview/webview-environment.ts +2 -1
- package/src/main/common/paths/const.ts +28 -0
- package/src/main/node/paths/const.ts +5 -5
- package/src/main/node/paths/plugin-paths-service.ts +1 -1
- package/src/main/node/plugin-cli-contribution.ts +4 -3
- package/src/main/node/plugins-key-value-storage.ts +1 -1
- package/src/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.ts +61 -0
- package/src/main/node/resolvers/local-directory-plugin-deployer-resolver.ts +14 -1
- package/src/plugin/plugin-context.ts +3 -2
- package/src/plugin/plugin-manager.ts +11 -1
- package/src/plugin/relative-pattern.spec.ts +55 -0
- package/src/plugin/telemetry-ext.spec.ts +158 -17
- package/src/plugin/telemetry-ext.ts +63 -33
- package/src/plugin-ext-frontend-only-module.ts +34 -0
|
@@ -15,47 +15,188 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import * as chai from 'chai';
|
|
18
|
+
import { TelemetryLevel } from '@theia/telemetry/lib/common/telemetry-types';
|
|
18
19
|
import { TelemetryExtImpl } from './telemetry-ext';
|
|
19
20
|
|
|
20
21
|
const expect = chai.expect;
|
|
21
22
|
|
|
22
|
-
describe('
|
|
23
|
+
describe('TelemetryExtImpl', () => {
|
|
23
24
|
const sender = {
|
|
24
25
|
sendEventData: () => { },
|
|
25
26
|
sendErrorData: () => { }
|
|
26
27
|
};
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
interface Expectation {
|
|
30
|
+
isTelemetryEnabled: boolean;
|
|
31
|
+
isUsageEnabled: boolean;
|
|
32
|
+
isErrorsEnabled: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const expectations: Record<TelemetryLevel, Expectation> = {
|
|
36
|
+
off: { isTelemetryEnabled: false, isUsageEnabled: false, isErrorsEnabled: false },
|
|
37
|
+
crash: { isTelemetryEnabled: false, isUsageEnabled: false, isErrorsEnabled: false },
|
|
38
|
+
error: { isTelemetryEnabled: false, isUsageEnabled: false, isErrorsEnabled: true },
|
|
39
|
+
all: { isTelemetryEnabled: true, isUsageEnabled: true, isErrorsEnabled: true }
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
for (const level of ['off', 'crash', 'error', 'all'] as const) {
|
|
43
|
+
const expected = expectations[level];
|
|
44
|
+
|
|
45
|
+
it(`derives the enablement states from telemetry level '${level}'`, () => {
|
|
46
|
+
const telemetry = new TelemetryExtImpl();
|
|
47
|
+
telemetry.$onDidChangeTelemetryLevel(level);
|
|
48
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
49
|
+
|
|
50
|
+
expect(telemetry.level).to.equal(level);
|
|
51
|
+
expect(telemetry.isTelemetryEnabled).to.equal(expected.isTelemetryEnabled);
|
|
52
|
+
expect(logger.isUsageEnabled).to.equal(expected.isUsageEnabled);
|
|
53
|
+
expect(logger.isErrorsEnabled).to.equal(expected.isErrorsEnabled);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it(`applies telemetry level '${level}' to loggers created before the level arrived`, () => {
|
|
57
|
+
const telemetry = new TelemetryExtImpl();
|
|
58
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
59
|
+
telemetry.$onDidChangeTelemetryLevel(level);
|
|
60
|
+
|
|
61
|
+
expect(logger.isUsageEnabled).to.equal(expected.isUsageEnabled);
|
|
62
|
+
expect(logger.isErrorsEnabled).to.equal(expected.isErrorsEnabled);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
it('only fires onDidChangeTelemetryEnabled when the boolean it reports changes', () => {
|
|
67
|
+
const telemetry = new TelemetryExtImpl();
|
|
68
|
+
const fired: boolean[] = [];
|
|
69
|
+
telemetry.onDidChangeTelemetryEnabled(enabled => fired.push(enabled));
|
|
70
|
+
|
|
71
|
+
telemetry.$onDidChangeTelemetryLevel('crash');
|
|
72
|
+
telemetry.$onDidChangeTelemetryLevel('error');
|
|
73
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
74
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
75
|
+
|
|
76
|
+
expect(fired).to.deep.equal([true, false]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('fires onDidChangeEnableStates once per transition that changes an enablement state', () => {
|
|
29
80
|
const telemetry = new TelemetryExtImpl();
|
|
30
81
|
const logger = telemetry.createTelemetryLogger(sender);
|
|
82
|
+
let changes = 0;
|
|
83
|
+
logger.onDidChangeEnableStates(() => changes++);
|
|
31
84
|
|
|
32
|
-
|
|
33
|
-
expect(
|
|
34
|
-
expect(logger.isErrorsEnabled).to.equal(false);
|
|
85
|
+
telemetry.$onDidChangeTelemetryLevel('crash'); // off -> crash: both stay false
|
|
86
|
+
expect(changes).to.equal(0);
|
|
35
87
|
|
|
36
|
-
telemetry
|
|
88
|
+
telemetry.$onDidChangeTelemetryLevel('error'); // errors become enabled
|
|
89
|
+
expect(changes).to.equal(1);
|
|
37
90
|
|
|
38
|
-
|
|
39
|
-
expect(
|
|
40
|
-
expect(logger.isErrorsEnabled).to.equal(true);
|
|
91
|
+
telemetry.$onDidChangeTelemetryLevel('all'); // usage becomes enabled
|
|
92
|
+
expect(changes).to.equal(2);
|
|
41
93
|
|
|
42
|
-
telemetry
|
|
94
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
95
|
+
expect(changes).to.equal(3);
|
|
96
|
+
});
|
|
43
97
|
|
|
44
|
-
|
|
98
|
+
it('stops following the level once the logger is disposed', () => {
|
|
99
|
+
const telemetry = new TelemetryExtImpl();
|
|
100
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
101
|
+
let changes = 0;
|
|
102
|
+
logger.onDidChangeEnableStates(() => changes++);
|
|
103
|
+
|
|
104
|
+
logger.dispose();
|
|
105
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
45
106
|
expect(logger.isUsageEnabled).to.equal(false);
|
|
46
|
-
|
|
107
|
+
|
|
108
|
+
logger.isUsageEnabled = true;
|
|
109
|
+
expect(changes).to.equal(0);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('logs rather than propagates a sender that fails to flush on disposal', async () => {
|
|
113
|
+
const telemetry = new TelemetryExtImpl();
|
|
114
|
+
const logged: unknown[] = [];
|
|
115
|
+
const consoleError = console.error;
|
|
116
|
+
console.error = (...args: unknown[]) => { logged.push(args); };
|
|
117
|
+
try {
|
|
118
|
+
telemetry.createTelemetryLogger({ ...sender, flush: () => { throw new Error('boom'); } }).dispose();
|
|
119
|
+
telemetry.createTelemetryLogger({ ...sender, flush: () => Promise.reject(new Error('boom')) }).dispose();
|
|
120
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
121
|
+
} finally {
|
|
122
|
+
console.error = consoleError;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
expect(logged).to.have.lengthOf(2);
|
|
47
126
|
});
|
|
48
127
|
|
|
49
|
-
it('
|
|
128
|
+
it('ignores a repeated telemetry level', () => {
|
|
50
129
|
const telemetry = new TelemetryExtImpl();
|
|
51
130
|
const logger = telemetry.createTelemetryLogger(sender);
|
|
52
131
|
let changes = 0;
|
|
53
|
-
|
|
54
132
|
logger.onDidChangeEnableStates(() => changes++);
|
|
55
133
|
|
|
56
|
-
telemetry
|
|
57
|
-
telemetry
|
|
134
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
135
|
+
telemetry.$onDidChangeTelemetryLevel('all');
|
|
58
136
|
|
|
59
|
-
expect(changes).to.equal(
|
|
137
|
+
expect(changes).to.equal(1);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('TelemetryLogger', () => {
|
|
142
|
+
|
|
143
|
+
interface RecordingSender {
|
|
144
|
+
events: string[];
|
|
145
|
+
errors: Error[];
|
|
146
|
+
sendEventData(eventName: string): void;
|
|
147
|
+
sendErrorData(error: Error): void;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function createSender(): RecordingSender {
|
|
151
|
+
const events: string[] = [];
|
|
152
|
+
const errors: Error[] = [];
|
|
153
|
+
return {
|
|
154
|
+
events,
|
|
155
|
+
errors,
|
|
156
|
+
sendEventData: (eventName: string) => events.push(eventName),
|
|
157
|
+
sendErrorData: (error: Error) => errors.push(error)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
it('delivers errors but suppresses usage at telemetry level \'error\'', () => {
|
|
162
|
+
const telemetry = new TelemetryExtImpl();
|
|
163
|
+
telemetry.$onDidChangeTelemetryLevel('error');
|
|
164
|
+
const sender = createSender();
|
|
165
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
166
|
+
|
|
167
|
+
logger.logUsage('usage-event');
|
|
168
|
+
logger.logError('error-event');
|
|
169
|
+
logger.logError(new Error('boom'));
|
|
170
|
+
|
|
171
|
+
expect(sender.events).to.deep.equal(['error-event']);
|
|
172
|
+
expect(sender.errors).to.have.lengthOf(1);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('suppresses usage that a plugin re-enables while the telemetry level forbids it', () => {
|
|
176
|
+
const telemetry = new TelemetryExtImpl();
|
|
177
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
178
|
+
const sender = createSender();
|
|
179
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
180
|
+
|
|
181
|
+
logger.isUsageEnabled = true;
|
|
182
|
+
logger.isErrorsEnabled = true;
|
|
183
|
+
logger.logUsage('usage-event');
|
|
184
|
+
logger.logError('error-event');
|
|
185
|
+
|
|
186
|
+
expect(sender.events).to.be.empty;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('refuses to let a plugin assign the telemetry level of its logger', () => {
|
|
190
|
+
const telemetry = new TelemetryExtImpl();
|
|
191
|
+
telemetry.$onDidChangeTelemetryLevel('off');
|
|
192
|
+
const sender = createSender();
|
|
193
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
194
|
+
|
|
195
|
+
expect(Reflect.set(logger, 'level', 'all')).to.be.false;
|
|
196
|
+
logger.logUsage('usage-event');
|
|
197
|
+
|
|
198
|
+
expect(logger.level).to.equal('off');
|
|
199
|
+
expect(logger.isUsageEnabled).to.be.false;
|
|
200
|
+
expect(sender.events).to.be.empty;
|
|
60
201
|
});
|
|
61
202
|
});
|
|
@@ -14,33 +14,54 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
|
|
16
16
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
|
17
|
+
import { Disposable } from '@theia/core/lib/common/disposable';
|
|
17
18
|
import { cloneAndChange } from '@theia/core';
|
|
19
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
20
|
+
import { TelemetryLevel, isKindAllowedByLevel } from '@theia/telemetry/lib/common/telemetry-types';
|
|
21
|
+
import { TelemetryExt } from '../common/plugin-api-rpc';
|
|
18
22
|
import { mixin } from '../common/types';
|
|
19
23
|
import { TelemetryTrustedValue, TelemetryLoggerOptions } from './types-impl';
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Holds the telemetry level the user consented to and hands it to the loggers plugins create.
|
|
27
|
+
*
|
|
28
|
+
* @experimental
|
|
29
|
+
*/
|
|
30
|
+
@injectable()
|
|
31
|
+
export class TelemetryExtImpl implements TelemetryExt {
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
protected currentLevel: TelemetryLevel = 'off';
|
|
24
34
|
private readonly onDidChangeTelemetryEnabledEmitter = new Emitter<boolean>();
|
|
25
35
|
readonly onDidChangeTelemetryEnabled: Event<boolean> = this.onDidChangeTelemetryEnabledEmitter.event;
|
|
36
|
+
private readonly onDidChangeTelemetryLevelEmitter = new Emitter<TelemetryLevel>();
|
|
37
|
+
protected readonly onDidChangeTelemetryLevel: Event<TelemetryLevel> = this.onDidChangeTelemetryLevelEmitter.event;
|
|
26
38
|
|
|
27
|
-
get
|
|
28
|
-
return this.
|
|
39
|
+
get level(): TelemetryLevel {
|
|
40
|
+
return this.currentLevel;
|
|
29
41
|
}
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
$onDidChangeTelemetryLevel(level: TelemetryLevel): void {
|
|
44
|
+
this.setLevel(level);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
setLevel(level: TelemetryLevel): void {
|
|
48
|
+
if (this.currentLevel === level) {
|
|
49
|
+
return;
|
|
35
50
|
}
|
|
51
|
+
const wasTelemetryEnabled = this.isTelemetryEnabled;
|
|
52
|
+
this.currentLevel = level;
|
|
53
|
+
this.onDidChangeTelemetryLevelEmitter.fire(level);
|
|
54
|
+
if (this.isTelemetryEnabled !== wasTelemetryEnabled) {
|
|
55
|
+
this.onDidChangeTelemetryEnabledEmitter.fire(this.isTelemetryEnabled);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get isTelemetryEnabled(): boolean {
|
|
60
|
+
return isKindAllowedByLevel(this.currentLevel, 'usage');
|
|
36
61
|
}
|
|
37
62
|
|
|
38
63
|
createTelemetryLogger(sender: TelemetrySender, options?: TelemetryLoggerOptions | undefined): TelemetryLogger {
|
|
39
|
-
|
|
40
|
-
this.onDidChangeTelemetryEnabled(isEnabled => {
|
|
41
|
-
logger.telemetryEnabled = isEnabled;
|
|
42
|
-
});
|
|
43
|
-
return logger;
|
|
64
|
+
return new TelemetryLogger(sender, this.currentLevel, this.onDidChangeTelemetryLevel, options);
|
|
44
65
|
}
|
|
45
66
|
}
|
|
46
67
|
|
|
@@ -49,30 +70,36 @@ export class TelemetryLogger {
|
|
|
49
70
|
readonly options: TelemetryLoggerOptions | undefined;
|
|
50
71
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
72
|
readonly commonProperties: Record<string, any>;
|
|
52
|
-
private
|
|
73
|
+
private _level: TelemetryLevel;
|
|
53
74
|
|
|
54
75
|
private readonly onDidChangeEnableStatesEmitter: Emitter<TelemetryLogger> = new Emitter();
|
|
55
76
|
readonly onDidChangeEnableStates: Event<TelemetryLogger> = this.onDidChangeEnableStatesEmitter.event;
|
|
56
77
|
private _isUsageEnabled: boolean;
|
|
57
78
|
private _isErrorsEnabled: boolean;
|
|
79
|
+
private readonly levelSubscription: Disposable;
|
|
58
80
|
|
|
59
|
-
constructor(sender: TelemetrySender,
|
|
81
|
+
constructor(sender: TelemetrySender, level: TelemetryLevel, onDidChangeTelemetryLevel: Event<TelemetryLevel>, options?: TelemetryLoggerOptions) {
|
|
60
82
|
this.sender = sender;
|
|
61
83
|
this.options = options;
|
|
62
84
|
this.commonProperties = this.getCommonProperties();
|
|
63
|
-
this.
|
|
64
|
-
this._isErrorsEnabled =
|
|
65
|
-
this._isUsageEnabled =
|
|
85
|
+
this._level = level;
|
|
86
|
+
this._isErrorsEnabled = isKindAllowedByLevel(level, 'error');
|
|
87
|
+
this._isUsageEnabled = isKindAllowedByLevel(level, 'usage');
|
|
88
|
+
this.levelSubscription = onDidChangeTelemetryLevel(next => this.applyLevel(next));
|
|
66
89
|
}
|
|
67
90
|
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
/**
|
|
92
|
+
* The telemetry level the user consented to. Must stay read-only: the object handed to a plugin is proxied with a
|
|
93
|
+
* `get` trap only, so a setter here would let the plugin raise its own gate.
|
|
94
|
+
*/
|
|
95
|
+
get level(): TelemetryLevel {
|
|
96
|
+
return this._level;
|
|
70
97
|
}
|
|
71
98
|
|
|
72
|
-
|
|
73
|
-
if (this.
|
|
74
|
-
this.
|
|
75
|
-
this.updateEnableStates(
|
|
99
|
+
private applyLevel(level: TelemetryLevel): void {
|
|
100
|
+
if (this._level !== level) {
|
|
101
|
+
this._level = level;
|
|
102
|
+
this.updateEnableStates(isKindAllowedByLevel(level, 'usage'), isKindAllowedByLevel(level, 'error'));
|
|
76
103
|
}
|
|
77
104
|
}
|
|
78
105
|
|
|
@@ -108,7 +135,7 @@ export class TelemetryLogger {
|
|
|
108
135
|
|
|
109
136
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
137
|
logUsage(eventName: string, data?: Record<string, any | TelemetryTrustedValue<any>>): void {
|
|
111
|
-
if (!this.
|
|
138
|
+
if (!isKindAllowedByLevel(this._level, 'usage') || !this.isUsageEnabled) {
|
|
112
139
|
return;
|
|
113
140
|
}
|
|
114
141
|
this.logEvent(eventName, data);
|
|
@@ -116,7 +143,7 @@ export class TelemetryLogger {
|
|
|
116
143
|
|
|
117
144
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
145
|
logError(eventNameOrException: string | Error, data?: Record<string, any | TelemetryTrustedValue<any>>): void {
|
|
119
|
-
if (!this.
|
|
146
|
+
if (!isKindAllowedByLevel(this._level, 'error') || !this.isErrorsEnabled || !this.sender) {
|
|
120
147
|
// no sender available or error shall not be sent
|
|
121
148
|
return;
|
|
122
149
|
}
|
|
@@ -128,14 +155,17 @@ export class TelemetryLogger {
|
|
|
128
155
|
}
|
|
129
156
|
|
|
130
157
|
dispose(): void {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
158
|
+
this.levelSubscription.dispose();
|
|
159
|
+
this.onDidChangeEnableStatesEmitter.dispose();
|
|
160
|
+
const sender = this.sender;
|
|
161
|
+
this.sender = undefined;
|
|
162
|
+
const reportFlushFailure = (error: unknown): void => console.error('Failed to flush the telemetry sender.', error);
|
|
163
|
+
try {
|
|
164
|
+
Promise.resolve(sender?.flush?.()).catch(reportFlushFailure);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
reportFlushFailure(error);
|
|
137
167
|
}
|
|
138
|
-
}
|
|
168
|
+
}
|
|
139
169
|
|
|
140
170
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
141
171
|
private logEvent(eventName: string, data?: Record<string, any>): void {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 Robert Jandow
|
|
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 { ContainerModule } from '@theia/core/shared/inversify';
|
|
18
|
+
import { HostedPluginServer, PluginServer } from './common/plugin-protocol';
|
|
19
|
+
import { BrowserOnlyHostedPluginServer } from './hosted/browser-only/browser-only-hosted-plugin-server';
|
|
20
|
+
import { PluginPathsService } from './main/common/plugin-paths-protocol';
|
|
21
|
+
import { BrowserOnlyPluginPathsService } from './hosted/browser-only/browser-only-plugin-paths-service';
|
|
22
|
+
import { BrowserOnlyPluginServer } from './hosted/browser-only/browser-only-plugin-server';
|
|
23
|
+
import { BrowserOnlyPluginFileServiceContribution, BrowserOnlyPluginFileSystemProvider } from './hosted/browser-only/browser-only-plugin-file-system-provider';
|
|
24
|
+
import { FileServiceContribution } from '@theia/filesystem/lib/browser/file-service';
|
|
25
|
+
|
|
26
|
+
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
27
|
+
rebind(HostedPluginServer).to(BrowserOnlyHostedPluginServer).inSingletonScope();
|
|
28
|
+
rebind(PluginServer).to(BrowserOnlyPluginServer).inSingletonScope();
|
|
29
|
+
rebind(PluginPathsService).to(BrowserOnlyPluginPathsService).inSingletonScope();
|
|
30
|
+
|
|
31
|
+
bind(BrowserOnlyPluginFileSystemProvider).toSelf().inSingletonScope();
|
|
32
|
+
bind(BrowserOnlyPluginFileServiceContribution).toSelf().inSingletonScope();
|
|
33
|
+
bind(FileServiceContribution).toService(BrowserOnlyPluginFileServiceContribution);
|
|
34
|
+
});
|