@theia/plugin-ext 1.75.0-next.25 → 1.75.0-next.29

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 (73) hide show
  1. package/lib/common/errors.d.ts +1 -14
  2. package/lib/common/errors.d.ts.map +1 -1
  3. package/lib/common/errors.js +3 -16
  4. package/lib/common/errors.js.map +1 -1
  5. package/lib/common/plugin-protocol.d.ts +44 -719
  6. package/lib/common/plugin-protocol.d.ts.map +1 -1
  7. package/lib/common/plugin-protocol.js +11 -34
  8. package/lib/common/plugin-protocol.js.map +1 -1
  9. package/lib/hosted/browser/worker/plugin-manifest-loader.d.ts.map +1 -1
  10. package/lib/hosted/browser/worker/plugin-manifest-loader.js +5 -36
  11. package/lib/hosted/browser/worker/plugin-manifest-loader.js.map +1 -1
  12. package/lib/hosted/browser/worker/worker-main.js +2 -1
  13. package/lib/hosted/browser/worker/worker-main.js.map +1 -1
  14. package/lib/hosted/node/hosted-plugin-localization-service.d.ts.map +1 -1
  15. package/lib/hosted/node/hosted-plugin-localization-service.js +4 -68
  16. package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
  17. package/lib/hosted/node/plugin-host-rpc.d.ts.map +1 -1
  18. package/lib/hosted/node/plugin-host-rpc.js +2 -2
  19. package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
  20. package/lib/hosted/node/plugin-reader.d.ts.map +1 -1
  21. package/lib/hosted/node/plugin-reader.js +4 -3
  22. package/lib/hosted/node/plugin-reader.js.map +1 -1
  23. package/lib/hosted/node/scanners/grammars-reader.d.ts +3 -2
  24. package/lib/hosted/node/scanners/grammars-reader.d.ts.map +1 -1
  25. package/lib/hosted/node/scanners/grammars-reader.js +5 -23
  26. package/lib/hosted/node/scanners/grammars-reader.js.map +1 -1
  27. package/lib/hosted/node/scanners/scanner-theia.d.ts +37 -72
  28. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  29. package/lib/hosted/node/scanners/scanner-theia.js +114 -854
  30. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  31. package/lib/hosted/node/scanners/scanner-theia.spec.js +4 -4
  32. package/lib/hosted/node/scanners/scanner-theia.spec.js.map +1 -1
  33. package/lib/main/browser/plugin-contribution-handler.js +1 -1
  34. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  35. package/lib/main/browser/plugin-icon-service.d.ts.map +1 -1
  36. package/lib/main/browser/plugin-icon-service.js +2 -1
  37. package/lib/main/browser/plugin-icon-service.js.map +1 -1
  38. package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
  39. package/lib/main/browser/plugin-icon-theme-service.js +2 -1
  40. package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
  41. package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
  42. package/lib/main/browser/plugin-shared-style.js +2 -1
  43. package/lib/main/browser/plugin-shared-style.js.map +1 -1
  44. package/package.json +31 -30
  45. package/src/common/errors.ts +1 -25
  46. package/src/common/plugin-protocol.ts +194 -719
  47. package/src/hosted/browser/worker/plugin-manifest-loader.ts +8 -41
  48. package/src/hosted/browser/worker/worker-main.ts +2 -1
  49. package/src/hosted/node/hosted-plugin-localization-service.ts +3 -82
  50. package/src/hosted/node/plugin-host-rpc.ts +3 -3
  51. package/src/hosted/node/plugin-reader.ts +4 -3
  52. package/src/hosted/node/scanners/grammars-reader.ts +14 -23
  53. package/src/hosted/node/scanners/scanner-theia.spec.ts +4 -4
  54. package/src/hosted/node/scanners/scanner-theia.ts +200 -972
  55. package/src/main/browser/plugin-contribution-handler.ts +1 -1
  56. package/src/main/browser/plugin-icon-service.ts +2 -1
  57. package/src/main/browser/plugin-icon-theme-service.ts +2 -1
  58. package/src/main/browser/plugin-shared-style.ts +2 -1
  59. package/lib/hosted/node/plugin-activation-events.d.ts +0 -7
  60. package/lib/hosted/node/plugin-activation-events.d.ts.map +0 -1
  61. package/lib/hosted/node/plugin-activation-events.js +0 -95
  62. package/lib/hosted/node/plugin-activation-events.js.map +0 -1
  63. package/lib/hosted/node/plugin-manifest-loader.d.ts +0 -3
  64. package/lib/hosted/node/plugin-manifest-loader.d.ts.map +0 -1
  65. package/lib/hosted/node/plugin-manifest-loader.js +0 -34
  66. package/lib/hosted/node/plugin-manifest-loader.js.map +0 -1
  67. package/lib/main/node/errors.spec.d.ts +0 -2
  68. package/lib/main/node/errors.spec.d.ts.map +0 -1
  69. package/lib/main/node/errors.spec.js +0 -36
  70. package/lib/main/node/errors.spec.js.map +0 -1
  71. package/src/hosted/node/plugin-activation-events.ts +0 -112
  72. package/src/hosted/node/plugin-manifest-loader.ts +0 -32
  73. package/src/main/node/errors.spec.ts +0 -37
@@ -14,7 +14,6 @@
14
14
  //
15
15
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
16
  // *****************************************************************************
17
- var TheiaPluginScanner_1;
18
17
  Object.defineProperty(exports, "__esModule", { value: true });
19
18
  exports.TheiaPluginScanner = exports.AbstractPluginScanner = void 0;
20
19
  const tslib_1 = require("tslib");
@@ -23,43 +22,17 @@ const inversify_1 = require("@theia/core/shared/inversify");
23
22
  const plugin_protocol_1 = require("../../../common/plugin-protocol");
24
23
  const fs_1 = require("fs");
25
24
  const path = require("path");
26
- const types_1 = require("@theia/core/lib/common/types");
27
- const grammars_reader_1 = require("./grammars-reader");
28
- const errors_1 = require("../../../common/errors");
29
25
  const jsoncparser = require("jsonc-parser");
30
- const objects_1 = require("@theia/core/lib/common/objects");
31
- const icon_utilities_1 = require("@theia/core/lib/common/markdown-rendering/icon-utilities");
26
+ const grammars_reader_1 = require("./grammars-reader");
27
+ const utils_1 = require("@theia/plugin-utils/lib/common/utils");
32
28
  const plugin_uri_factory_1 = require("./plugin-uri-factory");
33
- const preference_scope_1 = require("@theia/core/lib/common/preferences/preference-scope");
34
29
  const core_1 = require("@theia/core");
35
- const colorIdPattern = '^\\w+[.\\w+]*$';
36
- const iconIdPattern = `^${icon_utilities_1.CSSIcon.iconNameSegment}(-${icon_utilities_1.CSSIcon.iconNameSegment})+$`;
37
- /** Maps the view container locations used by VS Code extensions to the Theia shell locations. */
38
- const VIEW_CONTAINER_LOCATION_ALIASES = {
39
- activitybar: 'left',
40
- panel: 'bottom',
41
- secondarySidebar: 'right',
42
- auxiliarybar: 'right'
43
- };
44
- function getFileExtension(filePath) {
45
- const index = filePath.lastIndexOf('.');
46
- return index === -1 ? '' : filePath.substring(index + 1);
47
- }
48
- /**
49
- * Mirrors VS Code's `ConfigurationRegistry.getDefaultValue(type)`: plugins expect typed-but-defaultless properties to read as a type-based default, not `undefined`.
50
- */
51
- function deriveDefaultForType(type) {
52
- const t = Array.isArray(type) ? type[0] : type;
53
- switch (t) {
54
- case 'boolean': return false;
55
- case 'integer':
56
- case 'number': return 0;
57
- case 'string': return '';
58
- case 'array': return [];
59
- case 'object': return {};
60
- default: return null;
61
- }
62
- }
30
+ const node_async_hooks_1 = require("node:async_hooks");
31
+ const normalize_contributions_1 = require("@theia/plugin-utils/lib/node/normalize-contributions");
32
+ const plugin_model_1 = require("@theia/plugin-utils/lib/common/plugin-model");
33
+ const plugin_model_2 = require("@theia/plugin-utils/lib/node/plugin-model");
34
+ /** Async-local contribution ctx — safe for concurrent scans on the singleton scanner. */
35
+ const contributionCtxStorage = new node_async_hooks_1.AsyncLocalStorage();
63
36
  let AbstractPluginScanner = class AbstractPluginScanner {
64
37
  constructor(_apiType, _backendInitPath) {
65
38
  this._apiType = _apiType;
@@ -70,33 +43,21 @@ let AbstractPluginScanner = class AbstractPluginScanner {
70
43
  }
71
44
  getModel(plugin) {
72
45
  const publisher = plugin.publisher ?? plugin_protocol_1.PluginIdentifiers.UNPUBLISHED;
73
- const result = {
74
- packagePath: plugin.packagePath,
75
- packageUri: this.pluginUriFactory.createUri(plugin).toString(),
76
- // see id definition: https://github.com/microsoft/vscode/blob/15916055fe0cb9411a5f36119b3b012458fe0a1d/src/vs/platform/extensions/common/extensions.ts#L167-L169
77
- id: `${publisher.toLowerCase()}.${plugin.name.toLowerCase()}`,
78
- name: plugin.name,
46
+ const result = (0, plugin_model_1.buildModelForTheia)({
47
+ ...plugin,
79
48
  publisher,
80
- version: plugin.version,
81
- displayName: plugin.displayName,
82
- description: plugin.description,
83
- l10n: plugin.l10n,
84
- engine: {
85
- type: this._apiType,
86
- version: plugin.engines[this._apiType]
87
- },
88
- entryPoint: this.getEntryPoint(plugin),
89
- licenseUrl: this.getLicenseUrl(plugin),
90
- readmeUrl: this.getReadmeUrl(plugin)
91
- };
49
+ packageUri: this.pluginUriFactory.createUri(plugin).toString(),
50
+ });
51
+ result.engine.type = this._apiType;
52
+ result.engine.version = plugin.engines[this._apiType] ?? '*';
53
+ result.entryPoint = this.getEntryPoint(plugin);
54
+ result.licenseUrl = this.getLicenseUrl(plugin);
55
+ result.readmeUrl = this.getReadmeUrl(plugin);
92
56
  this.applyTrustExtraction(plugin, result);
93
57
  return result;
94
58
  }
95
59
  applyTrustExtraction(plugin, result) {
96
- const untrustedWorkspacesSupport = plugin.capabilities?.untrustedWorkspaces?.supported;
97
- if (untrustedWorkspacesSupport !== undefined) {
98
- result.untrustedWorkspacesSupport = untrustedWorkspacesSupport;
99
- }
60
+ (0, plugin_model_1.applyTrustExtraction)(plugin, result);
100
61
  }
101
62
  getReadmeUrl(plugin) {
102
63
  return this.getPluginRootFileUrl(plugin, ['readme.md', 'readme.txt', 'readme']);
@@ -105,25 +66,10 @@ let AbstractPluginScanner = class AbstractPluginScanner {
105
66
  return this.getPluginRootFileUrl(plugin, ['license', 'license.txt', 'license.md']);
106
67
  }
107
68
  getPluginRootFileUrl(plugin, names) {
108
- const nameSet = new Set(names.map(n => n.toLowerCase()));
109
- try {
110
- const dir = (0, fs_1.readdirSync)(plugin.packagePath, { withFileTypes: true });
111
- for (const dirent of dir) {
112
- if (dirent.isFile() && nameSet.has(dirent.name.toLowerCase())) {
113
- return plugin_protocol_1.PluginPackage.toPluginUrl(plugin, dirent.name);
114
- }
115
- }
116
- }
117
- catch {
118
- return undefined;
119
- }
69
+ return (0, plugin_model_2.getPluginRootFileUrl)(plugin, names);
120
70
  }
121
71
  getLifecycle(plugin) {
122
- const result = {
123
- startMethod: 'start',
124
- stopMethod: 'stop',
125
- frontendModuleName: (0, plugin_protocol_1.buildFrontendModuleName)(plugin),
126
- };
72
+ const result = (0, plugin_model_1.buildLifecycle)(plugin, 'theiaPlugin');
127
73
  if (this._backendInitPath) {
128
74
  result.backendInitPath = path.join(__dirname, this._backendInitPath);
129
75
  }
@@ -164,689 +110,142 @@ exports.AbstractPluginScanner = AbstractPluginScanner = tslib_1.__decorate([
164
110
  tslib_1.__param(1, (0, inversify_1.unmanaged)()),
165
111
  tslib_1.__metadata("design:paramtypes", [String, String])
166
112
  ], AbstractPluginScanner);
167
- let TheiaPluginScanner = TheiaPluginScanner_1 = class TheiaPluginScanner extends AbstractPluginScanner {
113
+ let TheiaPluginScanner = class TheiaPluginScanner extends AbstractPluginScanner {
168
114
  constructor() {
169
115
  super('theiaPlugin', 'backend-init-theia');
170
116
  }
171
117
  getEntryPoint(plugin) {
172
- const result = {
173
- frontend: plugin.theiaPlugin.frontend,
174
- backend: plugin.theiaPlugin.backend
175
- };
176
- if (plugin.theiaPlugin?.headless) {
177
- result.headless = plugin.theiaPlugin.headless;
178
- }
179
- return result;
118
+ return (0, plugin_model_1.buildEntryPointForTheia)(plugin);
180
119
  }
181
120
  static getScope(monacoScope) {
182
- switch (monacoScope) {
183
- case 'machine-overridable':
184
- case 'window':
185
- case 'resource':
186
- return { scope: preference_scope_1.PreferenceScope.Folder, overridable: false };
187
- case 'language-overridable':
188
- return { scope: preference_scope_1.PreferenceScope.Folder, overridable: true };
189
- case 'application':
190
- case 'machine':
191
- return { scope: preference_scope_1.PreferenceScope.User, overridable: false };
192
- }
193
- return { scope: undefined, overridable: false };
121
+ return (0, normalize_contributions_1.getScope)(monacoScope);
194
122
  }
195
123
  async readContributions(rawPlugin, contributions) {
196
- try {
197
- if (rawPlugin.contributes.configuration) {
198
- const configurations = Array.isArray(rawPlugin.contributes.configuration) ? rawPlugin.contributes.configuration : [rawPlugin.contributes.configuration];
199
- const hasMultipleConfigs = configurations.length > 1;
200
- contributions.configuration = [];
201
- for (const c of configurations) {
202
- const config = this.readConfiguration(c, rawPlugin.packagePath);
203
- if (config) {
204
- Object.values(config.properties).forEach(property => {
205
- if (hasMultipleConfigs) {
206
- // If there are multiple configuration contributions, we need to distinguish them by their title in the settings UI.
207
- // They are placed directly under the plugin's name in the settings UI.
208
- property.owner = rawPlugin.displayName;
209
- property.group = config.title;
210
- }
211
- else {
212
- // If there's only one configuration contribution, we display the title in the settings UI.
213
- property.owner = config.title;
214
- }
215
- });
216
- contributions.configuration.push(config);
217
- }
218
- }
219
- }
220
- }
221
- catch (err) {
222
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'configuration'.`, rawPlugin.contributes.configuration, err);
223
- }
224
- const configurationDefaults = rawPlugin.contributes.configurationDefaults;
225
- contributions.configurationDefaults = (0, types_1.isObject)(configurationDefaults) ? configurationDefaults : undefined;
226
- try {
227
- if (rawPlugin.contributes.submenus) {
228
- contributions.submenus = this.readSubmenus(rawPlugin.contributes.submenus, rawPlugin);
229
- }
230
- }
231
- catch (err) {
232
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'submenus'.`, rawPlugin.contributes.submenus, err);
233
- }
234
- try {
235
- if (rawPlugin.contributes.customEditors) {
236
- const customEditors = this.readCustomEditors(rawPlugin.contributes.customEditors);
237
- contributions.customEditors = customEditors;
238
- }
239
- }
240
- catch (err) {
241
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'customEditors'.`, rawPlugin.contributes.customEditors, err);
242
- }
243
- try {
244
- if (rawPlugin.contributes.viewsContainers) {
245
- const viewsContainers = rawPlugin.contributes.viewsContainers;
246
- contributions.viewsContainers = {};
247
- for (const location of Object.keys(viewsContainers)) {
248
- const containers = this.readViewsContainers(viewsContainers[location], rawPlugin);
249
- const loc = VIEW_CONTAINER_LOCATION_ALIASES[location] ?? location;
250
- if (contributions.viewsContainers[loc]) {
251
- contributions.viewsContainers[loc] = contributions.viewsContainers[loc].concat(containers);
252
- }
253
- else {
254
- contributions.viewsContainers[loc] = containers;
255
- }
256
- }
257
- }
258
- }
259
- catch (err) {
260
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'viewsContainers'.`, rawPlugin.contributes.viewsContainers, err);
261
- }
262
- try {
263
- if (rawPlugin.contributes.views) {
264
- contributions.views = {};
265
- for (const location of Object.keys(rawPlugin.contributes.views)) {
266
- const views = this.readViews(rawPlugin.contributes.views[location]);
267
- contributions.views[location] = views;
268
- }
269
- }
270
- }
271
- catch (err) {
272
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'views'.`, rawPlugin.contributes.views, err);
273
- }
274
- try {
275
- if (rawPlugin.contributes.viewsWelcome) {
276
- contributions.viewsWelcome = this.readViewsWelcome(rawPlugin.contributes.viewsWelcome, rawPlugin.contributes.views);
277
- }
278
- }
279
- catch (err) {
280
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'viewsWelcome'.`, rawPlugin.contributes.viewsWelcome, err);
281
- }
282
- try {
283
- const pluginCommands = rawPlugin.contributes.commands;
284
- if (pluginCommands) {
285
- const commands = Array.isArray(pluginCommands) ? pluginCommands : [pluginCommands];
286
- contributions.commands = commands.map(command => this.readCommand(command, rawPlugin));
287
- }
288
- }
289
- catch (err) {
290
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'commands'.`, rawPlugin.contributes.commands, err);
291
- }
292
- try {
293
- if (rawPlugin.contributes.menus) {
294
- contributions.menus = {};
295
- for (const location of Object.keys(rawPlugin.contributes.menus)) {
296
- const menus = this.readMenus(rawPlugin.contributes.menus[location]);
297
- contributions.menus[location] = menus;
298
- }
299
- }
300
- }
301
- catch (err) {
302
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'menus'.`, rawPlugin.contributes.menus, err);
303
- }
304
- try {
305
- if (rawPlugin.contributes.keybindings) {
306
- const rawKeybindings = Array.isArray(rawPlugin.contributes.keybindings) ? rawPlugin.contributes.keybindings : [rawPlugin.contributes.keybindings];
307
- contributions.keybindings = rawKeybindings.map(rawKeybinding => this.readKeybinding(rawKeybinding));
308
- }
309
- }
310
- catch (err) {
311
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'keybindings'.`, rawPlugin.contributes.keybindings, err);
312
- }
313
- try {
314
- if (rawPlugin.contributes.debuggers) {
315
- const debuggers = this.readDebuggers(rawPlugin.contributes.debuggers);
316
- contributions.debuggers = debuggers;
317
- }
318
- }
319
- catch (err) {
320
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'debuggers'.`, rawPlugin.contributes.debuggers, err);
321
- }
322
- try {
323
- if (rawPlugin.contributes.taskDefinitions) {
324
- const definitions = rawPlugin.contributes.taskDefinitions;
325
- contributions.taskDefinitions = definitions.map(definitionContribution => this.readTaskDefinition(rawPlugin.name, definitionContribution));
326
- }
327
- }
328
- catch (err) {
329
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'taskDefinitions'.`, rawPlugin.contributes.taskDefinitions, err);
330
- }
331
- try {
332
- contributions.problemMatchers = rawPlugin.contributes.problemMatchers;
333
- }
334
- catch (err) {
335
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'problemMatchers'.`, rawPlugin.contributes.problemMatchers, err);
336
- }
337
- try {
338
- contributions.problemPatterns = rawPlugin.contributes.problemPatterns;
339
- }
340
- catch (err) {
341
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'problemPatterns'.`, rawPlugin.contributes.problemPatterns, err);
342
- }
343
- try {
344
- contributions.resourceLabelFormatters = rawPlugin.contributes.resourceLabelFormatters;
345
- }
346
- catch (err) {
347
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'resourceLabelFormatters'.`, rawPlugin.contributes.resourceLabelFormatters, err);
348
- }
349
- try {
350
- contributions.authentication = rawPlugin.contributes.authentication;
351
- }
352
- catch (err) {
353
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'authentication'.`, rawPlugin.contributes.authentication, err);
354
- }
355
- try {
356
- contributions.notebooks = rawPlugin.contributes.notebooks;
357
- }
358
- catch (err) {
359
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'notebooks'.`, rawPlugin.contributes.notebooks, err);
360
- }
361
- try {
362
- contributions.notebookRenderer = rawPlugin.contributes.notebookRenderer;
363
- }
364
- catch (err) {
365
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'notebook-renderer'.`, rawPlugin.contributes.notebookRenderer, err);
366
- }
367
- try {
368
- contributions.notebookPreload = rawPlugin.contributes.notebookPreload;
369
- }
370
- catch (err) {
371
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'notebooks-preload'.`, rawPlugin.contributes.notebookPreload, err);
372
- }
373
- try {
374
- contributions.snippets = this.readSnippets(rawPlugin);
375
- }
376
- catch (err) {
377
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'snippets'.`, rawPlugin.contributes.snippets, err);
378
- }
379
- try {
380
- contributions.themes = this.readThemes(rawPlugin);
381
- }
382
- catch (err) {
383
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'themes'.`, rawPlugin.contributes.themes, err);
384
- }
385
- try {
386
- contributions.icons = this.readIcons(rawPlugin);
387
- }
388
- catch (err) {
389
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'icons'.`, rawPlugin.contributes.icons, err);
390
- }
391
- try {
392
- contributions.iconThemes = this.readIconThemes(rawPlugin);
393
- }
394
- catch (err) {
395
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'iconThemes'.`, rawPlugin.contributes.iconThemes, err);
396
- }
397
- try {
398
- contributions.colors = this.readColors(rawPlugin);
399
- }
400
- catch (err) {
401
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'colors'.`, rawPlugin.contributes.colors, err);
402
- }
403
- try {
404
- contributions.terminalProfiles = this.readTerminals(rawPlugin);
405
- }
406
- catch (err) {
407
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'terminals'.`, rawPlugin.contributes.terminal, err);
408
- }
409
- try {
410
- contributions.localizations = this.readLocalizations(rawPlugin);
411
- }
412
- catch (err) {
413
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'localizations'.`, rawPlugin.contributes.localizations, err);
414
- }
415
- const [languagesResult, grammarsResult] = await Promise.allSettled([
416
- rawPlugin.contributes.languages ? this.readLanguages(rawPlugin.contributes.languages, rawPlugin) : undefined,
417
- rawPlugin.contributes.grammars ? this.grammarsReader.readGrammars(rawPlugin.contributes.grammars, rawPlugin.packagePath) : undefined
418
- ]);
419
- if (rawPlugin.contributes.languages) {
420
- if (languagesResult.status === 'fulfilled') {
421
- contributions.languages = languagesResult.value;
422
- }
423
- else {
424
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'languages'.`, rawPlugin.contributes.languages, languagesResult.reason);
425
- }
426
- }
427
- if (rawPlugin.contributes.grammars) {
428
- if (grammarsResult.status === 'fulfilled') {
429
- contributions.grammars = grammarsResult.value;
430
- }
431
- else {
432
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'grammars'.`, rawPlugin.contributes.grammars, grammarsResult.reason);
433
- }
434
- }
435
- try {
436
- contributions.walkthroughs = this.readWalkthroughs(rawPlugin);
437
- }
438
- catch (err) {
439
- this.logger.error(`Could not read '${rawPlugin.name}' contribution 'walkthroughs'.`, rawPlugin.contributes.walkthroughs, err);
440
- }
441
- return contributions;
124
+ const ctx = this.contributionCtx(rawPlugin);
125
+ return contributionCtxStorage.run(ctx, () => (0, normalize_contributions_1.normalizeContributions)(ctx, contributions));
126
+ }
127
+ contributionCtx(pck) {
128
+ const active = contributionCtxStorage.getStore();
129
+ if (active?.plugin === pck) {
130
+ return active;
131
+ }
132
+ const ctx = {
133
+ plugin: pck,
134
+ resolveUrl: relativePath => this.toPluginUrl(pck, relativePath),
135
+ resolveUri: (_plugin, relativePath) => this.pluginUriFactory.createUri(pck, relativePath).toString(),
136
+ onError: (type, err, detail) => this.logger.error(`Could not read '${pck.name}' contribution '${type}'.`, detail, err),
137
+ onWarn: msg => this.logger.warn(msg),
138
+ readJsonFile: filePath => this.readJson(filePath),
139
+ // Route through protected methods so Inversify/subclass overrides still apply.
140
+ transformIconUrl: (plugin, original) => this.transformIconUrl(plugin, original),
141
+ readLocalization: (entry, pluginPath) => this.readLocalization(entry, pluginPath),
142
+ readTranslation: (entry, pluginPath) => this.readTranslation(entry, pluginPath),
143
+ toSchema: definition => this.toSchema(definition),
144
+ readConfiguration: this.readConfiguration.bind(this),
145
+ readCustomEditors: this.readCustomEditors.bind(this),
146
+ readViews: this.readViews.bind(this),
147
+ readKeybinding: this.readKeybinding.bind(this),
148
+ readDebuggers: this.readDebuggers.bind(this),
149
+ readSubmenus: (submenus, plugin) => this.readSubmenus(submenus, plugin),
150
+ readViewsContainers: (containers, plugin) => this.readViewsContainers(containers, plugin),
151
+ readViewsWelcome: (welcome, views) => this.readViewsWelcome(welcome, views),
152
+ readCommand: (command, plugin) => this.readCommand(command, plugin),
153
+ readMenus: menus => this.readMenus(menus),
154
+ readTaskDefinition: (pluginName, definition) => this.readTaskDefinition(pluginName, definition),
155
+ readSnippets: plugin => this.readSnippets(plugin),
156
+ readThemes: plugin => this.readThemes(plugin),
157
+ readIcons: plugin => this.readIcons(plugin),
158
+ readIconThemes: plugin => this.readIconThemes(plugin),
159
+ readColors: plugin => this.readColors(plugin),
160
+ readTerminals: plugin => this.readTerminals(plugin),
161
+ readLocalizations: plugin => this.readLocalizations(plugin),
162
+ readWalkthroughs: plugin => this.readWalkthroughs(plugin),
163
+ readLanguages: (languages, plugin) => this.readLanguages(languages, plugin),
164
+ };
165
+ ctx.readGrammars = (grammars, pluginPath) => this.grammarsReader.readGrammars(grammars, pluginPath, ctx);
166
+ return ctx;
442
167
  }
443
168
  readTerminals(pck) {
444
- if (!pck?.contributes?.terminal?.profiles) {
445
- return undefined;
446
- }
447
- return pck.contributes.terminal.profiles.filter(profile => profile.id && profile.title);
169
+ return (0, normalize_contributions_1.readTerminals)(pck);
448
170
  }
449
171
  readLocalizations(pck) {
450
- if (!pck.contributes || !pck.contributes.localizations) {
451
- return undefined;
452
- }
453
- return pck.contributes.localizations.map(e => this.readLocalization(e, pck.packagePath));
172
+ return (0, normalize_contributions_1.readLocalizations)(pck, this.contributionCtx(pck));
454
173
  }
455
- readLocalization({ languageId, languageName, localizedLanguageName, translations }, pluginPath) {
456
- const local = {
457
- languageId,
458
- languageName,
459
- localizedLanguageName,
460
- translations: []
461
- };
462
- local.translations = translations.map(e => this.readTranslation(e, pluginPath));
463
- return local;
174
+ readLocalization(entry, pluginPath) {
175
+ return (0, normalize_contributions_1.readLocalization)(entry, pluginPath, {
176
+ readTranslation: (translation, translationPath) => this.readTranslation(translation, translationPath),
177
+ });
464
178
  }
465
179
  readTranslation(packageTranslation, pluginPath) {
466
- const translation = {
467
- id: packageTranslation.id,
468
- path: packageTranslation.path
469
- };
470
- return translation;
180
+ return (0, normalize_contributions_1.readTranslation)(packageTranslation, pluginPath);
471
181
  }
472
182
  readWalkthroughs(pck) {
473
- if (!pck.contributes || !pck.contributes.walkthroughs) {
474
- return undefined;
475
- }
476
- const pluginId = plugin_protocol_1.PluginIdentifiers.componentsToUnversionedId({ publisher: pck.publisher, name: pck.name, version: pck.version });
477
- // `PluginModel` does not carry the extension icon, so it travels with the walkthroughs that show it.
478
- const pluginIcon = pck.icon ? this.toPluginUrl(pck, pck.icon) : undefined;
479
- const result = [];
480
- for (const walkthrough of pck.contributes.walkthroughs) {
481
- if (typeof walkthrough.id !== 'string' || !walkthrough.id) {
482
- this.logger.error(`'contributes.walkthroughs.id' of '${pluginId}' must be defined and non-empty`);
483
- continue;
484
- }
485
- if (typeof walkthrough.title !== 'string' || !walkthrough.title) {
486
- this.logger.error(`'contributes.walkthroughs.title' of '${pluginId}.${walkthrough.id}' must be defined and non-empty`);
487
- continue;
488
- }
489
- if (!Array.isArray(walkthrough.steps)) {
490
- this.logger.error(`'contributes.walkthroughs.steps' of '${pluginId}.${walkthrough.id}' must be an array`);
491
- continue;
492
- }
493
- const steps = [];
494
- for (const step of walkthrough.steps) {
495
- if (typeof step.id !== 'string' || !step.id) {
496
- this.logger.error(`'contributes.walkthroughs.steps.id' of '${pluginId}.${walkthrough.id}' must be defined and non-empty`);
497
- continue;
498
- }
499
- if (typeof step.title !== 'string' || !step.title) {
500
- this.logger.error(`'contributes.walkthroughs.steps.title' of '${pluginId}.${walkthrough.id}.${step.id}' must be defined and non-empty`);
501
- continue;
502
- }
503
- steps.push({
504
- id: step.id,
505
- title: step.title,
506
- description: step.description || '',
507
- media: this.resolveWalkthroughMedia(pck, step.media),
508
- completionEvents: step.completionEvents,
509
- when: step.when
510
- });
511
- }
512
- result.push({
513
- id: walkthrough.id,
514
- title: walkthrough.title,
515
- description: walkthrough.description || '',
516
- steps,
517
- when: walkthrough.when,
518
- icon: walkthrough.icon,
519
- pluginId,
520
- pluginIcon
521
- });
522
- }
523
- return result.length > 0 ? result : undefined;
183
+ return (0, normalize_contributions_1.readWalkthroughs)(pck, this.contributionCtx(pck));
524
184
  }
525
- resolveWalkthroughMedia(pck, media) {
526
- if (!media) {
527
- return undefined;
528
- }
529
- if ('markdown' in media) {
530
- return { markdown: this.toPluginUrl(pck, media.markdown) };
531
- }
532
- const altText = 'altText' in media ? media.altText : undefined;
533
- if ('svg' in media) {
534
- return { svg: this.toPluginUrl(pck, media.svg), ...(altText !== undefined && { altText }) };
535
- }
536
- if ('image' in media) {
537
- if (typeof media.image === 'string') {
538
- return { image: this.toPluginUrl(pck, media.image), ...(altText !== undefined && { altText }) };
539
- }
540
- // Only `dark` and `light` are mandatory; the high contrast variants fall back to them.
541
- const dark = this.toPluginUrl(pck, media.image.dark);
542
- const light = this.toPluginUrl(pck, media.image.light);
543
- return {
544
- image: {
545
- dark,
546
- light,
547
- hc: media.image.hc ? this.toPluginUrl(pck, media.image.hc) : dark,
548
- hcLight: media.image.hcLight ? this.toPluginUrl(pck, media.image.hcLight) : light
549
- },
550
- ...(altText !== undefined && { altText })
551
- };
552
- }
553
- return undefined;
554
- }
555
- readCommand({ command, title, shortTitle, original, category, icon, enablement }, pck) {
556
- const { themeIcon, iconUrl } = this.transformIconUrl(pck, icon) ?? {};
557
- return { command, title, shortTitle, originalTitle: original, category, iconUrl, themeIcon, enablement };
185
+ readCommand(command, pck) {
186
+ return (0, normalize_contributions_1.readCommand)(this.contributionCtx(pck), command, pck);
558
187
  }
559
188
  transformIconUrl(plugin, original) {
560
- if (original) {
561
- if (typeof original === 'string') {
562
- if (original.startsWith('$(')) {
563
- return { themeIcon: original };
564
- }
565
- else {
566
- return { iconUrl: this.toPluginUrl(plugin, original) };
567
- }
568
- }
569
- else {
570
- return {
571
- iconUrl: {
572
- light: this.toPluginUrl(plugin, original.light),
573
- dark: this.toPluginUrl(plugin, original.dark)
574
- }
575
- };
576
- }
577
- }
189
+ return (0, normalize_contributions_1.transformIconUrl)(this.contributionCtx(plugin), plugin, original);
578
190
  }
579
191
  toPluginUrl(pck, relativePath) {
580
- return plugin_protocol_1.PluginPackage.toPluginUrl(pck, relativePath);
192
+ return (0, plugin_model_1.toPluginUrl)(pck, relativePath);
581
193
  }
582
194
  readColors(pck) {
583
- if (!pck.contributes || !pck.contributes.colors) {
584
- return undefined;
585
- }
586
- const result = [];
587
- for (const contribution of pck.contributes.colors) {
588
- if (typeof contribution.id !== 'string' || contribution.id.length === 0) {
589
- this.logger.error("'configuration.colors.id' must be defined and can not be empty");
590
- continue;
591
- }
592
- if (!contribution.id.match(colorIdPattern)) {
593
- this.logger.error("'configuration.colors.id' must follow the word[.word]*");
594
- continue;
595
- }
596
- if (typeof contribution.description !== 'string' || contribution.id.length === 0) {
597
- this.logger.error("'configuration.colors.description' must be defined and can not be empty");
598
- continue;
599
- }
600
- const defaults = contribution.defaults;
601
- if (!defaults || typeof defaults !== 'object' || typeof defaults.light !== 'string' || typeof defaults.dark !== 'string' || typeof defaults.highContrast !== 'string') {
602
- this.logger.error("'configuration.colors.defaults' must be defined and must contain 'light', 'dark' and 'highContrast'");
603
- continue;
604
- }
605
- result.push({
606
- id: contribution.id,
607
- description: contribution.description,
608
- defaults: {
609
- light: defaults.light,
610
- dark: defaults.dark,
611
- hc: defaults.highContrast
612
- }
613
- });
614
- }
615
- return result;
195
+ return (0, normalize_contributions_1.readColors)(this.contributionCtx(pck), pck);
616
196
  }
617
197
  readThemes(pck) {
618
- if (!pck.contributes || !pck.contributes.themes) {
619
- return undefined;
620
- }
621
- const result = [];
622
- for (const contribution of pck.contributes.themes) {
623
- if (contribution.path) {
624
- result.push({
625
- id: contribution.id,
626
- uri: this.pluginUriFactory.createUri(pck, contribution.path).toString(),
627
- description: contribution.description,
628
- label: contribution.label,
629
- uiTheme: contribution.uiTheme
630
- });
631
- }
632
- }
633
- return result;
198
+ return (0, normalize_contributions_1.readThemes)(this.contributionCtx(pck), pck);
634
199
  }
635
200
  readIconThemes(pck) {
636
- if (!pck.contributes || !pck.contributes.iconThemes) {
637
- return undefined;
638
- }
639
- const result = [];
640
- for (const contribution of pck.contributes.iconThemes) {
641
- if (typeof contribution.id !== 'string') {
642
- this.logger.error('Expected string in `contributes.iconThemes.id`. Provided value:', contribution.id);
643
- continue;
644
- }
645
- if (typeof contribution.path !== 'string') {
646
- this.logger.error('Expected string in `contributes.iconThemes.path`. Provided value:', contribution.path);
647
- continue;
648
- }
649
- result.push({
650
- id: contribution.id,
651
- uri: this.pluginUriFactory.createUri(pck, contribution.path).toString(),
652
- description: contribution.description,
653
- label: contribution.label,
654
- uiTheme: contribution.uiTheme
655
- });
656
- }
657
- return result;
201
+ return (0, normalize_contributions_1.readIconThemes)(this.contributionCtx(pck), pck);
658
202
  }
659
203
  readIcons(pck) {
660
- if (!pck.contributes || !pck.contributes.icons) {
661
- return undefined;
662
- }
663
- const result = [];
664
- const iconEntries = pck.contributes.icons;
665
- for (const id in iconEntries) {
666
- if (pck.contributes.icons.hasOwnProperty(id)) {
667
- if (!id.match(iconIdPattern)) {
668
- this.logger.error("'configuration.icons' keys represent the icon id and can only contain letter, digits and minuses. " +
669
- 'They need to consist of at least two segments in the form `component-iconname`.', 'extension: ', pck.name, 'icon id: ', id);
670
- return;
671
- }
672
- const iconContribution = iconEntries[id];
673
- if (typeof iconContribution.description !== 'string' || iconContribution.description['length'] === 0) {
674
- this.logger.error('configuration.icons.description must be defined and can not be empty, ', 'extension: ', pck.name, 'icon id: ', id);
675
- return;
676
- }
677
- const defaultIcon = iconContribution.default;
678
- if (typeof defaultIcon === 'string') {
679
- result.push({
680
- id,
681
- extensionId: pck.publisher + '.' + pck.name,
682
- description: iconContribution.description,
683
- defaults: { id: defaultIcon }
684
- });
685
- }
686
- else if (typeof defaultIcon === 'object' && typeof defaultIcon.fontPath === 'string' && typeof defaultIcon.fontCharacter === 'string') {
687
- const format = getFileExtension(defaultIcon.fontPath);
688
- if (['woff', 'woff2', 'ttf'].indexOf(format) === -1) {
689
- this.logger.warn("Expected `contributes.icons.default.fontPath` to have file extension 'woff', woff2' or 'ttf', is '{0}'.", format);
690
- return;
691
- }
692
- const iconFontLocation = this.pluginUriFactory.createUri(pck, defaultIcon.fontPath).toString();
693
- result.push({
694
- id,
695
- extensionId: pck.publisher + '.' + pck.name,
696
- description: iconContribution.description,
697
- defaults: {
698
- fontCharacter: defaultIcon.fontCharacter,
699
- location: iconFontLocation
700
- }
701
- });
702
- }
703
- else {
704
- this.logger.error("'configuration.icons.default' must be either a reference to the id of an other theme icon (string) or a icon definition (object) with ", 'properties `fontPath` and `fontCharacter`.');
705
- }
706
- }
707
- }
708
- return result;
204
+ return (0, normalize_contributions_1.readIcons)(this.contributionCtx(pck), pck);
709
205
  }
710
206
  readSnippets(pck) {
711
- if (!pck.contributes || !pck.contributes.snippets) {
712
- return undefined;
713
- }
714
- const result = [];
715
- for (const contribution of pck.contributes.snippets) {
716
- if (contribution.path) {
717
- result.push({
718
- language: contribution.language,
719
- source: pck.displayName || pck.name,
720
- uri: this.pluginUriFactory.createUri(pck, contribution.path).toString()
721
- });
722
- }
723
- }
724
- return result;
207
+ return (0, normalize_contributions_1.readSnippets)(this.contributionCtx(pck), pck);
725
208
  }
726
- async readJson(filePath) {
727
- const content = await this.readFile(filePath);
728
- return content ? jsoncparser.parse(content, undefined, { disallowComments: false }) : undefined;
729
- }
730
- async readFile(filePath) {
731
- try {
732
- const content = await fs_1.promises.readFile(filePath, { encoding: 'utf8' });
733
- return content;
734
- }
735
- catch (e) {
736
- if (!(0, errors_1.isENOENT)(e)) {
737
- this.logger.error(e);
738
- }
739
- return '';
740
- }
741
- }
742
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
743
209
  readConfiguration(rawConfiguration, pluginPath) {
744
- const { scope, overridable } = TheiaPluginScanner_1.getScope(rawConfiguration.scope);
745
- const schema = {
746
- scope,
747
- defaultOverridable: overridable,
748
- title: rawConfiguration.title,
749
- properties: {}
750
- };
751
- if (rawConfiguration.properties) {
752
- for (const [key, property] of Object.entries(rawConfiguration.properties)) {
753
- const scopeInfo = TheiaPluginScanner_1.getScope(property.scope);
754
- const schemaProperty = {
755
- ...property,
756
- scope: scopeInfo.scope,
757
- overridable: scopeInfo.overridable,
758
- default: property.default !== undefined ? property.default : deriveDefaultForType(property.type)
759
- };
760
- schema.properties[key] = schemaProperty;
761
- }
762
- }
763
- return schema;
210
+ return (0, normalize_contributions_1.readConfiguration)(rawConfiguration, pluginPath);
764
211
  }
765
212
  readKeybinding(rawKeybinding) {
766
- return {
767
- keybinding: rawKeybinding.key,
768
- command: rawKeybinding.command,
769
- when: rawKeybinding.when,
770
- mac: rawKeybinding.mac,
771
- linux: rawKeybinding.linux,
772
- win: rawKeybinding.win,
773
- args: rawKeybinding.args
774
- };
213
+ return (0, normalize_contributions_1.readKeybinding)(rawKeybinding);
775
214
  }
776
215
  readCustomEditors(rawCustomEditors) {
777
216
  return rawCustomEditors.map(rawCustomEditor => this.readCustomEditor(rawCustomEditor));
778
217
  }
779
218
  readCustomEditor(rawCustomEditor) {
780
- return {
781
- viewType: rawCustomEditor.viewType,
782
- displayName: rawCustomEditor.displayName,
783
- selector: rawCustomEditor.selector || [],
784
- priority: rawCustomEditor.priority || plugin_protocol_1.CustomEditorPriority.default
785
- };
219
+ return (0, normalize_contributions_1.readCustomEditor)(rawCustomEditor);
786
220
  }
787
221
  readViewsContainers(rawViewsContainers, pck) {
788
- return rawViewsContainers.map(rawViewContainer => this.readViewContainer(rawViewContainer, pck));
222
+ return rawViewsContainers
223
+ .map(rawViewContainer => this.readViewContainer(rawViewContainer, pck))
224
+ .filter((container) => container !== undefined);
789
225
  }
790
226
  readViewContainer(rawViewContainer, pck) {
791
- const themeIcon = rawViewContainer.icon.startsWith('$(') ? rawViewContainer.icon : undefined;
792
- const iconUrl = this.toPluginUrl(pck, rawViewContainer.icon);
793
- return {
794
- id: rawViewContainer.id,
795
- title: rawViewContainer.title,
796
- iconUrl,
797
- themeIcon,
798
- when: rawViewContainer.when,
799
- };
227
+ return (0, normalize_contributions_1.readViewContainer)(this.contributionCtx(pck), rawViewContainer, pck);
800
228
  }
801
229
  readViews(rawViews) {
802
230
  return rawViews.map(rawView => this.readView(rawView));
803
231
  }
804
232
  readView(rawView) {
805
- const result = {
806
- id: rawView.id,
807
- name: rawView.name,
808
- when: rawView.when,
809
- type: rawView.type
810
- };
811
- return result;
233
+ return (0, normalize_contributions_1.readView)(rawView);
812
234
  }
813
235
  readViewsWelcome(rawViewsWelcome, rowViews) {
814
236
  return rawViewsWelcome.map(rawViewWelcome => this.readViewWelcome(rawViewWelcome, this.extractPluginViewsIds(rowViews)));
815
237
  }
816
238
  readViewWelcome(rawViewWelcome, pluginViewsIds) {
817
- const result = {
818
- view: rawViewWelcome.view,
819
- content: rawViewWelcome.contents,
820
- when: rawViewWelcome.when,
821
- enablement: rawViewWelcome.enablement,
822
- // if the plugin contributes Welcome view to its own view - it will be ordered first
823
- order: pluginViewsIds.findIndex(v => v === rawViewWelcome.view) > -1 ? 0 : 1
824
- };
825
- return result;
239
+ return (0, normalize_contributions_1.readViewWelcome)(rawViewWelcome, pluginViewsIds);
826
240
  }
827
241
  extractPluginViewsIds(views) {
828
- const pluginViewsIds = [];
829
- if (views) {
830
- for (const location of Object.keys(views)) {
831
- const viewsIds = views[location].map(view => view.id);
832
- pluginViewsIds.push(...viewsIds);
833
- }
834
- ;
835
- }
836
- return pluginViewsIds;
242
+ return (0, normalize_contributions_1.extractPluginViewsIds)(views);
837
243
  }
838
244
  readMenus(rawMenus) {
839
245
  return rawMenus.map(rawMenu => this.readMenu(rawMenu));
840
246
  }
841
247
  readMenu(rawMenu) {
842
- const result = {
843
- command: rawMenu.command,
844
- submenu: rawMenu.submenu,
845
- alt: rawMenu.alt,
846
- group: rawMenu.group,
847
- when: rawMenu.when
848
- };
849
- return result;
248
+ return (0, normalize_contributions_1.readMenu)(rawMenu);
850
249
  }
851
250
  async readLanguages(rawLanguages, plugin) {
852
251
  return Promise.all(rawLanguages.map(language => this.readLanguage(language, plugin)));
@@ -855,175 +254,40 @@ let TheiaPluginScanner = TheiaPluginScanner_1 = class TheiaPluginScanner extends
855
254
  return rawSubmenus.map(submenu => this.readSubmenu(submenu, plugin));
856
255
  }
857
256
  readSubmenu(rawSubmenu, plugin) {
858
- const icon = this.transformIconUrl(plugin, rawSubmenu.icon);
859
- return {
860
- icon: icon?.iconUrl ?? icon?.themeIcon,
861
- id: rawSubmenu.id,
862
- label: rawSubmenu.label
863
- };
257
+ return (0, normalize_contributions_1.readSubmenu)(this.contributionCtx(plugin), rawSubmenu, plugin);
864
258
  }
865
259
  async readLanguage(rawLang, plugin) {
866
- // TODO: add validation to all parameters
867
- const icon = this.transformIconUrl(plugin, rawLang.icon);
868
- const result = {
869
- id: rawLang.id,
870
- aliases: rawLang.aliases,
871
- extensions: rawLang.extensions,
872
- filenamePatterns: rawLang.filenamePatterns,
873
- filenames: rawLang.filenames,
874
- firstLine: rawLang.firstLine,
875
- mimetypes: rawLang.mimetypes,
876
- icon: icon?.iconUrl ?? icon?.themeIcon
877
- };
878
- if (rawLang.configuration) {
879
- const rawConfiguration = await this.readJson(path.resolve(plugin.packagePath, rawLang.configuration));
880
- if (rawConfiguration) {
881
- const configuration = {
882
- brackets: rawConfiguration.brackets,
883
- comments: rawConfiguration.comments,
884
- folding: rawConfiguration.folding,
885
- wordPattern: rawConfiguration.wordPattern,
886
- autoClosingPairs: this.extractValidAutoClosingPairs(rawLang.id, rawConfiguration),
887
- indentationRules: rawConfiguration.indentationRules,
888
- surroundingPairs: this.extractValidSurroundingPairs(rawLang.id, rawConfiguration),
889
- onEnterRules: rawConfiguration.onEnterRules,
890
- };
891
- result.configuration = configuration;
892
- }
893
- }
894
- return result;
260
+ return (0, normalize_contributions_1.readLanguage)(this.contributionCtx(plugin), rawLang, plugin);
895
261
  }
896
262
  readDebuggers(rawDebuggers) {
897
- return rawDebuggers.map(rawDebug => this.readDebugger(rawDebug));
263
+ return rawDebuggers.map(rawDebugger => this.readDebugger(rawDebugger));
898
264
  }
899
265
  readDebugger(rawDebugger) {
900
- const result = {
901
- type: rawDebugger.type,
902
- label: rawDebugger.label,
903
- languages: rawDebugger.languages,
904
- enableBreakpointsFor: rawDebugger.enableBreakpointsFor,
905
- variables: rawDebugger.variables,
906
- adapterExecutableCommand: rawDebugger.adapterExecutableCommand,
907
- configurationSnippets: rawDebugger.configurationSnippets,
908
- win: rawDebugger.win,
909
- winx86: rawDebugger.winx86,
910
- windows: rawDebugger.windows,
911
- osx: rawDebugger.osx,
912
- linux: rawDebugger.linux,
913
- program: rawDebugger.program,
914
- args: rawDebugger.args,
915
- runtime: rawDebugger.runtime,
916
- runtimeArgs: rawDebugger.runtimeArgs,
917
- configurationAttributes: rawDebugger.configurationAttributes
918
- };
919
- return result;
266
+ return (0, normalize_contributions_1.readDebugger)(rawDebugger);
920
267
  }
921
268
  readTaskDefinition(pluginName, definitionContribution) {
922
- const propertyKeys = definitionContribution.properties ? Object.keys(definitionContribution.properties) : [];
923
- const schema = this.toSchema(definitionContribution);
924
- return {
925
- taskType: definitionContribution.type,
926
- source: pluginName,
927
- properties: {
928
- required: definitionContribution.required || [],
929
- all: propertyKeys,
930
- schema
931
- }
932
- };
269
+ return (0, normalize_contributions_1.readTaskDefinition)(pluginName, definitionContribution, {
270
+ toSchema: definition => this.toSchema(definition)
271
+ });
933
272
  }
934
273
  toSchema(definition) {
935
- const reconciliation = { ...definition, type: 'object' };
936
- const schema = (0, objects_1.deepClone)(reconciliation);
937
- if (schema.properties === undefined) {
938
- schema.properties = Object.create(null);
939
- }
940
- schema.type = 'object';
941
- schema.properties.type = { type: 'string', const: definition.type };
942
- return schema;
274
+ return (0, normalize_contributions_1.toSchema)(definition);
943
275
  }
944
- extractValidAutoClosingPairs(langId, configuration) {
945
- const source = configuration.autoClosingPairs;
946
- if (typeof source === 'undefined') {
947
- return undefined;
948
- }
949
- if (!Array.isArray(source)) {
950
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs\` to be an array.`);
951
- return undefined;
952
- }
953
- let result = undefined;
954
- for (let i = 0, len = source.length; i < len; i++) {
955
- const pair = source[i];
956
- if (Array.isArray(pair)) {
957
- if (!isCharacterPair(pair)) {
958
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}]\` to be an array of two strings or an object.`);
959
- continue;
960
- }
961
- result = result || [];
962
- result.push({ open: pair[0], close: pair[1] });
963
- }
964
- else {
965
- if (!(0, types_1.isObject)(pair)) {
966
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}]\` to be an array of two strings or an object.`);
967
- continue;
968
- }
969
- if (typeof pair.open !== 'string') {
970
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}].open\` to be a string.`);
971
- continue;
972
- }
973
- if (typeof pair.close !== 'string') {
974
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}].close\` to be a string.`);
975
- continue;
976
- }
977
- if (typeof pair.notIn !== 'undefined') {
978
- if (!(0, types_1.isStringArray)(pair.notIn)) {
979
- this.logger.warn(`[${langId}]: language configuration: expected \`autoClosingPairs[${i}].notIn\` to be a string array.`);
980
- continue;
981
- }
982
- }
983
- result = result || [];
984
- result.push({ open: pair.open, close: pair.close, notIn: pair.notIn });
985
- }
986
- }
987
- return result;
276
+ async readJson(filePath) {
277
+ const content = await this.readFile(filePath);
278
+ return content ? jsoncparser.parse(content, undefined, { disallowComments: false }) : undefined;
988
279
  }
989
- extractValidSurroundingPairs(langId, configuration) {
990
- const source = configuration.surroundingPairs;
991
- if (typeof source === 'undefined') {
992
- return undefined;
993
- }
994
- if (!Array.isArray(source)) {
995
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs\` to be an array.`);
996
- return undefined;
280
+ async readFile(filePath) {
281
+ try {
282
+ const content = await fs_1.promises.readFile(filePath, { encoding: 'utf8' });
283
+ return content;
997
284
  }
998
- let result = undefined;
999
- for (let i = 0, len = source.length; i < len; i++) {
1000
- const pair = source[i];
1001
- if (Array.isArray(pair)) {
1002
- if (!isCharacterPair(pair)) {
1003
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}]\` to be an array of two strings or an object.`);
1004
- continue;
1005
- }
1006
- result = result || [];
1007
- result.push({ open: pair[0], close: pair[1] });
1008
- }
1009
- else {
1010
- if (!(0, types_1.isObject)(pair)) {
1011
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}]\` to be an array of two strings or an object.`);
1012
- continue;
1013
- }
1014
- if (typeof pair.open !== 'string') {
1015
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}].open\` to be a string.`);
1016
- continue;
1017
- }
1018
- if (typeof pair.close !== 'string') {
1019
- this.logger.warn(`[${langId}]: language configuration: expected \`surroundingPairs[${i}].close\` to be a string.`);
1020
- continue;
1021
- }
1022
- result = result || [];
1023
- result.push({ open: pair.open, close: pair.close });
285
+ catch (e) {
286
+ if (!(0, utils_1.isENOENT)(e)) {
287
+ this.logger.error(e);
1024
288
  }
289
+ return '';
1025
290
  }
1026
- return result;
1027
291
  }
1028
292
  };
1029
293
  exports.TheiaPluginScanner = TheiaPluginScanner;
@@ -1032,12 +296,8 @@ tslib_1.__decorate([
1032
296
  (0, inversify_1.named)('plugin-ext:TheiaPluginScanner'),
1033
297
  tslib_1.__metadata("design:type", Object)
1034
298
  ], TheiaPluginScanner.prototype, "logger", void 0);
1035
- exports.TheiaPluginScanner = TheiaPluginScanner = TheiaPluginScanner_1 = tslib_1.__decorate([
299
+ exports.TheiaPluginScanner = TheiaPluginScanner = tslib_1.__decorate([
1036
300
  (0, inversify_1.injectable)(),
1037
301
  tslib_1.__metadata("design:paramtypes", [])
1038
302
  ], TheiaPluginScanner);
1039
- function isCharacterPair(something) {
1040
- return ((0, types_1.isStringArray)(something)
1041
- && something.length === 2);
1042
- }
1043
303
  //# sourceMappingURL=scanner-theia.js.map