@theia/plugin-ext 1.76.0-next.7 → 1.76.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
|
@@ -26,6 +26,7 @@ import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'
|
|
|
26
26
|
import { IconThemeService, IconTheme, IconThemeDefinition } from '@theia/core/lib/browser/icon-theme-service';
|
|
27
27
|
import { IconThemeContribution, DeployedPlugin, UiTheme, getPluginId } from '../../common/plugin-protocol';
|
|
28
28
|
import { PLUGINS_BASE_PATH } from '@theia/plugin-utils/lib/common/constants';
|
|
29
|
+
import { encodePluginAssetPath } from '@theia/plugin-utils/lib/common/plugin-model';
|
|
29
30
|
import URI from '@theia/core/lib/common/uri';
|
|
30
31
|
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
31
32
|
import { Emitter } from '@theia/core/lib/common/event';
|
|
@@ -364,7 +365,7 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
|
|
|
364
365
|
const iconUri = this.locationUri.resolve(iconPath);
|
|
365
366
|
const relativePath = this.packageRootUri.path.relative(iconUri.path.normalize());
|
|
366
367
|
return relativePath && `url('${new Endpoint({
|
|
367
|
-
path: `${PLUGINS_BASE_PATH}/${this.pluginId}/${
|
|
368
|
+
path: `${PLUGINS_BASE_PATH}/${this.pluginId}/${encodePluginAssetPath(relativePath.normalize().toString())}`
|
|
368
369
|
}).getRestUrl().toString()}')`;
|
|
369
370
|
}
|
|
370
371
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 JuliaHub, Inc. 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 { Emitter } from '@theia/core/lib/common/event';
|
|
19
|
+
import { Container } from '@theia/core/shared/inversify';
|
|
20
|
+
import { TelemetryConsentProvider } from '@theia/telemetry/lib/common/telemetry-consent-provider';
|
|
21
|
+
import { TelemetryLevel } from '@theia/telemetry/lib/common/telemetry-types';
|
|
22
|
+
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
23
|
+
import { TelemetryMainImpl } from './telemetry-main';
|
|
24
|
+
|
|
25
|
+
describe('TelemetryMainImpl', () => {
|
|
26
|
+
|
|
27
|
+
let level: TelemetryLevel;
|
|
28
|
+
let pushed: TelemetryLevel[];
|
|
29
|
+
let levelChanged: Emitter<TelemetryLevel>;
|
|
30
|
+
let container: Container;
|
|
31
|
+
let rpc: RPCProtocol;
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
level = 'off';
|
|
35
|
+
pushed = [];
|
|
36
|
+
levelChanged = new Emitter<TelemetryLevel>();
|
|
37
|
+
container = new Container();
|
|
38
|
+
container.bind(TelemetryConsentProvider).toConstantValue(<TelemetryConsentProvider>{
|
|
39
|
+
get level(): TelemetryLevel { return level; },
|
|
40
|
+
onDidChangeTelemetryLevel: levelChanged.event,
|
|
41
|
+
ready: Promise.resolve()
|
|
42
|
+
});
|
|
43
|
+
rpc = {
|
|
44
|
+
getProxy<T>(_proxyId: unknown): T {
|
|
45
|
+
return {
|
|
46
|
+
$onDidChangeTelemetryLevel: (next: TelemetryLevel) => { pushed.push(next); }
|
|
47
|
+
} as unknown as T;
|
|
48
|
+
},
|
|
49
|
+
set: <T, R extends T>(_identifier: unknown, instance: R) => instance,
|
|
50
|
+
dispose: () => { }
|
|
51
|
+
} as RPCProtocol;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('does not push a level on construction, the initial level is seeded through $init', () => {
|
|
55
|
+
new TelemetryMainImpl(rpc, container);
|
|
56
|
+
|
|
57
|
+
expect(pushed).to.be.empty;
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('pushes every level change to the plugin host', () => {
|
|
61
|
+
new TelemetryMainImpl(rpc, container);
|
|
62
|
+
|
|
63
|
+
levelChanged.fire('all');
|
|
64
|
+
levelChanged.fire('error');
|
|
65
|
+
|
|
66
|
+
expect(pushed).to.deep.equal(['all', 'error']);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('stops pushing once disposed', () => {
|
|
70
|
+
const telemetryMain = new TelemetryMainImpl(rpc, container);
|
|
71
|
+
|
|
72
|
+
telemetryMain.dispose();
|
|
73
|
+
levelChanged.fire('all');
|
|
74
|
+
|
|
75
|
+
expect(pushed).to.be.empty;
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 JuliaHub, Inc. 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 { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
|
|
18
|
+
import { interfaces } from '@theia/core/shared/inversify';
|
|
19
|
+
import { TelemetryConsentProvider } from '@theia/telemetry/lib/common/telemetry-consent-provider';
|
|
20
|
+
import { MAIN_RPC_CONTEXT, TelemetryExt, TelemetryMain } from '../../common/plugin-api-rpc';
|
|
21
|
+
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Forwards the user's telemetry consent to the plugin host. The initial level is seeded through
|
|
25
|
+
* `PluginManagerInitializeParams` so that it is in place before any plugin activates.
|
|
26
|
+
*
|
|
27
|
+
* `TelemetryMain` declares no `$` methods; the instance is registered with the RPC protocol so that the consent
|
|
28
|
+
* subscription is disposed along with the channel.
|
|
29
|
+
*
|
|
30
|
+
* @experimental
|
|
31
|
+
*/
|
|
32
|
+
export class TelemetryMainImpl implements TelemetryMain, Disposable {
|
|
33
|
+
|
|
34
|
+
protected readonly proxy: TelemetryExt;
|
|
35
|
+
protected readonly toDispose = new DisposableCollection();
|
|
36
|
+
|
|
37
|
+
constructor(rpc: RPCProtocol, container: interfaces.Container) {
|
|
38
|
+
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.TELEMETRY_EXT);
|
|
39
|
+
const consentProvider = container.get<TelemetryConsentProvider>(TelemetryConsentProvider);
|
|
40
|
+
this.toDispose.push(consentProvider.onDidChangeTelemetryLevel(level => this.proxy.$onDidChangeTelemetryLevel(level)));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dispose(): void {
|
|
44
|
+
this.toDispose.dispose();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -14,14 +14,18 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { ApplicationShell, FocusTracker, Widget } from '@theia/core/lib/browser';
|
|
17
|
+
import { ApplicationShell, FocusTracker, Widget, WidgetContextKeyContribution } from '@theia/core/lib/browser';
|
|
18
18
|
import { ContextKey, ContextKeyService } from '@theia/core/lib/browser/context-key-service';
|
|
19
19
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
20
20
|
import { CustomEditorWidget } from '../custom-editors/custom-editor-widget';
|
|
21
|
+
import { CodeEditorWidgetUtil } from '../menus/vscode-theia-menu-mappings';
|
|
21
22
|
import { WebviewWidget } from './webview';
|
|
22
23
|
|
|
24
|
+
const ACTIVE_WEBVIEW_PANEL_ID = 'activeWebviewPanelId';
|
|
25
|
+
const ACTIVE_CUSTOM_EDITOR_ID = 'activeCustomEditorId';
|
|
26
|
+
|
|
23
27
|
@injectable()
|
|
24
|
-
export class WebviewContextKeys {
|
|
28
|
+
export class WebviewContextKeys implements WidgetContextKeyContribution {
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
31
|
* Context key representing the `viewType` of the active `WebviewWidget`, if any.
|
|
@@ -41,11 +45,23 @@ export class WebviewContextKeys {
|
|
|
41
45
|
|
|
42
46
|
@postConstruct()
|
|
43
47
|
protected init(): void {
|
|
44
|
-
this.activeWebviewPanelId = this.contextKeyService.createKey(
|
|
45
|
-
this.activeCustomEditorId = this.contextKeyService.createKey(
|
|
48
|
+
this.activeWebviewPanelId = this.contextKeyService.createKey(ACTIVE_WEBVIEW_PANEL_ID, '');
|
|
49
|
+
this.activeCustomEditorId = this.contextKeyService.createKey(ACTIVE_CUSTOM_EDITOR_ID, '');
|
|
46
50
|
this.applicationShell.onDidChangeCurrentWidget(this.handleDidChangeCurrentWidget, this);
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
getContextKeyValues(widget: Widget): Iterable<[string, unknown]> | undefined {
|
|
54
|
+
// A view toolbar item may key on the *active* editor, so only the editor-like widgets these keys can
|
|
55
|
+
// describe get an answer; everything else keeps the ambient value.
|
|
56
|
+
if (!CodeEditorWidgetUtil.is(widget)) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return [
|
|
60
|
+
[ACTIVE_CUSTOM_EDITOR_ID, widget instanceof CustomEditorWidget ? widget.viewType : ''],
|
|
61
|
+
[ACTIVE_WEBVIEW_PANEL_ID, widget instanceof WebviewWidget ? widget.viewType : '']
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
49
65
|
protected handleDidChangeCurrentWidget(change: FocusTracker.IChangedArgs<Widget>): void {
|
|
50
66
|
const { newValue } = change;
|
|
51
67
|
if (newValue instanceof CustomEditorWidget) {
|
|
@@ -20,6 +20,7 @@ import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
|
20
20
|
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
|
21
21
|
import URI from '@theia/core/lib/common/uri';
|
|
22
22
|
import { WebviewExternalEndpoint } from '../../common/webview-protocol';
|
|
23
|
+
import { PLUGIN_HOST_FRONTEND } from '../../../common/plugin-protocol';
|
|
23
24
|
import { environment } from '@theia/core/shared/@theia/application-package/lib/environment';
|
|
24
25
|
|
|
25
26
|
@injectable()
|
|
@@ -65,7 +66,7 @@ export class WebviewEnvironment {
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
async resourceRoot(host: string): Promise<string> {
|
|
68
|
-
if (host ===
|
|
69
|
+
if (host === PLUGIN_HOST_FRONTEND) {
|
|
69
70
|
return (await this.externalEndpointUrl()).withPath('{{path}}').toString(true);
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2018 Red Hat, Inc. 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
|
+
export namespace PluginPaths {
|
|
18
|
+
export const PLUGINS_LOGS_DIR = 'logs';
|
|
19
|
+
export const PLUGINS_GLOBAL_STORAGE_DIR = 'plugin-storage';
|
|
20
|
+
export const PLUGINS_WORKSPACE_STORAGE_DIR = 'workspace-storage';
|
|
21
|
+
/**
|
|
22
|
+
* Default number of per-session plugin log folders to retain. Shared between the backend's
|
|
23
|
+
* `--plugin-max-session-logs-folders` CLI option and the browser-only frontend, which has no
|
|
24
|
+
* CLI to read it from. This is the default value used in VSCode, see:
|
|
25
|
+
* https://github.com/Microsoft/vscode/blob/613447d6b3f458ef7fee227e3876303bf5184580/src/vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner.ts#L32
|
|
26
|
+
*/
|
|
27
|
+
export const DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS = 10;
|
|
28
|
+
}
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated since 1.76.0 - `PluginPaths` moved to `@theia/plugin-ext/lib/main/common/paths/const`
|
|
19
|
+
* so the browser-only frontend can share it. Import it from there.
|
|
20
|
+
*/
|
|
21
|
+
export { PluginPaths } from '../../common/paths/const';
|
|
@@ -23,7 +23,7 @@ import { remove } from '@theia/core/shared/fs-extra';
|
|
|
23
23
|
import * as crypto from 'crypto';
|
|
24
24
|
import { ILogger } from '@theia/core';
|
|
25
25
|
import { FileUri } from '@theia/core/lib/node';
|
|
26
|
-
import { PluginPaths } from '
|
|
26
|
+
import { PluginPaths } from '../../common/paths/const';
|
|
27
27
|
import { PluginPathsService } from '../../common/plugin-paths-protocol';
|
|
28
28
|
import { UntitledWorkspaceService } from '@theia/workspace/lib/common';
|
|
29
29
|
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
|
@@ -18,6 +18,7 @@ import { injectable } from '@theia/core/shared/inversify';
|
|
|
18
18
|
import { Argv, Arguments } from '@theia/core/shared/yargs';
|
|
19
19
|
import { CliContribution } from '@theia/core/lib/node/cli';
|
|
20
20
|
import { LocalDirectoryPluginDeployerResolver } from './resolvers/local-directory-plugin-deployer-resolver';
|
|
21
|
+
import { PluginPaths } from '../common/paths/const';
|
|
21
22
|
|
|
22
23
|
@injectable()
|
|
23
24
|
export class PluginCliContribution implements CliContribution {
|
|
@@ -26,10 +27,10 @@ export class PluginCliContribution implements CliContribution {
|
|
|
26
27
|
static PLUGIN_MAX_SESSION_LOGS_FOLDERS = 'plugin-max-session-logs-folders';
|
|
27
28
|
static UNCOMPRESSED_PLUGINS_IN_PLACE = 'uncompressed-plugins-in-place';
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
30
|
+
* Shared with the browser-only frontend (which has no CLI to read this option from) via
|
|
31
|
+
* {@link PluginPaths.DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS}, so the two defaults cannot drift apart.
|
|
31
32
|
*/
|
|
32
|
-
static DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS =
|
|
33
|
+
static DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS = PluginPaths.DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS;
|
|
33
34
|
|
|
34
35
|
protected _localDir: string | undefined;
|
|
35
36
|
protected _maxSessionLogsFolders: number;
|
|
@@ -21,7 +21,7 @@ import * as path from 'path';
|
|
|
21
21
|
import { FileUri } from '@theia/core/lib/common/file-uri';
|
|
22
22
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
23
23
|
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
|
24
|
-
import { PluginPaths } from '
|
|
24
|
+
import { PluginPaths } from '../common/paths/const';
|
|
25
25
|
import { PluginPathsService } from '../common/plugin-paths-protocol';
|
|
26
26
|
import { KeysToAnyValues, KeysToKeysToAnyValue } from '../../common/types';
|
|
27
27
|
import { PluginStorageKind } from '../../common';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 Matthew Farrow 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 * as fs from 'fs';
|
|
19
|
+
import * as os from 'os';
|
|
20
|
+
import * as path from 'path';
|
|
21
|
+
import { LocalDirectoryPluginDeployerResolver } from './local-directory-plugin-deployer-resolver';
|
|
22
|
+
import { PluginDeployerResolverContext } from '../../../common/plugin-protocol';
|
|
23
|
+
|
|
24
|
+
describe('LocalDirectoryPluginDeployerResolver', () => {
|
|
25
|
+
|
|
26
|
+
let localPath: string;
|
|
27
|
+
let deployed: Map<string, string>;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
localPath = fs.mkdtempSync(path.join(os.tmpdir(), 'theia-local-dir-'));
|
|
31
|
+
deployed = new Map();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
fs.rmSync(localPath, { recursive: true, force: true });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function createContext(): PluginDeployerResolverContext {
|
|
39
|
+
return {
|
|
40
|
+
getOriginId: () => `${LocalDirectoryPluginDeployerResolver.LOCAL_DIR}:${localPath}`,
|
|
41
|
+
addPlugin: (pluginId: string, pluginPath: string) => {
|
|
42
|
+
deployed.set(pluginId, pluginPath);
|
|
43
|
+
}
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
} as any as PluginDeployerResolverContext;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
it('should skip files that are not plugins', async () => {
|
|
49
|
+
fs.mkdirSync(path.join(localPath, 'my.plugin'));
|
|
50
|
+
fs.writeFileSync(path.join(localPath, 'my-other.plugin.vsix'), '');
|
|
51
|
+
fs.writeFileSync(path.join(localPath, '.DS_Store'), '');
|
|
52
|
+
fs.writeFileSync(path.join(localPath, '._my.plugin'), '');
|
|
53
|
+
fs.writeFileSync(path.join(localPath, 'Thumbs.db'), '');
|
|
54
|
+
fs.writeFileSync(path.join(localPath, 'desktop.ini'), '');
|
|
55
|
+
|
|
56
|
+
await new LocalDirectoryPluginDeployerResolver().resolve(createContext());
|
|
57
|
+
|
|
58
|
+
expect([...deployed.keys()].sort()).to.deep.equal(['my-other.plugin.vsix', 'my.plugin']);
|
|
59
|
+
expect(deployed.get('my.plugin')).to.equal(path.resolve(localPath, 'my.plugin'));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -20,6 +20,11 @@ import * as fs from '@theia/core/shared/fs-extra';
|
|
|
20
20
|
import * as path from 'path';
|
|
21
21
|
import { LocalPluginDeployerResolver } from './local-plugin-deployer-resolver';
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Lower-case names of files a file manager leaves behind, which are never plugins.
|
|
25
|
+
*/
|
|
26
|
+
const IGNORED_FILE_NAMES = new Set(['thumbs.db', 'desktop.ini']);
|
|
27
|
+
|
|
23
28
|
@injectable()
|
|
24
29
|
export class LocalDirectoryPluginDeployerResolver extends LocalPluginDeployerResolver {
|
|
25
30
|
static LOCAL_DIR = 'local-dir';
|
|
@@ -30,8 +35,16 @@ export class LocalDirectoryPluginDeployerResolver extends LocalPluginDeployerRes
|
|
|
30
35
|
|
|
31
36
|
protected async resolveFromLocalPath(pluginResolverContext: PluginDeployerResolverContext, localPath: string): Promise<void> {
|
|
32
37
|
const files = await fs.readdir(localPath);
|
|
33
|
-
files.forEach(file =>
|
|
38
|
+
files.filter(file => !this.isIgnored(file)).forEach(file =>
|
|
34
39
|
pluginResolverContext.addPlugin(file, path.resolve(localPath, file))
|
|
35
40
|
);
|
|
36
41
|
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Whether a directory entry should be skipped instead of being deployed as a plugin.
|
|
45
|
+
* Covers dotfiles such as the macOS `.DS_Store` and the Windows `Thumbs.db` and `desktop.ini`.
|
|
46
|
+
*/
|
|
47
|
+
protected isIgnored(file: string): boolean {
|
|
48
|
+
return file.startsWith('.') || IGNORED_FILE_NAMES.has(file.toLowerCase());
|
|
49
|
+
}
|
|
37
50
|
}
|
|
@@ -325,7 +325,8 @@ export function createAPIFactory(
|
|
|
325
325
|
messageRegistryExt: MessageRegistryExt,
|
|
326
326
|
clipboard: ClipboardExt,
|
|
327
327
|
webviewExt: WebviewsExtImpl,
|
|
328
|
-
localizationExt: LocalizationExtImpl
|
|
328
|
+
localizationExt: LocalizationExtImpl,
|
|
329
|
+
telemetryExt: TelemetryExtImpl
|
|
329
330
|
): PluginAPIFactory {
|
|
330
331
|
|
|
331
332
|
const authenticationExt = rpc.set(MAIN_RPC_CONTEXT.AUTHENTICATION_EXT, new AuthenticationExtImpl(rpc));
|
|
@@ -359,12 +360,12 @@ export function createAPIFactory(
|
|
|
359
360
|
const tabsExt = rpc.set(MAIN_RPC_CONTEXT.TABS_EXT, new TabsExtImpl(rpc));
|
|
360
361
|
const customEditorExt = rpc.set(MAIN_RPC_CONTEXT.CUSTOM_EDITORS_EXT, new CustomEditorsExtImpl(rpc, documents, webviewExt));
|
|
361
362
|
const webviewViewsExt = rpc.set(MAIN_RPC_CONTEXT.WEBVIEW_VIEWS_EXT, new WebviewViewsExtImpl(rpc, webviewExt));
|
|
362
|
-
const telemetryExt = rpc.set(MAIN_RPC_CONTEXT.TELEMETRY_EXT, new TelemetryExtImpl());
|
|
363
363
|
const testingExt = rpc.set(MAIN_RPC_CONTEXT.TESTING_EXT, new TestingExtImpl(rpc, commandRegistry));
|
|
364
364
|
const uriExt = rpc.set(MAIN_RPC_CONTEXT.URI_EXT, new UriExtImpl(rpc));
|
|
365
365
|
const lmExt = rpc.set(MAIN_RPC_CONTEXT.MCP_SERVER_DEFINITION_REGISTRY_EXT, new LmExtImpl(rpc));
|
|
366
366
|
const lmToolExt = rpc.set(MAIN_RPC_CONTEXT.LM_TOOLS_EXT, new LanguageModelToolsExtImpl(rpc));
|
|
367
367
|
rpc.set(MAIN_RPC_CONTEXT.DEBUG_EXT, debugExt);
|
|
368
|
+
rpc.set(MAIN_RPC_CONTEXT.TELEMETRY_EXT, telemetryExt);
|
|
368
369
|
|
|
369
370
|
const commandLogger = new PluginLogger(rpc, 'commands-plugin');
|
|
370
371
|
|
|
@@ -37,6 +37,7 @@ import * as theia from '@theia/plugin';
|
|
|
37
37
|
import * as types from './types-impl';
|
|
38
38
|
import { join } from './path';
|
|
39
39
|
import { EnvExtImpl } from './env';
|
|
40
|
+
import { TelemetryExtImpl } from './telemetry-ext';
|
|
40
41
|
import { PreferenceRegistryExtImpl } from './preference-registry';
|
|
41
42
|
import { InternalStorageExt, Memento, GlobalState } from './plugin-storage';
|
|
42
43
|
import { ExtPluginApi } from '../common/plugin-ext-api-contribution';
|
|
@@ -244,8 +245,12 @@ export abstract class AbstractPluginManagerExtImpl<P extends Record<string, any>
|
|
|
244
245
|
contributes.jsonValidation = (contributes.jsonValidation || []).concat(this.jsonValidation);
|
|
245
246
|
}
|
|
246
247
|
this.registry.set(plugin.model.id, plugin);
|
|
248
|
+
if (!plugin.pluginPath) {
|
|
249
|
+
// No entry point at all, so nothing to activate here.
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
247
252
|
const activationEvents = this.getActivationEvents(plugin);
|
|
248
|
-
if (
|
|
253
|
+
if (activationEvents) {
|
|
249
254
|
const activation = () => this.$activatePlugin(plugin.model.id);
|
|
250
255
|
// an internal activation event is a subject to change
|
|
251
256
|
this.setActivation(`onPlugin:${plugin.model.id}`, activation);
|
|
@@ -474,6 +479,9 @@ export class PluginManagerExtImpl extends AbstractPluginManagerExtImpl<PluginMan
|
|
|
474
479
|
@inject(WebviewsExtImpl)
|
|
475
480
|
protected readonly webview: WebviewsExtImpl;
|
|
476
481
|
|
|
482
|
+
@inject(TelemetryExtImpl)
|
|
483
|
+
protected readonly telemetryExt: TelemetryExtImpl;
|
|
484
|
+
|
|
477
485
|
private supportedActivationEvents: Set<string>;
|
|
478
486
|
|
|
479
487
|
async $init(params: PluginManagerInitializeParams): Promise<void> {
|
|
@@ -489,6 +497,8 @@ export class PluginManagerExtImpl extends AbstractPluginManagerExtImpl<PluginMan
|
|
|
489
497
|
this.envExt.setAppUriScheme(params.env.appUriScheme);
|
|
490
498
|
|
|
491
499
|
this.preferencesManager.init(params.preferences);
|
|
500
|
+
// must be in place before activation: plugins create their telemetry loggers during `activate()`
|
|
501
|
+
this.telemetryExt.setLevel(params.telemetryLevel ?? 'off');
|
|
492
502
|
|
|
493
503
|
if (params.extApi) {
|
|
494
504
|
this.host.initExtApi(params.extApi);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 JuliaHub, Inc. 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 * as os from 'os';
|
|
19
|
+
import * as path from 'path';
|
|
20
|
+
import { parse } from '@theia/core/lib/common/glob';
|
|
21
|
+
import { isWindows } from '@theia/core/lib/common/os';
|
|
22
|
+
import { URI } from '@theia/core/shared/vscode-uri';
|
|
23
|
+
import { RelativePattern } from './types-impl';
|
|
24
|
+
|
|
25
|
+
// This is the matching a `FileSystemWatcher` performs on every incoming event:
|
|
26
|
+
// `ExtHostFileSystemEventService` builds `parse(globPattern)` once and applies it
|
|
27
|
+
// to each event's `fsPath`. `wrapRelativePattern` rejects a base that is not a
|
|
28
|
+
// parent of the path under `nativeSep`, so a backslash-separated base is only
|
|
29
|
+
// reachable on Windows — elsewhere the pattern is rejected before the glob runs.
|
|
30
|
+
(isWindows ? describe : describe.skip)('RelativePattern matching against native Windows paths', () => {
|
|
31
|
+
|
|
32
|
+
// Derive the child paths from the URI's own `fsPath`: `Uri.file` lower-cases the
|
|
33
|
+
// drive letter, and the parent check is case-sensitive.
|
|
34
|
+
const base = URI.file(path.join(os.tmpdir(), 'theia-relative-pattern'));
|
|
35
|
+
|
|
36
|
+
it('should match a file named by a bare-filename pattern', () => {
|
|
37
|
+
const matches = parse(new RelativePattern(base, 'Project.toml'));
|
|
38
|
+
expect(matches(path.join(base.fsPath, 'Project.toml'))).to.be.ok;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should not match a different file in the same folder', () => {
|
|
42
|
+
const matches = parse(new RelativePattern(base, 'Project.toml'));
|
|
43
|
+
expect(matches(path.join(base.fsPath, 'Manifest.toml'))).to.not.be.ok;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should match a nested file named by a subpath pattern', () => {
|
|
47
|
+
const matches = parse(new RelativePattern(base, 'generated/*.jl'));
|
|
48
|
+
expect(matches(path.join(base.fsPath, 'generated', 'definitions.jl'))).to.be.ok;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should not match a file outside the subpath of the pattern', () => {
|
|
52
|
+
const matches = parse(new RelativePattern(base, 'generated/*.jl'));
|
|
53
|
+
expect(matches(path.join(base.fsPath, 'definitions.jl'))).to.not.be.ok;
|
|
54
|
+
});
|
|
55
|
+
});
|