@theia/plugin-utils 1.77.0-next.99 → 1.77.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.
Files changed (92) hide show
  1. package/lib/common/constants.js +12 -15
  2. package/lib/common/constants.js.map +1 -1
  3. package/lib/common/constants.spec.js +7 -9
  4. package/lib/common/constants.spec.js.map +1 -1
  5. package/lib/common/contribution-types.d.ts +8 -3
  6. package/lib/common/contribution-types.d.ts.map +1 -1
  7. package/lib/common/contribution-types.js +5 -7
  8. package/lib/common/contribution-types.js.map +1 -1
  9. package/lib/common/manifest-types.d.ts +1 -1
  10. package/lib/common/manifest-types.d.ts.map +1 -1
  11. package/lib/common/manifest-types.js +7 -11
  12. package/lib/common/manifest-types.js.map +1 -1
  13. package/lib/common/manifest-types.spec.js +7 -9
  14. package/lib/common/manifest-types.spec.js.map +1 -1
  15. package/lib/common/package-nls.js +6 -11
  16. package/lib/common/package-nls.js.map +1 -1
  17. package/lib/common/package-nls.spec.js +23 -25
  18. package/lib/common/package-nls.spec.js.map +1 -1
  19. package/lib/common/plugin-activation-events.d.ts +1 -1
  20. package/lib/common/plugin-activation-events.d.ts.map +1 -1
  21. package/lib/common/plugin-activation-events.js +14 -17
  22. package/lib/common/plugin-activation-events.js.map +1 -1
  23. package/lib/common/plugin-activation-events.spec.js +14 -16
  24. package/lib/common/plugin-activation-events.spec.js.map +1 -1
  25. package/lib/common/plugin-manifest.d.ts +1 -1
  26. package/lib/common/plugin-manifest.d.ts.map +1 -1
  27. package/lib/common/plugin-manifest.js +8 -12
  28. package/lib/common/plugin-manifest.js.map +1 -1
  29. package/lib/common/plugin-manifest.spec.js +21 -23
  30. package/lib/common/plugin-manifest.spec.js.map +1 -1
  31. package/lib/common/plugin-model.d.ts +1 -1
  32. package/lib/common/plugin-model.d.ts.map +1 -1
  33. package/lib/common/plugin-model.js +23 -37
  34. package/lib/common/plugin-model.js.map +1 -1
  35. package/lib/common/plugin-model.spec.js +66 -69
  36. package/lib/common/plugin-model.spec.js.map +1 -1
  37. package/lib/common/protocol-shims.js +3 -6
  38. package/lib/common/protocol-shims.js.map +1 -1
  39. package/lib/common/test-helpers.d.ts +2 -2
  40. package/lib/common/test-helpers.d.ts.map +1 -1
  41. package/lib/common/test-helpers.js +5 -9
  42. package/lib/common/test-helpers.js.map +1 -1
  43. package/lib/common/utils.js +6 -14
  44. package/lib/common/utils.js.map +1 -1
  45. package/lib/common/utils.spec.js +25 -27
  46. package/lib/common/utils.spec.js.map +1 -1
  47. package/lib/node/normalize-contributions.d.ts +3 -3
  48. package/lib/node/normalize-contributions.d.ts.map +1 -1
  49. package/lib/node/normalize-contributions.js +95 -129
  50. package/lib/node/normalize-contributions.js.map +1 -1
  51. package/lib/node/normalize-contributions.spec.js +184 -162
  52. package/lib/node/normalize-contributions.spec.js.map +1 -1
  53. package/lib/node/package-nls.d.ts +1 -1
  54. package/lib/node/package-nls.d.ts.map +1 -1
  55. package/lib/node/package-nls.js +9 -12
  56. package/lib/node/package-nls.js.map +1 -1
  57. package/lib/node/plugin-manifest.d.ts +2 -2
  58. package/lib/node/plugin-manifest.d.ts.map +1 -1
  59. package/lib/node/plugin-manifest.js +6 -9
  60. package/lib/node/plugin-manifest.js.map +1 -1
  61. package/lib/node/plugin-model.d.ts +1 -1
  62. package/lib/node/plugin-model.d.ts.map +1 -1
  63. package/lib/node/plugin-model.js +5 -8
  64. package/lib/node/plugin-model.js.map +1 -1
  65. package/lib/node/read-grammars.d.ts +2 -2
  66. package/lib/node/read-grammars.d.ts.map +1 -1
  67. package/lib/node/read-grammars.js +8 -12
  68. package/lib/node/read-grammars.js.map +1 -1
  69. package/lib/node/read-grammars.spec.js +25 -27
  70. package/lib/node/read-grammars.spec.js.map +1 -1
  71. package/package.json +11 -3
  72. package/src/common/constants.spec.ts +1 -1
  73. package/src/common/contribution-types.ts +9 -3
  74. package/src/common/manifest-types.spec.ts +1 -1
  75. package/src/common/manifest-types.ts +2 -2
  76. package/src/common/package-nls.spec.ts +4 -3
  77. package/src/common/package-nls.ts +1 -1
  78. package/src/common/plugin-activation-events.spec.ts +2 -2
  79. package/src/common/plugin-activation-events.ts +2 -2
  80. package/src/common/plugin-manifest.spec.ts +6 -5
  81. package/src/common/plugin-manifest.ts +3 -3
  82. package/src/common/plugin-model.spec.ts +4 -4
  83. package/src/common/plugin-model.ts +2 -2
  84. package/src/common/test-helpers.ts +3 -3
  85. package/src/common/utils.spec.ts +2 -2
  86. package/src/node/normalize-contributions.spec.ts +37 -7
  87. package/src/node/normalize-contributions.ts +15 -7
  88. package/src/node/package-nls.ts +4 -3
  89. package/src/node/plugin-manifest.ts +4 -3
  90. package/src/node/plugin-model.ts +1 -1
  91. package/src/node/read-grammars.spec.ts +3 -2
  92. package/src/node/read-grammars.ts +5 -4
@@ -21,10 +21,10 @@ import type {
21
21
  JSONObject,
22
22
  PreferenceSchema,
23
23
  TaskDefinition,
24
- } from './protocol-shims';
25
- import type { PluginManifest } from './manifest-types';
24
+ } from './protocol-shims.js';
25
+ import type { PluginManifest } from './manifest-types.js';
26
26
 
27
- export type { JSONObject } from './protocol-shims';
27
+ export type { JSONObject } from './protocol-shims.js';
28
28
 
29
29
  /**
30
30
  * Raw `contributes` section from `package.json` before normalization.
@@ -213,11 +213,17 @@ export enum PluginViewType {
213
213
  Webview = 'webview'
214
214
  }
215
215
 
216
+ export const PLUGIN_VIEW_VISIBILITIES = ['visible', 'collapsed', 'hidden'] as const;
217
+ export type PluginViewVisibility = typeof PLUGIN_VIEW_VISIBILITIES[number];
218
+
216
219
  export interface PluginPackageView {
217
220
  id: string;
218
221
  name: string;
219
222
  when?: string;
220
223
  type?: string;
224
+ visibility?: PluginViewVisibility;
225
+ /** Initial size of the view relative to the other views in its container, like the CSS `flex` property. */
226
+ initialSize?: number;
221
227
  }
222
228
 
223
229
  export interface PluginPackageViewWelcome {
@@ -15,7 +15,7 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
- import { rawContributes } from './manifest-types';
18
+ import { rawContributes } from './manifest-types.js';
19
19
 
20
20
  describe('manifest-types', () => {
21
21
 
@@ -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
- import { isObject } from './utils';
18
- import type { NormalizedPluginContribution, PluginManifestContribution } from './contribution-types';
17
+ import { isObject } from './utils.js';
18
+ import type { NormalizedPluginContribution, PluginManifestContribution } from './contribution-types.js';
19
19
 
20
20
  export const PLUGIN_HOST_BACKEND = 'main' as const;
21
21
  export const PLUGIN_HOST_FRONTEND = 'frontend' as const;
@@ -15,11 +15,12 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
- import * as fs from 'fs-extra';
18
+ // A CommonJS module whose exports cannot be detected statically, so it is imported as a whole.
19
+ import fs from 'fs-extra';
19
20
  import * as os from 'os';
20
21
  import * as path from 'path';
21
- import { coerceLocalizations, localizePackage, localizeWithResolver } from './package-nls';
22
- import { loadPackageTranslations } from '../node/package-nls';
22
+ import { coerceLocalizations, localizePackage, localizeWithResolver } from './package-nls.js';
23
+ import { loadPackageTranslations } from '../node/package-nls.js';
23
24
 
24
25
  describe('package-nls', () => {
25
26
 
@@ -14,7 +14,7 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import { isObject } from './utils';
17
+ import { isObject } from './utils.js';
18
18
 
19
19
  export interface PackageTranslation {
20
20
  translation?: Record<string, string>;
@@ -15,8 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
- import { updateActivationEvents } from './plugin-activation-events';
19
- import type { PluginManifest } from './manifest-types';
18
+ import { updateActivationEvents } from './plugin-activation-events.js';
19
+ import type { PluginManifest } from './manifest-types.js';
20
20
 
21
21
  function manifest(partial: Pick<PluginManifest, 'contributes' | 'activationEvents'>): Pick<PluginManifest, 'contributes' | 'activationEvents'> {
22
22
  return {
@@ -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
- import { flatten, isObject, isStringArray } from './utils';
18
- import { rawContributes, type PluginManifest } from './manifest-types';
17
+ import { flatten, isObject, isStringArray } from './utils.js';
18
+ import { rawContributes, type PluginManifest } from './manifest-types.js';
19
19
 
20
20
  /**
21
21
  * Most activation events can be automatically deduced from the package manifest.
@@ -15,11 +15,12 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
- import { UNPUBLISHED, VSCODE_BUILTIN_NAME_PREFIX } from './constants';
19
- import { prepareLoadedManifest, stripVscodeBuiltinNamePrefix } from './plugin-manifest';
20
- import { loadManifest } from '../node/plugin-manifest';
21
- import type { PluginManifest } from './manifest-types';
22
- import * as fs from 'fs-extra';
18
+ import { UNPUBLISHED, VSCODE_BUILTIN_NAME_PREFIX } from './constants.js';
19
+ import { prepareLoadedManifest, stripVscodeBuiltinNamePrefix } from './plugin-manifest.js';
20
+ import { loadManifest } from '../node/plugin-manifest.js';
21
+ import type { PluginManifest } from './manifest-types.js';
22
+ // A CommonJS module whose exports cannot be detected statically, so it is imported as a whole.
23
+ import fs from 'fs-extra';
23
24
  import * as os from 'os';
24
25
  import * as path from 'path';
25
26
 
@@ -14,9 +14,9 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import { UNPUBLISHED, VSCODE_BUILTIN_NAME_PREFIX } from './constants';
18
- import type { PluginManifest } from './manifest-types';
19
- import { updateActivationEvents } from './plugin-activation-events';
17
+ import { UNPUBLISHED, VSCODE_BUILTIN_NAME_PREFIX } from './constants.js';
18
+ import type { PluginManifest } from './manifest-types.js';
19
+ import { updateActivationEvents } from './plugin-activation-events.js';
20
20
 
21
21
  export interface PrepareLoadedManifestOptions {
22
22
  /** @default true */
@@ -26,7 +26,7 @@ import {
26
26
  VSCODE_FRONTEND_INIT,
27
27
  THEIA_PLUGIN_START_METHOD,
28
28
  THEIA_PLUGIN_STOP_METHOD
29
- } from './constants';
29
+ } from './constants.js';
30
30
  import {
31
31
  applyTrustExtraction,
32
32
  buildEntryPointForTheia,
@@ -40,9 +40,9 @@ import {
40
40
  pickEngineType,
41
41
  toPluginUri,
42
42
  toPluginUrl
43
- } from './plugin-model';
44
- import { getPluginRootFileUrl } from '../node/plugin-model';
45
- import { manifest } from './test-helpers';
43
+ } from './plugin-model.js';
44
+ import { getPluginRootFileUrl } from '../node/plugin-model.js';
45
+ import { manifest } from './test-helpers.js';
46
46
 
47
47
  describe('plugin-model', () => {
48
48
 
@@ -23,14 +23,14 @@ import {
23
23
  VSCODE_EXTENSION_ACTIVATE,
24
24
  VSCODE_EXTENSION_DEACTIVATE,
25
25
  VSCODE_FRONTEND_INIT
26
- } from './constants';
26
+ } from './constants.js';
27
27
  import type {
28
28
  PluginEntryPoint,
29
29
  PluginLifecycle,
30
30
  PluginModel,
31
31
  PluginManifest,
32
32
  PluginPackageCapabilities
33
- } from './manifest-types';
33
+ } from './manifest-types.js';
34
34
 
35
35
  export interface PluginIdentifierSource {
36
36
  publisher?: string;
@@ -14,9 +14,9 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import type { NormalizeContributionsContext } from './contribution-types';
18
- import type { PluginManifest } from './manifest-types';
19
- import { toPluginUrl } from './plugin-model';
17
+ import type { NormalizeContributionsContext } from './contribution-types.js';
18
+ import type { PluginManifest } from './manifest-types.js';
19
+ import { toPluginUrl } from './plugin-model.js';
20
20
 
21
21
  export function manifest(partial: Partial<PluginManifest> & Pick<PluginManifest, 'name'>): PluginManifest {
22
22
  return {
@@ -17,7 +17,7 @@
17
17
  import { expect } from 'chai';
18
18
  import { rejects } from 'assert';
19
19
  import { promises as fs } from 'fs';
20
- import { deepClone, isENOENT, isObject, isStringArray } from './utils';
20
+ import { deepClone, isENOENT, isObject, isStringArray } from './utils.js';
21
21
 
22
22
  describe('utils', () => {
23
23
 
@@ -63,7 +63,7 @@ describe('utils', () => {
63
63
  });
64
64
 
65
65
  it('returns false for other errno codes', async () => {
66
- await rejects(fs.readdir(__filename), reason => !isENOENT(reason));
66
+ await rejects(fs.readdir(import.meta.filename), reason => !isENOENT(reason));
67
67
  });
68
68
  });
69
69
 
@@ -15,8 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
- import { CustomEditorPriority, type GrammarsContribution, type PluginUiTheme, type WalkthroughContribution } from '../common/contribution-types';
19
- import { PreferenceScope } from '../common/protocol-shims';
18
+ import { CustomEditorPriority, type GrammarsContribution, type PluginPackageView, type PluginUiTheme, type WalkthroughContribution } from '../common/contribution-types.js';
19
+ import { PreferenceScope } from '../common/protocol-shims.js';
20
20
  import {
21
21
  deriveDefaultForType,
22
22
  extractPluginViewsIds,
@@ -47,9 +47,9 @@ import {
47
47
  readWalkthroughs,
48
48
  toSchema,
49
49
  transformIconUrl
50
- } from './normalize-contributions';
51
- import { createNormalizeCtx, manifest } from '../common/test-helpers';
52
- import type { PluginManifest } from '../common/manifest-types';
50
+ } from './normalize-contributions.js';
51
+ import { createNormalizeCtx, manifest } from '../common/test-helpers.js';
52
+ import type { PluginManifest } from '../common/manifest-types.js';
53
53
 
54
54
  describe('normalize-contributions', () => {
55
55
 
@@ -203,7 +203,9 @@ describe('normalize-contributions', () => {
203
203
  id: 'sample.view',
204
204
  name: 'Sample View',
205
205
  when: undefined,
206
- type: undefined
206
+ type: undefined,
207
+ visibility: undefined,
208
+ initialSize: undefined
207
209
  }]);
208
210
 
209
211
  const welcome = readViewsWelcome([{
@@ -217,6 +219,16 @@ describe('normalize-contributions', () => {
217
219
  }, ['sample.view']).order).to.equal(1);
218
220
  });
219
221
 
222
+ it('keeps the initial visibility and size a view declares, and drops values of the wrong kind', () => {
223
+ const rawView: PluginPackageView = { id: 'sample.view', name: 'Sample View', visibility: 'collapsed', initialSize: 3 };
224
+ const malformedView = { id: 'malformed.view', name: 'Malformed View', visibility: 'shown', initialSize: Infinity } as unknown as PluginPackageView;
225
+
226
+ const [view, malformed] = readViews([rawView, malformedView]);
227
+
228
+ expect(view).to.include({ visibility: 'collapsed', initialSize: 3 });
229
+ expect(malformed).to.include({ visibility: undefined, initialSize: undefined });
230
+ });
231
+
220
232
  it('skips view containers without a string icon and reports an error', () => {
221
233
  const errors: unknown[] = [];
222
234
  const ctx = createNormalizeCtx({}, {
@@ -714,7 +726,7 @@ describe('normalize-contributions', () => {
714
726
  }]
715
727
  });
716
728
  expect(contributions.views).to.deep.equal({
717
- explorer: [{ id: 'sample.view', name: 'Sample View', when: undefined, type: undefined }]
729
+ explorer: [{ id: 'sample.view', name: 'Sample View', when: undefined, type: undefined, visibility: undefined, initialSize: undefined }]
718
730
  });
719
731
  expect(contributions.viewsWelcome).to.deep.equal([{
720
732
  view: 'sample.view',
@@ -825,6 +837,24 @@ describe('normalize-contributions', () => {
825
837
  }]);
826
838
  });
827
839
 
840
+ it('keeps the initial size of a view only in a view container the same plugin contributes', async () => {
841
+ const ctx = createNormalizeCtx({
842
+ name: 'sized',
843
+ contributes: {
844
+ viewsContainers: { activitybar: [{ id: 'own', title: 'Own', icon: '$(a)' }] },
845
+ views: {
846
+ own: [{ id: 'own.view', name: 'Own View', initialSize: 2 }],
847
+ explorer: [{ id: 'foreign.view', name: 'Foreign View', initialSize: 3 }]
848
+ }
849
+ }
850
+ });
851
+
852
+ const { views } = await normalizeContributions(ctx, {} as { views?: { [location: string]: PluginPackageView[] } });
853
+
854
+ expect(views?.own[0].initialSize).to.equal(2);
855
+ expect(views?.explorer[0].initialSize).to.equal(undefined);
856
+ });
857
+
828
858
  it('merges aliased view container locations and reports async reader failures', async () => {
829
859
  const errors: Array<{ kind: string; message: unknown }> = [];
830
860
  const ctx = createNormalizeCtx({
@@ -19,7 +19,7 @@
19
19
  import { promises as fs } from 'fs';
20
20
  import * as path from 'path';
21
21
  import * as jsoncparser from 'jsonc-parser';
22
- import { deepClone, isColorDefaults, isENOENT, isObject, isStringArray } from '../common/utils';
22
+ import { deepClone, isColorDefaults, isENOENT, isObject, isStringArray } from '../common/utils.js';
23
23
  import {
24
24
  ICON_NAME_SEGMENT,
25
25
  type ColorDefinition,
@@ -30,9 +30,10 @@ import {
30
30
  type PreferenceSchema,
31
31
  PreferenceScope,
32
32
  type TaskDefinition,
33
- } from '../common/protocol-shims';
33
+ } from '../common/protocol-shims.js';
34
34
  import {
35
35
  CustomEditorPriority,
36
+ PLUGIN_VIEW_VISIBILITIES,
36
37
  type AutoClosingPair,
37
38
  type AutoClosingPairConditional,
38
39
  type CharacterPair,
@@ -77,9 +78,9 @@ import {
77
78
  type WalkthroughStepContribution,
78
79
  type WalkthroughStepMedia,
79
80
  type PluginPackageWalkthroughStepMedia,
80
- } from '../common/contribution-types';
81
- import { rawContributes, type PluginManifest } from '../common/manifest-types';
82
- import { UNPUBLISHED } from '../common/constants';
81
+ } from '../common/contribution-types.js';
82
+ import { rawContributes, type PluginManifest } from '../common/manifest-types.js';
83
+ import { UNPUBLISHED } from '../common/constants.js';
83
84
 
84
85
  function isPluginUiTheme(value: unknown): value is PluginUiTheme {
85
86
  return value === 'vs' || value === 'vs-dark' || value === 'hc-black' || value === 'hc-light';
@@ -261,8 +262,13 @@ export async function normalizeContributions<TContrib extends object>(
261
262
  try {
262
263
  if (contributes.views) {
263
264
  const views: { [location: string]: RawView[] } = {};
265
+ // As in VS Code, a view may set its initial size only within a view container of its own plugin.
266
+ const ownViewContainerIds = new Set(Object.values(output.viewsContainers ?? {}).flat().map(container => container.id));
264
267
  for (const location of Object.keys(contributes.views)) {
265
- views[location] = readViewsFn(contributes.views[location]);
268
+ const locationViews = readViewsFn(contributes.views[location]);
269
+ views[location] = ownViewContainerIds.has(location)
270
+ ? locationViews
271
+ : locationViews.map(view => ({ ...view, initialSize: undefined }));
266
272
  }
267
273
  output.views = views;
268
274
  }
@@ -853,7 +859,9 @@ export function readView(rawView: RawView): RawView {
853
859
  id: rawView.id,
854
860
  name: rawView.name,
855
861
  when: rawView.when,
856
- type: rawView.type
862
+ type: rawView.type,
863
+ visibility: PLUGIN_VIEW_VISIBILITIES.find(visibility => visibility === rawView.visibility),
864
+ initialSize: Number.isFinite(rawView.initialSize) && rawView.initialSize! > 0 ? rawView.initialSize : undefined
857
865
  };
858
866
  }
859
867
 
@@ -15,12 +15,13 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import * as path from 'path';
18
- import * as fs from 'fs-extra';
19
- import { isENOENT } from '../common/utils';
18
+ // A CommonJS module whose exports cannot be detected statically, so it is imported as a whole.
19
+ import fs from 'fs-extra';
20
+ import { isENOENT } from '../common/utils.js';
20
21
  import {
21
22
  coerceLocalizations,
22
23
  type PackageTranslation,
23
- } from '../common/package-nls';
24
+ } from '../common/package-nls.js';
24
25
 
25
26
  export async function loadPackageTranslations(pluginPath: string, locale?: string): Promise<PackageTranslation> {
26
27
  const defaultPath = path.join(pluginPath, 'package.nls.json');
@@ -15,9 +15,10 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import * as path from 'path';
18
- import * as fs from 'fs-extra';
19
- import type { PluginManifest } from '../common/manifest-types';
20
- import { prepareLoadedManifest, type PrepareLoadedManifestOptions } from '../common/plugin-manifest';
18
+ // A CommonJS module whose exports cannot be detected statically, so it is imported as a whole.
19
+ import fs from 'fs-extra';
20
+ import type { PluginManifest } from '../common/manifest-types.js';
21
+ import { prepareLoadedManifest, type PrepareLoadedManifestOptions } from '../common/plugin-manifest.js';
21
22
 
22
23
  type LoadedManifest = Pick<PluginManifest, 'name' | 'publisher' | 'contributes' | 'activationEvents'>;
23
24
 
@@ -15,7 +15,7 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { readdirSync } from 'fs';
18
- import { toPluginUrl, type PluginIdentifierSource } from '../common/plugin-model';
18
+ import { toPluginUrl, type PluginIdentifierSource } from '../common/plugin-model.js';
19
19
 
20
20
  export function getPluginRootFileUrl(manifest: PluginIdentifierSource & { packagePath: string }, names: string[]): string | undefined {
21
21
  const nameSet = new Set(names.map(n => n.toLowerCase()));
@@ -15,10 +15,11 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { expect } from 'chai';
18
- import * as fs from 'fs-extra';
18
+ // A CommonJS module whose exports cannot be detected statically, so it is imported as a whole.
19
+ import fs from 'fs-extra';
19
20
  import * as os from 'os';
20
21
  import * as path from 'path';
21
- import { readGrammarFromDisk, getGrammarContributionValidationError } from './read-grammars';
22
+ import { readGrammarFromDisk, getGrammarContributionValidationError } from './read-grammars.js';
22
23
 
23
24
  describe('readGrammarFromDisk', () => {
24
25
 
@@ -15,15 +15,16 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import * as path from 'path';
18
- import * as fs from 'fs-extra';
19
- import { isObject } from '../common/utils';
18
+ // A CommonJS module whose exports cannot be detected statically, so it is imported as a whole.
19
+ import fs from 'fs-extra';
20
+ import { isObject } from '../common/utils.js';
20
21
  import type {
21
22
  GrammarsContribution,
22
23
  NormalizeContributionsContext,
23
24
  PluginPackageGrammarsContribution,
24
- } from '../common/contribution-types';
25
+ } from '../common/contribution-types.js';
25
26
 
26
- export type { GrammarsContribution } from '../common/contribution-types';
27
+ export type { GrammarsContribution } from '../common/contribution-types.js';
27
28
 
28
29
  /**
29
30
  * Returns a validation error message, or `undefined` if the contribution is valid.